Skip to content

Commit 1fbe8a8

Browse files
committed
[DWARF] Add support for parsing/dumping section indices in location lists
Summary: This does exactly what it says on the box. The only small gotcha is the section index computation for offset_pair entries, which can use either the base address section, or the section from the offset_pair entry. This is to support both the cases where the base address is relocated (points to the base of the CU, typically), and the case where the base address is a constant (typically zero) and relocations are on the offsets themselves. Reviewers: dblaikie, JDevlieghere, aprantl, SouraVX Subscribers: hiraditya, llvm-commits, probinson Tags: #llvm Differential Revision: https://reviews.llvm.org/D70540
1 parent 46d0ec3 commit 1fbe8a8

File tree

6 files changed

+113
-54
lines changed

6 files changed

+113
-54
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ struct DWARFLocationEntry {
3434
/// The second value of the location entry (if applicable).
3535
uint64_t Value1;
3636

37+
/// The index of the section this entry is relative to (if applicable).
38+
uint64_t SectionIndex;
39+
3740
/// The location expression itself (if applicable).
3841
SmallVector<uint8_t, 4> Loc;
3942
};
@@ -60,8 +63,9 @@ class DWARFLocationTable {
6063
/// updated to point past the end of the current list).
6164
bool dumpLocationList(uint64_t *Offset, raw_ostream &OS,
6265
Optional<object::SectionedAddress> BaseAddr,
63-
const MCRegisterInfo *MRI, DWARFUnit *U,
64-
DIDumpOptions DumpOpts, unsigned Indent) const;
66+
const MCRegisterInfo *MRI, const DWARFObject &Obj,
67+
DWARFUnit *U, DIDumpOptions DumpOpts,
68+
unsigned Indent) const;
6569

6670
Error visitAbsoluteLocationList(
6771
uint64_t Offset, Optional<object::SectionedAddress> BaseAddr,
@@ -72,7 +76,8 @@ class DWARFLocationTable {
7276
DWARFDataExtractor Data;
7377

7478
virtual void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
75-
unsigned Indent) const = 0;
79+
unsigned Indent, DIDumpOptions DumpOpts,
80+
const DWARFObject &Obj) const = 0;
7681
};
7782

7883
class DWARFDebugLoc final : public DWARFLocationTable {
@@ -98,7 +103,8 @@ class DWARFDebugLoc final : public DWARFLocationTable {
98103
: DWARFLocationTable(std::move(Data)) {}
99104

100105
/// Print the location lists found within the debug_loc section.
101-
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, DIDumpOptions DumpOpts,
106+
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo,
107+
const DWARFObject &Obj, DIDumpOptions DumpOpts,
102108
Optional<uint64_t> Offset) const;
103109

104110
Error visitLocationList(
@@ -107,7 +113,8 @@ class DWARFDebugLoc final : public DWARFLocationTable {
107113

108114
protected:
109115
void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
110-
unsigned Indent) const override;
116+
unsigned Indent, DIDumpOptions DumpOpts,
117+
const DWARFObject &Obj) const override;
111118
};
112119

113120
class DWARFDebugLoclists final : public DWARFLocationTable {
@@ -121,11 +128,13 @@ class DWARFDebugLoclists final : public DWARFLocationTable {
121128

122129
/// Dump all location lists within the given range.
123130
void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS,
124-
const MCRegisterInfo *MRI, DIDumpOptions DumpOpts);
131+
const MCRegisterInfo *MRI, const DWARFObject &Obj,
132+
DIDumpOptions DumpOpts);
125133

126134
protected:
127135
void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
128-
unsigned Indent) const override;
136+
unsigned Indent, DIDumpOptions DumpOpts,
137+
const DWARFObject &Obj) const override;
129138

130139
private:
131140
uint16_t Version;

