diff options
Diffstat (limited to 'src/tools/fuzzing.h')
-rw-r--r-- | src/tools/fuzzing.h | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index b8434353a..7b47dea8f 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -255,6 +255,7 @@ private: } void setupMemory() { + // Add memory itself MemoryUtils::ensureExists(wasm.memory); if (features.hasBulkMemory()) { size_t memCovered = 0; @@ -283,6 +284,41 @@ private: wasm.memory.segments[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.makeSetLocal(0, builder.makeConst(Literal(uint32_t(5381)))) + ); + for (Index i = 0; i < USABLE_MEMORY; i++) { + contents.push_back( + builder.makeSetLocal(0, + builder.makeBinary(XorInt32, + builder.makeBinary(AddInt32, + builder.makeBinary(ShlInt32, + builder.makeGetLocal(0, i32), + builder.makeConst(Literal(uint32_t(5))) + ), + builder.makeGetLocal(0, i32) + ), + builder.makeLoad(1, false, i, 1, builder.makeConst(Literal(uint32_t(0))), i32) + ) + ) + ); + } + contents.push_back( + builder.makeGetLocal(0, i32) + ); + auto* body = builder.makeBlock(contents); + auto* hasher = wasm.addFunction(builder.makeFunction("hashMemory", std::vector<Type>{}, i32, { i32 }, body)); + hasher->type = ensureFunctionType(getSig(hasher), &wasm)->name; + wasm.addExport(builder.makeExport(hasher->name, hasher->name, ExternalKind::Function)); } void setupTable() { @@ -675,6 +711,10 @@ private: invoke = builder.makeDrop(invoke); } invocations.push_back(invoke); + // log out memory in some cases + if (oneIn(2)) { + invocations.push_back(makeMemoryHashLogging()); + } } if (invocations.empty()) return; auto* invoker = new Function; @@ -770,7 +810,13 @@ private: Expression* _makenone() { auto choice = upTo(100); - if (choice < LOGGING_PERCENT) return makeLogging(); + if (choice < LOGGING_PERCENT) { + if (choice < LOGGING_PERCENT / 2) { + return makeLogging(); + } else { + return makeMemoryHashLogging(); + } + } choice = upTo(100); if (choice < 50) return makeSetLocal(none); if (choice < 60) return makeBlock(none); @@ -1814,6 +1860,11 @@ private: return builder.makeCall(std::string("log-") + printType(type), { make(type) }, none); } + Expression* makeMemoryHashLogging() { + auto* hash = builder.makeCall(std::string("hashMemory"), {}, i32); + return builder.makeCall(std::string("log-i32"), { hash }, none); + } + // special getters Type getType() { |