Index: tools/llvm-readobj/ELFDumper.cpp =================================================================== --- tools/llvm-readobj/ELFDumper.cpp +++ tools/llvm-readobj/ELFDumper.cpp @@ -285,6 +285,9 @@ const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; } const DynRegionInfo &getDynRelrRegion() const { return DynRelrRegion; } const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; } + StringRef getSymbolVersionByIndex(StringRef StrTab, + const uint32_t VersionSymbolIndex, + bool &IsDefault) const; const Elf_Hash *getHashTable() const { return HashTable; } const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; } }; @@ -745,52 +748,62 @@ } template -StringRef ELFDumper::getSymbolVersion(StringRef StrTab, - const Elf_Sym *symb, - bool &IsDefault) const { - // This is a dynamic symbol. Look in the GNU symbol version table. - if (!dot_gnu_version_sec) { - // No version table. - IsDefault = false; - return StringRef(""); - } - - // Determine the position in the symbol table of this entry. - size_t entry_index = (reinterpret_cast(symb) - - 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; +StringRef +ELFDumper::getSymbolVersionByIndex(StringRef StrTab, + const uint32_t VersionSymbolIndex, + bool &IsDefault) const { + size_t VersionIndex = VersionSymbolIndex & ELF::VERSYM_VERSION; // Special markers for unversioned symbols. - if (version_index == ELF::VER_NDX_LOCAL || - version_index == ELF::VER_NDX_GLOBAL) { + if (VersionIndex == ELF::VER_NDX_LOCAL || + VersionIndex == 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()) + if (VersionIndex >= VersionMap.size() || VersionMap[VersionIndex].isNull()) reportError("Invalid version entry"); - const VersionMapEntry &entry = VersionMap[version_index]; + const VersionMapEntry &Entry = VersionMap[VersionIndex]; // Get the version name string - size_t name_offset; - if (entry.isVerdef()) { + size_t NameOffset; + if (Entry.isVerdef()) { // The first Verdaux entry holds the name. - name_offset = entry.getVerdef()->getAux()->vda_name; - IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); + NameOffset = Entry.getVerdef()->getAux()->vda_name; + IsDefault = !(VersionSymbolIndex & ELF::VERSYM_HIDDEN); } else { - name_offset = entry.getVernaux()->vna_name; + NameOffset = Entry.getVernaux()->vna_name; IsDefault = false; } - if (name_offset >= StrTab.size()) + if (NameOffset >= StrTab.size()) reportError("Invalid string offset"); - return StringRef(StrTab.data() + name_offset); + return StringRef(StrTab.data() + NameOffset); +} + +template +StringRef ELFDumper::getSymbolVersion(StringRef StrTab, + const Elf_Sym *Sym, + bool &IsDefault) const { + // This is a dynamic symbol. Look in the GNU symbol version table. + if (!dot_gnu_version_sec) { + // No version table. + IsDefault = false; + return StringRef(""); + } + + // Determine the position in the symbol table of this entry. + size_t EntryIndex = (reinterpret_cast(Sym) - + reinterpret_cast(DynSymRegion.Addr)) / + sizeof(Elf_Sym); + + // Get the corresponding version index entry + 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) {