Home | History | Annotate | Download | only in DWARF
      1 //===- DWARFDie.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_DEBUGINFO_DWARFDIE_H
     11 #define LLVM_DEBUGINFO_DWARFDIE_H
     12 
     13 #include "llvm/ADT/ArrayRef.h"
     14 #include "llvm/ADT/Optional.h"
     15 #include "llvm/ADT/iterator.h"
     16 #include "llvm/ADT/iterator_range.h"
     17 #include "llvm/BinaryFormat/Dwarf.h"
     18 #include "llvm/DebugInfo/DIContext.h"
     19 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
     20 #include "llvm/DebugInfo/DWARF/DWARFAttribute.h"
     21 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
     22 #include <cassert>
     23 #include <cstdint>
     24 #include <iterator>
     25 
     26 namespace llvm {
     27 
     28 class DWARFUnit;
     29 class raw_ostream;
     30 
     31 //===----------------------------------------------------------------------===//
     32 /// Utility class that carries the DWARF compile/type unit and the debug info
     33 /// entry in an object.
     34 ///
     35 /// When accessing information from a debug info entry we always need to DWARF
     36 /// compile/type unit in order to extract the info correctly as some information
     37 /// is relative to the compile/type unit. Prior to this class the DWARFUnit and
     38 /// the DWARFDebugInfoEntry was passed around separately and there was the
     39 /// possibility for error if the wrong DWARFUnit was used to extract a unit
     40 /// relative offset. This class helps to ensure that this doesn't happen and
     41 /// also simplifies the attribute extraction calls by not having to specify the
     42 /// DWARFUnit for each call.
     43 class DWARFDie {
     44   DWARFUnit *U = nullptr;
     45   const DWARFDebugInfoEntry *Die = nullptr;
     46 
     47 public:
     48   DWARFDie() = default;
     49   DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry *D) : U(Unit), Die(D) {}
     50 
     51   bool isValid() const { return U && Die; }
     52   explicit operator bool() const { return isValid(); }
     53   const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; }
     54   DWARFUnit *getDwarfUnit() const { return U; }
     55 
     56   /// Get the abbreviation declaration for this DIE.
     57   ///
     58   /// \returns the abbreviation declaration or NULL for null tags.
     59   const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
     60     assert(isValid() && "must check validity prior to calling");
     61     return Die->getAbbreviationDeclarationPtr();
     62   }
     63 
     64   /// Get the absolute offset into the debug info or types section.
     65   ///
     66   /// \returns the DIE offset or -1U if invalid.
     67   uint32_t getOffset() const {
     68     assert(isValid() && "must check validity prior to calling");
     69     return Die->getOffset();
     70   }
     71 
     72   dwarf::Tag getTag() const {
     73     auto AbbrevDecl = getAbbreviationDeclarationPtr();
     74     if (AbbrevDecl)
     75       return AbbrevDecl->getTag();
     76     return dwarf::DW_TAG_null;
     77   }
     78 
     79   bool hasChildren() const {
     80     assert(isValid() && "must check validity prior to calling");
     81     return Die->hasChildren();
     82   }
     83 
     84   /// Returns true for a valid DIE that terminates a sibling chain.
     85   bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; }
     86 
     87   /// Returns true if DIE represents a subprogram (not inlined).
     88   bool isSubprogramDIE() const;
     89 
     90   /// Returns true if DIE represents a subprogram or an inlined subroutine.
     91   bool isSubroutineDIE() const;
     92 
     93   /// Get the parent of this DIE object.
     94   ///
     95   /// \returns a valid DWARFDie instance if this object has a parent or an
     96   /// invalid DWARFDie instance if it doesn't.
     97   DWARFDie getParent() const;
     98 
     99   /// Get the sibling of this DIE object.
    100   ///
    101   /// \returns a valid DWARFDie instance if this object has a sibling or an
    102   /// invalid DWARFDie instance if it doesn't.
    103   DWARFDie getSibling() const;
    104 
    105   /// Get the previous sibling of this DIE object.
    106   ///
    107   /// \returns a valid DWARFDie instance if this object has a sibling or an
    108   /// invalid DWARFDie instance if it doesn't.
    109   DWARFDie getPreviousSibling() const;
    110 
    111   /// Get the first child of this DIE object.
    112   ///
    113   /// \returns a valid DWARFDie instance if this object has children or an
    114   /// invalid DWARFDie instance if it doesn't.
    115   DWARFDie getFirstChild() const;
    116 
    117   /// Get the last child of this DIE object.
    118   ///
    119   /// \returns a valid null DWARFDie instance if this object has children or an
    120   /// invalid DWARFDie instance if it doesn't.
    121   DWARFDie getLastChild() const;
    122 
    123   /// Dump the DIE and all of its attributes to the supplied stream.
    124   ///
    125   /// \param OS the stream to use for output.
    126   /// \param indent the number of characters to indent each line that is output.
    127   void dump(raw_ostream &OS, unsigned indent = 0,
    128             DIDumpOptions DumpOpts = DIDumpOptions()) const;
    129 
    130   /// Convenience zero-argument overload for debugging.
    131   LLVM_DUMP_METHOD void dump() const;
    132 
    133   /// Extract the specified attribute from this DIE.
    134   ///
    135   /// Extract an attribute value from this DIE only. This call doesn't look
    136   /// for the attribute value in any DW_AT_specification or
    137   /// DW_AT_abstract_origin referenced DIEs.
    138   ///
    139   /// \param Attr the attribute to extract.
    140   /// \returns an optional DWARFFormValue that will have the form value if the
    141   /// attribute was successfully extracted.
    142   Optional<DWARFFormValue> find(dwarf::Attribute Attr) const;
    143 
    144   /// Extract the first value of any attribute in Attrs from this DIE.
    145   ///
    146   /// Extract the first attribute that matches from this DIE only. This call
    147   /// doesn't look for the attribute value in any DW_AT_specification or
    148   /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched
    149   /// linearly in the order they are specified within Attrs.
    150   ///
    151   /// \param Attrs an array of DWARF attribute to look for.
    152   /// \returns an optional that has a valid DWARFFormValue for the first
    153   /// matching attribute in Attrs, or None if none of the attributes in Attrs
    154   /// exist in this DIE.
    155   Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const;
    156 
    157   /// Extract the first value of any attribute in Attrs from this DIE and
    158   /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced
    159   /// DIEs.
    160   ///
    161   /// \param Attrs an array of DWARF attribute to look for.
    162   /// \returns an optional that has a valid DWARFFormValue for the first
    163   /// matching attribute in Attrs, or None if none of the attributes in Attrs
    164   /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin
    165   /// DIEs.
    166   Optional<DWARFFormValue>
    167   findRecursively(ArrayRef<dwarf::Attribute> Attrs) const;
    168 
    169   /// Extract the specified attribute from this DIE as the referenced DIE.
    170   ///
    171   /// Regardless of the reference type, return the correct DWARFDie instance if
    172   /// the attribute exists. The returned DWARFDie object might be from another
    173   /// DWARFUnit, but that is all encapsulated in the new DWARFDie object.
    174   ///
    175   /// Extract an attribute value from this DIE only. This call doesn't look
    176   /// for the attribute value in any DW_AT_specification or
    177   /// DW_AT_abstract_origin referenced DIEs.
    178   ///
    179   /// \param Attr the attribute to extract.
    180   /// \returns a valid DWARFDie instance if the attribute exists, or an invalid
    181   /// DWARFDie object if it doesn't.
    182   DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const;
    183 
    184   /// Extract the range base attribute from this DIE as absolute section offset.
    185   ///
    186   /// This is a utility function that checks for either the DW_AT_rnglists_base
    187   /// or DW_AT_GNU_ranges_base attribute.
    188   ///
    189   /// \returns anm optional absolute section offset value for the attribute.
    190   Optional<uint64_t> getRangesBaseAttribute() const;
    191 
    192   /// Get the DW_AT_high_pc attribute value as an address.
    193   ///
    194   /// In DWARF version 4 and later the high PC can be encoded as an offset from
    195   /// the DW_AT_low_pc. This function takes care of extracting the value as an
    196   /// address or offset and adds it to the low PC if needed and returns the
    197   /// value as an optional in case the DIE doesn't have a DW_AT_high_pc
    198   /// attribute.
    199   ///
    200   /// \param LowPC the low PC that might be needed to calculate the high PC.
    201   /// \returns an optional address value for the attribute.
    202   Optional<uint64_t> getHighPC(uint64_t LowPC) const;
    203 
    204   /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
    205   /// Returns true if both attributes are present.
    206   bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
    207                        uint64_t &SectionIndex) const;
    208 
    209   /// Get the address ranges for this DIE.
    210   ///
    211   /// Get the hi/low PC range if both attributes are available or exrtracts the
    212   /// non-contiguous address ranges from the DW_AT_ranges attribute.
    213   ///
    214   /// Extracts the range information from this DIE only. This call doesn't look
    215   /// for the range in any DW_AT_specification or DW_AT_abstract_origin DIEs.
    216   ///
    217   /// \returns a address range vector that might be empty if no address range
    218   /// information is available.
    219   Expected<DWARFAddressRangesVector> getAddressRanges() const;
    220 
    221   /// Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any
    222   /// of its children.
    223   ///
    224   /// Get the hi/low PC range if both attributes are available or exrtracts the
    225   /// non-contiguous address ranges from the DW_AT_ranges attribute for this DIE
    226   /// and all children.
    227   ///
    228   /// \param Ranges the addres range vector to fill in.
    229   void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const;
    230 
    231   bool addressRangeContainsAddress(const uint64_t Address) const;
    232 
    233   /// If a DIE represents a subprogram (or inlined subroutine), returns its
    234   /// mangled name (or short name, if mangled is missing). This name may be
    235   /// fetched from specification or abstract origin for this subprogram.
    236   /// Returns null if no name is found.
    237   const char *getSubroutineName(DINameKind Kind) const;
    238 
    239   /// Return the DIE name resolving DW_AT_sepcification or DW_AT_abstract_origin
    240   /// references if necessary. Returns null if no name is found.
    241   const char *getName(DINameKind Kind) const;
    242 
    243   /// Returns the declaration line (start line) for a DIE, assuming it specifies
    244   /// a subprogram. This may be fetched from specification or abstract origin
    245   /// for this subprogram by resolving DW_AT_sepcification or
    246   /// DW_AT_abstract_origin references if necessary.
    247   uint64_t getDeclLine() const;
    248 
    249   /// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column
    250   /// from DIE (or zeroes if they are missing). This function looks for
    251   /// DW_AT_call attributes in this DIE only, it will not resolve the attribute
    252   /// values in any DW_AT_specification or DW_AT_abstract_origin DIEs.
    253   /// \param CallFile filled in with non-zero if successful, zero if there is no
    254   /// DW_AT_call_file attribute in this DIE.
    255   /// \param CallLine filled in with non-zero if successful, zero if there is no
    256   /// DW_AT_call_line attribute in this DIE.
    257   /// \param CallColumn filled in with non-zero if successful, zero if there is
    258   /// no DW_AT_call_column attribute in this DIE.
    259   /// \param CallDiscriminator filled in with non-zero if successful, zero if
    260   /// there is no DW_AT_GNU_discriminator attribute in this DIE.
    261   void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
    262                       uint32_t &CallColumn, uint32_t &CallDiscriminator) const;
    263 
    264   class attribute_iterator;
    265 
    266   /// Get an iterator range to all attributes in the current DIE only.
    267   ///
    268   /// \returns an iterator range for the attributes of the current DIE.
    269   iterator_range<attribute_iterator> attributes() const;
    270 
    271   class iterator;
    272 
    273   iterator begin() const;
    274   iterator end() const;
    275 
    276   std::reverse_iterator<iterator> rbegin() const;
    277   std::reverse_iterator<iterator> rend() const;
    278 
    279   iterator_range<iterator> children() const;
    280 };
    281 
    282 class DWARFDie::attribute_iterator
    283     : public iterator_facade_base<attribute_iterator, std::forward_iterator_tag,
    284                                   const DWARFAttribute> {
    285   /// The DWARF DIE we are extracting attributes from.
    286   DWARFDie Die;
    287   /// The value vended to clients via the operator*() or operator->().
    288   DWARFAttribute AttrValue;
    289   /// The attribute index within the abbreviation declaration in Die.
    290   uint32_t Index;
    291 
    292   friend bool operator==(const attribute_iterator &LHS,
    293                          const attribute_iterator &RHS);
    294 
    295   /// Update the attribute index and attempt to read the attribute value. If the
    296   /// attribute is able to be read, update AttrValue and the Index member
    297   /// variable. If the attribute value is not able to be read, an appropriate
    298   /// error will be set if the Err member variable is non-NULL and the iterator
    299   /// will be set to the end value so iteration stops.
    300   void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I);
    301 
    302 public:
    303   attribute_iterator() = delete;
    304   explicit attribute_iterator(DWARFDie D, bool End);
    305 
    306   attribute_iterator &operator++();
    307   attribute_iterator &operator--();
    308   explicit operator bool() const { return AttrValue.isValid(); }
    309   const DWARFAttribute &operator*() const { return AttrValue; }
    310 };
    311 
    312 inline bool operator==(const DWARFDie::attribute_iterator &LHS,
    313                        const DWARFDie::attribute_iterator &RHS) {
    314   return LHS.Index == RHS.Index;
    315 }
    316 
    317 inline bool operator!=(const DWARFDie::attribute_iterator &LHS,
    318                        const DWARFDie::attribute_iterator &RHS) {
    319   return !(LHS == RHS);
    320 }
    321 
    322 inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) {
    323   return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() &&
    324          LHS.getDwarfUnit() == RHS.getDwarfUnit();
    325 }
    326 
    327 inline bool operator!=(const DWARFDie &LHS, const DWARFDie &RHS) {
    328   return !(LHS == RHS);
    329 }
    330 
    331 inline bool operator<(const DWARFDie &LHS, const DWARFDie &RHS) {
    332   return LHS.getOffset() < RHS.getOffset();
    333 }
    334 
    335 class DWARFDie::iterator
    336     : public iterator_facade_base<iterator, std::bidirectional_iterator_tag,
    337                                   const DWARFDie> {
    338   DWARFDie Die;
    339 
    340   friend std::reverse_iterator<llvm::DWARFDie::iterator>;
    341   friend bool operator==(const DWARFDie::iterator &LHS,
    342                          const DWARFDie::iterator &RHS);
    343 
    344 public:
    345   iterator() = default;
    346 
    347   explicit iterator(DWARFDie D) : Die(D) {}
    348 
    349   iterator &operator++() {
    350     Die = Die.getSibling();
    351     return *this;
    352   }
    353 
    354   iterator &operator--() {
    355     Die = Die.getPreviousSibling();
    356     return *this;
    357   }
    358 
    359   const DWARFDie &operator*() const { return Die; }
    360 };
    361 
    362 inline bool operator==(const DWARFDie::iterator &LHS,
    363                        const DWARFDie::iterator &RHS) {
    364   return LHS.Die == RHS.Die;
    365 }
    366 
    367 inline bool operator!=(const DWARFDie::iterator &LHS,
    368                        const DWARFDie::iterator &RHS) {
    369   return !(LHS == RHS);
    370 }
    371 
    372 // These inline functions must follow the DWARFDie::iterator definition above
    373 // as they use functions from that class.
    374 inline DWARFDie::iterator DWARFDie::begin() const {
    375   return iterator(getFirstChild());
    376 }
    377 
    378 inline DWARFDie::iterator DWARFDie::end() const {
    379   return iterator(getLastChild());
    380 }
    381 
    382 inline iterator_range<DWARFDie::iterator> DWARFDie::children() const {
    383   return make_range(begin(), end());
    384 }
    385 
    386 } // end namespace llvm
    387 
    388 namespace std {
    389 
    390 template <>
    391 class reverse_iterator<llvm::DWARFDie::iterator>
    392     : public llvm::iterator_facade_base<
    393           reverse_iterator<llvm::DWARFDie::iterator>,
    394           bidirectional_iterator_tag, const llvm::DWARFDie> {
    395 
    396 private:
    397   llvm::DWARFDie Die;
    398   bool AtEnd;
    399 
    400 public:
    401   reverse_iterator(llvm::DWARFDie::iterator It)
    402       : Die(It.Die), AtEnd(!It.Die.getPreviousSibling()) {
    403     if (!AtEnd)
    404       Die = Die.getPreviousSibling();
    405   }
    406 
    407   reverse_iterator<llvm::DWARFDie::iterator> &operator++() {
    408     assert(!AtEnd && "Incrementing rend");
    409     llvm::DWARFDie D = Die.getPreviousSibling();
    410     if (D)
    411       Die = D;
    412     else
    413       AtEnd = true;
    414     return *this;
    415   }
    416 
    417   reverse_iterator<llvm::DWARFDie::iterator> &operator--() {
    418     if (AtEnd) {
    419       AtEnd = false;
    420       return *this;
    421     }
    422     Die = Die.getSibling();
    423     assert(!Die.isNULL() && "Decrementing rbegin");
    424     return *this;
    425   }
    426 
    427   const llvm::DWARFDie &operator*() const {
    428     assert(Die.isValid());
    429     return Die;
    430   }
    431 
    432   // FIXME: We should be able to specify the equals operator as a friend, but
    433   //        that causes the compiler to think the operator overload is ambiguous
    434   //        with the friend declaration and the actual definition as candidates.
    435   bool equals(const reverse_iterator<llvm::DWARFDie::iterator> &RHS) const {
    436     return Die == RHS.Die && AtEnd == RHS.AtEnd;
    437   }
    438 };
    439 
    440 } // namespace std
    441 
    442 namespace llvm {
    443 
    444 inline bool operator==(const std::reverse_iterator<DWARFDie::iterator> &LHS,
    445                        const std::reverse_iterator<DWARFDie::iterator> &RHS) {
    446   return LHS.equals(RHS);
    447 }
    448 
    449 inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS,
    450                        const std::reverse_iterator<DWARFDie::iterator> &RHS) {
    451   return !(LHS == RHS);
    452 }
    453 
    454 inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rbegin() const {
    455   return llvm::make_reverse_iterator(end());
    456 }
    457 
    458 inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rend() const {
    459   return llvm::make_reverse_iterator(begin());
    460 }
    461 
    462 } // end namespace llvm
    463 
    464 #endif // LLVM_DEBUGINFO_DWARFDIE_H
    465