[lld] r281318 - [ELF] - Versionscript: support mangled symbols with the same name.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 13 03:45:40 PDT 2016
Author: grimar
Date: Tue Sep 13 05:45:39 2016
New Revision: 281318
URL: http://llvm.org/viewvc/llvm-project?rev=281318&view=rev
Log:
[ELF] - Versionscript: support mangled symbols with the same name.
This is PR30312. Info from bug page:
Both of these symbols demangle to abc::abc():
_ZN3abcC1Ev
_ZN3abcC2Ev
(These would be abc's complete object constructor and base object constructor, respectively.)
however with "abc::abc()" in the version script only one of the two receives the symbol version.
Patch fixes that.
It uses testcase created by Ed Maste (D24306).
Differential revision: https://reviews.llvm.org/D24336
Modified:
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/test/ELF/version-script-extern.s
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=281318&r1=281317&r2=281318&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Sep 13 05:45:39 2016
@@ -600,11 +600,12 @@ static void setVersionId(SymbolBody *Bod
}
template <class ELFT>
-std::map<std::string, SymbolBody *> SymbolTable<ELFT>::getDemangledSyms() {
- std::map<std::string, SymbolBody *> Result;
+std::map<std::string, std::vector<SymbolBody *>>
+SymbolTable<ELFT>::getDemangledSyms() {
+ std::map<std::string, std::vector<SymbolBody *>> Result;
for (Symbol *Sym : SymVector) {
SymbolBody *B = Sym->body();
- Result[demangle(B->getName())] = B;
+ Result[demangle(B->getName())].push_back(B);
}
return Result;
}
@@ -617,22 +618,24 @@ static bool hasExternCpp() {
return false;
}
-static SymbolBody *findDemangled(const std::map<std::string, SymbolBody *> &D,
- StringRef Name) {
+static ArrayRef<SymbolBody *>
+findDemangled(std::map<std::string, std::vector<SymbolBody *>> &D,
+ StringRef Name) {
auto I = D.find(Name);
if (I != D.end())
return I->second;
- return nullptr;
+ return {};
}
static std::vector<SymbolBody *>
-findAllDemangled(const std::map<std::string, SymbolBody *> &D,
+findAllDemangled(const std::map<std::string, std::vector<SymbolBody *>> &D,
const Regex &Re) {
std::vector<SymbolBody *> Res;
for (auto &P : D) {
- SymbolBody *Body = P.second;
- if (!Body->isUndefined() && const_cast<Regex &>(Re).match(P.first))
- Res.push_back(Body);
+ if (const_cast<Regex &>(Re).match(P.first))
+ for (SymbolBody *Body : P.second)
+ if (!Body->isUndefined())
+ Res.push_back(Body);
}
return Res;
}
@@ -676,7 +679,7 @@ template <class ELFT> void SymbolTable<E
// "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
// other than trying to match a regexp against all demangled symbols.
// So, if "extern C++" feature is used, we demangle all known symbols.
- std::map<std::string, SymbolBody *> Demangled;
+ std::map<std::string, std::vector<SymbolBody *>> Demangled;
if (hasExternCpp())
Demangled = getDemangledSyms();
@@ -686,9 +689,13 @@ template <class ELFT> void SymbolTable<E
for (SymbolVersion Sym : V.Globals) {
if (Sym.HasWildcards)
continue;
+
StringRef N = Sym.Name;
- SymbolBody *B = Sym.IsExternCpp ? findDemangled(Demangled, N) : find(N);
- setVersionId(B, V.Name, N, V.Id);
+ ArrayRef<SymbolBody *> Arr = Sym.IsExternCpp
+ ? findDemangled(Demangled, N)
+ : ArrayRef<SymbolBody *>(find(N));
+ for (SymbolBody *B : Arr)
+ setVersionId(B, V.Name, N, V.Id);
}
}
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=281318&r1=281317&r2=281318&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Tue Sep 13 05:45:39 2016
@@ -101,7 +101,7 @@ private:
std::string conflictMsg(SymbolBody *Existing, InputFile *NewFile);
void reportDuplicate(SymbolBody *Existing, InputFile *NewFile);
- std::map<std::string, SymbolBody *> getDemangledSyms();
+ std::map<std::string, std::vector<SymbolBody *>> getDemangledSyms();
struct SymIndex {
SymIndex(int Idx, bool Traced) : Idx(Idx), Traced(Traced) {}
Modified: lld/trunk/test/ELF/version-script-extern.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script-extern.s?rev=281318&r1=281317&r2=281318&view=diff
==============================================================================
--- lld/trunk/test/ELF/version-script-extern.s (original)
+++ lld/trunk/test/ELF/version-script-extern.s Tue Sep 13 05:45:39 2016
@@ -64,11 +64,20 @@
# DSO-NEXT: Other: 0
# DSO-NEXT: Section: .text (0x6)
# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: _ZN3abcC2Ev@@LIBSAMPLE_1.0
+# DSO-NEXT: Value: 0x1004
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global (0x1)
+# DSO-NEXT: Type: Function (0x2)
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text (0x6)
+# DSO-NEXT: }
# DSO-NEXT: ]
# DSO-NEXT: Version symbols {
# DSO-NEXT: Section Name: .gnu.version
-# DSO-NEXT: Address: 0x240
-# DSO-NEXT: Offset: 0x240
+# DSO-NEXT: Address: 0x258
+# DSO-NEXT: Offset: 0x258
# DSO-NEXT: Link: 1
# DSO-NEXT: Symbols [
# DSO-NEXT: Symbol {
@@ -91,6 +100,10 @@
# DSO-NEXT: Version: 2
# DSO-NEXT: Name: _ZN3abcC1Ev@@LIBSAMPLE_1.0
# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 2
+# DSO-NEXT: Name: _ZN3abcC2Ev@@LIBSAMPLE_1.0
+# DSO-NEXT: }
# DSO-NEXT: ]
# DSO-NEXT: }
@@ -114,3 +127,8 @@ retq
.type _ZN3abcC1Ev, at function
_ZN3abcC1Ev:
retq
+
+.globl _ZN3abcC2Ev
+.type _ZN3abcC2Ev, at function
+_ZN3abcC2Ev:
+retq
More information about the llvm-commits
mailing list