diff options
-rw-r--r-- | src/tools/fuzzing.h (renamed from src/tools/translate-to-fuzz.h) | 96 | ||||
-rw-r--r-- | src/tools/wasm-opt.cpp | 13 |
2 files changed, 85 insertions, 24 deletions
diff --git a/src/tools/translate-to-fuzz.h b/src/tools/fuzzing.h index b9aaea397..978d4e443 100644 --- a/src/tools/translate-to-fuzz.h +++ b/src/tools/fuzzing.h @@ -54,9 +54,7 @@ struct BinaryArgs { class TranslateToFuzzReader { public: - TranslateToFuzzReader(Module& wasm) : wasm(wasm), builder(wasm) {} - - void read(std::string& filename) { + TranslateToFuzzReader(Module& wasm, std::string& filename) : wasm(wasm), builder(wasm) { auto input(read_file<std::vector<char>>(filename, Flags::Binary, Flags::Release)); bytes.swap(input); pos = 0; @@ -65,7 +63,80 @@ public: if (bytes.size() == 0) { bytes.push_back(0); } - build(); + } + + void pickPasses(OptimizationOptions& options) { + while (options.passes.size() < 20 && !finishedInput && !oneIn(3)) { + switch (upTo(32)) { + case 0: + case 1: + case 2: + case 3: + case 4: { + options.passes.push_back("O"); + options.passOptions.optimizeLevel = upTo(4); + options.passOptions.shrinkLevel = upTo(4); + break; + } + case 5: options.passes.push_back("coalesce-locals"); break; + case 6: options.passes.push_back("code-pushing"); break; + case 7: options.passes.push_back("code-folding"); break; + case 8: options.passes.push_back("dce"); break; + case 9: options.passes.push_back("duplicate-function-elimination"); break; + case 10: options.passes.push_back("flatten"); break; + case 11: options.passes.push_back("inlining"); break; + case 12: options.passes.push_back("inlining-optimizing"); break; + case 13: options.passes.push_back("local-cse"); break; + case 14: options.passes.push_back("memory-packing"); break; + case 15: options.passes.push_back("merge-blocks"); break; + case 16: options.passes.push_back("optimize-instructions"); break; + case 17: options.passes.push_back("pick-load-signs"); break; + case 18: options.passes.push_back("precompute"); break; + case 19: options.passes.push_back("precompute-propagate"); break; + case 20: options.passes.push_back("remove-unused-brs"); break; + case 21: options.passes.push_back("remove-unused-module-elements"); break; + case 22: options.passes.push_back("remove-unused-names"); break; + case 23: options.passes.push_back("reorder-functions"); break; + case 24: options.passes.push_back("reorder-locals"); break; + case 25: { + options.passes.push_back("flatten"); + options.passes.push_back("rereloop"); + break; + } + case 26: options.passes.push_back("simplify-locals"); break; + case 27: options.passes.push_back("simplify-locals-notee"); break; + case 28: options.passes.push_back("simplify-locals-nostructure"); break; + case 29: options.passes.push_back("simplify-locals-notee-nostructure"); break; + case 30: options.passes.push_back("ssa"); break; + case 31: options.passes.push_back("vacuum"); break; + default: WASM_UNREACHABLE(); + } + } + if (oneIn(2)) { + options.passOptions.optimizeLevel = upTo(4); + } + if (oneIn(2)) { + options.passOptions.shrinkLevel = upTo(4); + } + std::cout << "opt level: " << options.passOptions.optimizeLevel << '\n'; + std::cout << "shrink level: " << options.passOptions.shrinkLevel << '\n'; + } + + void build() { + setupMemory(); + setupTable(); + setupGlobals(); + // keep adding functions until we run out of input + while (!finishedInput) { + addFunction(); + } + if (HANG_LIMIT > 0) { + addHangLimitSupport(); + } + if (DE_NAN) { + addDeNanSupport(); + } + finalizeTable(); } private: @@ -141,23 +212,6 @@ private: return Literal(get64()).reinterpretf64(); } - void build() { - setupMemory(); - setupTable(); - setupGlobals(); - // keep adding functions until we run out of input - while (!finishedInput) { - addFunction(); - } - if (HANG_LIMIT > 0) { - addHangLimitSupport(); - } - if (DE_NAN) { - addDeNanSupport(); - } - finalizeTable(); - } - void setupMemory() { wasm.memory.exists = true; // use one page diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index 91e1633f0..8fe55aef1 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -33,7 +33,7 @@ #include "shell-interface.h" #include "optimization-options.h" #include "execution-results.h" -#include "translate-to-fuzz.h" +#include "fuzzing.h" #include "js-wrapper.h" #include "spec-wrapper.h" @@ -68,6 +68,7 @@ int main(int argc, const char* argv[]) { bool fuzzBinary = false; std::string extraFuzzCommand; bool translateToFuzz = false; + bool fuzzPasses = false; std::string emitJSWrapper; std::string emitSpecWrapper; @@ -97,6 +98,9 @@ int main(int argc, const char* argv[]) { .add("--translate-to-fuzz", "-ttf", "Translate the input into a valid wasm module *somehow*, useful for fuzzing", Options::Arguments::Zero, [&](Options *o, const std::string &arguments) { translateToFuzz = true; }) + .add("--fuzz-passes", "-fp", "Pick a random set of passes to run, useful for fuzzing. this depends on translate-to-fuzz (it picks the passes from the input)", + Options::Arguments::Zero, + [&](Options *o, const std::string &arguments) { fuzzPasses = true; }) .add("--emit-js-wrapper", "-ejw", "Emit a JavaScript wrapper file that can run the wasm with some test values, useful for fuzzing", Options::Arguments::One, [&](Options *o, const std::string &arguments) { emitJSWrapper = arguments; }) @@ -134,8 +138,11 @@ int main(int argc, const char* argv[]) { } } else { // translate-to-fuzz - TranslateToFuzzReader reader(wasm); - reader.read(options.extra["infile"]); + TranslateToFuzzReader reader(wasm, options.extra["infile"]); + if (fuzzPasses) { + reader.pickPasses(options); + } + reader.build(); if (!WasmValidator().validate(wasm, features)) { WasmPrinter::printModule(&wasm); std::cerr << "translate-to-fuzz must always generate a valid module"; |