| 459 | } |
| 460 | |
| 461 | bool Replay(const spv_target_env& target_env, |
| 462 | spv_const_fuzzer_options fuzzer_options, |
| 463 | spv_validator_options validator_options, |
| 464 | const std::vector<uint32_t>& binary_in, |
| 465 | const spvtools::fuzz::protobufs::FactSequence& initial_facts, |
| 466 | const std::string& replay_transformations_file, |
| 467 | std::vector<uint32_t>* binary_out, |
| 468 | spvtools::fuzz::protobufs::TransformationSequence* |
| 469 | transformations_applied) { |
| 470 | spvtools::fuzz::protobufs::TransformationSequence transformation_sequence; |
| 471 | if (!ParseTransformations(replay_transformations_file, |
| 472 | &transformation_sequence)) { |
| 473 | return false; |
| 474 | } |
| 475 | |
| 476 | uint32_t num_transformations_to_apply; |
| 477 | if (fuzzer_options->replay_range > 0) { |
| 478 | // We have a positive replay range, N. We would like transformations |
| 479 | // [0, N), truncated to the number of available transformations if N is too |
| 480 | // large. |
| 481 | num_transformations_to_apply = static_cast<uint32_t>( |
| 482 | std::min(fuzzer_options->replay_range, |
| 483 | transformation_sequence.transformation_size())); |
| 484 | } else { |
| 485 | // We have non-positive replay range, -N (where N may be 0). We would like |
| 486 | // transformations [0, num_transformations - N), or no transformations if N |
| 487 | // is too large. |
| 488 | num_transformations_to_apply = static_cast<uint32_t>( |
| 489 | std::max(0, transformation_sequence.transformation_size() + |
| 490 | fuzzer_options->replay_range)); |
| 491 | } |
| 492 | |
| 493 | auto replay_result = |
| 494 | spvtools::fuzz::Replayer( |
| 495 | target_env, spvtools::utils::CLIMessageConsumer, binary_in, |
| 496 | initial_facts, transformation_sequence, num_transformations_to_apply, |
| 497 | fuzzer_options->replay_validation_enabled, validator_options) |
| 498 | .Run(); |
| 499 | replay_result.transformed_module->module()->ToBinary(binary_out, false); |
| 500 | *transformations_applied = std::move(replay_result.applied_transformations); |
| 501 | return replay_result.status == |
| 502 | spvtools::fuzz::Replayer::ReplayerResultStatus::kComplete; |
| 503 | } |
| 504 | |
| 505 | bool Shrink(const spv_target_env& target_env, |
| 506 | spv_const_fuzzer_options fuzzer_options, |