[llvm] [DWARF] Dump an updated location for DW_CFA_advance_loc* (PR #84274)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 6 19:51:11 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Igor Kudrin (igorkudrin)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/84274.diff
5 Files Affected:
- (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h (+3-3)
- (modified) llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (+13-6)
- (modified) llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test (+3-3)
- (modified) llvm/test/tools/llvm-readobj/ELF/unwind.test (+17-17)
- (modified) llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h (+5-2)
``````````diff
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index bc35f2ab988ed2..c7c558850a2805 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -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); }
@@ -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
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index aae1668c1639c4..0f77d9f5f76058 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -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];
@@ -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
@@ -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)
@@ -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';
}
}
@@ -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))
@@ -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))
diff --git a/llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test b/llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test
index 6c049af43efe74..2cd281c8d0af9f 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 2deb1a587d2438..2e51ec2a61a637 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 687d97abd0232d..2e89463e68d519 100644
--- a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
+++ b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
@@ -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";
``````````
</details>
https://github.com/llvm/llvm-project/pull/84274
More information about the llvm-commits
mailing list