Line data Source code
1 : //===- DWARFAbbreviationDeclaration.cpp -----------------------------------===//
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 : #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
11 :
12 : #include "llvm/ADT/None.h"
13 : #include "llvm/ADT/Optional.h"
14 : #include "llvm/BinaryFormat/Dwarf.h"
15 : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
16 : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
17 : #include "llvm/Support/DataExtractor.h"
18 : #include "llvm/Support/Format.h"
19 : #include "llvm/Support/FormatVariadic.h"
20 : #include "llvm/Support/raw_ostream.h"
21 : #include <cstddef>
22 : #include <cstdint>
23 :
24 : using namespace llvm;
25 : using namespace dwarf;
26 :
27 35071 : void DWARFAbbreviationDeclaration::clear() {
28 35071 : Code = 0;
29 35071 : Tag = DW_TAG_null;
30 35071 : CodeByteSize = 0;
31 35071 : HasChildren = false;
32 : AttributeSpecs.clear();
33 : FixedAttributeSize.reset();
34 35071 : }
35 :
36 3612 : DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
37 3612 : clear();
38 3612 : }
39 :
40 : bool
41 31459 : DWARFAbbreviationDeclaration::extract(DataExtractor Data,
42 : uint32_t* OffsetPtr) {
43 31459 : clear();
44 31459 : const uint32_t Offset = *OffsetPtr;
45 31459 : Code = Data.getULEB128(OffsetPtr);
46 31459 : if (Code == 0) {
47 : return false;
48 : }
49 27847 : CodeByteSize = *OffsetPtr - Offset;
50 27847 : Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
51 27847 : if (Tag == DW_TAG_null) {
52 0 : clear();
53 0 : return false;
54 : }
55 27847 : uint8_t ChildrenByte = Data.getU8(OffsetPtr);
56 27847 : HasChildren = (ChildrenByte == DW_CHILDREN_yes);
57 : // Assign a value to our optional FixedAttributeSize member variable. If
58 : // this member variable still has a value after the while loop below, then
59 : // all attribute data in this abbreviation declaration has a fixed byte size.
60 27847 : FixedAttributeSize = FixedSizeInfo();
61 :
62 : // Read all of the abbreviation attributes and forms.
63 : while (true) {
64 161272 : auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
65 161272 : auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
66 161272 : if (A && F) {
67 : bool IsImplicitConst = (F == DW_FORM_implicit_const);
68 133425 : if (IsImplicitConst) {
69 6 : int64_t V = Data.getSLEB128(OffsetPtr);
70 12 : AttributeSpecs.push_back(AttributeSpec(A, F, V));
71 : continue;
72 : }
73 : Optional<uint8_t> ByteSize;
74 : // If this abbrevation still has a fixed byte size, then update the
75 : // FixedAttributeSize as needed.
76 133419 : switch (F) {
77 14665 : case DW_FORM_addr:
78 14665 : if (FixedAttributeSize)
79 14588 : ++FixedAttributeSize->NumAddrs;
80 : break;
81 :
82 313 : case DW_FORM_ref_addr:
83 313 : if (FixedAttributeSize)
84 228 : ++FixedAttributeSize->NumRefAddrs;
85 : break;
86 :
87 27403 : case DW_FORM_strp:
88 : case DW_FORM_GNU_ref_alt:
89 : case DW_FORM_GNU_strp_alt:
90 : case DW_FORM_line_strp:
91 : case DW_FORM_sec_offset:
92 : case DW_FORM_strp_sup:
93 27403 : if (FixedAttributeSize)
94 26154 : ++FixedAttributeSize->NumDwarfOffsets;
95 : break;
96 :
97 91038 : default:
98 : // The form has a byte size that doesn't depend on Params.
99 : // If it's a fixed size, keep track of it.
100 182076 : if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
101 87585 : if (FixedAttributeSize)
102 82324 : FixedAttributeSize->NumBytes += *ByteSize;
103 : break;
104 : }
105 : // Indicate we no longer have a fixed byte size for this
106 : // abbreviation by clearing the FixedAttributeSize optional value
107 : // so it doesn't have a value.
108 : FixedAttributeSize.reset();
109 : break;
110 : }
111 : // Record this attribute and its fixed size if it has one.
112 266838 : AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
113 27847 : } else if (A == 0 && F == 0) {
114 : // We successfully reached the end of this abbreviation declaration
115 : // since both attribute and form are zero.
116 : break;
117 : } else {
118 : // Attribute and form pairs must either both be non-zero, in which case
119 : // they are added to the abbreviation declaration, or both be zero to
120 : // terminate the abbrevation declaration. In this case only one was
121 : // zero which is an error.
122 0 : clear();
123 0 : return false;
124 : }
125 : }
126 : return true;
127 : }
128 :
129 1485 : void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
130 1485 : OS << '[' << getCode() << "] ";
131 1485 : OS << formatv("{0}", getTag());
132 2435 : OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
133 8454 : for (const AttributeSpec &Spec : AttributeSpecs) {
134 6969 : OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
135 6969 : if (Spec.isImplicitConst())
136 3 : OS << '\t' << Spec.getImplicitConstValue();
137 : OS << '\n';
138 : }
139 : OS << '\n';
140 1485 : }
141 :
142 : Optional<uint32_t>
143 91870 : DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
144 485427 : for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
145 847776 : if (AttributeSpecs[i].Attr == Attr)
146 : return i;
147 : }
148 : return None;
149 : }
150 :
151 91028 : Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
152 : const uint32_t DIEOffset, const dwarf::Attribute Attr,
153 : const DWARFUnit &U) const {
154 91028 : Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
155 91028 : if (!MatchAttrIndex)
156 : return None;
157 :
158 29772 : auto DebugInfoData = U.getDebugInfoExtractor();
159 :
160 : // Add the byte size of ULEB that for the abbrev Code so we can start
161 : // skipping the attribute data.
162 29772 : uint32_t Offset = DIEOffset + CodeByteSize;
163 : uint32_t AttrIndex = 0;
164 120198 : for (const auto &Spec : AttributeSpecs) {
165 120198 : if (*MatchAttrIndex == AttrIndex) {
166 : // We have arrived at the attribute to extract, extract if from Offset.
167 29772 : DWARFFormValue FormValue(Spec.Form);
168 29772 : if (Spec.isImplicitConst()) {
169 7 : FormValue.setSValue(Spec.getImplicitConstValue());
170 29772 : return FormValue;
171 : }
172 29765 : if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
173 : return FormValue;
174 : }
175 : // March Offset along until we get to the attribute we want.
176 90426 : if (auto FixedSize = Spec.getByteSize(U))
177 86188 : Offset += *FixedSize;
178 : else
179 4238 : DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
180 : U.getFormParams());
181 90426 : ++AttrIndex;
182 : }
183 : return None;
184 : }
185 :
186 26366 : size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
187 : const DWARFUnit &U) const {
188 26366 : size_t ByteSize = NumBytes;
189 26366 : if (NumAddrs)
190 6352 : ByteSize += NumAddrs * U.getAddressByteSize();
191 26366 : if (NumRefAddrs)
192 542 : ByteSize += NumRefAddrs * U.getRefAddrByteSize();
193 26366 : if (NumDwarfOffsets)
194 12232 : ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
195 26366 : return ByteSize;
196 : }
197 :
198 122315 : Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
199 : const DWARFUnit &U) const {
200 122315 : if (isImplicitConst())
201 : return 0;
202 122305 : if (ByteSize.HasByteSize)
203 53193 : return ByteSize.ByteSize;
204 : Optional<int64_t> S;
205 69112 : auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
206 69112 : if (FixedByteSize)
207 58786 : S = *FixedByteSize;
208 : return S;
209 : }
210 :
211 31763 : Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
212 : const DWARFUnit &U) const {
213 31763 : if (FixedAttributeSize)
214 26366 : return FixedAttributeSize->getByteSize(U);
215 : return None;
216 : }
|