diff --git a/lld/test/wasm/global-base.test b/lld/test/wasm/global-base.test new file mode 100644 --- /dev/null +++ b/lld/test/wasm/global-base.test @@ -0,0 +1,71 @@ +RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o + +RUN: wasm-ld --export=__global_base --export=__data_end --allow-undefined -o %t.wasm %t.o +RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-1024 +CHECK-1024: - Type: GLOBAL +CHECK-1024-NEXT: Globals: +CHECK-1024-NEXT: - Index: 0 +CHECK-1024-NEXT: Type: I32 +CHECK-1024-NEXT: Mutable: true +CHECK-1024-NEXT: InitExpr: +CHECK-1024-NEXT: Opcode: I32_CONST +CHECK-1024-NEXT: Value: 66560 +CHECK-1024-NEXT: - Index: 1 +CHECK-1024-NEXT: Type: I32 +CHECK-1024-NEXT: Mutable: false +CHECK-1024-NEXT: InitExpr: +CHECK-1024-NEXT: Opcode: I32_CONST +CHECK-1024-NEXT: Value: 1024 +CHECK-1024-NEXT: - Index: 2 +CHECK-1024-NEXT: Type: I32 +CHECK-1024-NEXT: Mutable: false +CHECK-1024-NEXT: InitExpr: +CHECK-1024-NEXT: Opcode: I32_CONST +CHECK-1024-NEXT: Value: 1024 + +CHECK-1024: - Type: EXPORT +CHECK-1024-NEXT: Exports: +CHECK-1024-NEXT: - Name: memory +CHECK-1024-NEXT: Kind: MEMORY +CHECK-1024-NEXT: Index: 0 +CHECK-1024-NEXT: - Name: __data_end +CHECK-1024-NEXT: Kind: GLOBAL +CHECK-1024-NEXT: Index: 1 +CHECK-1024-NEXT: - Name: __global_base +CHECK-1024-NEXT: Kind: GLOBAL +CHECK-1024-NEXT: Index: 2 + +RUN: wasm-ld --export=__global_base --export=__data_end --allow-undefined --global-base=16777216 -o %t.wasm %t.o +RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-16777216 +CHECK-16777216: - Type: GLOBAL +CHECK-16777216-NEXT: Globals: +CHECK-16777216-NEXT: - Index: 0 +CHECK-16777216-NEXT: Type: I32 +CHECK-16777216-NEXT: Mutable: true +CHECK-16777216-NEXT: InitExpr: +CHECK-16777216-NEXT: Opcode: I32_CONST +CHECK-16777216-NEXT: Value: 16842752 +CHECK-16777216-NEXT: - Index: 1 +CHECK-16777216-NEXT: Type: I32 +CHECK-16777216-NEXT: Mutable: false +CHECK-16777216-NEXT: InitExpr: +CHECK-16777216-NEXT: Opcode: I32_CONST +CHECK-16777216-NEXT: Value: 16777216 +CHECK-16777216-NEXT: - Index: 2 +CHECK-16777216-NEXT: Type: I32 +CHECK-16777216-NEXT: Mutable: false +CHECK-16777216-NEXT: InitExpr: +CHECK-16777216-NEXT: Opcode: I32_CONST +CHECK-16777216-NEXT: Value: 16777216 + +CHECK-16777216: - Type: EXPORT +CHECK-16777216-NEXT: Exports: +CHECK-16777216-NEXT: - Name: memory +CHECK-16777216-NEXT: Kind: MEMORY +CHECK-16777216-NEXT: Index: 0 +CHECK-16777216-NEXT: - Name: __data_end +CHECK-16777216-NEXT: Kind: GLOBAL +CHECK-16777216-NEXT: Index: 1 +CHECK-16777216-NEXT: - Name: __global_base +CHECK-16777216-NEXT: Kind: GLOBAL +CHECK-16777216-NEXT: Index: 2 diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -482,6 +482,7 @@ WasmSym::StackPointer = Symtab->addSyntheticGlobal( "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); WasmSym::DataEnd = Symtab->addOptionalDataSymbol("__data_end"); + WasmSym::GlobalBase = Symtab->addOptionalDataSymbol("__global_base"); WasmSym::HeapBase = Symtab->addOptionalDataSymbol("__heap_base"); } diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -415,6 +415,10 @@ // linker-generated symbols struct WasmSym { + // __global_base + // Symbol marking the start of the global section. + static DefinedData *GlobalBase; + // __stack_pointer // Global that holds the address of the top of the explicit value stack in // linear memory. diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -28,6 +28,7 @@ DefinedFunction *WasmSym::ApplyRelocs; DefinedData *WasmSym::DsoHandle; DefinedData *WasmSym::DataEnd; +DefinedData *WasmSym::GlobalBase; DefinedData *WasmSym::HeapBase; GlobalSymbol *WasmSym::StackPointer; UndefinedGlobal *WasmSym::TableBase; diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -224,6 +224,9 @@ log("mem: global base = " + Twine(Config->GlobalBase)); } + if (WasmSym::GlobalBase) + WasmSym::GlobalBase->setVirtualAddress(Config->GlobalBase); + uint32_t DataStart = MemoryPtr; // Arbitrarily set __dso_handle handle to point to the start of the data