[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