summaryrefslogtreecommitdiff
path: root/src/fallback_malloc.cpp
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-03-04 02:04:45 +0000
committerEric Fiselier <eric@efcs.ca>2017-03-04 02:04:45 +0000
commitaad059409f93f48058f669d730cb35ad7b84bb69 (patch)
tree9ed81b7357634d43cfdd134cb1f915e75de2daac /src/fallback_malloc.cpp
parentda7d616fd2870e097eaa85bcec38b97a6d6dbde2 (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@296952 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'src/fallback_malloc.cpp')
-rw-r--r--src/fallback_malloc.cpp35
1 files changed, 30 insertions, 5 deletions
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 @@ size_t print_free_list () {
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 @@ void * __calloc_with_fallback(size_t count, size_t size) {
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);