diff options
author | Vasyl Teliman <vasniktel@gmail.com> | 2021-03-03 18:34:53 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-03 18:34:53 +0300 |
commit | 43cfa9bc1ddbe8bf0729fed3ac44da9bf37b3854 (patch) | |
tree | 88b3e5177329ebcaee09577d24db2415ab1a6a38 /tools | |
parent | 939bc02603933200da5e375cb33f3a381472861c (diff) |
spirv-fuzz: Add persistent state to the fuzzer (#4137)
Adds persistent state to the fuzzer so that it can be used as a custom
mutator for mutation-based fuzzing.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/fuzz/fuzz.cpp | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/tools/fuzz/fuzz.cpp b/tools/fuzz/fuzz.cpp index 3423f6c9c..a93d26acf 100644 --- a/tools/fuzz/fuzz.cpp +++ b/tools/fuzz/fuzz.cpp @@ -204,7 +204,7 @@ FuzzStatus ParseFlags( std::vector<std::string>* interestingness_test, std::string* shrink_transformations_file, std::string* shrink_temp_file_prefix, - spvtools::fuzz::Fuzzer::RepeatedPassStrategy* repeated_pass_strategy, + spvtools::fuzz::RepeatedPassStrategy* repeated_pass_strategy, spvtools::FuzzerOptions* fuzzer_options, spvtools::ValidatorOptions* validator_options) { uint32_t positional_arg_index = 0; @@ -212,7 +212,7 @@ FuzzStatus ParseFlags( bool force_render_red = false; *repeated_pass_strategy = - spvtools::fuzz::Fuzzer::RepeatedPassStrategy::kLoopedWithRecommendations; + spvtools::fuzz::RepeatedPassStrategy::kLoopedWithRecommendations; for (int argi = 1; argi < argc; ++argi) { const char* cur_arg = argv[argi]; @@ -250,14 +250,14 @@ FuzzStatus ParseFlags( sizeof("--repeated-pass-strategy=") - 1)) { std::string strategy = spvtools::utils::SplitFlagArgs(cur_arg).second; if (strategy == "looped") { - *repeated_pass_strategy = spvtools::fuzz::Fuzzer:: - RepeatedPassStrategy::kLoopedWithRecommendations; + *repeated_pass_strategy = + spvtools::fuzz::RepeatedPassStrategy::kLoopedWithRecommendations; } else if (strategy == "random") { - *repeated_pass_strategy = spvtools::fuzz::Fuzzer:: - RepeatedPassStrategy::kRandomWithRecommendations; + *repeated_pass_strategy = + spvtools::fuzz::RepeatedPassStrategy::kRandomWithRecommendations; } else if (strategy == "simple") { *repeated_pass_strategy = - spvtools::fuzz::Fuzzer::RepeatedPassStrategy::kSimple; + spvtools::fuzz::RepeatedPassStrategy::kSimple; } else { std::stringstream ss; ss << "Unknown repeated pass strategy '" << strategy << "'" @@ -549,7 +549,7 @@ bool Fuzz(const spv_target_env& target_env, const std::vector<uint32_t>& binary_in, const spvtools::fuzz::protobufs::FactSequence& initial_facts, const std::string& donors, - spvtools::fuzz::Fuzzer::RepeatedPassStrategy repeated_pass_strategy, + spvtools::fuzz::RepeatedPassStrategy repeated_pass_strategy, std::vector<uint32_t>* binary_out, spvtools::fuzz::protobufs::TransformationSequence* transformations_applied) { @@ -578,24 +578,42 @@ bool Fuzz(const spv_target_env& target_env, }); } - auto fuzz_result = - spvtools::fuzz::Fuzzer( - target_env, message_consumer, binary_in, initial_facts, - donor_suppliers, - spvtools::MakeUnique<spvtools::fuzz::PseudoRandomGenerator>( - fuzzer_options->has_random_seed - ? fuzzer_options->random_seed - : static_cast<uint32_t>(std::random_device()())), - fuzzer_options->all_passes_enabled, repeated_pass_strategy, - fuzzer_options->fuzzer_pass_validation_enabled, validator_options) - .Run(); - *binary_out = std::move(fuzz_result.transformed_binary); - *transformations_applied = std::move(fuzz_result.applied_transformations); - if (fuzz_result.status != - spvtools::fuzz::Fuzzer::FuzzerResultStatus::kComplete) { + std::unique_ptr<spvtools::opt::IRContext> ir_context; + if (!spvtools::fuzz::fuzzerutil::BuildIRContext(target_env, message_consumer, + binary_in, validator_options, + &ir_context)) { + spvtools::Error(FuzzDiagnostic, nullptr, {}, "Initial binary is invalid"); + return false; + } + + auto fuzzer_context = spvtools::MakeUnique<spvtools::fuzz::FuzzerContext>( + spvtools::MakeUnique<spvtools::fuzz::PseudoRandomGenerator>( + fuzzer_options->has_random_seed + ? fuzzer_options->random_seed + : static_cast<uint32_t>(std::random_device()())), + spvtools::fuzz::FuzzerContext::GetMinFreshId(ir_context.get())); + + auto transformation_context = + spvtools::MakeUnique<spvtools::fuzz::TransformationContext>( + spvtools::MakeUnique<spvtools::fuzz::FactManager>(ir_context.get()), + validator_options); + transformation_context->GetFactManager()->AddInitialFacts(message_consumer, + initial_facts); + + spvtools::fuzz::Fuzzer fuzzer( + std::move(ir_context), std::move(transformation_context), + std::move(fuzzer_context), message_consumer, donor_suppliers, + fuzzer_options->all_passes_enabled, repeated_pass_strategy, + fuzzer_options->fuzzer_pass_validation_enabled, validator_options); + auto fuzz_result = fuzzer.Run(0); + if (fuzz_result.status == + spvtools::fuzz::Fuzzer::Status::kFuzzerPassLedToInvalidModule) { spvtools::Error(FuzzDiagnostic, nullptr, {}, "Error running fuzzer"); return false; } + + fuzzer.GetIRContext()->module()->ToBinary(binary_out, true); + *transformations_applied = fuzzer.GetTransformationSequence(); return true; } @@ -656,7 +674,7 @@ int main(int argc, const char** argv) { std::vector<std::string> interestingness_test; std::string shrink_transformations_file; std::string shrink_temp_file_prefix = "temp_"; - spvtools::fuzz::Fuzzer::RepeatedPassStrategy repeated_pass_strategy; + spvtools::fuzz::RepeatedPassStrategy repeated_pass_strategy; spvtools::FuzzerOptions fuzzer_options; spvtools::ValidatorOptions validator_options; |