diff options
-rw-r--r-- | src/tools/fuzzing.h | 40 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz.txt | 1125 |
2 files changed, 385 insertions, 780 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 978d4e443..d9acadbd1 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -128,7 +128,8 @@ public: setupGlobals(); // keep adding functions until we run out of input while (!finishedInput) { - addFunction(); + auto* func = addFunction(); + addInvocations(func); } if (HANG_LIMIT > 0) { addHangLimitSupport(); @@ -161,12 +162,12 @@ private: // the memory that we use, a small portion so that we have a good chance of // looking at writes (we also look outside of this region with small probability) // this should be a power of 2 - static const int USABLE_MEMORY = 32; + static const int USABLE_MEMORY = 16; // the number of runtime iterations (function calls, loop backbranches) we // allow before we stop execution with a trap, to prevent hangs. 0 means // no hang protection. - static const int HANG_LIMIT = 100; + static const int HANG_LIMIT = 10; // Optionally remove NaNs, which are a source of nondeterminism (which makes // cross-VM comparisons harder) @@ -343,7 +344,7 @@ private: std::map<WasmType, std::vector<Index>> typeLocals; // type => list of locals with that type - void addFunction() { + Function* addFunction() { Index num = wasm.functions.size(); func = new Function; func->name = std::string("func_") + std::to_string(num); @@ -400,6 +401,37 @@ private: } // cleanup typeLocals.clear(); + return func; + } + + // the fuzzer external interface sends in zeros (simpler to compare + // across invocations from JS or wasm-opt etc.). Add invocations in + // the wasm, so they run everywhere + void addInvocations(Function* func) { + std::vector<Expression*> invocations; + while (oneIn(2)) { + std::vector<Expression*> args; + for (auto type : func->params) { + args.push_back(makeConst(type)); + } + Expression* invoke = builder.makeCall(func->name, args, func->result); + if (isConcreteWasmType(func->result)) { + invoke = builder.makeDrop(invoke); + } + invocations.push_back(invoke); + } + if (invocations.empty()) return; + auto* invoker = new Function; + invoker->name = func->name.str + std::string("_invoker"); + invoker->result = none; + invoker->body = builder.makeBlock(invocations); + wasm.addFunction(invoker); + invoker->type = ensureFunctionType(getSig(invoker), &wasm)->name; + auto* export_ = new Export; + export_->name = invoker->name; + export_->value = invoker->name; + export_->kind = ExternalKind::Function; + wasm.addExport(export_); } Name makeLabel() { diff --git a/test/passes/translate-to-fuzz.txt b/test/passes/translate-to-fuzz.txt index 34abb603f..e13dbc509 100644 --- a/test/passes/translate-to-fuzz.txt +++ b/test/passes/translate-to-fuzz.txt @@ -1,24 +1,33 @@ (module - (type $FUNCSIG$ji (func (param i32) (result i64))) - (type $FUNCSIG$ff (func (param f32) (result f32))) - (global $global$0 (mut f64) (f64.const 138413376)) - (global $global$1 (mut f64) (f64.const -3402823466385288598117041e14)) - (global $hangLimit (mut i32) (i32.const 100)) - (table 0 anyfunc) - + (type $FUNCSIG$i (func (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$ij (func (param i64) (result i32))) + (global $global$0 (mut f32) (f32.const 536870912)) + (global $global$1 (mut f32) (f32.const 2147483648)) + (global $global$2 (mut f64) (f64.const -1048576)) + (global $global$3 (mut f64) (f64.const 23643)) + (global $hangLimit (mut i32) (i32.const 10)) + (table 1 anyfunc) + (elem (i32.const 0) $func_0) (memory $0 (shared 1 1)) - (data (i32.const 0) "\00C\00[\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data (i32.const 0) "n\00\05E\00\00\00\00") (export "func_0" (func $func_0)) - (export "func_1" (func $func_1)) + (export "func_0_invoker" (func $func_0_invoker)) + (export "func_2" (func $func_2)) + (export "func_2_invoker" (func $func_2_invoker)) (export "hangLimitInitializer" (func $hangLimitInitializer)) - (func $func_0 (; 0 ;) (type $FUNCSIG$ji) (param $0 i32) (result i64) + (func $func_0 (; 0 ;) (type $FUNCSIG$i) (result i32) + (local $0 i32) + (local $1 f64) + (local $2 i64) + (local $3 i64) (block (if (i32.eqz (get_global $hangLimit) ) (return - (i64.const 3564930269531684152) + (i32.const -127) ) ) (set_global $hangLimit @@ -28,184 +37,101 @@ ) ) ) - (block $label$0 (result i64) - (drop - (wake - (i32.and - (i32.const 5142) - (i32.const 31) - ) - (i32.const 88) - ) - ) - (i64.and - (i64.const 5340426979903478799) - (i64.const 1836149622) - ) - ) - ) - (func $func_1 (; 1 ;) (type $FUNCSIG$ff) (param $0 f32) (result f32) - (local $1 f32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (block $label$0 - (nop) - (if - (i32.const -8) - (block - (block $label$1 - (nop) - (br_table $label$0 $label$1 $label$1 $label$1 $label$0 $label$1 $label$0 $label$0 $label$0 $label$0 - (i32.const -28) - ) - ) - (block $label$9 - (loop $label$10 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) + (block $label$0 (result i32) + (set_local $1 + (if (result f64) + (i32.const -2147483648) + (call $deNan64 + (f64.add + (call $deNan64 + (f64.promote/f32 + (f32.const 4.212240583647452e-17) ) - (block $label$11 - (if - (i32.eqz - (if (result i32) - (i32.const 65535) - (i32.const -4194304) - (block $label$14 (result i32) - (nop) - (br $label$11) + ) + (block $label$14 (result f64) + (block $label$15 + (drop + (if (result f64) + (i32.eqz + (i32.const -32768) + ) + (f64.load offset=22 + (i32.clz + (get_local $0) ) ) + (block $label$16 (result f64) + (set_local $1 + (f64.const 2147483648) + ) + (br $label$15) + ) ) - (block $label$15 - (nop) - (loop $label$16 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const -2147483648) - ) + ) + (block $label$17 + (nop) + (loop $label$18 + (block + (if + (i32.eqz + (get_global $hangLimit) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (return + (get_local $0) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) ) ) - (nop) ) - ) - (block $label$17 - (i32.store8 offset=2 - (i32.and - (i32.const 8) - (i32.const 31) + (block $label$19 + (set_global $global$3 + (get_local $1) ) - (i32.const -16777216) + (nop) ) - (nop) - ) - ) - (block $label$18 - (drop - (f64.const -9223372036854775808) ) - (nop) ) ) - ) - (loop $label$19 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) + (loop $label$20 (result f64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (i32.const -127) + ) ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) ) ) - ) - (block - (block $label$20 - (nop) + (block (result f64) (block $label$21 - (drop - (i64.atomic.rmw8_u.xor offset=3 - (i32.and - (i32.load8_s offset=2 - (i32.and - (i32.const 524288) - (i32.const 31) - ) - ) - (i32.const 31) - ) - (loop $label$23 (result i64) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 3477819136) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (i64.const -69) - ) + (i64.store offset=4 align=1 + (i32.and + (i32.const 1) + (i32.const 15) + ) + (tee_local $2 + (i64.const 32768) ) ) - (loop $label$24 + (loop $label$22 (block (if (i32.eqz (get_global $hangLimit) ) (return - (get_local $1) + (get_local $0) ) ) (set_global $hangLimit @@ -215,476 +141,180 @@ ) ) ) - (block $label$25 - (if + (block + (br_if $label$21 (i32.eqz - (wake - (i32.and - (i32.trunc_u/f32 - (f32.const 2056) - ) - (i32.const 31) - ) - (i32.load offset=2 align=2 - (i32.and - (i32.atomic.load8_u offset=2 - (i32.and - (i32.atomic.load offset=2 - (i32.and - (i32.const -131072) - (i32.const 31) - ) - ) - (i32.const 31) - ) - ) - (i32.const 31) - ) - ) - ) + (i32.const 32768) ) - (set_local $0 - (f32.const 536) - ) - (block $label$26 - (br_if $label$26 - (i32.const -16) - ) - (if - (block $label$27 (result i32) - (nop) - (br $label$24) - ) - (block $label$28 - (if - (block $label$29 (result i32) - (set_local $1 - (block $label$30 (result f32) - (set_local $0 - (call $deNan32 - (f32.demote/f64 - (f64.const 1970236986) - ) - ) - ) - (block $label$31 (result f32) - (nop) - (br $label$19) - ) - ) - ) - (br $label$20) - ) - (block $label$32 - (set_local $0 - (f32.const 9223372036854775808) - ) - (loop $label$33 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 57542873088) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (nop) - ) - ) - (block $label$34 - (nop) - (nop) - ) - ) - (f64.store offset=3 align=2 + ) + (br_if $label$22 + (i32.eqz + (i64.le_u + (block $label$23 (result i64) + (i64.atomic.load8_u offset=22 (i32.and - (i32.const 2097152) - (i32.const 31) + (get_local $0) + (i32.const 15) ) - (f64.const -2097152) ) ) - (block $label$36 - (loop $label$37 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const -68719476736) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (loop $label$38 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (br_if $label$37 - (i32.eqz - (if (result i32) - (i32.eqz - (i32.const 340281875) - ) - (i32.const 255) - (i32.const -25) - ) - ) - ) - (br_if $label$38 - (i32.const -32767) - ) - (loop $label$39 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $0) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (nop) - (br_if $label$39 - (i32.const 5651) - ) - (nop) - ) - ) - ) - ) - ) - (if - (i32.const 96) - (set_local $1 - (call $deNan32 - (select - (f32.const 9223372036854775808) - (get_local $0) - (i32.const 0) - ) - ) - ) - (block $label$40 - (if - (i32.eqz - (block $label$41 (result i32) - (drop - (get_local $0) - ) - (br $label$24) - ) - ) - (block $label$42 - (if - (i32.const -4) - (loop $label$43 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const -4503599627370496) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (loop $label$44 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (nop) - ) - (br_if $label$43 - (i32.eqz - (i32.const 0) - ) - ) - (nop) - ) - ) - (nop) - ) - (block $label$45 - (nop) - (nop) - ) - ) - (f64.store offset=4 align=4 - (i32.and - (i32.const 128) - (i32.const 31) - ) - (f64.const -25) - ) - ) - (loop $label$46 - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const 9223372036854775808) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$47 - (br_if $label$19 - (i32.eqz - (block $label$48 (result i32) - (i32.const 386995996) - ) - ) - ) - (br_if $label$20 - (i32.eqz - (i32.const -2147483647) - ) - ) - ) - ) - ) - ) + (select + (get_local $2) + (i64.const 0) + (i32.const 0) ) ) ) ) - (nop) + (set_local $3 + (get_local $3) + ) ) ) ) + (br_if $label$20 + (get_local $0) + ) + (f64.const -nan:0xffffffffffff0) ) - (br_if $label$19 - (i64.ne - (i64.trunc_s/f32 - (tee_local $0 - (if (result f32) - (wake - (f64.ge - (block $label$49 (result f64) - (nop) - (f64.const 5) - ) - (f64.const -1024) - ) - (loop $label$50 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (block $label$51 - (i32.atomic.store16 offset=22 - (i32.and - (i32.const 127) - (i32.const 31) - ) - (i32.const 0) - ) - (drop - (i64.const 64) - ) - ) - (br_if $label$50 - (wake - (i32.and - (i32.const 18505) - (i32.const 31) - ) - (i32.const 25) - ) - ) - (i32.const 16384) - ) - ) - ) - (block $label$52 (result f32) - (drop - (call $deNan32 - (f32.convert_s/i32 - (i32.atomic.load offset=22 - (i32.and - (i32.const -68) - (i32.const 31) - ) - ) - ) - ) - ) - (br $label$19) - ) - (block $label$53 (result f32) - (if - (f32.lt - (f32.load offset=3 align=1 - (i32.and - (i32.const -65535) - (i32.const 31) - ) - ) - (call $deNan32 - (f32.abs - (f32.const 1047536704) - ) - ) - ) - (block $label$54 - (if - (i32.eqz - (i32.wrap/i64 - (i64.const 255) - ) - ) - (block $label$55 - (set_local $0 - (get_local $0) - ) - (block $label$56 - (if - (i32.const 20341) - (nop) - (set_local $1 - (get_local $1) - ) - ) - (nop) - ) - ) - (block $label$57 - (block $label$58 - (block $label$59 - (nop) - (block $label$60 - (nop) - (nop) - ) - ) - (nop) - ) - (block $label$61 - (nop) - ) - ) - ) - (nop) - ) - (block $label$62 - (nop) - (nop) - ) - ) - (call $deNan32 - (f32.demote/f64 - (call $deNan64 - (f64.div - (call $deNan64 - (select - (call $deNan64 - (select - (f64.const -2048) - (f64.const 386145560) - (i32.const 1769303922) - ) - ) - (f64.const 8234166675167740447353394e125) - (i32.const 21824) - ) - ) - (get_global $global$0) - ) - ) - ) + ) + ) + ) + ) + (block $label$25 (result f64) + (nop) + (f64.const 336399619) + ) + ) + ) + (return + (i32.const -16777216) + ) + ) + ) + (func $func_0_invoker (; 1 ;) (type $FUNCSIG$v) + (drop + (call $func_0) + ) + (drop + (call $func_0) + ) + (drop + (call $func_0) + ) + ) + (func $func_2 (; 2 ;) (type $FUNCSIG$ij) (param $0 i64) (result i32) + (local $1 f32) + (local $2 i32) + (local $3 i64) + (local $4 f64) + (local $5 i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (get_local $2) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (i32.load8_u offset=4 + (i32.and + (call $func_0) + (i32.const 15) + ) + ) + ) + (func $func_2_invoker (; 3 ;) (type $FUNCSIG$v) + (drop + (call $func_2 + (i64.const 1162292275) + ) + ) + ) + (func $func_4 (; 4 ;) (result f32) + (local $0 i32) + (local $1 f32) + (local $2 i64) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i64) + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const -4294967296) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (block $label$1 + (if + (block $label$2 (result i32) + (block $label$3 + (block $label$4 + (loop $label$5 + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const 1734634880) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$6 + (set_local $1 + (f32.load offset=4 align=2 + (i32.and + (block $label$7 (result i32) + (nop) + (i32.atomic.load16_u offset=4 + (i32.and + (i32.const 202274421) + (i32.const 15) ) ) ) + (i32.const 15) ) ) - (i64.const -9223372036854775806) ) + (call $func_2_invoker) ) - (loop $label$65 + ) + (block $label$8 + (loop $label$9 (block (if (i32.eqz (get_global $hangLimit) ) (return - (f32.const 3402823466385288598117041e14) + (f32.const -nan:0x7fffc6) ) ) (set_global $hangLimit @@ -695,206 +325,149 @@ ) ) (block - (block $label$66 - (br_if $label$66 - (i32.eqz - (i32.const 32768) + (block $label$10 + (nop) + (br_if $label$9 + (call_indirect (type $FUNCSIG$i) + (i32.const 0) ) ) ) - (br_if $label$65 - (loop $label$67 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $1) + (br_if $label$9 + (i32.eqz + (if (result i32) + (i32.eqz + (i32.trunc_s/f32 + (tee_local $1 + (f32.const -nan:0x7fffe6) + ) ) ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) + (block $label$11 (result i32) + (br $label$4) + ) + (block $label$12 (result i32) + (nop) + (br $label$1) ) ) - (block (result i32) - (block $label$68 - (set_local $0 - (f32.const 6.947862890707752e-37) - ) - (i32.atomic.store16 offset=22 - (i32.and - (select - (select - (i32.const 32768) - (f64.lt - (f64.const 1.1754943508222875e-38) - (f64.load offset=22 align=2 - (i32.and - (i32.const -5) - (i32.const 31) - ) - ) - ) - (i32.atomic.load16_u offset=4 - (i32.const -126) - ) - ) - (i32.atomic.rmw8_u.cmpxchg offset=4 - (i32.and - (f32.lt - (get_local $1) - (f32.const 5100585927634429158935007e9) - ) - (i32.const 31) - ) - (i32.add - (i32.const 65536) - (if (result i32) - (i32.const -2147483647) - (i32.const 440812573) - (f64.ge - (call $deNan64 - (f64.abs - (f64.const 1) - ) - ) - (f64.const 512) - ) - ) - ) - (if (result i32) - (i32.eqz - (i32.const -2147483648) - ) - (block $label$69 (result i32) - (i64.eqz - (i64.const -6) - ) - ) - (block $label$70 (result i32) - (nop) - (loop $label$71 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (f32.const -nan:0x7fffcd) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (nop) - (br_if $label$71 - (i32.const -268435456) - ) - (i32.const 1499148335) - ) - ) - ) - ) - ) - (i32.const 2147483647) - ) - (i32.const 31) - ) - (i32.trunc_s/f64 - (get_global $global$1) - ) - ) + ) + ) + (nop) + ) + ) + (loop $label$13 + (block + (if + (i32.eqz + (get_global $hangLimit) + ) + (return + (f32.const 16250) + ) + ) + (set_global $hangLimit + (i32.sub + (get_global $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$14 + (nop) + (call $func_2_invoker) + ) + ) + ) + ) + (if + (i32.eqz + (select + (br_if $label$2 + (i32.const 268435456) + (if (result i32) + (call $func_0) + (block $label$15 (result i32) + (nop) + (block $label$16 (result i32) + (set_local $0 + (get_local $3) ) - (br_if $label$67 - (loop $label$72 (result i32) - (block - (if - (i32.eqz - (get_global $hangLimit) - ) - (return - (get_local $0) - ) - ) - (set_global $hangLimit - (i32.sub - (get_global $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (nop) - (br_if $label$72 - (i32.eqz - (i32.load16_s offset=2 align=1 - (i32.and - (i32.const -64) - (i32.const -4194304) - ) - ) - ) - ) - (f64.ge - (call $deNan64 - (f64.convert_u/i32 - (i32.const -2147483647) - ) - ) - (get_global $global$1) - ) - ) - ) + (return + (get_local $1) ) - (i32.const -68) ) ) + (block $label$17 (result i32) + (br $label$3) + ) ) - (if - (i32.const -89) - (f64.store offset=4 align=4 - (return - (f32.const -274877906944) + ) + (call_indirect (type $FUNCSIG$i) + (i32.const 0) + ) + (i32.atomic.load16_u + (i32.and + (wake + (i32.and + (i32.wrap/i64 + (get_local $2) + ) + (i32.const 15) ) - (return - (f32.const 19) + (if (result i32) + (i32.const -111) + (call_indirect (type $FUNCSIG$i) + (i32.const 0) + ) + (if (result i32) + (get_local $0) + (if (result i32) + (i32.const 7793) + (i32.const 128) + (get_local $0) + ) + (get_local $0) + ) ) ) - (return - (get_local $0) - ) + (i32.const 15) ) ) ) ) + (nop) + (nop) ) ) + (br $label$1) + ) + (block $label$18 + (call $func_0_invoker) + (nop) ) - (return - (get_local $1) + (block $label$19 + (call $func_2_invoker) + ) + ) + (br_if $label$1 + (i32.eqz + (i32.const 3077) ) ) ) + (nop) (return - (f32.const 2147483648) + (f32.const 31) ) ) ) - (func $hangLimitInitializer (; 2 ;) + (func $hangLimitInitializer (; 5 ;) (set_global $hangLimit - (i32.const 100) + (i32.const 10) ) ) - (func $deNan32 (; 3 ;) (param $0 f32) (result f32) + (func $deNan32 (; 6 ;) (param $0 f32) (result f32) (if (result f32) (f32.eq (get_local $0) @@ -904,7 +477,7 @@ (f32.const 0) ) ) - (func $deNan64 (; 4 ;) (param $0 f64) (result f64) + (func $deNan64 (; 7 ;) (param $0 f64) (result f64) (if (result f64) (f64.eq (get_local $0) |