[llvm-branch-commits] [lld] 1bb7987 - [lld][WebAssembly] Set memory limits correctly for PIC + shared memory

Sam Clegg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Dec 3 18:24:48 PST 2020


Author: Sam Clegg
Date: 2020-12-03T18:14:28-08:00
New Revision: 1bb79875e4b8f9018142a5155ca3f7df37778419

URL: https://github.com/llvm/llvm-project/commit/1bb79875e4b8f9018142a5155ca3f7df37778419
DIFF: https://github.com/llvm/llvm-project/commit/1bb79875e4b8f9018142a5155ca3f7df37778419.diff

LOG: [lld][WebAssembly] Set memory limits correctly for PIC + shared memory

Don't early return from layoutMemory in PIC mode before we have set the
memory limits.

This matters in particular with shared-memory + PIC because shared
memories require maximum size.

Secondly, when we need a maximum, but the user does not supply one,
default to MAX_INT rather than 0 (defaulting to zero is completely
useless and means that building with -shared didn't previously work at
all without --maximum-memory, because zero is never big enough).

This is part of an ongoing effort to enable dynamic linking with
threads in emscripten.

See https://github.com/emscripten-core/emscripten/issues/3494

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

Added: 
    

Modified: 
    lld/test/wasm/shared-memory.yaml
    lld/test/wasm/shared.ll
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/shared-memory.yaml b/lld/test/wasm/shared-memory.yaml
index 11dd6b166fbf..8710a06db3f7 100644
--- a/lld/test/wasm/shared-memory.yaml
+++ b/lld/test/wasm/shared-memory.yaml
@@ -1,6 +1,6 @@
 # RUN: yaml2obj %s -o %t1.o
 
-# RUN: not wasm-ld --no-entry --shared-memory %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED-NO-MAX
+# RUN: wasm-ld --no-entry --shared-memory --features=atomics,bulk-memory %t1.o -o - | obj2yaml | FileCheck %s --check-prefix SHARED
 
 # RUN: not wasm-ld --no-entry --shared-memory --max-memory=100000 %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED-UNALIGNED
 
@@ -56,8 +56,6 @@ Sections:
         Flags:           [  ]
 ...
 
-# SHARED-NO-MAX: maximum memory too small, 66576 bytes needed{{$}}
-
 # SHARED-UNALIGNED: maximum memory must be 65536-byte aligned{{$}}
 
 # SHARED-NO-ATOMICS: 'atomics' feature must be used in order to use shared memory

diff  --git a/lld/test/wasm/shared.ll b/lld/test/wasm/shared.ll
index 3740ea336b73..98751adda489 100644
--- a/lld/test/wasm/shared.ll
+++ b/lld/test/wasm/shared.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
-; RUN: wasm-ld -shared -o %t.wasm %t.o
+; RUN: wasm-ld --experimental-pic -shared -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 target triple = "wasm32-unknown-emscripten"
@@ -67,7 +67,7 @@ declare void @func_external()
 ; CHECK-NEXT:         Field:           memory
 ; CHECK-NEXT:         Kind:            MEMORY
 ; CHECK-NEXT:         Memory:
-; CHECK-NEXT:           Initial:       0x0
+; CHECK-NEXT:           Initial:       0x1
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           __indirect_function_table
 ; CHECK-NEXT:         Kind:            TABLE

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 89f79aea8bd0..d927b71e1d97 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -308,20 +308,19 @@ void Writer::layoutMemory() {
 
   uint64_t staticDataSize = memoryPtr - dataStart;
   log("mem: static data = " + Twine(staticDataSize));
-  if (config->isPic) {
+  if (config->isPic)
     out.dylinkSec->memSize = staticDataSize;
-    return;
-  }
 
   if (!config->stackFirst)
     placeStack();
 
-  // Set `__heap_base` to directly follow the end of the stack or global data.
-  // The fact that this comes last means that a malloc/brk implementation
-  // can grow the heap at runtime.
-  log("mem: heap base   = " + Twine(memoryPtr));
-  if (WasmSym::heapBase)
+  if (WasmSym::heapBase) {
+    // Set `__heap_base` to directly follow the end of the stack or global data.
+    // The fact that this comes last means that a malloc/brk implementation
+    // can grow the heap at runtime.
+    log("mem: heap base   = " + Twine(memoryPtr));
     WasmSym::heapBase->setVirtualAddress(memoryPtr);
+  }
 
   uint64_t maxMemorySetting = 1ULL
                               << (config->is64.getValueOr(false) ? 48 : 32);
@@ -340,8 +339,7 @@ void Writer::layoutMemory() {
       alignTo(memoryPtr, WasmPageSize) / WasmPageSize;
   log("mem: total pages = " + Twine(out.memorySec->numMemoryPages));
 
-  // Check max if explicitly supplied or required by shared memory
-  if (config->maxMemory != 0 || config->sharedMemory) {
+  if (config->maxMemory != 0) {
     if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize))
       error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
     if (memoryPtr > config->maxMemory)
@@ -349,7 +347,20 @@ void Writer::layoutMemory() {
     if (config->maxMemory > maxMemorySetting)
       error("maximum memory too large, cannot be greater than " +
             Twine(maxMemorySetting));
-    out.memorySec->maxMemoryPages = config->maxMemory / WasmPageSize;
+  }
+
+  // Check max if explicitly supplied or required by shared memory
+  if (config->maxMemory != 0 || config->sharedMemory) {
+    uint64_t max = config->maxMemory;
+    if (max == 0) {
+      // If no maxMemory config was supplied but we are building with
+      // shared memory, we need to pick a sensible upper limit.
+      if (config->isPic)
+        max = maxMemorySetting;
+      else
+        max = alignTo(memoryPtr, WasmPageSize);
+    }
+    out.memorySec->maxMemoryPages = max / WasmPageSize;
     log("mem: max pages   = " + Twine(out.memorySec->maxMemoryPages));
   }
 }


        


More information about the llvm-branch-commits mailing list