Skip to content

Commit 1b3e376

Browse files
authored
[lld][ELF] --wrap: Make X weak when __real_X is to avoid undefined symbol errors (#98297)
Fix #98294. When you specify --wrap=foo, sometimes foo is undefined in any context. If you declare __real_foo as weak, GNU ld will not attempt to find the strong symbol foo, instead, it generates a weak undefined symbol. This pull request imitates this behavior by copying the binding attribute from __real_foo to foo.
1 parent 80ff3ac commit 1b3e376

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

lld/ELF/Driver.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2551,8 +2551,12 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
25512551
// If __real_ is referenced, pull in the symbol if it is lazy. Do this after
25522552
// processing __wrap_ as that may have referenced __real_.
25532553
StringRef realName = saver().save("__real_" + name);
2554-
if (symtab.find(realName))
2554+
if (Symbol *real = symtab.find(realName)) {
25552555
symtab.addUnusedUndefined(name, sym->binding);
2556+
// Update sym's binding, which will replace real's later in
2557+
// SymbolTable::wrap.
2558+
sym->binding = real->binding;
2559+
}
25562560

25572561
Symbol *real = symtab.addUnusedUndefined(realName);
25582562
v.push_back({sym, real, wrap});

lld/test/ELF/wrap-weak.s

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3+
# RUN: ld.lld -shared -o %t.so %t.o -wrap foo
4+
5+
# RUN: llvm-readelf --dyn-syms %t.so | FileCheck %s
6+
7+
# CHECK: Symbol table '.dynsym' contains 4 entries:
8+
# CHECK: NOTYPE LOCAL DEFAULT UND
9+
# CHECK-NEXT: NOTYPE WEAK DEFAULT UND foo
10+
# CHECK-NEXT: NOTYPE GLOBAL DEFAULT [[#]] __wrap_foo
11+
# CHECK-NEXT: NOTYPE GLOBAL DEFAULT [[#]] _start
12+
13+
.global foo
14+
.weak __real_foo
15+
16+
.global __wrap_foo
17+
__wrap_foo:
18+
movq __real_foo@gotpcrel(%rip), %rax
19+
call __real_foo@plt
20+
21+
.global _start
22+
_start:
23+
call foo@plt

0 commit comments

Comments
 (0)