diff options
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 23 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 18 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/MachODumper.cpp | 21 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.cpp | 42 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.h | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 10 |
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) |