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

Summary:
In 32 bit builds on a 64 bit system `std::malloc` does not return correctly aligned memory.  This leads to undefined behavior.

This patch switches to using `posix_memalign` to allocate correctly aligned memory instead.

Reviewers: mclow.lists, danalbert, jroelofs, compnerd

Reviewed By: compnerd

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D25417

llvm-svn: 296952
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: c74a2e1297341bdf7111c3aa833c71afeae31402
diff --git a/src/fallback_malloc.cpp b/src/fallback_malloc.cpp
index ed53283..31911bd 100644
--- a/src/fallback_malloc.cpp
+++ b/src/fallback_malloc.cpp
@@ -194,13 +194,26 @@
 
 namespace __cxxabiv1 {
 
-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;
+struct __attribute__((aligned)) __aligned_type  {};
+
+void * __aligned_malloc_with_fallback(size_t size) {
+#if defined(_WIN32)
+    if (void *dest = _aligned_malloc(size, alignof(__aligned_type)))
+      return dest;
+#elif defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+    if (void* dest = std::malloc(size))
+      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) {
     void *ptr = std::calloc(count, size);
     if (NULL != ptr)
@@ -212,6 +225,18 @@
     return ptr;
 }
 
+void __aligned_free_with_fallback(void* ptr) {
+  if (is_fallback_ptr(ptr))
+        fallback_free(ptr);
+  else {
+#if defined(_WIN32)
+        ::_aligned_free(ptr);
+#else
+        std::free(ptr);
+#endif
+  }
+}
+
 void __free_with_fallback(void *ptr) {
     if (is_fallback_ptr(ptr))
         fallback_free(ptr);