forked from OSchip/llvm-project
[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:
parent
9ddf128f79
commit
fa5597b24d
|
@ -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 {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue