From 31c25ae90a4311d57f31ac8fc6a41a36a6b4b1cb Mon Sep 17 00:00:00 2001 From: George Rimar Date: Thu, 15 Sep 2016 12:44:38 +0000 Subject: [PATCH] Recommit r281318 "[ELF] - Versionscript: support mangled symbols with the same name." Previouly bot was failing: http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/413/steps/test-stage1-compiler/logs/stdio Fixed possible segfault, so commit should bix the buildbot. Initial commit message: 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: 281605 --- lld/ELF/SymbolTable.cpp | 34 +++++++++++++++++++++------------- lld/ELF/SymbolTable.h | 2 +- lld/test/ELF/version-script-extern.s | 22 ++++++++++++++++++++-- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 78b0bdc..e72f7ef 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -594,11 +594,12 @@ static void setVersionId(SymbolBody *Body, StringRef VersionName, // The relationship is 1:N instead of 1:1 because with the symbol // versioning, more than one symbol may have the same name. 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; } @@ -611,22 +612,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; } @@ -675,7 +678,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(); @@ -685,9 +688,14 @@ 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); + if (Sym.IsExternCpp) { + for (SymbolBody *B : findDemangled(Demangled, N)) + setVersionId(B, V.Name, N, V.Id); + continue; + } + setVersionId(find(N), V.Name, N, V.Id); } } diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index e37549b..8059e61 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(); void handleAnonymousVersion(); struct SymIndex { 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