From e84f5aaedfe46d847303e694cd1c8823fe8ff09d Mon Sep 17 00:00:00 2001 From: Xing GUO Date: Thu, 28 Mar 2019 12:51:35 +0000 Subject: [PATCH] [llvm-readobj] Add new helper function `getSymbolVersionByIndex()` Summary: When implementing `GNU style` dumper for `.gnu.version` section, we should find symbol version name by `vs_index`. Reviewers: jhenderson, rupprecht Reviewed By: rupprecht Subscribers: arphaman, rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59545 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357164 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 75 ++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 091456329f9..89257e833d4 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -274,6 +274,9 @@ public: 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 void ELFDumper::LoadVersionMap() const { 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 @@ StringRef ELFDumper::getSymbolVersion(StringRef StrTab, } // 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) { @@ -689,6 +667,39 @@ std::string ELFDumper::getStaticSymbolName(uint32_t Index) const { return maybeDemangle(unwrapOrError(Sym->getName(StrTable))); } +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, -- 2.40.0