summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-06-22 17:30:19 +0000
committerRui Ueyama <ruiu@google.com>2017-06-22 17:30:19 +0000
commit4402a39981063992cd8f4ca81e240a6fe7cdf4fd (patch)
treef03e508fe8780d1ebd1f2beb89f24a5cdd6ebebc
parent8a261c2565b377bd00dee3ac2fe1fa075cb910e4 (diff)
downloadbcm5719-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.h2
-rw-r--r--lld/ELF/SymbolTable.cpp24
-rw-r--r--lld/ELF/Symbols.h1
-rw-r--r--lld/test/ELF/defsym.s2
-rw-r--r--lld/test/ELF/lto/wrap-2.ll2
-rw-r--r--lld/test/ELF/wrap.s8
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
OpenPOWER on IntegriCloud