Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit fe030f3

Browse files
author
Alexey Samsonov
committed
[DWARF parser] Refactor fetching DIE address ranges.
Add a helper method to get address ranges specified in a DIE (either by DW_AT_low_pc/DW_AT_high_pc, or by DW_AT_ranges). Use it to untangle and simplify the code. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206624 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 54850be commit fe030f3

7 files changed

+72
-64
lines changed

lib/DebugInfo/DWARFDebugAranges.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
5858
// manually build aranges for the rest of them.
5959
for (const auto &CU : CTX->compile_units()) {
6060
uint32_t CUOffset = CU->getOffset();
61-
if (ParsedCUOffsets.insert(CUOffset).second)
62-
CU->buildAddressRangeTable(this, true, CUOffset);
61+
if (ParsedCUOffsets.insert(CUOffset).second) {
62+
DWARFAddressRangesVector CURanges;
63+
CU->collectAddressRanges(CURanges);
64+
for (const auto &R : CURanges) {
65+
appendRange(CUOffset, R.first, R.second);
66+
}
67+
}
6368
}
6469

6570
sortAndMinimize();

lib/DebugInfo/DWARFDebugInfoEntry.cpp

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -226,39 +226,47 @@ bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
226226
return (HighPC != -1ULL);
227227
}
228228

229-
void DWARFDebugInfoEntryMinimal::buildAddressRangeTable(
230-
const DWARFUnit *U, DWARFDebugAranges *DebugAranges,
231-
uint32_t UOffsetInAranges) const {
232-
if (AbbrevDecl) {
233-
if (isSubprogramDIE()) {
234-
uint64_t LowPC, HighPC;
235-
if (getLowAndHighPC(U, LowPC, HighPC))
236-
DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC);
237-
// FIXME: try to append ranges from .debug_ranges section.
238-
}
239-
240-
const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
241-
while (Child) {
242-
Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges);
243-
Child = Child->getSibling();
244-
}
245-
}
246-
}
247-
248-
bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
249-
const DWARFUnit *U, const uint64_t Address) const {
229+
DWARFAddressRangesVector
230+
DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
250231
if (isNULL())
251-
return false;
232+
return DWARFAddressRangesVector{};
233+
// Single range specified by low/high PC.
252234
uint64_t LowPC, HighPC;
253-
if (getLowAndHighPC(U, LowPC, HighPC))
254-
return (LowPC <= Address && Address <= HighPC);
255-
// Try to get address ranges from .debug_ranges section.
235+
if (getLowAndHighPC(U, LowPC, HighPC)) {
236+
return DWARFAddressRangesVector{std::make_pair(LowPC, HighPC)};
237+
}
238+
// Multiple ranges from .debug_ranges section.
256239
uint32_t RangesOffset =
257240
getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
258241
if (RangesOffset != -1U) {
259242
DWARFDebugRangeList RangeList;
260243
if (U->extractRangeList(RangesOffset, RangeList))
261-
return RangeList.containsAddress(U->getBaseAddress(), Address);
244+
return RangeList.getAbsoluteRanges(U->getBaseAddress());
245+
}
246+
return DWARFAddressRangesVector{};
247+
}
248+
249+
void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
250+
const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
251+
if (isNULL())
252+
return;
253+
if (isSubprogramDIE()) {
254+
const auto &DIERanges = getAddressRanges(U);
255+
Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
256+
}
257+
258+
const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
259+
while (Child) {
260+
Child->collectChildrenAddressRanges(U, Ranges);
261+
Child = Child->getSibling();
262+
}
263+
}
264+
265+
bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
266+
const DWARFUnit *U, const uint64_t Address) const {
267+
for (const auto& R : getAddressRanges(U)) {
268+
if (R.first <= Address && Address < R.second)
269+
return true;
262270
}
263271
return false;
264272
}

lib/DebugInfo/DWARFDebugInfoEntry.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
1212

1313
#include "DWARFAbbreviationDeclaration.h"
14+
#include "DWARFDebugRangeList.h"
1415
#include "llvm/ADT/SmallVector.h"
1516
#include "llvm/Support/DataTypes.h"
1617

@@ -135,9 +136,10 @@ class DWARFDebugInfoEntryMinimal {
135136
bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
136137
uint64_t &HighPC) const;
137138

138-
void buildAddressRangeTable(const DWARFUnit *U,
139-
DWARFDebugAranges *DebugAranges,
140-
uint32_t CUOffsetInAranges) const;
139+
DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const;
140+
141+
void collectChildrenAddressRanges(const DWARFUnit *U,
142+
DWARFAddressRangesVector &Ranges) const;
141143

