DWARFDie.h revision 311116
1311116Sdim//===-- DWARFDie.h --------------------------------------------------------===//
2311116Sdim//
3311116Sdim//                     The LLVM Compiler Infrastructure
4311116Sdim//
5311116Sdim// This file is distributed under the University of Illinois Open Source
6311116Sdim// License. See LICENSE.TXT for details.
7311116Sdim//
8311116Sdim//===----------------------------------------------------------------------===//
9311116Sdim
10311116Sdim#ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H
11311116Sdim#define LLVM_LIB_DEBUGINFO_DWARFDIE_H
12311116Sdim
13311116Sdim#include "llvm/ADT/Optional.h"
14311116Sdim#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
15311116Sdim
16311116Sdimnamespace llvm {
17311116Sdim
18311116Sdimclass DWARFUnit;
19311116Sdimclass DWARFDebugInfoEntry;
20311116Sdimclass raw_ostream;
21311116Sdim
22311116Sdim//===----------------------------------------------------------------------===//
23311116Sdim/// Utility class that carries the DWARF compile/type unit and the debug info
24311116Sdim/// entry in an object.
25311116Sdim///
26311116Sdim/// When accessing information from a debug info entry we always need to DWARF
27311116Sdim/// compile/type unit in order to extract the info correctly as some information
28311116Sdim/// is relative to the compile/type unit. Prior to this class the DWARFUnit and
29311116Sdim/// the DWARFDebugInfoEntry was passed around separately and there was the
30311116Sdim/// possibility for error if the wrong DWARFUnit was used to extract a unit
31311116Sdim/// relative offset. This class helps to ensure that this doesn't happen and
32311116Sdim/// also simplifies the attribute extraction calls by not having to specify the
33311116Sdim/// DWARFUnit for each call.
34311116Sdimclass DWARFDie {
35311116Sdim  DWARFUnit *U;
36311116Sdim  const DWARFDebugInfoEntry *Die;
37311116Sdimpublic:
38311116Sdim  DWARFDie() : U(nullptr), Die(nullptr) {}
39311116Sdim  DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {}
40311116Sdim
41311116Sdim  bool isValid() const { return U && Die; }
42311116Sdim  explicit operator bool() const { return isValid(); }
43311116Sdim  bool operator ==(const DWARFDie &RHS) const {
44311116Sdim    return Die == RHS.Die && U == RHS.U;
45311116Sdim  }
46311116Sdim  const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; }
47311116Sdim  DWARFUnit *getDwarfUnit() const { return U; }
48311116Sdim
49311116Sdim
50311116Sdim  /// Get the abbreviation declaration for this DIE.
51311116Sdim  ///
52311116Sdim  /// \returns the abbreviation declaration or NULL for null tags.
53311116Sdim  const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
54311116Sdim    assert(isValid() && "must check validity prior to calling");
55311116Sdim    return Die->getAbbreviationDeclarationPtr();
56311116Sdim  }
57311116Sdim
58311116Sdim  /// Get the absolute offset into the debug info or types section.
59311116Sdim  ///
60311116Sdim  /// \returns the DIE offset or -1U if invalid.
61311116Sdim  uint32_t getOffset() const {
62311116Sdim    assert(isValid() && "must check validity prior to calling");
63311116Sdim    return Die->getOffset();
64311116Sdim  }
65311116Sdim
66311116Sdim  dwarf::Tag getTag() const {
67311116Sdim    auto AbbrevDecl = getAbbreviationDeclarationPtr();
68311116Sdim    if (AbbrevDecl)
69311116Sdim      return AbbrevDecl->getTag();
70311116Sdim    return dwarf::DW_TAG_null;
71311116Sdim  }
72311116Sdim
73311116Sdim  bool hasChildren() const {
74311116Sdim    assert(isValid() && "must check validity prior to calling");
75311116Sdim    return Die->hasChildren();
76311116Sdim  }
77311116Sdim
78311116Sdim  /// Returns true for a valid DIE that terminates a sibling chain.
79311116Sdim  bool isNULL() const {
80311116Sdim    return getAbbreviationDeclarationPtr() == nullptr;
81311116Sdim  }
82311116Sdim  /// Returns true if DIE represents a subprogram (not inlined).
83311116Sdim  bool isSubprogramDIE() const;
84311116Sdim
85311116Sdim  /// Returns true if DIE represents a subprogram or an inlined subroutine.
86311116Sdim  bool isSubroutineDIE() const;
87311116Sdim
88311116Sdim  /// Get the parent of this DIE object.
89311116Sdim  ///
90311116Sdim  /// \returns a valid DWARFDie instance if this object has a parent or an
91311116Sdim  /// invalid DWARFDie instance if it doesn't.
92311116Sdim  DWARFDie getParent() const;
93311116Sdim
94311116Sdim  /// Get the sibling of this DIE object.
95311116Sdim  ///
96311116Sdim  /// \returns a valid DWARFDie instance if this object has a sibling or an
97311116Sdim  /// invalid DWARFDie instance if it doesn't.
98311116Sdim  DWARFDie getSibling() const;
99311116Sdim
100311116Sdim  /// Get the first child of this DIE object.
101311116Sdim  ///
102311116Sdim  /// \returns a valid DWARFDie instance if this object has children or an
103311116Sdim  /// invalid DWARFDie instance if it doesn't.
104311116Sdim  DWARFDie getFirstChild() const {
105311116Sdim    if (isValid() && Die->hasChildren())
106311116Sdim      return DWARFDie(U, Die + 1);
107311116Sdim    return DWARFDie();
108311116Sdim  }
109311116Sdim
110311116Sdim  /// Dump the DIE and all of its attributes to the supplied stream.
111311116Sdim  ///
112311116Sdim  /// \param OS the stream to use for output.
113311116Sdim  /// \param recurseDepth the depth to recurse to when dumping this DIE and its
114311116Sdim  /// children.
115311116Sdim  /// \param indent the number of characters to indent each line that is output.
116311116Sdim  void dump(raw_ostream &OS, unsigned recurseDepth, unsigned indent = 0) const;
117311116Sdim
118311116Sdim  /// Extract the specified attribute from this DIE.
119311116Sdim  ///
120311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
121311116Sdim  /// for the attribute value in any DW_AT_specification or
122311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
123311116Sdim  ///
124311116Sdim  /// \param Attr the attribute to extract.
125311116Sdim  /// \returns an optional DWARFFormValue that will have the form value if the
126311116Sdim  /// attribute was successfully extracted.
127311116Sdim  Optional<DWARFFormValue> getAttributeValue(dwarf::Attribute Attr) const;
128311116Sdim
129311116Sdim  /// Extract the specified attribute from this DIE as a C string.
130311116Sdim  ///
131311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
132311116Sdim  /// for the attribute value in any DW_AT_specification or
133311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
134311116Sdim  ///
135311116Sdim  /// \param Attr the attribute to extract.
136311116Sdim  /// \param FailValue the value to return if this DIE doesn't have this
137311116Sdim  /// attribute.
138311116Sdim  /// \returns the NULL terminated C string value owned by the DWARF section
139311116Sdim  /// that contains the string or FailValue if the attribute doesn't exist or
140311116Sdim  /// if the attribute's form isn't a form that describes an string.
141311116Sdim  const char *getAttributeValueAsString(dwarf::Attribute Attr,
142311116Sdim                                        const char *FailValue) const;
143311116Sdim
144311116Sdim  /// Extract the specified attribute from this DIE as an address.
145311116Sdim  ///
146311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
147311116Sdim  /// for the attribute value in any DW_AT_specification or
148311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
149311116Sdim  ///
150311116Sdim  /// \param Attr the attribute to extract.
151311116Sdim  /// \param FailValue the value to return if this DIE doesn't have this
152311116Sdim  /// attribute.
153311116Sdim  /// \returns the address value of the attribute or FailValue if the
154311116Sdim  /// attribute doesn't exist or if the attribute's form isn't a form that
155311116Sdim  /// describes an address.
156311116Sdim  uint64_t getAttributeValueAsAddress(dwarf::Attribute Attr,
157311116Sdim                                      uint64_t FailValue) const;
158311116Sdim
159311116Sdim  /// Extract the specified attribute from this DIE as an address.
160311116Sdim  ///
161311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
162311116Sdim  /// for the attribute value in any DW_AT_specification or
163311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
164311116Sdim  ///
165311116Sdim  /// \param Attr the attribute to extract.
166311116Sdim  /// \returns an optional value for the attribute.
167311116Sdim  Optional<uint64_t> getAttributeValueAsAddress(dwarf::Attribute Attr) const;
168311116Sdim
169311116Sdim  /// Extract the specified attribute from this DIE as a signed integer.
170311116Sdim  ///
171311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
172311116Sdim  /// for the attribute value in any DW_AT_specification or
173311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
174311116Sdim  ///
175311116Sdim  /// \param Attr the attribute to extract.
176311116Sdim  /// \param FailValue the value to return if this DIE doesn't have this
177311116Sdim  /// attribute.
178311116Sdim  /// \returns the signed integer constant value of the attribute or FailValue
179311116Sdim  /// if the attribute doesn't exist or if the attribute's form isn't a form
180311116Sdim  /// that describes a signed integer.
181311116Sdim  int64_t getAttributeValueAsSignedConstant(dwarf::Attribute Attr,
182311116Sdim                                            int64_t FailValue) const;
183311116Sdim
184311116Sdim  /// Extract the specified attribute from this DIE as a signed integer.
185311116Sdim  ///
186311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
187311116Sdim  /// for the attribute value in any DW_AT_specification or
188311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
189311116Sdim  ///
190311116Sdim  /// \param Attr the attribute to extract.
191311116Sdim  /// \returns an optional value for the attribute.
192311116Sdim  Optional<int64_t>
193311116Sdim  getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const;
194311116Sdim
195311116Sdim  /// Extract the specified attribute from this DIE as an unsigned integer.
196311116Sdim  ///
197311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
198311116Sdim  /// for the attribute value in any DW_AT_specification or
199311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
200311116Sdim  ///
201311116Sdim  /// \param Attr the attribute to extract.
202311116Sdim  /// \param FailValue the value to return if this DIE doesn't have this
203311116Sdim  /// attribute.
204311116Sdim  /// \returns the unsigned integer constant value of the attribute or FailValue
205311116Sdim  /// if the attribute doesn't exist or if the attribute's form isn't a form
206311116Sdim  /// that describes an unsigned integer.
207311116Sdim  uint64_t getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr,
208311116Sdim                                               uint64_t FailValue) const;
209311116Sdim
210311116Sdim  /// Extract the specified attribute from this DIE as an unsigned integer.
211311116Sdim  ///
212311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
213311116Sdim  /// for the attribute value in any DW_AT_specification or
214311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
215311116Sdim  ///
216311116Sdim  /// \param Attr the attribute to extract.
217311116Sdim  /// \returns an optional value for the attribute.
218311116Sdim  Optional<uint64_t>
219311116Sdim  getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const;
220311116Sdim
221311116Sdim  /// Extract the specified attribute from this DIE as absolute DIE Offset.
222311116Sdim  ///
223311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
224311116Sdim  /// for the attribute value in any DW_AT_specification or
225311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
226311116Sdim  ///
227311116Sdim  /// \param Attr the attribute to extract.
228311116Sdim  /// \param FailValue the value to return if this DIE doesn't have this
229311116Sdim  /// attribute.
230311116Sdim  /// \returns the unsigned integer constant value of the attribute or FailValue
231311116Sdim  /// if the attribute doesn't exist or if the attribute's form isn't a form
232311116Sdim  /// that describes a reference.
233311116Sdim  uint64_t getAttributeValueAsReference(dwarf::Attribute Attr,
234311116Sdim                                        uint64_t FailValue) const;
235311116Sdim
236311116Sdim  /// Extract the specified attribute from this DIE as absolute DIE Offset.
237311116Sdim  ///
238311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
239311116Sdim  /// for the attribute value in any DW_AT_specification or
240311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
241311116Sdim  ///
242311116Sdim  /// \param Attr the attribute to extract.
243311116Sdim  /// \returns an optional value for the attribute.
244311116Sdim  Optional<uint64_t> getAttributeValueAsReference(dwarf::Attribute Attr) const;
245311116Sdim
246311116Sdim  /// Extract the specified attribute from this DIE as absolute section offset.
247311116Sdim  ///
248311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
249311116Sdim  /// for the attribute value in any DW_AT_specification or
250311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
251311116Sdim  ///
252311116Sdim  /// \param Attr the attribute to extract.
253311116Sdim  /// \param FailValue the value to return if this DIE doesn't have this
254311116Sdim  /// attribute.
255311116Sdim  /// \returns the unsigned integer constant value of the attribute or FailValue
256311116Sdim  /// if the attribute doesn't exist or if the attribute's form isn't a form
257311116Sdim  /// that describes a section offset.
258311116Sdim  uint64_t getAttributeValueAsSectionOffset(dwarf::Attribute Attr,
259311116Sdim                                            uint64_t FailValue) const;
260311116Sdim  /// Extract the specified attribute from this DIE as absolute section offset.
261311116Sdim  ///
262311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
263311116Sdim  /// for the attribute value in any DW_AT_specification or
264311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
265311116Sdim  ///
266311116Sdim  /// \param Attr the attribute to extract.
267311116Sdim  /// \returns an optional value for the attribute.
268311116Sdim  Optional<uint64_t>
269311116Sdim  getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const;
270311116Sdim
271311116Sdim  /// Extract the specified attribute from this DIE as the referenced DIE.
272311116Sdim  ///
273311116Sdim  /// Regardless of the reference type, return the correct DWARFDie instance if
274311116Sdim  /// the attribute exists. The returned DWARFDie object might be from another
275311116Sdim  /// DWARFUnit, but that is all encapsulated in the new DWARFDie object.
276311116Sdim  ///
277311116Sdim  /// Extract an attribute value from this DIE only. This call doesn't look
278311116Sdim  /// for the attribute value in any DW_AT_specification or
279311116Sdim  /// DW_AT_abstract_origin referenced DIEs.
280311116Sdim  ///
281311116Sdim  /// \param Attr the attribute to extract.
282311116Sdim  /// \returns a valid DWARFDie instance if the attribute exists, or an invalid
283311116Sdim  /// DWARFDie object if it doesn't.
284311116Sdim  DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const;
285311116Sdim
286311116Sdim  /// Extract the range base attribute from this DIE as absolute section offset.
287311116Sdim  ///
288311116Sdim  /// This is a utility function that checks for either the DW_AT_rnglists_base
289311116Sdim  /// or DW_AT_GNU_ranges_base attribute.
290311116Sdim  ///
291311116Sdim  /// \returns anm optional absolute section offset value for the attribute.
292311116Sdim  Optional<uint64_t> getRangesBaseAttribute() const;
293311116Sdim
294311116Sdim  /// Get the DW_AT_high_pc attribute value as an address.
295311116Sdim  ///
296311116Sdim  /// In DWARF version 4 and later the high PC can be encoded as an offset from
297311116Sdim  /// the DW_AT_low_pc. This function takes care of extracting the value as an
298311116Sdim  /// address or offset and adds it to the low PC if needed and returns the
299311116Sdim  /// value as an optional in case the DIE doesn't have a DW_AT_high_pc
300311116Sdim  /// attribute.
301311116Sdim  ///
302311116Sdim  /// \param LowPC the low PC that might be needed to calculate the high PC.
303311116Sdim  /// \returns an optional address value for the attribute.
304311116Sdim  Optional<uint64_t> getHighPC(uint64_t LowPC) const;
305311116Sdim
306311116Sdim  /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
307311116Sdim  /// Returns true if both attributes are present.
308311116Sdim  bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const;
309311116Sdim
310311116Sdim  /// Get the address ranges for this DIE.
311311116Sdim  ///
312311116Sdim  /// Get the hi/low PC range if both attributes are available or exrtracts the
313311116Sdim  /// non-contiguous address ranges from the DW_AT_ranges attribute.
314311116Sdim  ///
315311116Sdim  /// Extracts the range information from this DIE only. This call doesn't look
316311116Sdim  /// for the range in any DW_AT_specification or DW_AT_abstract_origin DIEs.
317311116Sdim  ///
318311116Sdim  /// \returns a address range vector that might be empty if no address range
319311116Sdim  /// information is available.
320311116Sdim  DWARFAddressRangesVector getAddressRanges() const;
321311116Sdim
322311116Sdim  /// Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any
323311116Sdim  /// of its children.
324311116Sdim  ///
325311116Sdim  /// Get the hi/low PC range if both attributes are available or exrtracts the
326311116Sdim  /// non-contiguous address ranges from the DW_AT_ranges attribute for this DIE
327311116Sdim  /// and all children.
328311116Sdim  ///
329311116Sdim  /// \param Ranges the addres range vector to fill in.
330311116Sdim  void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const;
331311116Sdim
332311116Sdim  bool addressRangeContainsAddress(const uint64_t Address) const;
333311116Sdim
334311116Sdim  /// If a DIE represents a subprogram (or inlined subroutine), returns its
335311116Sdim  /// mangled name (or short name, if mangled is missing). This name may be
336311116Sdim  /// fetched from specification or abstract origin for this subprogram.
337311116Sdim  /// Returns null if no name is found.
338311116Sdim  const char *getSubroutineName(DINameKind Kind) const;
339311116Sdim
340311116Sdim  /// Return the DIE name resolving DW_AT_sepcification or DW_AT_abstract_origin
341311116Sdim  /// references if necessary. Returns null if no name is found.
342311116Sdim  const char *getName(DINameKind Kind) const;
343311116Sdim
344311116Sdim  /// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column
345311116Sdim  /// from DIE (or zeroes if they are missing). This function looks for
346311116Sdim  /// DW_AT_call attributes in this DIE only, it will not resolve the attribute
347311116Sdim  /// values in any DW_AT_specification or DW_AT_abstract_origin DIEs.
348311116Sdim  /// \param CallFile filled in with non-zero if successful, zero if there is no
349311116Sdim  /// DW_AT_call_file attribute in this DIE.
350311116Sdim  /// \param CallLine filled in with non-zero if successful, zero if there is no
351311116Sdim  /// DW_AT_call_line attribute in this DIE.
352311116Sdim  /// \param CallColumn filled in with non-zero if successful, zero if there is
353311116Sdim  /// no DW_AT_call_column attribute in this DIE.
354311116Sdim  void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
355311116Sdim                      uint32_t &CallColumn) const;
356311116Sdim
357311116Sdim  /// Get inlined chain for a given address, rooted at the current DIE.
358311116Sdim  /// Returns empty chain if address is not contained in address range
359311116Sdim  /// of current DIE.
360311116Sdim  void
361311116Sdim  getInlinedChainForAddress(const uint64_t Address,
362311116Sdim                            SmallVectorImpl<DWARFDie> &InlinedChain) const;
363311116Sdim
364311116Sdim};
365311116Sdim
366311116Sdim
367311116Sdim} // end namespace llvm
368311116Sdim
369311116Sdim#endif  // LLVM_LIB_DEBUGINFO_DWARFDIE_H
370