[WebAssembly] Import __stack_pointer when building -pie binaries
authorSam Clegg <sbc@chromium.org>
Thu, 11 Jul 2019 13:13:25 +0000 (13:13 +0000)
committerSam Clegg <sbc@chromium.org>
Thu, 11 Jul 2019 13:13:25 +0000 (13:13 +0000)
The -pie binary doesn't know that layout ahead of time so needs to
import the stack pointer from the embedder, just like we do already
for shared libraries.

This change is needed in order to address:
https://github.com/emscripten-core/emscripten/issues/8915

Differential Revision: https://reviews.llvm.org/D64516

llvm-svn: 365771

lld/test/wasm/pie.ll
lld/wasm/Driver.cpp
lld/wasm/Writer.cpp

index e7aa243..c576e7c 100644 (file)
@@ -40,6 +40,11 @@ define void @_start() {
 ; CHECK-NEXT:           Limits:
 ; CHECK-NEXT:             Initial:         0x00000001
 ; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           __stack_pointer
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         GlobalType:      I32
+; CHECK-NEXT:         GlobalMutable:   true
+; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           __memory_base
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         GlobalType:      I32
index d190dba..3de6995 100644 (file)
@@ -482,11 +482,22 @@ static void createSyntheticSymbols() {
     }
   }
 
-  // The __stack_pointer is imported in the shared library case, and exported
-  // in the non-shared (executable) case.
-  if (config->shared) {
+  if (!config->shared)
+    WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
+
+  if (config->isPic) {
     WasmSym::stackPointer =
         createUndefinedGlobal("__stack_pointer", &mutableGlobalTypeI32);
+    // For PIC code, we import two global variables (__memory_base and
+    // __table_base) from the environment and use these as the offset at
+    // which to load our static data and function table.
+    // See:
+    // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+    WasmSym::memoryBase =
+        createUndefinedGlobal("__memory_base", &globalTypeI32);
+    WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32);
+    WasmSym::memoryBase->markLive();
+    WasmSym::tableBase->markLive();
   } else {
     llvm::wasm::WasmGlobal global;
     global.Type = {WASM_TYPE_I32, true};
@@ -501,24 +512,10 @@ static void createSyntheticSymbols() {
     // See: https://github.com/WebAssembly/mutable-global
     WasmSym::stackPointer = symtab->addSyntheticGlobal(
         "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, stackPointer);
-    WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
     WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
     WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
   }
 
-  if (config->isPic) {
-    // For PIC code, we import two global variables (__memory_base and
-    // __table_base) from the environment and use these as the offset at
-    // which to load our static data and function table.
-    // See:
-    // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
-    WasmSym::memoryBase =
-        createUndefinedGlobal("__memory_base", &globalTypeI32);
-    WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32);
-    WasmSym::memoryBase->markLive();
-    WasmSym::tableBase->markLive();
-  }
-
   WasmSym::dsoHandle = symtab->addSyntheticDataSymbol(
       "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
 }
index 11c4b91..1a35344 100644 (file)
@@ -204,7 +204,7 @@ void Writer::layoutMemory() {
   uint32_t memoryPtr = 0;
 
   auto placeStack = [&]() {
-    if (config->relocatable || config->shared)
+    if (config->relocatable || config->isPic)
       return;
     memoryPtr = alignTo(memoryPtr, stackAlignment);
     if (config->zStackSize != alignTo(config->zStackSize, stackAlignment))