diff options
Diffstat (limited to 'scripts/fuzz_shell.js')
-rw-r--r-- | scripts/fuzz_shell.js | 115 |
1 files changed, 80 insertions, 35 deletions
diff --git a/scripts/fuzz_shell.js b/scripts/fuzz_shell.js index 1e4068dc8..3d29b197c 100644 --- a/scripts/fuzz_shell.js +++ b/scripts/fuzz_shell.js @@ -1,25 +1,47 @@ -// Shell integration. -if (typeof console === 'undefined') { - console = { log: print }; -} -var tempRet0; -var binary; -if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) { - var args = process.argv.slice(2); - binary = require('fs').readFileSync(args[0]); - if (!binary.buffer) binary = new Uint8Array(binary); +// Shell integration: find argv and set up readBinary(). +var argv; +var readBinary; +if (typeof process === 'object' && typeof require === 'function') { + // Node.js. + argv = process.argv.slice(2); + readBinary = function(name) { + var data = require('fs').readFileSync(name); + if (!data.buffer) data = new Uint8Array(data); + return data; + }; } else { - var args; + // A shell like D8. if (typeof scriptArgs != 'undefined') { - args = scriptArgs; + argv = scriptArgs; } else if (typeof arguments != 'undefined') { - args = arguments; - } - if (typeof readbuffer === 'function') { - binary = new Uint8Array(readbuffer(args[0])); - } else { - binary = read(args[0], 'binary'); + argv = arguments; } + readBinary = function(name) { + if (typeof readbuffer === 'function') { + return new Uint8Array(readbuffer(name)); + } else { + return read(name, 'binary'); + } + }; +} + +// We are given the binary to run as a parameter. +var binary = readBinary(argv[0]); + +// Normally we call all the exports of the given wasm file. But, if we are +// passed a final parameter in the form of "exports:X,Y,Z" then we call +// specifically the exports X, Y, and Z. +var exportsToCall; +if (argv[argv.length - 1].startsWith('exports:')) { + exportsToCall = argv[argv.length - 1].substr('exports:'.length).split(','); + argv.pop(); +} + +// If a second parameter is given, it is a second binary that we will link in +// with it. +var secondBinary; +if (argv[1]) { + secondBinary = readBinary(argv[1]); } // Utilities. @@ -27,17 +49,6 @@ function assert(x, y) { if (!x) throw (y || 'assertion failed');// + new Error().stack; } -// Deterministic randomness. -var detrand = (function() { - var hash = 5381; // TODO DET_RAND_SEED; - var x = 0; - return function() { - hash = (((hash << 5) + hash) ^ (x & 0xff)) >>> 0; - x = (x + 1) % 256; - return (hash % 256) / 256; - }; -})(); - // Print out a value in a way that works well for fuzzing. function printed(x, y) { if (typeof y !== 'undefined') { @@ -124,6 +135,7 @@ function logValue(x, y) { } // Set up the imports. +var tempRet0; var imports = { 'fuzzing-support': { 'log-i32': logValue, @@ -151,6 +163,24 @@ if (typeof WebAssembly.Tag !== 'undefined') { }; } +// If a second binary will be linked in then set up the imports for +// placeholders. Any import like (import "placeholder" "0" (func .. will be +// provided by the secondary module, and must be called using an indirection. +if (secondBinary) { + imports['placeholder'] = new Proxy({}, { + get(target, prop, receiver) { + // Return a function that throws. We could do an indirect call using the + // exported table, but as we immediately link in the secondary module, + // these stubs will not be called (they are written to the table, and the + // secondary module overwrites them). We do need to return something so + // the primary module links without erroring, though. + return () => { + throw 'proxy stub should not be called'; + } + } + }); +} + // Create the wasm. var module = new WebAssembly.Module(binary); @@ -165,17 +195,32 @@ try { // Handle the exports. var exports = instance.exports; -var view; +// Link in a second module, if one was provided. +if (secondBinary) { + var secondModule = new WebAssembly.Module(secondBinary); -// Recreate the view. This is important both initially and after a growth. -function refreshView() { - if (exports.memory) { - view = new Int32Array(exports.memory.buffer); + // The secondary module just needs to import the primary one: all original + // imports it might have needed were exported from there. + var secondImports = {'primary': exports}; + var secondInstance; + try { + secondInstance = new WebAssembly.Instance(secondModule, secondImports); + } catch (e) { + console.log('exception thrown: failed to instantiate second module'); + quit(); } } // Run the wasm. -for (var e in exports) { +if (!exportsToCall) { + // We were not told specific exports, so call them all. + exportsToCall = []; + for (var e in exports) { + exportsToCall.push(e); + } +} + +for (var e of exportsToCall) { if (typeof exports[e] !== 'function') { continue; } |