llvm/lib/DebugInfo/DWARF/DWARFContext.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ static void dumpRnglistsSection(
288288
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
289289
DWARFDataExtractor Data,
290290
const MCRegisterInfo *MRI,
291+
const DWARFObject &Obj,
291292
Optional<uint64_t> DumpOffset) {
292293
uint64_t Offset = 0;
293294

@@ -306,13 +307,13 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
306307
if (DumpOffset) {
307308
if (DumpOffset >= Offset && DumpOffset < EndOffset) {
308309
Offset = *DumpOffset;
309-
Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, nullptr,
310+
Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr,
310311
DumpOpts, /*Indent=*/0);
311312
OS << "\n";
312313
return;
313314
}
314315
} else {
315-
Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, DumpOpts);
316+
Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts);
316317
}
317318
Offset = EndOffset;
318319
}
@@ -394,21 +395,21 @@ void DWARFContext::dump(
394395

395396
if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
396397
DObj->getLocSection().Data)) {
397-
getDebugLoc()->dump(OS, getRegisterInfo(), LLDumpOpts, *Off);
398+
getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off);
398399
}
399400
if (const auto *Off =
400401
shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
401402
DObj->getLoclistsSection().Data)) {
402403
DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
403404
0);
404-
dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *Off);
405+
dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
405406
}
406407
if (const auto *Off =
407408
shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
408409
DObj->getLoclistsDWOSection().Data)) {
409410
DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
410411
isLittleEndian(), 0);
411-
dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *Off);
412+
dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
412413
}
413414

414415
if (const auto *Off =
@@ -420,11 +421,11 @@ void DWARFContext::dump(
420421
if (*Off) {
421422
uint64_t Offset = **Off;
422423
Loc.dumpLocationList(&Offset, OS,
423-
/*BaseAddr=*/None, getRegisterInfo(), nullptr,
424+
/*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr,
424425
LLDumpOpts, /*Indent=*/0);
425426
OS << "\n";
426427
} else {
427-
Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(),
428+
Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj,
428429
LLDumpOpts);
429430
}
430431
}

llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,24 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
6666
LowPC->SectionIndex},
6767
E.Loc};
6868
}
69-
case dwarf::DW_LLE_offset_pair:
69+
case dwarf::DW_LLE_offset_pair: {
7070
if (!Base) {
7171
return createStringError(
7272
inconvertibleErrorCode(),
7373
"Unable to resolve DW_LLE_offset_pair: base address unknown");
7474
}
75-
return DWARFLocationExpression{DWARFAddressRange{Base->Address + E.Value0,
76-
Base->Address + E.Value1,
77-
Base->SectionIndex},
78-
E.Loc};
75+
DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
76+
Base->SectionIndex};
77+
if (Range.SectionIndex == SectionedAddress::UndefSection)
78+
Range.SectionIndex = E.SectionIndex;
79+
return DWARFLocationExpression{Range, E.Loc};
80+
}
7981
case dwarf::DW_LLE_base_address:
80-
Base = SectionedAddress{E.Value0, SectionedAddress::UndefSection};
82+
Base = SectionedAddress{E.Value0, E.SectionIndex};
8183
return None;
8284
case dwarf::DW_LLE_start_length:
8385
return DWARFLocationExpression{
84-
DWARFAddressRange{E.Value0, E.Value0 + E.Value1,
85-
SectionedAddress::UndefSection},
86+
DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
8687
E.Loc};
8788
default:
8889
llvm_unreachable("unreachable locations list kind");
@@ -104,7 +105,8 @@ static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
104105
bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
105106
Optional<SectionedAddress> BaseAddr,
106107
const MCRegisterInfo *MRI,
107-
DWARFUnit *U, DIDumpOptions DumpOpts,
108+
const DWARFObject &Obj, DWARFUnit *U,
109+
DIDumpOptions DumpOpts,
108110
unsigned Indent) const {
109111
DWARFLocationInterpreter Interp(
110112
BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
@@ -116,7 +118,7 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
116118
Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
117119
Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
118120
if (!Loc || DumpOpts.DisplayRawContents)
119-
dumpRawEntry(E, OS, Indent);
121+
dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
120122
if (Loc && *Loc) {
121123
OS << "\n";
122124
OS.indent(Indent);
@@ -125,10 +127,7 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
125127

126128
DIDumpOptions RangeDumpOpts(DumpOpts);
127129
RangeDumpOpts.DisplayRawContents = false;
128-
const DWARFObject *Obj = nullptr;
129-
if (U)
130-
Obj = &U->getContext().getDWARFObj();
131-
Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, Obj);
130+
Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
132131
}
133132
if (!Loc)
134133
consumeError(Loc.takeError());
@@ -167,12 +166,12 @@ Error DWARFLocationTable::visitAbsoluteLocationList(
167166
}
168167

169168
void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
170-
DIDumpOptions DumpOpts,
169+
const DWARFObject &Obj, DIDumpOptions DumpOpts,
171170
Optional<uint64_t> DumpOffset) const {
172171
auto BaseAddr = None;
173172
unsigned Indent = 12;
174173
if (DumpOffset) {
175-
dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, nullptr, DumpOpts,
174+
dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
176175
Indent);
177176
} else {
178177
uint64_t Offset = 0;
@@ -182,7 +181,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
182181
OS << Separator;
183182
Separator = "\n";
184183

185-
CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, nullptr,
184+
CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
186185
DumpOpts, Indent);
187186
OS << '\n';
188187
}
@@ -194,8 +193,9 @@ Error DWARFDebugLoc::visitLocationList(
194193
function_ref<bool(const DWARFLocationEntry &)> Callback) const {
195194
DataExtractor::Cursor C(*Offset);
196195
while (true) {
196+
uint64_t SectionIndex;
197197
uint64_t Value0 = Data.getRelocatedAddress(C);
198-
uint64_t Value1 = Data.getRelocatedAddress(C);
198+
uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
199199

200200
DWARFLocationEntry E;
201201

@@ -208,10 +208,12 @@ Error DWARFDebugLoc::visitLocationList(
208208
} else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
209209
E.Kind = dwarf::DW_LLE_base_address;
210210
E.Value0 = Value1;
211+
E.SectionIndex = SectionIndex;
211212
} else {
212213
E.Kind = dwarf::DW_LLE_offset_pair;
213214
E.Value0 = Value0;
214215
E.Value1 = Value1;
216+
E.SectionIndex = SectionIndex;
215217
unsigned Bytes = Data.getU16(C);
216218
// A single location description describing the location of the object...
217219
Data.getU8(C, E.Loc, Bytes);
@@ -227,7 +229,9 @@ Error DWARFDebugLoc::visitLocationList(
227229
}
228230

229231
void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
230-
raw_ostream &OS, unsigned Indent) const {
232+
raw_ostream &OS, unsigned Indent,
233+
DIDumpOptions DumpOpts,
234+
const DWARFObject &Obj) const {
231235
uint64_t Value0, Value1;
232236
switch (Entry.Kind) {
233237
case dwarf::DW_LLE_base_address:
@@ -248,6 +252,7 @@ void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
248252
OS.indent(Indent);
249253
OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
250254
<< format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
255+
DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
251256
}
252257

253258
Error DWARFDebugLoclists::visitLocationList(
@@ -276,12 +281,13 @@ Error DWARFDebugLoclists::visitLocationList(
276281
case dwarf::DW_LLE_offset_pair:
277282
E.Value0 = Data.getULEB128(C);
278283
E.Value1 = Data.getULEB128(C);
284+
E.SectionIndex = SectionedAddress::UndefSection;
279285
break;
280286
case dwarf::DW_LLE_base_address:
281-
E.Value0 = Data.getRelocatedAddress(C);
287+
E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
282288
break;
283289
case dwarf::DW_LLE_start_length:
284-
E.Value0 = Data.getRelocatedAddress(C);
290+
E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
285291
E.Value1 = Data.getULEB128(C);
286292
break;
287293
case dwarf::DW_LLE_startx_endx:
@@ -310,7 +316,9 @@ Error DWARFDebugLoclists::visitLocationList(
310316
}
311317

312318
void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
313-
raw_ostream &OS, unsigned Indent) const {
319+
raw_ostream &OS, unsigned Indent,
320+
DIDumpOptions DumpOpts,
321+
const DWARFObject &Obj) const {
314322
size_t MaxEncodingStringLength = 0;
315323
#define HANDLE_DW_LLE(ID, NAME) \
316324
MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
@@ -339,10 +347,19 @@ void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
339347
break;
340348
}
341349
OS << ')';
350+
switch (Entry.Kind) {
351+
case dwarf::DW_LLE_start_length:
352+
case dwarf::DW_LLE_base_address:
353+
DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
354+
break;
355+
default:
356+
break;
357+
}
342358
}
343359

344360
void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
345361
raw_ostream &OS, const MCRegisterInfo *MRI,
362+
const DWARFObject &Obj,
346363
DIDumpOptions DumpOpts) {
347364
if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
348365
OS << "Invalid dump range\n";
@@ -355,8 +372,8 @@ void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
355372
OS << Separator;
356373
Separator = "\n";
357374

358-
CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, nullptr,
359-
DumpOpts, /*Indent=*/12);
375+
CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
376+
nullptr, DumpOpts, /*Indent=*/12);
360377
OS << '\n';
361378
}
362379
}

