diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-08-19 14:03:37 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2017-08-25 16:04:24 -0700 |
commit | db3adf6c6a6a34bb23f0a91a7fad568dfa906062 (patch) | |
tree | d3caff8013649684e62830d28f0da6a2a3878366 /src | |
parent | f3d59ea84e899f2b1cca9c1c7d23c80260b0df04 (diff) | |
download | binaryen-db3adf6c6a6a34bb23f0a91a7fad568dfa906062.tar.gz binaryen-db3adf6c6a6a34bb23f0a91a7fad568dfa906062.tar.bz2 binaryen-db3adf6c6a6a34bb23f0a91a7fad568dfa906062.zip |
add an option to run an extra command when fuzzing in wasm-opt
for now this is linux-only as it uses popen etc.
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm-opt.cpp | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index c34331366..a66bc612f 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -39,6 +39,23 @@ using namespace wasm; +// runs a command and returns its output TODO: portability, return code checking +std::string runCommand(std::string command) { +#ifdef __linux__ + std::string output; + const int MAX_BUFFER = 1024; + char buffer[MAX_BUFFER]; + FILE *stream = popen(command.c_str(), "r"); + while (fgets(buffer, MAX_BUFFER, stream) != NULL) { + output.append(buffer); + } + pclose(stream); + return output; +#else + Fatal() << "TODO: portability for wasm-opt runCommand"; +#endif +} + // // main // @@ -50,6 +67,7 @@ int main(int argc, const char* argv[]) { bool debugInfo = false; bool fuzzExec = false; bool fuzzBinary = false; + std::string extraFuzzCommand; bool translateToFuzz = false; std::string emitJSWrapper; std::string emitSpecWrapper; @@ -74,6 +92,9 @@ int main(int argc, const char* argv[]) { .add("--fuzz-binary", "-fb", "Convert to binary and back after optimizations and before fuzz-exec, helping fuzzing find binary format bugs", Options::Arguments::Zero, [&](Options *o, const std::string &arguments) { fuzzBinary = true; }) + .add("--extra-fuzz-command", "-efc", "An extra command to run on the output before and after optimizing. The output is compared between the two, and an error occurs if they are not equal", + Options::Arguments::One, + [&](Options *o, const std::string &arguments) { extraFuzzCommand = arguments; }) .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; }) @@ -123,6 +144,33 @@ int main(int argc, const char* argv[]) { results.get(wasm); } + if (emitJSWrapper.size() > 0) { + std::ofstream outfile; + outfile.open(emitJSWrapper, std::ofstream::out); + outfile << generateJSWrapper(wasm); + outfile.close(); + } + + if (emitSpecWrapper.size() > 0) { + std::ofstream outfile; + outfile.open(emitSpecWrapper, std::ofstream::out); + outfile << generateSpecWrapper(wasm); + outfile.close(); + } + + std::string firstOutput; + + if (extraFuzzCommand.size() > 0 && options.extra.count("output") > 0) { + if (options.debug) std::cerr << "writing binary before opts, for extra fuzz command..." << std::endl; + ModuleWriter writer; + writer.setDebug(options.debug); + writer.setBinary(emitBinary); + writer.setDebugInfo(debugInfo); + writer.write(wasm, options.extra["output"]); + firstOutput = runCommand(extraFuzzCommand); + std::cout << "[extra-fuzz-command first output:]\n" << firstOutput << '\n'; + } + if (options.runningPasses()) { if (options.debug) std::cerr << "running passes...\n"; PassRunner passRunner = options.getPassRunner(wasm); @@ -155,19 +203,14 @@ int main(int argc, const char* argv[]) { writer.setBinary(emitBinary); writer.setDebugInfo(debugInfo); writer.write(wasm, options.extra["output"]); - } - - if (emitJSWrapper.size() > 0) { - std::ofstream outfile; - outfile.open(emitJSWrapper, std::ofstream::out); - outfile << generateJSWrapper(wasm); - outfile.close(); - } - if (emitSpecWrapper.size() > 0) { - std::ofstream outfile; - outfile.open(emitSpecWrapper, std::ofstream::out); - outfile << generateSpecWrapper(wasm); - outfile.close(); + if (extraFuzzCommand.size() > 0) { + auto secondOutput = runCommand(extraFuzzCommand); + std::cout << "[extra-fuzz-command second output:]\n" << firstOutput << '\n'; + if (firstOutput != secondOutput) { + std::cerr << "extra fuzz command output differs\n"; + abort(); + } + } } } |