diff options
author | Xing GUO <higuoxing@gmail.com> | 2019-03-28 12:51:35 +0000 |
---|---|---|
committer | Xing GUO <higuoxing@gmail.com> | 2019-03-28 12:51:35 +0000 |
commit | 137315e7d43f569e3a1703347df7f33021720752 (patch) | |
tree | 1530dc47b2c90d6dcfb4f03b555278e410a79d75 /llvm/tools/llvm-readobj | |
parent | 288c2d98af415847e81c2ffbd2f4efb08c7d8167 (diff) | |
download | bcm5719-llvm-137315e7d43f569e3a1703347df7f33021720752.tar.gz bcm5719-llvm-137315e7d43f569e3a1703347df7f33021720752.zip |
[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
llvm-svn: 357164
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 75 |
1 files changed, 43 insertions, 32 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 091456329f9..89257e833d4 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/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 <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() const { template <typename ELFT> StringRef ELFDumper<ELFT>::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<ELFT>::getSymbolVersion(StringRef StrTab, } // Determine the position in the symbol table of this entry. - size_t entry_index = (reinterpret_cast<uintptr_t>(symb) - + size_t EntryIndex = (reinterpret_cast<uintptr_t>(Sym) - reinterpret_cast<uintptr_t>(DynSymRegion.Addr)) / sizeof(Elf_Sym); // Get the corresponding version index entry - const Elf_Versym *vs = unwrapOrError( - ObjF->getELFFile()->template getEntry<Elf_Versym>(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<Elf_Versym>( + dot_gnu_version_sec, EntryIndex)); + return StringRef( + this->getSymbolVersionByIndex(StrTab, Versym->vs_index, IsDefault)); } static std::string maybeDemangle(StringRef Name) { @@ -690,6 +668,39 @@ std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const { } template <typename ELFT> +std::string ELFDumper<ELFT>::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 <typename ELFT> std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic) const { |