mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[llvm-readobj] Generic -string-dump option
Differential Revision: https://reviews.llvm.org/D49470 llvm-svn: 337408
This commit is contained in:
parent
0c3cec6697
commit
e4ae3a86ed
8
test/tools/llvm-readobj/print-section.test
Normal file
8
test/tools/llvm-readobj/print-section.test
Normal file
@ -0,0 +1,8 @@
|
||||
RUN: llvm-readobj -p .text %p/Inputs/elf-groups.x86_64 \
|
||||
RUN: | FileCheck %s
|
||||
|
||||
CHECK: [ 0] UH..H....E.
|
||||
CHECK: [ f] .E.x.E..
|
||||
CHECK: [ 1a] ..}..
|
||||
CHECK: [ 23] .}..
|
||||
CHECK: [ 2b] 1.H...].
|
@ -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);
|
||||
}
|
||||
@ -3335,36 +3325,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) {
|
||||
@ -4400,38 +4360,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";
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user