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
This commit is contained in:
Rui Ueyama 2017-06-22 17:30:19 +00:00
parent 8a261c2565
commit 4402a39981
6 changed files with 24 additions and 13 deletions

View File

@ -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.

View File

@ -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;
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. 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));
// 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);
}
}

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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