llvm.org GIT mirror llvm / cd7c498
Exract most of DWARFCompileUnit into a new DWARFUnit to prepare for the coming DWARFTypeUnit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191233 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 7 years ago
10 changed file(s) with 704 addition(s) and 675 deletion(s). Raw diff Collapse all Expand all
1313
1414 namespace llvm {
1515
16 class DWARFCompileUnit;
16 class DWARFUnit;
1717 class raw_ostream;
1818
1919 class DWARFFormValue {
4848 DWARFFormValue(uint16_t form = 0) : Form(form) {}
4949 uint16_t getForm() const { return Form; }
5050 const ValueType& value() const { return Value; }
51 void dump(raw_ostream &OS, const DWARFCompileUnit* cu) const;
51 void dump(raw_ostream &OS, const DWARFUnit *U) const;
5252 bool extractValue(DataExtractor data, uint32_t *offset_ptr,
53 const DWARFCompileUnit *cu);
53 const DWARFUnit *u);
5454 bool isInlinedCStr() const {
5555 return Value.data != NULL && Value.data == (const uint8_t*)Value.cstr;
5656 }
5757 const uint8_t *BlockData() const;
58 uint64_t getReference(const DWARFCompileUnit* cu) const;
58 uint64_t getReference(const DWARFUnit *U) const;
5959
6060 uint64_t getUnsigned() const { return Value.uval; }
6161 int64_t getSigned() const { return Value.sval; }
62 const char *getAsCString(const DWARFCompileUnit *CU) const;
63 uint64_t getAsAddress(const DWARFCompileUnit *CU) const;
62 const char *getAsCString(const DWARFUnit *U) const;
63 uint64_t getAsAddress(const DWARFUnit *U) const;
6464 bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
65 const DWARFCompileUnit *cu) const;
65 const DWARFUnit *u) const;
6666 static bool skipValue(uint16_t form, DataExtractor debug_info_data,
67 uint32_t *offset_ptr, const DWARFCompileUnit *cu);
67 uint32_t *offset_ptr, const DWARFUnit *u);
6868 static bool isBlockForm(uint16_t form);
6969 static bool isDataForm(uint16_t form);
7070 static const uint8_t *getFixedFormSizes(uint8_t AddrSize, uint16_t Version);
1111 DWARFDebugLoc.cpp
1212 DWARFDebugRangeList.cpp
1313 DWARFFormValue.cpp
14 DWARFUnit.cpp
1415 )
77 //===----------------------------------------------------------------------===//
88
99 #include "DWARFCompileUnit.h"
10 #include "DWARFContext.h"
11 #include "llvm/DebugInfo/DWARFFormValue.h"
12 #include "llvm/Support/Dwarf.h"
1310 #include "llvm/Support/Format.h"
14 #include "llvm/Support/Path.h"
1511 #include "llvm/Support/raw_ostream.h"
12
1613 using namespace llvm;
17 using namespace dwarf;
18
19 bool DWARFCompileUnit::getAddrOffsetSectionItem(uint32_t Index,
20 uint64_t &Result) const {
21 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
22 if (AddrOffsetSection.size() < Offset + AddrSize)
23 return false;
24 DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
25 Result = DA.getAddress(&Offset);
26 return true;
27 }
28
29 bool DWARFCompileUnit::getStringOffsetSectionItem(uint32_t Index,
30 uint32_t &Result) const {
31 // FIXME: string offset section entries are 8-byte for DWARF64.
32 const uint32_t ItemSize = 4;
33 uint32_t Offset = Index * ItemSize;
34 if (StringOffsetSection.size() < Offset + ItemSize)
35 return false;
36 DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
37 Result = DA.getU32(&Offset);
38 return true;
39 }
40
41 bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
42 clear();
43
44 Offset = *offset_ptr;
45
46 if (debug_info.isValidOffset(*offset_ptr)) {
47 uint64_t abbrOffset;
48 Length = debug_info.getU32(offset_ptr);
49 Version = debug_info.getU16(offset_ptr);
50 abbrOffset = debug_info.getU32(offset_ptr);
51 AddrSize = debug_info.getU8(offset_ptr);
52
53 bool lengthOK = debug_info.isValidOffset(getNextCompileUnitOffset()-1);
54 bool versionOK = DWARFContext::isSupportedVersion(Version);
55 bool abbrOffsetOK = AbbrevSection.size() > abbrOffset;
56 bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
57
58 if (lengthOK && versionOK && addrSizeOK && abbrOffsetOK && Abbrev != NULL) {
59 Abbrevs = Abbrev->getAbbreviationDeclarationSet(abbrOffset);
60 return true;
61 }
62
63 // reset the offset to where we tried to parse from if anything went wrong
64 *offset_ptr = Offset;
65 }
66
67 return false;
68 }
69
70 uint32_t
71 DWARFCompileUnit::extract(uint32_t offset, DataExtractor debug_info_data,
72 const DWARFAbbreviationDeclarationSet *abbrevs) {
73 clear();
74
75 Offset = offset;
76
77 if (debug_info_data.isValidOffset(offset)) {
78 Length = debug_info_data.getU32(&offset);
79 Version = debug_info_data.getU16(&offset);
80 bool abbrevsOK = debug_info_data.getU32(&offset) == abbrevs->getOffset();
81 Abbrevs = abbrevs;
82 AddrSize = debug_info_data.getU8(&offset);
83
84 bool versionOK = DWARFContext::isSupportedVersion(Version);
85 bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
86
87 if (versionOK && addrSizeOK && abbrevsOK &&
88 debug_info_data.isValidOffset(offset))
89 return offset;
90 }
91 return 0;
92 }
93
94 bool DWARFCompileUnit::extractRangeList(uint32_t RangeListOffset,
95 DWARFDebugRangeList &RangeList) const {
96 // Require that compile unit is extracted.
97 assert(DieArray.size() > 0);
98 DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
99 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
100 return RangeList.extract(RangesData, &ActualRangeListOffset);
101 }
102
103 void DWARFCompileUnit::clear() {
104 Offset = 0;
105 Length = 0;
106 Version = 0;
107 Abbrevs = 0;
108 AddrSize = 0;
109 BaseAddr = 0;
110 RangeSectionBase = 0;
111 AddrOffsetSectionBase = 0;
112 clearDIEs(false);
113 DWO.reset();
114 }
11514
11615 void DWARFCompileUnit::dump(raw_ostream &OS) {
117 OS << format("0x%08x", Offset) << ": Compile Unit:"
118 << " length = " << format("0x%08x", Length)
119 << " version = " << format("0x%04x", Version)
120 << " abbr_offset = " << format("0x%04x", Abbrevs->getOffset())
121 << " addr_size = " << format("0x%02x", AddrSize)
122 << " (next CU at " << format("0x%08x", getNextCompileUnitOffset())
16 OS << format("0x%08x", getOffset()) << ": Compile Unit:"
17 << " length = " << format("0x%08x", getLength())
18 << " version = " << format("0x%04x", getVersion())
19 << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
20 << " addr_size = " << format("0x%02x", getAddressByteSize())
21 << " (next unit at " << format("0x%08x", getNextUnitOffset())
12322 << ")\n";
12423
12524 const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
12726 CU->dump(OS, this, -1U);
12827 }
12928
130 const char *DWARFCompileUnit::getCompilationDir() {
131 extractDIEsIfNeeded(true);
132 if (DieArray.empty())
133 return 0;
134 return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
29 // VTable anchor.
30 DWARFCompileUnit::~DWARFCompileUnit() {
13531 }
136
137 uint64_t DWARFCompileUnit::getDWOId() {
138 extractDIEsIfNeeded(true);
139 const uint64_t FailValue = -1ULL;
140 if (DieArray.empty())
141 return FailValue;
142 return DieArray[0]
143 .getAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, FailValue);
144 }
145
146 void DWARFCompileUnit::setDIERelations() {
147 if (DieArray.empty())
148 return;
149 DWARFDebugInfoEntryMinimal *die_array_begin = &DieArray.front();
150 DWARFDebugInfoEntryMinimal *die_array_end = &DieArray.back();
151 DWARFDebugInfoEntryMinimal *curr_die;
152 // We purposely are skipping the last element in the array in the loop below
153 // so that we can always have a valid next item
154 for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) {
155 // Since our loop doesn't include the last element, we can always
156 // safely access the next die in the array.
157 DWARFDebugInfoEntryMinimal *next_die = curr_die + 1;
158
159 const DWARFAbbreviationDeclaration *curr_die_abbrev =
160 curr_die->getAbbreviationDeclarationPtr();
161
162 if (curr_die_abbrev) {
163 // Normal DIE
164 if (curr_die_abbrev->hasChildren())
165 next_die->setParent(curr_die);
166 else
167 curr_die->setSibling(next_die);
168 } else {
169 // NULL DIE that terminates a sibling chain
170 DWARFDebugInfoEntryMinimal *parent = curr_die->getParent();
171 if (parent)
172 parent->setSibling(next_die);
173 }
174 }
175
176 // Since we skipped the last element, we need to fix it up!
177 if (die_array_begin < die_array_end)
178 curr_die->setParent(die_array_begin);
179 }
180
181 void DWARFCompileUnit::extractDIEsToVector(
182 bool AppendCUDie, bool AppendNonCUDies,
183 std::vector &Dies) const {
184 if (!AppendCUDie && !AppendNonCUDies)
185 return;
186
187 // Set the offset to that of the first DIE and calculate the start of the
188 // next compilation unit header.
189 uint32_t Offset = getFirstDIEOffset();
190 uint32_t NextCUOffset = getNextCompileUnitOffset();
191 DWARFDebugInfoEntryMinimal DIE;
192 uint32_t Depth = 0;
193 const uint8_t *FixedFormSizes =
194 DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion());
195 bool IsCUDie = true;
196
197 while (Offset < NextCUOffset &&
198 DIE.extractFast(this, FixedFormSizes, &Offset)) {
199 if (IsCUDie) {
200 if (AppendCUDie)
201 Dies.push_back(DIE);
202 if (!AppendNonCUDies)
203 break;
204 // The average bytes per DIE entry has been seen to be
205 // around 14-20 so let's pre-reserve the needed memory for
206 // our DIE entries accordingly.
207 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
208 IsCUDie = false;
209 } else {
210 Dies.push_back(DIE);
211 }
212
213 const DWARFAbbreviationDeclaration *AbbrDecl =
214 DIE.getAbbreviationDeclarationPtr();
215 if (AbbrDecl) {
216 // Normal DIE
217 if (AbbrDecl->hasChildren())
218 ++Depth;
219 } else {
220 // NULL DIE.
221 if (Depth > 0)
222 --Depth;
223 if (Depth == 0)
224 break; // We are done with this compile unit!
225 }
226 }
227
228 // Give a little bit of info if we encounter corrupt DWARF (our offset
229 // should always terminate at or before the start of the next compilation
230 // unit header).
231 if (Offset > NextCUOffset)
232 fprintf(stderr, "warning: DWARF compile unit extends beyond its "
233 "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), Offset);
234 }
235
236 size_t DWARFCompileUnit::extractDIEsIfNeeded(bool CUDieOnly) {
237 if ((CUDieOnly && DieArray.size() > 0) ||
238 DieArray.size() > 1)
239 return 0; // Already parsed.
240
241 bool HasCUDie = DieArray.size() > 0;
242 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
243
244 if (DieArray.empty())
245 return 0;
246
247 // If CU DIE was just parsed, copy several attribute values from it.
248 if (!HasCUDie) {
249 uint64_t BaseAddr =
250 DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
251 if (BaseAddr == -1U)
252 BaseAddr = DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
253 setBaseAddress(BaseAddr);
254 AddrOffsetSectionBase =
255 DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_addr_base, 0);
256 RangeSectionBase =
257 DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_ranges_base, 0);
258 }
259
260 setDIERelations();
261 return DieArray.size();
262 }
263
264 DWARFCompileUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile)
265 : DWOFile(DWOFile),
266 DWOContext(cast(DIContext::getDWARFContext(DWOFile))),
267 DWOCU(0) {
268 if (DWOContext->getNumDWOCompileUnits() > 0)
269 DWOCU = DWOContext->getDWOCompileUnitAtIndex(0);
270 }
271
272 bool DWARFCompileUnit::parseDWO() {
273 if (DWO.get() != 0)
274 return false;
275 extractDIEsIfNeeded(true);
276 if (DieArray.empty())
277 return false;
278 const char *DWOFileName =
279 DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, 0);
280 if (DWOFileName == 0)
281 return false;
282 const char *CompilationDir =
283 DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
284 SmallString<16> AbsolutePath;
285 if (sys::path::is_relative(DWOFileName) && CompilationDir != 0) {
286 sys::path::append(AbsolutePath, CompilationDir);
287 }
288 sys::path::append(AbsolutePath, DWOFileName);
289 object::ObjectFile *DWOFile =
290 object::ObjectFile::createObjectFile(AbsolutePath);
291 if (!DWOFile)
292 return false;
293 // Reset DWOHolder.
294 DWO.reset(new DWOHolder(DWOFile));
295 DWARFCompileUnit *DWOCU = DWO->getCU();
296 // Verify that compile unit in .dwo file is valid.
297 if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) {
298 DWO.reset();
299 return false;
300 }
301 // Share .debug_addr and .debug_ranges section with compile unit in .dwo
302 DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
303 DWOCU->setRangesSection(RangeSection, RangeSectionBase);
304 return true;
305 }
306
307 void DWARFCompileUnit::clearDIEs(bool KeepCUDie) {
308 if (DieArray.size() > (unsigned)KeepCUDie) {
309 // std::vectors never get any smaller when resized to a smaller size,
310 // or when clear() or erase() are called, the size will report that it
311 // is smaller, but the memory allocated remains intact (call capacity()
312 // to see this). So we need to create a temporary vector and swap the
313 // contents which will cause just the internal pointers to be swapped
314 // so that when temporary vector goes out of scope, it will destroy the
315 // contents.
316 std::vector TmpArray;
317 DieArray.swap(TmpArray);
318 // Save at least the compile unit DIE
319 if (KeepCUDie)
320 DieArray.push_back(TmpArray.front());
321 }
322 }
323
324 void
325 DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
326 bool clear_dies_if_already_not_parsed,
327 uint32_t CUOffsetInAranges) {
328 // This function is usually called if there in no .debug_aranges section
329 // in order to produce a compile unit level set of address ranges that
330 // is accurate. If the DIEs weren't parsed, then we don't want all dies for
331 // all compile units to stay loaded when they weren't needed. So we can end
332 // up parsing the DWARF and then throwing them all away to keep memory usage
333 // down.
334 const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
335 clear_dies_if_already_not_parsed;
336 DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
337 bool DWOCreated = parseDWO();
338 if (DWO.get()) {
339 // If there is a .dwo file for this compile unit, then skeleton CU DIE
340 // doesn't have children, and we should instead build address range table
341 // from DIEs in the .debug_info.dwo section of .dwo file.
342 DWO->getCU()->buildAddressRangeTable(
343 debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
344 }
345 if (DWOCreated && clear_dies_if_already_not_parsed)
346 DWO.reset();
347
348 // Keep memory down by clearing DIEs if this generate function
349 // caused them to be parsed.
350 if (clear_dies)
351 clearDIEs(true);
352 }
353
354 const DWARFDebugInfoEntryMinimal *
355 DWARFCompileUnit::getSubprogramForAddress(uint64_t Address) {
356 extractDIEsIfNeeded(false);
357 for (size_t i = 0, n = DieArray.size(); i != n; i++)
358 if (DieArray[i].isSubprogramDIE() &&
359 DieArray[i].addressRangeContainsAddress(this, Address)) {
360 return &DieArray[i];
361 }
362 return 0;
363 }
364
365 DWARFDebugInfoEntryInlinedChain
366 DWARFCompileUnit::getInlinedChainForAddress(uint64_t Address) {
367 // First, find a subprogram that contains the given address (the root
368 // of inlined chain).
369 const DWARFCompileUnit *ChainCU = 0;
370 const DWARFDebugInfoEntryMinimal *SubprogramDIE =
371 getSubprogramForAddress(Address);
372 if (SubprogramDIE) {
373 ChainCU = this;
374 } else {
375 // Try to look for subprogram DIEs in the DWO file.
376 parseDWO();
377 if (DWO.get()) {
378 SubprogramDIE = DWO->getCU()->getSubprogramForAddress(Address);
379 if (SubprogramDIE)
380 ChainCU = DWO->getCU();
381 }
382 }
383
384 // Get inlined chain rooted at this subprogram DIE.
385 if (!SubprogramDIE)
386 return DWARFDebugInfoEntryInlinedChain();
387 return SubprogramDIE->getInlinedChainForAddress(ChainCU, Address);
388 }
99 #ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
1010 #define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
1111
12 #include "llvm/ADT/OwningPtr.h"
13 #include "DWARFDebugAbbrev.h"
14 #include "DWARFDebugInfoEntry.h"
15 #include "DWARFDebugRangeList.h"
16 #include "DWARFRelocMap.h"
17 #include
12 #include "DWARFUnit.h"
1813
1914 namespace llvm {
2015
21 namespace object {
22 class ObjectFile;
23 }
24
25 class DWARFDebugAbbrev;
26 class StringRef;
27 class raw_ostream;
28
29 class DWARFCompileUnit {
30 DWARFCompileUnit(DWARFCompileUnit const &) LLVM_DELETED_FUNCTION;
31 DWARFCompileUnit &operator=(DWARFCompileUnit const &) LLVM_DELETED_FUNCTION;
32
33 const DWARFDebugAbbrev *Abbrev;
34 StringRef InfoSection;
35 StringRef AbbrevSection;
36 StringRef RangeSection;
37 uint32_t RangeSectionBase;
38 StringRef StringSection;
39 StringRef StringOffsetSection;
40 StringRef AddrOffsetSection;
41 uint32_t AddrOffsetSectionBase;
42 const RelocAddrMap *RelocMap;
43 bool isLittleEndian;
44
45 uint32_t Offset;
46 uint32_t Length;
47 uint16_t Version;
48 const DWARFAbbreviationDeclarationSet *Abbrevs;
49 uint8_t AddrSize;
50 uint64_t BaseAddr;
51 // The compile unit debug information entry items.
52 std::vector DieArray;
53
54 class DWOHolder {
55 OwningPtr DWOFile;
56 OwningPtr DWOContext;
57 DWARFCompileUnit *DWOCU;
58 public:
59 DWOHolder(object::ObjectFile *DWOFile);
60 DWARFCompileUnit *getCU() const { return DWOCU; }
61 };
62 OwningPtr DWO;
63
16 class DWARFCompileUnit : public DWARFUnit {
6417 public:
65
6618 DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
6719 StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
68 const RelocAddrMap *M, bool LE) :
69 Abbrev(DA), InfoSection(IS), AbbrevSection(AS),
70 RangeSection(RS), StringSection(SS), StringOffsetSection(SOS),
71 AddrOffsetSection(AOS), RelocMap(M), isLittleEndian(LE) {
72 clear();
73 }
74
75 StringRef getStringSection() const { return StringSection; }
76 StringRef getStringOffsetSection() const { return StringOffsetSection; }
77 void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
78 AddrOffsetSection = AOS;
79 AddrOffsetSectionBase = Base;
80 }
81 void setRangesSection(StringRef RS, uint32_t Base) {
82 RangeSection = RS;
83 RangeSectionBase = Base;
84 }
85
86 bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
87 // FIXME: Result should be uint64_t in DWARF64.
88 bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
89
90 DataExtractor getDebugInfoExtractor() const {
91 return DataExtractor(InfoSection, isLittleEndian, AddrSize);
92 }
93 DataExtractor getStringExtractor() const {
94 return DataExtractor(StringSection, false, 0);
95 }
96
97 const RelocAddrMap *getRelocMap() const { return RelocMap; }
98
99 bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
100 uint32_t extract(uint32_t offset, DataExtractor debug_info_data,
101 const DWARFAbbreviationDeclarationSet *abbrevs);
102
103 /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
104 /// hasn't already been done. Returns the number of DIEs parsed at this call.
105 size_t extractDIEsIfNeeded(bool CUDieOnly);
106 /// extractRangeList - extracts the range list referenced by this compile
107 /// unit from .debug_ranges section. Returns true on success.
108 /// Requires that compile unit is already extracted.
109 bool extractRangeList(uint32_t RangeListOffset,
110 DWARFDebugRangeList &RangeList) const;
111 void clear();
20 const RelocAddrMap *M, bool LE)
21 : DWARFUnit(DA, IS, AS, RS, SS, SOS, AOS, M, LE) {}
11222 void dump(raw_ostream &OS);
113 uint32_t getOffset() const { return Offset; }
114 /// Size in bytes of the compile unit header.
115 uint32_t getSize() const { return 11; }
116 bool containsDIEOffset(uint32_t die_offset) const {
117 return die_offset >= getFirstDIEOffset() &&
118 die_offset < getNextCompileUnitOffset();
119 }
120 uint32_t getFirstDIEOffset() const { return Offset + getSize(); }
121 uint32_t getNextCompileUnitOffset() const { return Offset + Length + 4; }
122 /// Size in bytes of the .debug_info data associated with this compile unit.
123 size_t getDebugInfoSize() const { return Length + 4 - getSize(); }
124 uint32_t getLength() const { return Length; }
125 uint16_t getVersion() const { return Version; }
126 const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
127 return Abbrevs;
128 }
129 uint8_t getAddressByteSize() const { return AddrSize; }
130 uint64_t getBaseAddress() const { return BaseAddr; }
131
132 void setBaseAddress(uint64_t base_addr) {
133 BaseAddr = base_addr;
134 }
135
136 const DWARFDebugInfoEntryMinimal *
137 getCompileUnitDIE(bool extract_cu_die_only = true) {
138 extractDIEsIfNeeded(extract_cu_die_only);
139 return DieArray.empty() ? NULL : &DieArray[0];
140 }
141
142 const char *getCompilationDir();
143 uint64_t getDWOId();
144
145 /// setDIERelations - We read in all of the DIE entries into our flat list
146 /// of DIE entries and now we need to go back through all of them and set the
147 /// parent, sibling and child pointers for quick DIE navigation.
148 void setDIERelations();
149
150 void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
151 bool clear_dies_if_already_not_parsed,
152 uint32_t CUOffsetInAranges);
153
154 /// getInlinedChainForAddress - fetches inlined chain for a given address.
155 /// Returns empty chain if there is no subprogram containing address. The
156 /// chain is valid as long as parsed compile unit DIEs are not cleared.
157 DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
158
159 private:
160 /// extractDIEsToVector - Appends all parsed DIEs to a vector.
161 void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
162 std::vector &DIEs) const;
163 /// clearDIEs - Clear parsed DIEs to keep memory usage low.
164 void clearDIEs(bool KeepCUDie);
165
166 /// parseDWO - Parses .dwo file for current compile unit. Returns true if
167 /// it was actually constructed.
168 bool parseDWO();
169
170 /// getSubprogramForAddress - Returns subprogram DIE with address range
171 /// encompassing the provided address. The pointer is alive as long as parsed
172 /// compile unit DIEs are not cleared.
173 const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
23 // VTable anchor.
24 ~DWARFCompileUnit() LLVM_OVERRIDE;
17425 };
17526
17627 }
282282 break;
283283 }
284284 CUs.push_back(CU.take());
285 offset = CUs.back()->getNextCompileUnitOffset();
285 offset = CUs.back()->getNextUnitOffset();
286286 }
287287 }
288288
300300 break;
301301 }
302302 DWOCUs.push_back(DWOCU.take());
303 offset = DWOCUs.back()->getNextCompileUnitOffset();
303 offset = DWOCUs.back()->getNextUnitOffset();
304304 }
305305 }
306306
399399 CU->getInlinedChainForAddress(Address);
400400 if (InlinedChain.DIEs.size() > 0) {
401401 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
402 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.CU))
402 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
403403 FunctionName = Name;
404404 }
405405 }
432432 CU->getInlinedChainForAddress(Address);
433433 if (InlinedChain.DIEs.size() > 0) {
434434 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
435 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.CU))
435 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
436436 FunctionName = Name;
437437 }
438438 }
491491 uint32_t Column = 0;
492492 // Get function name if necessary.
493493 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
494 if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.CU))
494 if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
495495 FunctionName = Name;
496496 }
497497 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
515515 }
516516 // Get call file/line/column of a current DIE.
517517 if (i + 1 < n) {
518 FunctionDIE.getCallerFrame(InlinedChain.CU, CallFile, CallLine,
518 FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
519519 CallColumn);
520520 }
521521 }
1818 using namespace llvm;
1919 using namespace dwarf;
2020
21 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS,
22 const DWARFCompileUnit *cu,
21 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
2322 unsigned recurseDepth,
2423 unsigned indent) const {
25 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
24 DataExtractor debug_info_data = u->getDebugInfoExtractor();
2625 uint32_t offset = Offset;
2726
2827 if (debug_info_data.isValidOffset(offset)) {
4443 for (uint32_t i = 0; i != numAttributes; ++i) {
4544 uint16_t attr = AbbrevDecl->getAttrByIndex(i);
4645 uint16_t form = AbbrevDecl->getFormByIndex(i);
47 dumpAttribute(OS, cu, &offset, attr, form, indent);
46 dumpAttribute(OS, u, &offset, attr, form, indent);
4847 }
4948
5049 const DWARFDebugInfoEntryMinimal *child = getFirstChild();
5150 if (recurseDepth > 0 && child) {
5251 while (child) {
53 child->dump(OS, cu, recurseDepth-1, indent+2);
52 child->dump(OS, u, recurseDepth-1, indent+2);
5453 child = child->getSibling();
5554 }
5655 }
6564 }
6665
6766 void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
68 const DWARFCompileUnit *cu,
69 uint32_t* offset_ptr,
70 uint16_t attr,
71 uint16_t form,
67 const DWARFUnit *u,
68 uint32_t *offset_ptr,
69 uint16_t attr, uint16_t form,
7270 unsigned indent) const {
7371 OS << " ";
7472 OS.indent(indent+2);
8583
8684 DWARFFormValue formValue(form);
8785
88 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu))
86 if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u))
8987 return;
9088
9189 OS << "\t(";
92 formValue.dump(OS, cu);
90 formValue.dump(OS, u);
9391 OS << ")\n";
9492 }
9593
96 bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *CU,
94 bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
9795 const uint8_t *FixedFormSizes,
9896 uint32_t *OffsetPtr) {
9997 Offset = *OffsetPtr;
100 DataExtractor DebugInfoData = CU->getDebugInfoExtractor();
98 DataExtractor DebugInfoData = U->getDebugInfoExtractor();
10199 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
102100 if (0 == AbbrCode) {
103101 // NULL debug tag entry.
104102 AbbrevDecl = NULL;
105103 return true;
106104 }
107 AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
105 AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
108106 assert(AbbrevDecl);
109107 assert(FixedFormSizes); // For best performance this should be specified!
110108
120118 if (FixedFormSize)
121119 *OffsetPtr += FixedFormSize;
122120 else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
123 CU)) {
121 U)) {
124122 // Restore the original offset.
125123 *OffsetPtr = Offset;
126124 return false;
129127 return true;
130128 }
131129
132 bool
133 DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *CU,
134 uint32_t *OffsetPtr) {
135 DataExtractor DebugInfoData = CU->getDebugInfoExtractor();
136 const uint32_t CUEndOffset = CU->getNextCompileUnitOffset();
130 bool DWARFDebugInfoEntryMinimal::extract(const DWARFUnit *U,
131 uint32_t *OffsetPtr) {
132 DataExtractor DebugInfoData = U->getDebugInfoExtractor();
133 const uint32_t UEndOffset = U->getNextUnitOffset();
137134 Offset = *OffsetPtr;
138 if ((Offset >= CUEndOffset) || !DebugInfoData.isValidOffset(Offset))
135 if ((Offset >= UEndOffset) || !DebugInfoData.isValidOffset(Offset))
139136 return false;
140137 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
141138 if (0 == AbbrCode) {
143140 AbbrevDecl = NULL;
144141 return true;
145142 }
146 AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
143 AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
147144 if (0 == AbbrevDecl) {
148145 // Restore the original offset.
149146 *OffsetPtr = Offset;
151148 }
152149 bool IsCompileUnitTag = (AbbrevDecl->getTag() == DW_TAG_compile_unit);
153150 if (IsCompileUnitTag)
154 const_castCompileUnit*>(CU)->setBaseAddress(0);
151 const_castUnit *>(U)->setBaseAddress(0);
155152
156153 // Skip all data in the .debug_info for the attributes
157154 for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) {
161158 if (IsCompileUnitTag &&
162159 ((Attr == DW_AT_entry_pc) || (Attr == DW_AT_low_pc))) {
163160 DWARFFormValue FormValue(Form);
164 if (FormValue.extractValue(DebugInfoData, OffsetPtr, CU)) {
161 if (FormValue.extractValue(DebugInfoData, OffsetPtr, U)) {
165162 if (Attr == DW_AT_low_pc || Attr == DW_AT_entry_pc)
166 const_cast(CU)
167 ->setBaseAddress(FormValue.getUnsigned());
163 const_cast(U)->setBaseAddress(FormValue.getUnsigned());
168164 }
169 } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
170 CU)) {
165 } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) {
171166 // Restore the original offset.
172167 *OffsetPtr = Offset;
173168 return false;
186181 Tag == DW_TAG_inlined_subroutine;
187182 }
188183
189 uint32_t
190 DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu,
191 const uint16_t attr,
192 DWARFFormValue &form_value,
193 uint32_t *end_attr_offset_ptr)
194 const {
184 uint32_t DWARFDebugInfoEntryMinimal::getAttributeValue(
185 const DWARFUnit *u, const uint16_t attr, DWARFFormValue &form_value,
186 uint32_t *end_attr_offset_ptr) const {
195187 if (AbbrevDecl) {
196188 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr);
197189
198190 if (attr_idx != -1U) {
199191 uint32_t offset = getOffset();
200192
201 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
193 DataExtractor debug_info_data = u->getDebugInfoExtractor();
202194
203195 // Skip the abbreviation code so we are at the data for the attributes
204196 debug_info_data.getULEB128(&offset);
206198 uint32_t idx = 0;
207199 while (idx < attr_idx)
208200 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++),
209 debug_info_data, &offset, cu);
201 debug_info_data, &offset, u);
210202
211203 const uint32_t attr_offset = offset;
212204 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx));
213 if (form_value.extractValue(debug_info_data, &offset, cu)) {
205 if (form_value.extractValue(debug_info_data, &offset, u)) {
214206 if (end_attr_offset_ptr)
215207 *end_attr_offset_ptr = offset;
216208 return attr_offset;
222214 }
223215
224216 const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
225 const DWARFCompileUnit *CU, const uint16_t Attr,
226 const char *FailValue) const {
217 const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const {
227218 DWARFFormValue FormValue;
228 if (getAttributeValue(CU, Attr, FormValue))
229 return FormValue.getAsCString(CU);
219 if (getAttributeValue(U, Attr, FormValue))
220 return FormValue.getAsCString(U);
230221 return FailValue;
231222 }
232223
233224 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
234 const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
225 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
235226 DWARFFormValue FormValue;
236 if (getAttributeValue(CU, Attr, FormValue))
237 return FormValue.getAsAddress(CU);
227 if (getAttributeValue(U, Attr, FormValue))
228 return FormValue.getAsAddress(U);
238229 return FailValue;
239230 }
240231
241232 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
242 const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
233 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
243234 DWARFFormValue FormValue;
244 if (getAttributeValue(CU, Attr, FormValue)) {
235 if (getAttributeValue(U, Attr, FormValue))
245236 return FormValue.getUnsigned();
246 }
247237 return FailValue;
248238 }
249239
250 int64_t
251 DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
252 const DWARFCompileUnit* cu,
253 const uint16_t attr,
254 int64_t fail_value) const {
240 int64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
241 const DWARFUnit *u, const uint16_t attr, int64_t fail_value) const {
255242 DWARFFormValue form_value;
256 if (getAttributeValue(cu, attr, form_value))
243 if (getAttributeValue(u, attr, form_value))
257244 return form_value.getSigned();
258245 return fail_value;
259246 }
260247
261 uint64_t
262 DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
263 const DWARFCompileUnit* cu,
264 const uint16_t attr,
265 uint64_t fail_value)
266 const {
248 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
249 const DWARFUnit *u, const uint16_t attr, uint64_t fail_value) const {
267250 DWARFFormValue form_value;
268 if (getAttributeValue(cu, attr, form_value))
269 return form_value.getReference(cu);
251 if (getAttributeValue(u, attr, form_value))
252 return form_value.getReference(u);
270253 return fail_value;
271254 }
272255
273 bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU,
256 bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
274257 uint64_t &LowPC,
275258 uint64_t &HighPC) const {
276259 HighPC = -1ULL;
277 LowPC = getAttributeValueAsAddress(CU, DW_AT_low_pc, -1ULL);
260 LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL);
278261 if (LowPC != -1ULL)
279 HighPC = getAttributeValueAsAddress(CU, DW_AT_high_pc, -1ULL);
262 HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL);
280263 return (HighPC != -1ULL);
281264 }
282265
283 void
284 DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU,
285 DWARFDebugAranges *DebugAranges,
286 uint32_t CUOffsetInAranges)
287 const {
266 void DWARFDebugInfoEntryMinimal::buildAddressRangeTable(
267 const DWARFUnit *U, DWARFDebugAranges *DebugAranges,
268 uint32_t UOffsetInAranges) const {
288269 if (AbbrevDecl) {
289270 if (isSubprogramDIE()) {
290271 uint64_t LowPC, HighPC;
291 if (getLowAndHighPC(CU, LowPC, HighPC))
292 DebugAranges->appendRange(CUOffsetInAranges, LowPC, HighPC);
272 if (getLowAndHighPC(U, LowPC, HighPC))
273 DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC);
293274 // FIXME: try to append ranges from .debug_ranges section.
294275 }
295276
296277 const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
297278 while (Child) {
298 Child->buildAddressRangeTable(CU, DebugAranges, CUOffsetInAranges);
279 Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges);
299280 Child = Child->getSibling();
300281 }
301282 }
302283 }
303284
304 bool
305 DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
306 const DWARFCompileUnit *CU,
307 const uint64_t Address)
308 const {
285 bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
286 const DWARFUnit *U, const uint64_t Address) const {
309287 if (isNULL())
310288 return false;
311289 uint64_t LowPC, HighPC;
312 if (getLowAndHighPC(CU, LowPC, HighPC))
290 if (getLowAndHighPC(U, LowPC, HighPC))
313291 return (LowPC <= Address && Address <= HighPC);
314292 // Try to get address ranges from .debug_ranges section.
315 uint32_t RangesOffset = getAttributeValueAsReference(CU, DW_AT_ranges, -1U);
293 uint32_t RangesOffset = getAttributeValueAsReference(U, DW_AT_ranges, -1U);
316294 if (RangesOffset != -1U) {
317295 DWARFDebugRangeList RangeList;
318 if (CU->extractRangeList(RangesOffset, RangeList))
319 return RangeList.containsAddress(CU->getBaseAddress(), Address);
296 if (U->extractRangeList(RangesOffset, RangeList))
297 return RangeList.containsAddress(U->getBaseAddress(), Address);
320298 }
321299 return false;
322300 }
323301
324 const char*
325 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFCompileUnit *CU)
326 const {
302 const char *
303 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
327304 if (!isSubroutineDIE())
328305 return 0;
329306 // Try to get mangled name if possible.
330307 if (const char *name =
331 getAttributeValueAsString(CU, DW_AT_MIPS_linkage_name, 0))
308 getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, 0))
332309 return name;
333 if (const char *name = getAttributeValueAsString(CU, DW_AT_linkage_name, 0))
310 if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name, 0))
334311 return name;
335 if (const char *name = getAttributeValueAsString(CU, DW_AT_name, 0))
312 if (const char *name = getAttributeValueAsString(U, DW_AT_name, 0))
336313 return name;
337314 // Try to get name from specification DIE.
338315 uint32_t spec_ref =
339 getAttributeValueAsReference(CU, DW_AT_specification, -1U);
316 getAttributeValueAsReference(U, DW_AT_specification, -1U);
340317 if (spec_ref != -1U) {
341318 DWARFDebugInfoEntryMinimal spec_die;
342 if (spec_die.extract(CU, &spec_ref)) {
343 if (const char *name = spec_die.getSubroutineName(CU))
319 if (spec_die.extract(U, &spec_ref)) {
320 if (const char *name = spec_die.getSubroutineName(U))
344321 return name;
345322 }
346323 }
347324 // Try to get name from abstract origin DIE.
348325 uint32_t abs_origin_ref =
349 getAttributeValueAsReference(CU, DW_AT_abstract_origin, -1U);
326 getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
350327 if (abs_origin_ref != -1U) {
351328 DWARFDebugInfoEntryMinimal abs_origin_die;
352 if (abs_origin_die.extract(CU, &abs_origin_ref)) {
353 if (const char *name = abs_origin_die.getSubroutineName(CU))
329 if (abs_origin_die.extract(U, &abs_origin_ref)) {
330 if (const char *name = abs_origin_die.getSubroutineName(U))
354331 return name;
355332 }
356333 }
357334 return 0;
358335 }
359336
360 void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFCompileUnit *CU,
337 void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
361338 uint32_t &CallFile,
362339 uint32_t &CallLine,
363340 uint32_t &CallColumn) const {
364 CallFile = getAttributeValueAsUnsigned(CU, DW_AT_call_file, 0);
365 CallLine = getAttributeValueAsUnsigned(CU, DW_AT_call_line, 0);
366 CallColumn = getAttributeValueAsUnsigned(CU, DW_AT_call_column, 0);
341 CallFile = getAttributeValueAsUnsigned(U, DW_AT_call_file, 0);
342 CallLine = getAttributeValueAsUnsigned(U, DW_AT_call_line, 0);
343 CallColumn = getAttributeValueAsUnsigned(U, DW_AT_call_column, 0);
367344 }
368345
369346 DWARFDebugInfoEntryInlinedChain
370347 DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
371 const DWARFCompileUnit *CU, const uint64_t Address) const {
348 const DWARFUnit *U, const uint64_t Address) const {
372349 DWARFDebugInfoEntryInlinedChain InlinedChain;
373 InlinedChain.CU = CU;
350 InlinedChain.U = U;
374351 if (isNULL())
375352 return InlinedChain;
376353 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
382359 // Try to get child which also contains provided address.
383360 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
384361 while (Child) {
385 if (Child->addressRangeContainsAddress(CU, Address)) {
362 if (Child->addressRangeContainsAddress(U, Address)) {
386363 // Assume there is only one such child.
387364 break;
388365 }
1717
1818 class DWARFDebugAranges;
1919 class DWARFCompileUnit;
20 class DWARFUnit;
2021 class DWARFContext;
2122 class DWARFFormValue;
2223 struct DWARFDebugInfoEntryInlinedChain;
3839 DWARFDebugInfoEntryMinimal()
3940 : Offset(0), ParentIdx(0), SiblingIdx(0), AbbrevDecl(0) {}
4041
41 void dump(raw_ostream &OS, const DWARFCompileUnit *cu,
42 unsigned recurseDepth, unsigned indent = 0) const;
43 void dumpAttribute(raw_ostream &OS, const DWARFCompileUnit *cu,
44 uint32_t *offset_ptr, uint16_t attr, uint16_t form,
45 unsigned indent = 0) const;
42 void dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth,
43 unsigned indent = 0) const;
44 void dumpAttribute(raw_ostream &OS, const DWARFUnit *u, uint32_t *offset_ptr,
45 uint16_t attr, uint16_t form, unsigned indent = 0) const;
4646
4747 /// Extracts a debug info entry, which is a child of a given compile unit,
4848 /// starting at a given offset. If DIE can't be extracted, returns false and
4949 /// doesn't change OffsetPtr.
50 bool extractFast(const DWARFCompileUnit *CU, const uint8_t *FixedFormSizes,
50 bool extractFast(const DWARFUnit *U, const uint8_t *FixedFormSizes,
5151 uint32_t *OffsetPtr);
5252
5353 /// Extract a debug info entry for a given compile unit from the
5454 /// .debug_info and .debug_abbrev data starting at the given offset.
5555 /// If compile unit can't be parsed, returns false and doesn't change
5656 /// OffsetPtr.
57 bool extract(const DWARFCompileUnit *CU, uint32_t *OffsetPtr);
57 bool extract(const DWARFUnit *U, uint32_t *OffsetPtr);
5858
5959 uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; }
6060 bool isNULL() const { return AbbrevDecl == 0; }
119119 return AbbrevDecl;
120120 }
121121
122 uint32_t getAttributeValue(const DWARFCompileUnit *cu,
123 const uint16_t attr, DWARFFormValue &formValue,
122 uint32_t getAttributeValue(const DWARFUnit *u, const uint16_t attr,
123 DWARFFormValue &formValue,
124124 uint32_t *end_attr_offset_ptr = 0) const;
125125
126 const char* getAttributeValueAsString(const DWARFCompileUnit* cu,
127 const uint16_t attr,
126 const char *getAttributeValueAsString(const DWARFUnit *u, const uint16_t attr,
128127 const char *fail_value) const;
129128
130 uint64_t getAttributeValueAsAddress(const DWARFCompileUnit *CU,
131 const uint16_t Attr,
129 uint64_t getAttributeValueAsAddress(const DWARFUnit *U, const uint16_t Attr,
132130 uint64_t FailValue) const;
133131
134 uint64_t getAttributeValueAsUnsigned(const DWARFCompileUnit *cu,
135 const uint16_t attr,
132 uint64_t getAttributeValueAsUnsigned(const DWARFUnit *u, const uint16_t attr,
136133 uint64_t fail_value) const;
137134
138 uint64_t getAttributeValueAsReference(const DWARFCompileUnit *cu,
139 const uint16_t attr,
135 uint64_t getAttributeValueAsReference(const DWARFUnit *u, const uint16_t attr,
140136 uint64_t fail_value) const;
141137
142 int64_t getAttributeValueAsSigned(const DWARFCompileUnit* cu,
143 const uint16_t attr,
138 int64_t getAttributeValueAsSigned(const DWARFUnit *u, const uint16_t attr,
144139 int64_t fail_value) const;
145140
146141 /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
147142 /// Returns true if both attributes are present.
148 bool getLowAndHighPC(const DWARFCompileUnit *CU,
149 uint64_t &LowPC, uint64_t &HighPC) const;
143 bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
144 uint64_t &HighPC) const;
150145
151 void buildAddressRangeTable(const DWARFCompileUnit *CU,
146 void buildAddressRangeTable(const DWARFUnit *U,
152147 DWARFDebugAranges *DebugAranges,
153148 uint32_t CUOffsetInAranges) const;
154149
155 bool addressRangeContainsAddress(const DWARFCompileUnit *CU,
150 bool addressRangeContainsAddress(const DWARFUnit *U,
156151 const uint64_t Address) const;
157152
158153 /// If a DIE represents a subprogram (or inlined subroutine),
159154 /// returns its mangled name (or short name, if mangled is missing).
160155 /// This name may be fetched from specification or abstract origin
161156 /// for this subprogram. Returns null if no name is found.
162 const char* getSubroutineName(const DWARFCompileUnit *CU) const;
157 const char *getSubroutineName(const DWARFUnit *U) const;
163158
164159 /// Retrieves values of DW_AT_call_file, DW_AT_call_line and
165160 /// DW_AT_call_column from DIE (or zeroes if they are missing).
166 void getCallerFrame(const DWARFCompileUnit *CU, uint32_t &CallFile,
161 void getCallerFrame(const DWARFUnit *U, uint32_t &CallFile,
167162 uint32_t &CallLine, uint32_t &CallColumn) const;
168163
169164 /// Get inlined chain for a given address, rooted at the current DIE.
170165 /// Returns empty chain if address is not contained in address range
171166 /// of current DIE.
172167 DWARFDebugInfoEntryInlinedChain
173 getInlinedChainForAddress(const DWARFCompileUnit *CU,
174 const uint64_t Address) const;
168 getInlinedChainForAddress(const DWARFUnit *U, const uint64_t Address) const;
175169 };
176170
177171 /// DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine
180174 /// (except the last DIE) in this chain is contained in address
181175 /// range for next DIE in the chain.
182176 struct DWARFDebugInfoEntryInlinedChain {
183 DWARFDebugInfoEntryInlinedChain() : CU(0) {}
177 DWARFDebugInfoEntryInlinedChain() : U(0) {}
184178 SmallVector DIEs;
185 const DWARFCompileUnit *CU;
179 const DWARFUnit *U;
186180 };
187181
188182 }
7373 return 0;
7474 }
7575
76 bool
77 DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
78 const DWARFCompileUnit *cu) {
76 bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
77 const DWARFUnit *cu) {
7978 bool indirect = false;
8079 bool is_block = false;
8180 Value.data = NULL;
205204
206205 bool
207206 DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
208 const DWARFCompileUnit *cu) const {
207 const DWARFUnit *cu) const {
209208 return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
210209 }
211210
212211 bool
213212 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
214 uint32_t *offset_ptr, const DWARFCompileUnit *cu) {
213 uint32_t *offset_ptr, const DWARFUnit *cu) {
215214 bool indirect = false;
216215 do {
217216 switch (form) {
311310 }
312311
313312 void
314 DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
313 DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
315314 DataExtractor debug_str_data(cu->getStringSection(), true, 0);
316315 DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0);
317316 uint64_t uvalue = getUnsigned();
435434 OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
436435 }
437436
438 const char*
439 DWARFFormValue::getAsCString(const DWARFCompileUnit *CU) const {
437 const char *DWARFFormValue::getAsCString(const DWARFUnit *CU) const {
440438 if (isInlinedCStr())
441439 return Value.cstr;
442440 if (!CU)
451449 return CU->getStringExtractor().getCStr(&Offset);
452450 }
453451
454 uint64_t
455 DWARFFormValue::getAsAddress(const DWARFCompileUnit *CU) const {
452 uint64_t DWARFFormValue::getAsAddress(const DWARFUnit *CU) const {
456453 if (!CU)
457454 return 0;
458455 if (Value.IsDWOIndex) {
465462 return Value.uval;
466463 }
467464
468 uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
465 uint64_t DWARFFormValue::getReference(const DWARFUnit *cu) const {
469466 uint64_t die_offset = Value.uval;
470467 switch (Form) {
471468 case DW_FORM_ref1:
0 //===-- DWARFUnit.cpp -----------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "DWARFUnit.h"
10 #include "DWARFContext.h"
11 #include "llvm/DebugInfo/DWARFFormValue.h"
12 #include "llvm/Support/Dwarf.h"
13 #include "llvm/Support/Path.h"
14
15 using namespace llvm;
16 using namespace dwarf;
17
18 DWARFUnit::DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
19 StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
20 const RelocAddrMap *M, bool LE)
21 : Abbrev(DA), InfoSection(IS), AbbrevSection(AS), RangeSection(RS),
22 StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
23 RelocMap(M), isLittleEndian(LE) {
24 clear();
25 }
26
27 DWARFUnit::~DWARFUnit() {
28 }
29
30 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
31 uint64_t &Result) const {
32 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
33 if (AddrOffsetSection.size() < Offset + AddrSize)
34 return false;
35 DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
36 Result = DA.getAddress(&Offset);
37 return true;
38 }
39
40 bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
41 uint32_t &Result) const {
42 // FIXME: string offset section entries are 8-byte for DWARF64.
43 const uint32_t ItemSize = 4;
44 uint32_t Offset = Index * ItemSize;
45 if (StringOffsetSection.size() < Offset + ItemSize)
46 return false;
47 DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
48 Result = DA.getU32(&Offset);
49 return true;
50 }
51
52 bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
53 Length = debug_info.getU32(offset_ptr);
54 Version = debug_info.getU16(offset_ptr);
55 uint64_t abbrOffset = debug_info.getU32(offset_ptr);
56 AddrSize = debug_info.getU8(offset_ptr);
57
58 bool lengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
59 bool versionOK = DWARFContext::isSupportedVersion(Version);
60 bool abbrOffsetOK = AbbrevSection.size() > abbrOffset;
61 bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
62
63 if (!lengthOK || !versionOK || !addrSizeOK || !abbrOffsetOK)
64 return false;
65
66 Abbrevs = Abbrev->getAbbreviationDeclarationSet(abbrOffset);
67 return true;
68 }
69
70 bool DWARFUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
71 clear();
72
73 Offset = *offset_ptr;
74
75 if (debug_info.isValidOffset(*offset_ptr)) {
76 if (extractImpl(debug_info, offset_ptr))
77 return true;
78
79 // reset the offset to where we tried to parse from if anything went wrong
80 *offset_ptr = Offset;
81 }
82
83 return false;
84 }
85
86 uint32_t
87 DWARFUnit::extract(uint32_t offset, DataExtractor debug_info_data,
88 const DWARFAbbreviationDeclarationSet *abbrevs) {
89 clear();
90
91 Offset = offset;
92
93 if (debug_info_data.isValidOffset(offset)) {
94 Length = debug_info_data.getU32(&offset);
95 Version = debug_info_data.getU16(&offset);
96 bool abbrevsOK = debug_info_data.getU32(&offset) == abbrevs->getOffset();
97 Abbrevs = abbrevs;
98 AddrSize = debug_info_data.getU8(&offset);
99
100 bool versionOK = DWARFContext::isSupportedVersion(Version);
101 bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
102
103 if (versionOK && addrSizeOK && abbrevsOK &&
104 debug_info_data.isValidOffset(offset))
105 return offset;
106 }
107 return 0;
108 }
109
110 bool DWARFUnit::extractRangeList(uint32_t RangeListOffset,
111 DWARFDebugRangeList &RangeList) const {
112 // Require that compile unit is extracted.
113 assert(DieArray.size() > 0);
114 DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
115 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
116 return RangeList.extract(RangesData, &ActualRangeListOffset);
117 }
118
119 void DWARFUnit::clear() {
120 Offset = 0;
121 Length = 0;
122 Version = 0;
123 Abbrevs = 0;
124 AddrSize = 0;
125 BaseAddr = 0;
126 RangeSectionBase = 0;
127 AddrOffsetSectionBase = 0;
128 clearDIEs(false);
129 DWO.reset();
130 }
131
132 const char *DWARFUnit::getCompilationDir() {
133 extractDIEsIfNeeded(true);
134 if (DieArray.empty())
135 return 0;
136 return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
137 }
138
139 uint64_t DWARFUnit::getDWOId() {
140 extractDIEsIfNeeded(true);
141 const uint64_t FailValue = -1ULL;
142 if (DieArray.empty())
143 return FailValue;
144 return DieArray[0]
145 .getAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, FailValue);
146 }
147
148 void DWARFUnit::setDIERelations() {
149 if (DieArray.empty())
150 return;
151 DWARFDebugInfoEntryMinimal *die_array_begin = &DieArray.front();
152 DWARFDebugInfoEntryMinimal *die_array_end = &DieArray.back();
153 DWARFDebugInfoEntryMinimal *curr_die;
154 // We purposely are skipping the last element in the array in the loop below
155 // so that we can always have a valid next item
156 for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) {
157 // Since our loop doesn't include the last element, we can always
158 // safely access the next die in the array.
159 DWARFDebugInfoEntryMinimal *next_die = curr_die + 1;
160
161 const DWARFAbbreviationDeclaration *curr_die_abbrev =
162 curr_die->getAbbreviationDeclarationPtr();
163
164 if (curr_die_abbrev) {
165 // Normal DIE
166 if (curr_die_abbrev->hasChildren())
167 next_die->setParent(curr_die);
168 else
169 curr_die->setSibling(next_die);
170 } else {
171 // NULL DIE that terminates a sibling chain
172 DWARFDebugInfoEntryMinimal *parent = curr_die->getParent();
173 if (parent)
174 parent->setSibling(next_die);
175 }
176 }
177
178 // Since we skipped the last element, we need to fix it up!
179 if (die_array_begin < die_array_end)
180 curr_die->setParent(die_array_begin);
181 }
182
183 void DWARFUnit::extractDIEsToVector(
184 bool AppendCUDie, bool AppendNonCUDies,
185 std::vector &Dies) const {
186 if (!AppendCUDie && !AppendNonCUDies)
187 return;
188
189 // Set the offset to that of the first DIE and calculate the start of the
190 // next compilation unit header.
191 uint32_t Offset = getFirstDIEOffset();
192 uint32_t NextCUOffset = getNextUnitOffset();
193 DWARFDebugInfoEntryMinimal DIE;
194 uint32_t Depth = 0;
195 const uint8_t *FixedFormSizes =
196 DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion());
197 bool IsCUDie = true;
198
199 while (Offset < NextCUOffset &&
200 DIE.extractFast(this, FixedFormSizes, &Offset)) {
201 if (IsCUDie) {
202 if (AppendCUDie)
203 Dies.push_back(DIE);
204 if (!AppendNonCUDies)
205 break;
206 // The average bytes per DIE entry has been seen to be
207 // around 14-20 so let's pre-reserve the needed memory for
208 // our DIE entries accordingly.
209 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
210 IsCUDie = false;
211 } else {
212 Dies.push_back(DIE);
213 }
214
215 const DWARFAbbreviationDeclaration *AbbrDecl =
216 DIE.getAbbreviationDeclarationPtr();
217 if (AbbrDecl) {
218 // Normal DIE
219 if (AbbrDecl->hasChildren())
220 ++Depth;
221 } else {
222 // NULL DIE.
223 if (Depth > 0)
224 --Depth;
225 if (Depth == 0)
226 break; // We are done with this compile unit!
227 }
228 }
229
230 // Give a little bit of info if we encounter corrupt DWARF (our offset
231 // should always terminate at or before the start of the next compilation
232 // unit header).
233 if (Offset > NextCUOffset)
234 fprintf(stderr, "warning: DWARF compile unit extends beyond its "
235 "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), Offset);
236 }
237
238 size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
239 if ((CUDieOnly && DieArray.size() > 0) ||
240 DieArray.size() > 1)
241 return 0; // Already parsed.
242
243 bool HasCUDie = DieArray.size() > 0;
244 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
245
246 if (DieArray.empty())
247 return 0;
248
249 // If CU DIE was just parsed, copy several attribute values from it.
250 if (!HasCUDie) {
251 uint64_t BaseAddr =
252 DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
253 if (BaseAddr == -1U)
254 BaseAddr = DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
255 setBaseAddress(BaseAddr);
256 AddrOffsetSectionBase =
257 DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_addr_base, 0);
258 RangeSectionBase =
259 DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_ranges_base, 0);
260 }
261
262 setDIERelations();
263 return DieArray.size();
264 }
265
266 DWARFUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile)
267 : DWOFile(DWOFile),
268 DWOContext(cast(DIContext::getDWARFContext(DWOFile))),
269 DWOU(0) {
270 if (DWOContext->getNumDWOCompileUnits() > 0)
271 DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
272 }
273
274 bool DWARFUnit::parseDWO() {
275 if (DWO.get() != 0)
276 return false;
277 extractDIEsIfNeeded(true);
278 if (DieArray.empty())
279 return false;
280 const char *DWOFileName =
281 DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, 0);
282 if (DWOFileName == 0)
283 return false;
284 const char *CompilationDir =
285 DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
286 SmallString<16> AbsolutePath;
287 if (sys::path::is_relative(DWOFileName) && CompilationDir != 0) {
288 sys::path::append(AbsolutePath, CompilationDir);
289 }
290 sys::path::append(AbsolutePath, DWOFileName);
291 object::ObjectFile *DWOFile =
292 object::ObjectFile::createObjectFile(AbsolutePath);
293 if (!DWOFile)
294 return false;
295 // Reset DWOHolder.
296 DWO.reset(new DWOHolder(DWOFile));
297 DWARFUnit *DWOCU = DWO->getUnit();
298 // Verify that compile unit in .dwo file is valid.
299 if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) {
300 DWO.reset();
301 return false;
302 }
303 // Share .debug_addr and .debug_ranges section with compile unit in .dwo
304 DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
305 DWOCU->setRangesSection(RangeSection, RangeSectionBase);
306 return true;
307 }
308
309 void DWARFUnit::clearDIEs(bool KeepCUDie) {
310 if (DieArray.size() > (unsigned)KeepCUDie) {
311 // std::vectors never get any smaller when resized to a smaller size,
312 // or when clear() or erase() are called, the size will report that it
313 // is smaller, but the memory allocated remains intact (call capacity()
314 // to see this). So we need to create a temporary vector and swap the
315 // contents which will cause just the internal pointers to be swapped
316 // so that when temporary vector goes out of scope, it will destroy the
317 // contents.
318 std::vector TmpArray;
319 DieArray.swap(TmpArray);
320 // Save at least the compile unit DIE
321 if (KeepCUDie)
322 DieArray.push_back(TmpArray.front());
323 }
324 }
325
326 void
327 DWARFUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
328 bool clear_dies_if_already_not_parsed,
329 uint32_t CUOffsetInAranges) {
330 // This function is usually called if there in no .debug_aranges section
331 // in order to produce a compile unit level set of address ranges that
332 // is accurate. If the DIEs weren't parsed, then we don't want all dies for
333 // all compile units to stay loaded when they weren't needed. So we can end
334 // up parsing the DWARF and then throwing them all away to keep memory usage
335 // down.
336 const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
337 clear_dies_if_already_not_parsed;
338 DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
339 bool DWOCreated = parseDWO();
340 if (DWO.get()) {
341 // If there is a .dwo file for this compile unit, then skeleton CU DIE
342 // doesn't have children, and we should instead build address range table
343 // from DIEs in the .debug_info.dwo section of .dwo file.
344 DWO->getUnit()->buildAddressRangeTable(
345 debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
346 }
347 if (DWOCreated && clear_dies_if_already_not_parsed)
348 DWO.reset();
349
350 // Keep memory down by clearing DIEs if this generate function
351 // caused them to be parsed.
352 if (clear_dies)
353 clearDIEs(true);
354 }
355
356 const DWARFDebugInfoEntryMinimal *
357 DWARFUnit::getSubprogramForAddress(uint64_t Address) {
358 extractDIEsIfNeeded(false);
359 for (size_t i = 0, n = DieArray.size(); i != n; i++)
360 if (DieArray[i].isSubprogramDIE() &&
361 DieArray[i].addressRangeContainsAddress(this, Address)) {
362 return &DieArray[i];
363 }
364 return 0;
365 }
366
367 DWARFDebugInfoEntryInlinedChain
368 DWARFUnit::getInlinedChainForAddress(uint64_t Address) {
369 // First, find a subprogram that contains the given address (the root
370 // of inlined chain).
371 const DWARFUnit *ChainCU = 0;
372 const DWARFDebugInfoEntryMinimal *SubprogramDIE =
373 getSubprogramForAddress(Address);
374 if (SubprogramDIE) {
375 ChainCU = this;
376 } else {
377 // Try to look for subprogram DIEs in the DWO file.
378 parseDWO();
379 if (DWO.get()) {
380 SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
381 if (SubprogramDIE)
382 ChainCU = DWO->getUnit();
383 }
384 }
385
386 // Get inlined chain rooted at this subprogram DIE.
387 if (!SubprogramDIE)
388 return DWARFDebugInfoEntryInlinedChain();
389 return SubprogramDIE->getInlinedChainForAddress(ChainCU, Address);
390 }
0 //===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_DWARFUNIT_H
10 #define LLVM_DEBUGINFO_DWARFUNIT_H
11
12 #include "llvm/ADT/OwningPtr.h"
13 #include "DWARFDebugAbbrev.h"
14 #include "DWARFDebugInfoEntry.h"
15 #include "DWARFDebugRangeList.h"
16 #include "DWARFRelocMap.h"
17 #include
18
19 namespace llvm {
20
21 namespace object {
22 class ObjectFile;
23 }
24
25 class DWARFDebugAbbrev;
26 class StringRef;
27 class raw_ostream;
28
29 class DWARFUnit {
30 const DWARFDebugAbbrev *Abbrev;
31 StringRef InfoSection;
32 StringRef AbbrevSection;
33 StringRef RangeSection;
34 uint32_t RangeSectionBase;
35 StringRef StringSection;
36 StringRef StringOffsetSection;
37 StringRef AddrOffsetSection;
38 uint32_t AddrOffsetSectionBase;
39 const RelocAddrMap *RelocMap;
40 bool isLittleEndian;
41
42 uint32_t Offset;
43 uint32_t Length;
44 uint16_t Version;
45 const DWARFAbbreviationDeclarationSet *Abbrevs;
46 uint8_t AddrSize;
47 uint64_t BaseAddr;
48 // The compile unit debug information entry items.
49 std::vector DieArray;
50
51 class DWOHolder {
52 OwningPtr DWOFile;
53 OwningPtr DWOContext;
54 DWARFUnit *DWOU;
55 public:
56 DWOHolder(object::ObjectFile *DWOFile);
57 DWARFUnit *getUnit() const { return DWOU; }
58 };
59 OwningPtr DWO;
60
61 protected:
62 virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
63
64 public:
65
66 DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
67 StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
68 const RelocAddrMap *M, bool LE);
69
70 virtual ~DWARFUnit();
71
72 StringRef getStringSection() const { return StringSection; }
73 StringRef getStringOffsetSection() const { return StringOffsetSection; }
74 void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
75 AddrOffsetSection = AOS;
76 AddrOffsetSectionBase = Base;
77 }
78 void setRangesSection(StringRef RS, uint32_t Base) {
79 RangeSection = RS;
80 RangeSectionBase = Base;
81 }
82
83 bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
84 // FIXME: Result should be uint64_t in DWARF64.
85 bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
86
87 DataExtractor getDebugInfoExtractor() const {
88 return DataExtractor(InfoSection, isLittleEndian, AddrSize);
89 }
90 DataExtractor getStringExtractor() const {
91 return DataExtractor(StringSection, false, 0);
92 }
93
94 const RelocAddrMap *getRelocMap() const { return RelocMap; }
95
96 bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
97 uint32_t extract(uint32_t offset, DataExtractor debug_info_data,
98 const DWARFAbbreviationDeclarationSet *abbrevs);
99
100 /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
101 /// hasn't already been done. Returns the number of DIEs parsed at this call.
102 size_t extractDIEsIfNeeded(bool CUDieOnly);
103 /// extractRangeList - extracts the range list referenced by this compile
104 /// unit from .debug_ranges section. Returns true on success.
105 /// Requires that compile unit is already extracted.
106 bool extractRangeList(uint32_t RangeListOffset,
107 DWARFDebugRangeList &RangeList) const;
108 void clear();
109 uint32_t getOffset() const { return Offset; }
110 /// Size in bytes of the compile unit header.
111 virtual uint32_t getSize() const { return 11; }
112 bool containsDIEOffset(uint32_t die_offset) const {
113 return die_offset >= getFirstDIEOffset() &&
114 die_offset < getNextUnitOffset();
115 }
116 uint32_t getFirstDIEOffset() const { return Offset + getSize(); }
117 uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
118 /// Size in bytes of the .debug_info data associated with this compile unit.
119 size_t getDebugInfoSize() const { return Length + 4 - getSize(); }
120 uint32_t getLength() const { return Length; }
121 uint16_t getVersion() const { return Version; }
122 const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
123 return Abbrevs;
124 }
125 uint8_t getAddressByteSize() const { return AddrSize; }
126 uint64_t getBaseAddress() const { return BaseAddr; }
127
128 void setBaseAddress(uint64_t base_addr) {
129 BaseAddr = base_addr;
130 }
131
132 const DWARFDebugInfoEntryMinimal *
133 getCompileUnitDIE(bool extract_cu_die_only = true) {
134 extractDIEsIfNeeded(extract_cu_die_only);
135 return DieArray.empty() ? NULL : &DieArray[0];
136 }
137
138 const char *getCompilationDir();
139 uint64_t getDWOId();
140
141 /// setDIERelations - We read in all of the DIE entries into our flat list
142 /// of DIE entries and now we need to go back through all of them and set the
143 /// parent, sibling and child pointers for quick DIE navigation.
144 void setDIERelations();
145
146 void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
147 bool clear_dies_if_already_not_parsed,
148 uint32_t CUOffsetInAranges);
149
150 /// getInlinedChainForAddress - fetches inlined chain for a given address.
151 /// Returns empty chain if there is no subprogram containing address. The
152 /// chain is valid as long as parsed compile unit DIEs are not cleared.
153 DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
154
155 private:
156 /// extractDIEsToVector - Appends all parsed DIEs to a vector.
157 void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
158 std::vector &DIEs) const;
159 /// clearDIEs - Clear parsed DIEs to keep memory usage low.
160 void clearDIEs(bool KeepCUDie);
161
162 /// parseDWO - Parses .dwo file for current compile unit. Returns true if
163 /// it was actually constructed.
164 bool parseDWO();
165
166 /// getSubprogramForAddress - Returns subprogram DIE with address range
167 /// encompassing the provided address. The pointer is alive as long as parsed
168 /// compile unit DIEs are not cleared.
169 const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
170 };
171
172 }
173
174 #endif