From e2051efcbe51211ca954c2c7fda3725974ed4bdd Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 13 Sep 2016 10:45:39 +0000 Subject: [PATCH] [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 llvm-svn: 281318 --- lld/ELF/SymbolTable.cpp | 33 ++++++++++++++++++++------------- lld/ELF/SymbolTable.h | 2 +- lld/test/ELF/version-script-extern.s | 22 ++++++++++++++++++++-- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index baeb99d..ab4e407 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -600,11 +600,12 @@ static void setVersionId(SymbolBody *Body, StringRef VersionName, } template -std::map SymbolTable::getDemangledSyms() { - std::map Result; +std::map> +SymbolTable::getDemangledSyms() { + std::map> 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 &D, - StringRef Name) { +static ArrayRef +findDemangled(std::map> &D, + StringRef Name) { auto I = D.find(Name); if (I != D.end()) return I->second; - return nullptr; + return {}; } static std::vector -findAllDemangled(const std::map &D, +findAllDemangled(const std::map> &D, const Regex &Re) { std::vector Res; for (auto &P : D) { - SymbolBody *Body = P.second; - if (!Body->isUndefined() && const_cast(Re).match(P.first)) - Res.push_back(Body); + if (const_cast(Re).match(P.first)) + for (SymbolBody *Body : P.second) + if (!Body->isUndefined()) + Res.push_back(Body); } return Res; } @@ -676,7 +679,7 @@ template void SymbolTable::scanVersionScript() { // "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 Demangled; + std::map> Demangled; if (hasExternCpp()) Demangled = getDemangledSyms(); @@ -686,9 +689,13 @@ template void SymbolTable::scanVersionScript() { 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 Arr = Sym.IsExternCpp + ? findDemangled(Demangled, N) + : ArrayRef(find(N)); + for (SymbolBody *B : Arr) + setVersionId(B, V.Name, N, V.Id); } } diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index f8d601c..091befd 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -101,7 +101,7 @@ private: std::string conflictMsg(SymbolBody *Existing, InputFile *NewFile); void reportDuplicate(SymbolBody *Existing, InputFile *NewFile); - std::map getDemangledSyms(); + std::map> getDemangledSyms(); struct SymIndex { SymIndex(int Idx, bool Traced) : Idx(Idx), Traced(Traced) {} diff --git a/lld/test/ELF/version-script-extern.s b/lld/test/ELF/version-script-extern.s index 1b296ef..4db121d 100644 --- a/lld/test/ELF/version-script-extern.s +++ b/lld/test/ELF/version-script-extern.s @@ -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,@function _ZN3abcC1Ev: retq + +.globl _ZN3abcC2Ev +.type _ZN3abcC2Ev,@function +_ZN3abcC2Ev: +retq -- 2.7.4