[lld] [lld][WebAssembly] Allow linker-synthetic symbols to be undefine when building shared libraries (PR #128223)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 21 11:58:52 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-wasm
Author: Sam Clegg (sbc100)
<details>
<summary>Changes</summary>
… building shared libraries
Fixes: #<!-- -->103592
---
Full diff: https://github.com/llvm/llvm-project/pull/128223.diff
3 Files Affected:
- (added) lld/test/wasm/shared-synthetic-symbols.s (+69)
- (modified) lld/wasm/Driver.cpp (+19-12)
- (modified) lld/wasm/Symbols.h (+1-1)
``````````diff
diff --git a/lld/test/wasm/shared-synthetic-symbols.s b/lld/test/wasm/shared-synthetic-symbols.s
new file mode 100644
index 0000000000000..0fd5a9516a94e
--- /dev/null
+++ b/lld/test/wasm/shared-synthetic-symbols.s
@@ -0,0 +1,69 @@
+## Check that synthetic data-layout symbols such as __heap_base and __heap_end
+## can be references from shared libraries and pie executables without
+## generating undefined symbols.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --experimental-pic -pie -o %t.wasm %t.o
+# RUN: wasm-ld --experimental-pic -shared -o %t.so %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+.globl _start
+
+_start:
+ .functype _start () -> ()
+ i32.const __heap_base at GOT
+ drop
+ i32.const __heap_end at GOT
+ drop
+ i32.const __stack_low at GOT
+ drop
+ i32.const __stack_high at GOT
+ drop
+ i32.const __global_base at GOT
+ drop
+ i32.const __data_end at GOT
+ drop
+ end_function
+
+# CHECK: - Type: IMPORT
+# CHECK-NEXT: Imports:
+# CHECK-NEXT: - Module: env
+# CHECK-NEXT: Field: __memory_base
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: false
+# CHECK-NEXT: - Module: env
+# CHECK-NEXT: Field: __table_base
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: false
+# CHECK-NEXT: - Module: GOT.mem
+# CHECK-NEXT: Field: __heap_base
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: true
+# CHECK-NEXT: - Module: GOT.mem
+# CHECK-NEXT: Field: __heap_end
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: true
+# CHECK-NEXT: - Module: GOT.mem
+# CHECK-NEXT: Field: __stack_low
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: true
+# CHECK-NEXT: - Module: GOT.mem
+# CHECK-NEXT: Field: __stack_high
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: true
+# CHECK-NEXT: - Module: GOT.mem
+# CHECK-NEXT: Field: __global_base
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: true
+# CHECK-NEXT: - Module: GOT.mem
+# CHECK-NEXT: Field: __data_end
+# CHECK-NEXT: Kind: GLOBAL
+# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalMutable: true
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index c3a74dde6480e..89b35ef8d671d 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -965,6 +965,8 @@ static void createSyntheticSymbols() {
} else {
// For non-PIC code
WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true);
+ WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
+ WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
WasmSym::stackPointer->markLive();
}
@@ -986,18 +988,23 @@ static void createOptionalSymbols() {
WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");
- if (!ctx.arg.shared)
- WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
-
- if (!ctx.isPic) {
- WasmSym::stackLow = symtab->addOptionalDataSymbol("__stack_low");
- WasmSym::stackHigh = symtab->addOptionalDataSymbol("__stack_high");
- WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
- WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
- WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end");
- WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
- WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
- }
+ auto addDataLayoutSymbol = [&](StringRef s) -> DefinedData* {
+ // Data layout symbols are either defined by the lld, or (in the case
+ // of PIC code) defined by the dynamic linker / embedder.
+ if (ctx.isPic) {
+ ctx.arg.allowUndefinedSymbols.insert(s);
+ return nullptr;
+ } else {
+ return symtab->addOptionalDataSymbol(s);
+ }
+ };
+
+ WasmSym::dataEnd = addDataLayoutSymbol("__data_end");
+ WasmSym::stackLow = addDataLayoutSymbol("__stack_low");
+ WasmSym::stackHigh = addDataLayoutSymbol("__stack_high");
+ WasmSym::globalBase = addDataLayoutSymbol("__global_base");
+ WasmSym::heapBase = addDataLayoutSymbol("__heap_base");
+ WasmSym::heapEnd = addDataLayoutSymbol("__heap_end");
// For non-shared memory programs we still need to define __tls_base since we
// allow object files built with TLS to be linked into single threaded
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index b409fffc50a6c..4ccb95aa486a1 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -560,7 +560,7 @@ struct WasmSym {
// Symbol whose value is the size of the TLS block.
static GlobalSymbol *tlsSize;
- // __tls_size
+ // __tls_align
// Symbol whose value is the alignment of the TLS block.
static GlobalSymbol *tlsAlign;
``````````
</details>
https://github.com/llvm/llvm-project/pull/128223
More information about the llvm-commits
mailing list