diff --git a/lld/test/wasm/shared-memory.yaml b/lld/test/wasm/shared-memory.yaml --- 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 @@ 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 --- 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 @@ ; 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 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -308,20 +308,19 @@ 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 @@ 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 @@ 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)); } }