| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| //===-- wrappers_cpp_test.cc ------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "gtest/gtest.h" | ||
|
|
||
| #include <condition_variable> | ||
| #include <mutex> | ||
| #include <thread> | ||
|
|
||
| // Note that every Cxx allocation function in the test binary will be fulfilled | ||
| // by Scudo. See the comment in the C counterpart of this file. | ||
|
|
||
| extern "C" __attribute__((visibility("default"))) const char * | ||
| __scudo_default_options() { | ||
| return "quarantine_size_kb=256:thread_local_quarantine_size_kb=128:" | ||
| "quarantine_max_chunk_size=512:dealloc_type_mismatch=true"; | ||
| } | ||
|
|
||
| template <typename T> static void testCxxNew() { | ||
| T *P = new T; | ||
| EXPECT_NE(P, nullptr); | ||
| memset(P, 0x42, sizeof(T)); | ||
| EXPECT_DEATH(delete[] P, ""); | ||
| delete P; | ||
| EXPECT_DEATH(delete P, ""); | ||
|
|
||
| P = new T; | ||
| EXPECT_NE(P, nullptr); | ||
| memset(P, 0x42, sizeof(T)); | ||
| operator delete(P, sizeof(T)); | ||
|
|
||
| P = new (std::nothrow) T; | ||
| EXPECT_NE(P, nullptr); | ||
| memset(P, 0x42, sizeof(T)); | ||
| delete P; | ||
|
|
||
| const size_t N = 16U; | ||
| T *A = new T[N]; | ||
| EXPECT_NE(A, nullptr); | ||
| memset(A, 0x42, sizeof(T) * N); | ||
| EXPECT_DEATH(delete A, ""); | ||
| delete[] A; | ||
| EXPECT_DEATH(delete[] A, ""); | ||
|
|
||
| A = new T[N]; | ||
| EXPECT_NE(A, nullptr); | ||
| memset(A, 0x42, sizeof(T) * N); | ||
| operator delete[](A, sizeof(T) * N); | ||
|
|
||
| A = new (std::nothrow) T[N]; | ||
| EXPECT_NE(A, nullptr); | ||
| memset(A, 0x42, sizeof(T) * N); | ||
| delete[] A; | ||
| } | ||
|
|
||
| class Pixel { | ||
| public: | ||
| enum class Color { Red, Green, Blue }; | ||
| int X = 0; | ||
| int Y = 0; | ||
| Color C = Color::Red; | ||
| }; | ||
|
|
||
| TEST(ScudoWrappersCppTest, New) { | ||
| testCxxNew<bool>(); | ||
| testCxxNew<uint8_t>(); | ||
| testCxxNew<uint16_t>(); | ||
| testCxxNew<uint32_t>(); | ||
| testCxxNew<uint64_t>(); | ||
| testCxxNew<float>(); | ||
| testCxxNew<double>(); | ||
| testCxxNew<long double>(); | ||
| testCxxNew<Pixel>(); | ||
| } | ||
|
|
||
| static std::mutex Mutex; | ||
| static std::condition_variable Cv; | ||
| static bool Ready = false; | ||
|
|
||
| static void stressNew() { | ||
| std::vector<uintptr_t *> V; | ||
| { | ||
| std::unique_lock<std::mutex> Lock(Mutex); | ||
| while (!Ready) | ||
| Cv.wait(Lock); | ||
| } | ||
| for (size_t I = 0; I < 256U; I++) { | ||
| const size_t N = std::rand() % 128U; | ||
| uintptr_t *P = new uintptr_t[N]; | ||
| if (P) { | ||
| memset(P, 0x42, sizeof(uintptr_t) * N); | ||
| V.push_back(P); | ||
| } | ||
| } | ||
| while (!V.empty()) { | ||
| delete[] V.back(); | ||
| V.pop_back(); | ||
| } | ||
| } | ||
|
|
||
| TEST(ScudoWrappersCppTest, ThreadedNew) { | ||
| std::thread Threads[32]; | ||
| for (size_t I = 0U; I < sizeof(Threads) / sizeof(Threads[0]); I++) | ||
| Threads[I] = std::thread(stressNew); | ||
| { | ||
| std::unique_lock<std::mutex> Lock(Mutex); | ||
| Ready = true; | ||
| Cv.notify_all(); | ||
| } | ||
| for (auto &T : Threads) | ||
| T.join(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| //===-- wrappers_c.cc -------------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "platform.h" | ||
|
|
||
| // Skip this compilation unit if compiled as part of Bionic. | ||
| #if !SCUDO_ANDROID || !_BIONIC | ||
|
|
||
| #include "allocator_config.h" | ||
| #include "wrappers_c.h" | ||
| #include "wrappers_c_checks.h" | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdio.h> | ||
|
|
||
| static scudo::Allocator<scudo::Config> Allocator; | ||
| // Pointer to the static allocator so that the C++ wrappers can access it. | ||
| // Technically we could have a completely separated heap for C & C++ but in | ||
| // reality the amount of cross pollination between the two is staggering. | ||
| scudo::Allocator<scudo::Config> *AllocatorPtr = &Allocator; | ||
|
|
||
| extern "C" { | ||
|
|
||
| #define SCUDO_PREFIX(name) name | ||
| #define SCUDO_ALLOCATOR Allocator | ||
| #include "wrappers_c.inc" | ||
| #undef SCUDO_ALLOCATOR | ||
| #undef SCUDO_PREFIX | ||
|
|
||
| INTERFACE void __scudo_print_stats(void) { Allocator.printStats(); } | ||
|
|
||
| } // extern "C" | ||
|
|
||
| #endif // !SCUDO_ANDROID || !_BIONIC |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| //===-- wrappers_c.h --------------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef SCUDO_WRAPPERS_C_H_ | ||
| #define SCUDO_WRAPPERS_C_H_ | ||
|
|
||
| #include "platform.h" | ||
| #include "stats.h" | ||
|
|
||
| // Bionic's struct mallinfo consists of size_t (mallinfo(3) uses int). | ||
| #if SCUDO_ANDROID | ||
| typedef size_t __scudo_mallinfo_data_t; | ||
| #else | ||
| typedef int __scudo_mallinfo_data_t; | ||
| #endif | ||
|
|
||
| struct __scudo_mallinfo { | ||
| __scudo_mallinfo_data_t arena; | ||
| __scudo_mallinfo_data_t ordblks; | ||
| __scudo_mallinfo_data_t smblks; | ||
| __scudo_mallinfo_data_t hblks; | ||
| __scudo_mallinfo_data_t hblkhd; | ||
| __scudo_mallinfo_data_t usmblks; | ||
| __scudo_mallinfo_data_t fsmblks; | ||
| __scudo_mallinfo_data_t uordblks; | ||
| __scudo_mallinfo_data_t fordblks; | ||
| __scudo_mallinfo_data_t keepcost; | ||
| }; | ||
|
|
||
| // Android sometimes includes malloc.h no matter what, which yields to | ||
| // conflicting return types for mallinfo() if we use our own structure. So if | ||
| // struct mallinfo is declared (#define courtesy of malloc.h), use it directly. | ||
| #if STRUCT_MALLINFO_DECLARED | ||
| #define SCUDO_MALLINFO mallinfo | ||
| #else | ||
| #define SCUDO_MALLINFO __scudo_mallinfo | ||
| #endif | ||
|
|
||
| #ifndef M_DECAY_TIME | ||
| #define M_DECAY_TIME -100 | ||
| #endif | ||
|
|
||
| #ifndef M_PURGE | ||
| #define M_PURGE -101 | ||
| #endif | ||
|
|
||
| #endif // SCUDO_WRAPPERS_C_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| //===-- wrappers_c.inc ------------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef SCUDO_PREFIX | ||
| #error "Define SCUDO_PREFIX prior to including this file!" | ||
| #endif | ||
|
|
||
| // malloc-type functions have to be aligned to std::max_align_t. This is | ||
| // distinct from (1U << SCUDO_MIN_ALIGNMENT_LOG), since C++ new-type functions | ||
| // do not have to abide by the same requirement. | ||
| #ifndef SCUDO_MALLOC_ALIGNMENT | ||
| #define SCUDO_MALLOC_ALIGNMENT FIRST_32_SECOND_64(8U, 16U) | ||
| #endif | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(calloc)(size_t nmemb, size_t size) { | ||
| scudo::uptr Product; | ||
| if (UNLIKELY(scudo::checkForCallocOverflow(size, nmemb, &Product))) { | ||
| if (SCUDO_ALLOCATOR.canReturnNull()) { | ||
| errno = ENOMEM; | ||
| return nullptr; | ||
| } | ||
| scudo::reportCallocOverflow(nmemb, size); | ||
| } | ||
| return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate( | ||
| Product, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT, true)); | ||
| } | ||
|
|
||
| INTERFACE WEAK void SCUDO_PREFIX(free)(void *ptr) { | ||
| SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc); | ||
| } | ||
|
|
||
| INTERFACE WEAK struct SCUDO_MALLINFO SCUDO_PREFIX(mallinfo)(void) { | ||
| struct SCUDO_MALLINFO Info = {}; | ||
| scudo::StatCounters Stats; | ||
| SCUDO_ALLOCATOR.getStats(Stats); | ||
| Info.uordblks = | ||
| static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatAllocated]); | ||
| return Info; | ||
| } | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(malloc)(size_t size) { | ||
| return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate( | ||
| size, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT)); | ||
| } | ||
|
|
||
| #if SCUDO_ANDROID | ||
| INTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(const void *ptr) { | ||
| #else | ||
| INTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(void *ptr) { | ||
| #endif | ||
| return SCUDO_ALLOCATOR.getUsableSize(ptr); | ||
| } | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(memalign)(size_t alignment, size_t size) { | ||
| // Android rounds up the alignment to a power of two if it isn't one. | ||
| if (SCUDO_ANDROID) { | ||
| if (UNLIKELY(!alignment)) { | ||
| alignment = 1U; | ||
| } else { | ||
| if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) | ||
| alignment = scudo::roundUpToPowerOfTwo(alignment); | ||
| } | ||
| } else { | ||
| if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) { | ||
| if (SCUDO_ALLOCATOR.canReturnNull()) { | ||
| errno = EINVAL; | ||
| return nullptr; | ||
| } | ||
| scudo::reportAlignmentNotPowerOfTwo(alignment); | ||
| } | ||
| } | ||
| return SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, | ||
| alignment); | ||
| } | ||
|
|
||
| INTERFACE WEAK int SCUDO_PREFIX(posix_memalign)(void **memptr, size_t alignment, | ||
| size_t size) { | ||
| if (UNLIKELY(scudo::checkPosixMemalignAlignment(alignment))) { | ||
| if (!SCUDO_ALLOCATOR.canReturnNull()) | ||
| scudo::reportInvalidPosixMemalignAlignment(alignment); | ||
| return EINVAL; | ||
| } | ||
| void *Ptr = | ||
| SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, alignment); | ||
| if (UNLIKELY(!Ptr)) | ||
| return ENOMEM; | ||
| *memptr = Ptr; | ||
| return 0; | ||
| } | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(pvalloc)(size_t size) { | ||
| const scudo::uptr PageSize = scudo::getPageSizeCached(); | ||
| if (UNLIKELY(scudo::checkForPvallocOverflow(size, PageSize))) { | ||
| if (SCUDO_ALLOCATOR.canReturnNull()) { | ||
| errno = ENOMEM; | ||
| return nullptr; | ||
| } | ||
| scudo::reportPvallocOverflow(size); | ||
| } | ||
| // pvalloc(0) should allocate one page. | ||
| return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate( | ||
| size ? scudo::roundUpTo(size, PageSize) : PageSize, | ||
| scudo::Chunk::Origin::Memalign, PageSize)); | ||
| } | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(realloc)(void *ptr, size_t size) { | ||
| if (!ptr) | ||
| return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate( | ||
| size, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT)); | ||
| if (size == 0) { | ||
| SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc); | ||
| return nullptr; | ||
| } | ||
| return scudo::setErrnoOnNull( | ||
| SCUDO_ALLOCATOR.reallocate(ptr, size, SCUDO_MALLOC_ALIGNMENT)); | ||
| } | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(valloc)(size_t size) { | ||
| return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate( | ||
| size, scudo::Chunk::Origin::Memalign, scudo::getPageSizeCached())); | ||
| } | ||
|
|
||
| // Bionic wants a function named PREFIX_iterate and not PREFIX_malloc_iterate | ||
| // which is somewhat inconsistent with the rest, workaround that. | ||
| #if SCUDO_ANDROID && _BIONIC | ||
| #define SCUDO_ITERATE iterate | ||
| #else | ||
| #define SCUDO_ITERATE malloc_iterate | ||
| #endif | ||
|
|
||
| INTERFACE WEAK int SCUDO_PREFIX(SCUDO_ITERATE)( | ||
| uintptr_t base, size_t size, | ||
| void (*callback)(uintptr_t base, size_t size, void *arg), void *arg) { | ||
| SCUDO_ALLOCATOR.iterateOverChunks(base, size, callback, arg); | ||
| return 0; | ||
| } | ||
|
|
||
| INTERFACE WEAK void SCUDO_PREFIX(malloc_disable)() { | ||
| SCUDO_ALLOCATOR.disable(); | ||
| } | ||
|
|
||
| INTERFACE WEAK void SCUDO_PREFIX(malloc_enable)() { SCUDO_ALLOCATOR.enable(); } | ||
|
|
||
| INTERFACE WEAK int SCUDO_PREFIX(mallopt)(int param, UNUSED int value) { | ||
| if (param == M_DECAY_TIME) { | ||
| // TODO(kostyak): set release_to_os_interval_ms accordingly. | ||
| return 1; | ||
| } else if (param == M_PURGE) { | ||
| SCUDO_ALLOCATOR.releaseToOS(); | ||
| return 1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| INTERFACE WEAK void *SCUDO_PREFIX(aligned_alloc)(size_t alignment, | ||
| size_t size) { | ||
| if (UNLIKELY(scudo::checkAlignedAllocAlignmentAndSize(alignment, size))) { | ||
| if (SCUDO_ALLOCATOR.canReturnNull()) { | ||
| errno = EINVAL; | ||
| return nullptr; | ||
| } | ||
| scudo::reportInvalidAlignedAllocAlignment(alignment, size); | ||
| } | ||
| return scudo::setErrnoOnNull( | ||
| SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, alignment)); | ||
| } | ||
|
|
||
| INTERFACE WEAK int SCUDO_PREFIX(malloc_info)(int, FILE *) { | ||
| errno = ENOTSUP; | ||
| return -1; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| //===-- wrappers_c_bionic.cc ------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "platform.h" | ||
|
|
||
| // This is only used when compiled as part of Bionic. | ||
| #if SCUDO_ANDROID && _BIONIC | ||
|
|
||
| #include "allocator_config.h" | ||
| #include "wrappers_c.h" | ||
| #include "wrappers_c_checks.h" | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdio.h> | ||
|
|
||
| static scudo::Allocator<scudo::AndroidConfig> Allocator; | ||
| static scudo::Allocator<scudo::AndroidSvelteConfig> SvelteAllocator; | ||
|
|
||
| extern "C" { | ||
|
|
||
| // Regular MallocDispatch definitions. | ||
| #define SCUDO_PREFIX(name) CONCATENATE(scudo_, name) | ||
| #define SCUDO_ALLOCATOR Allocator | ||
| #include "wrappers_c.inc" | ||
| #undef SCUDO_ALLOCATOR | ||
| #undef SCUDO_PREFIX | ||
|
|
||
| // Svelte MallocDispatch definitions. | ||
| #define SCUDO_PREFIX(name) CONCATENATE(scudo_svelte_, name) | ||
| #define SCUDO_ALLOCATOR SvelteAllocator | ||
| #include "wrappers_c.inc" | ||
| #undef SCUDO_ALLOCATOR | ||
| #undef SCUDO_PREFIX | ||
|
|
||
| // The following is the only function that will end up initializing both | ||
| // allocators, which will result in a slight increase in memory footprint. | ||
| INTERFACE void __scudo_print_stats(void) { | ||
| Allocator.printStats(); | ||
| SvelteAllocator.printStats(); | ||
| } | ||
|
|
||
| } // extern "C" | ||
|
|
||
| #endif // SCUDO_ANDROID && _BIONIC |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| //===-- wrappers_c_checks.h -------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef SCUDO_CHECKS_H_ | ||
| #define SCUDO_CHECKS_H_ | ||
|
|
||
| #include "common.h" | ||
|
|
||
| #include <errno.h> | ||
|
|
||
| namespace scudo { | ||
|
|
||
| // A common errno setting logic shared by almost all Scudo C wrappers. | ||
| INLINE void *setErrnoOnNull(void *Ptr) { | ||
| if (UNLIKELY(!Ptr)) | ||
| errno = ENOMEM; | ||
| return Ptr; | ||
| } | ||
|
|
||
| // Checks return true on failure. | ||
|
|
||
| // Checks aligned_alloc() parameters, verifies that the alignment is a power of | ||
| // two and that the size is a multiple of alignment. | ||
| INLINE bool checkAlignedAllocAlignmentAndSize(uptr Alignment, uptr Size) { | ||
| return Alignment == 0 || !isPowerOfTwo(Alignment) || | ||
| !isAligned(Size, Alignment); | ||
| } | ||
|
|
||
| // Checks posix_memalign() parameters, verifies that alignment is a power of two | ||
| // and a multiple of sizeof(void *). | ||
| INLINE bool checkPosixMemalignAlignment(uptr Alignment) { | ||
| return Alignment == 0 || !isPowerOfTwo(Alignment) || | ||
| !isAligned(Alignment, sizeof(void *)); | ||
| } | ||
|
|
||
| // Returns true if calloc(Size, N) overflows on Size*N calculation. The typical | ||
| // way would be to check for (UINTPTR_MAX / Size) < N, but the division ends up | ||
| // being very costly, so use a builtin supported by recent clang & GCC. | ||
| INLINE bool checkForCallocOverflow(uptr Size, uptr N, uptr *Product) { | ||
| return __builtin_umull_overflow(Size, N, Product); | ||
| } | ||
|
|
||
| // Returns true if the size passed to pvalloc overflows when rounded to the next | ||
| // multiple of PageSize. | ||
| INLINE bool checkForPvallocOverflow(uptr Size, uptr PageSize) { | ||
| return roundUpTo(Size, PageSize) < Size; | ||
| } | ||
|
|
||
| } // namespace scudo | ||
|
|
||
| #endif // SCUDO_CHECKS_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| //===-- wrappers_cpp.cc -----------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "platform.h" | ||
|
|
||
| // Skip this compilation unit if compiled as part of Bionic. | ||
| #if !SCUDO_ANDROID || !_BIONIC | ||
|
|
||
| #include "allocator_config.h" | ||
|
|
||
| #include <stdint.h> | ||
|
|
||
| extern scudo::Allocator<scudo::Config> *AllocatorPtr; | ||
|
|
||
| namespace std { | ||
| struct nothrow_t {}; | ||
| enum class align_val_t : size_t {}; | ||
| } // namespace std | ||
|
|
||
| INTERFACE WEAK void *operator new(size_t size) { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::New); | ||
| } | ||
| INTERFACE WEAK void *operator new[](size_t size) { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::NewArray); | ||
| } | ||
| INTERFACE WEAK void *operator new(size_t size, | ||
| std::nothrow_t const &) NOEXCEPT { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::New); | ||
| } | ||
| INTERFACE WEAK void *operator new[](size_t size, | ||
| std::nothrow_t const &) NOEXCEPT { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::NewArray); | ||
| } | ||
| INTERFACE WEAK void *operator new(size_t size, std::align_val_t align) { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::New, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align) { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::NewArray, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void *operator new(size_t size, std::align_val_t align, | ||
| std::nothrow_t const &) NOEXCEPT { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::New, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align, | ||
| std::nothrow_t const &) NOEXCEPT { | ||
| return AllocatorPtr->allocate(size, scudo::Chunk::Origin::NewArray, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
|
|
||
| INTERFACE WEAK void operator delete(void *ptr)NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::New); | ||
| } | ||
| INTERFACE WEAK void operator delete[](void *ptr) NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::NewArray); | ||
| } | ||
| INTERFACE WEAK void operator delete(void *ptr, std::nothrow_t const &)NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::New); | ||
| } | ||
| INTERFACE WEAK void operator delete[](void *ptr, | ||
| std::nothrow_t const &) NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::NewArray); | ||
| } | ||
| INTERFACE WEAK void operator delete(void *ptr, size_t size)NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::New, size); | ||
| } | ||
| INTERFACE WEAK void operator delete[](void *ptr, size_t size) NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::NewArray, size); | ||
| } | ||
| INTERFACE WEAK void operator delete(void *ptr, std::align_val_t align)NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::New, 0, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void operator delete[](void *ptr, | ||
| std::align_val_t align) NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::NewArray, 0, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void operator delete(void *ptr, std::align_val_t align, | ||
| std::nothrow_t const &)NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::New, 0, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void operator delete[](void *ptr, std::align_val_t align, | ||
| std::nothrow_t const &) NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::NewArray, 0, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void operator delete(void *ptr, size_t size, | ||
| std::align_val_t align)NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::New, size, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
| INTERFACE WEAK void operator delete[](void *ptr, size_t size, | ||
| std::align_val_t align) NOEXCEPT { | ||
| AllocatorPtr->deallocate(ptr, scudo::Chunk::Origin::NewArray, size, | ||
| static_cast<scudo::uptr>(align)); | ||
| } | ||
|
|
||
| #endif // !SCUDO_ANDROID || !_BIONIC |