xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- DWARFUnit.h ----------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
100b57cec5SDimitry Andric #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
110b57cec5SDimitry Andric 
1281ad6265SDimitry Andric #include "llvm/ADT/DenseSet.h"
130b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
160b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
170b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
1881ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
1981ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
200b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
210b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDie.h"
2281ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
230b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
240b57cec5SDimitry Andric #include "llvm/Support/DataExtractor.h"
250b57cec5SDimitry Andric #include <cassert>
260b57cec5SDimitry Andric #include <cstddef>
270b57cec5SDimitry Andric #include <cstdint>
280b57cec5SDimitry Andric #include <map>
290b57cec5SDimitry Andric #include <memory>
3081ad6265SDimitry Andric #include <set>
310b57cec5SDimitry Andric #include <utility>
320b57cec5SDimitry Andric #include <vector>
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric namespace llvm {
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric class DWARFAbbreviationDeclarationSet;
370b57cec5SDimitry Andric class DWARFContext;
380b57cec5SDimitry Andric class DWARFDebugAbbrev;
390b57cec5SDimitry Andric class DWARFUnit;
4081ad6265SDimitry Andric class DWARFDebugRangeList;
4181ad6265SDimitry Andric class DWARFLocationTable;
4281ad6265SDimitry Andric class DWARFObject;
4381ad6265SDimitry Andric class raw_ostream;
4481ad6265SDimitry Andric struct DIDumpOptions;
4581ad6265SDimitry Andric struct DWARFSection;
461db9f3b2SDimitry Andric namespace dwarf_linker {
471db9f3b2SDimitry Andric namespace parallel {
4806c3fb27SDimitry Andric class CompileUnit;
4906c3fb27SDimitry Andric }
501db9f3b2SDimitry Andric } // namespace dwarf_linker
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric /// Base class describing the header of any kind of "unit."  Some information
530b57cec5SDimitry Andric /// is specific to certain unit types.  We separate this class out so we can
540b57cec5SDimitry Andric /// parse the header before deciding what specific kind of unit to construct.
550b57cec5SDimitry Andric class DWARFUnitHeader {
560b57cec5SDimitry Andric   // Offset within section.
578bcb0991SDimitry Andric   uint64_t Offset = 0;
580b57cec5SDimitry Andric   // Version, address size, and DWARF format.
590b57cec5SDimitry Andric   dwarf::FormParams FormParams;
600b57cec5SDimitry Andric   uint64_t Length = 0;
610b57cec5SDimitry Andric   uint64_t AbbrOffset = 0;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   // For DWO units only.
640b57cec5SDimitry Andric   const DWARFUnitIndex::Entry *IndexEntry = nullptr;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   // For type units only.
670b57cec5SDimitry Andric   uint64_t TypeHash = 0;
688bcb0991SDimitry Andric   uint64_t TypeOffset = 0;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   // For v5 split or skeleton compile units only.
71bdd1243dSDimitry Andric   std::optional<uint64_t> DWOId;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   // Unit type as parsed, or derived from the section kind.
740b57cec5SDimitry Andric   uint8_t UnitType = 0;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   // Size as parsed. uint8_t for compactness.
770b57cec5SDimitry Andric   uint8_t Size = 0;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric public:
800b57cec5SDimitry Andric   /// Parse a unit header from \p debug_info starting at \p offset_ptr.
815ffd83dbSDimitry Andric   /// Note that \p SectionKind is used as a hint to guess the unit type
825ffd83dbSDimitry Andric   /// for DWARF formats prior to DWARFv5. In DWARFv5 the unit type is
835ffd83dbSDimitry Andric   /// explicitly defined in the header and the hint is ignored.
845f757f3fSDimitry Andric   Error extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
855ffd83dbSDimitry Andric                 uint64_t *offset_ptr, DWARFSectionKind SectionKind);
865ffd83dbSDimitry Andric   // For units in DWARF Package File, remember the index entry and update
875ffd83dbSDimitry Andric   // the abbreviation offset read by extract().
88*0fca6ea1SDimitry Andric   Error applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
getOffset()898bcb0991SDimitry Andric   uint64_t getOffset() const { return Offset; }
getFormParams()900b57cec5SDimitry Andric   const dwarf::FormParams &getFormParams() const { return FormParams; }
getVersion()910b57cec5SDimitry Andric   uint16_t getVersion() const { return FormParams.Version; }
getFormat()920b57cec5SDimitry Andric   dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
getAddressByteSize()930b57cec5SDimitry Andric   uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
getRefAddrByteSize()940b57cec5SDimitry Andric   uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
getDwarfOffsetByteSize()950b57cec5SDimitry Andric   uint8_t getDwarfOffsetByteSize() const {
960b57cec5SDimitry Andric     return FormParams.getDwarfOffsetByteSize();
970b57cec5SDimitry Andric   }
getLength()980b57cec5SDimitry Andric   uint64_t getLength() const { return Length; }
getAbbrOffset()990b57cec5SDimitry Andric   uint64_t getAbbrOffset() const { return AbbrOffset; }
getDWOId()100bdd1243dSDimitry Andric   std::optional<uint64_t> getDWOId() const { return DWOId; }
setDWOId(uint64_t Id)1010b57cec5SDimitry Andric   void setDWOId(uint64_t Id) {
1020b57cec5SDimitry Andric     assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value");
1030b57cec5SDimitry Andric     DWOId = Id;
1040b57cec5SDimitry Andric   }
getIndexEntry()1050b57cec5SDimitry Andric   const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
getTypeHash()1060b57cec5SDimitry Andric   uint64_t getTypeHash() const { return TypeHash; }
getTypeOffset()1078bcb0991SDimitry Andric   uint64_t getTypeOffset() const { return TypeOffset; }
getUnitType()1080b57cec5SDimitry Andric   uint8_t getUnitType() const { return UnitType; }
isTypeUnit()1090b57cec5SDimitry Andric   bool isTypeUnit() const {
1100b57cec5SDimitry Andric     return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
1110b57cec5SDimitry Andric   }
getSize()1120b57cec5SDimitry Andric   uint8_t getSize() const { return Size; }
getUnitLengthFieldByteSize()1138bcb0991SDimitry Andric   uint8_t getUnitLengthFieldByteSize() const {
1148bcb0991SDimitry Andric     return dwarf::getUnitLengthFieldByteSize(FormParams.Format);
1158bcb0991SDimitry Andric   }
getNextUnitOffset()1168bcb0991SDimitry Andric   uint64_t getNextUnitOffset() const {
1178bcb0991SDimitry Andric     return Offset + Length + getUnitLengthFieldByteSize();
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric };
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
1220b57cec5SDimitry Andric                                         DWARFSectionKind Kind);
1230b57cec5SDimitry Andric 
124e8d8bef9SDimitry Andric bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U);
125e8d8bef9SDimitry Andric 
1260b57cec5SDimitry Andric /// Describe a collection of units. Intended to hold all units either from
1270b57cec5SDimitry Andric /// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
1280b57cec5SDimitry Andric class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
1298bcb0991SDimitry Andric   std::function<std::unique_ptr<DWARFUnit>(uint64_t, DWARFSectionKind,
1300b57cec5SDimitry Andric                                            const DWARFSection *,
1310b57cec5SDimitry Andric                                            const DWARFUnitIndex::Entry *)>
1320b57cec5SDimitry Andric       Parser;
1330b57cec5SDimitry Andric   int NumInfoUnits = -1;
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric public:
1360b57cec5SDimitry Andric   using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
1370b57cec5SDimitry Andric   using iterator = typename UnitVector::iterator;
1380b57cec5SDimitry Andric   using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
1390b57cec5SDimitry Andric 
140e8d8bef9SDimitry Andric   using compile_unit_range =
141e8d8bef9SDimitry Andric       decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit));
142e8d8bef9SDimitry Andric 
1438bcb0991SDimitry Andric   DWARFUnit *getUnitForOffset(uint64_t Offset) const;
1440b57cec5SDimitry Andric   DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   /// Read units from a .debug_info or .debug_types section.  Calls made
1470b57cec5SDimitry Andric   /// before finishedInfoUnits() are assumed to be for .debug_info sections,
1480b57cec5SDimitry Andric   /// calls after finishedInfoUnits() are for .debug_types sections.  Caller
1490b57cec5SDimitry Andric   /// must not mix calls to addUnitsForSection and addUnitsForDWOSection.
1500b57cec5SDimitry Andric   void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
1510b57cec5SDimitry Andric                           DWARFSectionKind SectionKind);
1520b57cec5SDimitry Andric   /// Read units from a .debug_info.dwo or .debug_types.dwo section.  Calls
1530b57cec5SDimitry Andric   /// made before finishedInfoUnits() are assumed to be for .debug_info.dwo
1540b57cec5SDimitry Andric   /// sections, calls after finishedInfoUnits() are for .debug_types.dwo
1550b57cec5SDimitry Andric   /// sections.  Caller must not mix calls to addUnitsForSection and
1560b57cec5SDimitry Andric   /// addUnitsForDWOSection.
1570b57cec5SDimitry Andric   void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
1580b57cec5SDimitry Andric                              DWARFSectionKind SectionKind, bool Lazy = false);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   /// Add an existing DWARFUnit to this UnitVector. This is used by the DWARF
1610b57cec5SDimitry Andric   /// verifier to process unit separately.
1620b57cec5SDimitry Andric   DWARFUnit *addUnit(std::unique_ptr<DWARFUnit> Unit);
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   /// Returns number of all units held by this instance.
getNumUnits()1650b57cec5SDimitry Andric   unsigned getNumUnits() const { return size(); }
1660b57cec5SDimitry Andric   /// Returns number of units from all .debug_info[.dwo] sections.
getNumInfoUnits()1670b57cec5SDimitry Andric   unsigned getNumInfoUnits() const {
1680b57cec5SDimitry Andric     return NumInfoUnits == -1 ? size() : NumInfoUnits;
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric   /// Returns number of units from all .debug_types[.dwo] sections.
getNumTypesUnits()1710b57cec5SDimitry Andric   unsigned getNumTypesUnits() const { return size() - NumInfoUnits; }
1720b57cec5SDimitry Andric   /// Indicate that parsing .debug_info[.dwo] is done, and remaining units
1730b57cec5SDimitry Andric   /// will be from .debug_types[.dwo].
finishedInfoUnits()1740b57cec5SDimitry Andric   void finishedInfoUnits() { NumInfoUnits = size(); }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric private:
1770b57cec5SDimitry Andric   void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
1780b57cec5SDimitry Andric                     const DWARFSection &Section, const DWARFDebugAbbrev *DA,
1790b57cec5SDimitry Andric                     const DWARFSection *RS, const DWARFSection *LocSection,
1800b57cec5SDimitry Andric                     StringRef SS, const DWARFSection &SOS,
1810b57cec5SDimitry Andric                     const DWARFSection *AOS, const DWARFSection &LS, bool LE,
1820b57cec5SDimitry Andric                     bool IsDWO, bool Lazy, DWARFSectionKind SectionKind);
1830b57cec5SDimitry Andric };
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric /// Represents base address of the CU.
1860b57cec5SDimitry Andric /// Represents a unit's contribution to the string offsets table.
1870b57cec5SDimitry Andric struct StrOffsetsContributionDescriptor {
1880b57cec5SDimitry Andric   uint64_t Base = 0;
1890b57cec5SDimitry Andric   /// The contribution size not including the header.
1900b57cec5SDimitry Andric   uint64_t Size = 0;
1910b57cec5SDimitry Andric   /// Format and version.
1920b57cec5SDimitry Andric   dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32};
1930b57cec5SDimitry Andric 
StrOffsetsContributionDescriptorStrOffsetsContributionDescriptor1940b57cec5SDimitry Andric   StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size,
1950b57cec5SDimitry Andric                                    uint8_t Version, dwarf::DwarfFormat Format)
1960b57cec5SDimitry Andric       : Base(Base), Size(Size), FormParams({Version, 0, Format}) {}
1970b57cec5SDimitry Andric   StrOffsetsContributionDescriptor() = default;
1980b57cec5SDimitry Andric 
getVersionStrOffsetsContributionDescriptor1990b57cec5SDimitry Andric   uint8_t getVersion() const { return FormParams.Version; }
getFormatStrOffsetsContributionDescriptor2000b57cec5SDimitry Andric   dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
getDwarfOffsetByteSizeStrOffsetsContributionDescriptor2010b57cec5SDimitry Andric   uint8_t getDwarfOffsetByteSize() const {
2020b57cec5SDimitry Andric     return FormParams.getDwarfOffsetByteSize();
2030b57cec5SDimitry Andric   }
2040b57cec5SDimitry Andric   /// Determine whether a contribution to the string offsets table is
2050b57cec5SDimitry Andric   /// consistent with the relevant section size and that its length is
2060b57cec5SDimitry Andric   /// a multiple of the size of one of its entries.
2070b57cec5SDimitry Andric   Expected<StrOffsetsContributionDescriptor>
2080b57cec5SDimitry Andric   validateContributionSize(DWARFDataExtractor &DA);
2090b57cec5SDimitry Andric };
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric class DWARFUnit {
2120b57cec5SDimitry Andric   DWARFContext &Context;
2130b57cec5SDimitry Andric   /// Section containing this DWARFUnit.
2140b57cec5SDimitry Andric   const DWARFSection &InfoSection;
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   DWARFUnitHeader Header;
2170b57cec5SDimitry Andric   const DWARFDebugAbbrev *Abbrev;
2180b57cec5SDimitry Andric   const DWARFSection *RangeSection;
2198bcb0991SDimitry Andric   uint64_t RangeSectionBase;
220480093f4SDimitry Andric   uint64_t LocSectionBase;
221480093f4SDimitry Andric 
222480093f4SDimitry Andric   /// Location table of this unit.
223480093f4SDimitry Andric   std::unique_ptr<DWARFLocationTable> LocTable;
224480093f4SDimitry Andric 
2250b57cec5SDimitry Andric   const DWARFSection &LineSection;
2260b57cec5SDimitry Andric   StringRef StringSection;
2270b57cec5SDimitry Andric   const DWARFSection &StringOffsetSection;
2280b57cec5SDimitry Andric   const DWARFSection *AddrOffsetSection;
229fe6060f1SDimitry Andric   DWARFUnit *SU;
230bdd1243dSDimitry Andric   std::optional<uint64_t> AddrOffsetSectionBase;
231bdd1243dSDimitry Andric   bool IsLittleEndian;
2320b57cec5SDimitry Andric   bool IsDWO;
2330b57cec5SDimitry Andric   const DWARFUnitVector &UnitVector;
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   /// Start, length, and DWARF format of the unit's contribution to the string
2360b57cec5SDimitry Andric   /// offsets table (DWARF v5).
237bdd1243dSDimitry Andric   std::optional<StrOffsetsContributionDescriptor>
238bdd1243dSDimitry Andric       StringOffsetsTableContribution;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
241bdd1243dSDimitry Andric   std::optional<object::SectionedAddress> BaseAddr;
2420b57cec5SDimitry Andric   /// The compile unit debug information entry items.
2430b57cec5SDimitry Andric   std::vector<DWARFDebugInfoEntry> DieArray;
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   /// Map from range's start address to end address and corresponding DIE.
2460b57cec5SDimitry Andric   /// IntervalMap does not support range removal, as a result, we use the
2470b57cec5SDimitry Andric   /// std::map::upper_bound for address range lookup.
2480b57cec5SDimitry Andric   std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
2490b57cec5SDimitry Andric 
25081ad6265SDimitry Andric   /// Map from the location (interpreted DW_AT_location) of a DW_TAG_variable,
25181ad6265SDimitry Andric   /// to the end address and the corresponding DIE.
25281ad6265SDimitry Andric   std::map<uint64_t, std::pair<uint64_t, DWARFDie>> VariableDieMap;
25381ad6265SDimitry Andric   DenseSet<uint64_t> RootsParsedForVariables;
25481ad6265SDimitry Andric 
2550b57cec5SDimitry Andric   using die_iterator_range =
2560b57cec5SDimitry Andric       iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   std::shared_ptr<DWARFUnit> DWO;
2590b57cec5SDimitry Andric 
260bdd1243dSDimitry Andric protected:
2611db9f3b2SDimitry Andric   friend dwarf_linker::parallel::CompileUnit;
26206c3fb27SDimitry Andric 
263bdd1243dSDimitry Andric   /// Return the index of a \p Die entry inside the unit's DIE vector.
264bdd1243dSDimitry Andric   ///
265bdd1243dSDimitry Andric   /// It is illegal to call this method with a DIE that hasn't be
266bdd1243dSDimitry Andric   /// created by this unit. In other word, it's illegal to call this
267bdd1243dSDimitry Andric   /// method on a DIE that isn't accessible by following
268bdd1243dSDimitry Andric   /// children/sibling links starting from this unit's getUnitDIE().
getDIEIndex(const DWARFDebugInfoEntry * Die)269bdd1243dSDimitry Andric   uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {
2700b57cec5SDimitry Andric     auto First = DieArray.data();
2710b57cec5SDimitry Andric     assert(Die >= First && Die < First + DieArray.size());
2720b57cec5SDimitry Andric     return Die - First;
2730b57cec5SDimitry Andric   }
2740b57cec5SDimitry Andric 
275bdd1243dSDimitry Andric   /// Return DWARFDebugInfoEntry for the specified index \p Index.
getDebugInfoEntry(unsigned Index)276bdd1243dSDimitry Andric   const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {
277bdd1243dSDimitry Andric     assert(Index < DieArray.size());
278bdd1243dSDimitry Andric     return &DieArray[Index];
279bdd1243dSDimitry Andric   }
280bdd1243dSDimitry Andric 
281bdd1243dSDimitry Andric   const DWARFDebugInfoEntry *
282bdd1243dSDimitry Andric   getParentEntry(const DWARFDebugInfoEntry *Die) const;
283bdd1243dSDimitry Andric   const DWARFDebugInfoEntry *
284bdd1243dSDimitry Andric   getSiblingEntry(const DWARFDebugInfoEntry *Die) const;
285bdd1243dSDimitry Andric   const DWARFDebugInfoEntry *
286bdd1243dSDimitry Andric   getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const;
287bdd1243dSDimitry Andric   const DWARFDebugInfoEntry *
288bdd1243dSDimitry Andric   getFirstChildEntry(const DWARFDebugInfoEntry *Die) const;
289bdd1243dSDimitry Andric   const DWARFDebugInfoEntry *
290bdd1243dSDimitry Andric   getLastChildEntry(const DWARFDebugInfoEntry *Die) const;
291bdd1243dSDimitry Andric 
getHeader()2920b57cec5SDimitry Andric   const DWARFUnitHeader &getHeader() const { return Header; }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   /// Find the unit's contribution to the string offsets table and determine its
2950b57cec5SDimitry Andric   /// length and form. The given offset is expected to be derived from the unit
2960b57cec5SDimitry Andric   /// DIE's DW_AT_str_offsets_base attribute.
297bdd1243dSDimitry Andric   Expected<std::optional<StrOffsetsContributionDescriptor>>
2980b57cec5SDimitry Andric   determineStringOffsetsTableContribution(DWARFDataExtractor &DA);
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   /// Find the unit's contribution to the string offsets table and determine its
3010b57cec5SDimitry Andric   /// length and form. The given offset is expected to be 0 in a dwo file or,
3020b57cec5SDimitry Andric   /// in a dwp file, the start of the unit's contribution to the string offsets
3030b57cec5SDimitry Andric   /// table section (as determined by the index table).
304bdd1243dSDimitry Andric   Expected<std::optional<StrOffsetsContributionDescriptor>>
3050b57cec5SDimitry Andric   determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA);
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric public:
3080b57cec5SDimitry Andric   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
3090b57cec5SDimitry Andric             const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
3100b57cec5SDimitry Andric             const DWARFSection *RS, const DWARFSection *LocSection,
3110b57cec5SDimitry Andric             StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
3120b57cec5SDimitry Andric             const DWARFSection &LS, bool LE, bool IsDWO,
3130b57cec5SDimitry Andric             const DWARFUnitVector &UnitVector);
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   virtual ~DWARFUnit();
3160b57cec5SDimitry Andric 
isLittleEndian()317bdd1243dSDimitry Andric   bool isLittleEndian() const { return IsLittleEndian; }
isDWOUnit()3180b57cec5SDimitry Andric   bool isDWOUnit() const { return IsDWO; }
getContext()3190b57cec5SDimitry Andric   DWARFContext& getContext() const { return Context; }
getInfoSection()3200b57cec5SDimitry Andric   const DWARFSection &getInfoSection() const { return InfoSection; }
getOffset()3218bcb0991SDimitry Andric   uint64_t getOffset() const { return Header.getOffset(); }
getFormParams()3220b57cec5SDimitry Andric   const dwarf::FormParams &getFormParams() const {
3230b57cec5SDimitry Andric     return Header.getFormParams();
3240b57cec5SDimitry Andric   }
getVersion()3250b57cec5SDimitry Andric   uint16_t getVersion() const { return Header.getVersion(); }
getAddressByteSize()3260b57cec5SDimitry Andric   uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); }
getRefAddrByteSize()3270b57cec5SDimitry Andric   uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); }
getDwarfOffsetByteSize()3280b57cec5SDimitry Andric   uint8_t getDwarfOffsetByteSize() const {
3290b57cec5SDimitry Andric     return Header.getDwarfOffsetByteSize();
3300b57cec5SDimitry Andric   }
331fe6060f1SDimitry Andric   /// Size in bytes of the parsed unit header.
getHeaderSize()332fe6060f1SDimitry Andric   uint32_t getHeaderSize() const { return Header.getSize(); }
getLength()3338bcb0991SDimitry Andric   uint64_t getLength() const { return Header.getLength(); }
getFormat()3345ffd83dbSDimitry Andric   dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
getUnitType()3350b57cec5SDimitry Andric   uint8_t getUnitType() const { return Header.getUnitType(); }
isTypeUnit()3360b57cec5SDimitry Andric   bool isTypeUnit() const { return Header.isTypeUnit(); }
getAbbrOffset()337e8d8bef9SDimitry Andric   uint64_t getAbbrOffset() const { return Header.getAbbrOffset(); }
getNextUnitOffset()3388bcb0991SDimitry Andric   uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
getLineSection()3390b57cec5SDimitry Andric   const DWARFSection &getLineSection() const { return LineSection; }
getStringSection()3400b57cec5SDimitry Andric   StringRef getStringSection() const { return StringSection; }
getStringOffsetSection()3410b57cec5SDimitry Andric   const DWARFSection &getStringOffsetSection() const {
3420b57cec5SDimitry Andric     return StringOffsetSection;
3430b57cec5SDimitry Andric   }
3440b57cec5SDimitry Andric 
setSkeletonUnit(DWARFUnit * SU)345fe6060f1SDimitry Andric   void setSkeletonUnit(DWARFUnit *SU) { this->SU = SU; }
346fe6060f1SDimitry Andric   // Returns itself if not using Split DWARF, or if the unit is a skeleton unit
347fe6060f1SDimitry Andric   // - otherwise returns the split full unit's corresponding skeleton, if
348fe6060f1SDimitry Andric   // available.
getLinkedUnit()349fe6060f1SDimitry Andric   DWARFUnit *getLinkedUnit() { return IsDWO ? SU : this; }
350fe6060f1SDimitry Andric 
setAddrOffsetSection(const DWARFSection * AOS,uint64_t Base)3515ffd83dbSDimitry Andric   void setAddrOffsetSection(const DWARFSection *AOS, uint64_t Base) {
3520b57cec5SDimitry Andric     AddrOffsetSection = AOS;
3530b57cec5SDimitry Andric     AddrOffsetSectionBase = Base;
3540b57cec5SDimitry Andric   }
3550b57cec5SDimitry Andric 
getAddrOffsetSectionBase()356bdd1243dSDimitry Andric   std::optional<uint64_t> getAddrOffsetSectionBase() const {
357fe6060f1SDimitry Andric     return AddrOffsetSectionBase;
358fe6060f1SDimitry Andric   }
359fe6060f1SDimitry Andric 
36006c3fb27SDimitry Andric   /// Returns offset to the indexed address value inside .debug_addr section.
getIndexedAddressOffset(uint64_t Index)36106c3fb27SDimitry Andric   std::optional<uint64_t> getIndexedAddressOffset(uint64_t Index) {
36206c3fb27SDimitry Andric     if (std::optional<uint64_t> AddrOffsetSectionBase =
36306c3fb27SDimitry Andric             getAddrOffsetSectionBase())
36406c3fb27SDimitry Andric       return *AddrOffsetSectionBase + Index * getAddressByteSize();
36506c3fb27SDimitry Andric 
36606c3fb27SDimitry Andric     return std::nullopt;
36706c3fb27SDimitry Andric   }
36806c3fb27SDimitry Andric 
3690b57cec5SDimitry Andric   /// Recursively update address to Die map.
3700b57cec5SDimitry Andric   void updateAddressDieMap(DWARFDie Die);
3710b57cec5SDimitry Andric 
37281ad6265SDimitry Andric   /// Recursively update address to variable Die map.
37381ad6265SDimitry Andric   void updateVariableDieMap(DWARFDie Die);
37481ad6265SDimitry Andric 
setRangesSection(const DWARFSection * RS,uint64_t Base)3758bcb0991SDimitry Andric   void setRangesSection(const DWARFSection *RS, uint64_t Base) {
3760b57cec5SDimitry Andric     RangeSection = RS;
3770b57cec5SDimitry Andric     RangeSectionBase = Base;
3780b57cec5SDimitry Andric   }
379480093f4SDimitry Andric 
getLocSectionBase()380480093f4SDimitry Andric   uint64_t getLocSectionBase() const {
381480093f4SDimitry Andric     return LocSectionBase;
382480093f4SDimitry Andric   }
3830b57cec5SDimitry Andric 
384bdd1243dSDimitry Andric   std::optional<object::SectionedAddress>
3850b57cec5SDimitry Andric   getAddrOffsetSectionItem(uint32_t Index) const;
3860eae32dcSDimitry Andric   Expected<uint64_t> getStringOffsetSectionItem(uint32_t Index) const;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   DWARFDataExtractor getDebugInfoExtractor() const;
3890b57cec5SDimitry Andric 
getStringExtractor()3900b57cec5SDimitry Andric   DataExtractor getStringExtractor() const {
3910b57cec5SDimitry Andric     return DataExtractor(StringSection, false, 0);
3920b57cec5SDimitry Andric   }
3930b57cec5SDimitry Andric 
getLocationTable()394480093f4SDimitry Andric   const DWARFLocationTable &getLocationTable() { return *LocTable; }
395480093f4SDimitry Andric 
3960b57cec5SDimitry Andric   /// Extract the range list referenced by this compile unit from the
3970b57cec5SDimitry Andric   /// .debug_ranges section. If the extraction is unsuccessful, an error
3980b57cec5SDimitry Andric   /// is returned. Successful extraction requires that the compile unit
3990b57cec5SDimitry Andric   /// has already been extracted.
4008bcb0991SDimitry Andric   Error extractRangeList(uint64_t RangeListOffset,
4010b57cec5SDimitry Andric                          DWARFDebugRangeList &RangeList) const;
4020b57cec5SDimitry Andric   void clear();
4030b57cec5SDimitry Andric 
404bdd1243dSDimitry Andric   const std::optional<StrOffsetsContributionDescriptor> &
getStringOffsetsTableContribution()4055f757f3fSDimitry Andric   getStringOffsetsTableContribution() {
4065f757f3fSDimitry Andric     extractDIEsIfNeeded(true /*CUDIeOnly*/);
4070b57cec5SDimitry Andric     return StringOffsetsTableContribution;
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric 
getDwarfStringOffsetsByteSize()4100b57cec5SDimitry Andric   uint8_t getDwarfStringOffsetsByteSize() const {
4110b57cec5SDimitry Andric     assert(StringOffsetsTableContribution);
4120b57cec5SDimitry Andric     return StringOffsetsTableContribution->getDwarfOffsetByteSize();
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric 
getStringOffsetsBase()4150b57cec5SDimitry Andric   uint64_t getStringOffsetsBase() const {
4160b57cec5SDimitry Andric     assert(StringOffsetsTableContribution);
4170b57cec5SDimitry Andric     return StringOffsetsTableContribution->Base;
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric 
getAbbreviationsOffset()420fe6060f1SDimitry Andric   uint64_t getAbbreviationsOffset() const { return Header.getAbbrOffset(); }
421fe6060f1SDimitry Andric 
4220b57cec5SDimitry Andric   const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
4230b57cec5SDimitry Andric 
isMatchingUnitTypeAndTag(uint8_t UnitType,dwarf::Tag Tag)4240b57cec5SDimitry Andric   static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) {
4250b57cec5SDimitry Andric     switch (UnitType) {
4260b57cec5SDimitry Andric     case dwarf::DW_UT_compile:
4270b57cec5SDimitry Andric       return Tag == dwarf::DW_TAG_compile_unit;
4280b57cec5SDimitry Andric     case dwarf::DW_UT_type:
4290b57cec5SDimitry Andric       return Tag == dwarf::DW_TAG_type_unit;
4300b57cec5SDimitry Andric     case dwarf::DW_UT_partial:
4310b57cec5SDimitry Andric       return Tag == dwarf::DW_TAG_partial_unit;
4320b57cec5SDimitry Andric     case dwarf::DW_UT_skeleton:
4330b57cec5SDimitry Andric       return Tag == dwarf::DW_TAG_skeleton_unit;
4340b57cec5SDimitry Andric     case dwarf::DW_UT_split_compile:
4350b57cec5SDimitry Andric     case dwarf::DW_UT_split_type:
4360b57cec5SDimitry Andric       return dwarf::isUnitType(Tag);
4370b57cec5SDimitry Andric     }
4380b57cec5SDimitry Andric     return false;
4390b57cec5SDimitry Andric   }
4400b57cec5SDimitry Andric 
441bdd1243dSDimitry Andric   std::optional<object::SectionedAddress> getBaseAddress();
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
4440b57cec5SDimitry Andric     extractDIEsIfNeeded(ExtractUnitDIEOnly);
4450b57cec5SDimitry Andric     if (DieArray.empty())
4460b57cec5SDimitry Andric       return DWARFDie();
4470b57cec5SDimitry Andric     return DWARFDie(this, &DieArray[0]);
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric 
450bdd1243dSDimitry Andric   DWARFDie getNonSkeletonUnitDIE(bool ExtractUnitDIEOnly = true,
451bdd1243dSDimitry Andric                                  StringRef DWOAlternativeLocation = {}) {
452bdd1243dSDimitry Andric     parseDWO(DWOAlternativeLocation);
453bdd1243dSDimitry Andric     return DWO ? DWO->getUnitDIE(ExtractUnitDIEOnly)
454bdd1243dSDimitry Andric                : getUnitDIE(ExtractUnitDIEOnly);
4550b57cec5SDimitry Andric   }
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric   const char *getCompilationDir();
getDWOId()458bdd1243dSDimitry Andric   std::optional<uint64_t> getDWOId() {
4590b57cec5SDimitry Andric     extractDIEsIfNeeded(/*CUDieOnly*/ true);
4600b57cec5SDimitry Andric     return getHeader().getDWOId();
4610b57cec5SDimitry Andric   }
setDWOId(uint64_t NewID)4620b57cec5SDimitry Andric   void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric   /// Return a vector of address ranges resulting from a (possibly encoded)
4650b57cec5SDimitry Andric   /// range list starting at a given offset in the appropriate ranges section.
4668bcb0991SDimitry Andric   Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint64_t Offset);
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   /// Return a vector of address ranges retrieved from an encoded range
4690b57cec5SDimitry Andric   /// list whose offset is found via a table lookup given an index (DWARF v5
4700b57cec5SDimitry Andric   /// and later).
4710b57cec5SDimitry Andric   Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index);
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric   /// Return a rangelist's offset based on an index. The index designates
4740b57cec5SDimitry Andric   /// an entry in the rangelist table's offset array and is supplied by
4750b57cec5SDimitry Andric   /// DW_FORM_rnglistx.
476bdd1243dSDimitry Andric   std::optional<uint64_t> getRnglistOffset(uint32_t Index);
4770b57cec5SDimitry Andric 
478bdd1243dSDimitry Andric   std::optional<uint64_t> getLoclistOffset(uint32_t Index);
479e8d8bef9SDimitry Andric 
4800b57cec5SDimitry Andric   Expected<DWARFAddressRangesVector> collectAddressRanges();
4810b57cec5SDimitry Andric 
482480093f4SDimitry Andric   Expected<DWARFLocationExpressionsVector>
483480093f4SDimitry Andric   findLoclistFromOffset(uint64_t Offset);
484480093f4SDimitry Andric 
4850b57cec5SDimitry Andric   /// Returns subprogram DIE with address range encompassing the provided
4860b57cec5SDimitry Andric   /// address. The pointer is alive as long as parsed compile unit DIEs are not
4870b57cec5SDimitry Andric   /// cleared.
4880b57cec5SDimitry Andric   DWARFDie getSubroutineForAddress(uint64_t Address);
4890b57cec5SDimitry Andric 
49081ad6265SDimitry Andric   /// Returns variable DIE for the address provided. The pointer is alive as
49181ad6265SDimitry Andric   /// long as parsed compile unit DIEs are not cleared.
49281ad6265SDimitry Andric   DWARFDie getVariableForAddress(uint64_t Address);
49381ad6265SDimitry Andric 
4940b57cec5SDimitry Andric   /// getInlinedChainForAddress - fetches inlined chain for a given address.
4950b57cec5SDimitry Andric   /// Returns empty chain if there is no subprogram containing address. The
4960b57cec5SDimitry Andric   /// chain is valid as long as parsed compile unit DIEs are not cleared.
4970b57cec5SDimitry Andric   void getInlinedChainForAddress(uint64_t Address,
4980b57cec5SDimitry Andric                                  SmallVectorImpl<DWARFDie> &InlinedChain);
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   /// Return the DWARFUnitVector containing this unit.
getUnitVector()5010b57cec5SDimitry Andric   const DWARFUnitVector &getUnitVector() const { return UnitVector; }
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   /// Returns the number of DIEs in the unit. Parses the unit
5040b57cec5SDimitry Andric   /// if necessary.
getNumDIEs()5050b57cec5SDimitry Andric   unsigned getNumDIEs() {
5060b57cec5SDimitry Andric     extractDIEsIfNeeded(false);
5070b57cec5SDimitry Andric     return DieArray.size();
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   /// Return the index of a DIE inside the unit's DIE vector.
5110b57cec5SDimitry Andric   ///
5120b57cec5SDimitry Andric   /// It is illegal to call this method with a DIE that hasn't be
5130b57cec5SDimitry Andric   /// created by this unit. In other word, it's illegal to call this
5140b57cec5SDimitry Andric   /// method on a DIE that isn't accessible by following
5150b57cec5SDimitry Andric   /// children/sibling links starting from this unit's getUnitDIE().
getDIEIndex(const DWARFDie & D)516bdd1243dSDimitry Andric   uint32_t getDIEIndex(const DWARFDie &D) const {
5170b57cec5SDimitry Andric     return getDIEIndex(D.getDebugInfoEntry());
5180b57cec5SDimitry Andric   }
5190b57cec5SDimitry Andric 
520bdd1243dSDimitry Andric   /// Return the DIE object at the given index \p Index.
getDIEAtIndex(unsigned Index)5210b57cec5SDimitry Andric   DWARFDie getDIEAtIndex(unsigned Index) {
522bdd1243dSDimitry Andric     return DWARFDie(this, getDebugInfoEntry(Index));
5230b57cec5SDimitry Andric   }
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric   DWARFDie getParent(const DWARFDebugInfoEntry *Die);
5260b57cec5SDimitry Andric   DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
5270b57cec5SDimitry Andric   DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
5280b57cec5SDimitry Andric   DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
5290b57cec5SDimitry Andric   DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
5300b57cec5SDimitry Andric 
531bdd1243dSDimitry Andric   /// Return the DIE object for a given offset \p Offset inside the
5320b57cec5SDimitry Andric   /// unit's DIE vector.
getDIEForOffset(uint64_t Offset)5338bcb0991SDimitry Andric   DWARFDie getDIEForOffset(uint64_t Offset) {
534bdd1243dSDimitry Andric     if (std::optional<uint32_t> DieIdx = getDIEIndexForOffset(Offset))
535bdd1243dSDimitry Andric       return DWARFDie(this, &DieArray[*DieIdx]);
536bdd1243dSDimitry Andric 
537bdd1243dSDimitry Andric     return DWARFDie();
538bdd1243dSDimitry Andric   }
539bdd1243dSDimitry Andric 
540bdd1243dSDimitry Andric   /// Return the DIE index for a given offset \p Offset inside the
541bdd1243dSDimitry Andric   /// unit's DIE vector.
getDIEIndexForOffset(uint64_t Offset)542bdd1243dSDimitry Andric   std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
5430b57cec5SDimitry Andric     extractDIEsIfNeeded(false);
5440b57cec5SDimitry Andric     auto It =
5450b57cec5SDimitry Andric         llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
5460b57cec5SDimitry Andric           return DIE.getOffset() < Offset;
5470b57cec5SDimitry Andric         });
5480b57cec5SDimitry Andric     if (It != DieArray.end() && It->getOffset() == Offset)
549bdd1243dSDimitry Andric       return It - DieArray.begin();
550bdd1243dSDimitry Andric     return std::nullopt;
5510b57cec5SDimitry Andric   }
5520b57cec5SDimitry Andric 
getLineTableOffset()5530b57cec5SDimitry Andric   uint32_t getLineTableOffset() const {
5540b57cec5SDimitry Andric     if (auto IndexEntry = Header.getIndexEntry())
5555ffd83dbSDimitry Andric       if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LINE))
556bdd1243dSDimitry Andric         return Contrib->getOffset32();
5570b57cec5SDimitry Andric     return 0;
5580b57cec5SDimitry Andric   }
5590b57cec5SDimitry Andric 
dies()5600b57cec5SDimitry Andric   die_iterator_range dies() {
5610b57cec5SDimitry Andric     extractDIEsIfNeeded(false);
5620b57cec5SDimitry Andric     return die_iterator_range(DieArray.begin(), DieArray.end());
5630b57cec5SDimitry Andric   }
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric   virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
5668bcb0991SDimitry Andric 
5678bcb0991SDimitry Andric   Error tryExtractDIEsIfNeeded(bool CUDieOnly);
5688bcb0991SDimitry Andric 
5690b57cec5SDimitry Andric private:
5700b57cec5SDimitry Andric   /// Size in bytes of the .debug_info data associated with this compile unit.
getDebugInfoSize()5710b57cec5SDimitry Andric   size_t getDebugInfoSize() const {
5728bcb0991SDimitry Andric     return Header.getLength() + Header.getUnitLengthFieldByteSize() -
5738bcb0991SDimitry Andric            getHeaderSize();
5740b57cec5SDimitry Andric   }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
5778bcb0991SDimitry Andric   /// hasn't already been done
5788bcb0991SDimitry Andric   void extractDIEsIfNeeded(bool CUDieOnly);
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   /// extractDIEsToVector - Appends all parsed DIEs to a vector.
5810b57cec5SDimitry Andric   void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
5820b57cec5SDimitry Andric                            std::vector<DWARFDebugInfoEntry> &DIEs) const;
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   /// clearDIEs - Clear parsed DIEs to keep memory usage low.
5850b57cec5SDimitry Andric   void clearDIEs(bool KeepCUDie);
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric   /// parseDWO - Parses .dwo file for current compile unit. Returns true if
5880b57cec5SDimitry Andric   /// it was actually constructed.
589bdd1243dSDimitry Andric   /// The \p AlternativeLocation specifies an alternative location to get
590bdd1243dSDimitry Andric   /// the DWARF context for the DWO object; this is the case when it has
591bdd1243dSDimitry Andric   /// been moved from its original location.
592bdd1243dSDimitry Andric   bool parseDWO(StringRef AlternativeLocation = {});
5930b57cec5SDimitry Andric };
5940b57cec5SDimitry Andric 
isCompileUnit(const std::unique_ptr<DWARFUnit> & U)595e8d8bef9SDimitry Andric inline bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U) {
596e8d8bef9SDimitry Andric   return !U->isTypeUnit();
597e8d8bef9SDimitry Andric }
598e8d8bef9SDimitry Andric 
5990b57cec5SDimitry Andric } // end namespace llvm
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric #endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
602