diff options
Diffstat (limited to 'src/wasm/wasm-emscripten.cpp')
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 00a3eb6b7..8463354e8 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -397,6 +397,32 @@ private: Global* stackPointer; }; +// lld can sometimes produce a build with an imported mutable __stack_pointer +// (i.e. when linking with -fpie). This method internalizes the +// __stack_pointer and initializes it from an immutable global instead. +// For -shared builds we instead call replaceStackPointerGlobal. +void EmscriptenGlueGenerator::internalizeStackPointerGlobal() { + Global* stackPointer = getStackPointerGlobal(); + if (!stackPointer || !stackPointer->imported() || !stackPointer->mutable_) { + return; + } + + Name internalName = stackPointer->name; + Name externalName = internalName.c_str() + std::string("_import"); + + // Rename the imported global, and make it immutable + stackPointer->name = externalName; + stackPointer->mutable_ = false; + wasm.updateMaps(); + + // Create a new global with the old name that is not imported. + Builder builder(wasm); + auto* init = builder.makeGlobalGet(externalName, stackPointer->type); + auto* sp = builder.makeGlobal( + internalName, stackPointer->type, init, Builder::Mutable); + wasm.addGlobal(sp); +} + void EmscriptenGlueGenerator::replaceStackPointerGlobal() { Global* stackPointer = getStackPointerGlobal(); if (!stackPointer) { |