[DWARF] Dump an updated location for DW_CFA_advance_loc* (#84274)
When dumping FDEs, `readelf` prints new location values after `DW_CFA_advance_loc(*)` instructions, which looks quite convenient: ``` > readelf -wf test.o ... ... FDE ... pc=0000000000000030..0000000000000064 DW_CFA_advance_loc: 4 to 0000000000000034 ... DW_CFA_advance_loc: 4 to 0000000000000038 ... ``` This patch makes `llvm-dwarfdump` and `llvm-readobj` do the same.
This commit is contained in:
parent
0cd7942c7f
commit
fe84764724
@ -454,8 +454,8 @@ public:
|
||||
/// where a problem occurred in case an error is returned.
|
||||
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
|
||||
|
||||
void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
unsigned IndentLevel = 1) const;
|
||||
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel,
|
||||
std::optional<uint64_t> InitialLocation) const;
|
||||
|
||||
void addInstruction(const Instruction &I) { Instructions.push_back(I); }
|
||||
|
||||
@ -524,7 +524,7 @@ private:
|
||||
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
|
||||
void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
const Instruction &Instr, unsigned OperandIdx,
|
||||
uint64_t Operand) const;
|
||||
uint64_t Operand, std::optional<uint64_t> &Address) const;
|
||||
};
|
||||
|
||||
/// An entry in either debug_frame or eh_frame. This entry can be a CIE or an
|
||||
|
||||
@ -860,7 +860,8 @@ CFIProgram::getOperandTypes() {
|
||||
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
|
||||
void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
const Instruction &Instr, unsigned OperandIdx,
|
||||
uint64_t Operand) const {
|
||||
uint64_t Operand,
|
||||
std::optional<uint64_t> &Address) const {
|
||||
assert(OperandIdx < MaxOperands);
|
||||
uint8_t Opcode = Instr.Opcode;
|
||||
OperandType Type = getOperandTypes()[Opcode][OperandIdx];
|
||||
@ -879,6 +880,7 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
break;
|
||||
case OT_Address:
|
||||
OS << format(" %" PRIx64, Operand);
|
||||
Address = Operand;
|
||||
break;
|
||||
case OT_Offset:
|
||||
// The offsets are all encoded in a unsigned form, but in practice
|
||||
@ -890,7 +892,11 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
if (CodeAlignmentFactor)
|
||||
OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
|
||||
else
|
||||
OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
|
||||
OS << format(" %" PRId64 "*code_alignment_factor", Operand);
|
||||
if (Address && CodeAlignmentFactor) {
|
||||
*Address += Operand * CodeAlignmentFactor;
|
||||
OS << format(" to 0x%" PRIx64, *Address);
|
||||
}
|
||||
break;
|
||||
case OT_SignedFactDataOffset:
|
||||
if (DataAlignmentFactor)
|
||||
@ -920,13 +926,14 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
}
|
||||
|
||||
void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
unsigned IndentLevel) const {
|
||||
unsigned IndentLevel,
|
||||
std::optional<uint64_t> Address) const {
|
||||
for (const auto &Instr : Instructions) {
|
||||
uint8_t Opcode = Instr.Opcode;
|
||||
OS.indent(2 * IndentLevel);
|
||||
OS << callFrameString(Opcode) << ":";
|
||||
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
|
||||
printOperand(OS, DumpOpts, Instr, i, Instr.Ops[i]);
|
||||
printOperand(OS, DumpOpts, Instr, i, Instr.Ops[i], Address);
|
||||
OS << '\n';
|
||||
}
|
||||
}
|
||||
@ -977,7 +984,7 @@ void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
|
||||
OS << "\n";
|
||||
}
|
||||
OS << "\n";
|
||||
CFIs.dump(OS, DumpOpts);
|
||||
CFIs.dump(OS, DumpOpts, /*IndentLevel=*/1, /*InitialLocation=*/{});
|
||||
OS << "\n";
|
||||
|
||||
if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this))
|
||||
@ -1005,7 +1012,7 @@ void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
|
||||
OS << " Format: " << FormatString(IsDWARF64) << "\n";
|
||||
if (LSDAAddress)
|
||||
OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
|
||||
CFIs.dump(OS, DumpOpts);
|
||||
CFIs.dump(OS, DumpOpts, /*IndentLevel=*/1, InitialLocation);
|
||||
OS << "\n";
|
||||
|
||||
if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this))
|
||||
|
||||
@ -12,15 +12,15 @@
|
||||
; FRAMES-NEXT: DW_CFA_nop:
|
||||
|
||||
; FRAMES: 00000014 00000010 00000000 FDE cie=00000000 pc=00000000...00000022
|
||||
; FRAMES: DW_CFA_advance_loc: 3
|
||||
; FRAMES: DW_CFA_advance_loc: 3 to 0x3
|
||||
; FRAMES-NEXT: DW_CFA_def_cfa_offset: +12
|
||||
; FRAMES-NEXT: DW_CFA_nop:
|
||||
|
||||
; FRAMES: 00000028 00000014 00000000 FDE cie=00000000 pc=00000030...00000080
|
||||
; FRAMES: DW_CFA_advance_loc: 1
|
||||
; FRAMES: DW_CFA_advance_loc: 1 to 0x31
|
||||
; FRAMES-NEXT: DW_CFA_def_cfa_offset: +8
|
||||
; FRAMES-NEXT: DW_CFA_offset: {{reg5|EBP}} -8
|
||||
; FRAMES-NEXT: DW_CFA_advance_loc: 2
|
||||
; FRAMES-NEXT: DW_CFA_advance_loc: 2 to 0x33
|
||||
; FRAMES-NEXT: DW_CFA_def_cfa_register: {{reg5|EBP}}
|
||||
|
||||
; FRAMES-NOT: CIE
|
||||
|
||||
@ -96,9 +96,9 @@
|
||||
|
||||
# CHECK: Program:
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_offset: +16
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 6
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 6 to 0x4004a6
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_offset: +24
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 10
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 10 to 0x4004b0
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_expression: DW_OP_breg7 +8, DW_OP_breg16 +0, DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge, DW_OP_lit3, DW_OP_shl, DW_OP_plus
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
@ -110,12 +110,12 @@
|
||||
# CHECK-NEXT: address_range: 0x10 (end : 0x4005c6)
|
||||
|
||||
# CHECK: Program:
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 1
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 1 to 0x4005b7
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_offset: +16
|
||||
# CHECK-NEXT: DW_CFA_offset: reg6 -16
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 3
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 3 to 0x4005ba
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_register: reg6
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 11
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 11 to 0x4005c5
|
||||
# CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
@ -126,15 +126,15 @@
|
||||
# CHECK-NEXT: address_range: 0xc7f (end : 0x40124f)
|
||||
|
||||
# CHECK: Program:
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x4005d5
|
||||
# CHECK-NEXT: DW_CFA_def_cfa: reg10 +0
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 9
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 9 to 0x4005de
|
||||
# CHECK-NEXT: DW_CFA_expression: reg6 DW_OP_breg6 +0
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x4005e3
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_expression: DW_OP_breg6 -8, DW_OP_deref
|
||||
# CHECK-NEXT: DW_CFA_advance_loc2: 3174
|
||||
# CHECK-NEXT: DW_CFA_advance_loc2: 3174 to 0x401249
|
||||
# CHECK-NEXT: DW_CFA_def_cfa: reg10 +0
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x40124e
|
||||
# CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
@ -146,21 +146,21 @@
|
||||
# CHECK-NEXT: address_range: 0x66 (end : 0x4012b6)
|
||||
|
||||
# CHECK: Program:
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 1
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 1 to 0x401251
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_offset: +16
|
||||
# CHECK-NEXT: DW_CFA_offset: reg6 -16
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 3
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 3 to 0x401254
|
||||
# CHECK-NEXT: DW_CFA_def_cfa_register: reg6
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 2
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 2 to 0x401256
|
||||
# CHECK-NEXT: DW_CFA_offset: reg15 -24
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x40125b
|
||||
# CHECK-NEXT: DW_CFA_offset: reg14 -32
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 7
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 7 to 0x401262
|
||||
# CHECK-NEXT: DW_CFA_offset: reg13 -40
|
||||
# CHECK-NEXT: DW_CFA_offset: reg12 -48
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 8
|
||||
# CHECK-NEXT: DW_CFA_advance_loc: 8 to 0x40126a
|
||||
# CHECK-NEXT: DW_CFA_offset: reg3 -56
|
||||
# CHECK-NEXT: DW_CFA_advance_loc1: 75
|
||||
# CHECK-NEXT: DW_CFA_advance_loc1: 75 to 0x4012b5
|
||||
# CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
# CHECK-NEXT: DW_CFA_nop:
|
||||
|
||||
@ -196,6 +196,7 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
|
||||
reportError(std::move(E), ObjF.getFileName());
|
||||
|
||||
for (const dwarf::FrameEntry &Entry : EHFrame) {
|
||||
std::optional<uint64_t> InitialLocation;
|
||||
if (const dwarf::CIE *CIE = dyn_cast<dwarf::CIE>(&Entry)) {
|
||||
W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n",
|
||||
Address + CIE->getOffset(), CIE->getLength());
|
||||
@ -214,8 +215,9 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
|
||||
Address + FDE->getLinkedCIE()->getOffset());
|
||||
W.indent();
|
||||
|
||||
InitialLocation = FDE->getInitialLocation();
|
||||
W.startLine() << format("initial_location: 0x%" PRIx64 "\n",
|
||||
FDE->getInitialLocation());
|
||||
*InitialLocation);
|
||||
W.startLine() << format(
|
||||
"address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",
|
||||
FDE->getAddressRange(),
|
||||
@ -227,7 +229,8 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
|
||||
W.indent();
|
||||
auto DumpOpts = DIDumpOptions();
|
||||
DumpOpts.IsEH = true;
|
||||
Entry.cfis().dump(W.getOStream(), DumpOpts, W.getIndentLevel());
|
||||
Entry.cfis().dump(W.getOStream(), DumpOpts, W.getIndentLevel(),
|
||||
InitialLocation);
|
||||
W.unindent();
|
||||
W.unindent();
|
||||
W.getOStream() << "\n";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user