MacOS fixes
This commit is contained in:
@@ -21,7 +21,8 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|||||||
"MinSizeRel" "RelWithDebInfo")
|
"MinSizeRel" "RelWithDebInfo")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_compile_options(-fdata-sections -ffunction-sections)
|
add_compile_options(-fdata-sections -ffunction-sections
|
||||||
|
-Wno-return-stack-address)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
add_link_options(-Wl,-dead_strip)
|
add_link_options(-Wl,-dead_strip)
|
||||||
else()
|
else()
|
||||||
@@ -54,19 +55,13 @@ target_link_options(${PROJECT_NAME} PRIVATE $<$<NOT:$<CONFIG:Debug>>:
|
|||||||
add_library(${PROJECT_NAME}_static STATIC ConflictSet.cpp)
|
add_library(${PROJECT_NAME}_static STATIC ConflictSet.cpp)
|
||||||
target_compile_options(conflict_set_static PRIVATE -fno-exceptions
|
target_compile_options(conflict_set_static PRIVATE -fno-exceptions
|
||||||
-fvisibility=hidden)
|
-fvisibility=hidden)
|
||||||
add_custom_command(
|
if(NOT APPLE AND CMAKE_OBJCOPY)
|
||||||
TARGET conflict_set_static
|
add_custom_command(
|
||||||
POST_BUILD
|
TARGET conflict_set_static
|
||||||
COMMAND
|
POST_BUILD
|
||||||
${CMAKE_OBJCOPY} --keep-global-symbols=${CMAKE_SOURCE_DIR}/symbols.txt
|
COMMAND
|
||||||
$<TARGET_FILE:${PROJECT_NAME}_static>)
|
${CMAKE_OBJCOPY} --keep-global-symbols=${CMAKE_SOURCE_DIR}/symbols.txt
|
||||||
|
$<TARGET_FILE:${PROJECT_NAME}_static>)
|
||||||
if(APPLE)
|
|
||||||
target_link_options(
|
|
||||||
${PROJECT_NAME}
|
|
||||||
PRIVATE
|
|
||||||
"LINKER:-no_weak_exports,-exported_symbols_list,${CMAKE_SOURCE_DIR}/symbols.txt"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(TEST_FLAGS -Wall -Wextra -Wpedantic -Wunreachable-code -UNDEBUG)
|
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")
|
set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined")
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
cmake_push_check_state()
|
cmake_push_check_state()
|
||||||
set(CMAKE_REQUIRED_LINK_OPTIONS ${FUZZ_FLAGS})
|
set(CMAKE_REQUIRED_LINK_OPTIONS -fsanitize=fuzzer)
|
||||||
check_cxx_compiler_flag(${FUZZ_FLAGS} HAS_LIB_FUZZER)
|
check_cxx_compiler_flag(-fsanitize=fuzzer HAS_LIB_FUZZER)
|
||||||
cmake_pop_check_state()
|
cmake_pop_check_state()
|
||||||
|
|
||||||
if(HAS_LIB_FUZZER)
|
if(HAS_LIB_FUZZER)
|
||||||
|
@@ -32,6 +32,8 @@ __attribute__((always_inline)) inline void *safe_malloc(size_t s) {
|
|||||||
|
|
||||||
// ==================== BEGIN ARENA IMPL ====================
|
// ==================== BEGIN ARENA IMPL ====================
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/// Group allocations with similar lifetimes to amortize the cost of malloc/free
|
/// Group allocations with similar lifetimes to amortize the cost of malloc/free
|
||||||
struct Arena {
|
struct Arena {
|
||||||
explicit Arena(int initialSize = 0);
|
explicit Arena(int initialSize = 0);
|
||||||
@@ -43,34 +45,37 @@ struct Arena {
|
|||||||
Arena(Arena &&other) noexcept;
|
Arena(Arena &&other) noexcept;
|
||||||
Arena &operator=(Arena &&other) noexcept;
|
Arena &operator=(Arena &&other) noexcept;
|
||||||
|
|
||||||
private:
|
|
||||||
ArenaImpl *impl = nullptr;
|
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 &) {}
|
[[maybe_unused]] inline void operator delete(void *, std::align_val_t,
|
||||||
void *operator new(size_t size, std::align_val_t align, Arena &arena);
|
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;
|
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) {
|
inline void *operator new(size_t size, Arena &arena) {
|
||||||
return operator new(size, std::align_val_t(alignof(std::max_align_t)), 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 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) {
|
inline void *operator new[](size_t size, Arena &arena) {
|
||||||
return operator new(size, arena);
|
return operator new(size, arena);
|
||||||
}
|
}
|
||||||
inline void *operator new[](size_t size, Arena *arena) = delete;
|
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) {
|
inline void *operator new[](size_t size, std::align_val_t align, Arena &arena) {
|
||||||
return operator new(size, align, arena);
|
return operator new(size, align, arena);
|
||||||
}
|
}
|
||||||
inline void *operator new[](size_t size, std::align_val_t align,
|
inline void *operator new[](size_t size, std::align_val_t align,
|
||||||
Arena *arena) = delete;
|
Arena *arena) = delete;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/// align must be a power of two
|
/// align must be a power of two
|
||||||
template <class T> T *align_up(T *t, size_t align) {
|
template <class T> T *align_up(T *t, size_t align) {
|
||||||
auto unaligned = uintptr_t(t);
|
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
|
/// 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));
|
return x <= 1 ? 1 : 1 << (32 - __builtin_clz(x - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +132,9 @@ Arena &Arena::operator=(Arena &&other) noexcept {
|
|||||||
|
|
||||||
Arena::~Arena() { onDestroy(impl); }
|
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;
|
int64_t aligned_size = size + size_t(align) - 1;
|
||||||
if (arena.impl == nullptr ||
|
if (arena.impl == nullptr ||
|
||||||
(arena.impl->capacity - arena.impl->used) < aligned_size) {
|
(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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/// STL-friendly allocator using an arena
|
/// STL-friendly allocator using an arena
|
||||||
template <class T> struct ArenaAlloc {
|
template <class T> struct ArenaAlloc {
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
@@ -195,10 +204,14 @@ bool operator!=(const ArenaAlloc<T> &lhs, const ArenaAlloc<U> &rhs) {
|
|||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// ==================== END ARENA IMPL ====================
|
// ==================== END ARENA IMPL ====================
|
||||||
|
|
||||||
// ==================== BEGIN ARBITRARY IMPL ====================
|
// ==================== BEGIN ARBITRARY IMPL ====================
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/// Think of `Arbitrary` as an attacker-controlled random number generator.
|
/// Think of `Arbitrary` as an attacker-controlled random number generator.
|
||||||
/// Usually you want your random number generator to be fair, so that you can
|
/// 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
|
/// 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 ====================
|
// ==================== END ARBITRARY IMPL ====================
|
||||||
|
|
||||||
// ==================== BEGIN UTILITIES IMPL ====================
|
// ==================== BEGIN UTILITIES IMPL ====================
|
||||||
@@ -412,7 +427,7 @@ struct ReferenceImpl {
|
|||||||
|
|
||||||
using Key = ConflictSet::Key;
|
using Key = ConflictSet::Key;
|
||||||
|
|
||||||
Key toKey(Arena &arena, int n) {
|
[[maybe_unused]] Key toKey(Arena &arena, int n) {
|
||||||
constexpr int kMaxLength = 8;
|
constexpr int kMaxLength = 8;
|
||||||
int i = kMaxLength;
|
int i = kMaxLength;
|
||||||
uint8_t *itoaBuf = new (arena) uint8_t[kMaxLength];
|
uint8_t *itoaBuf = new (arena) uint8_t[kMaxLength];
|
||||||
@@ -424,7 +439,7 @@ Key toKey(Arena &arena, int n) {
|
|||||||
return Key{itoaBuf, kMaxLength};
|
return Key{itoaBuf, kMaxLength};
|
||||||
}
|
}
|
||||||
|
|
||||||
Key toKeyAfter(Arena &arena, int n) {
|
[[maybe_unused]] Key toKeyAfter(Arena &arena, int n) {
|
||||||
constexpr int kMaxLength = 8;
|
constexpr int kMaxLength = 8;
|
||||||
int i = kMaxLength;
|
int i = kMaxLength;
|
||||||
uint8_t *itoaBuf = new (arena) uint8_t[kMaxLength + 1];
|
uint8_t *itoaBuf = new (arena) uint8_t[kMaxLength + 1];
|
||||||
@@ -443,6 +458,8 @@ Key toKeyAfter(Arena &arena, int n) {
|
|||||||
|
|
||||||
// GCOVR_EXCL_STOP
|
// GCOVR_EXCL_STOP
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
int64_t pointVersion;
|
int64_t pointVersion;
|
||||||
int64_t rangeVersion;
|
int64_t rangeVersion;
|
||||||
@@ -619,7 +636,7 @@ int lastNonNeg1(const int8_t x[16]) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Node *getChild(Node *self, uint8_t index) {
|
[[maybe_unused]] Node *getChild(Node *self, uint8_t index) {
|
||||||
if (self->type == Type::Node4) {
|
if (self->type == Type::Node4) {
|
||||||
auto *self4 = static_cast<Node4 *>(self);
|
auto *self4 = static_cast<Node4 *>(self);
|
||||||
int i = getNodeIndex(self4, index);
|
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
|
// 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) {
|
if (self->type == Type::Node4) {
|
||||||
auto *self4 = static_cast<Node4 *>(self);
|
auto *self4 = static_cast<Node4 *>(self);
|
||||||
int nodeIndex = getNodeIndex(self4, index);
|
int nodeIndex = getNodeIndex(self4, index);
|
||||||
@@ -1042,9 +1059,7 @@ struct Iterator {
|
|||||||
int cmp;
|
int cmp;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::string_view getSearchPath(Arena &arena, Node *n);
|
std::string_view getSearchPath(Arena &arena, Node *n);
|
||||||
}
|
|
||||||
|
|
||||||
Iterator lastLeq(Node *n, const std::span<const uint8_t> key) {
|
Iterator lastLeq(Node *n, const std::span<const uint8_t> key) {
|
||||||
auto remaining = key;
|
auto remaining = key;
|
||||||
@@ -1113,9 +1128,9 @@ void insert(Node **self_, std::span<const uint8_t> key, int64_t writeVersion) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::string printable(std::string_view key);
|
std::string printable(std::string_view key);
|
||||||
std::string printable(const Key &key);
|
std::string printable(const Key &key);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||||
|
@@ -10,7 +10,7 @@ int main(int argc, char **argv) {
|
|||||||
std::ifstream t(argv[i], std::ios::binary);
|
std::ifstream t(argv[i], std::ios::binary);
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << t.rdbuf();
|
buffer << t.rdbuf();
|
||||||
auto str = buffer.view();
|
auto str = buffer.str();
|
||||||
LLVMFuzzerTestOneInput((const uint8_t *)str.data(), str.size());
|
LLVMFuzzerTestOneInput((const uint8_t *)str.data(), str.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user