142144
bool addressRangeContainsAddress(const DWARFUnit *U,
143145
const uint64_t Address) const;

lib/DebugInfo/DWARFDebugRangeList.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,16 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
5454
OS << format("%08x <End of list>\n", Offset);
5555
}
5656

57-
bool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress,
58-
uint64_t Address) const {
57+
DWARFAddressRangesVector
58+
DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
59+
DWARFAddressRangesVector Res;
5960
for (const RangeListEntry &RLE : Entries) {
60-
if (RLE.isBaseAddressSelectionEntry(AddressSize))
61+
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
6162
BaseAddress = RLE.EndAddress;
62-
else if (RLE.containsAddress(BaseAddress, Address))
63-
return true;
63+
} else {
64+
Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress,
65+
BaseAddress + RLE.EndAddress));
66+
}
6467
}
65-
return false;
68+
return Res;
6669
}

lib/DebugInfo/DWARFDebugRangeList.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ namespace llvm {
1717

1818
class raw_ostream;
1919

20+
/// DWARFAddressRangesVector - represents a set of absolute address ranges.
21+
typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector;
22+
2023
class DWARFDebugRangeList {
2124
public:
2225
struct RangeListEntry {
@@ -50,10 +53,6 @@ class DWARFDebugRangeList {
5053
else
5154
return StartAddress == -1ULL;
5255
}
53-
bool containsAddress(uint64_t BaseAddress, uint64_t Address) const {
54-
return (BaseAddress + StartAddress <= Address) &&
55-
(Address < BaseAddress + EndAddress);
56-
}
5756
};
5857

5958
private:
@@ -67,10 +66,10 @@ class DWARFDebugRangeList {
6766
void clear();
6867
void dump(raw_ostream &OS) const;
6968
bool extract(DataExtractor data, uint32_t *offset_ptr);
70-
/// containsAddress - Returns true if range list contains the given
71-
/// address. Has to be passed base address of the compile unit that
72-
/// references this range list.
73-
bool containsAddress(uint64_t BaseAddress, uint64_t Address) const;
69+
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
70+
/// list. Has to be passed base address of the compile unit referencing this
71+
/// range list.
72+
DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
7473
};
7574

7675
} // namespace llvm

lib/DebugInfo/DWARFUnit.cpp

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -298,33 +298,26 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
298298
}
299299
}
300300

301-
void
302-
DWARFUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
303-
bool clear_dies_if_already_not_parsed,
304-
uint32_t CUOffsetInAranges) {
301+
void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
305302
// This function is usually called if there in no .debug_aranges section
306303
// in order to produce a compile unit level set of address ranges that
307304
// is accurate. If the DIEs weren't parsed, then we don't want all dies for
308305
// all compile units to stay loaded when they weren't needed. So we can end
309306
// up parsing the DWARF and then throwing them all away to keep memory usage
310307
// down.
311-
const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
312-
clear_dies_if_already_not_parsed;
313-
DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
308+
const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
309+
DieArray[0].collectChildrenAddressRanges(this, CURanges);
310+
311+
// Collect address ranges from DIEs in .dwo if necessary.
314312
bool DWOCreated = parseDWO();
315-
if (DWO.get()) {
316-
// If there is a .dwo file for this compile unit, then skeleton CU DIE
317-
// doesn't have children, and we should instead build address range table
318-
// from DIEs in the .debug_info.dwo section of .dwo file.
319-
DWO->getUnit()->buildAddressRangeTable(
320-
debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
321-
}
322-
if (DWOCreated && clear_dies_if_already_not_parsed)
313+
if (DWO.get())
314+
DWO->getUnit()->collectAddressRanges(CURanges);
315+
if (DWOCreated)
323316
DWO.reset();
324317

325318
// Keep memory down by clearing DIEs if this generate function
326319
// caused them to be parsed.
327-
if (clear_dies)
320+
if (ClearDIEs)
328321
clearDIEs(true);
329322
}
330323

lib/DebugInfo/DWARFUnit.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,7 @@ class DWARFUnit {
129129
const char *getCompilationDir();
130130
uint64_t getDWOId();
131131

132-
void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
133-
bool clear_dies_if_already_not_parsed,
134-
uint32_t CUOffsetInAranges);
132+
void collectAddressRanges(DWARFAddressRangesVector &CURanges);
135133

136134
/// getInlinedChainForAddress - fetches inlined chain for a given address.
137135
/// Returns empty chain if there is no subprogram containing address. The

0 commit comments

Comments
 (0)