diff --git a/lld/test/wasm/large-memory.test b/lld/test/wasm/large-memory.test --- a/lld/test/wasm/large-memory.test +++ b/lld/test/wasm/large-memory.test @@ -2,4 +2,23 @@ ; Verify we can parse large integers such as when we ask for 2G of total ; memory. -RUN: wasm-ld %t.o -o %t.wasm --max-memory=2147483648 +RUN: wasm-ld %t.o -o %t1.wasm --max-memory=2147483648 +RUN: obj2yaml %t1.wasm | FileCheck %s --check-prefixes=CHECK,CHECK-2G + +; And also 4G of total memory +RUN: wasm-ld %t.o -o %t2.wasm --max-memory=4294967296 +RUN: obj2yaml %t2.wasm | FileCheck %s --check-prefixes=CHECK,CHECK-4G + +CHECK: - Type: MEMORY +CHECK-NEXT: Memories: +CHECK-NEXT: - Flags: [ HAS_MAX ] +CHECK-NEXT: Initial: 0x00000002 +CHECK-2G-NEXT: Maximum: 0x00008000 +CHECK-4G-NEXT: Maximum: 0x00010000 + +; Test error for more than 4G of memory +RUN: not wasm-ld %t.o -o %t3.wasm --initial-memory=4295032832 2>&1 | FileCheck %s --check-prefix INIT-ERROR +RUN: not wasm-ld %t.o -o %t4.wasm --max-memory=4295032832 2>&1 | FileCheck %s --check-prefix MAX-ERROR + +INIT-ERROR: initial memory too large, cannot be greater than 4294967296 +MAX-ERROR: maximum memory too large, cannot be greater than 4294967296 diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -46,10 +46,10 @@ bool stripDebug; bool stackFirst; bool trace; - uint32_t globalBase; - uint32_t initialMemory; - uint32_t maxMemory; - uint32_t zStackSize; + uint64_t globalBase; + uint64_t initialMemory; + uint64_t maxMemory; + uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; unsigned optimize; diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -201,7 +201,7 @@ // rather than overwriting global data, but also increases code size since all // static data loads and stores requires larger offsets. void Writer::layoutMemory() { - uint32_t memoryPtr = 0; + uint64_t memoryPtr = 0; auto placeStack = [&]() { if (config->relocatable || config->isPic) @@ -227,7 +227,7 @@ if (WasmSym::globalBase) WasmSym::globalBase->setVirtualAddress(memoryPtr); - uint32_t dataStart = memoryPtr; + uint64_t dataStart = memoryPtr; // Arbitrarily set __dso_handle handle to point to the start of the data // segments. @@ -286,8 +286,9 @@ error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); if (memoryPtr > config->initialMemory) error("initial memory too small, " + Twine(memoryPtr) + " bytes needed"); - else - memoryPtr = config->initialMemory; + if (config->initialMemory > (1ULL << 32)) + error("initial memory too large, cannot be greater than 4294967296"); + memoryPtr = config->initialMemory; } out.dylinkSec->memSize = memoryPtr; out.memorySec->numMemoryPages = @@ -300,6 +301,8 @@ error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); if (memoryPtr > config->maxMemory) error("maximum memory too small, " + Twine(memoryPtr) + " bytes needed"); + if (config->maxMemory > (1ULL << 32)) + error("maximum memory too large, cannot be greater than 4294967296"); out.memorySec->maxMemoryPages = config->maxMemory / WasmPageSize; log("mem: max pages = " + Twine(out.memorySec->maxMemoryPages)); }