summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
authorPaul Semel <semelpaul@gmail.com>2018-07-18 18:00:41 +0000
committerPaul Semel <semelpaul@gmail.com>2018-07-18 18:00:41 +0000
commit6e13790801ea0df65fe62e91f53944d2705120da (patch)
treee923dd5d8b72cf37b5ce4b0bedddd904e820f549 /llvm/tools/llvm-readobj
parentc93530d873de4c0e713942a021bf622ca59c5593 (diff)
downloadbcm5719-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.cpp72
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.cpp65
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h4
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp4
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) {
OpenPOWER on IntegriCloud