diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 1 | ||||
-rw-r--r-- | src/wasm-emscripten.h | 4 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 26 |
3 files changed, 31 insertions, 0 deletions
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index fd3d21df9..56a6c3b39 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -205,6 +205,7 @@ int main(int argc, const char* argv[]) { generator.generatePostInstantiateFunction(); } else { generator.generateRuntimeFunctions(); + generator.internalizeStackPointerGlobal(); generator.generateMemoryGrowthFunction(); // For side modules these gets called via __post_instantiate if (Function* F = generator.generateAssignGOTEntriesFunction()) { diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h index 1f9b22926..0841708f2 100644 --- a/src/wasm-emscripten.h +++ b/src/wasm-emscripten.h @@ -44,6 +44,10 @@ public: // and restore functions. void replaceStackPointerGlobal(); + // Remove the import of a mutable __stack_pointer and instead initialize the + // stack pointer from an immutable import. + void internalizeStackPointerGlobal(); + std::string generateEmscriptenMetadata(Address staticBump, std::vector<Name> const& initializerFunctions); 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) { |