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/COFFDumper.cpp23
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp18
-rw-r--r--llvm/tools/llvm-readobj/MachODumper.cpp21
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.cpp42
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h2
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp10
6 files changed, 116 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 0ed4ccd09f6..c840d7efb84 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -83,6 +83,7 @@ public:
void printSymbols() override;
void printDynamicSymbols() override;
void printUnwindInfo() override;
+ void printSectionAsHex(StringRef StringName) override;
void printNeededLibraries() override;
@@ -654,6 +655,28 @@ void COFFDumper::printFileHeaders() {
printDOSHeader(DH);
}
+void COFFDumper::printSectionAsHex(StringRef SectionName) {
+ char *StrPtr;
+ long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+ const coff_section *Sec;
+ if (*StrPtr)
+ error(Obj->getSection(SectionName, Sec));
+ else {
+ error(Obj->getSection((int)SectionIndex, Sec));
+ if (!Sec)
+ return error(object_error::parse_failed);
+ }
+
+ StringRef SecName;
+ error(Obj->getSectionName(Sec, SecName));
+
+ ArrayRef<uint8_t> Content;
+ error(Obj->getSectionContents(Sec, Content));
+ const uint8_t *SecContent = Content.data();
+
+ SectionHexDump(SecName, SecContent, Content.size());
+}
+
void COFFDumper::printDOSHeader(const dos_header *DH) {
DictScope D(W, "DOSHeader");
W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 9a2be3100ac..ce41e9a48b5 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -152,6 +152,7 @@ public:
void printNeededLibraries() override;
void printProgramHeaders() override;
void printSectionAsString(StringRef StringName) override;
+ void printSectionAsHex(StringRef StringName) override;
void printHashTable() override;
void printGnuHashTable() override;
void printLoadName() override;
@@ -282,6 +283,23 @@ public:
};
template <class ELFT>
+void ELFDumper<ELFT>::printSectionAsHex(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));
+ const uint8_t *SecContent =
+ reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
+
+ SectionHexDump(SecName, SecContent, Sec->sh_size);
+}
+
+template <class ELFT>
void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
StringRef StrTable, SymtabName;
size_t Entries = 0;
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index 69ef1556f78..c97f598bdd7 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -38,6 +38,7 @@ public:
void printDynamicSymbols() override;
void printUnwindInfo() override;
void printStackMap() const override;
+ void printSectionAsHex(StringRef SectionName) override;
void printNeededLibraries() override;
@@ -676,6 +677,26 @@ void MachODumper::printStackMap() const {
StackMapV2Parser<support::big>(StackMapContentsArray));
}
+void MachODumper::printSectionAsHex(StringRef SectionName) {
+ char *StrPtr;
+ long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+ SectionRef SecTmp;
+ const SectionRef *Sec = &SecTmp;
+ if (*StrPtr)
+ SecTmp = unwrapOrError(Obj->getSection(SectionName));
+ else
+ SecTmp = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
+
+ StringRef SecName;
+ error(Sec->getName(SecName));
+
+ StringRef Data;
+ error(Sec->getContents(Data));
+ const uint8_t *SecContent = reinterpret_cast<const uint8_t *>(Data.data());
+
+ SectionHexDump(SecName, SecContent, Data.size());
+}
+
void MachODumper::printNeededLibraries() {
ListScope D(W, "NeededLibraries");
diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp
index 95a6d0325e2..3eb24bdf791 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.cpp
+++ b/llvm/tools/llvm-readobj/ObjDumper.cpp
@@ -25,4 +25,46 @@ ObjDumper::ObjDumper(ScopedPrinter &Writer) : W(Writer) {}
ObjDumper::~ObjDumper() {
}
+void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section,
+ size_t Size) {
+ const uint8_t *SecContent = Section;
+ const uint8_t *SecEnd = Section + Size;
+ W.startLine() << "Hex dump of section '" << SecName << "':\n";
+
+ for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
+ const uint8_t *TmpSecPtr = SecPtr;
+ uint8_t i;
+ uint8_t k;
+
+ W.startLine() << format_hex(SecPtr - SecContent, 10);
+ W.startLine() << ' ';
+ for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) {
+ for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) {
+ uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr));
+ W.startLine() << format_hex_no_prefix(Val, 2);
+ }
+ W.startLine() << ' ';
+ }
+
+ // We need to print the correct amount of spaces to match the format.
+ // We are adding the (4 - i) last rows that are 8 characters each.
+ // Then, the (4 - i) spaces that are in between the rows.
+ // Least, if we cut in a middle of a row, we add the remaining characters,
+ // which is (8 - (k * 2))
+ if (i < 4)
+ W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)),
+ ' ');
+
+ TmpSecPtr = SecPtr;
+ for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) {
+ if (isprint(TmpSecPtr[i]))
+ W.startLine() << TmpSecPtr[i];
+ else
+ W.startLine() << '.';
+ }
+
+ W.startLine() << '\n';
+ }
+}
+
} // namespace llvm
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 57e59372ee5..09c8acb7493 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -44,6 +44,7 @@ public:
virtual void printNeededLibraries() { }
virtual void printProgramHeaders() { }
virtual void printSectionAsString(StringRef SectionName) {}
+ virtual void printSectionAsHex(StringRef SectionName) {}
virtual void printHashTable() { }
virtual void printGnuHashTable() { }
virtual void printLoadName() {}
@@ -88,6 +89,7 @@ public:
protected:
ScopedPrinter &W;
+ void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size);
};
std::error_code createCOFFDumper(const object::ObjectFile *Obj,
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index aa2cc762daf..39567b80235 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -152,6 +152,12 @@ namespace opts {
cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),
cl::aliasopt(StringDump));
+ // -hex-dump
+ cl::list<std::string> HexDump("hex-dump", cl::desc("<number|name>"),
+ cl::ZeroOrMore);
+ cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"),
+ cl::aliasopt(HexDump));
+
// -hash-table
cl::opt<bool> HashTable("hash-table",
cl::desc("Display ELF hash table"));
@@ -431,6 +437,10 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
llvm::for_each(opts::StringDump, [&Dumper](StringRef SectionName) {
Dumper->printSectionAsString(SectionName);
});
+ if (!opts::HexDump.empty())
+ llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) {
+ Dumper->printSectionAsHex(SectionName);
+ });
if (opts::HashTable)
Dumper->printHashTable();
if (opts::GnuHashTable)
OpenPOWER on IntegriCloud