summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp1
-rw-r--r--src/wasm-emscripten.h4
-rw-r--r--src/wasm/wasm-emscripten.cpp26
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) {