fuzz: Link all targets once

This commit is contained in:
MarcoFalke
2020-12-03 16:42:49 +01:00
parent 751ffaabad
commit 44444ba759
97 changed files with 434 additions and 1306 deletions

View File

@@ -5,6 +5,7 @@
#include <test/fuzz/fuzz.h>
#include <test/util/setup_common.h>
#include <util/check.h>
#include <cstdint>
#include <unistd.h>
@@ -12,6 +13,36 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>>& FuzzTargets()
{
static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>> g_fuzz_targets;
return g_fuzz_targets;
}
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init)
{
const auto it_ins = FuzzTargets().try_emplace(name, std::move(target), std::move(init));
Assert(it_ins.second);
}
static TypeTestOneInput* g_test_one_input{nullptr};
void initialize()
{
if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) {
for (const auto& t : FuzzTargets()) {
std::cout << t.first << std::endl;
}
Assert(false);
}
std::string_view fuzz_target{Assert(std::getenv("FUZZ"))};
const auto it = FuzzTargets().find(fuzz_target);
Assert(it != FuzzTargets().end());
Assert(!g_test_one_input);
g_test_one_input = &std::get<0>(it->second);
std::get<1>(it->second)();
}
#if defined(PROVIDE_MAIN_FUNCTION)
static bool read_stdin(std::vector<uint8_t>& data)
{
@@ -24,14 +55,10 @@ static bool read_stdin(std::vector<uint8_t>& data)
}
#endif
// Default initialization: Override using a non-weak initialize().
__attribute__((weak)) void initialize()
{
}
// This function is used by libFuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
static const auto& test_one_input = *Assert(g_test_one_input);
const std::vector<uint8_t> input(data, data + size);
test_one_input(input);
return 0;
@@ -48,6 +75,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
__attribute__((weak)) int main(int argc, char** argv)
{
initialize();
static const auto& test_one_input = *Assert(g_test_one_input);
#ifdef __AFL_INIT
// Enable AFL deferred forkserver mode. Requires compilation using
// afl-clang-fast++. See fuzzing.md for details.