summaryrefslogtreecommitdiff
path: root/src/tools/js-wrapper.h
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-08-11 10:53:21 -0700
committerGitHub <noreply@github.com>2017-08-11 10:53:21 -0700
commit4216894b22e5891e83851d2af42080293e6089e4 (patch)
treee4fdcdd5becaf80dcaf924bd20e01f107b05b388 /src/tools/js-wrapper.h
parent5295929fd239ea8a760cd2c3f65510da9972c33c (diff)
downloadbinaryen-4216894b22e5891e83851d2af42080293e6089e4.tar.gz
binaryen-4216894b22e5891e83851d2af42080293e6089e4.tar.bz2
binaryen-4216894b22e5891e83851d2af42080293e6089e4.zip
New fuzzer (#1126)
This adds a new method of fuzzing, "translate to fuzz" which means we consider the input to be a stream of data that we translate into a valid wasm module. It's sort of like a random seed for a process that creates a random wasm module. By using the input that way, we can explore the space of valid wasm modules quickly, and it makes afl-fuzz integration easy. Also adds a "fuzz binary" option which is similar to "fuzz execution". It makes wasm-opt not only execute the code before and after opts, but also write to binary and read from it, helping to fuzz the binary format.
Diffstat (limited to 'src/tools/js-wrapper.h')
-rw-r--r--src/tools/js-wrapper.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/tools/js-wrapper.h b/src/tools/js-wrapper.h
new file mode 100644
index 000000000..90453eb35
--- /dev/null
+++ b/src/tools/js-wrapper.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Emit a JavaScript wrapper to run a wasm module with some test
+// values, useful for fuzzing.
+//
+
+namespace wasm {
+
+static std::string generateJSWrapper(Module& wasm) {
+ std::string ret;
+ ret += "if (typeof console === 'undefined') {\n"
+ " console = { log: print };\n"
+ "}\n"
+ "var binary;\n"
+ "if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) {\n"
+ " var args = process.argv.slice(2);\n"
+ " binary = require('fs').readFileSync(args[0]);\n"
+ " if (!binary.buffer) binary = new Uint8Array(binary);\n"
+ "} else {\n"
+ " var args;\n"
+ " if (typeof scriptArgs != 'undefined') {\n"
+ " args = scriptArgs;\n"
+ " } else if (typeof arguments != 'undefined') {\n"
+ " args = arguments;\n"
+ " }\n"
+ " if (typeof readbuffer === 'function') {\n"
+ " binary = new Uint8Array(readbuffer(args[0]));\n"
+ " } else {\n"
+ " binary = read(args[0], 'binary');\n"
+ " }\n"
+ "}\n"
+ "var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {});\n";
+ for (auto& exp : wasm.exports) {
+ auto* func = wasm.getFunctionOrNull(exp->value);
+ if (!func) continue; // something exported other than a function
+ auto bad = false; // check for things we can't support
+ for (WasmType param : func->params) {
+ if (param == i64) bad = true;
+ }
+ if (func->result == i64) bad = true;
+ if (bad) continue;
+ ret += "if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer();\n";
+ ret += "try {\n";
+ ret += std::string(" console.log('calling: ") + exp->name.str + "');\n";
+ if (func->result != none) {
+ ret += " console.log(' result: ' + ";
+ }
+ ret += std::string("instance.exports.") + exp->name.str + "(";
+ bool first = true;
+ for (WasmType param : func->params) {
+ WASM_UNUSED(param);
+ // zeros in arguments TODO more?
+ if (first) {
+ first = false;
+ } else {
+ ret += ", ";
+ }
+ ret += "0";
+ }
+ ret += ")";
+ if (func->result != none) {
+ ret += ")"; // for console.log
+ }
+ ret += ";\n";
+ ret += "} catch (e) {\n";
+ ret += " console.log(' exception: ' + e);\n";
+ ret += "}\n";
+ }
+ ret += "console.log('done.')\n";
+ return ret;
+}
+
+} // namespace wasm
+