Skip to content

Commit

Permalink
[llvm-readobj] Generic hex-dump option
Browse files Browse the repository at this point in the history
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
  • Loading branch information
paulsemel committed Jul 25, 2018
1 parent 4f6481d commit 5ce8f15
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 77 deletions.
5 changes: 5 additions & 0 deletions llvm/test/tools/llvm-readobj/print-hex.test
Expand Up @@ -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 .`...`....`...
23 changes: 0 additions & 23 deletions llvm/tools/llvm-readobj/COFFDumper.cpp
Expand Up @@ -83,7 +83,6 @@ class COFFDumper : public ObjDumper {
void printSymbols() override;
void printDynamicSymbols() override;
void printUnwindInfo() override;
void printSectionAsHex(StringRef StringName) override;

void printNeededLibraries() override;

Expand Down Expand Up @@ -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)));
Expand Down
18 changes: 0 additions & 18 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Expand Up @@ -152,7 +152,6 @@ class ELFDumper : public ObjDumper {
void printDynamicTable() override;
void printNeededLibraries() override;
void printProgramHeaders() override;
void printSectionAsHex(StringRef StringName) override;
void printHashTable() override;
void printGnuHashTable() override;
void printLoadName() override;
Expand Down Expand Up @@ -285,23 +284,6 @@ class ELFDumper : public ObjDumper {
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;
Expand Down
21 changes: 0 additions & 21 deletions llvm/tools/llvm-readobj/MachODumper.cpp
Expand Up @@ -38,7 +38,6 @@ class MachODumper : public ObjDumper {
void printDynamicSymbols() override;
void printUnwindInfo() override;
void printStackMap() const override;
void printSectionAsHex(StringRef SectionName) override;

void printNeededLibraries() override;

Expand Down Expand Up @@ -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");

Expand Down
37 changes: 25 additions & 12 deletions llvm/tools/llvm-readobj/ObjDumper.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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';
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-readobj/ObjDumper.h
Expand Up @@ -89,10 +89,10 @@ class ObjDumper {
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,
Expand Down
4 changes: 2 additions & 2 deletions llvm/tools/llvm-readobj/llvm-readobj.cpp
Expand Up @@ -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();
Expand Down

0 comments on commit 5ce8f15

Please sign in to comment.