From 35cf3f3132ab82e85feb14717412fe015b8e8389 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Wed, 24 Jan 2024 15:55:44 -0800 Subject: [PATCH] MacOS fixes --- CMakeLists.txt | 27 +++++++++++---------------- ConflictSet.cpp | 47 +++++++++++++++++++++++++++++++---------------- TestDriver.cpp | 2 +- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73a4747..829c8e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,8 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) "MinSizeRel" "RelWithDebInfo") endif() -add_compile_options(-fdata-sections -ffunction-sections) +add_compile_options(-fdata-sections -ffunction-sections + -Wno-return-stack-address) if(APPLE) add_link_options(-Wl,-dead_strip) else() @@ -54,19 +55,13 @@ target_link_options(${PROJECT_NAME} PRIVATE $<$>: add_library(${PROJECT_NAME}_static STATIC ConflictSet.cpp) target_compile_options(conflict_set_static PRIVATE -fno-exceptions -fvisibility=hidden) -add_custom_command( - TARGET conflict_set_static - POST_BUILD - COMMAND - ${CMAKE_OBJCOPY} --keep-global-symbols=${CMAKE_SOURCE_DIR}/symbols.txt - $) - -if(APPLE) - target_link_options( - ${PROJECT_NAME} - PRIVATE - "LINKER:-no_weak_exports,-exported_symbols_list,${CMAKE_SOURCE_DIR}/symbols.txt" - ) +if(NOT APPLE AND CMAKE_OBJCOPY) + add_custom_command( + TARGET conflict_set_static + POST_BUILD + COMMAND + ${CMAKE_OBJCOPY} --keep-global-symbols=${CMAKE_SOURCE_DIR}/symbols.txt + $) endif() set(TEST_FLAGS -Wall -Wextra -Wpedantic -Wunreachable-code -UNDEBUG) @@ -82,8 +77,8 @@ target_compile_definitions(conflict_set_main PRIVATE ENABLE_MAIN) set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined") include(CheckCXXCompilerFlag) cmake_push_check_state() -set(CMAKE_REQUIRED_LINK_OPTIONS ${FUZZ_FLAGS}) -check_cxx_compiler_flag(${FUZZ_FLAGS} HAS_LIB_FUZZER) +set(CMAKE_REQUIRED_LINK_OPTIONS -fsanitize=fuzzer) +check_cxx_compiler_flag(-fsanitize=fuzzer HAS_LIB_FUZZER) cmake_pop_check_state() if(HAS_LIB_FUZZER) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 3eacfe1..b383257 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -32,6 +32,8 @@ __attribute__((always_inline)) inline void *safe_malloc(size_t s) { // ==================== BEGIN ARENA IMPL ==================== +namespace { + /// Group allocations with similar lifetimes to amortize the cost of malloc/free struct Arena { explicit Arena(int initialSize = 0); @@ -43,34 +45,37 @@ struct Arena { Arena(Arena &&other) noexcept; Arena &operator=(Arena &&other) noexcept; -private: ArenaImpl *impl = nullptr; - friend void *operator new(size_t size, std::align_val_t align, Arena &arena); }; +} // namespace -inline void operator delete(void *, std::align_val_t, Arena &) {} -void *operator new(size_t size, std::align_val_t align, Arena &arena); +[[maybe_unused]] inline void operator delete(void *, std::align_val_t, + Arena &) {} +inline void *operator new(size_t size, std::align_val_t align, Arena &arena); void *operator new(size_t size, std::align_val_t align, Arena *arena) = delete; -inline void operator delete(void *, Arena &) {} +[[maybe_unused]] inline void operator delete(void *, Arena &) {} inline void *operator new(size_t size, Arena &arena) { return operator new(size, std::align_val_t(alignof(std::max_align_t)), arena); } inline void *operator new(size_t size, Arena *arena) = delete; -inline void operator delete[](void *, Arena &) {} +[[maybe_unused]] inline void operator delete[](void *, Arena &) {} inline void *operator new[](size_t size, Arena &arena) { return operator new(size, arena); } inline void *operator new[](size_t size, Arena *arena) = delete; -inline void operator delete[](void *, std::align_val_t, Arena &) {} +[[maybe_unused]] inline void operator delete[](void *, std::align_val_t, + Arena &) {} inline void *operator new[](size_t size, std::align_val_t align, Arena &arena) { return operator new(size, align, arena); } inline void *operator new[](size_t size, std::align_val_t align, Arena *arena) = delete; +namespace { + /// align must be a power of two template T *align_up(T *t, size_t align) { auto unaligned = uintptr_t(t); @@ -85,7 +90,7 @@ constexpr inline int align_up(uint32_t unaligned, uint32_t align) { } /// Returns the smallest power of two >= x -constexpr inline uint32_t nextPowerOfTwo(uint32_t x) { +[[maybe_unused]] constexpr inline uint32_t nextPowerOfTwo(uint32_t x) { return x <= 1 ? 1 : 1 << (32 - __builtin_clz(x - 1)); } @@ -127,7 +132,9 @@ Arena &Arena::operator=(Arena &&other) noexcept { Arena::~Arena() { onDestroy(impl); } -void *operator new(size_t size, std::align_val_t align, Arena &arena) { +} // namespace + +inline void *operator new(size_t size, std::align_val_t align, Arena &arena) { int64_t aligned_size = size + size_t(align) - 1; if (arena.impl == nullptr || (arena.impl->capacity - arena.impl->used) < aligned_size) { @@ -151,6 +158,8 @@ void *operator new(size_t size, std::align_val_t align, Arena &arena) { return result; } +namespace { + /// STL-friendly allocator using an arena template struct ArenaAlloc { typedef T value_type; @@ -195,10 +204,14 @@ bool operator!=(const ArenaAlloc &lhs, const ArenaAlloc &rhs) { return !(lhs == rhs); } +} // namespace + // ==================== END ARENA IMPL ==================== // ==================== BEGIN ARBITRARY IMPL ==================== +namespace { + /// Think of `Arbitrary` as an attacker-controlled random number generator. /// Usually you want your random number generator to be fair, so that you can /// sensibly analyze probabilities. E.g. The analysis that shows that quicksort @@ -313,6 +326,8 @@ uint32_t Arbitrary::bounded(uint32_t s) { } } +} // namespace + // ==================== END ARBITRARY IMPL ==================== // ==================== BEGIN UTILITIES IMPL ==================== @@ -412,7 +427,7 @@ struct ReferenceImpl { using Key = ConflictSet::Key; -Key toKey(Arena &arena, int n) { +[[maybe_unused]] Key toKey(Arena &arena, int n) { constexpr int kMaxLength = 8; int i = kMaxLength; uint8_t *itoaBuf = new (arena) uint8_t[kMaxLength]; @@ -424,7 +439,7 @@ Key toKey(Arena &arena, int n) { return Key{itoaBuf, kMaxLength}; } -Key toKeyAfter(Arena &arena, int n) { +[[maybe_unused]] Key toKeyAfter(Arena &arena, int n) { constexpr int kMaxLength = 8; int i = kMaxLength; uint8_t *itoaBuf = new (arena) uint8_t[kMaxLength + 1]; @@ -443,6 +458,8 @@ Key toKeyAfter(Arena &arena, int n) { // GCOVR_EXCL_STOP +namespace { + struct Entry { int64_t pointVersion; int64_t rangeVersion; @@ -619,7 +636,7 @@ int lastNonNeg1(const int8_t x[16]) { } #endif -Node *getChild(Node *self, uint8_t index) { +[[maybe_unused]] Node *getChild(Node *self, uint8_t index) { if (self->type == Type::Node4) { auto *self4 = static_cast(self); int i = getNodeIndex(self4, index); @@ -955,7 +972,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index) { } // Precondition - an entry for index must exist in the node -void eraseChild(Node *self, uint8_t index) { +[[maybe_unused]] void eraseChild(Node *self, uint8_t index) { if (self->type == Type::Node4) { auto *self4 = static_cast(self); int nodeIndex = getNodeIndex(self4, index); @@ -1042,9 +1059,7 @@ struct Iterator { int cmp; }; -namespace { std::string_view getSearchPath(Arena &arena, Node *n); -} Iterator lastLeq(Node *n, const std::span key) { auto remaining = key; @@ -1113,9 +1128,9 @@ void insert(Node **self_, std::span key, int64_t writeVersion) { } } -namespace { std::string printable(std::string_view key); std::string printable(const Key &key); + } // namespace struct __attribute__((visibility("hidden"))) ConflictSet::Impl { diff --git a/TestDriver.cpp b/TestDriver.cpp index 48ec19c..a05c364 100644 --- a/TestDriver.cpp +++ b/TestDriver.cpp @@ -10,7 +10,7 @@ int main(int argc, char **argv) { std::ifstream t(argv[i], std::ios::binary); std::stringstream buffer; buffer << t.rdbuf(); - auto str = buffer.view(); + auto str = buffer.str(); LLVMFuzzerTestOneInput((const uint8_t *)str.data(), str.size()); } }