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::multimap getDemangledSyms(); struct SymIndex { SymIndex(int Idx, bool Traced) : Idx(Idx), Traced(Traced) {} Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -600,11 +600,11 @@ } template -std::map SymbolTable::getDemangledSyms() { - std::map Result; +std::multimap SymbolTable::getDemangledSyms() { + std::multimap Result; for (Symbol *Sym : SymVector) { SymbolBody *B = Sym->body(); - Result[demangle(B->getName())] = B; + Result.insert(std::make_pair(demangle(B->getName()), B)); } return Result; } @@ -617,23 +617,23 @@ return false; } -static SymbolBody *findDemangled(const std::map &D, - StringRef Name) { - auto I = D.find(Name); - if (I != D.end()) - return I->second; - return nullptr; +static std::vector +findDemangled(std::multimap &D, StringRef Name) { + std::vector Res; + auto R = D.equal_range(Name); + for (auto I = R.first; I != R.second; ++I) + Res.push_back(I->second); + return Res; } static std::vector -findAllDemangled(const std::map &D, +findAllDemangled(const std::multimap &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); - } + for (auto &P : D) + if (const_cast(Re).match(P.first)) + if (!P.second->isUndefined()) + Res.push_back(P.second); return Res; } @@ -676,7 +676,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::multimap Demangled; if (hasExternCpp()) Demangled = getDemangledSyms(); @@ -686,9 +686,13 @@ 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); + std::vector Arr = + Sym.IsExternCpp ? findDemangled(Demangled, N) + : std::vector({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