diff options
author | Sam Clegg <sbc@chromium.org> | 2022-01-19 17:43:22 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-19 17:43:22 -0800 |
commit | c918679ec50d4a404bd06244e79691651bdee95b (patch) | |
tree | 77604915d9fe2d1d2ec5c211f9626226c50ec852 /src/passes/SafeHeap.cpp | |
parent | b9fdc3b1155c48749f48f5b530d8ab295ea3185b (diff) | |
download | binaryen-c918679ec50d4a404bd06244e79691651bdee95b.tar.gz binaryen-c918679ec50d4a404bd06244e79691651bdee95b.tar.bz2 binaryen-c918679ec50d4a404bd06244e79691651bdee95b.zip |
SAFE_HEAP: Avoid annotating any function reachable from start function (#4463)
Since https://reviews.llvm.org/D117412 landed it has causes a bunch of
SAFE_HEAP tests in emscripten to start failing, because
`__wasm_apply_data_relocs` can now sometimes be called from with
`__wasm_init_memory` as opposed to directly from the start function.
Diffstat (limited to 'src/passes/SafeHeap.cpp')
-rw-r--r-- | src/passes/SafeHeap.cpp | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp index a90696f2c..068c8ef73 100644 --- a/src/passes/SafeHeap.cpp +++ b/src/passes/SafeHeap.cpp @@ -22,6 +22,7 @@ #include "asmjs/shared-constants.h" #include "ir/bits.h" +#include "ir/find_all.h" #include "ir/import-utils.h" #include "ir/load-utils.h" #include "pass.h" @@ -100,11 +101,30 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> { } }; -struct FindDirectCallees : public WalkerPass<PostWalker<FindDirectCallees>> { -public: - void visitCall(Call* curr) { callees.insert(curr->target); } - std::set<Name> callees; -}; +static std::set<Name> findCalledFunctions(Module* module, Name startFunc) { + std::set<Name> called; + std::vector<Name> toVisit; + + auto addFunction = [&](Name name) { + if (called.insert(name).second) { + toVisit.push_back(name); + } + }; + + if (startFunc.is()) { + addFunction(startFunc); + while (!toVisit.empty()) { + auto next = toVisit.back(); + toVisit.pop_back(); + auto* func = module->getFunction(next); + for (auto* call : FindAll<Call>(func->body).list) { + addFunction(call->target); + } + } + } + + return called; +} struct SafeHeap : public Pass { PassOptions options; @@ -114,24 +134,13 @@ struct SafeHeap : public Pass { // add imports addImports(module); // instrument loads and stores - // We avoid instrumenting the module start function of any function - // that it directly calls. This is because in some cases the linker - // generates `__wasm_init_memory` (either as the start function or - // a function directly called from it) and this function is used in shared - // memory builds to load the passive memory segments, which in turn means - // that value of sbrk() is not available until after it has run. - std::set<Name> ignoreFunctions; - if (module->start.is()) { - // Note that this only finds directly called functions, not transitively - // called ones. That is enough given the current LLVM output as start - // will only contain very specific, linker-generated code - // (__wasm_init_memory etc. as mentioned above). - FindDirectCallees findDirectCallees; - findDirectCallees.walkFunctionInModule(module->getFunction(module->start), - module); - ignoreFunctions = findDirectCallees.callees; - ignoreFunctions.insert(module->start); - } + // We avoid instrumenting the module start function of any function that it + // directly calls. This is because in some cases the linker generates + // `__wasm_init_memory` (either as the start function or a function directly + // called from it) and this function is used in shared memory builds to load + // the passive memory segments, which in turn means that value of sbrk() is + // not available until after it has run. + std::set<Name> ignoreFunctions = findCalledFunctions(module, module->start); ignoreFunctions.insert(getSbrkPtr); AccessInstrumenter(ignoreFunctions).run(runner, module); // add helper checking funcs and imports |