1cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
2cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//
3cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//                     The LLVM Compiler Infrastructure
4cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//
5cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// This file is distributed under the University of Illinois Open Source
6cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// License. See LICENSE.TXT for details.
7cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//
8cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//===----------------------------------------------------------------------===//
9cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
12cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h"
14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFSection.h"
19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
20cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include <vector>
21cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
22cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikienamespace llvm {
23cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
24cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikienamespace object {
25cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass ObjectFile;
26cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie}
27cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass DWARFContext;
29cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass DWARFDebugAbbrev;
3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass DWARFUnit;
31cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass StringRef;
32cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass raw_ostream;
33cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Base class for all DWARFUnitSection classes. This provides the
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// functionality common to all unit types.
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass DWARFUnitSectionBase {
3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// Returns the Unit that contains the given section offset in the
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// same section this Unit originated from.
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void parse(DWARFContext &C, const DWARFSection &Section);
43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                DWARFUnitIndex *Index = nullptr);
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprotected:
4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                         StringRef SOS, StringRef AOS, StringRef LS,
50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         bool isLittleEndian, bool isDWO) = 0;
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  ~DWARFUnitSectionBase() = default;
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarconst DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                        DWARFSectionKind Kind);
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate<typename UnitType>
6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               public DWARFUnitSectionBase {
62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool Parsed = false;
6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  typedef typename UnitVector::iterator iterator;
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  UnitType *getUnitForOffset(uint32_t Offset) const override {
70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto *CU = std::upper_bound(
71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        this->begin(), this->end(), Offset,
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          return LHS < RHS->getNextUnitOffset();
74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        });
7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (CU != this->end())
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return CU->get();
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate:
8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void parseImpl(DWARFContext &Context, const DWARFSection &Section,
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 StringRef SOS, StringRef AOS, StringRef LS, bool LE,
84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 bool IsDWO) override {
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parsed)
8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DataExtractor Data(Section.Data, LE, 0);
8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Offset = 0;
9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    while (Data.isValidOffset(Offset)) {
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
92de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                           AOS, LS, LE, IsDWO, *this,
93f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                           Index.getFromOffset(Offset));
9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!U->extract(Data, &Offset))
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      this->push_back(std::move(U));
9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Offset = this->back()->getNextUnitOffset();
9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Parsed = true;
10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
103cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass DWARFUnit {
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DWARFContext &Context;
10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Section containing this DWARFUnit.
10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const DWARFSection &InfoSection;
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
108cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFDebugAbbrev *Abbrev;
109cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef RangeSection;
110cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t RangeSectionBase;
111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef LineSection;
112cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef StringSection;
113cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef StringOffsetSection;
114cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef AddrOffsetSection;
115cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t AddrOffsetSectionBase;
116cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool isLittleEndian;
117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isDWO;
11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const DWARFUnitSectionBase &UnitSection;
119cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
120cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t Offset;
121cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t Length;
122cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint16_t Version;
123cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFAbbreviationDeclarationSet *Abbrevs;
124cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint8_t AddrSize;
125cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t BaseAddr;
126cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  // The compile unit debug information entry items.
127cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  std::vector<DWARFDebugInfoEntryMinimal> DieArray;
128cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
129cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  class DWOHolder {
13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    object::OwningBinary<object::ObjectFile> DWOFile;
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DWARFContext> DWOContext;
132cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    DWARFUnit *DWOU;
133cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  public:
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DWOHolder(StringRef DWOPath);
135cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    DWARFUnit *getUnit() const { return DWOU; }
136cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  };
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DWOHolder> DWO;
138cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const DWARFUnitIndex::Entry *IndexEntry;
140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
141cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieprotected:
142cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Size in bytes of the unit header.
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  virtual uint32_t getHeaderSize() const { return 11; }
145cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
146cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiepublic:
14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            const DWARFUnitSectionBase &UnitSection,
151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            const DWARFUnitIndex::Entry *IndexEntry = nullptr);
152cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
153cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  virtual ~DWARFUnit();
154cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DWARFContext& getContext() const { return Context; }
15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef getLineSection() const { return LineSection; }
158cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef getStringSection() const { return StringSection; }
159cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef getStringOffsetSection() const { return StringOffsetSection; }
160cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
161cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    AddrOffsetSection = AOS;
162cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    AddrOffsetSectionBase = Base;
163cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
164cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void setRangesSection(StringRef RS, uint32_t Base) {
165cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    RangeSection = RS;
166cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    RangeSectionBase = Base;
167cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
168cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
169cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
170cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  // FIXME: Result should be uint64_t in DWARF64.
171cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
172cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
173cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DataExtractor getDebugInfoExtractor() const {
17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
175cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
176cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DataExtractor getStringExtractor() const {
177cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    return DataExtractor(StringSection, false, 0);
178cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
179cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
181cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
182cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
183cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
184cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// extractRangeList - extracts the range list referenced by this compile
185cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// unit from .debug_ranges section. Returns true on success.
186cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// Requires that compile unit is already extracted.
187cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool extractRangeList(uint32_t RangeListOffset,
188cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                        DWARFDebugRangeList &RangeList) const;
189cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void clear();
190cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t getOffset() const { return Offset; }
191cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
192cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t getLength() const { return Length; }
193cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint16_t getVersion() const { return Version; }
194cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
195cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    return Abbrevs;
196cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
197cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint8_t getAddressByteSize() const { return AddrSize; }
198cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t getBaseAddress() const { return BaseAddr; }
199cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
200cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void setBaseAddress(uint64_t base_addr) {
201cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    BaseAddr = base_addr;
202cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
203cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
2046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const DWARFDebugInfoEntryMinimal *getUnitDIE(bool ExtractUnitDIEOnly = true) {
2056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    extractDIEsIfNeeded(ExtractUnitDIEOnly);
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DieArray.empty() ? nullptr : &DieArray[0];
207cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
208cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
209cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const char *getCompilationDir();
210cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t getDWOId();
211cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void collectAddressRanges(DWARFAddressRangesVector &CURanges);
213cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
214cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// getInlinedChainForAddress - fetches inlined chain for a given address.
215cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// Returns empty chain if there is no subprogram containing address. The
216cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// chain is valid as long as parsed compile unit DIEs are not cleared.
217cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
218cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// getUnitSection - Return the DWARFUnitSection containing this unit.
22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// \brief Returns the number of DIEs in the unit. Parses the unit
223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// if necessary.
224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned getNumDIEs() {
225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    extractDIEsIfNeeded(false);
226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return DieArray.size();
227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// \brief Return the index of a DIE inside the unit's DIE vector.
230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ///
231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// It is illegal to call this method with a DIE that hasn't be
232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// created by this unit. In other word, it's illegal to call this
233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// method on a DIE that isn't accessible by following
2346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// children/sibling links starting from this unit's getUnitDIE().
235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t getDIEIndex(const DWARFDebugInfoEntryMinimal *DIE) {
236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(!DieArray.empty() && DIE >= &DieArray[0] &&
237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines           DIE < &DieArray[0] + DieArray.size());
238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return DIE - &DieArray[0];
239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// \brief Return the DIE object at the given index.
242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const DWARFDebugInfoEntryMinimal *getDIEAtIndex(unsigned Index) const {
243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(Index < DieArray.size());
244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return &DieArray[Index];
245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// \brief Return the DIE object for a given offset inside the
248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// unit's DIE vector.
249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ///
250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  /// The unit needs to have its DIEs extracted for this method to work.
251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const DWARFDebugInfoEntryMinimal *getDIEForOffset(uint32_t Offset) const {
252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(!DieArray.empty());
253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    auto it = std::lower_bound(
254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        DieArray.begin(), DieArray.end(), Offset,
255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        [](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) {
256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return LHS.getOffset() < Offset;
257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        });
258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return it == DieArray.end() ? nullptr : &*it;
259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint32_t getLineTableOffset() const {
262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IndexEntry)
263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return Contrib->Offset;
265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return 0;
266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
268cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieprivate:
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Size in bytes of the .debug_info data associated with this compile unit.
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2727d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
2737d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// hasn't already been done. Returns the number of DIEs parsed at this call.
2747d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  size_t extractDIEsIfNeeded(bool CUDieOnly);
275cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// extractDIEsToVector - Appends all parsed DIEs to a vector.
276cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
277cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                           std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const;
2787d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// setDIERelations - We read in all of the DIE entries into our flat list
2797d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// of DIE entries and now we need to go back through all of them and set the
2807d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// parent, sibling and child pointers for quick DIE navigation.
2817d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  void setDIERelations();
282cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// clearDIEs - Clear parsed DIEs to keep memory usage low.
283cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void clearDIEs(bool KeepCUDie);
284cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
285cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// parseDWO - Parses .dwo file for current compile unit. Returns true if
286cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// it was actually constructed.
287cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool parseDWO();
288cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
289cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// getSubprogramForAddress - Returns subprogram DIE with address range
290cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// encompassing the provided address. The pointer is alive as long as parsed
291cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// compile unit DIEs are not cleared.
292cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
293cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie};
294cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
295cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie}
296cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
297cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#endif
298