llvm.org GIT mirror llvm / 9f006d3
[llvm-readobj] Generic -string-dump option Differential Revision: https://reviews.llvm.org/D49470 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337408 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Semel 2 years ago
5 changed file(s) with 78 addition(s) and 75 deletion(s). Raw diff Collapse all Expand all
0 RUN: llvm-readobj -p .text %p/Inputs/elf-groups.x86_64 \
1 RUN: | FileCheck %s
2
3 CHECK: [ 0] UH..H....E.
4 CHECK: [ f] .E.x.E..
5 CHECK: [ 1a] ..}..
6 CHECK: [ 23] .}..
7 CHECK: [ 2b] 1.H...].
151151 void printDynamicTable() override;
152152 void printNeededLibraries() override;
153153 void printProgramHeaders() override;
154 void printSectionAsString(StringRef StringName) override;
155154 void printSectionAsHex(StringRef StringName) override;
156155 void printHashTable() override;
157156 void printGnuHashTable() override;
351350 const Elf_Sym *FirstSym, StringRef StrTable,
352351 bool IsDynamic) = 0;
353352 virtual void printProgramHeaders(const ELFFile *Obj) = 0;
354 virtual void printSectionAsString(const ELFFile *Obj,
355 StringRef SectionName) = 0;
356353 virtual void printHashHistogram(const ELFFile *Obj) = 0;
357354 virtual void printCGProfile(const ELFFile *Obj) = 0;
358355 virtual void printAddrsig(const ELFFile *Obj) = 0;
385382 void printSymtabMessage(const ELFO *Obj, StringRef Name,
386383 size_t Offset) override;
387384 void printProgramHeaders(const ELFO *Obj) override;
388 void printSectionAsString(const ELFO *Obj, StringRef SectionName) override;
389385 void printHashHistogram(const ELFFile *Obj) override;
390386 void printCGProfile(const ELFFile *Obj) override;
391387 void printAddrsig(const ELFFile *Obj) override;
450446 void printDynamicSymbols(const ELFO *Obj) override;
451447 void printDynamicRelocations(const ELFO *Obj) override;
452448 void printProgramHeaders(const ELFO *Obj) override;
453 void printSectionAsString(const ELFO *Obj, StringRef SectionName) override;
454449 void printHashHistogram(const ELFFile *Obj) override;
455450 void printCGProfile(const ELFFile *Obj) override;
456451 void printAddrsig(const ELFFile *Obj) override;
15961591 ELFDumperStyle->printProgramHeaders(Obj);
15971592 }
15981593
1599 template
1600 void ELFDumper::printSectionAsString(StringRef SectionName) {
1601 ELFDumperStyle->printSectionAsString(Obj, SectionName);
1602 }
1603
16041594 template void ELFDumper::printDynamicRelocations() {
16051595 ELFDumperStyle->printDynamicRelocations(Obj);
16061596 }
33353325 }
33363326
33373327 template
3338 void GNUStyle::printSectionAsString(const ELFO *Obj,
3339 StringRef SectionName) {
3340 char *StrPtr;
3341 long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
3342 const Elf_Shdr *Sec;
3343 if (*StrPtr)
3344 Sec = unwrapOrError(Obj->getSection(SectionName));
3345 else
3346 Sec = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
3347
3348 StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
3349 OS << "String dump of section '" << SecName << "':\n";
3350 const char *SecContent =
3351 reinterpret_cast(Obj->base() + Sec->sh_offset);
3352 const char *CurrentWord = SecContent;
3353 const char *SecEnd = SecContent + Sec->sh_size;
3354 while (CurrentWord <= SecEnd) {
3355 size_t WordSize = strnlen(CurrentWord, SecEnd - CurrentWord);
3356 if (!WordSize) {
3357 CurrentWord++;
3358 continue;
3359 }
3360 OS << format("[%6tx]", CurrentWord - SecContent);
3361 OS << format(" %.*s\n", WordSize, CurrentWord);
3362 CurrentWord += WordSize + 1;
3363 }
3364 OS.flush();
3365 }
3366
3367 template
33683328 void GNUStyle::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
33693329 bool IsRela) {
33703330 SmallString<32> RelocName;
44004360 }
44014361
44024362 template
4403 void LLVMStyle::printSectionAsString(const ELFO *Obj,
4404 StringRef SectionName) {
4405 char *StrPtr;
4406 long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
4407 const Elf_Shdr *Sec;
4408 if (*StrPtr)
4409 Sec = unwrapOrError(Obj->getSection(SectionName));
4410 else
4411 Sec = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
4412
4413 StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
4414 W.startLine() << "String dump of section '" << SecName << "':\n";
4415 const char *SecContent =
4416 reinterpret_cast(Obj->base() + Sec->sh_offset);
4417 const char *CurrentWord = SecContent;
4418 const char *SecEnd = SecContent + Sec->sh_size;
4419 while (CurrentWord <= SecEnd) {
4420 size_t WordSize = strnlen(CurrentWord, SecEnd - CurrentWord);
4421 if (!WordSize) {
4422 CurrentWord++;
4423 continue;
4424 }
4425 W.startLine() << "["
4426 << to_string(
4427 format_hex_no_prefix((CurrentWord - SecContent), 6))
4428 << "]";
4429 W.startLine() << format(" %.*s\n", WordSize, CurrentWord);
4430 CurrentWord += WordSize + 1;
4431 }
4432 }
4433
4434 template
44354363 void LLVMStyle::printHashHistogram(const ELFFile *Obj) {
44364364 W.startLine() << "Hash Histogram not implemented!\n";
44374365 }
1313
1414 #include "ObjDumper.h"
1515 #include "Error.h"
16 #include "llvm-readobj.h"
1617 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Support/Error.h"
1719 #include "llvm/Support/ScopedPrinter.h"
1820 #include "llvm/Support/raw_ostream.h"
1921
2224 ObjDumper::ObjDumper(ScopedPrinter &Writer) : W(Writer) {}
2325
2426 ObjDumper::~ObjDumper() {
27 }
28
29 static void printAsPrintable(raw_ostream &W, const uint8_t *Start, size_t Len) {
30 for (size_t i = 0; i < Len; i++)
31 W << (isprint(Start[i]) ? static_cast(Start[i]) : '.');
32 }
33
34 static Expected
35 getSecNameOrIndexAsSecRef(const object::ObjectFile *Obj, StringRef SecName) {
36 char *StrPtr;
37 long SectionIndex = strtol(SecName.data(), &StrPtr, 10);
38 object::SectionRef Section;
39 unsigned SecIndex = 0;
40 for (object::SectionRef SecRef : Obj->sections()) {
41 if (*StrPtr) {
42 StringRef SectionName;
43
44 if (std::error_code E = SecRef.getName(SectionName))
45 return errorCodeToError(E);
46
47 if (SectionName == SecName)
48 return SecRef;
49 } else if (SecIndex == SectionIndex)
50 return SecRef;
51
52 SecIndex++;
53 }
54 return make_error("invalid section reference",
55 object::object_error::parse_failed);
56 }
57
58 void ObjDumper::printSectionAsString(const object::ObjectFile *Obj,
59 StringRef SecName) {
60 Expected SectionRefOrError =
61 getSecNameOrIndexAsSecRef(Obj, SecName);
62 if (!SectionRefOrError)
63 error(std::move(SectionRefOrError));
64 object::SectionRef Section = *SectionRefOrError;
65 StringRef SectionName;
66
67 if (std::error_code E = Section.getName(SectionName))
68 error(E);
69 W.startLine() << "String dump of section '" << SectionName << "':\n";
70
71 StringRef SectionContent;
72 Section.getContents(SectionContent);
73
74 const uint8_t *SecContent = SectionContent.bytes_begin();
75 const uint8_t *CurrentWord = SecContent;
76 const uint8_t *SecEnd = SectionContent.bytes_end();
77
78 while (CurrentWord <= SecEnd) {
79 size_t WordSize = strnlen(reinterpret_cast(CurrentWord),
80 SecEnd - CurrentWord);
81 if (!WordSize) {
82 CurrentWord++;
83 continue;
84 }
85 W.startLine() << format("[%6tx] ", CurrentWord - SecContent);
86 printAsPrintable(W.startLine(), CurrentWord, WordSize);
87 W.startLine() << '\n';
88 CurrentWord += WordSize + 1;
89 }
2590 }
2691
2792 void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section,
1313 #include
1414
1515 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Object/ObjectFile.h"
1617
1718 namespace llvm {
1819 namespace object {
4243 virtual void printDynamicTable() { }
4344 virtual void printNeededLibraries() { }
4445 virtual void printProgramHeaders() { }
45 virtual void printSectionAsString(StringRef SectionName) {}
4646 virtual void printSectionAsHex(StringRef SectionName) {}
4747 virtual void printHashTable() { }
4848 virtual void printGnuHashTable() { }
8787
8888 virtual void printStackMap() const = 0;
8989
90 void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName);
91
9092 protected:
9193 ScopedPrinter &W;
9294 void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size);
436436 if (opts::ProgramHeaders)
437437 Dumper->printProgramHeaders();
438438 if (!opts::StringDump.empty())
439 llvm::for_each(opts::StringDump, [&Dumper](StringRef SectionName) {
440 Dumper->printSectionAsString(SectionName);
439 llvm::for_each(opts::StringDump, [&Dumper, Obj](StringRef SectionName) {
440 Dumper->printSectionAsString(Obj, SectionName);
441441 });
442442 if (!opts::HexDump.empty())
443443 llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) {