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