| 21 | #include "test/fuzzers/random_generator.h" |
| 22 | |
| 23 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
| 24 | if (size == 0 || (size % sizeof(uint32_t)) != 0) { |
| 25 | // An empty binary, or a binary whose size is not a multiple of word-size, |
| 26 | // cannot be valid, so can be rejected immediately. |
| 27 | return 0; |
| 28 | } |
| 29 | |
| 30 | std::vector<uint32_t> initial_binary(size / sizeof(uint32_t)); |
| 31 | memcpy(initial_binary.data(), data, size); |
| 32 | |
| 33 | spvtools::ValidatorOptions validator_options; |
| 34 | |
| 35 | spvtools::MessageConsumer message_consumer = |
| 36 | [](spv_message_level_t, const char*, const spv_position_t&, const char*) { |
| 37 | }; |
| 38 | |
| 39 | spvtools::fuzzers::RandomGenerator random_gen(data, size); |
| 40 | auto target_env = random_gen.GetTargetEnv(); |
| 41 | std::unique_ptr<spvtools::opt::IRContext> ir_context; |
| 42 | if (!spvtools::fuzz::fuzzerutil::BuildIRContext( |
| 43 | target_env, message_consumer, initial_binary, validator_options, |
| 44 | &ir_context)) { |
| 45 | // The input is invalid - give up. |
| 46 | return 0; |
| 47 | } |
| 48 | |
| 49 | std::vector<spvtools::fuzz::fuzzerutil::ModuleSupplier> donor_suppliers = { |
| 50 | [&initial_binary, message_consumer, target_env, |
| 51 | &validator_options]() -> std::unique_ptr<spvtools::opt::IRContext> { |
| 52 | std::unique_ptr<spvtools::opt::IRContext> result; |
| 53 | if (!spvtools::fuzz::fuzzerutil::BuildIRContext( |
| 54 | target_env, message_consumer, initial_binary, validator_options, |
| 55 | &result)) { |
| 56 | // The input was successfully parsed and validated first time around, |
| 57 | // so something is wrong if it is now invalid. |
| 58 | abort(); |
| 59 | } |
| 60 | return result; |
| 61 | }}; |
| 62 | |
| 63 | uint32_t seed = random_gen.GetUInt32(std::numeric_limits<uint32_t>::max()); |
| 64 | auto fuzzer_context = spvtools::MakeUnique<spvtools::fuzz::FuzzerContext>( |
| 65 | spvtools::MakeUnique<spvtools::fuzz::PseudoRandomGenerator>(seed), |
| 66 | spvtools::fuzz::FuzzerContext::GetMinFreshId(ir_context.get()), false); |
| 67 | |
| 68 | auto transformation_context = |
| 69 | spvtools::MakeUnique<spvtools::fuzz::TransformationContext>( |
| 70 | spvtools::MakeUnique<spvtools::fuzz::FactManager>(ir_context.get()), |
| 71 | validator_options); |
| 72 | |
| 73 | spvtools::fuzz::Fuzzer fuzzer( |
| 74 | std::move(ir_context), std::move(transformation_context), |
| 75 | std::move(fuzzer_context), message_consumer, donor_suppliers, false, |
| 76 | spvtools::fuzz::RepeatedPassStrategy::kLoopedWithRecommendations, true, |
| 77 | validator_options); |
| 78 | fuzzer.Run(0); |
| 79 | return 0; |
| 80 | } |
nothing calls this directly
no test coverage detected