[llvm-readobj] Add -string-dump (-p) option

This option prints the section content as a string.

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

llvm-svn: 334834
This commit is contained in:
Paul Semel 2018-06-15 14:15:02 +00:00
parent 9ddf128f79
commit fa5597b24d
4 changed files with 102 additions and 0 deletions

View File

@ -235,6 +235,7 @@ public:
Elf_Sym_Range Symtab,
ArrayRef<Elf_Word> ShndxTable) const;
Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
Expected<const Elf_Shdr *> getSection(const StringRef SectionName) const;
Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
uint32_t Index) const;
@ -498,6 +499,22 @@ ELFFile<ELFT>::getSection(uint32_t Index) const {
return object::getSection<ELFT>(*TableOrErr, Index);
}
template <class ELFT>
Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(const StringRef SectionName) const {
auto TableOrErr = sections();
if (!TableOrErr)
return TableOrErr.takeError();
for (auto &Sec : *TableOrErr) {
auto SecNameOrErr = getSectionName(&Sec);
if (!SecNameOrErr)
return SecNameOrErr.takeError();
if (*SecNameOrErr == SectionName)
return &Sec;
}
return createError("invalid section name");
}
template <class ELFT>
Expected<StringRef>
ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {

View File

@ -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);
}
@ -3210,6 +3220,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) {
@ -4204,6 +4244,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";

View File

@ -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() {}

View File

@ -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)