Skip to content

Commit 46ebbc2

Browse files
committed
[lld][WebAssembly] Allow linker-synthetic symbols to be undefine when building shared libraries
Fixes: #103592
1 parent 449f84f commit 46ebbc2

File tree

3 files changed

+95
-13
lines changed

3 files changed

+95
-13
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
## Check that synthetic data-layout symbols such as __heap_base and __heap_end
2+
## can be referenced from shared libraries and pie executables without
3+
## generating undefined symbols.
4+
5+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
6+
# RUN: wasm-ld --experimental-pic -pie --import-memory -o %t.wasm %t.o
7+
# RUN: obj2yaml %t.wasm | FileCheck %s
8+
# RUN: wasm-ld --experimental-pic -shared -o %t.so %t.o
9+
# RUN: obj2yaml %t.so | FileCheck %s
10+
11+
.globl _start
12+
13+
_start:
14+
.functype _start () -> ()
15+
i32.const __heap_base@GOT
16+
drop
17+
i32.const __heap_end@GOT
18+
drop
19+
i32.const __stack_low@GOT
20+
drop
21+
i32.const __stack_high@GOT
22+
drop
23+
i32.const __global_base@GOT
24+
drop
25+
i32.const __data_end@GOT
26+
drop
27+
end_function
28+
29+
# CHECK: - Type: IMPORT
30+
# CHECK-NEXT: Imports:
31+
# CHECK-NEXT: - Module: env
32+
# CHECK-NEXT: Field: memory
33+
# CHECK-NEXT: Kind: MEMORY
34+
# CHECK-NEXT: Memory:
35+
# CHECK-NEXT: Minimum: 0x0
36+
# CHECK-NEXT: - Module: env
37+
# CHECK-NEXT: Field: __memory_base
38+
# CHECK-NEXT: Kind: GLOBAL
39+
# CHECK-NEXT: GlobalType: I32
40+
# CHECK-NEXT: GlobalMutable: false
41+
# CHECK-NEXT: - Module: env
42+
# CHECK-NEXT: Field: __table_base
43+
# CHECK-NEXT: Kind: GLOBAL
44+
# CHECK-NEXT: GlobalType: I32
45+
# CHECK-NEXT: GlobalMutable: false
46+
# CHECK-NEXT: - Module: GOT.mem
47+
# CHECK-NEXT: Field: __heap_base
48+
# CHECK-NEXT: Kind: GLOBAL
49+
# CHECK-NEXT: GlobalType: I32
50+
# CHECK-NEXT: GlobalMutable: true
51+
# CHECK-NEXT: - Module: GOT.mem
52+
# CHECK-NEXT: Field: __heap_end
53+
# CHECK-NEXT: Kind: GLOBAL
54+
# CHECK-NEXT: GlobalType: I32
55+
# CHECK-NEXT: GlobalMutable: true
56+
# CHECK-NEXT: - Module: GOT.mem
57+
# CHECK-NEXT: Field: __stack_low
58+
# CHECK-NEXT: Kind: GLOBAL
59+
# CHECK-NEXT: GlobalType: I32
60+
# CHECK-NEXT: GlobalMutable: true
61+
# CHECK-NEXT: - Module: GOT.mem
62+
# CHECK-NEXT: Field: __stack_high
63+
# CHECK-NEXT: Kind: GLOBAL
64+
# CHECK-NEXT: GlobalType: I32
65+
# CHECK-NEXT: GlobalMutable: true
66+
# CHECK-NEXT: - Module: GOT.mem
67+
# CHECK-NEXT: Field: __global_base
68+
# CHECK-NEXT: Kind: GLOBAL
69+
# CHECK-NEXT: GlobalType: I32
70+
# CHECK-NEXT: GlobalMutable: true
71+
# CHECK-NEXT: - Module: GOT.mem
72+
# CHECK-NEXT: Field: __data_end
73+
# CHECK-NEXT: Kind: GLOBAL
74+
# CHECK-NEXT: GlobalType: I32
75+
# CHECK-NEXT: GlobalMutable: true

lld/wasm/Driver.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,8 @@ static void createSyntheticSymbols() {
965965
} else {
966966
// For non-PIC code
967967
WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true);
968+
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
969+
WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
968970
WasmSym::stackPointer->markLive();
969971
}
970972

@@ -986,18 +988,23 @@ static void createOptionalSymbols() {
986988

987989
WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");
988990

989-
if (!ctx.arg.shared)
990-
WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
991-
992-
if (!ctx.isPic) {
993-
WasmSym::stackLow = symtab->addOptionalDataSymbol("__stack_low");
994-
WasmSym::stackHigh = symtab->addOptionalDataSymbol("__stack_high");
995-
WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
996-
WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
997-
WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end");
998-
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
999-
WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
1000-
}
991+
auto addDataLayoutSymbol = [&](StringRef s) -> DefinedData * {
992+
// Data layout symbols are either defined by the lld, or (in the case
993+
// of PIC code) defined by the dynamic linker / embedder.
994+
if (ctx.isPic) {
995+
ctx.arg.allowUndefinedSymbols.insert(s);
996+
return nullptr;
997+
} else {
998+
return symtab->addOptionalDataSymbol(s);
999+
}
1000+
};
1001+
1002+
WasmSym::dataEnd = addDataLayoutSymbol("__data_end");
1003+
WasmSym::stackLow = addDataLayoutSymbol("__stack_low");
1004+
WasmSym::stackHigh = addDataLayoutSymbol("__stack_high");
1005+
WasmSym::globalBase = addDataLayoutSymbol("__global_base");
1006+
WasmSym::heapBase = addDataLayoutSymbol("__heap_base");
1007+
WasmSym::heapEnd = addDataLayoutSymbol("__heap_end");
10011008

10021009
// For non-shared memory programs we still need to define __tls_base since we
10031010
// allow object files built with TLS to be linked into single threaded

lld/wasm/Symbols.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ struct WasmSym {
560560
// Symbol whose value is the size of the TLS block.
561561
static GlobalSymbol *tlsSize;
562562

563-
// __tls_size
563+
// __tls_align
564564
// Symbol whose value is the alignment of the TLS block.
565565
static GlobalSymbol *tlsAlign;
566566

0 commit comments

Comments
 (0)