Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorVasyl Teliman <vasniktel@gmail.com>2021-03-03 18:34:53 +0300
committerGitHub <noreply@github.com>2021-03-03 18:34:53 +0300
commit43cfa9bc1ddbe8bf0729fed3ac44da9bf37b3854 (patch)
tree88b3e5177329ebcaee09577d24db2415ab1a6a38 /tools
parent939bc02603933200da5e375cb33f3a381472861c (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.cpp66
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;