summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp72
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h3
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp10
3 files changed, 85 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 2492fa2acc2..05bcd1a4b56 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -149,6 +149,7 @@ public:
void printDynamicTable() override;
void printNeededLibraries() override;
void printProgramHeaders() override;
+ void printSectionAsString(StringRef StringName) override;
void printHashTable() override;
void printGnuHashTable() override;
void printLoadName() override;
@@ -324,6 +325,8 @@ public:
const Elf_Sym *FirstSym, StringRef StrTable,
bool IsDynamic) = 0;
virtual void printProgramHeaders(const ELFFile<ELFT> *Obj) = 0;
+ virtual void printSectionAsString(const ELFFile<ELFT> *Obj,
+ StringRef SectionName) = 0;
virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
virtual void printCGProfile(const ELFFile<ELFT> *Obj) = 0;
virtual void printNotes(const ELFFile<ELFT> *Obj) = 0;
@@ -355,6 +358,7 @@ public:
void printSymtabMessage(const ELFO *Obj, StringRef Name,
size_t Offset) override;
void printProgramHeaders(const ELFO *Obj) override;
+ void printSectionAsString(const ELFO *Obj, StringRef SectionName) override;
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
void printCGProfile(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
@@ -417,6 +421,7 @@ public:
void printDynamicSymbols(const ELFO *Obj) override;
void printDynamicRelocations(const ELFO *Obj) override;
void printProgramHeaders(const ELFO *Obj) override;
+ void printSectionAsString(const ELFO *Obj, StringRef SectionName) override;
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
void printCGProfile(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
@@ -1539,6 +1544,11 @@ template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
ELFDumperStyle->printProgramHeaders(Obj);
}
+template <class ELFT>
+void ELFDumper<ELFT>::printSectionAsString(StringRef SectionName) {
+ ELFDumperStyle->printSectionAsString(Obj, SectionName);
+}
+
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
ELFDumperStyle->printDynamicRelocations(Obj);
}
@@ -3211,6 +3221,36 @@ void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
}
template <class ELFT>
+void GNUStyle<ELFT>::printSectionAsString(const ELFO *Obj,
+ StringRef SectionName) {
+ char *StrPtr;
+ long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+ const Elf_Shdr *Sec;
+ if (*StrPtr)
+ Sec = unwrapOrError(Obj->getSection(SectionName));
+ else
+ Sec = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
+
+ StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
+ OS << "String dump of section '" << SecName << "':\n";
+ const char *SecContent =
+ reinterpret_cast<const char *>(Obj->base() + Sec->sh_offset);
+ const char *CurrentWord = SecContent;
+ const char *SecEnd = SecContent + Sec->sh_size;
+ while (CurrentWord <= SecEnd) {
+ size_t WordSize = strnlen(CurrentWord, SecEnd - CurrentWord);
+ if (!WordSize) {
+ CurrentWord++;
+ continue;
+ }
+ OS << format("[%6tx]", CurrentWord - SecContent);
+ OS << format(" %.*s\n", WordSize, CurrentWord);
+ CurrentWord += WordSize + 1;
+ }
+ OS.flush();
+}
+
+template <class ELFT>
void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
bool IsRela) {
SmallString<32> RelocName;
@@ -4205,6 +4245,38 @@ void LLVMStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
}
template <class ELFT>
+void LLVMStyle<ELFT>::printSectionAsString(const ELFO *Obj,
+ StringRef SectionName) {
+ char *StrPtr;
+ long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+ const Elf_Shdr *Sec;
+ if (*StrPtr)
+ Sec = unwrapOrError(Obj->getSection(SectionName));
+ else
+ Sec = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
+
+ StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
+ W.startLine() << "String dump of section '" << SecName << "':\n";
+ const char *SecContent =
+ reinterpret_cast<const char *>(Obj->base() + Sec->sh_offset);
+ const char *CurrentWord = SecContent;
+ const char *SecEnd = SecContent + Sec->sh_size;
+ while (CurrentWord <= SecEnd) {
+ size_t WordSize = strnlen(CurrentWord, SecEnd - CurrentWord);
+ if (!WordSize) {
+ CurrentWord++;
+ continue;
+ }
+ W.startLine() << "["
+ << to_string(
+ format_hex_no_prefix((CurrentWord - SecContent), 6))
+ << "]";
+ W.startLine() << format(" %.*s\n", WordSize, CurrentWord);
+ CurrentWord += WordSize + 1;
+ }
+}
+
+template <class ELFT>
void LLVMStyle<ELFT>::printHashHistogram(const ELFFile<ELFT> *Obj) {
W.startLine() << "Hash Histogram not implemented!\n";
}
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index e13646588e7..57e59372ee5 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -13,6 +13,8 @@
#include <memory>
#include <system_error>
+#include "llvm/ADT/StringRef.h"
+
namespace llvm {
namespace object {
class COFFImportFile;
@@ -41,6 +43,7 @@ public:
virtual void printDynamicTable() { }
virtual void printNeededLibraries() { }
virtual void printProgramHeaders() { }
+ virtual void printSectionAsString(StringRef SectionName) {}
virtual void printHashTable() { }
virtual void printGnuHashTable() { }
virtual void printLoadName() {}
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index f871dc90950..22a8fcde391 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -146,6 +146,12 @@ namespace opts {
cl::alias ProgramHeadersShort("l", cl::desc("Alias for --program-headers"),
cl::aliasopt(ProgramHeaders));
+ // -string-dump
+ cl::list<std::string> StringDump("string-dump", cl::desc("<number|name>"),
+ cl::ZeroOrMore);
+ cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),
+ cl::aliasopt(StringDump));
+
// -hash-table
cl::opt<bool> HashTable("hash-table",
cl::desc("Display ELF hash table"));
@@ -417,6 +423,10 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
Dumper->printNeededLibraries();
if (opts::ProgramHeaders)
Dumper->printProgramHeaders();
+ if (!opts::StringDump.empty())
+ llvm::for_each(opts::StringDump, [&Dumper](StringRef SectionName) {
+ Dumper->printSectionAsString(SectionName);
+ });
if (opts::HashTable)
Dumper->printHashTable();
if (opts::GnuHashTable)
OpenPOWER on IntegriCloud