Skip to content

Commit fe84764

Browse files
authored
[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.
1 parent 0cd7942 commit fe84764

File tree

5 files changed

+41
-31
lines changed

5 files changed

+41
-31
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,8 @@ class CFIProgram {
454454
/// where a problem occurred in case an error is returned.
455455
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
456456

457-
void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
458-
unsigned IndentLevel = 1) const;
457+
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel,
458+
std::optional<uint64_t> InitialLocation) const;
459459

460460
void addInstruction(const Instruction &I) { Instructions.push_back(I); }
461461

@@ -524,7 +524,7 @@ class CFIProgram {
524524
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
525525
void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
526526
const Instruction &Instr, unsigned OperandIdx,
527-
uint64_t Operand) const;
527+
uint64_t Operand, std::optional<uint64_t> &Address) const;
528528
};
529529

530530
/// An entry in either debug_frame or eh_frame. This entry can be a CIE or an

llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,8 @@ CFIProgram::getOperandTypes() {
860860
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
861861
void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
862862
const Instruction &Instr, unsigned OperandIdx,
863-
uint64_t Operand) const {
863+
uint64_t Operand,
864+
std::optional<uint64_t> &Address) const {
864865
assert(OperandIdx < MaxOperands);
865866
uint8_t Opcode = Instr.Opcode;
866867
OperandType Type = getOperandTypes()[Opcode][OperandIdx];
@@ -879,6 +880,7 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
879880
break;
880881
case OT_Address:
881882
OS << format(" %" PRIx64, Operand);
883+
Address = Operand;
882884
break;
883885
case OT_Offset:
884886
// The offsets are all encoded in a unsigned form, but in practice
@@ -890,7 +892,11 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
890892
if (CodeAlignmentFactor)
891893
OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
892894
else
893-
OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
895+
OS << format(" %" PRId64 "*code_alignment_factor", Operand);
896+
if (Address && CodeAlignmentFactor) {
897+
*Address += Operand * CodeAlignmentFactor;
898+
OS << format(" to 0x%" PRIx64, *Address);
899+
}
894900
break;
895901
case OT_SignedFactDataOffset:
896902
if (DataAlignmentFactor)
@@ -920,13 +926,14 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
920926
}
921927

922928
void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
923-
unsigned IndentLevel) const {
929+
unsigned IndentLevel,
930+
std::optional<uint64_t> Address) const {
924931
for (const auto &Instr : Instructions) {
925932
uint8_t Opcode = Instr.Opcode;
926933
OS.indent(2 * IndentLevel);
927934
OS << callFrameString(Opcode) << ":";
928935
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
929-
printOperand(OS, DumpOpts, Instr, i, Instr.Ops[i]);
936+
printOperand(OS, DumpOpts, Instr, i, Instr.Ops[i], Address);
930937
OS << '\n';
931938
}
932939
}
@@ -977,7 +984,7 @@ void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
977984
OS << "\n";
978985
}
979986
OS << "\n";
980-
CFIs.dump(OS, DumpOpts);
987+
CFIs.dump(OS, DumpOpts, /*IndentLevel=*/1, /*InitialLocation=*/{});
981988
OS << "\n";
982989

983990
if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this))
@@ -1005,7 +1012,7 @@ void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
10051012
OS << " Format: " << FormatString(IsDWARF64) << "\n";
10061013
if (LSDAAddress)
10071014
OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
1008-
CFIs.dump(OS, DumpOpts);
1015+
CFIs.dump(OS, DumpOpts, /*IndentLevel=*/1, InitialLocation);
10091016
OS << "\n";
10101017

10111018
if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this))

llvm/test/DebugInfo/dwarfdump-debug-frame-simple.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
; FRAMES-NEXT: DW_CFA_nop:
1313

