1 //===- DWARFAbbreviationDeclaration.h ---------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
10 #define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/iterator_range.h"
15 #include "llvm/BinaryFormat/Dwarf.h"
16 #include "llvm/Support/DataExtractor.h"
27 class DWARFAbbreviationDeclaration
{
29 struct AttributeSpec
{
30 AttributeSpec(dwarf::Attribute A
, dwarf::Form F
, int64_t Value
)
31 : Attr(A
), Form(F
), Value(Value
) {
32 assert(isImplicitConst());
34 AttributeSpec(dwarf::Attribute A
, dwarf::Form F
, Optional
<uint8_t> ByteSize
)
36 assert(!isImplicitConst());
37 this->ByteSize
.HasByteSize
= ByteSize
.hasValue();
38 if (this->ByteSize
.HasByteSize
)
39 this->ByteSize
.ByteSize
= *ByteSize
;
42 dwarf::Attribute Attr
;
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
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
{
64 ByteSizeStorage ByteSize
;
69 bool isImplicitConst() const {
70 return Form
== dwarf::DW_FORM_implicit_const
;
73 int64_t getImplicitConstValue() const {
74 assert(isImplicitConst());
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 Optional
<int64_t> getByteSize(const DWARFUnit
&U
) const;
84 using AttributeSpecVector
= SmallVector
<AttributeSpec
, 8>;
86 DWARFAbbreviationDeclaration();
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
; }
93 using attr_iterator_range
=
94 iterator_range
<AttributeSpecVector::const_iterator
>;
96 attr_iterator_range
attributes() const {
97 return attr_iterator_range(AttributeSpecs
.begin(), AttributeSpecs
.end());
100 dwarf::Form
getFormByIndex(uint32_t idx
) const {
101 assert(idx
< AttributeSpecs
.size());
102 return AttributeSpecs
[idx
].Form
;
105 size_t getNumAttributes() const {
106 return AttributeSpecs
.size();
109 dwarf::Attribute
getAttrByIndex(uint32_t idx
) const {
110 assert(idx
< AttributeSpecs
.size());
111 return AttributeSpecs
[idx
].Attr
;
114 /// Get the index of the specified attribute.
116 /// Searches the this abbreviation declaration for the index of the specified
119 /// \param attr DWARF attribute to search for.
120 /// \returns Optional index of the attribute if found, None otherwise.
121 Optional
<uint32_t> findAttributeIndex(dwarf::Attribute attr
) const;
123 /// Extract a DWARF form value from a DIE specified by DIE offset.
125 /// Extract an attribute value for a DWARFUnit given the DIE offset and the
128 /// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
129 /// code in the .debug_info data.
130 /// \param Attr DWARF attribute to search for.
131 /// \param U the DWARFUnit the contains the DIE.
132 /// \returns Optional DWARF form value if the attribute was extracted.
133 Optional
<DWARFFormValue
> getAttributeValue(const uint64_t DIEOffset
,
134 const dwarf::Attribute Attr
,
135 const DWARFUnit
&U
) const;
137 bool extract(DataExtractor Data
, uint64_t* OffsetPtr
);
138 void dump(raw_ostream
&OS
) const;
140 // Return an optional byte size of all attribute data in this abbreviation
141 // if a constant byte size can be calculated given a DWARFUnit. This allows
142 // DWARF parsing to be faster as many DWARF DIEs have a fixed byte size.
143 Optional
<size_t> getFixedAttributesByteSize(const DWARFUnit
&U
) const;
148 /// A helper structure that can quickly determine the size in bytes of an
149 /// abbreviation declaration.
150 struct FixedSizeInfo
{
151 /// The fixed byte size for fixed size forms.
152 uint16_t NumBytes
= 0;
153 /// Number of DW_FORM_address forms in this abbrevation declaration.
154 uint8_t NumAddrs
= 0;
155 /// Number of DW_FORM_ref_addr forms in this abbrevation declaration.
156 uint8_t NumRefAddrs
= 0;
157 /// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms.
158 uint8_t NumDwarfOffsets
= 0;
160 FixedSizeInfo() = default;
162 /// Calculate the fixed size in bytes given a DWARFUnit.
164 /// \param U the DWARFUnit to use when determing the byte size.
165 /// \returns the size in bytes for all attribute data in this abbreviation.
166 /// The returned size does not include bytes for the ULEB128 abbreviation
168 size_t getByteSize(const DWARFUnit
&U
) const;
173 uint8_t CodeByteSize
;
175 AttributeSpecVector AttributeSpecs
;
176 /// If this abbreviation has a fixed byte size then FixedAttributeSize member
177 /// variable below will have a value.
178 Optional
<FixedSizeInfo
> FixedAttributeSize
;
181 } // end namespace llvm
183 #endif // LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H