Skip to content

Commit

Permalink
Fuzzer: Shuffle exports (#7199)
Browse files Browse the repository at this point in the history
This adds more variety in some situations.
  • Loading branch information
kripken authored Jan 9, 2025
1 parent 666c9df commit b41327e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/tools/fuzzing.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class TranslateToFuzzReader {
void addTag();
void finalizeMemory();
void finalizeTable();
void shuffleExports();
void prepareHangLimitSupport();
void addHangLimitSupport();
void addImportLoggingSupport();
Expand Down
32 changes: 32 additions & 0 deletions src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ void TranslateToFuzzReader::build() {
addHashMemorySupport();
}
finalizeTable();
shuffleExports();
}

void TranslateToFuzzReader::setupMemory() {
Expand Down Expand Up @@ -746,6 +747,37 @@ void TranslateToFuzzReader::finalizeTable() {
}
}

void TranslateToFuzzReader::shuffleExports() {
// Randomly ordering the exports is useful for a few reasons. First, initial
// content may have a natural order in which to execute things (an "init"
// export first, for example), and changing that order may lead to very
// different execution. Second, even in the fuzzer's own random content there
// is a "direction", since we generate as we go (e.g. no function calls a
// later function that does not exist yet / will be created later), and also
// we emit invokes for a function right after it (so we end up calling the
// same code several times in succession, but interleaving it with others may
// find more things). But we also keep a good chance for the natural order
// here, as it may help some initial content.
if (wasm.exports.empty() || oneIn(2)) {
return;
}

// Sort the exports in the simple Fisher-Yates manner.
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
for (Index i = 0; i < wasm.exports.size() - 1; i++) {
// Pick the index of the item to place at index |i|. The number of items to
// pick from begins at the full length, then decreases with i.
auto j = i + upTo(wasm.exports.size() - i);

// Swap the item over here.
if (j != i) {
std::swap(wasm.exports[i], wasm.exports[j]);
}
}

wasm.updateMaps();
}

void TranslateToFuzzReader::prepareHangLimitSupport() {
HANG_LIMIT_GLOBAL = Names::getValidGlobalName(wasm, "hangLimit");
}
Expand Down

0 comments on commit b41327e

Please sign in to comment.