diff options
author | Alon Zakai <azakai@google.com> | 2020-08-25 15:22:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-25 15:22:19 -0700 |
commit | 18d678043438937222101290988ff3260053edcd (patch) | |
tree | 2a876261b1e305107a77fdb4ef9636e8ef4a3b2e /src | |
parent | 21a08f751bd641f9658455cbf44ecadbf895f5b2 (diff) | |
download | binaryen-18d678043438937222101290988ff3260053edcd.tar.gz binaryen-18d678043438937222101290988ff3260053edcd.tar.bz2 binaryen-18d678043438937222101290988ff3260053edcd.zip |
SAFE_HEAP: remove fastcomp, prepare for new emscripten approach (#3078)
In fastcomp we implemented emscripten_get_sbrk_ptr in wasm, and
exported _emscripten_get_sbrk_ptr. We don't need that anymore and
can remove it.
However I want to switch us to implementing emscripten_get_sbrk_ptr
in wasm in upstream too, as part of removing DYNAMICTOP_PTR and
other silliness that we have around link (#3043).
This makes us support an export of emscripten_get_sbrk_ptr (no
prefix), and also it makes sure not to instrument that function, which
may contain some memory operations itself, but if we SAFE_HEAP-ify
them we'd get infinite recursion, as the SAFE_HEAP methods need to
call that.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/SafeHeap.cpp | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp index a9ad62820..108739d66 100644 --- a/src/passes/SafeHeap.cpp +++ b/src/passes/SafeHeap.cpp @@ -32,8 +32,7 @@ namespace wasm { static const Name DYNAMICTOP_PTR_IMPORT("DYNAMICTOP_PTR"); -static const Name GET_SBRK_PTR_IMPORT("emscripten_get_sbrk_ptr"); -static const Name GET_SBRK_PTR_EXPORT("_emscripten_get_sbrk_ptr"); +static const Name GET_SBRK_PTR("emscripten_get_sbrk_ptr"); static const Name SBRK("sbrk"); static const Name SEGFAULT_IMPORT("segfault"); static const Name ALIGNFAULT_IMPORT("alignfault"); @@ -66,12 +65,21 @@ static Name getStoreName(Store* curr) { } struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> { + // If the getSbrkPtr function is implemented in the wasm, we must not + // instrument that, as it would lead to infinite recursion of it calling + // SAFE_HEAP_LOAD that calls it and so forth. + Name getSbrkPtr; + bool isFunctionParallel() override { return true; } - AccessInstrumenter* create() override { return new AccessInstrumenter; } + AccessInstrumenter* create() override { + return new AccessInstrumenter(getSbrkPtr); + } + + AccessInstrumenter(Name getSbrkPtr) : getSbrkPtr(getSbrkPtr) {} void visitLoad(Load* curr) { - if (curr->type == Type::unreachable) { + if (getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) { return; } Builder builder(*getModule()); @@ -85,7 +93,7 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> { } void visitStore(Store* curr) { - if (curr->type == Type::unreachable) { + if (getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) { return; } Builder builder(*getModule()); @@ -108,7 +116,7 @@ struct SafeHeap : public Pass { // add imports addImports(module); // instrument loads and stores - AccessInstrumenter().run(runner, module); + AccessInstrumenter(getSbrkPtr).run(runner, module); // add helper checking funcs and imports addGlobals(module, module->features); } @@ -118,24 +126,20 @@ struct SafeHeap : public Pass { void addImports(Module* module) { ImportInfo info(*module); // Older emscripten imports env.DYNAMICTOP_PTR. - // Newer emscripten imports emscripten_get_sbrk_ptr(), which is later - // optimized to have the number in the binary (or in the case of fastcomp, - // emscripten_get_sbrk_ptr is an asm.js library function so it is inside - // the wasm, and discoverable via an export). + // Newer emscripten imports or exports emscripten_get_sbrk_ptr(). if (auto* existing = info.getImportedGlobal(ENV, DYNAMICTOP_PTR_IMPORT)) { dynamicTopPtr = existing->name; - } else if (auto* existing = - info.getImportedFunction(ENV, GET_SBRK_PTR_IMPORT)) { + } else if (auto* existing = info.getImportedFunction(ENV, GET_SBRK_PTR)) { getSbrkPtr = existing->name; - } else if (auto* existing = module->getExportOrNull(GET_SBRK_PTR_EXPORT)) { + } else if (auto* existing = module->getExportOrNull(GET_SBRK_PTR)) { getSbrkPtr = existing->value; } else if (auto* existing = info.getImportedFunction(ENV, SBRK)) { sbrk = existing->name; } else { auto* import = new Function; - import->name = getSbrkPtr = GET_SBRK_PTR_IMPORT; + import->name = getSbrkPtr = GET_SBRK_PTR; import->module = ENV; - import->base = GET_SBRK_PTR_IMPORT; + import->base = GET_SBRK_PTR; import->sig = Signature(Type::none, Type::i32); module->addFunction(import); } |