1 //===- DWARFUnit.h ----------------------------------------------*- C++ -*-===// 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 #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H 11 #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H 12 13 #include "llvm/ADT/Optional.h" 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/iterator_range.h" 18 #include "llvm/BinaryFormat/Dwarf.h" 19 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" 20 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 21 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" 22 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 23 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 24 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 25 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 26 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" 27 #include "llvm/Support/DataExtractor.h" 28 #include <algorithm> 29 #include <cassert> 30 #include <cstddef> 31 #include <cstdint> 32 #include <map> 33 #include <memory> 34 #include <utility> 35 #include <vector> 36 37 namespace llvm { 38 39 class DWARFAbbreviationDeclarationSet; 40 class DWARFContext; 41 class DWARFDebugAbbrev; 42 class DWARFUnit; 43 44 /// Base class describing the header of any kind of "unit." Some information 45 /// is specific to certain unit types. We separate this class out so we can 46 /// parse the header before deciding what specific kind of unit to construct. 47 class DWARFUnitHeader { 48 // Offset within section. 49 uint32_t Offset = 0; 50 // Version, address size, and DWARF format. 51 dwarf::FormParams FormParams; 52 uint32_t Length = 0; 53 uint64_t AbbrOffset = 0; 54 55 // For DWO units only. 56 const DWARFUnitIndex::Entry *IndexEntry = nullptr; 57 58 // For type units only. 59 uint64_t TypeHash = 0; 60 uint32_t TypeOffset = 0; 61 62 // For v5 split or skeleton compile units only. 63 Optional<uint64_t> DWOId; 64 65 // Unit type as parsed, or derived from the section kind. 66 uint8_t UnitType = 0; 67 68 // Size as parsed. uint8_t for compactness. 69 uint8_t Size = 0; 70 71 public: 72 /// Parse a unit header from \p debug_info starting at \p offset_ptr. 73 bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info, 74 uint32_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO, 75 const DWARFUnitIndex *Index = nullptr); getOffset()76 uint32_t getOffset() const { return Offset; } getFormParams()77 const dwarf::FormParams &getFormParams() const { return FormParams; } getVersion()78 uint16_t getVersion() const { return FormParams.Version; } getFormat()79 dwarf::DwarfFormat getFormat() const { return FormParams.Format; } getAddressByteSize()80 uint8_t getAddressByteSize() const { return FormParams.AddrSize; } getRefAddrByteSize()81 uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); } getDwarfOffsetByteSize()82 uint8_t getDwarfOffsetByteSize() const { 83 return FormParams.getDwarfOffsetByteSize(); 84 } getLength()85 uint32_t getLength() const { return Length; } getAbbrOffset()86 uint64_t getAbbrOffset() const { return AbbrOffset; } getDWOId()87 Optional<uint64_t> getDWOId() const { return DWOId; } setDWOId(uint64_t Id)88 void setDWOId(uint64_t Id) { 89 assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value"); 90 DWOId = Id; 91 } getIndexEntry()92 const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; } getTypeHash()93 uint64_t getTypeHash() const { return TypeHash; } getTypeOffset()94 uint32_t getTypeOffset() const { return TypeOffset; } getUnitType()95 uint8_t getUnitType() const { return UnitType; } isTypeUnit()96 bool isTypeUnit() const { 97 return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type; 98 } getSize()99 uint8_t getSize() const { return Size; } 100 // FIXME: Support DWARF64. getNextUnitOffset()101 uint32_t getNextUnitOffset() const { return Offset + Length + 4; } 102 }; 103 104 /// Base class for all DWARFUnitSection classes. This provides the 105 /// functionality common to all unit types. 106 class DWARFUnitSectionBase { 107 public: 108 /// Returns the Unit that contains the given section offset in the 109 /// same section this Unit originated from. 110 virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0; 111 virtual DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) = 0; 112 113 void parse(DWARFContext &C, const DWARFSection &Section); 114 void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, 115 bool Lazy = false); 116 117 protected: 118 ~DWARFUnitSectionBase() = default; 119 120 virtual void parseImpl(DWARFContext &Context, const DWARFObject &Obj, 121 const DWARFSection &Section, 122 const DWARFDebugAbbrev *DA, const DWARFSection *RS, 123 StringRef SS, const DWARFSection &SOS, 124 const DWARFSection *AOS, const DWARFSection &LS, 125 bool isLittleEndian, bool isDWO, bool Lazy) = 0; 126 }; 127 128 const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, 129 DWARFSectionKind Kind); 130 131 /// Concrete instance of DWARFUnitSection, specialized for one Unit type. 132 template<typename UnitType> 133 class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, 134 public DWARFUnitSectionBase { 135 bool Parsed = false; 136 std::function<std::unique_ptr<UnitType>(uint32_t)> Parser; 137 138 public: 139 using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>; 140 using iterator = typename UnitVector::iterator; 141 using iterator_range = llvm::iterator_range<typename UnitVector::iterator>; 142 getUnitForOffset(uint32_t Offset)143 UnitType *getUnitForOffset(uint32_t Offset) const override { 144 auto *CU = std::upper_bound( 145 this->begin(), this->end(), Offset, 146 [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) { 147 return LHS < RHS->getNextUnitOffset(); 148 }); 149 if (CU != this->end() && (*CU)->getOffset() <= Offset) 150 return CU->get(); 151 return nullptr; 152 } getUnitForIndexEntry(const DWARFUnitIndex::Entry & E)153 UnitType *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) override { 154 const auto *CUOff = E.getOffset(DW_SECT_INFO); 155 if (!CUOff) 156 return nullptr; 157 158 auto Offset = CUOff->Offset; 159 160 auto *CU = std::upper_bound( 161 this->begin(), this->end(), CUOff->Offset, 162 [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) { 163 return LHS < RHS->getNextUnitOffset(); 164 }); 165 if (CU != this->end() && (*CU)->getOffset() <= Offset) 166 return CU->get(); 167 168 if (!Parser) 169 return nullptr; 170 171 auto U = Parser(Offset); 172 if (!U) 173 U = nullptr; 174 175 auto *NewCU = U.get(); 176 this->insert(CU, std::move(U)); 177 return NewCU; 178 } 179 180 private: parseImpl(DWARFContext & Context,const DWARFObject & Obj,const DWARFSection & Section,const DWARFDebugAbbrev * DA,const DWARFSection * RS,StringRef SS,const DWARFSection & SOS,const DWARFSection * AOS,const DWARFSection & LS,bool LE,bool IsDWO,bool Lazy)181 void parseImpl(DWARFContext &Context, const DWARFObject &Obj, 182 const DWARFSection &Section, const DWARFDebugAbbrev *DA, 183 const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, 184 const DWARFSection *AOS, const DWARFSection &LS, bool LE, 185 bool IsDWO, bool Lazy) override { 186 if (Parsed) 187 return; 188 DWARFDataExtractor Data(Obj, Section, LE, 0); 189 if (!Parser) { 190 const DWARFUnitIndex *Index = nullptr; 191 if (IsDWO) 192 Index = &getDWARFUnitIndex(Context, UnitType::Section); 193 Parser = [=, &Context, &Section, &SOS, 194 &LS](uint32_t Offset) -> std::unique_ptr<UnitType> { 195 if (!Data.isValidOffset(Offset)) 196 return nullptr; 197 DWARFUnitHeader Header; 198 if (!Header.extract(Context, Data, &Offset, UnitType::Section, Index)) 199 return nullptr; 200 auto U = llvm::make_unique<UnitType>( 201 Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, 202 *this); 203 return U; 204 }; 205 } 206 if (Lazy) 207 return; 208 auto I = this->begin(); 209 uint32_t Offset = 0; 210 while (Data.isValidOffset(Offset)) { 211 if (I != this->end() && (*I)->getOffset() == Offset) { 212 ++I; 213 continue; 214 } 215 auto U = Parser(Offset); 216 if (!U) 217 break; 218 Offset = U->getNextUnitOffset(); 219 I = std::next(this->insert(I, std::move(U))); 220 } 221 Parsed = true; 222 } 223 }; 224 225 /// Represents base address of the CU. 226 struct BaseAddress { 227 uint64_t Address; 228 uint64_t SectionIndex; 229 }; 230 231 /// Represents a unit's contribution to the string offsets table. 232 struct StrOffsetsContributionDescriptor { 233 uint64_t Base = 0; 234 /// The contribution size not including the header. 235 uint64_t Size = 0; 236 /// Format and version. 237 dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32}; 238 StrOffsetsContributionDescriptorStrOffsetsContributionDescriptor239 StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size, 240 uint8_t Version, dwarf::DwarfFormat Format) 241 : Base(Base), Size(Size), FormParams({Version, 0, Format}) {} 242 getVersionStrOffsetsContributionDescriptor243 uint8_t getVersion() const { return FormParams.Version; } getFormatStrOffsetsContributionDescriptor244 dwarf::DwarfFormat getFormat() const { return FormParams.Format; } getDwarfOffsetByteSizeStrOffsetsContributionDescriptor245 uint8_t getDwarfOffsetByteSize() const { 246 return FormParams.getDwarfOffsetByteSize(); 247 } 248 /// Determine whether a contribution to the string offsets table is 249 /// consistent with the relevant section size and that its length is 250 /// a multiple of the size of one of its entries. 251 Optional<StrOffsetsContributionDescriptor> 252 validateContributionSize(DWARFDataExtractor &DA); 253 }; 254 255 class DWARFUnit { 256 DWARFContext &Context; 257 /// Section containing this DWARFUnit. 258 const DWARFSection &InfoSection; 259 260 DWARFUnitHeader Header; 261 const DWARFDebugAbbrev *Abbrev; 262 const DWARFSection *RangeSection; 263 uint32_t RangeSectionBase; 264 const DWARFSection &LineSection; 265 StringRef StringSection; 266 const DWARFSection &StringOffsetSection; 267 const DWARFSection *AddrOffsetSection; 268 uint32_t AddrOffsetSectionBase = 0; 269 bool isLittleEndian; 270 bool isDWO; 271 const DWARFUnitSectionBase &UnitSection; 272 273 /// Start, length, and DWARF format of the unit's contribution to the string 274 /// offsets table (DWARF v5). 275 Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution; 276 277 /// A table of range lists (DWARF v5 and later). 278 Optional<DWARFDebugRnglistTable> RngListTable; 279 280 mutable const DWARFAbbreviationDeclarationSet *Abbrevs; 281 llvm::Optional<BaseAddress> BaseAddr; 282 /// The compile unit debug information entry items. 283 std::vector<DWARFDebugInfoEntry> DieArray; 284 285 /// Map from range's start address to end address and corresponding DIE. 286 /// IntervalMap does not support range removal, as a result, we use the 287 /// std::map::upper_bound for address range lookup. 288 std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap; 289 290 using die_iterator_range = 291 iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>; 292 293 std::shared_ptr<DWARFUnit> DWO; 294 getDIEIndex(const DWARFDebugInfoEntry * Die)295 uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) { 296 auto First = DieArray.data(); 297 assert(Die >= First && Die < First + DieArray.size()); 298 return Die - First; 299 } 300 301 protected: getHeader()302 const DWARFUnitHeader &getHeader() const { return Header; } 303 304 /// Size in bytes of the parsed unit header. getHeaderSize()305 uint32_t getHeaderSize() const { return Header.getSize(); } 306 307 /// Find the unit's contribution to the string offsets table and determine its 308 /// length and form. The given offset is expected to be derived from the unit 309 /// DIE's DW_AT_str_offsets_base attribute. 310 Optional<StrOffsetsContributionDescriptor> 311 determineStringOffsetsTableContribution(DWARFDataExtractor &DA, 312 uint64_t Offset); 313 314 /// Find the unit's contribution to the string offsets table and determine its 315 /// length and form. The given offset is expected to be 0 in a dwo file or, 316 /// in a dwp file, the start of the unit's contribution to the string offsets 317 /// table section (as determined by the index table). 318 Optional<StrOffsetsContributionDescriptor> 319 determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA, 320 uint64_t Offset); 321 322 public: 323 DWARFUnit(DWARFContext &Context, const DWARFSection &Section, 324 const DWARFUnitHeader &Header, 325 const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, 326 const DWARFSection &SOS, const DWARFSection *AOS, 327 const DWARFSection &LS, bool LE, bool IsDWO, 328 const DWARFUnitSectionBase &UnitSection); 329 330 virtual ~DWARFUnit(); 331 getContext()332 DWARFContext& getContext() const { return Context; } getOffset()333 uint32_t getOffset() const { return Header.getOffset(); } getFormParams()334 const dwarf::FormParams &getFormParams() const { 335 return Header.getFormParams(); 336 } getVersion()337 uint16_t getVersion() const { return Header.getVersion(); } getAddressByteSize()338 uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); } getRefAddrByteSize()339 uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); } getDwarfOffsetByteSize()340 uint8_t getDwarfOffsetByteSize() const { 341 return Header.getDwarfOffsetByteSize(); 342 } getLength()343 uint32_t getLength() const { return Header.getLength(); } getUnitType()344 uint8_t getUnitType() const { return Header.getUnitType(); } getNextUnitOffset()345 uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); } getLineSection()346 const DWARFSection &getLineSection() const { return LineSection; } getStringSection()347 StringRef getStringSection() const { return StringSection; } getStringOffsetSection()348 const DWARFSection &getStringOffsetSection() const { 349 return StringOffsetSection; 350 } 351 setAddrOffsetSection(const DWARFSection * AOS,uint32_t Base)352 void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) { 353 AddrOffsetSection = AOS; 354 AddrOffsetSectionBase = Base; 355 } 356 357 /// Recursively update address to Die map. 358 void updateAddressDieMap(DWARFDie Die); 359 setRangesSection(const DWARFSection * RS,uint32_t Base)360 void setRangesSection(const DWARFSection *RS, uint32_t Base) { 361 RangeSection = RS; 362 RangeSectionBase = Base; 363 } 364 365 bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const; 366 bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const; 367 368 DWARFDataExtractor getDebugInfoExtractor() const; 369 getStringExtractor()370 DataExtractor getStringExtractor() const { 371 return DataExtractor(StringSection, false, 0); 372 } 373 374 /// Extract the range list referenced by this compile unit from the 375 /// .debug_ranges section. If the extraction is unsuccessful, an error 376 /// is returned. Successful extraction requires that the compile unit 377 /// has already been extracted. 378 Error extractRangeList(uint32_t RangeListOffset, 379 DWARFDebugRangeList &RangeList) const; 380 void clear(); 381 382 const Optional<StrOffsetsContributionDescriptor> & getStringOffsetsTableContribution()383 getStringOffsetsTableContribution() const { 384 return StringOffsetsTableContribution; 385 } 386 getDwarfStringOffsetsByteSize()387 uint8_t getDwarfStringOffsetsByteSize() const { 388 assert(StringOffsetsTableContribution); 389 return StringOffsetsTableContribution->getDwarfOffsetByteSize(); 390 } 391 getStringOffsetsBase()392 uint64_t getStringOffsetsBase() const { 393 assert(StringOffsetsTableContribution); 394 return StringOffsetsTableContribution->Base; 395 } 396 397 const DWARFAbbreviationDeclarationSet *getAbbreviations() const; 398 isMatchingUnitTypeAndTag(uint8_t UnitType,dwarf::Tag Tag)399 static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) { 400 switch (UnitType) { 401 case dwarf::DW_UT_compile: 402 return Tag == dwarf::DW_TAG_compile_unit; 403 case dwarf::DW_UT_type: 404 return Tag == dwarf::DW_TAG_type_unit; 405 case dwarf::DW_UT_partial: 406 return Tag == dwarf::DW_TAG_partial_unit; 407 case dwarf::DW_UT_skeleton: 408 return Tag == dwarf::DW_TAG_skeleton_unit; 409 case dwarf::DW_UT_split_compile: 410 case dwarf::DW_UT_split_type: 411 return dwarf::isUnitType(Tag); 412 } 413 return false; 414 } 415 416 /// Return the number of bytes for the header of a unit of 417 /// UnitType type. 418 /// 419 /// This function must be called with a valid unit type which in 420 /// DWARF5 is defined as one of the following six types. getDWARF5HeaderSize(uint8_t UnitType)421 static uint32_t getDWARF5HeaderSize(uint8_t UnitType) { 422 switch (UnitType) { 423 case dwarf::DW_UT_compile: 424 case dwarf::DW_UT_partial: 425 return 12; 426 case dwarf::DW_UT_skeleton: 427 case dwarf::DW_UT_split_compile: 428 return 20; 429 case dwarf::DW_UT_type: 430 case dwarf::DW_UT_split_type: 431 return 24; 432 } 433 llvm_unreachable("Invalid UnitType."); 434 } 435 436 llvm::Optional<BaseAddress> getBaseAddress(); 437 438 DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { 439 extractDIEsIfNeeded(ExtractUnitDIEOnly); 440 if (DieArray.empty()) 441 return DWARFDie(); 442 return DWARFDie(this, &DieArray[0]); 443 } 444 445 const char *getCompilationDir(); getDWOId()446 Optional<uint64_t> getDWOId() { 447 extractDIEsIfNeeded(/*CUDieOnly*/ true); 448 return getHeader().getDWOId(); 449 } setDWOId(uint64_t NewID)450 void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); } 451 452 /// Return a vector of address ranges resulting from a (possibly encoded) 453 /// range list starting at a given offset in the appropriate ranges section. 454 Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint32_t Offset); 455 456 /// Return a vector of address ranges retrieved from an encoded range 457 /// list whose offset is found via a table lookup given an index (DWARF v5 458 /// and later). 459 Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index); 460 461 /// Return a rangelist's offset based on an index. The index designates 462 /// an entry in the rangelist table's offset array and is supplied by 463 /// DW_FORM_rnglistx. getRnglistOffset(uint32_t Index)464 Optional<uint32_t> getRnglistOffset(uint32_t Index) { 465 if (RngListTable) 466 return RngListTable->getOffsetEntry(Index); 467 return None; 468 } 469 470 void collectAddressRanges(DWARFAddressRangesVector &CURanges); 471 472 /// Returns subprogram DIE with address range encompassing the provided 473 /// address. The pointer is alive as long as parsed compile unit DIEs are not 474 /// cleared. 475 DWARFDie getSubroutineForAddress(uint64_t Address); 476 477 /// getInlinedChainForAddress - fetches inlined chain for a given address. 478 /// Returns empty chain if there is no subprogram containing address. The 479 /// chain is valid as long as parsed compile unit DIEs are not cleared. 480 void getInlinedChainForAddress(uint64_t Address, 481 SmallVectorImpl<DWARFDie> &InlinedChain); 482 483 /// getUnitSection - Return the DWARFUnitSection containing this unit. getUnitSection()484 const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; } 485 486 /// Returns the number of DIEs in the unit. Parses the unit 487 /// if necessary. getNumDIEs()488 unsigned getNumDIEs() { 489 extractDIEsIfNeeded(false); 490 return DieArray.size(); 491 } 492 493 /// Return the index of a DIE inside the unit's DIE vector. 494 /// 495 /// It is illegal to call this method with a DIE that hasn't be 496 /// created by this unit. In other word, it's illegal to call this 497 /// method on a DIE that isn't accessible by following 498 /// children/sibling links starting from this unit's getUnitDIE(). getDIEIndex(const DWARFDie & D)499 uint32_t getDIEIndex(const DWARFDie &D) { 500 return getDIEIndex(D.getDebugInfoEntry()); 501 } 502 503 /// Return the DIE object at the given index. getDIEAtIndex(unsigned Index)504 DWARFDie getDIEAtIndex(unsigned Index) { 505 assert(Index < DieArray.size()); 506 return DWARFDie(this, &DieArray[Index]); 507 } 508 509 DWARFDie getParent(const DWARFDebugInfoEntry *Die); 510 DWARFDie getSibling(const DWARFDebugInfoEntry *Die); 511 DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die); 512 DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die); 513 DWARFDie getLastChild(const DWARFDebugInfoEntry *Die); 514 515 /// Return the DIE object for a given offset inside the 516 /// unit's DIE vector. 517 /// 518 /// The unit needs to have its DIEs extracted for this method to work. getDIEForOffset(uint32_t Offset)519 DWARFDie getDIEForOffset(uint32_t Offset) { 520 extractDIEsIfNeeded(false); 521 assert(!DieArray.empty()); 522 auto it = std::lower_bound( 523 DieArray.begin(), DieArray.end(), Offset, 524 [](const DWARFDebugInfoEntry &LHS, uint32_t Offset) { 525 return LHS.getOffset() < Offset; 526 }); 527 if (it != DieArray.end() && it->getOffset() == Offset) 528 return DWARFDie(this, &*it); 529 return DWARFDie(); 530 } 531 getLineTableOffset()532 uint32_t getLineTableOffset() const { 533 if (auto IndexEntry = Header.getIndexEntry()) 534 if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE)) 535 return Contrib->Offset; 536 return 0; 537 } 538 dies()539 die_iterator_range dies() { 540 extractDIEsIfNeeded(false); 541 return die_iterator_range(DieArray.begin(), DieArray.end()); 542 } 543 544 private: 545 /// Size in bytes of the .debug_info data associated with this compile unit. getDebugInfoSize()546 size_t getDebugInfoSize() const { 547 return Header.getLength() + 4 - getHeaderSize(); 548 } 549 550 /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it 551 /// hasn't already been done. Returns the number of DIEs parsed at this call. 552 size_t extractDIEsIfNeeded(bool CUDieOnly); 553 554 /// extractDIEsToVector - Appends all parsed DIEs to a vector. 555 void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs, 556 std::vector<DWARFDebugInfoEntry> &DIEs) const; 557 558 /// clearDIEs - Clear parsed DIEs to keep memory usage low. 559 void clearDIEs(bool KeepCUDie); 560 561 /// parseDWO - Parses .dwo file for current compile unit. Returns true if 562 /// it was actually constructed. 563 bool parseDWO(); 564 }; 565 566 } // end namespace llvm 567 568 #endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H 569