diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h index bc35f2ab988e..c7c558850a28 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -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 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 &Address) const; }; /// An entry in either debug_frame or eh_frame. This entry can be a CIE or an diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index 0c968703f80b..aff26824dda1 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -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 &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 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 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 RowsOrErr = UnwindTable::create(this)) diff --git a/llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test b/llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test index 6c049af43efe..2cd281c8d0af 100644 --- a/llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test +++ b/llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test @@ -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 diff --git a/llvm/test/tools/llvm-readobj/ELF/unwind.test b/llvm/test/tools/llvm-readobj/ELF/unwind.test index 2deb1a587d24..2e51ec2a61a6 100644 --- a/llvm/test/tools/llvm-readobj/ELF/unwind.test +++ b/llvm/test/tools/llvm-readobj/ELF/unwind.test @@ -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: diff --git a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h index 687d97abd023..2e89463e68d5 100644 --- a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h +++ b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h @@ -196,6 +196,7 @@ void PrinterContext::printEHFrame(const Elf_Shdr *EHFrameShdr) const { reportError(std::move(E), ObjF.getFileName()); for (const dwarf::FrameEntry &Entry : EHFrame) { + std::optional InitialLocation; if (const dwarf::CIE *CIE = dyn_cast(&Entry)) { W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n", Address + CIE->getOffset(), CIE->getLength()); @@ -214,8 +215,9 @@ void PrinterContext::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::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";