LLVM  4.0.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/Optional.h"
15 #include "llvm/ADT/STLExtras.h"
23 #include <vector>
24 
25 namespace llvm {
26 
27 namespace object {
28 class ObjectFile;
29 }
30 
31 class DWARFContext;
32 class DWARFDebugAbbrev;
33 class DWARFUnit;
34 class StringRef;
35 class raw_ostream;
36 
37 /// Base class for all DWARFUnitSection classes. This provides the
38 /// functionality common to all unit types.
40 public:
41  /// Returns the Unit that contains the given section offset in the
42  /// same section this Unit originated from.
43  virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
44 
45  void parse(DWARFContext &C, const DWARFSection &Section);
46  void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
47  DWARFUnitIndex *Index = nullptr);
48 
49 protected:
50  virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
51  const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
52  StringRef SOS, StringRef AOS, StringRef LS,
53  bool isLittleEndian, bool isDWO) = 0;
54 
55  ~DWARFUnitSectionBase() = default;
56 };
57 
60 
61 /// Concrete instance of DWARFUnitSection, specialized for one Unit type.
62 template<typename UnitType>
63 class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
64  public DWARFUnitSectionBase {
65  bool Parsed = false;
66 
67 public:
69  typedef typename UnitVector::iterator iterator;
71 
72  UnitType *getUnitForOffset(uint32_t Offset) const override {
73  auto *CU = std::upper_bound(
74  this->begin(), this->end(), Offset,
75  [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
76  return LHS < RHS->getNextUnitOffset();
77  });
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, StringRef LS, bool LE,
87  bool IsDWO) override {
88  if (Parsed)
89  return;
90  const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
91  DataExtractor Data(Section.Data, LE, 0);
92  uint32_t Offset = 0;
93  while (Data.isValidOffset(Offset)) {
94  auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
95  AOS, LS, LE, IsDWO, *this,
96  Index.getFromOffset(Offset));
97  if (!U->extract(Data, &Offset))
98  break;
99  this->push_back(std::move(U));
100  Offset = this->back()->getNextUnitOffset();
101  }
102  Parsed = true;
103  }
104 };
105 
106 class DWARFUnit {
107  DWARFContext &Context;
108  // Section containing this DWARFUnit.
109  const DWARFSection &InfoSection;
110 
111  const DWARFDebugAbbrev *Abbrev;
112  StringRef RangeSection;
113  uint32_t RangeSectionBase;
114  StringRef LineSection;
115  StringRef StringSection;
116  StringRef StringOffsetSection;
117  StringRef AddrOffsetSection;
118  uint32_t AddrOffsetSectionBase;
119  bool isLittleEndian;
120  bool isDWO;
121  const DWARFUnitSectionBase &UnitSection;
122 
123  uint32_t Offset;
124  uint32_t Length;
125  uint16_t Version;
126  const DWARFAbbreviationDeclarationSet *Abbrevs;
127  uint8_t AddrSize;
128  uint64_t BaseAddr;
129  // The compile unit debug information entry items.
130  std::vector<DWARFDebugInfoEntry> DieArray;
133 
134  class DWOHolder {
136  std::unique_ptr<DWARFContext> DWOContext;
137  DWARFUnit *DWOU;
138  public:
139  DWOHolder(StringRef DWOPath);
140  DWARFUnit *getUnit() const { return DWOU; }
141  };
142  std::unique_ptr<DWOHolder> DWO;
143 
144  const DWARFUnitIndex::Entry *IndexEntry;
145 
146  uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
147  auto First = DieArray.data();
148  assert(Die >= First && Die < First + DieArray.size());
149  return Die - First;
150  }
151 
152 protected:
153  virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
154  /// Size in bytes of the unit header.
155  virtual uint32_t getHeaderSize() const { return 11; }
156 
157 public:
158  DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
159  const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
160  StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
161  const DWARFUnitSectionBase &UnitSection,
162  const DWARFUnitIndex::Entry *IndexEntry = nullptr);
163 
164  virtual ~DWARFUnit();
165 
166  DWARFContext& getContext() const { return Context; }
167 
168  StringRef getLineSection() const { return LineSection; }
169  StringRef getStringSection() const { return StringSection; }
170  StringRef getStringOffsetSection() const { return StringOffsetSection; }
172  AddrOffsetSection = AOS;
173  AddrOffsetSectionBase = Base;
174  }
176  RangeSection = RS;
177  RangeSectionBase = Base;
178  }
179 
180  bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
181  // FIXME: Result should be uint64_t in DWARF64.
182  bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
183 
185  return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
186  }
188  return DataExtractor(StringSection, false, 0);
189  }
190 
191  const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
192 
193  bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
194 
195  /// extractRangeList - extracts the range list referenced by this compile
196  /// unit from .debug_ranges section. Returns true on success.
197  /// Requires that compile unit is already extracted.
198  bool extractRangeList(uint32_t RangeListOffset,
199  DWARFDebugRangeList &RangeList) const;
200  void clear();
201  uint32_t getOffset() const { return Offset; }
202  uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
203  uint32_t getLength() const { return Length; }
204  uint16_t getVersion() const { return Version; }
206  return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64.
207  }
209  return Abbrevs;
210  }
211  uint8_t getAddressByteSize() const { return AddrSize; }
212  uint8_t getRefAddrByteSize() const {
213  if (Version == 2)
214  return AddrSize;
215  return getDwarfOffsetByteSize();
216  }
217  uint8_t getDwarfOffsetByteSize() const {
219  return 8;
220  return 4;
221  }
222  uint64_t getBaseAddress() const { return BaseAddr; }
223 
224  void setBaseAddress(uint64_t base_addr) {
225  BaseAddr = base_addr;
226  }
227 
228  DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
229  extractDIEsIfNeeded(ExtractUnitDIEOnly);
230  if (DieArray.empty())
231  return DWARFDie();
232  return DWARFDie(this, &DieArray[0]);
233  }
234 
235  const char *getCompilationDir();
237 
239 
240  /// getInlinedChainForAddress - fetches inlined chain for a given address.
241  /// Returns empty chain if there is no subprogram containing address. The
242  /// chain is valid as long as parsed compile unit DIEs are not cleared.
243  void getInlinedChainForAddress(uint64_t Address,
244  SmallVectorImpl<DWARFDie> &InlinedChain);
245 
246  /// getUnitSection - Return the DWARFUnitSection containing this unit.
247  const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
248 
249  /// \brief Returns the number of DIEs in the unit. Parses the unit
250  /// if necessary.
251  unsigned getNumDIEs() {
252  extractDIEsIfNeeded(false);
253  return DieArray.size();
254  }
255 
256  /// \brief Return the index of a DIE inside the unit's DIE vector.
257  ///
258  /// It is illegal to call this method with a DIE that hasn't be
259  /// created by this unit. In other word, it's illegal to call this
260  /// method on a DIE that isn't accessible by following
261  /// children/sibling links starting from this unit's getUnitDIE().
263  return getDIEIndex(D.getDebugInfoEntry());
264  }
265 
266  /// \brief Return the DIE object at the given index.
267  DWARFDie getDIEAtIndex(unsigned Index) {
268  assert(Index < DieArray.size());
269  return DWARFDie(this, &DieArray[Index]);
270  }
271 
274 
275  /// \brief Return the DIE object for a given offset inside the
276  /// unit's DIE vector.
277  ///
278  /// The unit needs to have its DIEs extracted for this method to work.
280  extractDIEsIfNeeded(false);
281  assert(!DieArray.empty());
282  auto it = std::lower_bound(
283  DieArray.begin(), DieArray.end(), Offset,
284  [](const DWARFDebugInfoEntry &LHS, uint32_t Offset) {
285  return LHS.getOffset() < Offset;
286  });
287  if (it == DieArray.end())
288  return DWARFDie();
289  return DWARFDie(this, &*it);
290  }
291 
293  if (IndexEntry)
294  if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
295  return Contrib->Offset;
296  return 0;
297  }
298 
300  extractDIEsIfNeeded(false);
301  return die_iterator_range(DieArray.begin(), DieArray.end());
302  }
303 
304 private:
305  /// Size in bytes of the .debug_info data associated with this compile unit.
306  size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
307 
308  /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
309  /// hasn't already been done. Returns the number of DIEs parsed at this call.
310  size_t extractDIEsIfNeeded(bool CUDieOnly);
311  /// extractDIEsToVector - Appends all parsed DIEs to a vector.
312  void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
313  std::vector<DWARFDebugInfoEntry> &DIEs) const;
314  /// clearDIEs - Clear parsed DIEs to keep memory usage low.
315  void clearDIEs(bool KeepCUDie);
316 
317  /// parseDWO - Parses .dwo file for current compile unit. Returns true if
318  /// it was actually constructed.
319  bool parseDWO();
320 
321  /// getSubprogramForAddress - Returns subprogram DIE with address range
322  /// encompassing the provided address. The pointer is alive as long as parsed
323  /// compile unit DIEs are not cleared.
324  DWARFDie getSubprogramForAddress(uint64_t Address);
325 };
326 
327 }
328 
329 #endif
void push_back(const T &Elt)
Definition: SmallVector.h:211
uint8_t getDwarfOffsetByteSize() const
Definition: DWARFUnit.h:217
LLVMContext & Context
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const
Definition: DWARFUnit.cpp:65
void setBaseAddress(uint64_t base_addr)
Definition: DWARFUnit.h:224
virtual ~DWARFUnit()
uint64_t getBaseAddress() const
Definition: DWARFUnit.h:222
std::vector< std::pair< uint64_t, uint64_t > > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
RelocAddrMap Relocs
Definition: DWARFSection.h:20
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
StringRef getStringOffsetSection() const
Definition: DWARFUnit.h:170
virtual uint32_t getHeaderSize() const
Size in bytes of the unit header.
Definition: DWARFUnit.h:155
This class is the base class for all object file types.
Definition: ObjectFile.h:178
uint32_t getNextUnitOffset() const
Definition: DWARFUnit.h:202
const DWARFDebugInfoEntry * getDebugInfoEntry() const
Definition: DWARFDie.h:45
uint8_t getRefAddrByteSize() const
Definition: DWARFUnit.h:212
UnitVector::iterator iterator
Definition: DWARFUnit.h:69
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr)
Definition: DWARFUnit.cpp:87
const DWARFAbbreviationDeclarationSet * getAbbreviations() const
Definition: DWARFUnit.h:208
uint32_t getLength() const
Definition: DWARFUnit.h:203
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
DWARFDie getSibling(const DWARFDebugInfoEntry *Die)
Definition: DWARFUnit.cpp:404
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:72
unsigned getNumDIEs()
Returns the number of DIEs in the unit.
Definition: DWARFUnit.h:251
llvm::SmallVectorImpl< std::unique_ptr< UnitType > > UnitVector
Definition: DWARFUnit.h:68
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
Definition: DWARFUnit.cpp:385
uint16_t getVersion() const
Definition: DWARFUnit.h:204
void collectAddressRanges(DWARFAddressRangesVector &CURanges)
Definition: DWARFUnit.cpp:311
dwarf::DwarfFormat getFormat() const
Definition: DWARFUnit.h:205
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...
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry=nullptr)
Definition: DWARFUnit.cpp:46
die_iterator_range dies()
Definition: DWARFUnit.h:299
void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, DWARFUnitIndex *Index=nullptr)
Definition: DWARFUnit.cpp:37
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
Definition: DWARFDie.h:36
StringRef getStringSection() const
Definition: DWARFUnit.h:169
void setRangesSection(StringRef RS, uint32_t Base)
Definition: DWARFUnit.h:175
DWARFSectionKind
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:440
const DWARFUnitSectionBase & getUnitSection() const
getUnitSection - Return the DWARFUnitSection containing this unit.
Definition: DWARFUnit.h:247
uint32_t Offset
StringRef getLineSection() const
Definition: DWARFUnit.h:168
uint32_t getDIEIndex(const DWARFDie &D)
Return the index of a DIE inside the unit's DIE vector.
Definition: DWARFUnit.h:262
const char * getCompilationDir()
Definition: DWARFUnit.cpp:153
const DWARFUnitIndex & getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind)
Definition: DWARFUnit.cpp:377
const RelocAddrMap * getRelocMap() const
Definition: DWARFUnit.h:191
DataExtractor getStringExtractor() const
Definition: DWARFUnit.h:187
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:228
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Concrete instance of DWARFUnitSection, specialized for one Unit type.
Definition: DWARFUnit.h:63
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:52
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:131
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
A range adaptor for a pair of iterators.
isDWO(IsDWO)
bool extract(DataExtractor debug_info, uint32_t *offset_ptr)
Definition: DWARFUnit.cpp:115
DWARFContext & getContext() const
Definition: DWARFUnit.h:166
DataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.h:184
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
DWARFDie getDIEAtIndex(unsigned Index)
Return the DIE object at the given index.
Definition: DWARFUnit.h:267
const SectionContribution * getOffset(DWARFSectionKind Sec) const
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:358
Optional< uint64_t > getDWOId()
Definition: DWARFUnit.cpp:157
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const
Definition: DWARFUnit.cpp:75
uint32_t getOffset() const
Definition: DWARFUnit.h:201
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:211
uint32_t getLineTableOffset() const
Definition: DWARFUnit.h:292
const unsigned Kind
DWARFDie getDIEForOffset(uint32_t Offset)
Return the DIE object for a given offset inside the unit's DIE vector.
Definition: DWARFUnit.h:279
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Base class for all DWARFUnitSection classes.
Definition: DWARFUnit.h:39
DWARFDebugInfoEntry - A DIE with only the minimum required data.
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool isLittleEndian, bool isDWO)=0
void parse(DWARFContext &C, const DWARFSection &Section)
Definition: DWARFUnit.cpp:31
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
isLittleEndian(LE)
llvm::iterator_range< typename UnitVector::iterator > iterator_range
Definition: DWARFUnit.h:70
void setAddrOffsetSection(StringRef AOS, uint32_t Base)
Definition: DWARFUnit.h:171