diff options
author | Paul Semel <semelpaul@gmail.com> | 2018-07-18 18:00:41 +0000 |
---|---|---|
committer | Paul Semel <semelpaul@gmail.com> | 2018-07-18 18:00:41 +0000 |
commit | 6e13790801ea0df65fe62e91f53944d2705120da (patch) | |
tree | e923dd5d8b72cf37b5ce4b0bedddd904e820f549 /llvm/tools/llvm-readobj | |
parent | c93530d873de4c0e713942a021bf622ca59c5593 (diff) | |
download | bcm5719-llvm-6e13790801ea0df65fe62e91f53944d2705120da.tar.gz bcm5719-llvm-6e13790801ea0df65fe62e91f53944d2705120da.zip |
[llvm-readobj] Generic -string-dump option
Differential Revision: https://reviews.llvm.org/D49470
llvm-svn: 337408
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 72 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.cpp | 65 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.h | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 4 |
4 files changed, 70 insertions, 75 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index db551de274f..951bc60108f 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -152,7 +152,6 @@ public: void printDynamicTable() override; void printNeededLibraries() override; void printProgramHeaders() override; - void printSectionAsString(StringRef StringName) override; void printSectionAsHex(StringRef StringName) override; void printHashTable() override; void printGnuHashTable() override; @@ -352,8 +351,6 @@ 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 printAddrsig(const ELFFile<ELFT> *Obj) = 0; @@ -386,7 +383,6 @@ 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 printAddrsig(const ELFFile<ELFT> *Obj) override; @@ -451,7 +447,6 @@ 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 printAddrsig(const ELFFile<ELFT> *Obj) override; @@ -1597,11 +1592,6 @@ 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); } @@ -3336,36 +3326,6 @@ 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) { SmallString<32> RelocName; @@ -4401,38 +4361,6 @@ 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"; } diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp index 3eb24bdf791..40846931874 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.cpp +++ b/llvm/tools/llvm-readobj/ObjDumper.cpp @@ -14,7 +14,9 @@ #include "ObjDumper.h" #include "Error.h" +#include "llvm-readobj.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" @@ -25,6 +27,69 @@ ObjDumper::ObjDumper(ScopedPrinter &Writer) : W(Writer) {} ObjDumper::~ObjDumper() { } +static void printAsPrintable(raw_ostream &W, const uint8_t *Start, size_t Len) { + for (size_t i = 0; i < Len; i++) + W << (isprint(Start[i]) ? static_cast<char>(Start[i]) : '.'); +} + +static Expected<object::SectionRef> +getSecNameOrIndexAsSecRef(const object::ObjectFile *Obj, StringRef SecName) { + char *StrPtr; + long SectionIndex = strtol(SecName.data(), &StrPtr, 10); + object::SectionRef Section; + unsigned SecIndex = 0; + for (object::SectionRef SecRef : Obj->sections()) { + if (*StrPtr) { + StringRef SectionName; + + if (std::error_code E = SecRef.getName(SectionName)) + return errorCodeToError(E); + + if (SectionName == SecName) + return SecRef; + } else if (SecIndex == SectionIndex) + return SecRef; + + SecIndex++; + } + return make_error<StringError>("invalid section reference", + object::object_error::parse_failed); +} + +void ObjDumper::printSectionAsString(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() << "String dump of section '" << SectionName << "':\n"; + + StringRef SectionContent; + Section.getContents(SectionContent); + + const uint8_t *SecContent = SectionContent.bytes_begin(); + const uint8_t *CurrentWord = SecContent; + const uint8_t *SecEnd = SectionContent.bytes_end(); + + while (CurrentWord <= SecEnd) { + size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord), + SecEnd - CurrentWord); + if (!WordSize) { + CurrentWord++; + continue; + } + W.startLine() << format("[%6tx] ", CurrentWord - SecContent); + printAsPrintable(W.startLine(), CurrentWord, WordSize); + W.startLine() << '\n'; + CurrentWord += WordSize + 1; + } +} + void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size) { const uint8_t *SecContent = Section; diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index ba036be6b60..786e1d47d71 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -14,6 +14,7 @@ #include <system_error> #include "llvm/ADT/StringRef.h" +#include "llvm/Object/ObjectFile.h" namespace llvm { namespace object { @@ -43,7 +44,6 @@ public: virtual void printDynamicTable() { } virtual void printNeededLibraries() { } virtual void printProgramHeaders() { } - virtual void printSectionAsString(StringRef SectionName) {} virtual void printSectionAsHex(StringRef SectionName) {} virtual void printHashTable() { } virtual void printGnuHashTable() { } @@ -88,6 +88,8 @@ public: virtual void printStackMap() const = 0; + void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName); + protected: ScopedPrinter &W; void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size); diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index 5c8a8803069..389053d5499 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -437,8 +437,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) { if (opts::ProgramHeaders) Dumper->printProgramHeaders(); if (!opts::StringDump.empty()) - llvm::for_each(opts::StringDump, [&Dumper](StringRef SectionName) { - Dumper->printSectionAsString(SectionName); + llvm::for_each(opts::StringDump, [&Dumper, Obj](StringRef SectionName) { + Dumper->printSectionAsString(Obj, SectionName); }); if (!opts::HexDump.empty()) llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) { |