[PATCH] D25417: [libcxxabi] Fix alignment of allocated exceptions in 32 bit builds

Eric Fiselier via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 7 14:11:02 PST 2016


EricWF updated this revision to Diff 80658.
EricWF added a comment.

- Use `_aligned_malloc` on windows.
- Ensure `posix_memalign` isn't called with a size of `0`. I'm 99% sure that's currently impossible but we might as well handle it.

I'll commit after testing on OS X.


https://reviews.llvm.org/D25417

Files:
  src/cxa_exception.cpp
  src/fallback_malloc.cpp
  test/test_exception_address_alignment.pass.cpp


Index: test/test_exception_address_alignment.pass.cpp
===================================================================
--- /dev/null
+++ test/test_exception_address_alignment.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that the address of the exception object is properly aligned to the
+// largest supported alignment for the system.
+
+#include <cstdint>
+#include <cassert>
+
+struct __attribute__((aligned)) AlignedType {};
+struct MinAligned {  };
+static_assert(alignof(MinAligned) == 1 && sizeof(MinAligned) == 1, "");
+
+int main() {
+  for (int i=0; i < 10; ++i) {
+    try {
+      throw MinAligned{};
+    } catch (MinAligned const& ref) {
+      assert(reinterpret_cast<uintptr_t>(&ref) % alignof(AlignedType) == 0);
+    }
+  }
+}
Index: src/fallback_malloc.cpp
===================================================================
--- src/fallback_malloc.cpp
+++ src/fallback_malloc.cpp
@@ -193,11 +193,20 @@
 
 #pragma GCC visibility push(hidden)
 
+struct __attribute__((aligned)) __aligned_type  {};
+
 void * __malloc_with_fallback(size_t size) {
-    void *ptr = std::malloc(size);
-    if (NULL == ptr) // if malloc fails, fall back to emergency stash
-        ptr = fallback_malloc(size);
-    return ptr;
+#if defined(_WIN32)
+    if (void *dest = _aligned_malloc(size, alignof(__aligned_type)))
+      return dest;
+#else
+    if (size == 0)
+        size = 1;
+    void* dest;
+    if (::posix_memalign(&dest, alignof(__aligned_type), size) == 0)
+        return dest;
+#endif
+    return fallback_malloc(size);
 }
 
 void * __calloc_with_fallback(size_t count, size_t size) {
Index: src/cxa_exception.cpp
===================================================================
--- src/cxa_exception.cpp
+++ src/cxa_exception.cpp
@@ -66,12 +66,16 @@
     return cxa_exception_from_thrown_object(unwind_exception + 1 );
 }
 
-static
-inline
-size_t
-cxa_exception_size_from_exception_thrown_size(size_t size)
-{
-    return size + sizeof (__cxa_exception);
+// Round s up to next multiple of a.
+static inline
+size_t aligned_allocation_size(size_t s, size_t a) {
+    return (s + a - 1) & ~(a - 1);
+}
+
+static inline
+size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
+    return aligned_allocation_size(size + sizeof (__cxa_exception),
+                                   alignof(__cxa_exception));
 }
 
 static void setExceptionClass(_Unwind_Exception* unwind_exception) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25417.80658.patch
Type: text/x-patch
Size: 2773 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161207/bc0b8fd5/attachment.bin>


More information about the cfe-commits mailing list