summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/fuzzing.h (renamed from src/tools/translate-to-fuzz.h)96
-rw-r--r--src/tools/wasm-opt.cpp13
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";