[lld] 2a04f5c - [ELF] Drop unused original symbol after wrapping if not defined
Shoaib Meenai via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 22 16:47:26 PDT 2022
Author: Shoaib Meenai
Date: 2022-04-22T16:47:15-07:00
New Revision: 2a04f5c455c83c443c71a86b1cee653b4c791bef
URL: https://github.com/llvm/llvm-project/commit/2a04f5c455c83c443c71a86b1cee653b4c791bef
DIFF: https://github.com/llvm/llvm-project/commit/2a04f5c455c83c443c71a86b1cee653b4c791bef.diff
LOG: [ELF] Drop unused original symbol after wrapping if not defined
We were previously only omitting the original of a wrapped symbol if it
was not used by an object file and undefined. We can tighten the second
condition to drop any symbol that isn't defined instead, which lets us
drop a previous check (added in https://reviews.llvm.org/D118756) that
was only covering some such symbols.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D124065
Added:
lld/test/ELF/wrap-drop-shared-original.s
Modified:
lld/ELF/Driver.cpp
lld/ELF/SymbolTable.cpp
lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
lld/test/ELF/wrap-lazy.test
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 8f31d48db0198..41620737e1f60 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2179,11 +2179,7 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
continue;
Symbol *sym = symtab->find(name);
- // Avoid wrapping symbols that are lazy and unreferenced at this point, to
- // not create undefined references. The isUsedInRegularObj check handles the
- // case of a weak reference, which we still want to wrap even though it
- // doesn't cause lazy symbols to be extracted.
- if (!sym || (sym->isLazy() && !sym->isUsedInRegularObj))
+ if (!sym)
continue;
Symbol *real = addUnusedUndefined(saver().save("__real_" + name));
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index e067c7d7dcbaf..0dda5dbded470 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -44,7 +44,10 @@ void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
wrap->isUsedInRegularObj = true;
if (real->isUsedInRegularObj)
sym->isUsedInRegularObj = true;
- else if (sym->isUndefined())
+ else if (!sym->isDefined())
+ // Now that all references to sym have been redirected to wrap, if there are
+ // no references to real (which has been redirected to sym), we only need to
+ // keep sym if it was defined, otherwise it's unused and can be dropped.
sym->isUsedInRegularObj = false;
// Now renaming is complete, and no one refers to real. We drop real from
diff --git a/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test b/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
index 613f5033d41c9..49c1fc5a82a27 100644
--- a/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
+++ b/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
@@ -19,10 +19,9 @@
# UNWIND-DISASM-LABEL: <__wrap__Unwind_Resume at plt>:
# UNWIND-DISASM-NEXT: jmpq *[[#]](%rip) # [[#%#x,RELOC]]
-# UNWIND-DYNSYM: Symbol table '.dynsym' contains 5 entries:
+# UNWIND-DYNSYM: Symbol table '.dynsym' contains 4 entries:
# UNWIND-DYNSYM: NOTYPE LOCAL DEFAULT UND
# UNWIND-DYNSYM-NEXT: NOTYPE GLOBAL DEFAULT UND throw
-# UNWIND-DYNSYM-NEXT: NOTYPE GLOBAL DEFAULT UND _Unwind_Resume
# UNWIND-DYNSYM-NEXT: NOTYPE GLOBAL DEFAULT UND __wrap__Unwind_Resume
# UNWIND-DYNSYM-NEXT: FUNC GLOBAL DEFAULT 9 _Z1fv
@@ -43,9 +42,8 @@
# USETLS-DISASM-LABEL: <__wrap_malloc at plt>:
# USETLS-DISASM-NEXT: jmpq *[[#]](%rip) # [[#%#x,RELOC]]
-# USETLS-DYNSYM: Symbol table '.dynsym' contains 6 entries:
+# USETLS-DYNSYM: Symbol table '.dynsym' contains 5 entries:
# USETLS-DYNSYM: NOTYPE LOCAL DEFAULT UND
-# USETLS-DYNSYM-NEXT: NOTYPE GLOBAL DEFAULT UND malloc
# USETLS-DYNSYM-NEXT: NOTYPE GLOBAL DEFAULT UND __wrap_malloc
# USETLS-DYNSYM-NEXT: FUNC GLOBAL DEFAULT 6 f
# USETLS-DYNSYM-NEXT: NOTYPE GLOBAL DEFAULT 6 __emutls_get_address
diff --git a/lld/test/ELF/wrap-drop-shared-original.s b/lld/test/ELF/wrap-drop-shared-original.s
new file mode 100644
index 0000000000000..f3784aa972796
--- /dev/null
+++ b/lld/test/ELF/wrap-drop-shared-original.s
@@ -0,0 +1,48 @@
+## If the original of a wrapped symbol becomes unreferenced after wrapping, it
+## should be dropped from the dynamic symbol table even if defined in a shared
+## library.
+
+# REQUIRES: x86
+
+# RUN: rm -rf %t && split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-elf %t/original.s -o %t/original.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-elf %t/wrapped.s -o %t/wrapped.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-elf %t/ref.s -o %t/ref.o
+# RUN: ld.lld -shared -o %t/liboriginal.so -soname liboriginal.so %t/original.o
+# RUN: ld.lld -shared -o %t/liboriginal-and-wrapped.so \
+# RUN: -soname liboriginal-and-wrapped.so %t/original.o %t/wrapped.o
+# RUN: ld.lld -shared -o %t/libref-with-original.so %t/ref.o \
+# RUN: --as-needed %t/liboriginal.so --wrap foo
+# RUN: llvm-readelf --dynamic --dyn-syms %t/libref-with-original.so | \
+# RUN: FileCheck --check-prefix=ORIGINAL %s
+# RUN: ld.lld -shared -o %t/libref-with-original-and-wrapped.so %t/ref.o \
+# RUN: --as-needed %t/liboriginal-and-wrapped.so --wrap foo
+# RUN: llvm-readelf --dynamic --dyn-syms %t/libref-with-original-and-wrapped.so | \
+# RUN: FileCheck --check-prefix=ORIGINAL-AND-WRAPPED %s
+
+# ORIGINAL-NOT: (NEEDED) Shared library: [liboriginal.so]
+# ORIGINAL: Symbol table '.dynsym' contains 3 entries:
+# ORIGINAL: NOTYPE LOCAL DEFAULT UND
+# ORIGINAL-NEXT: NOTYPE GLOBAL DEFAULT UND __wrap_foo
+# ORIGINAL-NEXT: NOTYPE GLOBAL DEFAULT 6 ref
+
+# ORIGINAL-AND-WRAPPED: (NEEDED) Shared library: [liboriginal-and-wrapped.so]
+# ORIGINAL-AND-WRAPPED: Symbol table '.dynsym' contains 3 entries:
+# ORIGINAL-AND-WRAPPED: NOTYPE LOCAL DEFAULT UND
+# ORIGINAL-AND-WRAPPED-NEXT: NOTYPE GLOBAL DEFAULT UND __wrap_foo
+# ORIGINAL-AND-WRAPPED-NEXT: NOTYPE GLOBAL DEFAULT 6 ref
+
+#--- original.s
+.globl foo
+foo:
+ retq
+
+#--- wrapped.s
+.globl __wrap_foo
+__wrap_foo:
+ retq
+
+#--- ref.s
+.globl ref
+ref:
+ jmp foo at plt
diff --git a/lld/test/ELF/wrap-lazy.test b/lld/test/ELF/wrap-lazy.test
index 8b85535517ab5..ecfea8d395439 100644
--- a/lld/test/ELF/wrap-lazy.test
+++ b/lld/test/ELF/wrap-lazy.test
@@ -30,8 +30,9 @@
# LAZY-DEF-DAG: [[#]] lazy
# LAZY-DEF-DAG: UND __wrap_lazy
-# LAZY-REF-DAG: UND lazy
+# LAZY-REF-NOT: UND lazy
# LAZY-REF-DAG: UND __wrap_lazy
+# LAZY-REF-NOT: UND lazy
#--- dummy.s
.globl dummy
More information about the llvm-commits
mailing list