Index: llvm/test/tools/llvm-nm/dynamic.test =================================================================== --- llvm/test/tools/llvm-nm/dynamic.test +++ llvm/test/tools/llvm-nm/dynamic.test @@ -62,6 +62,8 @@ Size: 0 ## Check we print symbol versions, when they are available. +## Check that we use "@@" prefix to print default versions (non-hidden, +## defined in the SHT_GNU_verdef section). # RUN: yaml2obj --docnum=4 %s -o %t4.o # RUN: llvm-nm --dynamic %t4.o 2>&1 | \ @@ -69,7 +71,7 @@ # VERSIONED-SYMS: U globalversym # VERSIONED-SYMS-NEXT: U localversym -# VERSIONED-SYMS-NEXT: U version2sym@v2 +# VERSIONED-SYMS-NEXT: U version2sym@@v2 # VERSIONED-SYMS-NEXT: U version3sym@v3hidden # VERSIONED-SYMS-NEXT: U version4sym@v4 # VERSIONED-SYMS-NEXT: U version5sym@v5hidden Index: llvm/tools/llvm-nm/llvm-nm.cpp =================================================================== --- llvm/tools/llvm-nm/llvm-nm.cpp +++ llvm/tools/llvm-nm/llvm-nm.cpp @@ -1686,8 +1686,15 @@ } } +namespace { + +struct SymbolVersion { + std::string Name; + bool IsDefault; +}; + template -static Expected> +Expected> readSymbolVersionsELF(const ELFFile &Obj, StringRef FileName, ELFObjectFileBase::elf_symbol_iterator_range Symbols) { using Elf_Shdr = typename ELFT::Shdr; @@ -1707,14 +1714,14 @@ } if (!SymVerSec) - return std::vector{}; + return std::vector{}; Expected, 0>> MapOrErr = Obj.loadVersionMap(SymVerNeedSec, SymVerDefSec); if (!MapOrErr) return MapOrErr.takeError(); - std::vector Ret; + std::vector Ret; size_t I = 0; for (BasicSymbolRef Sym : Symbols) { ++I; @@ -1733,13 +1740,13 @@ " of " + describe(Obj, *SymVerSec) + ": " + toString(VerOrErr.takeError())); - Ret.push_back((*VerOrErr).str()); + Ret.push_back({(*VerOrErr).str(), IsDefault}); } return Ret; } -static Expected> +Expected> readSymbolVersionsELF(const ELFObjectFileBase &Obj, ELFObjectFileBase::elf_symbol_iterator_range Symbols) { if (const auto *ELF = dyn_cast(&Obj)) @@ -1752,11 +1759,13 @@ Obj.getFileName(), Symbols); } +} // namespace + static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, StringRef ArchiveName = {}, StringRef ArchitectureName = {}) { auto Symbols = Obj.symbols(); - std::vector SymbolVersions; + std::vector SymbolVersions; if (DynamicSyms) { const auto *E = dyn_cast(&Obj); if (!E) { @@ -1765,7 +1774,7 @@ } Symbols = E->getDynamicSymbolIterators(); - if (Expected> VersionsOrErr = + if (Expected> VersionsOrErr = readSymbolVersionsELF(*E, Symbols)) SymbolVersions = std::move(*VersionsOrErr); else @@ -1827,8 +1836,9 @@ } else error(std::move(E), Obj.getFileName()); } - if (!SymbolVersions.empty() && !SymbolVersions[I].empty()) - S.Name += "@" + SymbolVersions[I]; + if (!SymbolVersions.empty() && !SymbolVersions[I].Name.empty()) + S.Name += + (SymbolVersions[I].IsDefault ? "@@" : "@") + SymbolVersions[I].Name; S.Sym = Sym; SymbolList.push_back(S);