diff options
author | Alon Zakai <azakai@google.com> | 2021-03-16 12:01:26 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-16 12:01:26 -0700 |
commit | 661ae32122f9f0ba70b03b2d76a41274ce5e4bb2 (patch) | |
tree | 9aab38236630e923b9d2fa7acaf70dae0d1c0415 | |
parent | 5fea332e1e6cf2b00334b617bb1bf399e9394592 (diff) | |
download | binaryen-661ae32122f9f0ba70b03b2d76a41274ce5e4bb2.tar.gz binaryen-661ae32122f9f0ba70b03b2d76a41274ce5e4bb2.tar.bz2 binaryen-661ae32122f9f0ba70b03b2d76a41274ce5e4bb2.zip |
Validate code in global data structures (#3694)
This validation is almost never needed, but it starts to get interesting with
GC, where a global initializer can be an rtt.sub which must be valid.
No tests here as testing requires a further GC fix in a later PR.
-rw-r--r-- | src/wasm/wasm-validator.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 80b7eb874..a057f34b9 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -201,13 +201,21 @@ struct ValidationInfo { struct FunctionValidator : public WalkerPass<PostWalker<FunctionValidator>> { bool isFunctionParallel() override { return true; } - Pass* create() override { return new FunctionValidator(&info); } + Pass* create() override { return new FunctionValidator(*getModule(), &info); } bool modifiesBinaryenIR() override { return false; } ValidationInfo& info; - FunctionValidator(ValidationInfo* info) : info(*info) {} + FunctionValidator(Module& wasm, ValidationInfo* info) : info(*info) { + setModule(&wasm); + } + + // Validate the entire module. + void validate(PassRunner* runner) { run(runner, getModule()); } + + // Validate a specific expression. + void validate(Expression* curr) { walk(curr); } std::unordered_map<Name, std::unordered_set<Type>> breakTypes; std::unordered_set<Name> delegateTargetNames; @@ -2710,6 +2718,7 @@ static void validateGlobals(Module& module, ValidationInfo& info) { !info.quiet) { info.getStream(nullptr) << "(on global " << curr->name << ")\n"; } + FunctionValidator(module, &info).validate(curr->init); }); } @@ -2775,6 +2784,7 @@ static void validateMemory(Module& module, ValidationInfo& info) { segment.data.size(), "segment size should fit in memory (end)"); } + FunctionValidator(module, &info).validate(segment.offset); } // If the memory is imported we don't actually know its initial size. // Specifically wasm dll's import a zero sized memory which is perfectly @@ -2809,6 +2819,7 @@ static void validateTables(Module& module, ValidationInfo& info) { table->initial * Table::kPageSize), segment->offset, "table segment offset should be reasonable"); + FunctionValidator(module, &info).validate(segment->offset); } for (auto name : segment->data) { info.shouldBeTrue( @@ -2879,7 +2890,7 @@ bool WasmValidator::validate(Module& module, Flags flags) { info.quiet = (flags & Quiet) != 0; // parallel wasm logic validation PassRunner runner(&module); - FunctionValidator(&info).run(&runner, &module); + FunctionValidator(module, &info).validate(&runner); // validate globally if (info.validateGlobally) { validateImports(module, info); |