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