DWARFDie.h revision 321369
1321369Sdim//===- DWARFDie.h -----------------------------------------------*- C++ -*-===// 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 10321369Sdim#ifndef LLVM_DEBUGINFO_DWARFDIE_H 11321369Sdim#define LLVM_DEBUGINFO_DWARFDIE_H 12311116Sdim 13321369Sdim#include "llvm/ADT/ArrayRef.h" 14321369Sdim#include "llvm/ADT/Optional.h" 15311544Sdim#include "llvm/ADT/iterator.h" 16311544Sdim#include "llvm/ADT/iterator_range.h" 17321369Sdim#include "llvm/BinaryFormat/Dwarf.h" 18321369Sdim#include "llvm/DebugInfo/DIContext.h" 19321369Sdim#include "llvm/DebugInfo/DWARF/DWARFAttribute.h" 20311116Sdim#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" 21321369Sdim#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 22321369Sdim#include <cassert> 23321369Sdim#include <cstdint> 24321369Sdim#include <iterator> 25311116Sdim 26311116Sdimnamespace llvm { 27321369Sdim 28311116Sdimclass DWARFUnit; 29311116Sdimclass raw_ostream; 30321369Sdim 31311116Sdim//===----------------------------------------------------------------------===// 32311116Sdim/// Utility class that carries the DWARF compile/type unit and the debug info 33311116Sdim/// entry in an object. 34311116Sdim/// 35311116Sdim/// When accessing information from a debug info entry we always need to DWARF 36311116Sdim/// compile/type unit in order to extract the info correctly as some information 37311116Sdim/// is relative to the compile/type unit. Prior to this class the DWARFUnit and 38311116Sdim/// the DWARFDebugInfoEntry was passed around separately and there was the 39311116Sdim/// possibility for error if the wrong DWARFUnit was used to extract a unit 40311116Sdim/// relative offset. This class helps to ensure that this doesn't happen and 41311116Sdim/// also simplifies the attribute extraction calls by not having to specify the 42311116Sdim/// DWARFUnit for each call. 43311116Sdimclass DWARFDie { 44321369Sdim DWARFUnit *U = nullptr; 45321369Sdim const DWARFDebugInfoEntry *Die = nullptr; 46321369Sdim 47311116Sdimpublic: 48321369Sdim DWARFDie() = default; 49311116Sdim DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {} 50321369Sdim 51311116Sdim bool isValid() const { return U && Die; } 52311116Sdim explicit operator bool() const { return isValid(); } 53311116Sdim const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; } 54311116Sdim DWARFUnit *getDwarfUnit() const { return U; } 55311116Sdim 56311116Sdim /// Get the abbreviation declaration for this DIE. 57311116Sdim /// 58311116Sdim /// \returns the abbreviation declaration or NULL for null tags. 59311116Sdim const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const { 60311116Sdim assert(isValid() && "must check validity prior to calling"); 61311116Sdim return Die->getAbbreviationDeclarationPtr(); 62311116Sdim } 63311116Sdim 64311116Sdim /// Get the absolute offset into the debug info or types section. 65311116Sdim /// 66311116Sdim /// \returns the DIE offset or -1U if invalid. 67311116Sdim uint32_t getOffset() const { 68311116Sdim assert(isValid() && "must check validity prior to calling"); 69311116Sdim return Die->getOffset(); 70311116Sdim } 71321369Sdim 72311116Sdim dwarf::Tag getTag() const { 73311116Sdim auto AbbrevDecl = getAbbreviationDeclarationPtr(); 74311116Sdim if (AbbrevDecl) 75311116Sdim return AbbrevDecl->getTag(); 76311116Sdim return dwarf::DW_TAG_null; 77311116Sdim } 78311116Sdim 79311116Sdim bool hasChildren() const { 80311116Sdim assert(isValid() && "must check validity prior to calling"); 81311116Sdim return Die->hasChildren(); 82311116Sdim } 83321369Sdim 84311116Sdim /// Returns true for a valid DIE that terminates a sibling chain. 85311116Sdim bool isNULL() const { 86311116Sdim return getAbbreviationDeclarationPtr() == nullptr; 87311116Sdim } 88321369Sdim 89311116Sdim /// Returns true if DIE represents a subprogram (not inlined). 90311116Sdim bool isSubprogramDIE() const; 91311116Sdim 92311116Sdim /// Returns true if DIE represents a subprogram or an inlined subroutine. 93311116Sdim bool isSubroutineDIE() const; 94311116Sdim 95311116Sdim /// Get the parent of this DIE object. 96311116Sdim /// 97311116Sdim /// \returns a valid DWARFDie instance if this object has a parent or an 98311116Sdim /// invalid DWARFDie instance if it doesn't. 99311116Sdim DWARFDie getParent() const; 100321369Sdim 101311116Sdim /// Get the sibling of this DIE object. 102311116Sdim /// 103311116Sdim /// \returns a valid DWARFDie instance if this object has a sibling or an 104311116Sdim /// invalid DWARFDie instance if it doesn't. 105311116Sdim DWARFDie getSibling() const; 106321369Sdim 107311116Sdim /// Get the first child of this DIE object. 108311116Sdim /// 109311116Sdim /// \returns a valid DWARFDie instance if this object has children or an 110311116Sdim /// invalid DWARFDie instance if it doesn't. 111311116Sdim DWARFDie getFirstChild() const { 112311116Sdim if (isValid() && Die->hasChildren()) 113311116Sdim return DWARFDie(U, Die + 1); 114311116Sdim return DWARFDie(); 115311116Sdim } 116321369Sdim 117311116Sdim /// Dump the DIE and all of its attributes to the supplied stream. 118311116Sdim /// 119311116Sdim /// \param OS the stream to use for output. 120311116Sdim /// \param recurseDepth the depth to recurse to when dumping this DIE and its 121311116Sdim /// children. 122311116Sdim /// \param indent the number of characters to indent each line that is output. 123321369Sdim void dump(raw_ostream &OS, unsigned recurseDepth, unsigned indent = 0, 124321369Sdim DIDumpOptions DumpOpts = DIDumpOptions()) const; 125321369Sdim 126311116Sdim /// Extract the specified attribute from this DIE. 127311116Sdim /// 128311116Sdim /// Extract an attribute value from this DIE only. This call doesn't look 129311116Sdim /// for the attribute value in any DW_AT_specification or 130311116Sdim /// DW_AT_abstract_origin referenced DIEs. 131311116Sdim /// 132311116Sdim /// \param Attr the attribute to extract. 133311116Sdim /// \returns an optional DWARFFormValue that will have the form value if the 134311116Sdim /// attribute was successfully extracted. 135321369Sdim Optional<DWARFFormValue> find(dwarf::Attribute Attr) const; 136321369Sdim 137321369Sdim /// Extract the first value of any attribute in Attrs from this DIE. 138311116Sdim /// 139321369Sdim /// Extract the first attribute that matches from this DIE only. This call 140321369Sdim /// doesn't look for the attribute value in any DW_AT_specification or 141321369Sdim /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched 142321369Sdim /// linearly in the order they are specified within Attrs. 143311116Sdim /// 144321369Sdim /// \param Attrs an array of DWARF attribute to look for. 145321369Sdim /// \returns an optional that has a valid DWARFFormValue for the first 146321369Sdim /// matching attribute in Attrs, or None if none of the attributes in Attrs 147321369Sdim /// exist in this DIE. 148321369Sdim Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const; 149321369Sdim 150321369Sdim /// Extract the first value of any attribute in Attrs from this DIE and 151321369Sdim /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced 152321369Sdim /// DIEs. 153311116Sdim /// 154321369Sdim /// \param Attrs an array of DWARF attribute to look for. 155321369Sdim /// \returns an optional that has a valid DWARFFormValue for the first 156321369Sdim /// matching attribute in Attrs, or None if none of the attributes in Attrs 157321369Sdim /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin 158321369Sdim /// DIEs. 159321369Sdim Optional<DWARFFormValue> 160321369Sdim findRecursively(ArrayRef<dwarf::Attribute> Attrs) const; 161311116Sdim 162311116Sdim /// Extract the specified attribute from this DIE as the referenced DIE. 163311116Sdim /// 164311116Sdim /// Regardless of the reference type, return the correct DWARFDie instance if 165311116Sdim /// the attribute exists. The returned DWARFDie object might be from another 166311116Sdim /// DWARFUnit, but that is all encapsulated in the new DWARFDie object. 167311116Sdim /// 168311116Sdim /// Extract an attribute value from this DIE only. This call doesn't look 169311116Sdim /// for the attribute value in any DW_AT_specification or 170311116Sdim /// DW_AT_abstract_origin referenced DIEs. 171311116Sdim /// 172311116Sdim /// \param Attr the attribute to extract. 173311116Sdim /// \returns a valid DWARFDie instance if the attribute exists, or an invalid 174311116Sdim /// DWARFDie object if it doesn't. 175311116Sdim DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const; 176311116Sdim 177311116Sdim /// Extract the range base attribute from this DIE as absolute section offset. 178311116Sdim /// 179311116Sdim /// This is a utility function that checks for either the DW_AT_rnglists_base 180311116Sdim /// or DW_AT_GNU_ranges_base attribute. 181311116Sdim /// 182311116Sdim /// \returns anm optional absolute section offset value for the attribute. 183311116Sdim Optional<uint64_t> getRangesBaseAttribute() const; 184321369Sdim 185311116Sdim /// Get the DW_AT_high_pc attribute value as an address. 186311116Sdim /// 187311116Sdim /// In DWARF version 4 and later the high PC can be encoded as an offset from 188311116Sdim /// the DW_AT_low_pc. This function takes care of extracting the value as an 189311116Sdim /// address or offset and adds it to the low PC if needed and returns the 190311116Sdim /// value as an optional in case the DIE doesn't have a DW_AT_high_pc 191311116Sdim /// attribute. 192311116Sdim /// 193311116Sdim /// \param LowPC the low PC that might be needed to calculate the high PC. 194311116Sdim /// \returns an optional address value for the attribute. 195311116Sdim Optional<uint64_t> getHighPC(uint64_t LowPC) const; 196311116Sdim 197311116Sdim /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU. 198311116Sdim /// Returns true if both attributes are present. 199321369Sdim bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC, 200321369Sdim uint64_t &SectionIndex) const; 201321369Sdim 202311116Sdim /// Get the address ranges for this DIE. 203311116Sdim /// 204311116Sdim /// Get the hi/low PC range if both attributes are available or exrtracts the 205311116Sdim /// non-contiguous address ranges from the DW_AT_ranges attribute. 206311116Sdim /// 207311116Sdim /// Extracts the range information from this DIE only. This call doesn't look 208311116Sdim /// for the range in any DW_AT_specification or DW_AT_abstract_origin DIEs. 209311116Sdim /// 210311116Sdim /// \returns a address range vector that might be empty if no address range 211311116Sdim /// information is available. 212311116Sdim DWARFAddressRangesVector getAddressRanges() const; 213321369Sdim 214311116Sdim /// Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any 215311116Sdim /// of its children. 216311116Sdim /// 217311116Sdim /// Get the hi/low PC range if both attributes are available or exrtracts the 218311116Sdim /// non-contiguous address ranges from the DW_AT_ranges attribute for this DIE 219311116Sdim /// and all children. 220311116Sdim /// 221311116Sdim /// \param Ranges the addres range vector to fill in. 222311116Sdim void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const; 223321369Sdim 224311116Sdim bool addressRangeContainsAddress(const uint64_t Address) const; 225321369Sdim 226311116Sdim /// If a DIE represents a subprogram (or inlined subroutine), returns its 227311116Sdim /// mangled name (or short name, if mangled is missing). This name may be 228311116Sdim /// fetched from specification or abstract origin for this subprogram. 229311116Sdim /// Returns null if no name is found. 230311116Sdim const char *getSubroutineName(DINameKind Kind) const; 231321369Sdim 232311116Sdim /// Return the DIE name resolving DW_AT_sepcification or DW_AT_abstract_origin 233311116Sdim /// references if necessary. Returns null if no name is found. 234311116Sdim const char *getName(DINameKind Kind) const; 235321369Sdim 236321369Sdim /// Returns the declaration line (start line) for a DIE, assuming it specifies 237321369Sdim /// a subprogram. This may be fetched from specification or abstract origin 238321369Sdim /// for this subprogram by resolving DW_AT_sepcification or 239321369Sdim /// DW_AT_abstract_origin references if necessary. 240321369Sdim uint64_t getDeclLine() const; 241321369Sdim 242311116Sdim /// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column 243311116Sdim /// from DIE (or zeroes if they are missing). This function looks for 244311116Sdim /// DW_AT_call attributes in this DIE only, it will not resolve the attribute 245311116Sdim /// values in any DW_AT_specification or DW_AT_abstract_origin DIEs. 246311116Sdim /// \param CallFile filled in with non-zero if successful, zero if there is no 247311116Sdim /// DW_AT_call_file attribute in this DIE. 248311116Sdim /// \param CallLine filled in with non-zero if successful, zero if there is no 249311116Sdim /// DW_AT_call_line attribute in this DIE. 250311116Sdim /// \param CallColumn filled in with non-zero if successful, zero if there is 251311116Sdim /// no DW_AT_call_column attribute in this DIE. 252321369Sdim /// \param CallDiscriminator filled in with non-zero if successful, zero if 253321369Sdim /// there is no DW_AT_GNU_discriminator attribute in this DIE. 254311116Sdim void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, 255321369Sdim uint32_t &CallColumn, uint32_t &CallDiscriminator) const; 256311116Sdim 257321369Sdim class attribute_iterator; 258321369Sdim 259321369Sdim /// Get an iterator range to all attributes in the current DIE only. 260321369Sdim /// 261321369Sdim /// \returns an iterator range for the attributes of the current DIE. 262321369Sdim iterator_range<attribute_iterator> attributes() const; 263321369Sdim 264311544Sdim class iterator; 265321369Sdim 266311544Sdim iterator begin() const; 267311544Sdim iterator end() const; 268311544Sdim iterator_range<iterator> children() const; 269311116Sdim}; 270311116Sdim 271321369Sdimclass DWARFDie::attribute_iterator : 272321369Sdim public iterator_facade_base<attribute_iterator, std::forward_iterator_tag, 273321369Sdim const DWARFAttribute> { 274321369Sdim /// The DWARF DIE we are extracting attributes from. 275321369Sdim DWARFDie Die; 276321369Sdim /// The value vended to clients via the operator*() or operator->(). 277321369Sdim DWARFAttribute AttrValue; 278321369Sdim /// The attribute index within the abbreviation declaration in Die. 279321369Sdim uint32_t Index; 280321369Sdim 281321369Sdim /// Update the attribute index and attempt to read the attribute value. If the 282321369Sdim /// attribute is able to be read, update AttrValue and the Index member 283321369Sdim /// variable. If the attribute value is not able to be read, an appropriate 284321369Sdim /// error will be set if the Err member variable is non-NULL and the iterator 285321369Sdim /// will be set to the end value so iteration stops. 286321369Sdim void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I); 287321369Sdim 288321369Sdimpublic: 289321369Sdim attribute_iterator() = delete; 290321369Sdim explicit attribute_iterator(DWARFDie D, bool End); 291321369Sdim 292321369Sdim attribute_iterator &operator++(); 293321369Sdim explicit operator bool() const { return AttrValue.isValid(); } 294321369Sdim const DWARFAttribute &operator*() const { return AttrValue; } 295321369Sdim bool operator==(const attribute_iterator &X) const { return Index == X.Index; } 296321369Sdim}; 297321369Sdim 298311544Sdiminline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) { 299311544Sdim return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() && 300311544Sdim LHS.getDwarfUnit() == RHS.getDwarfUnit(); 301311544Sdim} 302311116Sdim 303311544Sdiminline bool operator!=(const DWARFDie &LHS, const DWARFDie &RHS) { 304311544Sdim return !(LHS == RHS); 305311544Sdim} 306311544Sdim 307311544Sdimclass DWARFDie::iterator : public iterator_facade_base<iterator, 308311544Sdim std::forward_iterator_tag, 309311544Sdim const DWARFDie> { 310311544Sdim DWARFDie Die; 311311544Sdim void skipNull() { 312311544Sdim if (Die && Die.isNULL()) 313311544Sdim Die = DWARFDie(); 314311544Sdim } 315311544Sdimpublic: 316311544Sdim iterator() = default; 317321369Sdim 318311544Sdim explicit iterator(DWARFDie D) : Die(D) { 319311544Sdim // If we start out with only a Null DIE then invalidate. 320311544Sdim skipNull(); 321311544Sdim } 322321369Sdim 323311544Sdim iterator &operator++() { 324311544Sdim Die = Die.getSibling(); 325311544Sdim // Don't include the NULL die when iterating. 326311544Sdim skipNull(); 327311544Sdim return *this; 328311544Sdim } 329321369Sdim 330311544Sdim explicit operator bool() const { return Die.isValid(); } 331311544Sdim const DWARFDie &operator*() const { return Die; } 332311544Sdim bool operator==(const iterator &X) const { return Die == X.Die; } 333311544Sdim}; 334311544Sdim 335311544Sdim// These inline functions must follow the DWARFDie::iterator definition above 336311544Sdim// as they use functions from that class. 337311544Sdiminline DWARFDie::iterator DWARFDie::begin() const { 338311544Sdim return iterator(getFirstChild()); 339311544Sdim} 340311544Sdim 341311544Sdiminline DWARFDie::iterator DWARFDie::end() const { 342311544Sdim return iterator(); 343311544Sdim} 344311544Sdim 345311544Sdiminline iterator_range<DWARFDie::iterator> DWARFDie::children() const { 346311544Sdim return make_range(begin(), end()); 347311544Sdim} 348311544Sdim 349311116Sdim} // end namespace llvm 350311116Sdim 351321369Sdim#endif // LLVM_DEBUGINFO_DWARFDIE_H 352