diff options
| author | Rui Ueyama <ruiu@google.com> | 2017-06-22 17:30:19 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2017-06-22 17:30:19 +0000 |
| commit | 4402a39981063992cd8f4ca81e240a6fe7cdf4fd (patch) | |
| tree | f03e508fe8780d1ebd1f2beb89f24a5cdd6ebebc | |
| parent | 8a261c2565b377bd00dee3ac2fe1fa075cb910e4 (diff) | |
| download | bcm5719-llvm-4402a39981063992cd8f4ca81e240a6fe7cdf4fd.tar.gz bcm5719-llvm-4402a39981063992cd8f4ca81e240a6fe7cdf4fd.zip | |
Keep the original symbol name when renamed.
Previously, when symbol A is renamed B, both A and B end up having
the same name. This is because name is a symbol's attribute, and
we memcpy symbols for symbol renaming.
This pathc saves the original symbol name and restore it after memcpy
to keep the original name.
This patch shouldn't change program's meaning, but names in symbol
tables make more sense than before.
llvm-svn: 306036
| -rw-r--r-- | lld/ELF/Config.h | 2 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 24 | ||||
| -rw-r--r-- | lld/ELF/Symbols.h | 1 | ||||
| -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.s | 8 |
6 files changed, 25 insertions, 14 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 9c73b4c9c06..32e86b0ec7b 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -70,7 +70,7 @@ struct VersionDefinition { // Structure for mapping renamed symbols struct RenamedSymbol { Symbol *Target; - uint8_t OrigBinding; + uint8_t OriginalBinding; }; // This struct contains the global configuration for the linker. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 79251f0285d..ab8802c86d8 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -167,8 +167,8 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) { // Tell LTO not to eliminate this symbol Wrap->IsUsedInRegularObj = true; - Config->RenamedSymbols[Real] = RenamedSymbol{Sym, Real->Binding}; - Config->RenamedSymbols[Sym] = RenamedSymbol{Wrap, Sym->Binding}; + Config->RenamedSymbols[Real] = {Sym, Real->Binding}; + Config->RenamedSymbols[Sym] = {Wrap, Sym->Binding}; } // Creates alias for symbol. Used to implement --defsym=ALIAS=SYM. @@ -184,7 +184,7 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias, // Tell LTO not to eliminate this symbol Sym->IsUsedInRegularObj = true; - Config->RenamedSymbols[AliasSym] = RenamedSymbol{Sym, AliasSym->Binding}; + Config->RenamedSymbols[AliasSym] = {Sym, AliasSym->Binding}; } // Apply symbol renames created by -wrap and -defsym. The renames are created @@ -193,14 +193,16 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias, // symbols are finalized, we can perform the replacement. template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() { for (auto &KV : Config->RenamedSymbols) { - Symbol *Sym = KV.first; - Symbol *Rename = KV.second.Target; - Sym->Binding = KV.second.OrigBinding; - - // We rename symbols by replacing the old symbol's SymbolBody with the new - // symbol's SymbolBody. This causes all SymbolBody pointers referring to the - // old symbol to instead refer to the new symbol. - memcpy(Sym->Body.buffer, Rename->Body.buffer, sizeof(Sym->Body)); + Symbol *Dst = KV.first; + Symbol *Src = KV.second.Target; + Dst->Binding = KV.second.OriginalBinding; + + // We rename symbols by replacing the old symbol's SymbolBody with + // the new symbol's SymbolBody. The only attribute we want to keep + // is the symbol name, so that two symbols don't have the same name. + StringRef S = Dst->body()->getName(); + memcpy(Dst->Body.buffer, Src->Body.buffer, sizeof(Symbol::Body)); + Dst->body()->setName(S); } } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 030527f6374..f30b389506a 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -69,6 +69,7 @@ public: bool isLocal() const { return IsLocal; } bool isPreemptible() const; StringRef getName() const { return Name; } + void setName(StringRef S) { Name = S; } uint8_t getVisibility() const { return StOther & 0x3; } void parseSymbolVersion(); diff --git a/lld/test/ELF/defsym.s b/lld/test/ELF/defsym.s index 778180dc932..46ef00f2e05 100644 --- a/lld/test/ELF/defsym.s +++ b/lld/test/ELF/defsym.s @@ -21,7 +21,7 @@ # CHECK-NEXT: Section: Absolute # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: foo1 +# CHECK-NEXT: Name: foo2 # 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 b2e33f83138..b318b7f65f2 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.s b/lld/test/ELF/wrap.s index 17aac2db6e1..d8d802bb8ca 100644 --- a/lld/test/ELF/wrap.s +++ b/lld/test/ELF/wrap.s @@ -12,6 +12,14 @@ // CHECK-NEXT: movl $0x11010, %edx // CHECK-NEXT: movl $0x11000, %edx +// RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s +// SYM: Name: __real_foo +// SYM-NEXT: Value: 0x11000 +// SYM: Name: __wrap_foo +// SYM-NEXT: Value: 0x11010 +// SYM: Name: foo +// SYM-NEXT: Value: 0x11010 + .global _start _start: movl $foo, %edx |

