summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
authorXing GUO <higuoxing@gmail.com>2019-03-28 12:51:35 +0000
committerXing GUO <higuoxing@gmail.com>2019-03-28 12:51:35 +0000
commit137315e7d43f569e3a1703347df7f33021720752 (patch)
tree1530dc47b2c90d6dcfb4f03b555278e410a79d75 /llvm/tools/llvm-readobj
parent288c2d98af415847e81c2ffbd2f4efb08c7d8167 (diff)
downloadbcm5719-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.cpp75
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 {
OpenPOWER on IntegriCloud