summaryrefslogtreecommitdiff
path: root/src/passes/SafeHeap.cpp
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2022-01-19 17:43:22 -0800
committerGitHub <noreply@github.com>2022-01-19 17:43:22 -0800
commitc918679ec50d4a404bd06244e79691651bdee95b (patch)
tree77604915d9fe2d1d2ec5c211f9626226c50ec852 /src/passes/SafeHeap.cpp
parentb9fdc3b1155c48749f48f5b530d8ab295ea3185b (diff)
downloadbinaryen-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.cpp55
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