From c496d84b4f316d8189d3fc91ac08493e5c50ee12 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 3 Apr 2020 16:18:29 -0700 Subject: [PATCH] [lld][WebAssembly] Handle 4gb max memories Summary: A previous change (53211a) had updated the argument parsing to handle large max memories, but 4294967296 would still wrap to zero after the options were parsed. This change updates the configuration to use a 64-bit integer to store the max memory to avoid that overflow. Reviewers: sbc100 Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77437 --- lld/test/wasm/large-memory.test | 21 ++++++++++++++++++++- lld/wasm/Config.h | 8 ++++---- lld/wasm/Writer.cpp | 11 +++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lld/test/wasm/large-memory.test b/lld/test/wasm/large-memory.test index 8d403b5..0713a8b 100644 --- a/lld/test/wasm/large-memory.test +++ b/lld/test/wasm/large-memory.test @@ -2,4 +2,23 @@ RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o ; 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 index b396bda..1ba2889 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -46,10 +46,10 @@ struct Configuration { 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 index 9f4b6ad..d1ada22 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -201,7 +201,7 @@ void Writer::writeSections() { // 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 @@ void Writer::layoutMemory() { 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 @@ void Writer::layoutMemory() { 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 @@ void Writer::layoutMemory() { 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)); } -- 2.7.4