LLVM  3.7.0
DWARFUnit.h
Go to the documentation of this file.
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"
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.
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) {}
69  SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {}
70 
72  typedef typename UnitVector::iterator iterator;
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 {
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 
168  return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
169  }
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; }
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 
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.
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().
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
virtual ~DWARFUnit()
Definition: DWARFUnit.cpp:43
void push_back(const T &Elt)
Definition: SmallVector.h:222
void setBaseAddress(uint64_t base_addr)
Definition: DWARFUnit.h:194
static It2 move(It1 I, It1 E, It2 Dest)
Use move-assignment to move the range [I, E) onto the objects starting with "Dest".
Definition: SmallVector.h:184
uint64_t getBaseAddress() const
Definition: DWARFUnit.h:192
std::vector< std::pair< uint64_t, uint64_t > > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
RelocAddrMap Relocs
Definition: DWARFSection.h:20
void collectAddressRanges(DWARFAddressRangesVector &CURanges)
Definition: DWARFUnit.cpp:309
StringRef getStringOffsetSection() const
Definition: DWARFUnit.h:153
virtual uint32_t getHeaderSize() const
Size in bytes of the unit header.
Definition: DWARFUnit.h:140
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, bool LE, const DWARFUnitSectionBase &UnitSection)
Definition: DWARFUnit.cpp:33
This class is the base class for all object file types.
Definition: ObjectFile.h:176
bool extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const
extractRangeList - extracts the range list referenced by this compile unit from .debug_ranges section...
Definition: DWARFUnit.cpp:101
uint32_t getNextUnitOffset() const
Definition: DWARFUnit.h:185
UnitVector::iterator iterator
Definition: DWARFUnit.h:72
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const
Definition: DWARFUnit.cpp:56
const DWARFAbbreviationDeclarationSet * getAbbreviations() const
Definition: DWARFUnit.h:188
uint32_t getLength() const
Definition: DWARFUnit.h:186
const char * getCompilationDir()
Definition: DWARFUnit.cpp:123
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
uint64_t getDWOId()
Definition: DWARFUnit.cpp:130
#define false
Definition: ConvertUTF.c:65
UnitType * getUnitForOffset(uint32_t Offset) const override
Returns the Unit that contains the given section offset in the same section this Unit originated from...
Definition: DWARFUnit.h:75
unsigned getNumDIEs()
Returns the number of DIEs in the unit.
Definition: DWARFUnit.h:218
llvm::SmallVectorImpl< std::unique_ptr< UnitType > > UnitVector
Definition: DWARFUnit.h:71
const DWARFDebugInfoEntryMinimal * getDIEAtIndex(unsigned Index) const
Return the DIE object at the given index.
Definition: DWARFUnit.h:236
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:355
void parse(DWARFContext &C, const DWARFSection &Section)
Definition: DWARFUnit.cpp:20
uint16_t getVersion() const
Definition: DWARFUnit.h:187
virtual DWARFUnit * getUnitForOffset(uint32_t Offset) const =0
Returns the Unit that contains the given section offset in the same section this Unit originated from...
DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
StringRef getStringSection() const
Definition: DWARFUnit.h:152
void setRangesSection(StringRef RS, uint32_t Base)
Definition: DWARFUnit.h:158
DIE - A structured debug information entry.
Definition: DIE.h:623
const DWARFUnitSectionBase & getUnitSection() const
getUnitSection - Return the DWARFUnitSection containing this unit.
Definition: DWARFUnit.h:214
DWARFUnitSection(DWARFUnitSection &&DUS)
Definition: DWARFUnit.h:68
uint32_t getDIEIndex(const DWARFDebugInfoEntryMinimal *DIE)
Return the index of a DIE inside the unit's DIE vector.
Definition: DWARFUnit.h:229
const RelocAddrMap * getRelocMap() const
Definition: DWARFUnit.h:174
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, bool isLittleEndian)=0
DataExtractor getStringExtractor() const
Definition: DWARFUnit.h:170
bool extract(DataExtractor debug_info, uint32_t *offset_ptr)
Definition: DWARFUnit.cpp:85
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
Concrete instance of DWARFUnitSection, specialized for one Unit type.
Definition: DWARFUnit.h:54
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:39
A range adaptor for a pair of iterators.
const DWARFDebugInfoEntryMinimal * getDIEForOffset(uint32_t Offset) const
Return the DIE object for a given offset inside the unit's DIE vector.
Definition: DWARFUnit.h:245
void parseDWO(DWARFContext &C, const DWARFSection &DWOSection)
Definition: DWARFUnit.cpp:26
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const
Definition: DWARFUnit.cpp:46
DWARFContext & getContext() const
Definition: DWARFUnit.h:150
DataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.h:167
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr)
Definition: DWARFUnit.cpp:68
uint32_t getOffset() const
Definition: DWARFUnit.h:184
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:191
Base class for all DWARFUnitSection classes.
Definition: DWARFUnit.h:35
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
const DWARFDebugInfoEntryMinimal * getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:198
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
llvm::iterator_range< typename UnitVector::iterator > iterator_range
Definition: DWARFUnit.h:73
void setAddrOffsetSection(StringRef AOS, uint32_t Base)
Definition: DWARFUnit.h:154
DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine DIEs, (possibly ending wit...