Index: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp @@ -274,6 +274,9 @@ StringRef &SectionName, unsigned &SectionIndex) const; std::string getStaticSymbolName(uint32_t Index) const; + std::string getSymbolVersionByIndex(StringRef StrTab, + const uint32_t VersionSymbolIndex, + bool &IsDefault) const; void printSymbolsHelper(bool IsDynamic) const; const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; } @@ -627,7 +630,7 @@ template StringRef ELFDumper::getSymbolVersion(StringRef StrTab, - const Elf_Sym *symb, + const Elf_Sym *Sym, bool &IsDefault) const { // This is a dynamic symbol. Look in the GNU symbol version table. if (!dot_gnu_version_sec) { @@ -637,41 +640,16 @@ } // Determine the position in the symbol table of this entry. - size_t entry_index = (reinterpret_cast(symb) - + size_t EntryIndex = (reinterpret_cast(Sym) - reinterpret_cast(DynSymRegion.Addr)) / sizeof(Elf_Sym); // Get the corresponding version index entry - const Elf_Versym *vs = unwrapOrError( - ObjF->getELFFile()->template getEntry(dot_gnu_version_sec, entry_index)); - size_t version_index = vs->vs_index & ELF::VERSYM_VERSION; - - // Special markers for unversioned symbols. - if (version_index == ELF::VER_NDX_LOCAL || - version_index == ELF::VER_NDX_GLOBAL) { - IsDefault = false; - return StringRef(""); - } - - // Lookup this symbol in the version table - LoadVersionMap(); - if (version_index >= VersionMap.size() || VersionMap[version_index].isNull()) - reportError("Invalid version entry"); - const VersionMapEntry &entry = VersionMap[version_index]; - - // Get the version name string - size_t name_offset; - if (entry.isVerdef()) { - // The first Verdaux entry holds the name. - name_offset = entry.getVerdef()->getAux()->vda_name; - IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); - } else { - name_offset = entry.getVernaux()->vna_name; - IsDefault = false; - } - if (name_offset >= StrTab.size()) - reportError("Invalid string offset"); - return StringRef(StrTab.data() + name_offset); + const Elf_Versym *Versym = + unwrapOrError(ObjF->getELFFile()->template getEntry( + dot_gnu_version_sec, EntryIndex)); + return StringRef( + this->getSymbolVersionByIndex(StrTab, Versym->vs_index, IsDefault)); } static std::string maybeDemangle(StringRef Name) { @@ -690,6 +668,39 @@ } template +std::string ELFDumper::getSymbolVersionByIndex( + StringRef StrTab, const uint32_t SymbolVersionIndex, bool &IsDefault) const { + size_t VersionIndex = SymbolVersionIndex & VERSYM_VERSION; + + // Special markers for unversioned symbols. + if (VersionIndex == VER_NDX_LOCAL || + VersionIndex == VER_NDX_GLOBAL) { + IsDefault = false; + return ""; + } + + // Lookup this symbol in the version table + LoadVersionMap(); + if (VersionIndex >= VersionMap.size() || VersionMap[VersionIndex].isNull()) + reportError("Invalid version entry"); + const VersionMapEntry &Entry = VersionMap[VersionIndex]; + + // Get the version name string + size_t NameOffset; + if (Entry.isVerdef()) { + // The first Verdaux entry holds the name. + NameOffset = Entry.getVerdef()->getAux()->vda_name; + IsDefault = !(SymbolVersionIndex & VERSYM_HIDDEN); + } else { + NameOffset = Entry.getVernaux()->vna_name; + IsDefault = false; + } + if (NameOffset >= StrTab.size()) + reportError("Invalid string offset"); + return std::string(StrTab.data() + NameOffset); +} + +template std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic) const {