summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-08-19 14:03:37 -0700
committerAlon Zakai <alonzakai@gmail.com>2017-08-25 16:04:24 -0700
commitdb3adf6c6a6a34bb23f0a91a7fad568dfa906062 (patch)
treed3caff8013649684e62830d28f0da6a2a3878366 /src
parentf3d59ea84e899f2b1cca9c1c7d23c80260b0df04 (diff)
downloadbinaryen-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.cpp69
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();
+ }
+ }
}
}