Skip to content

[DWARF] Dump an updated location for DW_CFA_advance_loc* #84274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,8 @@ class CFIProgram {
/// 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); }

Expand Down Expand Up @@ -524,7 +524,7 @@ class CFIProgram {
/// 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
Expand Down
19 changes: 13 additions & 6 deletions llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,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];
Expand All @@ -877,6 +878,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
Expand All @@ -888,7 +890,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)
Expand Down Expand Up @@ -918,13 +924,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';
}
}
Expand Down Expand Up @@ -975,7 +982,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))
Expand Down Expand Up @@ -1003,7 +1010,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))
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 17 additions & 17 deletions llvm/test/tools/llvm-readobj/ELF/unwind.test
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand Down
7 changes: 5 additions & 2 deletions llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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(),
Expand All @@ -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";
Expand Down