LLVM  4.0.0
DWARFAbbreviationDeclaration.cpp
Go to the documentation of this file.
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 
13 #include "llvm/Support/Dwarf.h"
14 #include "llvm/Support/Format.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 
29  clear();
30 }
31 
32 bool
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) {
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 
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 
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 
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 
202  const DWARFUnit &U) const {
203  if (isImplicitConst())
204  return 0;
205  if (ByteSizeOrValue)
206  return ByteSizeOrValue;
208  auto FixedByteSize = DWARFFormValue::getFixedByteSize(Form, &U);
209  if (FixedByteSize)
210  S = *FixedByteSize;
211  return S;
212 }
213 
215  const DWARFUnit &U) const {
216  if (FixedAttributeSize)
217  return FixedAttributeSize->getByteSize(U);
218  return None;
219 }
const NoneType None
Definition: None.h:23
uint8_t getDwarfOffsetByteSize() const
Definition: DWARFUnit.h:217
bool extract(DataExtractor Data, uint32_t *OffsetPtr)
size_t i
bool extractValue(const DataExtractor &Data, uint32_t *OffsetPtr, const DWARFUnit *U)
extracts a value in data at offset *offset_ptr.
Attribute
Attributes.
Definition: Dwarf.h:94
uint8_t getRefAddrByteSize() const
Definition: DWARFUnit.h:212
Optional< DWARFFormValue > getAttributeValue(const uint32_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U) const
Extract a DWARF form value from a DIE specified by DIE offset.
Optional< size_t > getFixedAttributesByteSize(const DWARFUnit &U) const
StringRef FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:58
#define F(x, y, z)
Definition: MD5.cpp:51
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:47
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
uint8_t getU8(uint32_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
uint32_t Offset
uint64_t getULEB128(uint32_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
static Optional< uint8_t > getFixedByteSize(dwarf::Form Form, const DWARFUnit *U=nullptr)
Get the fixed byte size for a given form.
Optional< int64_t > getByteSize(const DWARFUnit &U) const
Get the fixed byte size of this Form if possible.
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:191
DataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.h:184
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
Optional< uint32_t > findAttributeIndex(dwarf::Attribute attr) const
Get the index of the specified attribute.
void setSValue(int64_t V)
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:211
void reset()
Definition: Optional.h:108
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
int64_t getSLEB128(uint32_t *offset_ptr) const
Extract a signed LEB128 value from *offset_ptr.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFUnit *U) const
Skip a form in debug_info_data at offset specified by offset_ptr.