forked from OSchip/llvm-project
[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
This commit is contained in:
parent
b985b6e3c1
commit
2a04f5c455
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,10 +19,9 @@
|
|||
# UNWIND-DISASM-LABEL: <__wrap__Unwind_Resume@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@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
|
||||
|
|
|
@ -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@plt
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue