Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- DWARFAbbreviationDeclaration.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_DWARFABBREVIATIONDECLARATION_H
  10. #define LLVM_DEBUGINFO_DWARF_DWARFABBREVIATIONDECLARATION_H
  11.  
  12. #include "llvm/ADT/SmallVector.h"
  13. #include "llvm/ADT/iterator_range.h"
  14. #include "llvm/BinaryFormat/Dwarf.h"
  15. #include <cassert>
  16. #include <cstddef>
  17. #include <cstdint>
  18.  
  19. namespace llvm {
  20.  
  21. class DataExtractor;
  22. class DWARFFormValue;
  23. class DWARFUnit;
  24. class raw_ostream;
  25.  
  26. class DWARFAbbreviationDeclaration {
  27. public:
  28.   struct AttributeSpec {
  29.     AttributeSpec(dwarf::Attribute A, dwarf::Form F, int64_t Value)
  30.         : Attr(A), Form(F), Value(Value) {
  31.       assert(isImplicitConst());
  32.     }
  33.     AttributeSpec(dwarf::Attribute A, dwarf::Form F,
  34.                   std::optional<uint8_t> ByteSize)
  35.         : Attr(A), Form(F) {
  36.       assert(!isImplicitConst());
  37.       this->ByteSize.HasByteSize = ByteSize.has_value();
  38.       if (this->ByteSize.HasByteSize)
  39.         this->ByteSize.ByteSize = *ByteSize;
  40.     }
  41.  
  42.     dwarf::Attribute Attr;
  43.     dwarf::Form Form;
  44.  
  45.   private:
  46.     /// The following field is used for ByteSize for non-implicit_const
  47.     /// attributes and as value for implicit_const ones, indicated by
  48.     /// Form == DW_FORM_implicit_const.
  49.     /// The following cases are distinguished:
  50.     /// * Form != DW_FORM_implicit_const and HasByteSize is true:
  51.     ///     ByteSize contains the fixed size in bytes for the Form in this
  52.     ///     object.
  53.     /// * Form != DW_FORM_implicit_const and HasByteSize is false:
  54.     ///     byte size of Form either varies according to the DWARFUnit
  55.     ///     that it is contained in or the value size varies and must be
  56.     ///     decoded from the debug information in order to determine its size.
  57.     /// * Form == DW_FORM_implicit_const:
  58.     ///     Value contains value for the implicit_const attribute.
  59.     struct ByteSizeStorage {
  60.       bool HasByteSize;
  61.       uint8_t ByteSize;
  62.     };
  63.     union {
  64.       ByteSizeStorage ByteSize;
  65.       int64_t Value;
  66.     };
  67.  
  68.   public:
  69.     bool isImplicitConst() const {
  70.       return Form == dwarf::DW_FORM_implicit_const;
  71.     }
  72.  
  73.     int64_t getImplicitConstValue() const {
  74.       assert(isImplicitConst());
  75.       return Value;
  76.     }
  77.  
  78.     /// Get the fixed byte size of this Form if possible. This function might
  79.     /// use the DWARFUnit to calculate the size of the Form, like for
  80.     /// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for
  81.     /// the ByteSize member.
  82.     std::optional<int64_t> getByteSize(const DWARFUnit &U) const;
  83.   };
  84.   using AttributeSpecVector = SmallVector<AttributeSpec, 8>;
  85.  
  86.   DWARFAbbreviationDeclaration();
  87.  
  88.   uint32_t getCode() const { return Code; }
  89.   uint8_t getCodeByteSize() const { return CodeByteSize; }
  90.   dwarf::Tag getTag() const { return Tag; }
  91.   bool hasChildren() const { return HasChildren; }
  92.  
  93.   using attr_iterator_range =
  94.       iterator_range<AttributeSpecVector::const_iterator>;
  95.  
  96.   attr_iterator_range attributes() const {
  97.     return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end());
  98.   }
  99.  
  100.   dwarf::Form getFormByIndex(uint32_t idx) const {
  101.     assert(idx < AttributeSpecs.size());
  102.     return AttributeSpecs[idx].Form;
  103.   }
  104.  
  105.   size_t getNumAttributes() const {
  106.     return AttributeSpecs.size();
  107.   }
  108.  
  109.   dwarf::Attribute getAttrByIndex(uint32_t idx) const {
  110.     assert(idx < AttributeSpecs.size());
  111.     return AttributeSpecs[idx].Attr;
  112.   }
  113.  
  114.   bool getAttrIsImplicitConstByIndex(uint32_t idx) const {
  115.     assert(idx < AttributeSpecs.size());
  116.     return AttributeSpecs[idx].isImplicitConst();
  117.   }
  118.  
  119.   int64_t getAttrImplicitConstValueByIndex(uint32_t idx) const {
  120.     assert(idx < AttributeSpecs.size());
  121.     return AttributeSpecs[idx].getImplicitConstValue();
  122.   }
  123.  
  124.   /// Get the index of the specified attribute.
  125.   ///
  126.   /// Searches the this abbreviation declaration for the index of the specified
  127.   /// attribute.
  128.   ///
  129.   /// \param attr DWARF attribute to search for.
  130.   /// \returns Optional index of the attribute if found, std::nullopt otherwise.
  131.   std::optional<uint32_t> findAttributeIndex(dwarf::Attribute attr) const;
  132.  
  133.   /// Extract a DWARF form value from a DIE specified by DIE offset.
  134.   ///
  135.   /// Extract an attribute value for a DWARFUnit given the DIE offset and the
  136.   /// attribute.
  137.   ///
  138.   /// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
  139.   /// code in the .debug_info data.
  140.   /// \param Attr DWARF attribute to search for.
  141.   /// \param U the DWARFUnit the contains the DIE.
  142.   /// \returns Optional DWARF form value if the attribute was extracted.
  143.   std::optional<DWARFFormValue> getAttributeValue(const uint64_t DIEOffset,
  144.                                                   const dwarf::Attribute Attr,
  145.                                                   const DWARFUnit &U) const;
  146.  
  147.   /// Compute an offset from a DIE specified by DIE offset and attribute index.
  148.   ///
  149.   /// \param AttrIndex an index of DWARF attribute.
  150.   /// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
  151.   /// code in the .debug_info data.
  152.   /// \param U the DWARFUnit the contains the DIE.
  153.   /// \returns an offset of the attribute.
  154.   uint64_t getAttributeOffsetFromIndex(uint32_t AttrIndex, uint64_t DIEOffset,
  155.                                        const DWARFUnit &U) const;
  156.  
  157.   /// Extract a DWARF form value from a DIE speccified by attribute index and
  158.   /// its offset.
  159.   ///
  160.   /// \param AttrIndex an index of DWARF attribute.
  161.   /// \param Offset offset of the attribute.
  162.   /// \param U the DWARFUnit the contains the DIE.
  163.   /// \returns Optional DWARF form value if the attribute was extracted.
  164.   std::optional<DWARFFormValue>
  165.   getAttributeValueFromOffset(uint32_t AttrIndex, uint64_t Offset,
  166.                               const DWARFUnit &U) const;
  167.  
  168.   bool extract(DataExtractor Data, uint64_t* OffsetPtr);
  169.   void dump(raw_ostream &OS) const;
  170.  
  171.   // Return an optional byte size of all attribute data in this abbreviation
  172.   // if a constant byte size can be calculated given a DWARFUnit. This allows
  173.   // DWARF parsing to be faster as many DWARF DIEs have a fixed byte size.
  174.   std::optional<size_t> getFixedAttributesByteSize(const DWARFUnit &U) const;
  175.  
  176. private:
  177.   void clear();
  178.  
  179.   /// A helper structure that can quickly determine the size in bytes of an
  180.   /// abbreviation declaration.
  181.   struct FixedSizeInfo {
  182.     /// The fixed byte size for fixed size forms.
  183.     uint16_t NumBytes = 0;
  184.     /// Number of DW_FORM_address forms in this abbrevation declaration.
  185.     uint8_t NumAddrs = 0;
  186.     /// Number of DW_FORM_ref_addr forms in this abbrevation declaration.
  187.     uint8_t NumRefAddrs = 0;
  188.     /// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms.
  189.     uint8_t NumDwarfOffsets = 0;
  190.  
  191.     FixedSizeInfo() = default;
  192.  
  193.     /// Calculate the fixed size in bytes given a DWARFUnit.
  194.     ///
  195.     /// \param U the DWARFUnit to use when determing the byte size.
  196.     /// \returns the size in bytes for all attribute data in this abbreviation.
  197.     /// The returned size does not include bytes for the  ULEB128 abbreviation
  198.     /// code
  199.     size_t getByteSize(const DWARFUnit &U) const;
  200.   };
  201.  
  202.   uint32_t Code;
  203.   dwarf::Tag Tag;
  204.   uint8_t CodeByteSize;
  205.   bool HasChildren;
  206.   AttributeSpecVector AttributeSpecs;
  207.   /// If this abbreviation has a fixed byte size then FixedAttributeSize member
  208.   /// variable below will have a value.
  209.   std::optional<FixedSizeInfo> FixedAttributeSize;
  210. };
  211.  
  212. } // end namespace llvm
  213.  
  214. #endif // LLVM_DEBUGINFO_DWARF_DWARFABBREVIATIONDECLARATION_H
  215.