summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/scudo
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2018-06-12 14:42:40 +0000
committerKostya Kortchinsky <kostyak@google.com>2018-06-12 14:42:40 +0000
commit76969eaf3d386df61f4891d439a50b9c471a31e6 (patch)
tree9bdf07546facf9c59bdfe2a318f34f3742e767a9 /compiler-rt/lib/scudo
parentc3466d2568f5f949d9caf229ab2301b5a79cacaf (diff)
downloadbcm5719-llvm-76969eaf3d386df61f4891d439a50b9c471a31e6.tar.gz
bcm5719-llvm-76969eaf3d386df61f4891d439a50b9c471a31e6.zip
[scudo] Add C++17 aligned new/delete operators support
Summary: This CL adds support for aligned new/delete operators (C++17). Currently we do not support alignment inconsistency detection on deallocation, as this requires a header change, but the APIs are introduced and are functional. Add a smoke test for the aligned version of the operators. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: delcypher, #sanitizers, llvm-commits Differential Revision: https://reviews.llvm.org/D48031 llvm-svn: 334505
Diffstat (limited to 'compiler-rt/lib/scudo')
-rw-r--r--compiler-rt/lib/scudo/scudo_allocator.cpp30
-rw-r--r--compiler-rt/lib/scudo/scudo_allocator.h6
-rw-r--r--compiler-rt/lib/scudo/scudo_malloc.cpp6
-rw-r--r--compiler-rt/lib/scudo/scudo_new_delete.cpp107
4 files changed, 87 insertions, 62 deletions
diff --git a/compiler-rt/lib/scudo/scudo_allocator.cpp b/compiler-rt/lib/scudo/scudo_allocator.cpp
index b497c5a9d5a..fba4b5ac07d 100644
--- a/compiler-rt/lib/scudo/scudo_allocator.cpp
+++ b/compiler-rt/lib/scudo/scudo_allocator.cpp
@@ -480,7 +480,8 @@ struct ScudoAllocator {
// Deallocates a Chunk, which means either adding it to the quarantine or
// directly returning it to the backend if criteria are met.
- void deallocate(void *Ptr, uptr DeleteSize, AllocType Type) {
+ void deallocate(void *Ptr, uptr DeleteSize, uptr DeleteAlignment,
+ AllocType Type) {
// For a deallocation, we only ensure minimal initialization, meaning thread
// local data will be left uninitialized for now (when using ELF TLS). The
// fallback cache will be used instead. This is a workaround for a situation
@@ -513,6 +514,7 @@ struct ScudoAllocator {
dieWithMessage("invalid sized delete when deallocating address %p\n",
Ptr);
}
+ (void)DeleteAlignment; // TODO(kostyak): verify that the alignment matches.
quarantineOrDeallocateChunk(Ptr, &Header, Size);
}
@@ -627,23 +629,23 @@ void ScudoTSD::commitBack() {
Instance.commitBack(this);
}
-void *scudoMalloc(uptr Size, AllocType Type) {
- return SetErrnoOnNull(Instance.allocate(Size, MinAlignment, Type));
-}
-
-void scudoFree(void *Ptr, AllocType Type) {
- Instance.deallocate(Ptr, 0, Type);
+void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type) {
+ if (Alignment && UNLIKELY(!IsPowerOfTwo(Alignment))) {
+ errno = EINVAL;
+ return Instance.handleBadRequest();
+ }
+ return SetErrnoOnNull(Instance.allocate(Size, Alignment, Type));
}
-void scudoSizedFree(void *Ptr, uptr Size, AllocType Type) {
- Instance.deallocate(Ptr, Size, Type);
+void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type) {
+ Instance.deallocate(Ptr, Size, Alignment, Type);
}
void *scudoRealloc(void *Ptr, uptr Size) {
if (!Ptr)
return SetErrnoOnNull(Instance.allocate(Size, MinAlignment, FromMalloc));
if (Size == 0) {
- Instance.deallocate(Ptr, 0, FromMalloc);
+ Instance.deallocate(Ptr, 0, 0, FromMalloc);
return nullptr;
}
return SetErrnoOnNull(Instance.reallocate(Ptr, Size));
@@ -669,14 +671,6 @@ void *scudoPvalloc(uptr Size) {
return SetErrnoOnNull(Instance.allocate(Size, PageSize, FromMemalign));
}
-void *scudoMemalign(uptr Alignment, uptr Size) {
- if (UNLIKELY(!IsPowerOfTwo(Alignment))) {
- errno = EINVAL;
- return Instance.handleBadRequest();
- }
- return SetErrnoOnNull(Instance.allocate(Size, Alignment, FromMemalign));
-}
-
int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size) {
if (UNLIKELY(!CheckPosixMemalignAlignment(Alignment))) {
Instance.handleBadRequest();
diff --git a/compiler-rt/lib/scudo/scudo_allocator.h b/compiler-rt/lib/scudo/scudo_allocator.h
index c29edea4692..f3234fbc95e 100644
--- a/compiler-rt/lib/scudo/scudo_allocator.h
+++ b/compiler-rt/lib/scudo/scudo_allocator.h
@@ -115,12 +115,10 @@ typedef ScudoCombinedAllocator<PrimaryAllocator, AllocatorCache,
void initScudo();
-void *scudoMalloc(uptr Size, AllocType Type);
-void scudoFree(void *Ptr, AllocType Type);
-void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
+void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type);
+void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type);
void *scudoRealloc(void *Ptr, uptr Size);
void *scudoCalloc(uptr NMemB, uptr Size);
-void *scudoMemalign(uptr Alignment, uptr Size);
void *scudoValloc(uptr Size);
void *scudoPvalloc(uptr Size);
int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
diff --git a/compiler-rt/lib/scudo/scudo_malloc.cpp b/compiler-rt/lib/scudo/scudo_malloc.cpp
index eb1047ac075..6e83be42224 100644
--- a/compiler-rt/lib/scudo/scudo_malloc.cpp
+++ b/compiler-rt/lib/scudo/scudo_malloc.cpp
@@ -20,11 +20,11 @@ using namespace __scudo;
extern "C" {
INTERCEPTOR_ATTRIBUTE void free(void *ptr) {
- scudoFree(ptr, FromMalloc);
+ scudoDeallocate(ptr, 0, 0, FromMalloc);
}
INTERCEPTOR_ATTRIBUTE void *malloc(SIZE_T size) {
- return scudoMalloc(size, FromMalloc);
+ return scudoAllocate(size, 0, FromMalloc);
}
INTERCEPTOR_ATTRIBUTE void *realloc(void *ptr, SIZE_T size) {
@@ -50,7 +50,7 @@ INTERCEPTOR_ATTRIBUTE void cfree(void *ptr) ALIAS("free");
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR_ATTRIBUTE void *memalign(SIZE_T alignment, SIZE_T size) {
- return scudoMemalign(alignment, size);
+ return scudoAllocate(size, alignment, FromMemalign);
}
INTERCEPTOR_ATTRIBUTE
diff --git a/compiler-rt/lib/scudo/scudo_new_delete.cpp b/compiler-rt/lib/scudo/scudo_new_delete.cpp
index c5a1abbed82..948d07a5210 100644
--- a/compiler-rt/lib/scudo/scudo_new_delete.cpp
+++ b/compiler-rt/lib/scudo/scudo_new_delete.cpp
@@ -24,51 +24,84 @@ using namespace __scudo;
// Fake std::nothrow_t to avoid including <new>.
namespace std {
struct nothrow_t {};
+enum class align_val_t: size_t {};
} // namespace std
// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
+#define OPERATOR_NEW_BODY_ALIGN(Type, Align, NoThrow) \
+ void *Ptr = scudoAllocate(size, static_cast<uptr>(Align), Type); \
+ if (!NoThrow && UNLIKELY(!Ptr)) DieOnFailure::OnOOM(); \
+ return Ptr;
+#define OPERATOR_NEW_BODY(Type, NoThrow) \
+ OPERATOR_NEW_BODY_ALIGN(Type, 0, NoThrow)
+
+CXX_OPERATOR_ATTRIBUTE
+void *operator new(size_t size)
+{ OPERATOR_NEW_BODY(FromNew, /*NoThrow=*/false); }
+CXX_OPERATOR_ATTRIBUTE
+void *operator new[](size_t size)
+{ OPERATOR_NEW_BODY(FromNewArray, /*NoThrow=*/false); }
+CXX_OPERATOR_ATTRIBUTE
+void *operator new(size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(FromNew, /*NoThrow=*/true); }
+CXX_OPERATOR_ATTRIBUTE
+void *operator new[](size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(FromNewArray, /*NoThrow=*/true); }
+CXX_OPERATOR_ATTRIBUTE
+void *operator new(size_t size, std::align_val_t align)
+{ OPERATOR_NEW_BODY_ALIGN(FromNew, align, /*NoThrow=*/false); }
+CXX_OPERATOR_ATTRIBUTE
+void *operator new[](size_t size, std::align_val_t align)
+{ OPERATOR_NEW_BODY_ALIGN(FromNewArray, align, /*NoThrow=*/false); }
+CXX_OPERATOR_ATTRIBUTE
+void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY_ALIGN(FromNew, align, /*NoThrow=*/true); }
CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size) {
- void *res = scudoMalloc(size, FromNew);
- if (UNLIKELY(!res)) DieOnFailure::OnOOM();
- return res;
-}
-CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size) {
- void *res = scudoMalloc(size, FromNewArray);
- if (UNLIKELY(!res)) DieOnFailure::OnOOM();
- return res;
-}
-CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size, std::nothrow_t const&) {
- return scudoMalloc(size, FromNew);
-}
-CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size, std::nothrow_t const&) {
- return scudoMalloc(size, FromNewArray);
-}
+void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY_ALIGN(FromNewArray, align, /*NoThrow=*/true); }
+#define OPERATOR_DELETE_BODY(Type) \
+ scudoDeallocate(ptr, 0, 0, Type);
+#define OPERATOR_DELETE_BODY_SIZE(Type) \
+ scudoDeallocate(ptr, size, 0, Type);
+#define OPERATOR_DELETE_BODY_ALIGN(Type) \
+ scudoDeallocate(ptr, 0, static_cast<uptr>(align), Type);
+#define OPERATOR_DELETE_BODY_SIZE_ALIGN(Type) \
+ scudoDeallocate(ptr, size, static_cast<uptr>(align), Type);
+
+CXX_OPERATOR_ATTRIBUTE
+void operator delete(void *ptr) NOEXCEPT
+{ OPERATOR_DELETE_BODY(FromNew); }
+CXX_OPERATOR_ATTRIBUTE
+void operator delete[](void *ptr) NOEXCEPT
+{ OPERATOR_DELETE_BODY(FromNewArray); }
+CXX_OPERATOR_ATTRIBUTE
+void operator delete(void *ptr, std::nothrow_t const&)
+{ OPERATOR_DELETE_BODY(FromNew); }
+CXX_OPERATOR_ATTRIBUTE
+void operator delete[](void *ptr, std::nothrow_t const&)
+{ OPERATOR_DELETE_BODY(FromNewArray); }
+CXX_OPERATOR_ATTRIBUTE
+void operator delete(void *ptr, size_t size) NOEXCEPT
+{ OPERATOR_DELETE_BODY_SIZE(FromNew); }
+CXX_OPERATOR_ATTRIBUTE
+void operator delete[](void *ptr, size_t size) NOEXCEPT
+{ OPERATOR_DELETE_BODY_SIZE(FromNewArray); }
CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr) NOEXCEPT {
- return scudoFree(ptr, FromNew);
-}
+void operator delete(void *ptr, std::align_val_t align) NOEXCEPT
+{ OPERATOR_DELETE_BODY_ALIGN(FromNew); }
CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr) NOEXCEPT {
- return scudoFree(ptr, FromNewArray);
-}
+void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT
+{ OPERATOR_DELETE_BODY_ALIGN(FromNewArray); }
CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, std::nothrow_t const&) NOEXCEPT {
- return scudoFree(ptr, FromNew);
-}
+void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&)
+{ OPERATOR_DELETE_BODY_ALIGN(FromNew); }
CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, std::nothrow_t const&) NOEXCEPT {
- return scudoFree(ptr, FromNewArray);
-}
+void operator delete[](void *ptr, std::align_val_t align, std::nothrow_t const&)
+{ OPERATOR_DELETE_BODY_ALIGN(FromNewArray); }
CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, size_t size) NOEXCEPT {
- scudoSizedFree(ptr, size, FromNew);
-}
+void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT
+{ OPERATOR_DELETE_BODY_SIZE_ALIGN(FromNew); }
CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, size_t size) NOEXCEPT {
- scudoSizedFree(ptr, size, FromNewArray);
-}
+void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT
+{ OPERATOR_DELETE_BODY_SIZE_ALIGN(FromNewArray); }
OpenPOWER on IntegriCloud