[lld] 1b3e376 - [lld][ELF] --wrap: Make X weak when __real_X is to avoid undefined symbol errors (#98297)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 18:38:54 PDT 2024
Author: Alexander Qi
Date: 2024-07-10T18:38:52-07:00
New Revision: 1b3e376ec0a77f7d7d20d0d32047678dafa142ae
URL: https://github.com/llvm/llvm-project/commit/1b3e376ec0a77f7d7d20d0d32047678dafa142ae
DIFF: https://github.com/llvm/llvm-project/commit/1b3e376ec0a77f7d7d20d0d32047678dafa142ae.diff
LOG: [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.
Added:
lld/test/ELF/wrap-weak.s
Modified:
lld/ELF/Driver.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a4863d6717efb..abfa313bfef0e 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2551,8 +2551,12 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
// If __real_ is referenced, pull in the symbol if it is lazy. Do this after
// processing __wrap_ as that may have referenced __real_.
StringRef realName = saver().save("__real_" + name);
- if (symtab.find(realName))
+ if (Symbol *real = symtab.find(realName)) {
symtab.addUnusedUndefined(name, sym->binding);
+ // Update sym's binding, which will replace real's later in
+ // SymbolTable::wrap.
+ sym->binding = real->binding;
+ }
Symbol *real = symtab.addUnusedUndefined(realName);
v.push_back({sym, real, wrap});
diff --git a/lld/test/ELF/wrap-weak.s b/lld/test/ELF/wrap-weak.s
new file mode 100644
index 0000000000000..b853eaa909dc8
--- /dev/null
+++ b/lld/test/ELF/wrap-weak.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: ld.lld -shared -o %t.so %t.o -wrap foo
+
+# RUN: llvm-readelf --dyn-syms %t.so | FileCheck %s
+
+# CHECK: Symbol table '.dynsym' contains 4 entries:
+# CHECK: NOTYPE LOCAL DEFAULT UND
+# CHECK-NEXT: NOTYPE WEAK DEFAULT UND foo
+# CHECK-NEXT: NOTYPE GLOBAL DEFAULT [[#]] __wrap_foo
+# CHECK-NEXT: NOTYPE GLOBAL DEFAULT [[#]] _start
+
+.global foo
+.weak __real_foo
+
+.global __wrap_foo
+__wrap_foo:
+ movq __real_foo at gotpcrel(%rip), %rax
+ call __real_foo at plt
+
+.global _start
+_start:
+ call foo at plt
More information about the llvm-commits
mailing list