1414
; FRAMES: 00000014 00000010 00000000 FDE cie=00000000 pc=00000000...00000022
15-
; FRAMES: DW_CFA_advance_loc: 3
15+
; FRAMES: DW_CFA_advance_loc: 3 to 0x3
1616
; FRAMES-NEXT: DW_CFA_def_cfa_offset: +12
1717
; FRAMES-NEXT: DW_CFA_nop:
1818

1919
; FRAMES: 00000028 00000014 00000000 FDE cie=00000000 pc=00000030...00000080
20-
; FRAMES: DW_CFA_advance_loc: 1
20+
; FRAMES: DW_CFA_advance_loc: 1 to 0x31
2121
; FRAMES-NEXT: DW_CFA_def_cfa_offset: +8
2222
; FRAMES-NEXT: DW_CFA_offset: {{reg5|EBP}} -8
23-
; FRAMES-NEXT: DW_CFA_advance_loc: 2
23+
; FRAMES-NEXT: DW_CFA_advance_loc: 2 to 0x33
2424
; FRAMES-NEXT: DW_CFA_def_cfa_register: {{reg5|EBP}}
2525

2626
; FRAMES-NOT: CIE

llvm/test/tools/llvm-readobj/ELF/unwind.test

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@
9696

9797
# CHECK: Program:
9898
# CHECK-NEXT: DW_CFA_def_cfa_offset: +16
99-
# CHECK-NEXT: DW_CFA_advance_loc: 6
99+
# CHECK-NEXT: DW_CFA_advance_loc: 6 to 0x4004a6
100100
# CHECK-NEXT: DW_CFA_def_cfa_offset: +24
101-
# CHECK-NEXT: DW_CFA_advance_loc: 10
101+
# CHECK-NEXT: DW_CFA_advance_loc: 10 to 0x4004b0
102102
# 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
103103
# CHECK-NEXT: DW_CFA_nop:
104104
# CHECK-NEXT: DW_CFA_nop:
@@ -110,12 +110,12 @@
110110
# CHECK-NEXT: address_range: 0x10 (end : 0x4005c6)
111111

112112
# CHECK: Program:
113-
# CHECK-NEXT: DW_CFA_advance_loc: 1
113+
# CHECK-NEXT: DW_CFA_advance_loc: 1 to 0x4005b7
114114
# CHECK-NEXT: DW_CFA_def_cfa_offset: +16
115115
# CHECK-NEXT: DW_CFA_offset: reg6 -16
116-
# CHECK-NEXT: DW_CFA_advance_loc: 3
116+
# CHECK-NEXT: DW_CFA_advance_loc: 3 to 0x4005ba
117117
# CHECK-NEXT: DW_CFA_def_cfa_register: reg6
118-
# CHECK-NEXT: DW_CFA_advance_loc: 11
118+
# CHECK-NEXT: DW_CFA_advance_loc: 11 to 0x4005c5
119119
# CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
120120
# CHECK-NEXT: DW_CFA_nop:
121121
# CHECK-NEXT: DW_CFA_nop:
@@ -126,15 +126,15 @@
126126
# CHECK-NEXT: address_range: 0xc7f (end : 0x40124f)
127127

128128
# CHECK: Program:
129-
# CHECK-NEXT: DW_CFA_advance_loc: 5
129+
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x4005d5
130130
# CHECK-NEXT: DW_CFA_def_cfa: reg10 +0
131-
# CHECK-NEXT: DW_CFA_advance_loc: 9
131+
# CHECK-NEXT: DW_CFA_advance_loc: 9 to 0x4005de
132132
# CHECK-NEXT: DW_CFA_expression: reg6 DW_OP_breg6 +0
133-
# CHECK-NEXT: DW_CFA_advance_loc: 5
133+
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x4005e3
134134
# CHECK-NEXT: DW_CFA_def_cfa_expression: DW_OP_breg6 -8, DW_OP_deref
135-
# CHECK-NEXT: DW_CFA_advance_loc2: 3174
135+
# CHECK-NEXT: DW_CFA_advance_loc2: 3174 to 0x401249
136136
# CHECK-NEXT: DW_CFA_def_cfa: reg10 +0
137-
# CHECK-NEXT: DW_CFA_advance_loc: 5
137+
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x40124e
138138
# CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
139139
# CHECK-NEXT: DW_CFA_nop:
140140
# CHECK-NEXT: DW_CFA_nop:
@@ -146,21 +146,21 @@
146146
# CHECK-NEXT: address_range: 0x66 (end : 0x4012b6)
147147

