| 560 | } |
| 561 | |
| 562 | bool Fuzz(const spv_target_env& target_env, |
| 563 | spv_const_fuzzer_options fuzzer_options, |
| 564 | spv_validator_options validator_options, |
| 565 | const std::vector<uint32_t>& binary_in, |
| 566 | const spvtools::fuzz::protobufs::FactSequence& initial_facts, |
| 567 | const std::string& donors, |
| 568 | spvtools::fuzz::RepeatedPassStrategy repeated_pass_strategy, |
| 569 | FuzzingTarget fuzzing_target, std::vector<uint32_t>* binary_out, |
| 570 | spvtools::fuzz::protobufs::TransformationSequence* |
| 571 | transformations_applied) { |
| 572 | auto message_consumer = spvtools::utils::CLIMessageConsumer; |
| 573 | |
| 574 | std::vector<spvtools::fuzz::fuzzerutil::ModuleSupplier> donor_suppliers; |
| 575 | |
| 576 | std::ifstream donors_file(donors); |
| 577 | if (!donors_file) { |
| 578 | spvtools::Error(FuzzDiagnostic, nullptr, {}, "Error opening donors file"); |
| 579 | return false; |
| 580 | } |
| 581 | std::string donor_filename; |
| 582 | while (std::getline(donors_file, donor_filename)) { |
| 583 | donor_suppliers.emplace_back( |
| 584 | [donor_filename, message_consumer, |
| 585 | target_env]() -> std::unique_ptr<spvtools::opt::IRContext> { |
| 586 | std::vector<uint32_t> donor_binary; |
| 587 | if (!ReadBinaryFile(donor_filename.c_str(), &donor_binary)) { |
| 588 | return nullptr; |
| 589 | } |
| 590 | return spvtools::BuildModule(target_env, message_consumer, |
| 591 | donor_binary.data(), |
| 592 | donor_binary.size()); |
| 593 | }); |
| 594 | } |
| 595 | |
| 596 | std::unique_ptr<spvtools::opt::IRContext> ir_context; |
| 597 | if (!spvtools::fuzz::fuzzerutil::BuildIRContext(target_env, message_consumer, |
| 598 | binary_in, validator_options, |
| 599 | &ir_context)) { |
| 600 | spvtools::Error(FuzzDiagnostic, nullptr, {}, "Initial binary is invalid"); |
| 601 | return false; |
| 602 | } |
| 603 | |
| 604 | assert((fuzzing_target == FuzzingTarget::kWgsl || |
| 605 | fuzzing_target == FuzzingTarget::kSpirv) && |
| 606 | "Not all fuzzing targets are handled"); |
| 607 | auto fuzzer_context = spvtools::MakeUnique<spvtools::fuzz::FuzzerContext>( |
| 608 | spvtools::MakeUnique<spvtools::fuzz::PseudoRandomGenerator>( |
| 609 | fuzzer_options->has_random_seed |
| 610 | ? fuzzer_options->random_seed |
| 611 | : static_cast<uint32_t>(std::random_device()())), |
| 612 | spvtools::fuzz::FuzzerContext::GetMinFreshId(ir_context.get()), |
| 613 | fuzzing_target == FuzzingTarget::kWgsl); |
| 614 | |
| 615 | auto transformation_context = |
| 616 | spvtools::MakeUnique<spvtools::fuzz::TransformationContext>( |
| 617 | spvtools::MakeUnique<spvtools::fuzz::FactManager>(ir_context.get()), |
| 618 | validator_options); |
| 619 | transformation_context->GetFactManager()->AddInitialFacts(message_consumer, |
no test coverage detected