LLVM  6.0.0svn
DWARFDebugAranges.cpp
Go to the documentation of this file.
1 //===- DWARFDebugAranges.cpp ----------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
15 #include <algorithm>
16 #include <cassert>
17 #include <cstdint>
18 #include <set>
19 #include <vector>
20 
21 using namespace llvm;
22 
23 void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
24  if (!DebugArangesData.isValidOffset(0))
25  return;
26  uint32_t Offset = 0;
28 
29  while (Set.extract(DebugArangesData, &Offset)) {
30  uint32_t CUOffset = Set.getCompileUnitDIEOffset();
31  for (const auto &Desc : Set.descriptors()) {
32  uint64_t LowPC = Desc.Address;
33  uint64_t HighPC = Desc.getEndAddress();
34  appendRange(CUOffset, LowPC, HighPC);
35  }
36  ParsedCUOffsets.insert(CUOffset);
37  }
38 }
39 
41  clear();
42  if (!CTX)
43  return;
44 
45  // Extract aranges from .debug_aranges section.
46  DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
47  CTX->isLittleEndian(), 0);
48  extract(ArangesData);
49 
50  // Generate aranges from DIEs: even if .debug_aranges section is present,
51  // it may describe only a small subset of compilation units, so we need to
52  // manually build aranges for the rest of them.
53  for (const auto &CU : CTX->compile_units()) {
54  uint32_t CUOffset = CU->getOffset();
55  if (ParsedCUOffsets.insert(CUOffset).second) {
56  DWARFAddressRangesVector CURanges;
57  CU->collectAddressRanges(CURanges);
58  for (const auto &R : CURanges)
59  appendRange(CUOffset, R.LowPC, R.HighPC);
60  }
61  }
62 
63  construct();
64 }
65 
66 void DWARFDebugAranges::clear() {
67  Endpoints.clear();
68  Aranges.clear();
69  ParsedCUOffsets.clear();
70 }
71 
72 void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
73  uint64_t HighPC) {
74  if (LowPC >= HighPC)
75  return;
76  Endpoints.emplace_back(LowPC, CUOffset, true);
77  Endpoints.emplace_back(HighPC, CUOffset, false);
78 }
79 
80 void DWARFDebugAranges::construct() {
81  std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing
82  // a current address range.
83  std::sort(Endpoints.begin(), Endpoints.end());
84  uint64_t PrevAddress = -1ULL;
85  for (const auto &E : Endpoints) {
86  if (PrevAddress < E.Address && !ValidCUs.empty()) {
87  // If the address range between two endpoints is described by some
88  // CU, first try to extend the last range in Aranges. If we can't
89  // do it, start a new range.
90  if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress &&
91  ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) {
92  Aranges.back().setHighPC(E.Address);
93  } else {
94  Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin());
95  }
96  }
97  // Update the set of valid CUs.
98  if (E.IsRangeStart) {
99  ValidCUs.insert(E.CUOffset);
100  } else {
101  auto CUPos = ValidCUs.find(E.CUOffset);
102  assert(CUPos != ValidCUs.end());
103  ValidCUs.erase(CUPos);
104  }
105  PrevAddress = E.Address;
106  }
107  assert(ValidCUs.empty());
108 
109  // Endpoints are not needed now.
110  Endpoints.clear();
111  Endpoints.shrink_to_fit();
112 }
113 
115  if (!Aranges.empty()) {
116  Range range(Address);
117  RangeCollIterator begin = Aranges.begin();
118  RangeCollIterator end = Aranges.end();
119  RangeCollIterator pos =
120  std::lower_bound(begin, end, range);
121 
122  if (pos != end && pos->containsAddress(Address)) {
123  return pos->CUOffset;
124  } else if (pos != begin) {
125  --pos;
126  if (pos->containsAddress(Address))
127  return pos->CUOffset;
128  }
129  }
130  return -1U;
131 }
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:244
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:235
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
desc_iterator_range descriptors() const
uint32_t findAddress(uint64_t Address) const
void generate(DWARFContext *CTX)
virtual StringRef getARangeSection() const
Definition: DWARFObject.h:40
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:187
bool extract(DataExtractor data, uint32_t *offset_ptr)
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:59
auto lower_bound(R &&Range, ForwardIt I) -> decltype(std::begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:859
cu_iterator_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:146
bool isLittleEndian() const
Definition: DWARFContext.h:279
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:123
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End, const Comparator &Comp=Comparator())
Definition: Parallel.h:199
uint32_t getCompileUnitDIEOffset() const