148148
# CHECK: Program:
149-
# CHECK-NEXT: DW_CFA_advance_loc: 1
149+
# CHECK-NEXT: DW_CFA_advance_loc: 1 to 0x401251
150150
# CHECK-NEXT: DW_CFA_def_cfa_offset: +16
151151
# CHECK-NEXT: DW_CFA_offset: reg6 -16
152-
# CHECK-NEXT: DW_CFA_advance_loc: 3
152+
# CHECK-NEXT: DW_CFA_advance_loc: 3 to 0x401254
153153
# CHECK-NEXT: DW_CFA_def_cfa_register: reg6
154-
# CHECK-NEXT: DW_CFA_advance_loc: 2
154+
# CHECK-NEXT: DW_CFA_advance_loc: 2 to 0x401256
155155
# CHECK-NEXT: DW_CFA_offset: reg15 -24
156-
# CHECK-NEXT: DW_CFA_advance_loc: 5
156+
# CHECK-NEXT: DW_CFA_advance_loc: 5 to 0x40125b
157157
# CHECK-NEXT: DW_CFA_offset: reg14 -32
158-
# CHECK-NEXT: DW_CFA_advance_loc: 7
158+
# CHECK-NEXT: DW_CFA_advance_loc: 7 to 0x401262
159159
# CHECK-NEXT: DW_CFA_offset: reg13 -40
160160
# CHECK-NEXT: DW_CFA_offset: reg12 -48
161-
# CHECK-NEXT: DW_CFA_advance_loc: 8
161+
# CHECK-NEXT: DW_CFA_advance_loc: 8 to 0x40126a
162162
# CHECK-NEXT: DW_CFA_offset: reg3 -56
163-
# CHECK-NEXT: DW_CFA_advance_loc1: 75
163+
# CHECK-NEXT: DW_CFA_advance_loc1: 75 to 0x4012b5
164164
# CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
165165
# CHECK-NEXT: DW_CFA_nop:
166166
# CHECK-NEXT: DW_CFA_nop:

llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
196196
reportError(std::move(E), ObjF.getFileName());
197197

198198
for (const dwarf::FrameEntry &Entry : EHFrame) {
199+
std::optional<uint64_t> InitialLocation;
199200
if (const dwarf::CIE *CIE = dyn_cast<dwarf::CIE>(&Entry)) {
200201
W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n",
201202
Address + CIE->getOffset(), CIE->getLength());
@@ -214,8 +215,9 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
214215
Address + FDE->getLinkedCIE()->getOffset());
215216
W.indent();
216217

218+
InitialLocation = FDE->getInitialLocation();
217219
W.startLine() << format("initial_location: 0x%" PRIx64 "\n",
218-
FDE->getInitialLocation());
220+
*InitialLocation);
219221
W.startLine() << format(
220222
"address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",
221223
FDE->getAddressRange(),
@@ -227,7 +229,8 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
227229
W.indent();
228230
auto DumpOpts = DIDumpOptions();
229231
DumpOpts.IsEH = true;
230-
Entry.cfis().dump(W.getOStream(), DumpOpts, W.getIndentLevel());
232+
Entry.cfis().dump(W.getOStream(), DumpOpts, W.getIndentLevel(),
233+
InitialLocation);
231234
W.unindent();
232235
W.unindent();
233236
W.getOStream() << "\n";

0 commit comments

Comments
 (0)