diff options
author | Alon Zakai <azakai@google.com> | 2023-03-08 12:11:50 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-08 12:11:50 -0800 |
commit | e03aa8931bc36fdf1f249e78d77cc14b4929c559 (patch) | |
tree | 0c589c538815ef7517729066c094f0688c71e292 /src | |
parent | 88b45a5a711678e789785f47701f9ae66131261f (diff) | |
download | binaryen-e03aa8931bc36fdf1f249e78d77cc14b4929c559.tar.gz binaryen-e03aa8931bc36fdf1f249e78d77cc14b4929c559.tar.bz2 binaryen-e03aa8931bc36fdf1f249e78d77cc14b4929c559.zip |
Fuzzer: Pick from existing heap types in the module (#5539)
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/fuzzing.h | 4 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 47 |
2 files changed, 46 insertions, 5 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 5529a14a8..830e204f8 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -109,6 +109,9 @@ private: std::vector<Type> loggableTypes; + // The heap types we can pick from to generate instructions. + std::vector<HeapType> interestingHeapTypes; + Index numAddedFunctions = 0; // RAII helper for managing the state used to create a single function. @@ -315,6 +318,7 @@ private: Type getStorableType(); Type getLoggableType(); bool isLoggableType(Type type); + Nullability getNullability(); Nullability getSubType(Nullability nullability); HeapType getSubType(HeapType type); Type getSubType(Type type); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 1159dcb0c..3ef721db9 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -15,6 +15,7 @@ */ #include "tools/fuzzing.h" +#include "ir/module-utils.h" #include "ir/type-updating.h" #include "tools/fuzzing/heap-types.h" #include "tools/fuzzing/parameters.h" @@ -168,6 +169,7 @@ void TranslateToFuzzReader::build() { if (allowMemory) { setupMemory(); } + setupHeapTypes(); setupTables(); setupGlobals(); if (wasm.features.hasExceptionHandling()) { @@ -270,6 +272,18 @@ void TranslateToFuzzReader::setupMemory() { } } +void TranslateToFuzzReader::setupHeapTypes() { + // Start with any existing heap types in the module, which may exist in any + // initial content we began with. + auto possibleHeapTypes = ModuleUtils::collectHeapTypes(wasm); + + // TODO: use heap type fuzzer to add new types in addition to the previous + + // Filter away uninhabitable heap types, that is, heap types that we cannot + // construct, like a type with a non-nullable reference to itself. + interestingHeapTypes = HeapTypeGenerator::getInhabitable(possibleHeapTypes); +} + // TODO(reference-types): allow the fuzzer to create multiple tables void TranslateToFuzzReader::setupTables() { // Ensure a funcref element segment and table exist. Segments with more @@ -3070,7 +3084,11 @@ Expression* TranslateToFuzzReader::makeMemoryFill() { } Type TranslateToFuzzReader::getSingleConcreteType() { - // TODO: Nontrivial reference types. + if (wasm.features.hasReferenceTypes() && oneIn(3)) { + auto heapType = pick(interestingHeapTypes); + auto nullability = getNullability(); + return Type(heapType, nullability); + } // Skip (ref func), (ref extern), and (ref i31) for now // because there is no way to create them in globals. TODO. using WeightedOption = FeatureOptions<Type>::WeightedOption; @@ -3100,6 +3118,11 @@ Type TranslateToFuzzReader::getSingleConcreteType() { } Type TranslateToFuzzReader::getReferenceType() { + if (wasm.features.hasReferenceTypes() && oneIn(2)) { + auto heapType = pick(interestingHeapTypes); + auto nullability = getNullability(); + return Type(heapType, nullability); + } return pick(FeatureOptions<Type>() // TODO: Add externref here. .add(FeatureSet::ReferenceTypes, Type(HeapType::func, Nullable)) @@ -3117,6 +3140,15 @@ Type TranslateToFuzzReader::getReferenceType() { } Type TranslateToFuzzReader::getEqReferenceType() { + if (oneIn(2)) { + // Try to find an interesting eq-compatible type. + auto heapType = pick(interestingHeapTypes); + if (HeapType::isSubType(heapType, HeapType::eq)) { + auto nullability = getNullability(); + return Type(heapType, nullability); + } + // Otherwise continue below. + } return pick( FeatureOptions<Type>().add(FeatureSet::ReferenceTypes | FeatureSet::GC, Type(HeapType::eq, Nullable), @@ -3180,10 +3212,7 @@ bool TranslateToFuzzReader::isLoggableType(Type type) { loggableTypes.end(); } -Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { - if (nullability == NonNullable) { - return NonNullable; - } +Nullability TranslateToFuzzReader::getNullability() { // Without wasm GC, avoid non-nullable types as we cannot create any values // of such types. For example, reference types adds eqref, but there is no // way to create such a value, only to receive it from the outside, while GC @@ -3196,7 +3225,15 @@ Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { return Nullable; } +Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { + if (nullability == NonNullable) { + return NonNullable; + } + return getNullability(); +} + HeapType TranslateToFuzzReader::getSubType(HeapType type) { + // TODO: pick from heapTypes if (oneIn(2)) { return type; } |