diff options
-rw-r--r-- | lld/ELF/Symbols.cpp | 13 | ||||
-rw-r--r-- | lld/test/ELF/Inputs/wrap-dynamic-undef.s | 2 | ||||
-rw-r--r-- | lld/test/ELF/defsym.s | 2 | ||||
-rw-r--r-- | lld/test/ELF/lto/wrap-2.ll | 2 | ||||
-rw-r--r-- | lld/test/ELF/wrap-dynamic-undef.s | 15 | ||||
-rw-r--r-- | lld/test/ELF/wrap.s | 8 |
6 files changed, 28 insertions, 14 deletions
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 148acfb8d1f..1d17f57f0c3 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -159,19 +159,12 @@ bool SymbolBody::isPreemptible() const { return true; } -// Overwrites all attributes except symbol name with Other's so that -// this symbol becomes an alias to Other. This is useful for handling -// some options such as --wrap. -// -// The reason why we want to keep the symbol name is because, if we -// copy symbol names, we'll end up having symbol tables in resulting -// executables or DSOs containing two or more identical symbols, which -// is just inconvenient. +// Overwrites all attributes with Other's so that this symbol becomes +// an alias to Other. This is useful for handling some options such as +// --wrap. void SymbolBody::copy(SymbolBody *Other) { - StringRef S = Name; memcpy(symbol()->Body.buffer, Other->symbol()->Body.buffer, sizeof(Symbol::Body)); - Name = S; } uint64_t SymbolBody::getVA(int64_t Addend) const { diff --git a/lld/test/ELF/Inputs/wrap-dynamic-undef.s b/lld/test/ELF/Inputs/wrap-dynamic-undef.s new file mode 100644 index 00000000000..ade79556db7 --- /dev/null +++ b/lld/test/ELF/Inputs/wrap-dynamic-undef.s @@ -0,0 +1,2 @@ +.global foo +foo: diff --git a/lld/test/ELF/defsym.s b/lld/test/ELF/defsym.s index 253d5d8f408..b821484261b 100644 --- a/lld/test/ELF/defsym.s +++ b/lld/test/ELF/defsym.s @@ -19,7 +19,7 @@ # CHECK-NEXT: Section: Absolute # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: foo2 +# CHECK-NEXT: Name: foo1 # CHECK-NEXT: Value: 0x123 # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Global diff --git a/lld/test/ELF/lto/wrap-2.ll b/lld/test/ELF/lto/wrap-2.ll index b318b7f65f2..b2e33f83138 100644 --- a/lld/test/ELF/lto/wrap-2.ll +++ b/lld/test/ELF/lto/wrap-2.ll @@ -10,8 +10,8 @@ ; CHECK: foo: ; CHECK-NEXT: pushq %rax +; CHECK-NEXT: callq{{.*}}<__wrap_bar> ; CHECK-NEXT: callq{{.*}}<bar> -; CHECK-NEXT: callq{{.*}}<__real_bar> ; Check that bar and __wrap_bar retain their original binding. ; BIND: Name: bar diff --git a/lld/test/ELF/wrap-dynamic-undef.s b/lld/test/ELF/wrap-dynamic-undef.s new file mode 100644 index 00000000000..95b98598101 --- /dev/null +++ b/lld/test/ELF/wrap-dynamic-undef.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-dynamic-undef.s -o %t2.o +# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: ld.lld %t1.o %t2.so -o %t --wrap foo +# RUN: llvm-readobj -dyn-symbols --elf-output-style=GNU %t | FileCheck %s + +# Test that the dynamic relocation uses foo. We used to produce a +# relocation with __real_foo. + +# CHECK: NOTYPE GLOBAL DEFAULT UND foo + +.global _start +_start: + callq __real_foo@plt diff --git a/lld/test/ELF/wrap.s b/lld/test/ELF/wrap.s index d8d802bb8ca..3e75fdbad81 100644 --- a/lld/test/ELF/wrap.s +++ b/lld/test/ELF/wrap.s @@ -12,12 +12,16 @@ // CHECK-NEXT: movl $0x11010, %edx // CHECK-NEXT: movl $0x11000, %edx +// This shows an oddity of our implementation. The symbol foo gets +// mapped to __wrap_foo, but stays in the symbol table. This results +// in it showing up twice in the output. + // RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s -// SYM: Name: __real_foo +// SYM: Name: foo // SYM-NEXT: Value: 0x11000 // SYM: Name: __wrap_foo // SYM-NEXT: Value: 0x11010 -// SYM: Name: foo +// SYM: Name: __wrap_foo // SYM-NEXT: Value: 0x11010 .global _start |