Skip to content

Commit 617278e

Browse files
authored
[lld][WebAssembly] Fix for shared library symbols WRT replacing lazy symbols (llvm#124619)
The rule here, which I'm copying from the ELF linker, is that shared library symbols should take presence, unless the symbol has already be extracted from the archive. e.g: ``` $ wasm-ld foo.a foo.so ref.o // .so wins $ wasm-ld foo.a ref.o foo.so // .a wins ``` In the first case the shared library takes precedence because the lazy symbol is replaced by the .so symbol before it is extracted from the archive. In the second example the ref.o file causes the archive to be exracted before the .so file is processed, so in that case the archive file wins. Fixes: emscripten-core/emscripten#23501
1 parent 28507ac commit 617278e

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

lld/test/wasm/shared-lazy.s

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
## Based on lld/test/ELF/shared-lazy.s
2+
3+
# RUN: rm -rf %t && split-file %s %t && cd %t
4+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten a.s -o a.o
5+
# RUN: wasm-ld a.o --experimental-pic -shared -o a.so
6+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten b.s -o b.o
7+
# RUN: wasm-ld b.o --experimental-pic -shared -o b.so
8+
# RUN: llvm-ar rc a.a a.o
9+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten ref.s -o ref.o
10+
# RUN: wasm-ld a.a b.so ref.o --experimental-pic -shared -o 1.so
11+
# RUN: obj2yaml 1.so | FileCheck %s
12+
# RUN: wasm-ld a.so a.a ref.o --experimental-pic -shared -o 1.so
13+
# RUN: obj2yaml 1.so | FileCheck %s
14+
15+
## The definitions from a.so are used and we don't extract a member from the
16+
## archive.
17+
18+
# CHECK: - Type: IMPORT
19+
# CHECK: - Module: GOT.mem
20+
# CHECK-NEXT: Field: x1
21+
# CHECK-NEXT: Kind: GLOBAL
22+
# CHECK-NEXT: GlobalType: I32
23+
# CHECK-NEXT: GlobalMutable: true
24+
# CHECK-NEXT: - Module: GOT.mem
25+
# CHECK-NEXT: Field: x2
26+
# CHECK-NEXT: Kind: GLOBAL
27+
# CHECK-NEXT: GlobalType: I32
28+
# CHECK-NEXT: GlobalMutable: true
29+
30+
## The extracted x1 is defined as STB_GLOBAL.
31+
# RUN: wasm-ld ref.o a.a b.so -o 2.so --experimental-pic -shared
32+
# RUN: obj2yaml 2.so | FileCheck %s --check-prefix=CHECK2
33+
# RUN: wasm-ld a.a ref.o b.so -o 2.so --experimental-pic -shared
34+
# RUN: obj2yaml 2.so | FileCheck %s --check-prefix=CHECK2
35+
36+
# CHECK2: - Type: EXPORT
37+
# CHECK2-NEXT: Exports:
38+
# CHECK2-NEXT: - Name: __wasm_call_ctors
39+
# CHECK2-NEXT: Kind: FUNCTION
40+
# CHECK2-NEXT: Index:
41+
# CHECK2-NEXT: - Name: x1
42+
# CHECK2-NEXT: Kind: GLOBAL
43+
# CHECK2-NEXT: Index:
44+
# CHECK2-NEXT: - Name: x2
45+
# CHECK2-NEXT: Kind: GLOBAL
46+
47+
#--- a.s
48+
.section .data.x1,"",@
49+
.global x1
50+
x1:
51+
.byte 0
52+
.size x1, 1
53+
54+
.section .data.x2,"",@
55+
.weak x2
56+
x2:
57+
.byte 0
58+
.size x2, 1
59+
#--- b.s
60+
.section .data.x1,"",@
61+
.globl x1
62+
x1:
63+
.byte 0
64+
.size x1, 1
65+
66+
.section .data.x2,"",@
67+
.globl x2
68+
x2:
69+
.byte 0
70+
.size x2, 1
71+
#--- ref.s
72+
.globl x1
73+
.globl x2
74+
.globl d
75+
.section .data.d,"",@
76+
d:
77+
.int x1
78+
.int x2
79+
.size d, 8

lld/wasm/SymbolTable.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ Symbol *SymbolTable::addSharedFunction(StringRef name, uint32_t flags,
363363
replaceSymbol<SharedFunctionSymbol>(sym, name, flags, file, sig);
364364
};
365365

366-
if (wasInserted) {
366+
if (wasInserted || s->isLazy()) {
367367
replaceSym(s);
368368
return s;
369369
}
@@ -408,10 +408,18 @@ Symbol *SymbolTable::addSharedData(StringRef name, uint32_t flags,
408408
bool wasInserted;
409409
std::tie(s, wasInserted) = insert(name, file);
410410

411-
if (wasInserted || s->isUndefined()) {
411+
if (wasInserted || s->isLazy()) {
412412
replaceSymbol<SharedData>(s, name, flags, file);
413+
return s;
414+
}
415+
416+
// Shared symbols should never replace locally-defined ones
417+
if (s->isDefined()) {
418+
return s;
413419
}
414420

421+
checkDataType(s, file);
422+
replaceSymbol<SharedData>(s, name, flags, file);
415423
return s;
416424
}
417425

0 commit comments

Comments
 (0)