Index: test/tools/llvm-objdump/X86/start-stop-address.test =================================================================== --- /dev/null +++ test/tools/llvm-objdump/X86/start-stop-address.test @@ -0,0 +1,29 @@ +// RUN: llvm-objdump -d %p/Inputs/simple-executable-x86_64 --start-address=0x18 --stop-address=0x2f | FileCheck %s +// RUN: llvm-objdump -d %p/Inputs/simple-executable-x86_64 --start-address=0xc --stop-address=0x11 | FileCheck %s --check-prefix "CROSSSECTION" +// RUN: llvm-objdump -d %p/Inputs/simple-executable-x86_64 --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 + Index: tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- tools/llvm-objdump/llvm-objdump.cpp +++ tools/llvm-objdump/llvm-objdump.cpp @@ -205,6 +205,13 @@ cl::alias PrintLinesShort("l", cl::desc("Alias for -line-numbers"), cl::aliasopt(PrintLines)); + +cl::opt + StartAddress("start-address", cl::desc("Disassemble beginning at address"), + cl::value_desc("address"), cl::init(0)); +cl::opt + StopAddress("stop-address", cl::desc("Stop disassembly at address"), + cl::value_desc("address"), cl::init(UINT64_MAX)); static StringRef ToolName; namespace { @@ -1060,6 +1067,9 @@ } 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 @@ -1238,10 +1248,14 @@ } 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) { @@ -1278,6 +1292,17 @@ 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); @@ -1308,6 +1333,12 @@ 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 @@ -1384,6 +1415,9 @@ 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"; @@ -1491,6 +1525,8 @@ // If this relocation is hidden, skip it. if (hidden) goto skip_print_rel; + if ((SectionAddr + addr) < StartAddress) + goto skip_print_rel; // Stop when rel_cur's address is past the current instruction. if (addr >= Index + Size) break; rel_cur->getTypeName(name); @@ -1525,7 +1561,7 @@ 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)); @@ -1616,6 +1652,8 @@ if (!AddressOrError) report_error(ArchiveName, o->getFileName(), AddressOrError.takeError()); uint64_t Address = *AddressOrError; + if ((Address < StartAddress) || (Address > StopAddress)) + continue; Expected TypeOrError = Symbol.getType(); if (!TypeOrError) report_error(ArchiveName, o->getFileName(), TypeOrError.takeError());