1 //===- DWARFUnit.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 
10 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
14 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
15 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
16 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
17 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
20 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
21 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
22 #include "llvm/Support/DataExtractor.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/WithColor.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <cstddef>
28 #include <cstdint>
29 #include <cstdio>
30 #include <utility>
31 #include <vector>
32 
33 using namespace llvm;
34 using namespace dwarf;
35 
36 void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
37                                          const DWARFSection &Section,
38                                          DWARFSectionKind SectionKind) {
39   const DWARFObject &D = C.getDWARFObj();
40   addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
41                D.getStringSection(), D.getStringOffsetSection(),
42                &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(),
43                false, false, SectionKind);
44 }
45 
46 void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
47                                             const DWARFSection &DWOSection,
48                                             DWARFSectionKind SectionKind,
49                                             bool Lazy) {
50   const DWARFObject &D = C.getDWARFObj();
51   addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
52                D.getStringDWOSection(), D.getStringOffsetDWOSection(),
53                &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
54                true, Lazy, SectionKind);
55 }
56 
57 void DWARFUnitVector::addUnitsImpl(
58     DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
59     const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
60     const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS,
61     bool LE, bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) {
62   DWARFDataExtractor Data(Obj, Section, LE, 0);
63   // Lazy initialization of Parser, now that we have all section info.
64   if (!Parser) {
65     Parser = [=, &Context, &Obj, &Section, &SOS, &LS](
66                  uint32_t Offset, DWARFSectionKind SectionKind,
67                  const DWARFSection *CurSection) -> std::unique_ptr<DWARFUnit> {
68       const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
69       DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
70       if (!Data.isValidOffset(Offset))
71         return nullptr;
72       const DWARFUnitIndex *Index = nullptr;
73       if (IsDWO)
74         Index = &getDWARFUnitIndex(Context, SectionKind);
75       DWARFUnitHeader Header;
76       if (!Header.extract(Context, Data, &Offset, SectionKind, Index))
77         return nullptr;
78       std::unique_ptr<DWARFUnit> U;
79       if (Header.isTypeUnit())
80         U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
81                                              RS, SS, SOS, AOS, LS, LE, IsDWO,
82                                              *this);
83       else
84         U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
85                                                 DA, RS, SS, SOS, AOS, LS, LE,
86                                                 IsDWO, *this);
87       return U;
88     };
89   }
90   if (Lazy)
91     return;
92   // Find a reasonable insertion point within the vector.  We skip over
93   // (a) units from a different section, (b) units from the same section
94   // but with lower offset-within-section.  This keeps units in order
95   // within a section, although not necessarily within the object file,
96   // even if we do lazy parsing.
97   auto I = this->begin();
98   uint32_t Offset = 0;
99   while (Data.isValidOffset(Offset)) {
100     if (I != this->end() &&
101         (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
102       ++I;
103       continue;
104     }
105     auto U = Parser(Offset, SectionKind, &Section);
106     // If parsing failed, we're done with this section.
107     if (!U)
108       break;
109     Offset = U->getNextUnitOffset();
110     I = std::next(this->insert(I, std::move(U)));
111   }
112 }
113 
114 DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const {
115   auto *CU = std::upper_bound(
116     this->begin(), this->end(), Offset,
117     [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
118     return LHS < RHS->getNextUnitOffset();
119   });
120   if (CU != this->end() && (*CU)->getOffset() <= Offset)
121     return CU->get();
122   return nullptr;
123 }
124 
125 DWARFUnit *
126 DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
127   const auto *CUOff = E.getOffset(DW_SECT_INFO);
128   if (!CUOff)
129     return nullptr;
130 
131   auto Offset = CUOff->Offset;
132 
133   auto *CU = std::upper_bound(
134     this->begin(), this->end(), CUOff->Offset,
135     [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
136     return LHS < RHS->getNextUnitOffset();
137   });
138   if (CU != this->end() && (*CU)->getOffset() <= Offset)
139     return CU->get();
140 
141   if (!Parser)
142     return nullptr;
143 
144   auto U = Parser(Offset, DW_SECT_INFO, nullptr);
145   if (!U)
146     U = nullptr;
147 
148   auto *NewCU = U.get();
149   this->insert(CU, std::move(U));
150   return NewCU;
151 }
152 
153 DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
154                      const DWARFUnitHeader &Header,
155                      const DWARFDebugAbbrev *DA, const DWARFSection *RS,
156                      StringRef SS, const DWARFSection &SOS,
157                      const DWARFSection *AOS, const DWARFSection &LS, bool LE,
158                      bool IsDWO, const DWARFUnitVector &UnitVector)
159     : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
160       RangeSection(RS), LineSection(LS), StringSection(SS),
161       StringOffsetSection(SOS),  AddrOffsetSection(AOS), isLittleEndian(LE),
162       isDWO(IsDWO), UnitVector(UnitVector) {
163   clear();
164 }
165 
166 DWARFUnit::~DWARFUnit() = default;
167 
168 DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
169   return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
170                             getAddressByteSize());
171 }
172 
173 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
174                                                 uint64_t &Result) const {
175   uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
176   if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
177     return false;
178   DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
179                         isLittleEndian, getAddressByteSize());
180   Result = DA.getRelocatedAddress(&Offset);
181   return true;
182 }
183 
184 bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
185                                            uint64_t &Result) const {
186   if (!StringOffsetsTableContribution)
187     return false;
188   unsigned ItemSize = getDwarfStringOffsetsByteSize();
189   uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
190   if (StringOffsetSection.Data.size() < Offset + ItemSize)
191     return false;
192   DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
193                         isLittleEndian, 0);
194   Result = DA.getRelocatedValue(ItemSize, &Offset);
195   return true;
196 }
197 
198 bool DWARFUnitHeader::extract(DWARFContext &Context,
199                               const DWARFDataExtractor &debug_info,
200                               uint32_t *offset_ptr,
201                               DWARFSectionKind SectionKind,
202                               const DWARFUnitIndex *Index) {
203   Offset = *offset_ptr;
204   IndexEntry = Index ? Index->getFromOffset(*offset_ptr) : nullptr;
205   Length = debug_info.getU32(offset_ptr);
206   // FIXME: Support DWARF64.
207   unsigned SizeOfLength = 4;
208   FormParams.Format = DWARF32;
209   FormParams.Version = debug_info.getU16(offset_ptr);
210   if (FormParams.Version >= 5) {
211     UnitType = debug_info.getU8(offset_ptr);
212     FormParams.AddrSize = debug_info.getU8(offset_ptr);
213     AbbrOffset = debug_info.getU32(offset_ptr);
214   } else {
215     AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr);
216     FormParams.AddrSize = debug_info.getU8(offset_ptr);
217     // Fake a unit type based on the section type.  This isn't perfect,
218     // but distinguishing compile and type units is generally enough.
219     if (SectionKind == DW_SECT_TYPES)
220       UnitType = DW_UT_type;
221     else
222       UnitType = DW_UT_compile;
223   }
224   if (IndexEntry) {
225     if (AbbrOffset)
226       return false;
227     auto *UnitContrib = IndexEntry->getOffset();
228     if (!UnitContrib || UnitContrib->Length != (Length + 4))
229       return false;
230     auto *AbbrEntry = IndexEntry->getOffset(DW_SECT_ABBREV);
231     if (!AbbrEntry)
232       return false;
233     AbbrOffset = AbbrEntry->Offset;
234   }
235   if (isTypeUnit()) {
236     TypeHash = debug_info.getU64(offset_ptr);
237     TypeOffset = debug_info.getU32(offset_ptr);
238   } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
239     DWOId = debug_info.getU64(offset_ptr);
240 
241   // Header fields all parsed, capture the size of this unit header.
242   assert(*offset_ptr - Offset <= 255 && "unexpected header size");
243   Size = uint8_t(*offset_ptr - Offset);
244 
245   // Type offset is unit-relative; should be after the header and before
246   // the end of the current unit.
247   bool TypeOffsetOK =
248       !isTypeUnit()
249           ? true
250           : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
251   bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
252   bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
253   bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
254 
255   if (!LengthOK || !VersionOK || !AddrSizeOK || !TypeOffsetOK)
256     return false;
257 
258   // Keep track of the highest DWARF version we encounter across all units.
259   Context.setMaxVersionIfGreater(getVersion());
260   return true;
261 }
262 
263 // Parse the rangelist table header, including the optional array of offsets
264 // following it (DWARF v5 and later).
265 static Expected<DWARFDebugRnglistTable>
266 parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
267   // TODO: Support DWARF64
268   // We are expected to be called with Offset 0 or pointing just past the table
269   // header, which is 12 bytes long for DWARF32.
270   if (Offset > 0) {
271     if (Offset < 12U) {
272       std::string Buffer;
273       raw_string_ostream Stream(Buffer);
274       Stream << format(
275           "Did not detect a valid range list table with base = 0x%x", Offset);
276       return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
277     }
278     Offset -= 12U;
279   }
280   llvm::DWARFDebugRnglistTable Table;
281   if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
282     return std::move(E);
283   return Table;
284 }
285 
286 Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,
287                                   DWARFDebugRangeList &RangeList) const {
288   // Require that compile unit is extracted.
289   assert(!DieArray.empty());
290   DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
291                                 isLittleEndian, getAddressByteSize());
292   uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
293   return RangeList.extract(RangesData, &ActualRangeListOffset);
294 }
295 
296 void DWARFUnit::clear() {
297   Abbrevs = nullptr;
298   BaseAddr.reset();
299   RangeSectionBase = 0;
300   AddrOffsetSectionBase = 0;
301   clearDIEs(false);
302   DWO.reset();
303 }
304 
305 const char *DWARFUnit::getCompilationDir() {
306   return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
307 }
308 
309 void DWARFUnit::extractDIEsToVector(
310     bool AppendCUDie, bool AppendNonCUDies,
311     std::vector<DWARFDebugInfoEntry> &Dies) const {
312   if (!AppendCUDie && !AppendNonCUDies)
313     return;
314 
315   // Set the offset to that of the first DIE and calculate the start of the
316   // next compilation unit header.
317   uint32_t DIEOffset = getOffset() + getHeaderSize();
318   uint32_t NextCUOffset = getNextUnitOffset();
319   DWARFDebugInfoEntry DIE;
320   DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
321   uint32_t Depth = 0;
322   bool IsCUDie = true;
323 
324   while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
325                          Depth)) {
326     if (IsCUDie) {
327       if (AppendCUDie)
328         Dies.push_back(DIE);
329       if (!AppendNonCUDies)
330         break;
331       // The average bytes per DIE entry has been seen to be
332       // around 14-20 so let's pre-reserve the needed memory for
333       // our DIE entries accordingly.
334       Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
335       IsCUDie = false;
336     } else {
337       Dies.push_back(DIE);
338     }
339 
340     if (const DWARFAbbreviationDeclaration *AbbrDecl =
341             DIE.getAbbreviationDeclarationPtr()) {
342       // Normal DIE
343       if (AbbrDecl->hasChildren())
344         ++Depth;
345     } else {
346       // NULL DIE.
347       if (Depth > 0)
348         --Depth;
349       if (Depth == 0)
350         break;  // We are done with this compile unit!
351     }
352   }
353 
354   // Give a little bit of info if we encounter corrupt DWARF (our offset
355   // should always terminate at or before the start of the next compilation
356   // unit header).
357   if (DIEOffset > NextCUOffset)
358     WithColor::warning() << format("DWARF compile unit extends beyond its "
359                                    "bounds cu 0x%8.8x at 0x%8.8x\n",
360                                    getOffset(), DIEOffset);
361 }
362 
363 size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
364   if ((CUDieOnly && !DieArray.empty()) ||
365       DieArray.size() > 1)
366     return 0; // Already parsed.
367 
368   bool HasCUDie = !DieArray.empty();
369   extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
370 
371   if (DieArray.empty())
372     return 0;
373 
374   // If CU DIE was just parsed, copy several attribute values from it.
375   if (!HasCUDie) {
376     DWARFDie UnitDie = getUnitDIE();
377     if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
378       Header.setDWOId(*DWOId);
379     if (!isDWO) {
380       assert(AddrOffsetSectionBase == 0);
381       assert(RangeSectionBase == 0);
382       AddrOffsetSectionBase =
383           toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
384       RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
385     }
386 
387     // In general, in DWARF v5 and beyond we derive the start of the unit's
388     // contribution to the string offsets table from the unit DIE's
389     // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
390     // attribute, so we assume that there is a contribution to the string
391     // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
392     // In both cases we need to determine the format of the contribution,
393     // which may differ from the unit's format.
394     uint64_t StringOffsetsContributionBase =
395         isDWO ? 0 : toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
396     auto IndexEntry = Header.getIndexEntry();
397     if (IndexEntry)
398       if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
399         StringOffsetsContributionBase += C->Offset;
400 
401     DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
402                           isLittleEndian, 0);
403     if (isDWO)
404       StringOffsetsTableContribution =
405           determineStringOffsetsTableContributionDWO(
406               DA, StringOffsetsContributionBase);
407     else if (getVersion() >= 5)
408       StringOffsetsTableContribution = determineStringOffsetsTableContribution(
409           DA, StringOffsetsContributionBase);
410 
411     // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
412     // describe address ranges.
413     if (getVersion() >= 5) {
414       if (isDWO)
415         setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
416       else
417         setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
418                          toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
419       if (RangeSection->Data.size()) {
420         // Parse the range list table header. Individual range lists are
421         // extracted lazily.
422         DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
423                                     isLittleEndian, 0);
424         if (auto TableOrError =
425                 parseRngListTableHeader(RangesDA, RangeSectionBase))
426           RngListTable = TableOrError.get();
427         else
428           WithColor::error() << "parsing a range list table: "
429                              << toString(TableOrError.takeError())
430                              << '\n';
431 
432         // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
433         // Adjust RangeSectionBase to point past the table header.
434         if (isDWO && RngListTable)
435           RangeSectionBase = RngListTable->getHeaderSize();
436       }
437     }
438 
439     // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
440     // skeleton CU DIE, so that DWARF users not aware of it are not broken.
441   }
442 
443   return DieArray.size();
444 }
445 
446 bool DWARFUnit::parseDWO() {
447   if (isDWO)
448     return false;
449   if (DWO.get())
450     return false;
451   DWARFDie UnitDie = getUnitDIE();
452   if (!UnitDie)
453     return false;
454   auto DWOFileName = dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
455   if (!DWOFileName)
456     return false;
457   auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
458   SmallString<16> AbsolutePath;
459   if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
460       *CompilationDir) {
461     sys::path::append(AbsolutePath, *CompilationDir);
462   }
463   sys::path::append(AbsolutePath, *DWOFileName);
464   auto DWOId = getDWOId();
465   if (!DWOId)
466     return false;
467   auto DWOContext = Context.getDWOContext(AbsolutePath);
468   if (!DWOContext)
469     return false;
470 
471   DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
472   if (!DWOCU)
473     return false;
474   DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
475   // Share .debug_addr and .debug_ranges section with compile unit in .dwo
476   DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
477   if (getVersion() >= 5) {
478     DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
479     DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
480                                 isLittleEndian, 0);
481     if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))
482       DWO->RngListTable = TableOrError.get();
483     else
484       WithColor::error() << "parsing a range list table: "
485                          << toString(TableOrError.takeError())
486                          << '\n';
487     if (DWO->RngListTable)
488       DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
489   } else {
490     auto DWORangesBase = UnitDie.getRangesBaseAttribute();
491     DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
492   }
493 
494   return true;
495 }
496 
497 void DWARFUnit::clearDIEs(bool KeepCUDie) {
498   if (DieArray.size() > (unsigned)KeepCUDie) {
499     DieArray.resize((unsigned)KeepCUDie);
500     DieArray.shrink_to_fit();
501   }
502 }
503 
504 Expected<DWARFAddressRangesVector>
505 DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
506   if (getVersion() <= 4) {
507     DWARFDebugRangeList RangeList;
508     if (Error E = extractRangeList(Offset, RangeList))
509       return std::move(E);
510     return RangeList.getAbsoluteRanges(getBaseAddress());
511   }
512   if (RngListTable) {
513     DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
514                                   isLittleEndian, RngListTable->getAddrSize());
515     auto RangeListOrError = RngListTable->findList(RangesData, Offset);
516     if (RangeListOrError)
517       return RangeListOrError.get().getAbsoluteRanges(getBaseAddress());
518     return RangeListOrError.takeError();
519   }
520 
521   return make_error<StringError>("missing or invalid range list table",
522                                  inconvertibleErrorCode());
523 }
524 
525 Expected<DWARFAddressRangesVector>
526 DWARFUnit::findRnglistFromIndex(uint32_t Index) {
527   if (auto Offset = getRnglistOffset(Index))
528     return findRnglistFromOffset(*Offset + RangeSectionBase);
529 
530   std::string Buffer;
531   raw_string_ostream Stream(Buffer);
532   if (RngListTable)
533     Stream << format("invalid range list table index %d", Index);
534   else
535     Stream << "missing or invalid range list table";
536   return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
537 }
538 
539 void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
540   DWARFDie UnitDie = getUnitDIE();
541   if (!UnitDie)
542     return;
543   // First, check if unit DIE describes address ranges for the whole unit.
544   auto CUDIERangesOrError = UnitDie.getAddressRanges();
545   if (CUDIERangesOrError) {
546     if (!CUDIERangesOrError.get().empty()) {
547       CURanges.insert(CURanges.end(), CUDIERangesOrError.get().begin(),
548                       CUDIERangesOrError.get().end());
549       return;
550     }
551   } else
552     WithColor::error() << "decoding address ranges: "
553                        << toString(CUDIERangesOrError.takeError()) << '\n';
554 
555   // This function is usually called if there in no .debug_aranges section
556   // in order to produce a compile unit level set of address ranges that
557   // is accurate. If the DIEs weren't parsed, then we don't want all dies for
558   // all compile units to stay loaded when they weren't needed. So we can end
559   // up parsing the DWARF and then throwing them all away to keep memory usage
560   // down.
561   const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
562   getUnitDIE().collectChildrenAddressRanges(CURanges);
563 
564   // Collect address ranges from DIEs in .dwo if necessary.
565   bool DWOCreated = parseDWO();
566   if (DWO)
567     DWO->collectAddressRanges(CURanges);
568   if (DWOCreated)
569     DWO.reset();
570 
571   // Keep memory down by clearing DIEs if this generate function
572   // caused them to be parsed.
573   if (ClearDIEs)
574     clearDIEs(true);
575 }
576 
577 void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
578   if (Die.isSubroutineDIE()) {
579     auto DIERangesOrError = Die.getAddressRanges();
580     if (DIERangesOrError) {
581       for (const auto &R : DIERangesOrError.get()) {
582         // Ignore 0-sized ranges.
583         if (R.LowPC == R.HighPC)
584           continue;
585         auto B = AddrDieMap.upper_bound(R.LowPC);
586         if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
587           // The range is a sub-range of existing ranges, we need to split the
588           // existing range.
589           if (R.HighPC < B->second.first)
590             AddrDieMap[R.HighPC] = B->second;
591           if (R.LowPC > B->first)
592             AddrDieMap[B->first].first = R.LowPC;
593         }
594         AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
595       }
596     } else
597       llvm::consumeError(DIERangesOrError.takeError());
598   }
599   // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
600   // simplify the logic to update AddrDieMap. The child's range will always
601   // be equal or smaller than the parent's range. With this assumption, when
602   // adding one range into the map, it will at most split a range into 3
603   // sub-ranges.
604   for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
605     updateAddressDieMap(Child);
606 }
607 
608 DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
609   extractDIEsIfNeeded(false);
610   if (AddrDieMap.empty())
611     updateAddressDieMap(getUnitDIE());
612   auto R = AddrDieMap.upper_bound(Address);
613   if (R == AddrDieMap.begin())
614     return DWARFDie();
615   // upper_bound's previous item contains Address.
616   --R;
617   if (Address >= R->second.first)
618     return DWARFDie();
619   return R->second.second;
620 }
621 
622 void
623 DWARFUnit::getInlinedChainForAddress(uint64_t Address,
624                                      SmallVectorImpl<DWARFDie> &InlinedChain) {
625   assert(InlinedChain.empty());
626   // Try to look for subprogram DIEs in the DWO file.
627   parseDWO();
628   // First, find the subroutine that contains the given address (the leaf
629   // of inlined chain).
630   DWARFDie SubroutineDIE =
631       (DWO ? DWO.get() : this)->getSubroutineForAddress(Address);
632 
633   if (!SubroutineDIE)
634     return;
635 
636   while (!SubroutineDIE.isSubprogramDIE()) {
637     if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
638       InlinedChain.push_back(SubroutineDIE);
639     SubroutineDIE  = SubroutineDIE.getParent();
640   }
641   InlinedChain.push_back(SubroutineDIE);
642 }
643 
644 const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
645                                               DWARFSectionKind Kind) {
646   if (Kind == DW_SECT_INFO)
647     return Context.getCUIndex();
648   assert(Kind == DW_SECT_TYPES);
649   return Context.getTUIndex();
650 }
651 
652 DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
653   if (!Die)
654     return DWARFDie();
655   const uint32_t Depth = Die->getDepth();
656   // Unit DIEs always have a depth of zero and never have parents.
657   if (Depth == 0)
658     return DWARFDie();
659   // Depth of 1 always means parent is the compile/type unit.
660   if (Depth == 1)
661     return getUnitDIE();
662   // Look for previous DIE with a depth that is one less than the Die's depth.
663   const uint32_t ParentDepth = Depth - 1;
664   for (uint32_t I = getDIEIndex(Die) - 1; I > 0; --I) {
665     if (DieArray[I].getDepth() == ParentDepth)
666       return DWARFDie(this, &DieArray[I]);
667   }
668   return DWARFDie();
669 }
670 
671 DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
672   if (!Die)
673     return DWARFDie();
674   uint32_t Depth = Die->getDepth();
675   // Unit DIEs always have a depth of zero and never have siblings.
676   if (Depth == 0)
677     return DWARFDie();
678   // NULL DIEs don't have siblings.
679   if (Die->getAbbreviationDeclarationPtr() == nullptr)
680     return DWARFDie();
681 
682   // Find the next DIE whose depth is the same as the Die's depth.
683   for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
684        ++I) {
685     if (DieArray[I].getDepth() == Depth)
686       return DWARFDie(this, &DieArray[I]);
687   }
688   return DWARFDie();
689 }
690 
691 DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
692   if (!Die)
693     return DWARFDie();
694   uint32_t Depth = Die->getDepth();
695   // Unit DIEs always have a depth of zero and never have siblings.
696   if (Depth == 0)
697     return DWARFDie();
698 
699   // Find the previous DIE whose depth is the same as the Die's depth.
700   for (size_t I = getDIEIndex(Die); I > 0;) {
701     --I;
702     if (DieArray[I].getDepth() == Depth - 1)
703       return DWARFDie();
704     if (DieArray[I].getDepth() == Depth)
705       return DWARFDie(this, &DieArray[I]);
706   }
707   return DWARFDie();
708 }
709 
710 DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
711   if (!Die->hasChildren())
712     return DWARFDie();
713 
714   // We do not want access out of bounds when parsing corrupted debug data.
715   size_t I = getDIEIndex(Die) + 1;
716   if (I >= DieArray.size())
717     return DWARFDie();
718   return DWARFDie(this, &DieArray[I]);
719 }
720 
721 DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
722   if (!Die->hasChildren())
723     return DWARFDie();
724 
725   uint32_t Depth = Die->getDepth();
726   for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
727        ++I) {
728     if (DieArray[I].getDepth() == Depth + 1 &&
729         DieArray[I].getTag() == dwarf::DW_TAG_null)
730       return DWARFDie(this, &DieArray[I]);
731     assert(DieArray[I].getDepth() > Depth && "Not processing children?");
732   }
733   return DWARFDie();
734 }
735 
736 const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
737   if (!Abbrevs)
738     Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
739   return Abbrevs;
740 }
741 
742 llvm::Optional<BaseAddress> DWARFUnit::getBaseAddress() {
743   if (BaseAddr)
744     return BaseAddr;
745 
746   DWARFDie UnitDie = getUnitDIE();
747   Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
748   if (Optional<uint64_t> Addr = toAddress(PC))
749     BaseAddr = {*Addr, PC->getSectionIndex()};
750 
751   return BaseAddr;
752 }
753 
754 Optional<StrOffsetsContributionDescriptor>
755 StrOffsetsContributionDescriptor::validateContributionSize(
756     DWARFDataExtractor &DA) {
757   uint8_t EntrySize = getDwarfOffsetByteSize();
758   // In order to ensure that we don't read a partial record at the end of
759   // the section we validate for a multiple of the entry size.
760   uint64_t ValidationSize = alignTo(Size, EntrySize);
761   // Guard against overflow.
762   if (ValidationSize >= Size)
763     if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
764       return *this;
765   return Optional<StrOffsetsContributionDescriptor>();
766 }
767 
768 // Look for a DWARF64-formatted contribution to the string offsets table
769 // starting at a given offset and record it in a descriptor.
770 static Optional<StrOffsetsContributionDescriptor>
771 parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
772   if (!DA.isValidOffsetForDataOfSize(Offset, 16))
773     return Optional<StrOffsetsContributionDescriptor>();
774 
775   if (DA.getU32(&Offset) != 0xffffffff)
776     return Optional<StrOffsetsContributionDescriptor>();
777 
778   uint64_t Size = DA.getU64(&Offset);
779   uint8_t Version = DA.getU16(&Offset);
780   (void)DA.getU16(&Offset); // padding
781   // The encoded length includes the 2-byte version field and the 2-byte
782   // padding, so we need to subtract them out when we populate the descriptor.
783   return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
784   //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
785 }
786 
787 // Look for a DWARF32-formatted contribution to the string offsets table
788 // starting at a given offset and record it in a descriptor.
789 static Optional<StrOffsetsContributionDescriptor>
790 parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
791   if (!DA.isValidOffsetForDataOfSize(Offset, 8))
792     return Optional<StrOffsetsContributionDescriptor>();
793   uint32_t ContributionSize = DA.getU32(&Offset);
794   if (ContributionSize >= 0xfffffff0)
795     return Optional<StrOffsetsContributionDescriptor>();
796   uint8_t Version = DA.getU16(&Offset);
797   (void)DA.getU16(&Offset); // padding
798   // The encoded length includes the 2-byte version field and the 2-byte
799   // padding, so we need to subtract them out when we populate the descriptor.
800   return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version,
801                                           DWARF32);
802   //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
803 }
804 
805 Optional<StrOffsetsContributionDescriptor>
806 DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA,
807                                                    uint64_t Offset) {
808   Optional<StrOffsetsContributionDescriptor> Descriptor;
809   // Attempt to find a DWARF64 contribution 16 bytes before the base.
810   if (Offset >= 16)
811     Descriptor =
812         parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16);
813   // Try to find a DWARF32 contribution 8 bytes before the base.
814   if (!Descriptor && Offset >= 8)
815     Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8);
816   return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor;
817 }
818 
819 Optional<StrOffsetsContributionDescriptor>
820 DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA,
821                                                       uint64_t Offset) {
822   if (getVersion() >= 5) {
823     // Look for a valid contribution at the given offset.
824     auto Descriptor =
825         parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset);
826     if (!Descriptor)
827       Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset);
828     return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor;
829   }
830   // Prior to DWARF v5, we derive the contribution size from the
831   // index table (in a package file). In a .dwo file it is simply
832   // the length of the string offsets section.
833   uint64_t Size = 0;
834   auto IndexEntry = Header.getIndexEntry();
835   if (!IndexEntry)
836     Size = StringOffsetSection.Data.size();
837   else if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
838     Size = C->Length;
839   // Return a descriptor with the given offset as base, version 4 and
840   // DWARF32 format.
841   //return Optional<StrOffsetsContributionDescriptor>(
842       //StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32));
843   return StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32);
844 }
845