[lld] c496d84 - [lld][WebAssembly] Handle 4gb max memories

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 13:06:50 PDT 2020


Author: Thomas Lively
Date: 2020-04-09T13:06:41-07:00
New Revision: c496d84b4f316d8189d3fc91ac08493e5c50ee12

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

LOG: [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

Added: 
    

Modified: 
    lld/test/wasm/large-memory.test
    lld/wasm/Config.h
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/large-memory.test b/lld/test/wasm/large-memory.test
index 8d403b5f6ab5..0713a8b02dd1 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 b396bda93d58..1ba28899e64d 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 9f4b6adc48bb..d1ada22f684a 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));
   }


        


More information about the llvm-commits mailing list