[DWARF parser] Make DWARF parser more robust against missing compile/type units.
[oota-llvm.git] / include / llvm / DebugInfo / DWARF / DWARFUnit.h
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_LIB_DEBUGINFO_DWARFUNIT_H
11 #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
12
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
15 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
16 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
17 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
18 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
19 #include <vector>
20
21 namespace llvm {
22
23 namespace object {
24 class ObjectFile;
25 }
26
27 class DWARFContext;
28 class DWARFDebugAbbrev;
29 class DWARFUnit;
30 class StringRef;
31 class raw_ostream;
32
33 /// Base class for all DWARFUnitSection classes. This provides the
34 /// functionality common to all unit types.
35 class DWARFUnitSectionBase {
36 public:
37   /// Returns the Unit that contains the given section offset in the
38   /// same section this Unit originated from.
39   virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
40
41   void parse(DWARFContext &C, const DWARFSection &Section);
42   void parseDWO(DWARFContext &C, const DWARFSection &DWOSection);
43
44 protected:
45   virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
46                          const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
47                          StringRef SOS, StringRef AOS, bool isLittleEndian) = 0;
48
49   ~DWARFUnitSectionBase() = default;
50 };
51
52 /// Concrete instance of DWARFUnitSection, specialized for one Unit type.
53 template<typename UnitType>
54 class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
55                                public DWARFUnitSectionBase {
56
57   struct UnitOffsetComparator {
58     bool operator()(uint32_t LHS,
59                     const std::unique_ptr<UnitType> &RHS) const {
60       return LHS < RHS->getNextUnitOffset();
61     }
62   };
63
64   bool Parsed;
65
66 public:
67   DWARFUnitSection() : Parsed(false) {}
68   DWARFUnitSection(DWARFUnitSection &&DUS) :
69     SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {}
70
71   typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
72   typedef typename UnitVector::iterator iterator;
73   typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
74
75   UnitType *getUnitForOffset(uint32_t Offset) const override {
76     auto *CU = std::upper_bound(this->begin(), this->end(), Offset,
77                                 UnitOffsetComparator());
78     if (CU != this->end())
79       return CU->get();
80     return nullptr;
81   }
82
83 private:
84   void parseImpl(DWARFContext &Context, const DWARFSection &Section,
85                  const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
86                  StringRef SOS, StringRef AOS, bool LE) override {
87     if (Parsed)
88       return;
89     DataExtractor Data(Section.Data, LE, 0);
90     uint32_t Offset = 0;
91     while (Data.isValidOffset(Offset)) {
92       auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
93                                            AOS, LE, *this);
94       if (!U->extract(Data, &Offset))
95         break;
96       this->push_back(std::move(U));
97       Offset = this->back()->getNextUnitOffset();
98     }
99     Parsed = true;
100   }
101 };
102
103 class DWARFUnit {
104   DWARFContext &Context;
105   // Section containing this DWARFUnit.
106   const DWARFSection &InfoSection;
107
108   const DWARFDebugAbbrev *Abbrev;
109   StringRef RangeSection;
110   uint32_t RangeSectionBase;
111   StringRef StringSection;
112   StringRef StringOffsetSection;
113   StringRef AddrOffsetSection;
114   uint32_t AddrOffsetSectionBase;
115   bool isLittleEndian;
116   const DWARFUnitSectionBase &UnitSection;
117
118   uint32_t Offset;
119   uint32_t Length;
120   uint16_t Version;
121   const DWARFAbbreviationDeclarationSet *Abbrevs;
122   uint8_t AddrSize;
123   uint64_t BaseAddr;
124   // The compile unit debug information entry items.
125   std::vector<DWARFDebugInfoEntryMinimal> DieArray;
126
127   class DWOHolder {
128     object::OwningBinary<object::ObjectFile> DWOFile;
129     std::unique_ptr<DWARFContext> DWOContext;
130     DWARFUnit *DWOU;
131   public:
132     DWOHolder(StringRef DWOPath);
133     DWARFUnit *getUnit() const { return DWOU; }
134   };
135   std::unique_ptr<DWOHolder> DWO;
136
137 protected:
138   virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
139   /// Size in bytes of the unit header.
140   virtual uint32_t getHeaderSize() const { return 11; }
141
142 public:
143   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
144             const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
145             StringRef SOS, StringRef AOS, bool LE,
146             const DWARFUnitSectionBase &UnitSection);
147
148   virtual ~DWARFUnit();
149
150   DWARFContext& getContext() const { return Context; }
151
152   StringRef getStringSection() const { return StringSection; }
153   StringRef getStringOffsetSection() const { return StringOffsetSection; }
154   void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
155     AddrOffsetSection = AOS;
156     AddrOffsetSectionBase = Base;
157   }
158   void setRangesSection(StringRef RS, uint32_t Base) {
159     RangeSection = RS;
160     RangeSectionBase = Base;
161   }
162
163   bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
164   // FIXME: Result should be uint64_t in DWARF64.
165   bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
166
167   DataExtractor getDebugInfoExtractor() const {
168     return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
169   }
170   DataExtractor getStringExtractor() const {
171     return DataExtractor(StringSection, false, 0);
172   }
173
174   const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
175
176   bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
177
178   /// extractRangeList - extracts the range list referenced by this compile
179   /// unit from .debug_ranges section. Returns true on success.
180   /// Requires that compile unit is already extracted.
181   bool extractRangeList(uint32_t RangeListOffset,
182                         DWARFDebugRangeList &RangeList) const;
183   void clear();
184   uint32_t getOffset() const { return Offset; }
185   uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
186   uint32_t getLength() const { return Length; }
187   uint16_t getVersion() const { return Version; }
188   const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
189     return Abbrevs;
190   }
191   uint8_t getAddressByteSize() const { return AddrSize; }
192   uint64_t getBaseAddress() const { return BaseAddr; }
193
194   void setBaseAddress(uint64_t base_addr) {
195     BaseAddr = base_addr;
196   }
197
198   const DWARFDebugInfoEntryMinimal *getUnitDIE(bool ExtractUnitDIEOnly = true) {
199     extractDIEsIfNeeded(ExtractUnitDIEOnly);
200     return DieArray.empty() ? nullptr : &DieArray[0];
201   }
202
203   const char *getCompilationDir();
204   uint64_t getDWOId();
205
206   void collectAddressRanges(DWARFAddressRangesVector &CURanges);
207
208   /// getInlinedChainForAddress - fetches inlined chain for a given address.
209   /// Returns empty chain if there is no subprogram containing address. The
210   /// chain is valid as long as parsed compile unit DIEs are not cleared.
211   DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
212
213   /// getUnitSection - Return the DWARFUnitSection containing this unit.
214   const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
215
216   /// \brief Returns the number of DIEs in the unit. Parses the unit
217   /// if necessary.
218   unsigned getNumDIEs() {
219     extractDIEsIfNeeded(false);
220     return DieArray.size();
221   }
222
223   /// \brief Return the index of a DIE inside the unit's DIE vector.
224   ///
225   /// It is illegal to call this method with a DIE that hasn't be
226   /// created by this unit. In other word, it's illegal to call this
227   /// method on a DIE that isn't accessible by following
228   /// children/sibling links starting from this unit's getUnitDIE().
229   uint32_t getDIEIndex(const DWARFDebugInfoEntryMinimal *DIE) {
230     assert(!DieArray.empty() && DIE >= &DieArray[0] &&
231            DIE < &DieArray[0] + DieArray.size());
232     return DIE - &DieArray[0];
233   }
234
235   /// \brief Return the DIE object at the given index.
236   const DWARFDebugInfoEntryMinimal *getDIEAtIndex(unsigned Index) const {
237     assert(Index < DieArray.size());
238     return &DieArray[Index];
239   }
240
241   /// \brief Return the DIE object for a given offset inside the
242   /// unit's DIE vector.
243   ///
244   /// The unit needs to have his DIEs extracted for this method to work.
245   const DWARFDebugInfoEntryMinimal *getDIEForOffset(uint32_t Offset) const {
246     assert(!DieArray.empty());
247     auto it = std::lower_bound(
248         DieArray.begin(), DieArray.end(), Offset,
249         [=](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) {
250           return LHS.getOffset() < Offset;
251         });
252     return it == DieArray.end() ? nullptr : &*it;
253   }
254
255 private:
256   /// Size in bytes of the .debug_info data associated with this compile unit.
257   size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
258
259   /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
260   /// hasn't already been done. Returns the number of DIEs parsed at this call.
261   size_t extractDIEsIfNeeded(bool CUDieOnly);
262   /// extractDIEsToVector - Appends all parsed DIEs to a vector.
263   void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
264                            std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const;
265   /// setDIERelations - We read in all of the DIE entries into our flat list
266   /// of DIE entries and now we need to go back through all of them and set the
267   /// parent, sibling and child pointers for quick DIE navigation.
268   void setDIERelations();
269   /// clearDIEs - Clear parsed DIEs to keep memory usage low.
270   void clearDIEs(bool KeepCUDie);
271
272   /// parseDWO - Parses .dwo file for current compile unit. Returns true if
273   /// it was actually constructed.
274   bool parseDWO();
275
276   /// getSubprogramForAddress - Returns subprogram DIE with address range
277   /// encompassing the provided address. The pointer is alive as long as parsed
278   /// compile unit DIEs are not cleared.
279   const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
280 };
281
282 }
283
284 #endif