Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -101,7 +101,7 @@ 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) {} Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -594,11 +594,12 @@ } 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 @@ 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; } @@ -658,7 +661,7 @@ // "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(); @@ -668,9 +671,13 @@ for (SymbolVersion Sym : V.Globals) { if (hasWildcard(Sym.Name)) 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); } } Index: test/ELF/version-script-extern.s =================================================================== --- test/ELF/version-script-extern.s +++ 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 @@ .type _ZN3abcC1Ev,@function _ZN3abcC1Ev: retq + +.globl _ZN3abcC2Ev +.type _ZN3abcC2Ev,@function +_ZN3abcC2Ev: +retq