mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-12 19:01:55 +00:00
[llvm-readobj] Allow --hex-dump/--string-dump to dump multiple sections
1) `-x foo` currently dumps one `foo`. This change makes it dump all `foo`. 2) `-x foo -x foo` currently dumps `foo` twice. This change makes it dump `foo` once. In addition, if foo has section index 9, `-x foo -x 9` dumps `foo` once. 3) Give a warning instead of an error if `foo` does not exist. The new behaviors match GNU readelf. Also, print a new line as a separator between two section dumps. GNU readelf uses two lines, but one seems good enough. Reviewed By: grimar, jhenderson Differential Revision: https://reviews.llvm.org/D63475 llvm-svn: 363683
This commit is contained in:
parent
d204987ada
commit
677423997d
@ -32,6 +32,7 @@
|
||||
|
||||
# CONTENTS: Hex dump of section '.first':
|
||||
# CONTENTS-NEXT: 0x00000000 01234567
|
||||
# CONTENTS-EMPTY:
|
||||
# CONTENTS-NEXT: Hex dump of section '.second':
|
||||
# CONTENTS-NEXT: 0x00000000 23456789
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
# CONTENTS: Hex dump of section '.first':
|
||||
# CONTENTS-NEXT: 0x00000000 01234567
|
||||
# CONTENTS-EMPTY:
|
||||
# CONTENTS-NEXT: Hex dump of section '.second':
|
||||
# CONTENTS-NEXT: 0x00000000 23456789
|
||||
|
||||
|
21
llvm/test/tools/llvm-readobj/hex-dump-multi.s
Normal file
21
llvm/test/tools/llvm-readobj/hex-dump-multi.s
Normal file
@ -0,0 +1,21 @@
|
||||
# REQUIRES: x86-registered-target
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t.o
|
||||
# RUN: llvm-readobj -x .a -x .b %t.o | FileCheck %s
|
||||
# RUN: llvm-readelf -x .a -x .b %t.o | FileCheck %s
|
||||
|
||||
# CHECK: Hex dump of section '.a':
|
||||
# CHECK-NEXT: 0x00000000 00
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: Hex dump of section '.b':
|
||||
# CHECK-NEXT: 0x00000000 01
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: Hex dump of section '.a':
|
||||
# CHECK-NEXT: 0x00000000 02
|
||||
|
||||
.section .a,"a",@progbits,unique,0
|
||||
.byte 0
|
||||
.section .b,"a",@progbits
|
||||
.byte 1
|
||||
.section .a,"a",@progbits,unique,1
|
||||
.byte 2
|
59
llvm/test/tools/llvm-readobj/hex-dump.test
Normal file
59
llvm/test/tools/llvm-readobj/hex-dump.test
Normal file
@ -0,0 +1,59 @@
|
||||
## Test that the -x alias can be used flexibly. Create a baseline and ensure
|
||||
## all other combinations are identical.
|
||||
# RUN: llvm-readelf --file-header --hex-dump=.text \
|
||||
# RUN: %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.out
|
||||
# RUN: llvm-readelf -h --hex-dump .text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.1
|
||||
# RUN: llvm-readelf -h -x .text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.2
|
||||
# RUN: llvm-readelf -h -x=.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.3
|
||||
# RUN: llvm-readelf -h -x.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.4
|
||||
# RUN: llvm-readelf -hx .text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.5
|
||||
# RUN: llvm-readelf -hx=.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.6
|
||||
# RUN: llvm-readelf -hx.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.7
|
||||
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.1
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.2
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.3
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.4
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.5
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.6
|
||||
# RUN: cmp %t.hexdump.out %t.hexdump.7
|
||||
|
||||
# RUN: llvm-readelf -S %p/Inputs/trivial.obj.elf-x86-64 | FileCheck %s --check-prefix=ELF-SEC
|
||||
|
||||
## Both 9 and .strtab refer to .strtab. Test we dump the section only once.
|
||||
# RUN: llvm-readobj -x 9 -x 9 -x .strtab -x .strtab %p/Inputs/trivial.obj.elf-x86-64 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=ELF
|
||||
# RUN: llvm-readobj -x 9 -x .strtab -x 10 -x not_exist \
|
||||
# RUN: %p/Inputs/trivial.obj.elf-x86-64 2>&1 | FileCheck %s --check-prefixes=ELF-WARN,ELF
|
||||
|
||||
# ELF-SEC: [ 9] .strtab
|
||||
|
||||
# ELF-WARN: warning: could not find section 'not_exist'
|
||||
# ELF-WARN: warning: could not find section 10
|
||||
# ELF: Hex dump of section '.strtab':
|
||||
# ELF-NEXT: 0x00000000 00747269 7669616c 2e6c6c00 6d61696e .trivial.ll.main
|
||||
# ELF-NEXT: 0x00000010 002e4c2e 73747200 70757473 00536f6d ..L.str.puts.Som
|
||||
# ELF-NEXT: 0x00000020 654f7468 65724675 6e637469 6f6e005f eOtherFunction._
|
||||
# ELF-NEXT: 0x00000030 474c4f42 414c5f4f 46465345 545f5441 GLOBAL_OFFSET_TA
|
||||
# ELF-NEXT: 0x00000040 424c455f 00 BLE_.
|
||||
# ELF-NOT: {{.}}
|
||||
|
||||
## Below we test -x can be used for other binary formats.
|
||||
|
||||
# RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.coff-x86-64 \
|
||||
# RUN: | FileCheck %s --check-prefix COFF
|
||||
|
||||
# COFF: 0x00000000 4883ec28 488d0d00 000000e8 00000000 H..(H...........
|
||||
# COFF: 0x00000010 e8000000 0031c048 83c428c3 .....1.H..(.
|
||||
|
||||
# RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.macho-x86-64 \
|
||||
# RUN: | FileCheck %s --check-prefix MACHO
|
||||
|
||||
# MACHO: 0x00000000 50488d3d 00000000 e8000000 00e80000 PH.=............
|
||||
# MACHO: 0x00000010 000031c0 5ac3 ..1.Z.
|
||||
|
||||
# RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.wasm \
|
||||
# RUN: | FileCheck %s --check-prefix WASM
|
||||
|
||||
# WASM: 0x00000000 04600001 7f60017f 017f6000 0060017f .`...`....`..`..
|
||||
# WASM: 0x00000010 00 .
|
@ -1,32 +0,0 @@
|
||||
// Check dumping of the hexadecimal bytes of a section.
|
||||
RUN: llvm-readobj -x .text %p/../../Object/Inputs/hello-world.elf-x86-64 | FileCheck %s
|
||||
|
||||
CHECK: Hex dump of section '.text':
|
||||
CHECK-NEXT: {{^}}0x00400460
|
||||
|
||||
// Test that the -x alias can be used flexibly. Create a baseline and ensure
|
||||
// all other combinations are identical.
|
||||
RUN: llvm-readelf --file-header --hex-dump=.text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.out
|
||||
RUN: llvm-readelf -h --hex-dump .text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.1
|
||||
RUN: llvm-readelf -h -x .text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.2
|
||||
RUN: llvm-readelf -h -x=.text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.3
|
||||
RUN: llvm-readelf -h -x.text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.4
|
||||
RUN: llvm-readelf -hx .text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.5
|
||||
RUN: llvm-readelf -hx=.text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.6
|
||||
RUN: llvm-readelf -hx.text \
|
||||
RUN: %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.7
|
||||
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.1
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.2
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.3
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.4
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.5
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.6
|
||||
RUN: cmp %t.hexdump.out %t.hexdump.7
|
@ -1,26 +0,0 @@
|
||||
RUN: llvm-readobj -x .strtab %p/Inputs/trivial.obj.elf-x86-64 \
|
||||
RUN: | FileCheck %s --check-prefix ELF
|
||||
|
||||
ELF: 0x00000000 00747269 7669616c 2e6c6c00 6d61696e .trivial.ll.main
|
||||
ELF: 0x00000010 002e4c2e 73747200 70757473 00536f6d ..L.str.puts.Som
|
||||
ELF: 0x00000020 654f7468 65724675 6e637469 6f6e005f eOtherFunction._
|
||||
ELF: 0x00000030 474c4f42 414c5f4f 46465345 545f5441 GLOBAL_OFFSET_TA
|
||||
ELF: 0x00000040 424c455f 00 BLE_.
|
||||
|
||||
RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.coff-x86-64 \
|
||||
RUN: | FileCheck %s --check-prefix COFF
|
||||
|
||||
COFF: 0x00000000 4883ec28 488d0d00 000000e8 00000000 H..(H...........
|
||||
COFF: 0x00000010 e8000000 0031c048 83c428c3 .....1.H..(.
|
||||
|
||||
RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.macho-x86-64 \
|
||||
RUN: | FileCheck %s --check-prefix MACHO
|
||||
|
||||
MACHO: 0x00000000 50488d3d 00000000 e8000000 00e80000 PH.=............
|
||||
MACHO: 0x00000010 000031c0 5ac3 ..1.Z.
|
||||
|
||||
RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.wasm \
|
||||
RUN: | FileCheck %s --check-prefix WASM
|
||||
|
||||
WASM: 0x00000000 04600001 7f60017f 017f6000 0060017f .`...`....`..`..
|
||||
WASM: 0x00000010 00 .
|
21
llvm/test/tools/llvm-readobj/string-dump-multi.s
Normal file
21
llvm/test/tools/llvm-readobj/string-dump-multi.s
Normal file
@ -0,0 +1,21 @@
|
||||
# REQUIRES: x86-registered-target
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t.o
|
||||
# RUN: llvm-readobj -p .a -p .b %t.o | FileCheck %s
|
||||
# RUN: llvm-readelf -p .a -p .b %t.o | FileCheck %s
|
||||
|
||||
# CHECK: String dump of section '.a':
|
||||
# CHECK-NEXT: [ 0] 0
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: String dump of section '.b':
|
||||
# CHECK-NEXT: [ 0] 1
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: String dump of section '.a':
|
||||
# CHECK-NEXT: [ 0] 2
|
||||
|
||||
.section .a,"a",@progbits,unique,0
|
||||
.asciz "0"
|
||||
.section .b,"a",@progbits
|
||||
.asciz "1"
|
||||
.section .a,"a",@progbits,unique,1
|
||||
.asciz "2"
|
@ -9,9 +9,9 @@
|
||||
# flag (-p), with different prefix modes (-p .foo, -p=.foo, -p.foo), and with
|
||||
# the value being a index section number instead of a section name.
|
||||
# RUN: llvm-readobj -p=.strings -p=.not_null_terminated %t > %t.readobj.1
|
||||
# RUN: llvm-readobj -p.strings -p.not_null_terminated %t > %t.readobj.2
|
||||
# RUN: llvm-readobj -p.strings -p.strings -p.not_null_terminated %t > %t.readobj.2
|
||||
# RUN: llvm-readobj --string-dump=1 --string-dump=2 %t > %t.readobj.3
|
||||
# RUN: llvm-readobj -p1 -p2 %t > %t.readobj.4
|
||||
# RUN: llvm-readobj -p1 -p1 -p2 %t > %t.readobj.4
|
||||
# RUN: llvm-readobj -p=1 -p=2 %t > %t.readobj.5
|
||||
|
||||
# RUN: cmp %t.readobj.out %t.readobj.1
|
||||
@ -45,19 +45,20 @@
|
||||
# CHECK-NEXT: [ 5] are
|
||||
# CHECK-NEXT: [ 9] some
|
||||
# CHECK-NEXT: [ e] strings
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: String dump of section '.not_null_terminated':
|
||||
# CHECK-NEXT: [ 0] no
|
||||
# CHECK-NEXT: [ 3] null{{$}}
|
||||
# CHECK-NOT: {{.}}
|
||||
|
||||
# RUN: not llvm-readobj --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=ERR1
|
||||
# RUN: not llvm-readobj --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=ERR2
|
||||
# RUN: llvm-readobj --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=WARN1
|
||||
# RUN: llvm-readobj --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=WARN2
|
||||
|
||||
# RUN: not llvm-readelf --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=ERR1
|
||||
# RUN: not llvm-readelf --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=ERR2
|
||||
# RUN: llvm-readelf --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=WARN1
|
||||
# RUN: llvm-readelf --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=WARN2
|
||||
|
||||
# ERR1: error: could not find section 'does_not_exist'
|
||||
# ERR2: error: could not find section '42'
|
||||
# WARN1: warning: could not find section 'does_not_exist'
|
||||
# WARN2: warning: could not find section 42
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/ScopedPrinter.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -32,115 +33,127 @@ static void printAsPrintable(raw_ostream &W, const uint8_t *Start, size_t Len) {
|
||||
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);
|
||||
long SecIndex;
|
||||
if (Obj->isELF())
|
||||
SecIndex = 0;
|
||||
else
|
||||
SecIndex = 1;
|
||||
static std::vector<object::SectionRef>
|
||||
getSectionRefsByNameOrIndex(const object::ObjectFile *Obj,
|
||||
ArrayRef<std::string> Sections) {
|
||||
std::vector<object::SectionRef> Ret;
|
||||
std::map<std::string, bool> SecNames;
|
||||
std::map<unsigned, bool> SecIndices;
|
||||
unsigned SecIndex;
|
||||
for (StringRef Section : Sections) {
|
||||
if (!Section.getAsInteger(0, SecIndex))
|
||||
SecIndices.emplace(SecIndex, false);
|
||||
else
|
||||
SecNames.emplace(Section, false);
|
||||
}
|
||||
|
||||
SecIndex = Obj->isELF() ? 0 : 1;
|
||||
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;
|
||||
|
||||
StringRef SecName;
|
||||
error(SecRef.getName(SecName));
|
||||
auto NameIt = SecNames.find(SecName);
|
||||
if (NameIt != SecNames.end())
|
||||
NameIt->second = true;
|
||||
auto IndexIt = SecIndices.find(SecIndex);
|
||||
if (IndexIt != SecIndices.end())
|
||||
IndexIt->second = true;
|
||||
if (NameIt != SecNames.end() || IndexIt != SecIndices.end())
|
||||
Ret.push_back(SecRef);
|
||||
SecIndex++;
|
||||
}
|
||||
return make_error<StringError>(
|
||||
formatv("could not find section '{0}'", SecName),
|
||||
object::object_error::parse_failed);
|
||||
|
||||
for (const std::pair<std::string, bool> &S : SecNames)
|
||||
if (!S.second)
|
||||
reportWarning(formatv("could not find section '{0}'", S.first).str());
|
||||
for (std::pair<unsigned, bool> S : SecIndices)
|
||||
if (!S.second)
|
||||
reportWarning(formatv("could not find section {0}", S.first).str());
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
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;
|
||||
void ObjDumper::printSectionsAsString(const object::ObjectFile *Obj,
|
||||
ArrayRef<std::string> Sections) {
|
||||
bool First = true;
|
||||
for (object::SectionRef Section :
|
||||
getSectionRefsByNameOrIndex(Obj, Sections)) {
|
||||
StringRef SectionName;
|
||||
error(Section.getName(SectionName));
|
||||
if (!First)
|
||||
W.startLine() << '\n';
|
||||
First = false;
|
||||
W.startLine() << "String dump of section '" << SectionName << "':\n";
|
||||
|
||||
if (std::error_code E = Section.getName(SectionName))
|
||||
error(E);
|
||||
W.startLine() << "String dump of section '" << SectionName << "':\n";
|
||||
StringRef SectionContent = unwrapOrError(Section.getContents());
|
||||
|
||||
StringRef SectionContent = unwrapOrError(Section.getContents());
|
||||
const uint8_t *SecContent = SectionContent.bytes_begin();
|
||||
const uint8_t *CurrentWord = SecContent;
|
||||
const uint8_t *SecEnd = SectionContent.bytes_end();
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
W.startLine() << format("[%6tx] ", CurrentWord - SecContent);
|
||||
printAsPrintable(W.startLine(), CurrentWord, WordSize);
|
||||
W.startLine() << '\n';
|
||||
CurrentWord += WordSize + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjDumper::printSectionAsHex(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;
|
||||
void ObjDumper::printSectionsAsHex(const object::ObjectFile *Obj,
|
||||
ArrayRef<std::string> Sections) {
|
||||
bool First = true;
|
||||
for (object::SectionRef Section :
|
||||
getSectionRefsByNameOrIndex(Obj, Sections)) {
|
||||
StringRef SectionName;
|
||||
error(Section.getName(SectionName));
|
||||
if (!First)
|
||||
W.startLine() << '\n';
|
||||
First = false;
|
||||
W.startLine() << "Hex dump of section '" << SectionName << "':\n";
|
||||
|
||||
if (std::error_code E = Section.getName(SectionName))
|
||||
error(E);
|
||||
W.startLine() << "Hex dump of section '" << SectionName << "':\n";
|
||||
StringRef SectionContent = unwrapOrError(Section.getContents());
|
||||
const uint8_t *SecContent = SectionContent.bytes_begin();
|
||||
const uint8_t *SecEnd = SecContent + SectionContent.size();
|
||||
|
||||
StringRef SectionContent = unwrapOrError(Section.getContents());
|
||||
const uint8_t *SecContent = SectionContent.bytes_begin();
|
||||
const uint8_t *SecEnd = SecContent + SectionContent.size();
|
||||
for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
|
||||
const uint8_t *TmpSecPtr = SecPtr;
|
||||
uint8_t i;
|
||||
uint8_t k;
|
||||
|
||||
for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
|
||||
const uint8_t *TmpSecPtr = SecPtr;
|
||||
uint8_t i;
|
||||
uint8_t k;
|
||||
|
||||
W.startLine() << format_hex(Section.getAddress() + (SecPtr - SecContent),
|
||||
10);
|
||||
W.startLine() << ' ';
|
||||
for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) {
|
||||
for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) {
|
||||
uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr));
|
||||
W.startLine() << format_hex_no_prefix(Val, 2);
|
||||
}
|
||||
W.startLine() << format_hex(Section.getAddress() + (SecPtr - SecContent),
|
||||
10);
|
||||
W.startLine() << ' ';
|
||||
for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) {
|
||||
for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) {
|
||||
uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr));
|
||||
W.startLine() << format_hex_no_prefix(Val, 2);
|
||||
}
|
||||
W.startLine() << ' ';
|
||||
}
|
||||
|
||||
// We need to print the correct amount of spaces to match the format.
|
||||
// We are adding the (4 - i) last rows that are 8 characters each.
|
||||
// Then, the (4 - i) spaces that are in between the rows.
|
||||
// Least, if we cut in a middle of a row, we add the remaining characters,
|
||||
// which is (8 - (k * 2)).
|
||||
if (i < 4)
|
||||
W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)),
|
||||
' ');
|
||||
|
||||
TmpSecPtr = SecPtr;
|
||||
for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i)
|
||||
W.startLine() << (isPrint(TmpSecPtr[i])
|
||||
? static_cast<char>(TmpSecPtr[i])
|
||||
: '.');
|
||||
|
||||
W.startLine() << '\n';
|
||||
}
|
||||
|
||||
// We need to print the correct amount of spaces to match the format.
|
||||
// We are adding the (4 - i) last rows that are 8 characters each.
|
||||
// Then, the (4 - i) spaces that are in between the rows.
|
||||
// Least, if we cut in a middle of a row, we add the remaining characters,
|
||||
// which is (8 - (k * 2)).
|
||||
if (i < 4)
|
||||
W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)),
|
||||
' ');
|
||||
|
||||
TmpSecPtr = SecPtr;
|
||||
for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i)
|
||||
W.startLine() << (isPrint(TmpSecPtr[i]) ? static_cast<char>(TmpSecPtr[i])
|
||||
: '.');
|
||||
|
||||
W.startLine() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,8 +104,10 @@ public:
|
||||
|
||||
virtual void printStackMap() const = 0;
|
||||
|
||||
void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName);
|
||||
void printSectionAsHex(const object::ObjectFile *Obj, StringRef SecName);
|
||||
void printSectionsAsString(const object::ObjectFile *Obj,
|
||||
ArrayRef<std::string> Sections);
|
||||
void printSectionsAsHex(const object::ObjectFile *Obj,
|
||||
ArrayRef<std::string> Sections);
|
||||
|
||||
protected:
|
||||
ScopedPrinter &W;
|
||||
|
@ -495,13 +495,9 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
|
||||
if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE)
|
||||
Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping);
|
||||
if (!opts::StringDump.empty())
|
||||
llvm::for_each(opts::StringDump, [&Dumper, Obj](StringRef SectionName) {
|
||||
Dumper->printSectionAsString(Obj, SectionName);
|
||||
});
|
||||
Dumper->printSectionsAsString(Obj, opts::StringDump);
|
||||
if (!opts::HexDump.empty())
|
||||
llvm::for_each(opts::HexDump, [&Dumper, Obj](StringRef SectionName) {
|
||||
Dumper->printSectionAsHex(Obj, SectionName);
|
||||
});
|
||||
Dumper->printSectionsAsHex(Obj, opts::HexDump);
|
||||
if (opts::HashTable)
|
||||
Dumper->printHashTable();
|
||||
if (opts::GnuHashTable)
|
||||
|
Loading…
x
Reference in New Issue
Block a user