[llvm] r206624 - [DWARF parser] Refactor fetching DIE address ranges.
Alexey Samsonov
samsonov at google.com
Fri Apr 18 10:25:47 PDT 2014
Author: samsonov
Date: Fri Apr 18 12:25:46 2014
New Revision: 206624
URL: http://llvm.org/viewvc/llvm-project?rev=206624&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp
llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h
llvm/trunk/lib/DebugInfo/DWARFUnit.cpp
llvm/trunk/lib/DebugInfo/DWARFUnit.h
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp Fri Apr 18 12:25:46 2014
@@ -58,8 +58,13 @@ void DWARFDebugAranges::generate(DWARFCo
// manually build aranges for the rest of them.
for (const auto &CU : CTX->compile_units()) {
uint32_t CUOffset = CU->getOffset();
- if (ParsedCUOffsets.insert(CUOffset).second)
- CU->buildAddressRangeTable(this, true, CUOffset);
+ if (ParsedCUOffsets.insert(CUOffset).second) {
+ DWARFAddressRangesVector CURanges;
+ CU->collectAddressRanges(CURanges);
+ for (const auto &R : CURanges) {
+ appendRange(CUOffset, R.first, R.second);
+ }
+ }
}
sortAndMinimize();
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp Fri Apr 18 12:25:46 2014
@@ -226,39 +226,47 @@ bool DWARFDebugInfoEntryMinimal::getLowA
return (HighPC != -1ULL);
}
-void DWARFDebugInfoEntryMinimal::buildAddressRangeTable(
- const DWARFUnit *U, DWARFDebugAranges *DebugAranges,
- uint32_t UOffsetInAranges) const {
- if (AbbrevDecl) {
- if (isSubprogramDIE()) {
- uint64_t LowPC, HighPC;
- if (getLowAndHighPC(U, LowPC, HighPC))
- DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC);
- // FIXME: try to append ranges from .debug_ranges section.
- }
-
- const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
- while (Child) {
- Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges);
- Child = Child->getSibling();
- }
- }
-}
-
-bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
- const DWARFUnit *U, const uint64_t Address) const {
+DWARFAddressRangesVector
+DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
if (isNULL())
- return false;
+ return DWARFAddressRangesVector{};
+ // Single range specified by low/high PC.
uint64_t LowPC, HighPC;
- if (getLowAndHighPC(U, LowPC, HighPC))
- return (LowPC <= Address && Address <= HighPC);
- // Try to get address ranges from .debug_ranges section.
+ if (getLowAndHighPC(U, LowPC, HighPC)) {
+ return DWARFAddressRangesVector{std::make_pair(LowPC, HighPC)};
+ }
+ // Multiple ranges from .debug_ranges section.
uint32_t RangesOffset =
getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
if (RangesOffset != -1U) {
DWARFDebugRangeList RangeList;
if (U->extractRangeList(RangesOffset, RangeList))
- return RangeList.containsAddress(U->getBaseAddress(), Address);
+ return RangeList.getAbsoluteRanges(U->getBaseAddress());
+ }
+ return DWARFAddressRangesVector{};
+}
+
+void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
+ const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
+ if (isNULL())
+ return;
+ if (isSubprogramDIE()) {
+ const auto &DIERanges = getAddressRanges(U);
+ Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
+ }
+
+ const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
+ while (Child) {
+ Child->collectChildrenAddressRanges(U, Ranges);
+ Child = Child->getSibling();
+ }
+}
+
+bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
+ const DWARFUnit *U, const uint64_t Address) const {
+ for (const auto& R : getAddressRanges(U)) {
+ if (R.first <= Address && Address < R.second)
+ return true;
}
return false;
}
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h Fri Apr 18 12:25:46 2014
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDebugRangeList.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
@@ -135,9 +136,10 @@ public:
bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
uint64_t &HighPC) const;
- void buildAddressRangeTable(const DWARFUnit *U,
- DWARFDebugAranges *DebugAranges,
- uint32_t CUOffsetInAranges) const;
+ DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const;
+
+ void collectChildrenAddressRanges(const DWARFUnit *U,
+ DWARFAddressRangesVector &Ranges) const;
bool addressRangeContainsAddress(const DWARFUnit *U,
const uint64_t Address) const;
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp Fri Apr 18 12:25:46 2014
@@ -54,13 +54,16 @@ void DWARFDebugRangeList::dump(raw_ostre
OS << format("%08x <End of list>\n", Offset);
}
-bool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress,
- uint64_t Address) const {
+DWARFAddressRangesVector
+DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
+ DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
- if (RLE.isBaseAddressSelectionEntry(AddressSize))
+ if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
BaseAddress = RLE.EndAddress;
- else if (RLE.containsAddress(BaseAddress, Address))
- return true;
+ } else {
+ Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress,
+ BaseAddress + RLE.EndAddress));
+ }
}
- return false;
+ return Res;
}
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h Fri Apr 18 12:25:46 2014
@@ -17,6 +17,9 @@ namespace llvm {
class raw_ostream;
+/// DWARFAddressRangesVector - represents a set of absolute address ranges.
+typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector;
+
class DWARFDebugRangeList {
public:
struct RangeListEntry {
@@ -50,10 +53,6 @@ public:
else
return StartAddress == -1ULL;
}
- bool containsAddress(uint64_t BaseAddress, uint64_t Address) const {
- return (BaseAddress + StartAddress <= Address) &&
- (Address < BaseAddress + EndAddress);
- }
};
private:
@@ -67,10 +66,10 @@ public:
void clear();
void dump(raw_ostream &OS) const;
bool extract(DataExtractor data, uint32_t *offset_ptr);
- /// containsAddress - Returns true if range list contains the given
- /// address. Has to be passed base address of the compile unit that
- /// references this range list.
- bool containsAddress(uint64_t BaseAddress, uint64_t Address) const;
+ /// getAbsoluteRanges - Returns absolute address ranges defined by this range
+ /// list. Has to be passed base address of the compile unit referencing this
+ /// range list.
+ DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
};
} // namespace llvm
Modified: llvm/trunk/lib/DebugInfo/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFUnit.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFUnit.cpp Fri Apr 18 12:25:46 2014
@@ -298,33 +298,26 @@ void DWARFUnit::clearDIEs(bool KeepCUDie
}
}
-void
-DWARFUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
- bool clear_dies_if_already_not_parsed,
- uint32_t CUOffsetInAranges) {
+void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
// This function is usually called if there in no .debug_aranges section
// in order to produce a compile unit level set of address ranges that
// is accurate. If the DIEs weren't parsed, then we don't want all dies for
// all compile units to stay loaded when they weren't needed. So we can end
// up parsing the DWARF and then throwing them all away to keep memory usage
// down.
- const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
- clear_dies_if_already_not_parsed;
- DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
+ const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
+ DieArray[0].collectChildrenAddressRanges(this, CURanges);
+
+ // Collect address ranges from DIEs in .dwo if necessary.
bool DWOCreated = parseDWO();
- if (DWO.get()) {
- // If there is a .dwo file for this compile unit, then skeleton CU DIE
- // doesn't have children, and we should instead build address range table
- // from DIEs in the .debug_info.dwo section of .dwo file.
- DWO->getUnit()->buildAddressRangeTable(
- debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
- }
- if (DWOCreated && clear_dies_if_already_not_parsed)
+ if (DWO.get())
+ DWO->getUnit()->collectAddressRanges(CURanges);
+ if (DWOCreated)
DWO.reset();
// Keep memory down by clearing DIEs if this generate function
// caused them to be parsed.
- if (clear_dies)
+ if (ClearDIEs)
clearDIEs(true);
}
Modified: llvm/trunk/lib/DebugInfo/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFUnit.h?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFUnit.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFUnit.h Fri Apr 18 12:25:46 2014
@@ -129,9 +129,7 @@ public:
const char *getCompilationDir();
uint64_t getDWOId();
- void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
- bool clear_dies_if_already_not_parsed,
- uint32_t CUOffsetInAranges);
+ void collectAddressRanges(DWARFAddressRangesVector &CURanges);
/// getInlinedChainForAddress - fetches inlined chain for a given address.
/// Returns empty chain if there is no subprogram containing address. The
More information about the llvm-commits
mailing list