diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-05-20 10:50:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-20 10:50:02 -0700 |
commit | 9e0958982d2044949746c2d8290dbc0368546ebf (patch) | |
tree | 40baee2d19419d76ff904b79b6146be980d5b287 | |
parent | 2ddb7cb1f45cf9aeef90ec5c8000a2d279f0302b (diff) | |
download | binaryen-9e0958982d2044949746c2d8290dbc0368546ebf.tar.gz binaryen-9e0958982d2044949746c2d8290dbc0368546ebf.tar.bz2 binaryen-9e0958982d2044949746c2d8290dbc0368546ebf.zip |
afl-fuzz bug fixes (#1018)
* values cannot flow through an if without an else, they never return a value
* check pass tests in pass-debug mode too
* add missing finalization in binary reading
-rwxr-xr-x | check.py | 16 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 3 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 4 | ||||
-rw-r--r-- | test/passes/flatten-control-flow.bin.txt | 239 | ||||
-rw-r--r-- | test/passes/flatten-control-flow.wasm | bin | 0 -> 458 bytes | |||
-rw-r--r-- | test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt | 22 | ||||
-rw-r--r-- | test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast | 29 |
7 files changed, 312 insertions, 1 deletions
@@ -85,10 +85,24 @@ for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))): assert len(asserts) == 0 with open('split.wast', 'w') as o: o.write(module) cmd = WASM_OPT + opts + ['split.wast', '--print'] - actual += run_command(cmd) + curr = run_command(cmd) + actual += curr # also check debug mode output is valid debugged = run_command(cmd + ['--debug'], stderr=subprocess.PIPE) fail_if_not_contained(actual, debugged) + # also check pass-debug mode + old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG') + try: + os.environ['BINARYEN_PASS_DEBUG'] = '1' + pass_debug = run_command(cmd) + fail_if_not_identical(curr, pass_debug) + finally: + if old_pass_debug is not None: + os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug + else: + if 'BINARYEN_PASS_DEBUG' in os.environ: + del os.environ['BINARYEN_PASS_DEBUG'] + fail_if_not_identical(actual, open(os.path.join('test', 'passes', passname + ('.bin' if binary else '') + '.txt'), 'rb').read()) print '[ checking asm2wasm testcases... ]\n' diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 4273b9f63..1fa996ae6 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -84,6 +84,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { flows.push_back(flow); } self->ifStack.pop_back(); + } else { + // if without else stops the flow of values + self->valueCanFlow = false; } } else if (curr->is<Block>()) { // any breaks flowing to here are unnecessary, as we get here anyhow diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 6448615a5..65c6f2a21 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1800,6 +1800,7 @@ void WasmBinaryBuilder::visitSwitch(Switch *curr) { curr->default_ = defaultTarget.name; if (debug) std::cerr << "default: "<< curr->default_<<std::endl; if (defaultTarget.arity) curr->value = popNonVoidExpression(); + curr->finalize(); } Expression* WasmBinaryBuilder::visitCall() { @@ -1862,6 +1863,7 @@ void WasmBinaryBuilder::visitGetLocal(GetLocal *curr) { throw ParseException("bad get_local index"); } curr->type = currFunction->getLocalType(curr->index); + curr->finalize(); } void WasmBinaryBuilder::visitSetLocal(SetLocal *curr, uint8_t code) { @@ -2034,6 +2036,7 @@ bool WasmBinaryBuilder::maybeVisitUnary(Expression*& out, uint8_t code) { } if (debug) std::cerr << "zz node: Unary" << std::endl; curr->value = popNonVoidExpression(); + curr->finalize(); out = curr; return true; } @@ -2116,6 +2119,7 @@ void WasmBinaryBuilder::visitReturn(Return *curr) { if (currFunction->result != none) { curr->value = popNonVoidExpression(); } + curr->finalize(); } bool WasmBinaryBuilder::maybeVisitHost(Expression*& out, uint8_t code) { diff --git a/test/passes/flatten-control-flow.bin.txt b/test/passes/flatten-control-flow.bin.txt new file mode 100644 index 000000000..9b33f976e --- /dev/null +++ b/test/passes/flatten-control-flow.bin.txt @@ -0,0 +1,239 @@ +(module + (type $0 (func (result i32))) + (type $1 (func (result i64))) + (type $2 (func (result f32))) + (type $3 (func (result f64))) + (type $4 (func (param i32) (result i32))) + (type $5 (func (param i64) (result i64))) + (type $6 (func (param f32) (result f32))) + (type $7 (func (param f64) (result f64))) + (type $8 (func (param i64 f32 f64 i32 i32))) + (type $9 (func (param i64 f32 f64 i32 i32) (result f64))) + (memory $0 0) + (export "type-local-i32" (func $0)) + (export "type-local-i64" (func $1)) + (export "type-local-f32" (func $2)) + (export "type-local-f64" (func $3)) + (export "type-param-i32" (func $4)) + (export "type-param-i64" (func $5)) + (export "tÿÿe-param-f32" (func $6)) + (export "type-param-f64" (func $7)) + (export "type-mixed" (func $8)) + (export "read" (func $9)) + (func $0 (type $0) (result i32) + (local $var$0 i32) + (local $1 i32) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $1 (type $1) (result i64) + (local $var$0 i64) + (local $1 i64) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $2 (type $2) (result f32) + (local $var$0 f32) + (local $1 f32) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $3 (type $3) (result f64) + (local $var$0 f64) + (local $1 f64) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $4 (type $4) (param $var$0 i32) (result i32) + (local $1 i32) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $5 (type $5) (param $var$0 i64) (result i64) + (local $1 i64) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $6 (type $6) (param $var$0 f32) (result f32) + (local $1 f32) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $7 (type $7) (param $var$0 f64) (result f64) + (local $1 f64) + (block + (set_local $1 + (get_local $var$0) + ) + ) + (return + (get_local $1) + ) + ) + (func $8 (type $8) (param $var$0 i64) (param $var$1 f32) (param $var$2 f64) (param $var$3 i32) (param $var$4 i32) + (local $var$5 i64) + (local $var$6 i64) + (local $var$7 f32) + (local $var$8 f64) + (block $label$0 + (nop) + (block + (block + (unreachable) + ) + ) + (drop + (f32.neg + (get_local $var$1) + ) + ) + (drop + (f64.neg + (get_local $var$2) + ) + ) + (drop + (i32.eqz + (get_local $var$3) + ) + ) + (drop + (i32.eqz + (get_local $var$4) + ) + ) + (drop + (f32.neg + (get_local $var$7) + ) + ) + (drop + (i64.eqz + (get_local $var$5) + ) + ) + (drop + (i64.eqz + (get_local $var$6) + ) + ) + (drop + (f64.neg + (get_local $var$8) + ) + ) + ) + ) + (func $9 (type $9) (param $var$0 i64) (param $var$1 f32) (param $var$2 f64) (param $var$3 i32) (param $var$4 i32) (result f64) + (local $var$5 i64) + (local $var$6 i64) + (local $var$7 f32) + (local $var$8 f64) + (local $9 f64) + (local $10 f64) + (block + (block + (block $label$0 + (set_local $var$7 + (f32.const 5.5) + ) + (set_local $var$5 + (i64.const 6) + ) + (set_local $var$8 + (f64.const 8) + ) + (set_local $9 + (f64.add + (f64.convert_u/i64 + (get_local $var$0) + ) + (f64.add + (f64.promote/f32 + (get_local $var$1) + ) + (f64.add + (get_local $var$2) + (f64.add + (f64.convert_u/i32 + (get_local $var$3) + ) + (f64.add + (f64.convert_s/i32 + (get_local $var$4) + ) + (f64.add + (f64.promote/f32 + (get_local $var$7) + ) + (f64.add + (f64.convert_u/i64 + (get_local $var$5) + ) + (f64.add + (f64.convert_u/i64 + (get_local $var$6) + ) + (get_local $var$8) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (set_local $10 + (get_local $9) + ) + ) + ) + (return + (get_local $10) + ) + ) +) diff --git a/test/passes/flatten-control-flow.wasm b/test/passes/flatten-control-flow.wasm Binary files differnew file mode 100644 index 000000000..0ba6a86fe --- /dev/null +++ b/test/passes/flatten-control-flow.wasm diff --git a/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt new file mode 100644 index 000000000..e2d4f13a9 --- /dev/null +++ b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.txt @@ -0,0 +1,22 @@ +(module + (type $0 (func (param i32) (result f64))) + (global $global$3 (mut f64) (f64.const 0)) + (memory $0 0) + (func $1 (type $0) (param $x i32) (result f64) + (local $var$0 f64) + (block $label$0 + (set_local $var$0 + (f64.const 0) + ) + (return + (f64.const -3.4) + ) + (if + (get_local $x) + (return + (f64.const 5.6) + ) + ) + ) + ) +) diff --git a/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast new file mode 100644 index 000000000..5dfbfa102 --- /dev/null +++ b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast @@ -0,0 +1,29 @@ +(module + (global $global$3 (mut f64) (f64.const 0)) + (func $1 (param $x i32) (result f64) + (local $var$0 f64) + (block $label$0 + (set_local $var$0 + (f64.const 0) + ) + (if + (i32.gt_s + (i32.const 9) + (i32.const 0) + ) + (return + (f64.const -3.4) + ) + ) + (if + (get_local $x) + (return + (f64.const 5.6) + ) + ) + (return + (f64.const 1.2) + ) + ) + ) +) |