diff options
-rw-r--r-- | src/tools/fuzzing.h | 1 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 100 | ||||
-rw-r--r-- | test/passes/fuzz_metrics_noprint.bin.txt | 53 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_all-features_metrics_noprint.txt | 70 |
4 files changed, 113 insertions, 111 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 830e204f8..9789a3a5b 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -176,6 +176,7 @@ private: void prepareHangLimitSupport(); void addHangLimitSupport(); void addImportLoggingSupport(); + void addHashMemorySupport(); // Special expression makers Expression* makeHangLimitCheck(); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 42d3ec3ba..db4d0196e 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -187,6 +187,7 @@ void TranslateToFuzzReader::build() { } if (allowMemory) { finalizeMemory(); + addHashMemorySupport(); } finalizeTable(); } @@ -227,49 +228,6 @@ void TranslateToFuzzReader::setupMemory() { wasm.dataSegments[0]->data.push_back(value >= 256 ? 0 : (value & 0xff)); } } - // Add memory hasher helper (for the hash, see hash.h). The function looks - // like: - // function hashMemory() { - // hash = 5381; - // hash = ((hash << 5) + hash) ^ mem[0]; - // hash = ((hash << 5) + hash) ^ mem[1]; - // .. - // return hash; - // } - std::vector<Expression*> contents; - contents.push_back( - builder.makeLocalSet(0, builder.makeConst(uint32_t(5381)))); - auto zero = Literal::makeFromInt32(0, wasm.memories[0]->indexType); - for (Index i = 0; i < USABLE_MEMORY; i++) { - contents.push_back(builder.makeLocalSet( - 0, - builder.makeBinary( - XorInt32, - builder.makeBinary( - AddInt32, - builder.makeBinary(ShlInt32, - builder.makeLocalGet(0, Type::i32), - builder.makeConst(uint32_t(5))), - builder.makeLocalGet(0, Type::i32)), - builder.makeLoad(1, - false, - i, - 1, - builder.makeConst(zero), - Type::i32, - wasm.memories[0]->name)))); - } - contents.push_back(builder.makeLocalGet(0, Type::i32)); - auto* body = builder.makeBlock(contents); - auto* hasher = wasm.addFunction(builder.makeFunction( - "hashMemory", Signature(Type::none, Type::i32), {Type::i32}, body)); - wasm.addExport( - builder.makeExport(hasher->name, hasher->name, ExternalKind::Function)); - // Export memory so JS fuzzing can use it - if (!wasm.getExportOrNull("memory")) { - wasm.addExport(builder.makeExport( - "memory", wasm.memories[0]->name, ExternalKind::Memory)); - } } void TranslateToFuzzReader::setupHeapTypes() { @@ -479,6 +437,52 @@ void TranslateToFuzzReader::addImportLoggingSupport() { } } +void TranslateToFuzzReader::addHashMemorySupport() { + // Add memory hasher helper (for the hash, see hash.h). The function looks + // like: + // function hashMemory() { + // hash = 5381; + // hash = ((hash << 5) + hash) ^ mem[0]; + // hash = ((hash << 5) + hash) ^ mem[1]; + // .. + // return hash; + // } + std::vector<Expression*> contents; + contents.push_back( + builder.makeLocalSet(0, builder.makeConst(uint32_t(5381)))); + auto zero = Literal::makeFromInt32(0, wasm.memories[0]->indexType); + for (Index i = 0; i < USABLE_MEMORY; i++) { + contents.push_back(builder.makeLocalSet( + 0, + builder.makeBinary( + XorInt32, + builder.makeBinary( + AddInt32, + builder.makeBinary(ShlInt32, + builder.makeLocalGet(0, Type::i32), + builder.makeConst(uint32_t(5))), + builder.makeLocalGet(0, Type::i32)), + builder.makeLoad(1, + false, + i, + 1, + builder.makeConst(zero), + Type::i32, + wasm.memories[0]->name)))); + } + contents.push_back(builder.makeLocalGet(0, Type::i32)); + auto* body = builder.makeBlock(contents); + auto* hasher = wasm.addFunction(builder.makeFunction( + "hashMemory", Signature(Type::none, Type::i32), {Type::i32}, body)); + wasm.addExport( + builder.makeExport(hasher->name, hasher->name, ExternalKind::Function)); + // Export memory so JS fuzzing can use it + if (!wasm.getExportOrNull("memory")) { + wasm.addExport(builder.makeExport( + "memory", wasm.memories[0]->name, ExternalKind::Memory)); + } +} + TranslateToFuzzReader::FunctionCreationContext::~FunctionCreationContext() { if (HANG_LIMIT > 0) { parent.addHangLimitChecks(func); @@ -1990,7 +1994,7 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) { // If there is no last function, and we have others, pick between them. Also // pick between them with some random probability even if there is a last // function. - if (!target || (!wasm.functions.empty() && !oneIn(wasm.functions.size()))) { + if (!wasm.functions.empty() && (!target || !oneIn(wasm.functions.size()))) { target = pick(wasm.functions).get(); } if (target) { @@ -3112,7 +3116,8 @@ Expression* TranslateToFuzzReader::makeMemoryFill() { } Type TranslateToFuzzReader::getSingleConcreteType() { - if (wasm.features.hasReferenceTypes() && oneIn(3)) { + if (wasm.features.hasReferenceTypes() && !interestingHeapTypes.empty() && + oneIn(3)) { auto heapType = pick(interestingHeapTypes); auto nullability = getNullability(); return Type(heapType, nullability); @@ -3146,7 +3151,8 @@ Type TranslateToFuzzReader::getSingleConcreteType() { } Type TranslateToFuzzReader::getReferenceType() { - if (wasm.features.hasReferenceTypes() && oneIn(2)) { + if (wasm.features.hasReferenceTypes() && !interestingHeapTypes.empty() && + oneIn(2)) { auto heapType = pick(interestingHeapTypes); auto nullability = getNullability(); return Type(heapType, nullability); @@ -3168,7 +3174,7 @@ Type TranslateToFuzzReader::getReferenceType() { } Type TranslateToFuzzReader::getEqReferenceType() { - if (oneIn(2)) { + if (oneIn(2) && !interestingHeapTypes.empty()) { // Try to find an interesting eq-compatible type. auto heapType = pick(interestingHeapTypes); if (HeapType::isSubType(heapType, HeapType::eq)) { diff --git a/test/passes/fuzz_metrics_noprint.bin.txt b/test/passes/fuzz_metrics_noprint.bin.txt index 3077b858d..700359899 100644 --- a/test/passes/fuzz_metrics_noprint.bin.txt +++ b/test/passes/fuzz_metrics_noprint.bin.txt @@ -1,33 +1,34 @@ total - [exports] : 71 - [funcs] : 97 + [exports] : 59 + [funcs] : 86 [globals] : 9 [imports] : 4 [memories] : 1 [memory-data] : 2 - [table-data] : 29 + [table-data] : 34 [tables] : 1 [tags] : 0 - [total] : 9772 - [vars] : 262 - Binary : 728 - Block : 1590 - Break : 299 - Call : 459 - CallIndirect : 97 - Const : 1686 - Drop : 92 - GlobalGet : 775 - GlobalSet : 636 - If : 515 - Load : 166 - LocalGet : 671 - LocalSet : 502 - Loop : 201 - Nop : 111 - RefFunc : 29 - Return : 82 - Select : 87 - Store : 93 - Unary : 653 - Unreachable : 300 + [total] : 9333 + [vars] : 265 + Binary : 675 + Block : 1567 + Break : 310 + Call : 441 + CallIndirect : 68 + Const : 1667 + Drop : 68 + GlobalGet : 735 + GlobalSet : 594 + If : 514 + Load : 144 + LocalGet : 542 + LocalSet : 431 + Loop : 197 + Nop : 167 + RefFunc : 34 + Return : 84 + Select : 65 + Store : 80 + Switch : 2 + Unary : 660 + Unreachable : 288 diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index dc8be142a..cdbd4dd27 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,45 +1,39 @@ total - [exports] : 3 - [funcs] : 4 + [exports] : 4 + [funcs] : 8 [globals] : 5 [imports] : 5 [memories] : 1 [memory-data] : 20 [table-data] : 2 [tables] : 1 - [tags] : 0 - [total] : 682 - [vars] : 3 - AtomicCmpxchg : 1 - AtomicFence : 3 - AtomicNotify : 2 - Binary : 76 - Block : 105 - Break : 15 - Call : 5 - CallRef : 3 - Const : 170 - Drop : 3 - GlobalGet : 42 - GlobalSet : 41 - I31Get : 2 - I31New : 2 - If : 32 - Load : 16 - LocalGet : 23 - LocalSet : 19 - Loop : 16 - MemoryCopy : 1 - MemoryFill : 2 - MemoryInit : 2 - Nop : 23 - RefFunc : 7 - RefNull : 1 - Return : 5 - SIMDExtract : 2 - Select : 4 - Store : 3 - StructNew : 1 - TupleMake : 2 - Unary : 33 - Unreachable : 20 + [tags] : 1 + [total] : 526 + [vars] : 8 + Binary : 69 + Block : 74 + Break : 11 + Call : 10 + Const : 100 + Drop : 1 + GlobalGet : 32 + GlobalSet : 33 + I31Get : 1 + I31New : 3 + If : 23 + Load : 19 + LocalGet : 40 + LocalSet : 23 + Loop : 10 + Nop : 17 + RefAs : 2 + RefFunc : 5 + RefIsNull : 1 + RefNull : 3 + Return : 2 + Select : 1 + Store : 1 + StructNew : 2 + TupleMake : 3 + Unary : 23 + Unreachable : 17 |