summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-06-26 09:46:26 +0000
committerHans Wennborg <hans@hanshq.net>2019-06-26 09:46:26 +0000
commitaf22943ae6c32c530e26902fde27a668837e2909 (patch)
treee46cfd6b7c62de9ebff36773647447296f887133
parent56c8a0cb270bbbc3ed98cdc46cb365a4298aff05 (diff)
downloadcompiler-rt-af22943ae6c32c530e26902fde27a668837e2909.tar.gz
Revert r364332 "[scudo][standalone] Introduce the C & C++ wrappers"
Makes the build fail with e.g. llvm/projects/compiler-rt/lib/scudo/standalone/wrappers_c.inc:20:68: error: declaration of 'void* calloc(size_t, size_t)' has a different exception specifier INTERFACE WEAK void *SCUDO_PREFIX(calloc)(size_t nmemb, size_t size) { ^ See llvm-commits thread. > Summary: > This CL adds C & C++ wrappers and associated tests. Those use default > configurations for a Scudo combined allocator that will likely be > tweaked in the future. > > This is the final CL required to have a functional C & C++ allocator > based on Scudo. > > The structure I have chosen is to define the core C allocation > primitives in an `.inc` file that can be customized through defines. > This allows to easily have 2 (or more) sets of wrappers backed by > different combined allocators, as demonstrated by the `Bionic` > wrappers: one set for the "default" allocator, one set for the "svelte" > allocator. > > Currently all the tests added have been gtests, but I am planning to > add some more lit tests as well. > > Reviewers: morehouse, eugenis, vitalybuka, hctim, rengolin > > Reviewed By: morehouse > > Subscribers: srhines, mgorny, delcypher, jfb, #sanitizers, llvm-commits > > Tags: #llvm, #sanitizers > > Differential Revision: https://reviews.llvm.org/D63612 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@364400 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/scudo/standalone/CMakeLists.txt75
-rw-r--r--lib/scudo/standalone/tests/CMakeLists.txt44
-rw-r--r--lib/scudo/standalone/tests/wrappers_c_test.cc225
-rw-r--r--lib/scudo/standalone/tests/wrappers_cpp_test.cc117
-rw-r--r--lib/scudo/standalone/tsd.h5
-rw-r--r--lib/scudo/standalone/wrappers_c.cc39
-rw-r--r--lib/scudo/standalone/wrappers_c.h52
-rw-r--r--lib/scudo/standalone/wrappers_c.inc176
-rw-r--r--lib/scudo/standalone/wrappers_c_bionic.cc49
-rw-r--r--lib/scudo/standalone/wrappers_c_checks.h56
-rw-r--r--lib/scudo/standalone/wrappers_cpp.cc107
11 files changed, 36 insertions, 909 deletions
diff --git a/lib/scudo/standalone/CMakeLists.txt b/lib/scudo/standalone/CMakeLists.txt
index 027b04105..953acd8f4 100644
--- a/lib/scudo/standalone/CMakeLists.txt
+++ b/lib/scudo/standalone/CMakeLists.txt
@@ -33,6 +33,29 @@ if(ANDROID)
append_list_if(COMPILER_RT_HAS_Z_GLOBAL -Wl,-z,global SCUDO_LINK_FLAGS)
endif()
+set(SCUDO_SOURCES
+ checksum.cc
+ crc32_hw.cc
+ common.cc
+ flags.cc
+ flags_parser.cc
+ fuchsia.cc
+ linux.cc
+ report.cc
+ secondary.cc
+ string_utils.cc)
+
+# Enable the SSE 4.2 instruction set for crc32_hw.cc, if available.
+if (COMPILER_RT_HAS_MSSE4_2_FLAG)
+ set_source_files_properties(crc32_hw.cc PROPERTIES COMPILE_FLAGS -msse4.2)
+endif()
+
+# Enable the AArch64 CRC32 feature for crc32_hw.cc, if available.
+# Note that it is enabled by default starting with armv8.1-a.
+if (COMPILER_RT_HAS_MCRC_FLAG)
+ set_source_files_properties(crc32_hw.cc PROPERTIES COMPILE_FLAGS -mcrc)
+endif()
+
set(SCUDO_HEADERS
allocator_config.h
atomic_helpers.h
@@ -62,38 +85,7 @@ set(SCUDO_HEADERS
tsd.h
tsd_exclusive.h
tsd_shared.h
- vector.h
- wrappers_c_checks.h
- wrappers_c.h)
-
-set(SCUDO_SOURCES
- checksum.cc
- crc32_hw.cc
- common.cc
- flags.cc
- flags_parser.cc
- fuchsia.cc
- linux.cc
- report.cc
- secondary.cc
- string_utils.cc)
-
-# Enable the SSE 4.2 instruction set for crc32_hw.cc, if available.
-if (COMPILER_RT_HAS_MSSE4_2_FLAG)
- set_source_files_properties(crc32_hw.cc PROPERTIES COMPILE_FLAGS -msse4.2)
-endif()
-
-# Enable the AArch64 CRC32 feature for crc32_hw.cc, if available.
-# Note that it is enabled by default starting with armv8.1-a.
-if (COMPILER_RT_HAS_MCRC_FLAG)
- set_source_files_properties(crc32_hw.cc PROPERTIES COMPILE_FLAGS -mcrc)
-endif()
-
-set(SCUDO_SOURCES_C_WRAPPERS
- wrappers_c.cc)
-
-set(SCUDO_SOURCES_CXX_WRAPPERS
- wrappers_cpp.cc)
+ vector.h)
if(COMPILER_RT_HAS_SCUDO_STANDALONE)
add_compiler_rt_object_libraries(RTScudoStandalone
@@ -101,28 +93,11 @@ if(COMPILER_RT_HAS_SCUDO_STANDALONE)
SOURCES ${SCUDO_SOURCES}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS})
- add_compiler_rt_object_libraries(RTScudoStandaloneCWrappers
- ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES_C_WRAPPERS}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- CFLAGS ${SCUDO_CFLAGS})
- add_compiler_rt_object_libraries(RTScudoStandaloneCxxWrappers
- ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES_CXX_WRAPPERS}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- CFLAGS ${SCUDO_CFLAGS})
add_compiler_rt_runtime(clang_rt.scudo_standalone
STATIC
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES} ${SCUDO_SOURCES_C_WRAPPERS}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- CFLAGS ${SCUDO_CFLAGS}
- PARENT_TARGET scudo_standalone)
- add_compiler_rt_runtime(clang_rt.scudo_standalone_cxx
- STATIC
- ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES_CXX_WRAPPERS}
+ SOURCES ${SCUDO_SOURCES}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
PARENT_TARGET scudo_standalone)
diff --git a/lib/scudo/standalone/tests/CMakeLists.txt b/lib/scudo/standalone/tests/CMakeLists.txt
index f0c259a90..9167ba7c4 100644
--- a/lib/scudo/standalone/tests/CMakeLists.txt
+++ b/lib/scudo/standalone/tests/CMakeLists.txt
@@ -10,10 +10,7 @@ set(SCUDO_UNITTEST_CFLAGS
-I${COMPILER_RT_SOURCE_DIR}/include
-I${COMPILER_RT_SOURCE_DIR}/lib
-I${COMPILER_RT_SOURCE_DIR}/lib/scudo/standalone
- -DGTEST_HAS_RTTI=0
- # Extra flags for the C++ tests
- -fsized-deallocation
- -Wno-mismatched-new-delete)
+ -DGTEST_HAS_RTTI=0)
set(SCUDO_TEST_ARCH ${SCUDO_STANDALONE_SUPPORTED_ARCH})
@@ -24,30 +21,27 @@ foreach(lib ${SANITIZER_TEST_CXX_LIBRARIES})
endforeach()
list(APPEND LINK_FLAGS -pthread)
-set(SCUDO_TEST_HEADERS)
+set(TEST_HEADERS)
foreach (header ${SCUDO_HEADERS})
- list(APPEND SCUDO_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
+ list(APPEND TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
endforeach()
+# add_scudo_unittest(<name>
+# SOURCES <sources list>
+# HEADERS <extra headers list>)
macro(add_scudo_unittest testname)
- cmake_parse_arguments(TEST "" "" "SOURCES;ADDITIONAL_RTOBJECTS" ${ARGN})
+ cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
if(COMPILER_RT_HAS_SCUDO_STANDALONE)
foreach(arch ${SCUDO_TEST_ARCH})
- # Additional runtime objects get added along RTScudoStandalone
- set(SCUDO_TEST_RTOBJECTS $<TARGET_OBJECTS:RTScudoStandalone.${arch}>)
- foreach(rtobject ${TEST_ADDITIONAL_RTOBJECTS})
- list(APPEND SCUDO_TEST_RTOBJECTS $<TARGET_OBJECTS:${rtobject}.${arch}>)
- endforeach()
- # Add the static runtime library made of all the runtime objects
- set(RUNTIME RT${testname}.${arch})
- add_library(${RUNTIME} STATIC ${SCUDO_TEST_RTOBJECTS})
set(ScudoUnitTestsObjects)
+ add_library("RTScudoStandalone.test.${arch}" STATIC
+ $<TARGET_OBJECTS:RTScudoStandalone.${arch}>)
generate_compiler_rt_tests(ScudoUnitTestsObjects ScudoUnitTests
"${testname}-${arch}-Test" ${arch}
SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
- COMPILE_DEPS ${SCUDO_TEST_HEADERS}
+ COMPILE_DEPS ${TEST_HEADERS}
DEPS gtest scudo_standalone
- RUNTIME ${RUNTIME}
+ RUNTIME RTScudoStandalone.test.${arch}
CFLAGS ${SCUDO_UNITTEST_CFLAGS}
LINK_FLAGS ${LINK_FLAGS})
endforeach()
@@ -78,19 +72,3 @@ set(SCUDO_UNIT_TEST_SOURCES
add_scudo_unittest(ScudoUnitTest
SOURCES ${SCUDO_UNIT_TEST_SOURCES})
-
-set(SCUDO_C_UNIT_TEST_SOURCES
- wrappers_c_test.cc
- scudo_unit_test_main.cc)
-
-add_scudo_unittest(ScudoCUnitTest
- SOURCES ${SCUDO_C_UNIT_TEST_SOURCES}
- ADDITIONAL_RTOBJECTS RTScudoStandaloneCWrappers)
-
-set(SCUDO_CXX_UNIT_TEST_SOURCES
- wrappers_cpp_test.cc
- scudo_unit_test_main.cc)
-
-add_scudo_unittest(ScudoCxxUnitTest
- SOURCES ${SCUDO_CXX_UNIT_TEST_SOURCES}
- ADDITIONAL_RTOBJECTS RTScudoStandaloneCWrappers RTScudoStandaloneCxxWrappers)
diff --git a/lib/scudo/standalone/tests/wrappers_c_test.cc b/lib/scudo/standalone/tests/wrappers_c_test.cc
deleted file mode 100644
index a5ba80677..000000000
--- a/lib/scudo/standalone/tests/wrappers_c_test.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-//===-- wrappers_c_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 "platform.h"
-
-#include "gtest/gtest.h"
-
-#include <limits.h>
-#include <malloc.h>
-#include <unistd.h>
-
-// Note that every C allocation function in the test binary will be fulfilled
-// by Scudo (this includes the gtest APIs, etc.), which is a test by itself.
-// But this might also lead to unexpected side-effects, since the allocation and
-// deallocation operations in the TEST functions will coexist with others (see
-// the EXPECT_DEATH comment below).
-
-// We have to use a small quarantine to make sure that our double-free tests
-// trigger. Otherwise EXPECT_DEATH ends up reallocating the chunk that was just
-// freed (this depends on the size obviously) and the following free succeeds.
-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";
-}
-
-static const size_t Size = 100U;
-
-TEST(ScudoWrappersCTest, Malloc) {
- void *P = malloc(Size);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size, malloc_usable_size(P));
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) % FIRST_32_SECOND_64(8U, 16U), 0U);
- EXPECT_DEATH(
- free(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(P) | 1U)), "");
- free(P);
- EXPECT_DEATH(free(P), "");
-
- P = malloc(0U);
- EXPECT_NE(P, nullptr);
- free(P);
-
- errno = 0;
- EXPECT_EQ(malloc(SIZE_MAX), nullptr);
- EXPECT_EQ(errno, ENOMEM);
-}
-
-TEST(ScudoWrappersCTest, Calloc) {
- void *P = calloc(1U, Size);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size, malloc_usable_size(P));
- for (size_t I = 0; I < Size; I++)
- EXPECT_EQ((reinterpret_cast<uint8_t *>(P))[I], 0U);
- free(P);
-
- P = calloc(1U, 0U);
- EXPECT_NE(P, nullptr);
- free(P);
- P = calloc(0U, 1U);
- EXPECT_NE(P, nullptr);
- free(P);
-
- errno = 0;
- EXPECT_EQ(calloc(SIZE_MAX, 1U), nullptr);
- EXPECT_EQ(errno, ENOMEM);
- errno = 0;
- EXPECT_EQ(calloc(static_cast<size_t>(LONG_MAX) + 1U, 2U), nullptr);
- if (SCUDO_ANDROID)
- EXPECT_EQ(errno, ENOMEM);
- errno = 0;
- EXPECT_EQ(calloc(SIZE_MAX, SIZE_MAX), nullptr);
- EXPECT_EQ(errno, ENOMEM);
-}
-
-TEST(ScudoWrappersCTest, Memalign) {
- void *P;
- for (size_t I = FIRST_32_SECOND_64(2U, 3U); I <= 18U; I++) {
- const size_t Alignment = 1U << I;
-
- P = memalign(Alignment, Size);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size, malloc_usable_size(P));
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) % Alignment, 0U);
- free(P);
-
- P = nullptr;
- EXPECT_EQ(posix_memalign(&P, Alignment, Size), 0);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size, malloc_usable_size(P));
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) % Alignment, 0U);
- free(P);
- }
-
- EXPECT_EQ(memalign(4096U, SIZE_MAX), nullptr);
- EXPECT_EQ(posix_memalign(&P, 15U, Size), EINVAL);
- EXPECT_EQ(posix_memalign(&P, 4096U, SIZE_MAX), ENOMEM);
-
- // Android's memalign accepts non power-of-2 alignments, and 0.
- if (SCUDO_ANDROID) {
- for (size_t Alignment = 0U; Alignment <= 128U; Alignment++) {
- P = memalign(Alignment, 1024U);
- EXPECT_NE(P, nullptr);
- free(P);
- }
- }
-}
-
-TEST(ScudoWrappersCTest, AlignedAlloc) {
- const size_t Alignment = 4096U;
- void *P = aligned_alloc(Alignment, Alignment * 4U);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Alignment * 4U, malloc_usable_size(P));
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) % Alignment, 0U);
- free(P);
-
- errno = 0;
- P = aligned_alloc(Alignment, Size);
- EXPECT_EQ(P, nullptr);
- EXPECT_EQ(errno, EINVAL);
-}
-
-TEST(ScudoWrappersCTest, Realloc) {
- // realloc(nullptr, N) is malloc(N)
- void *P = realloc(nullptr, 0U);
- EXPECT_NE(P, nullptr);
- free(P);
-
- P = malloc(Size);
- EXPECT_NE(P, nullptr);
- // realloc(P, 0U) is free(P) and returns nullptr
- EXPECT_EQ(realloc(P, 0U), nullptr);
-
- P = malloc(Size);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size, malloc_usable_size(P));
- memset(P, 0x42, Size);
-
- P = realloc(P, Size * 2U);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size * 2U, malloc_usable_size(P));
- for (size_t I = 0; I < Size; I++)
- EXPECT_EQ(0x42, (reinterpret_cast<uint8_t *>(P))[I]);
-
- P = realloc(P, Size / 2U);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size / 2U, malloc_usable_size(P));
- for (size_t I = 0; I < Size / 2U; I++)
- EXPECT_EQ(0x42, (reinterpret_cast<uint8_t *>(P))[I]);
- free(P);
-
- EXPECT_DEATH(P = realloc(P, Size), "");
-
- errno = 0;
- EXPECT_EQ(realloc(nullptr, SIZE_MAX), nullptr);
- EXPECT_EQ(errno, ENOMEM);
- P = malloc(Size);
- EXPECT_NE(P, nullptr);
- errno = 0;
- EXPECT_EQ(realloc(P, SIZE_MAX), nullptr);
- EXPECT_EQ(errno, ENOMEM);
- free(P);
-
- // Android allows realloc of memalign pointers.
- if (SCUDO_ANDROID) {
- const size_t Alignment = 1024U;
- P = memalign(Alignment, Size);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size, malloc_usable_size(P));
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) % Alignment, 0U);
- memset(P, 0x42, Size);
-
- P = realloc(P, Size * 2U);
- EXPECT_NE(P, nullptr);
- EXPECT_LE(Size * 2U, malloc_usable_size(P));
- for (size_t I = 0; I < Size; I++)
- EXPECT_EQ(0x42, (reinterpret_cast<uint8_t *>(P))[I]);
- free(P);
- }
-}
-
-#ifndef M_DECAY_TIME
-#define M_DECAY_TIME -100
-#endif
-
-#ifndef M_PURGE
-#define M_PURGE -101
-#endif
-
-TEST(ScudoWrappersCTest, Mallopt) {
- errno = 0;
- EXPECT_EQ(mallopt(-1000, 1), 0);
- // mallopt doesn't set errno.
- EXPECT_EQ(errno, 0);
-
- EXPECT_EQ(mallopt(M_PURGE, 0), 1);
-
- EXPECT_EQ(mallopt(M_DECAY_TIME, 1), 1);
- EXPECT_EQ(mallopt(M_DECAY_TIME, 0), 1);
- EXPECT_EQ(mallopt(M_DECAY_TIME, 1), 1);
- EXPECT_EQ(mallopt(M_DECAY_TIME, 0), 1);
-}
-
-TEST(ScudoWrappersCTest, OtherAlloc) {
- const size_t PageSize = sysconf(_SC_PAGESIZE);
-
- void *P = pvalloc(Size);
- EXPECT_NE(P, nullptr);
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) & (PageSize - 1), 0U);
- EXPECT_LE(PageSize, malloc_usable_size(P));
- free(P);
-
- EXPECT_EQ(pvalloc(SIZE_MAX), nullptr);
-
- P = pvalloc(Size);
- EXPECT_NE(P, nullptr);
- EXPECT_EQ(reinterpret_cast<uintptr_t>(P) & (PageSize - 1), 0U);
- free(P);
-
- EXPECT_EQ(valloc(SIZE_MAX), nullptr);
-}
diff --git a/lib/scudo/standalone/tests/wrappers_cpp_test.cc b/lib/scudo/standalone/tests/wrappers_cpp_test.cc
deleted file mode 100644
index 8d5842a25..000000000
--- a/lib/scudo/standalone/tests/wrappers_cpp_test.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-//===-- 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();
-}
diff --git a/lib/scudo/standalone/tsd.h b/lib/scudo/standalone/tsd.h
index 10cb83f94..d3958ddfc 100644
--- a/lib/scudo/standalone/tsd.h
+++ b/lib/scudo/standalone/tsd.h
@@ -15,11 +15,6 @@
#include <limits.h> // for PTHREAD_DESTRUCTOR_ITERATIONS
-// With some build setups, this might still not be defined.
-#ifndef PTHREAD_DESTRUCTOR_ITERATIONS
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4
-#endif
-
namespace scudo {
template <class Allocator> struct ALIGNED(SCUDO_CACHE_LINE_SIZE) TSD {
diff --git a/lib/scudo/standalone/wrappers_c.cc b/lib/scudo/standalone/wrappers_c.cc
deleted file mode 100644
index 5908c600b..000000000
--- a/lib/scudo/standalone/wrappers_c.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- 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
diff --git a/lib/scudo/standalone/wrappers_c.h b/lib/scudo/standalone/wrappers_c.h
deleted file mode 100644
index 33a0c53ce..000000000
--- a/lib/scudo/standalone/wrappers_c.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- 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_
diff --git a/lib/scudo/standalone/wrappers_c.inc b/lib/scudo/standalone/wrappers_c.inc
deleted file mode 100644
index 2beddc724..000000000
--- a/lib/scudo/standalone/wrappers_c.inc
+++ /dev/null
@@ -1,176 +0,0 @@
-//===-- 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;
-}
diff --git a/lib/scudo/standalone/wrappers_c_bionic.cc b/lib/scudo/standalone/wrappers_c_bionic.cc
deleted file mode 100644
index f6e863deb..000000000
--- a/lib/scudo/standalone/wrappers_c_bionic.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- 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
diff --git a/lib/scudo/standalone/wrappers_c_checks.h b/lib/scudo/standalone/wrappers_c_checks.h
deleted file mode 100644
index d9de5b261..000000000
--- a/lib/scudo/standalone/wrappers_c_checks.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- 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_
diff --git a/lib/scudo/standalone/wrappers_cpp.cc b/lib/scudo/standalone/wrappers_cpp.cc
deleted file mode 100644
index 3ae1cdc05..000000000
--- a/lib/scudo/standalone/wrappers_cpp.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-//===-- 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