LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFUnit.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 365 385 94.8 %
Date: 2018-10-20 13:21:21 Functions: 38 38 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13