[llvm] r244282 - Move to llvm-readobj code that is only used there.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 6 14:54:38 PDT 2015
Author: rafael
Date: Thu Aug 6 16:54:37 2015
New Revision: 244282
URL: http://llvm.org/viewvc/llvm-project?rev=244282&view=rev
Log:
Move to llvm-readobj code that is only used there.
lld might end up using a small part of this, but it will be in a much
refactored form. For now this unblocks avoiding the full section scan in the
ELFFile constructor.
This also has a (very small) error handling improvement.
Modified:
llvm/trunk/include/llvm/Object/ELF.h
llvm/trunk/test/Object/corrupt.test
llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=244282&r1=244281&r2=244282&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Thu Aug 6 16:54:37 2015
@@ -105,36 +105,6 @@ private:
const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr;
DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable;
- const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version
- const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r
- const Elf_Shdr *dot_gnu_version_d_sec = nullptr; // .gnu.version_d
-
- // Records for each version index the corresponding Verdef or Vernaux entry.
- // This is filled the first time LoadVersionMap() is called.
- class VersionMapEntry : public PointerIntPair<const void*, 1> {
- public:
- // If the integer is 0, this is an Elf_Verdef*.
- // If the integer is 1, this is an Elf_Vernaux*.
- VersionMapEntry() : PointerIntPair<const void*, 1>(nullptr, 0) { }
- VersionMapEntry(const Elf_Verdef *verdef)
- : PointerIntPair<const void*, 1>(verdef, 0) { }
- VersionMapEntry(const Elf_Vernaux *vernaux)
- : PointerIntPair<const void*, 1>(vernaux, 1) { }
- bool isNull() const { return getPointer() == nullptr; }
- bool isVerdef() const { return !isNull() && getInt() == 0; }
- bool isVernaux() const { return !isNull() && getInt() == 1; }
- const Elf_Verdef *getVerdef() const {
- return isVerdef() ? (const Elf_Verdef*)getPointer() : nullptr;
- }
- const Elf_Vernaux *getVernaux() const {
- return isVernaux() ? (const Elf_Vernaux*)getPointer() : nullptr;
- }
- };
- mutable SmallVector<VersionMapEntry, 16> VersionMap;
- void LoadVersionDefs(const Elf_Shdr *sec) const;
- void LoadVersionNeeds(const Elf_Shdr *ec) const;
- void LoadVersionMap() const;
-
public:
template<typename T>
const T *getEntry(uint32_t Section, uint32_t Entry) const;
@@ -147,8 +117,6 @@ public:
ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const;
ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
- ErrorOr<StringRef> getSymbolVersion(StringRef StrTab, const Elf_Sym *Symb,
- bool &IsDefault) const;
void VerifyStrTab(const Elf_Shdr *sh) const;
StringRef getRelocationTypeName(uint32_t Type) const;
@@ -282,87 +250,6 @@ typedef ELFFile<ELFType<support::little,
typedef ELFFile<ELFType<support::big, false>> ELF32BEFile;
typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
-// Iterate through the version definitions, and place each Elf_Verdef
-// in the VersionMap according to its index.
-template <class ELFT>
-void ELFFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
- unsigned vd_size = sec->sh_size; // Size of section in bytes
- unsigned vd_count = sec->sh_info; // Number of Verdef entries
- const char *sec_start = (const char*)base() + sec->sh_offset;
- const char *sec_end = sec_start + vd_size;
- // The first Verdef entry is at the start of the section.
- const char *p = sec_start;
- for (unsigned i = 0; i < vd_count; i++) {
- if (p + sizeof(Elf_Verdef) > sec_end)
- report_fatal_error("Section ended unexpectedly while scanning "
- "version definitions.");
- const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
- if (vd->vd_version != ELF::VER_DEF_CURRENT)
- report_fatal_error("Unexpected verdef version");
- size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
- if (index >= VersionMap.size())
- VersionMap.resize(index + 1);
- VersionMap[index] = VersionMapEntry(vd);
- p += vd->vd_next;
- }
-}
-
-// Iterate through the versions needed section, and place each Elf_Vernaux
-// in the VersionMap according to its index.
-template <class ELFT>
-void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
- unsigned vn_size = sec->sh_size; // Size of section in bytes
- unsigned vn_count = sec->sh_info; // Number of Verneed entries
- const char *sec_start = (const char *)base() + sec->sh_offset;
- const char *sec_end = sec_start + vn_size;
- // The first Verneed entry is at the start of the section.
- const char *p = sec_start;
- for (unsigned i = 0; i < vn_count; i++) {
- if (p + sizeof(Elf_Verneed) > sec_end)
- report_fatal_error("Section ended unexpectedly while scanning "
- "version needed records.");
- const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
- if (vn->vn_version != ELF::VER_NEED_CURRENT)
- report_fatal_error("Unexpected verneed version");
- // Iterate through the Vernaux entries
- const char *paux = p + vn->vn_aux;
- for (unsigned j = 0; j < vn->vn_cnt; j++) {
- if (paux + sizeof(Elf_Vernaux) > sec_end)
- report_fatal_error("Section ended unexpected while scanning auxiliary "
- "version needed records.");
- const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
- size_t index = vna->vna_other & ELF::VERSYM_VERSION;
- if (index >= VersionMap.size())
- VersionMap.resize(index + 1);
- VersionMap[index] = VersionMapEntry(vna);
- paux += vna->vna_next;
- }
- p += vn->vn_next;
- }
-}
-
-template <class ELFT>
-void ELFFile<ELFT>::LoadVersionMap() const {
- // If there is no dynamic symtab or version table, there is nothing to do.
- if (!DotDynSymSec || !dot_gnu_version_sec)
- return;
-
- // Has the VersionMap already been loaded?
- if (VersionMap.size() > 0)
- return;
-
- // The first two version indexes are reserved.
- // Index 0 is LOCAL, index 1 is GLOBAL.
- VersionMap.push_back(VersionMapEntry());
- VersionMap.push_back(VersionMapEntry());
-
- if (dot_gnu_version_d_sec)
- LoadVersionDefs(dot_gnu_version_d_sec);
-
- if (dot_gnu_version_r_sec)
- LoadVersionNeeds(dot_gnu_version_r_sec);
-}
-
template <class ELFT>
ELF::Elf64_Word
ELFFile<ELFT>::getExtendedSymbolTableIndex(const Elf_Sym *symb) const {
@@ -530,30 +417,6 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
DotDynSymSec = &Sec;
break;
}
- case ELF::SHT_GNU_versym:
- if (dot_gnu_version_sec != nullptr) {
- // More than one .gnu.version section!
- EC = object_error::parse_failed;
- return;
- }
- dot_gnu_version_sec = &Sec;
- break;
- case ELF::SHT_GNU_verdef:
- if (dot_gnu_version_d_sec != nullptr) {
- // More than one .gnu.version_d section!
- EC = object_error::parse_failed;
- return;
- }
- dot_gnu_version_d_sec = &Sec;
- break;
- case ELF::SHT_GNU_verneed:
- if (dot_gnu_version_r_sec != nullptr) {
- // More than one .gnu.version_r section!
- EC = object_error::parse_failed;
- return;
- }
- dot_gnu_version_r_sec = &Sec;
- break;
}
}
@@ -668,61 +531,6 @@ ELFFile<ELFT>::getSectionName(const Elf_
return StringRef(DotShstrtab.data() + Offset);
}
-template <class ELFT>
-ErrorOr<StringRef> ELFFile<ELFT>::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<uintptr_t>(symb) - DotDynSymSec->sh_offset -
- reinterpret_cast<uintptr_t>(base())) /
- sizeof(Elf_Sym);
-
- // Get the corresponding version index entry
- const Elf_Versym *vs = 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())
- return object_error::parse_failed;
- 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;
- } else {
- name_offset = entry.getVernaux()->vna_name;
- }
-
- // Set IsDefault
- if (entry.isVerdef()) {
- IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
- } else {
- IsDefault = false;
- }
-
- if (name_offset >= StrTab.size())
- return object_error::parse_failed;
- return StringRef(StrTab.data() + name_offset);
-}
-
/// This function returns the hash value for a symbol in the .dynsym section
/// Name of the API remains consistent as specified in the libelf
/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
Modified: llvm/trunk/test/Object/corrupt.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/corrupt.test?rev=244282&r1=244281&r2=244282&view=diff
==============================================================================
--- llvm/trunk/test/Object/corrupt.test (original)
+++ llvm/trunk/test/Object/corrupt.test Thu Aug 6 16:54:37 2015
@@ -23,7 +23,7 @@ SYMNAME: Error reading file: Invalid dat
RUN: not llvm-readobj %p/Inputs/corrupt-version.elf-x86_64 -dt \
RUN: 2>&1 | FileCheck --check-prefix=VER %s
-VER: Error reading file: Invalid data was encountered while parsing the file.
+VER: Error reading file: Invalid version entry.
// The file is missing the dynamic string table but has references to it.
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=244282&r1=244281&r2=244282&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Thu Aug 6 16:54:37 2015
@@ -78,6 +78,10 @@ private:
typedef typename ELFO::Elf_Hash Elf_Hash;
typedef typename ELFO::Elf_Ehdr Elf_Ehdr;
typedef typename ELFO::uintX_t uintX_t;
+ typedef typename ELFO::Elf_Versym Elf_Versym;
+ typedef typename ELFO::Elf_Verneed Elf_Verneed;
+ typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
+ typedef typename ELFO::Elf_Verdef Elf_Verdef;
/// \brief Represents a region described by entries in the .dynamic table.
struct DynRegionInfo {
@@ -106,6 +110,12 @@ private:
return make_range(dynamic_table_begin(), dynamic_table_end());
}
+ StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
+ bool &IsDefault);
+ void LoadVersionMap();
+ void LoadVersionNeeds(const Elf_Shdr *ec) const;
+ void LoadVersionDefs(const Elf_Shdr *sec) const;
+
const ELFO *Obj;
DynRegionInfo DynRelaRegion;
DynRegionInfo DynamicRegion;
@@ -113,6 +123,37 @@ private:
const Elf_Sym *DynSymStart = nullptr;
StringRef SOName;
const Elf_Hash *HashTable = nullptr;
+
+ const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version
+ const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r
+ const Elf_Shdr *dot_gnu_version_d_sec = nullptr; // .gnu.version_d
+
+ // Records for each version index the corresponding Verdef or Vernaux entry.
+ // This is filled the first time LoadVersionMap() is called.
+ class VersionMapEntry : public PointerIntPair<const void *, 1> {
+ public:
+ // If the integer is 0, this is an Elf_Verdef*.
+ // If the integer is 1, this is an Elf_Vernaux*.
+ VersionMapEntry() : PointerIntPair<const void *, 1>(nullptr, 0) {}
+ VersionMapEntry(const Elf_Verdef *verdef)
+ : PointerIntPair<const void *, 1>(verdef, 0) {}
+ VersionMapEntry(const Elf_Vernaux *vernaux)
+ : PointerIntPair<const void *, 1>(vernaux, 1) {}
+ bool isNull() const { return getPointer() == nullptr; }
+ bool isVerdef() const { return !isNull() && getInt() == 0; }
+ bool isVernaux() const { return !isNull() && getInt() == 1; }
+ const Elf_Verdef *getVerdef() const {
+ return isVerdef() ? (const Elf_Verdef *)getPointer() : nullptr;
+ }
+ const Elf_Vernaux *getVernaux() const {
+ return isVernaux() ? (const Elf_Vernaux *)getPointer() : nullptr;
+ }
+ };
+ mutable SmallVector<VersionMapEntry, 16> VersionMap;
+
+public:
+ std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
+ bool IsDynamic);
};
template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) {
@@ -159,10 +200,145 @@ std::error_code createELFDumper(const ob
} // namespace llvm
-template <typename ELFO>
-static std::string getFullSymbolName(const ELFO &Obj,
- const typename ELFO::Elf_Sym *Symbol,
- StringRef StrTable, bool IsDynamic) {
+// Iterate through the versions needed section, and place each Elf_Vernaux
+// in the VersionMap according to its index.
+template <class ELFT>
+void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
+ unsigned vn_size = sec->sh_size; // Size of section in bytes
+ unsigned vn_count = sec->sh_info; // Number of Verneed entries
+ const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
+ const char *sec_end = sec_start + vn_size;
+ // The first Verneed entry is at the start of the section.
+ const char *p = sec_start;
+ for (unsigned i = 0; i < vn_count; i++) {
+ if (p + sizeof(Elf_Verneed) > sec_end)
+ report_fatal_error("Section ended unexpectedly while scanning "
+ "version needed records.");
+ const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
+ if (vn->vn_version != ELF::VER_NEED_CURRENT)
+ report_fatal_error("Unexpected verneed version");
+ // Iterate through the Vernaux entries
+ const char *paux = p + vn->vn_aux;
+ for (unsigned j = 0; j < vn->vn_cnt; j++) {
+ if (paux + sizeof(Elf_Vernaux) > sec_end)
+ report_fatal_error("Section ended unexpected while scanning auxiliary "
+ "version needed records.");
+ const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
+ size_t index = vna->vna_other & ELF::VERSYM_VERSION;
+ if (index >= VersionMap.size())
+ VersionMap.resize(index + 1);
+ VersionMap[index] = VersionMapEntry(vna);
+ paux += vna->vna_next;
+ }
+ p += vn->vn_next;
+ }
+}
+
+// Iterate through the version definitions, and place each Elf_Verdef
+// in the VersionMap according to its index.
+template <class ELFT>
+void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
+ unsigned vd_size = sec->sh_size; // Size of section in bytes
+ unsigned vd_count = sec->sh_info; // Number of Verdef entries
+ const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
+ const char *sec_end = sec_start + vd_size;
+ // The first Verdef entry is at the start of the section.
+ const char *p = sec_start;
+ for (unsigned i = 0; i < vd_count; i++) {
+ if (p + sizeof(Elf_Verdef) > sec_end)
+ report_fatal_error("Section ended unexpectedly while scanning "
+ "version definitions.");
+ const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
+ if (vd->vd_version != ELF::VER_DEF_CURRENT)
+ report_fatal_error("Unexpected verdef version");
+ size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
+ if (index >= VersionMap.size())
+ VersionMap.resize(index + 1);
+ VersionMap[index] = VersionMapEntry(vd);
+ p += vd->vd_next;
+ }
+}
+
+template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() {
+ // If there is no dynamic symtab or version table, there is nothing to do.
+ if (!DynSymStart || !dot_gnu_version_sec)
+ return;
+
+ // Has the VersionMap already been loaded?
+ if (VersionMap.size() > 0)
+ return;
+
+ // The first two version indexes are reserved.
+ // Index 0 is LOCAL, index 1 is GLOBAL.
+ VersionMap.push_back(VersionMapEntry());
+ VersionMap.push_back(VersionMapEntry());
+
+ if (dot_gnu_version_d_sec)
+ LoadVersionDefs(dot_gnu_version_d_sec);
+
+ if (dot_gnu_version_r_sec)
+ LoadVersionNeeds(dot_gnu_version_r_sec);
+}
+
+template <typename ELFT>
+StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
+ const Elf_Sym *symb,
+ bool &IsDefault) {
+ // 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<uintptr_t>(symb) -
+ reinterpret_cast<uintptr_t>(DynSymStart)) /
+ sizeof(Elf_Sym);
+
+ // Get the corresponding version index entry
+ const Elf_Versym *vs =
+ Obj->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;
+ } else {
+ name_offset = entry.getVernaux()->vna_name;
+ }
+
+ // Set IsDefault
+ if (entry.isVerdef()) {
+ IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
+ } else {
+ IsDefault = false;
+ }
+
+ if (name_offset >= StrTab.size())
+ reportError("Invalid string offset");
+ return StringRef(StrTab.data() + name_offset);
+}
+
+template <typename ELFT>
+std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
+ StringRef StrTable,
+ bool IsDynamic) {
StringRef SymbolName = errorOrDefault(Symbol->getName(StrTable));
if (!IsDynamic)
return SymbolName;
@@ -170,13 +346,9 @@ static std::string getFullSymbolName(con
std::string FullSymbolName(SymbolName);
bool IsDefault;
- ErrorOr<StringRef> Version =
- Obj.getSymbolVersion(StrTable, &*Symbol, IsDefault);
- if (Version) {
- FullSymbolName += (IsDefault ? "@@" : "@");
- FullSymbolName += *Version;
- } else
- error(Version.getError());
+ StringRef Version = getSymbolVersion(StrTable, &*Symbol, IsDefault);
+ FullSymbolName += (IsDefault ? "@@" : "@");
+ FullSymbolName += Version;
return FullSymbolName;
}
@@ -671,6 +843,26 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile
DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
if (SONameOffset)
SOName = getDynamicString(SONameOffset);
+
+ for (const Elf_Shdr &Sec : Obj->sections()) {
+ switch (Sec.sh_type) {
+ case ELF::SHT_GNU_versym:
+ if (dot_gnu_version_sec != nullptr)
+ reportError("Multiple SHT_GNU_versym");
+ dot_gnu_version_sec = &Sec;
+ break;
+ case ELF::SHT_GNU_verdef:
+ if (dot_gnu_version_d_sec != nullptr)
+ reportError("Multiple SHT_GNU_verdef");
+ dot_gnu_version_d_sec = &Sec;
+ break;
+ case ELF::SHT_GNU_verneed:
+ if (dot_gnu_version_r_sec != nullptr)
+ reportError("Multilpe SHT_GNU_verneed");
+ dot_gnu_version_r_sec = &Sec;
+ break;
+ }
+ }
}
template <typename ELFT>
@@ -946,8 +1138,7 @@ void ELFDumper<ELFT>::printSymbol(const
unsigned SectionIndex = 0;
StringRef SectionName;
getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
- std::string FullSymbolName =
- getFullSymbolName(*Obj, Symbol, StrTable, IsDynamic);
+ std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
DictScope D(W, "Symbol");
W.printNumber("Name", FullSymbolName, Symbol->st_name);
@@ -1346,12 +1537,14 @@ public:
typedef typename ELFO::Elf_Rel Elf_Rel;
typedef typename ELFO::Elf_Rela Elf_Rela;
- MipsGOTParser(const ELFO *Obj, Elf_Dyn_Range DynTable, StreamWriter &W);
+ MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
+ Elf_Dyn_Range DynTable, StreamWriter &W);
void parseGOT();
void parsePLT();
private:
+ ELFDumper<ELFT> *Dumper;
const ELFO *Obj;
StreamWriter &W;
llvm::Optional<uint64_t> DtPltGot;
@@ -1377,9 +1570,9 @@ private:
}
template <class ELFT>
-MipsGOTParser<ELFT>::MipsGOTParser(const ELFO *Obj, Elf_Dyn_Range DynTable,
- StreamWriter &W)
- : Obj(Obj), W(W) {
+MipsGOTParser<ELFT>::MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
+ Elf_Dyn_Range DynTable, StreamWriter &W)
+ : Dumper(Dumper), Obj(Obj), W(W) {
for (const auto &Entry : DynTable) {
switch (Entry.getTag()) {
case ELF::DT_PLTGOT:
@@ -1606,7 +1799,7 @@ void MipsGOTParser<ELFT>::printGlobalGot
W.printHex("Section", SectionName, SectionIndex);
std::string FullSymbolName =
- getFullSymbolName(*Obj, Sym, StrTable, IsDynamic);
+ Dumper->getFullSymbolName(Sym, StrTable, IsDynamic);
W.printNumber("Name", FullSymbolName, Sym->st_name);
}
@@ -1638,7 +1831,7 @@ void MipsGOTParser<ELFT>::printPLTEntry(
getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
W.printHex("Section", SectionName, SectionIndex);
- std::string FullSymbolName = getFullSymbolName(*Obj, Sym, StrTable, true);
+ std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true);
W.printNumber("Name", FullSymbolName, Sym->st_name);
}
@@ -1648,7 +1841,7 @@ template <class ELFT> void ELFDumper<ELF
return;
}
- MipsGOTParser<ELFT> GOTParser(Obj, dynamic_table(), W);
+ MipsGOTParser<ELFT> GOTParser(this, Obj, dynamic_table(), W);
GOTParser.parseGOT();
GOTParser.parsePLT();
}
Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=244282&r1=244281&r2=244282&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Thu Aug 6 16:54:37 2015
@@ -191,7 +191,7 @@ namespace opts {
namespace llvm {
void reportError(Twine Msg) {
- outs() << Msg << "\n";
+ outs() << "\nError reading file: " << Msg << ".\n";
outs().flush();
exit(1);
}
@@ -200,7 +200,7 @@ void error(std::error_code EC) {
if (!EC)
return;
- reportError(Twine("\nError reading file: ") + EC.message() + ".");
+ reportError(EC.message());
}
bool relocAddressLess(RelocationRef a, RelocationRef b) {
More information about the llvm-commits
mailing list