--- /dev/null
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000010
+ Content: 554889E58B0425A80000005DC30F1F00
+ - Name: .anothertext
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000000010
+ AddressAlign: 0x0000000000000010
+ Content: 554889E54883EC20488D0425A8000000C745FC00000000488945F0488B45F08B08894DECE8C7FFFFFF8B4DEC01C189C84883C4205D746573742073747200C3
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x0000000000000050
+ AddressAlign: 0x0000000000000008
+ Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C00000090FFFFFF0D00000000410E108602430D06000000000000001C0000003C00000080FFFFFF3F00000000410E108602430D0600000000000000
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x00000000000000A8
+ AddressAlign: 0x0000000000000004
+ Content: '01000000'
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: 5562756E747520636C616E672076657273696F6E20332E352D317562756E74753120287472756E6B2920286261736564206F6E204C4C564D20332E352900
+Symbols:
+ Local:
+ - Type: STT_SECTION
+ Section: .text
+ - Type: STT_SECTION
+ Section: .anothertext
+ Value: 0x0000000000000010
+ - Type: STT_SECTION
+ Section: .eh_frame
+ Value: 0x0000000000000050
+ - Type: STT_SECTION
+ Section: .data
+ Value: 0x00000000000000A8
+ - Type: STT_SECTION
+ Section: .comment
+ - Name: /tmp/a.c
+ Type: STT_FILE
+ - Type: STT_FILE
+ Global:
+ - Name: somedata
+ Type: STT_OBJECT
+ Section: .anothertext
+ Value: 0x0000000000000045
+ - Name: main
+ Type: STT_FUNC
+ Section: .anothertext
+ Value: 0x0000000000000010
+ Size: 0x000000000000003F
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Size: 0x000000000000000D
+ - Name: a
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x00000000000000A8
+ Size: 0x0000000000000004
+...
--- /dev/null
+// RUN: yaml2obj -o %t.out %p/Inputs/simple-executable-x86_64.yaml
+// RUN: llvm-objdump -d %t.out --start-address=0x18 --stop-address=0x2f | FileCheck %s
+// RUN: llvm-objdump -d %t.out --start-address=0xc --stop-address=0x11 | FileCheck %s --check-prefix "CROSSSECTION"
+// RUN: llvm-objdump -d %t.out --start-address=0x40 --stop-address=0x47 | FileCheck %s --check-prefix "CROSSDATA"
+
+// CHECK: Disassembly of section .anothertext:
+// CHECK-NEXT: main:
+// CHECK-NEXT: 18: 48 8d 04 25 a8 00 00 00 leaq 168, %rax
+// CHECK-NEXT: 20: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
+// CHECK-NEXT: 27: 48 89 45 f0 movq %rax, -16(%rbp)
+// CHECK-NEXT: 2b: 48 8b 45 f0 movq -16(%rbp), %rax
+// CHECK-NOT: 2f:
+
+// CROSSSECTION: Disassembly of section .text:
+// CROSSSECTION-NEXT: foo:
+// CROSSSECTION-NEXT: c: c3 retq
+// CROSSSECTION-NEXT: d: 0f 1f 00 nopl (%rax)
+// CROSSSECTION-NEXT: Disassembly of section .anothertext:
+// CROSSSECTION-NEXT: main:
+// CROSSSECTION-NEXT: 10: 55 pushq %rbp
+// CROSSSECTION-NOT: 11:
+
+// CROSSDATA: Disassembly of section .anothertext:
+// CROSSDATA: main:
+// CROSSDATA: 40: 48 83 c4 20 addq $32, %rsp
+// CROSSDATA: 44: 5d popq %rbp
+// CROSSDATA-DAG: somedata:
+// CROSSDATA-NEXT: 45: 74 65 te
+
cl::alias PrintLinesShort("l", cl::desc("Alias for -line-numbers"),
cl::aliasopt(PrintLines));
+
+cl::opt<unsigned long long>
+ StartAddress("start-address", cl::desc("Disassemble beginning at address"),
+ cl::value_desc("address"), cl::init(0));
+cl::opt<unsigned long long>
+ StopAddress("stop-address", cl::desc("Stop disassembly at address"),
+ cl::value_desc("address"), cl::init(UINT64_MAX));
static StringRef ToolName;
namespace {
}
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
+ if (StartAddress > StopAddress)
+ error("Start address should be less than stop address");
+
const Target *TheTarget = getTarget(Obj);
// Package up features to be passed to target/subtarget
}
StringRef name;
error(Section.getName(name));
+
+ if ((SectionAddr <= StopAddress) &&
+ (SectionAddr + SectSize) >= StartAddress) {
outs() << "Disassembly of section ";
if (!SegmentName.empty())
outs() << SegmentName << ",";
outs() << name << ':';
+ }
// If the section has no symbol at the start, just insert a dummy one.
if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) {
if (Start >= End)
continue;
+ // Check if we need to skip symbol
+ // Skip if the symbol's data is not between StartAddress and StopAddress
+ if (End + SectionAddr < StartAddress ||
+ Start + SectionAddr > StopAddress) {
+ continue;
+ }
+
+ // Stop disassembly at the stop address specified
+ if (End + SectionAddr > StopAddress)
+ End = StopAddress - SectionAddr;
+
if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
// make size 4 bytes folded
End = Start + ((End - Start) & ~0x3ull);
for (Index = Start; Index < End; Index += Size) {
MCInst Inst;
+ if (Index + SectionAddr < StartAddress ||
+ Index + SectionAddr > StopAddress) {
+ // skip byte by byte till StartAddress is reached
+ Size = 1;
+ continue;
+ }
// AArch64 ELF binaries can interleave data and text in the
// same section. We rely on the markers introduced to
// understand what we need to dump. If the data marker is within a
int NumBytes = 0;
for (Index = Start; Index < End; Index += 1) {
+ if (((SectionAddr + Index) < StartAddress) ||
+ ((SectionAddr + Index) > StopAddress))
+ continue;
if (NumBytes == 0) {
outs() << format("%8" PRIx64 ":", SectionAddr + Index);
outs() << "\t";
SmallString<32> val;
// If this relocation is hidden, skip it.
- if (hidden) goto skip_print_rel;
+ if (hidden || ((SectionAddr + addr) < StartAddress)) {
+ ++rel_cur;
+ continue;
+ }
// Stop when rel_cur's address is past the current instruction.
if (addr >= Index + Size) break;
error(getRelocationValueString(*rel_cur, val));
outs() << format(Fmt.data(), SectionAddr + addr) << name
<< "\t" << val << "\n";
-
- skip_print_rel:
++rel_cur;
}
}
uint64_t address = Reloc.getOffset();
SmallString<32> relocname;
SmallString<32> valuestr;
- if (hidden)
+ if (address < StartAddress || address > StopAddress || hidden)
continue;
Reloc.getTypeName(relocname);
error(getRelocationValueString(Reloc, valuestr));
if (!AddressOrError)
report_error(ArchiveName, o->getFileName(), AddressOrError.takeError());
uint64_t Address = *AddressOrError;
+ if ((Address < StartAddress) || (Address > StopAddress))
+ continue;
Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
if (!TypeOrError)
report_error(ArchiveName, o->getFileName(), TypeOrError.takeError());