[llvm-readobj] Generic hex-dump option

Helpers are available to make this option file format independant. This
patch adds the feature for Wasm file format. It doesn't change the
behavior of the other file format handling.

Differential Revision: https://reviews.llvm.org/D49545

llvm-svn: 337896
This commit is contained in:
Paul Semel 2018-07-25 10:04:37 +00:00
parent 228bee46cc
commit e5caf328a5
7 changed files with 33 additions and 77 deletions

View File

@ -18,3 +18,8 @@ RUN: | FileCheck %s --check-prefix MACHO
MACHO: 0x00000000 50488d3d 00000000 e8000000 00e80000 PH.=............
MACHO: 0x00000010 000031c0 5ac3 ..1.Z.
RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.wasm \
RUN: | FileCheck %s --check-prefix WASM
WASM: 0x00000000 03600001 7f60017f 017f6001 7f00 .`...`....`...

View File

@ -83,7 +83,6 @@ public:
void printSymbols() override;
void printDynamicSymbols() override;
void printUnwindInfo() override;
void printSectionAsHex(StringRef StringName) override;
void printNeededLibraries() override;
@ -655,28 +654,6 @@ 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)));

View File

@ -152,7 +152,6 @@ public:
void printDynamicTable() override;
void printNeededLibraries() override;
void printProgramHeaders() override;
void printSectionAsHex(StringRef StringName) override;
void printHashTable() override;
void printGnuHashTable() override;
void printLoadName() override;
@ -285,23 +284,6 @@ public:
const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; }
};
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;

View File

@ -38,7 +38,6 @@ public:
void printDynamicSymbols() override;
void printUnwindInfo() override;
void printStackMap() const override;
void printSectionAsHex(StringRef SectionName) override;
void printNeededLibraries() override;
@ -677,26 +676,6 @@ 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");

View File

@ -37,7 +37,11 @@ getSecNameOrIndexAsSecRef(const object::ObjectFile *Obj, StringRef SecName) {
char *StrPtr;
long SectionIndex = strtol(SecName.data(), &StrPtr, 10);
object::SectionRef Section;
long SecIndex = 0;
long SecIndex;
if (Obj->isELF())
SecIndex = 0;
else
SecIndex = 1;
for (object::SectionRef SecRef : Obj->sections()) {
if (*StrPtr) {
StringRef SectionName;
@ -90,11 +94,23 @@ void ObjDumper::printSectionAsString(const object::ObjectFile *Obj,
}
}
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";
void ObjDumper::printSectionAsHex(const object::ObjectFile *Obj,
StringRef SecName) {
Expected<object::SectionRef> SectionRefOrError =
getSecNameOrIndexAsSecRef(Obj, SecName);
if (!SectionRefOrError)
error(std::move(SectionRefOrError));
object::SectionRef Section = *SectionRefOrError;
StringRef SectionName;
if (std::error_code E = Section.getName(SectionName))
error(E);
W.startLine() << "Hex dump of section '" << SectionName << "':\n";
StringRef SectionContent;
Section.getContents(SectionContent);
const uint8_t *SecContent = SectionContent.bytes_begin();
const uint8_t *SecEnd = SecContent + SectionContent.size();
for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
const uint8_t *TmpSecPtr = SecPtr;
@ -121,12 +137,9 @@ void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section,
' ');
TmpSecPtr = SecPtr;
for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) {
if (isprint(TmpSecPtr[i]))
W.startLine() << TmpSecPtr[i];
else
W.startLine() << '.';
}
for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i)
W.startLine() << (isprint(TmpSecPtr[i]) ? static_cast<char>(TmpSecPtr[i])
: '.');
W.startLine() << '\n';
}

View File

@ -89,10 +89,10 @@ public:
virtual void printStackMap() const = 0;
void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName);
void printSectionAsHex(const object::ObjectFile *Obj, StringRef SecName);
protected:
ScopedPrinter &W;
void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size);
};
std::error_code createCOFFDumper(const object::ObjectFile *Obj,

View File

@ -441,8 +441,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
Dumper->printSectionAsString(Obj, SectionName);
});
if (!opts::HexDump.empty())
llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) {
Dumper->printSectionAsHex(SectionName);
llvm::for_each(opts::HexDump, [&Dumper, Obj](StringRef SectionName) {
Dumper->printSectionAsHex(Obj, SectionName);
});
if (opts::HashTable)
Dumper->printHashTable();