Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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