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