llvm/lib/DebugInfo/DWARF/DWARFDie.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
9696
return;
9797
}
9898
U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
99-
MRI, U, DumpOpts, Indent);
99+
MRI, Ctx.getDWARFObj(), U, DumpOpts,
100+
Indent);
100101
return;
101102
}
102103

llvm/test/DebugInfo/X86/dwarfdump-debug-loc-simple.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ Note: the input file was generated from Inputs/dwarfdump-test-loc-list-32bit.elf
44
CHECK: .debug_info
55
CHECK: DW_AT_name{{.*}}"f"
66
CHECK: DW_AT_location{{.*}}([[F_LOC:0x[0-9a-f]*]]
7-
CHECK-NEXT: [0x00000000, 0x00000023): DW_OP_reg1 ECX
8-
CHECK-NEXT: [0x00000023, 0x0000005d): DW_OP_breg5 EBP-16)
7+
CHECK-NEXT: [0x00000000, 0x00000023) ".text": DW_OP_reg1 ECX
8+
CHECK-NEXT: [0x00000023, 0x0000005d) ".text": DW_OP_breg5 EBP-16)
99
CHECK: DW_AT_name{{.*}}"g"
1010
CHECK: DW_AT_location{{.*}}([[G_LOC:0x[0-9a-f]*]]
11-
CHECK-NEXT: [0x00000000, 0x00000020): DW_OP_reg0 EAX
12-
CHECK-NEXT: [0x00000020, 0x0000005d): DW_OP_breg5 EBP-12)
11+
CHECK-NEXT: [0x00000000, 0x00000020) ".text": DW_OP_reg0 EAX
12+
CHECK-NEXT: [0x00000020, 0x0000005d) ".text": DW_OP_breg5 EBP-12)
1313

1414
CHECK: .debug_loc contents:
1515
CHECK-NEXT: [[F_LOC]]:
1616
this is actually the wrong location due to PR14763, but that doesn't matter for
1717
the purposes of testing dwarfdump
18-
CHECK-NEXT: (0x00000000, 0x00000023): DW_OP_reg1 ECX
19-
CHECK-NEXT: (0x00000023, 0x0000005d): DW_OP_breg5 EBP-16
18+
CHECK-NEXT: (0x00000000, 0x00000023) ".text": DW_OP_reg1 ECX
19+
CHECK-NEXT: (0x00000023, 0x0000005d) ".text": DW_OP_breg5 EBP-16
2020
CHECK: [[G_LOC]]:
21-
CHECK-NEXT: (0x00000000, 0x00000020): DW_OP_reg0 EAX
22-
CHECK-NEXT: (0x00000020, 0x0000005d): DW_OP_breg5 EBP-12
21+
CHECK-NEXT: (0x00000000, 0x00000020) ".text": DW_OP_reg0 EAX
22+
CHECK-NEXT: (0x00000020, 0x0000005d) ".text": DW_OP_breg5 EBP-12

0 commit comments

Comments
 (0)