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