Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:40

0001 //===- DWARFAbbreviationDeclaration.h ---------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFABBREVIATIONDECLARATION_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFABBREVIATIONDECLARATION_H
0011 
0012 #include "llvm/ADT/SmallVector.h"
0013 #include "llvm/ADT/iterator_range.h"
0014 #include "llvm/BinaryFormat/Dwarf.h"
0015 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
0016 #include <cassert>
0017 #include <cstddef>
0018 #include <cstdint>
0019 
0020 namespace llvm {
0021 
0022 class DataExtractor;
0023 class DWARFUnit;
0024 class raw_ostream;
0025 
0026 class DWARFAbbreviationDeclaration {
0027 public:
0028   enum class ExtractState { Complete, MoreItems };
0029   struct AttributeSpec {
0030     AttributeSpec(dwarf::Attribute A, dwarf::Form F, int64_t Value)
0031         : Attr(A), Form(F), Value(Value) {
0032       assert(isImplicitConst());
0033     }
0034     AttributeSpec(dwarf::Attribute A, dwarf::Form F,
0035                   std::optional<uint8_t> ByteSize)
0036         : Attr(A), Form(F) {
0037       assert(!isImplicitConst());
0038       this->ByteSize.HasByteSize = ByteSize.has_value();
0039       if (this->ByteSize.HasByteSize)
0040         this->ByteSize.ByteSize = *ByteSize;
0041     }
0042 
0043     DWARFFormValue getFormValue() const {
0044       if (Form == dwarf::DW_FORM_implicit_const)
0045         return DWARFFormValue::createFromSValue(Form, getImplicitConstValue());
0046 
0047       return DWARFFormValue(Form);
0048     }
0049 
0050     dwarf::Attribute Attr;
0051     dwarf::Form Form;
0052 
0053   private:
0054     /// The following field is used for ByteSize for non-implicit_const
0055     /// attributes and as value for implicit_const ones, indicated by
0056     /// Form == DW_FORM_implicit_const.
0057     /// The following cases are distinguished:
0058     /// * Form != DW_FORM_implicit_const and HasByteSize is true:
0059     ///     ByteSize contains the fixed size in bytes for the Form in this
0060     ///     object.
0061     /// * Form != DW_FORM_implicit_const and HasByteSize is false:
0062     ///     byte size of Form either varies according to the DWARFUnit
0063     ///     that it is contained in or the value size varies and must be
0064     ///     decoded from the debug information in order to determine its size.
0065     /// * Form == DW_FORM_implicit_const:
0066     ///     Value contains value for the implicit_const attribute.
0067     struct ByteSizeStorage {
0068       bool HasByteSize;
0069       uint8_t ByteSize;
0070     };
0071     union {
0072       ByteSizeStorage ByteSize;
0073       int64_t Value;
0074     };
0075 
0076   public:
0077     bool isImplicitConst() const {
0078       return Form == dwarf::DW_FORM_implicit_const;
0079     }
0080 
0081     int64_t getImplicitConstValue() const {
0082       assert(isImplicitConst());
0083       return Value;
0084     }
0085 
0086     /// Get the fixed byte size of this Form if possible. This function might
0087     /// use the DWARFUnit to calculate the size of the Form, like for
0088     /// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for
0089     /// the ByteSize member.
0090     std::optional<int64_t> getByteSize(const DWARFUnit &U) const;
0091   };
0092   using AttributeSpecVector = SmallVector<AttributeSpec, 8>;
0093 
0094   DWARFAbbreviationDeclaration();
0095 
0096   uint32_t getCode() const { return Code; }
0097   uint8_t getCodeByteSize() const { return CodeByteSize; }
0098   dwarf::Tag getTag() const { return Tag; }
0099   bool hasChildren() const { return HasChildren; }
0100 
0101   using attr_iterator_range =
0102       iterator_range<AttributeSpecVector::const_iterator>;
0103 
0104   attr_iterator_range attributes() const {
0105     return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end());
0106   }
0107 
0108   dwarf::Form getFormByIndex(uint32_t idx) const {
0109     assert(idx < AttributeSpecs.size());
0110     return AttributeSpecs[idx].Form;
0111   }
0112 
0113   size_t getNumAttributes() const {
0114     return AttributeSpecs.size();
0115   }
0116 
0117   dwarf::Attribute getAttrByIndex(uint32_t idx) const {
0118     assert(idx < AttributeSpecs.size());
0119     return AttributeSpecs[idx].Attr;
0120   }
0121 
0122   bool getAttrIsImplicitConstByIndex(uint32_t idx) const {
0123     assert(idx < AttributeSpecs.size());
0124     return AttributeSpecs[idx].isImplicitConst();
0125   }
0126 
0127   int64_t getAttrImplicitConstValueByIndex(uint32_t idx) const {
0128     assert(idx < AttributeSpecs.size());
0129     return AttributeSpecs[idx].getImplicitConstValue();
0130   }
0131 
0132   /// Get the index of the specified attribute.
0133   ///
0134   /// Searches the this abbreviation declaration for the index of the specified
0135   /// attribute.
0136   ///
0137   /// \param attr DWARF attribute to search for.
0138   /// \returns Optional index of the attribute if found, std::nullopt otherwise.
0139   std::optional<uint32_t> findAttributeIndex(dwarf::Attribute attr) const;
0140 
0141   /// Extract a DWARF form value from a DIE specified by DIE offset.
0142   ///
0143   /// Extract an attribute value for a DWARFUnit given the DIE offset and the
0144   /// attribute.
0145   ///
0146   /// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
0147   /// code in the .debug_info data.
0148   /// \param Attr DWARF attribute to search for.
0149   /// \param U the DWARFUnit the contains the DIE.
0150   /// \returns Optional DWARF form value if the attribute was extracted.
0151   std::optional<DWARFFormValue> getAttributeValue(const uint64_t DIEOffset,
0152                                                   const dwarf::Attribute Attr,
0153                                                   const DWARFUnit &U) const;
0154 
0155   /// Compute an offset from a DIE specified by DIE offset and attribute index.
0156   ///
0157   /// \param AttrIndex an index of DWARF attribute.
0158   /// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
0159   /// code in the .debug_info data.
0160   /// \param U the DWARFUnit the contains the DIE.
0161   /// \returns an offset of the attribute.
0162   uint64_t getAttributeOffsetFromIndex(uint32_t AttrIndex, uint64_t DIEOffset,
0163                                        const DWARFUnit &U) const;
0164 
0165   /// Extract a DWARF form value from a DIE speccified by attribute index and
0166   /// its offset.
0167   ///
0168   /// \param AttrIndex an index of DWARF attribute.
0169   /// \param Offset offset of the attribute.
0170   /// \param U the DWARFUnit the contains the DIE.
0171   /// \returns Optional DWARF form value if the attribute was extracted.
0172   std::optional<DWARFFormValue>
0173   getAttributeValueFromOffset(uint32_t AttrIndex, uint64_t Offset,
0174                               const DWARFUnit &U) const;
0175 
0176   llvm::Expected<ExtractState> extract(DataExtractor Data, uint64_t *OffsetPtr);
0177   void dump(raw_ostream &OS) const;
0178 
0179   // Return an optional byte size of all attribute data in this abbreviation
0180   // if a constant byte size can be calculated given a DWARFUnit. This allows
0181   // DWARF parsing to be faster as many DWARF DIEs have a fixed byte size.
0182   std::optional<size_t> getFixedAttributesByteSize(const DWARFUnit &U) const;
0183 
0184 private:
0185   void clear();
0186 
0187   /// A helper structure that can quickly determine the size in bytes of an
0188   /// abbreviation declaration.
0189   struct FixedSizeInfo {
0190     /// The fixed byte size for fixed size forms.
0191     uint16_t NumBytes = 0;
0192     /// Number of DW_FORM_address forms in this abbrevation declaration.
0193     uint8_t NumAddrs = 0;
0194     /// Number of DW_FORM_ref_addr forms in this abbrevation declaration.
0195     uint8_t NumRefAddrs = 0;
0196     /// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms.
0197     uint8_t NumDwarfOffsets = 0;
0198 
0199     FixedSizeInfo() = default;
0200 
0201     /// Calculate the fixed size in bytes given a DWARFUnit.
0202     ///
0203     /// \param U the DWARFUnit to use when determing the byte size.
0204     /// \returns the size in bytes for all attribute data in this abbreviation.
0205     /// The returned size does not include bytes for the  ULEB128 abbreviation
0206     /// code
0207     size_t getByteSize(const DWARFUnit &U) const;
0208   };
0209 
0210   uint32_t Code;
0211   dwarf::Tag Tag;
0212   uint8_t CodeByteSize;
0213   bool HasChildren;
0214   AttributeSpecVector AttributeSpecs;
0215   /// If this abbreviation has a fixed byte size then FixedAttributeSize member
0216   /// variable below will have a value.
0217   std::optional<FixedSizeInfo> FixedAttributeSize;
0218 };
0219 
0220 } // end namespace llvm
0221 
0222 #endif // LLVM_DEBUGINFO_DWARF_DWARFABBREVIATIONDECLARATION_H