LLVM  6.0.0svn
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 
11 
12 #include "llvm/ADT/None.h"
13 #include "llvm/ADT/Optional.h"
18 #include "llvm/Support/Format.h"
20 #include <cstddef>
21 #include <cstdint>
22 
23 using namespace llvm;
24 using namespace dwarf;
25 
26 void DWARFAbbreviationDeclaration::clear() {
27  Code = 0;
28  Tag = DW_TAG_null;
29  CodeByteSize = 0;
30  HasChildren = false;
31  AttributeSpecs.clear();
32  FixedAttributeSize.reset();
33 }
34 
36  clear();
37 }
38 
39 bool
41  uint32_t* OffsetPtr) {
42  clear();
43  const uint32_t Offset = *OffsetPtr;
44  Code = Data.getULEB128(OffsetPtr);
45  if (Code == 0) {
46  return false;
47  }
48  CodeByteSize = *OffsetPtr - Offset;
49  Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
50  if (Tag == DW_TAG_null) {
51  clear();
52  return false;
53  }
54  uint8_t ChildrenByte = Data.getU8(OffsetPtr);
55  HasChildren = (ChildrenByte == DW_CHILDREN_yes);
56  // Assign a value to our optional FixedAttributeSize member variable. If
57  // this member variable still has a value after the while loop below, then
58  // all attribute data in this abbreviation declaration has a fixed byte size.
59  FixedAttributeSize = FixedSizeInfo();
60 
61  // Read all of the abbreviation attributes and forms.
62  while (true) {
63  auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
64  auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
65  if (A && F) {
66  bool IsImplicitConst = (F == DW_FORM_implicit_const);
67  if (IsImplicitConst) {
68  int64_t V = Data.getSLEB128(OffsetPtr);
69  AttributeSpecs.push_back(AttributeSpec(A, F, V));
70  continue;
71  }
72  Optional<uint8_t> ByteSize;
73  // If this abbrevation still has a fixed byte size, then update the
74  // FixedAttributeSize as needed.
75  switch (F) {
76  case DW_FORM_addr:
77  if (FixedAttributeSize)
78  ++FixedAttributeSize->NumAddrs;
79  break;
80 
81  case DW_FORM_ref_addr:
82  if (FixedAttributeSize)
83  ++FixedAttributeSize->NumRefAddrs;
84  break;
85 
86  case DW_FORM_strp:
87  case DW_FORM_GNU_ref_alt:
88  case DW_FORM_GNU_strp_alt:
89  case DW_FORM_line_strp:
90  case DW_FORM_sec_offset:
91  case DW_FORM_strp_sup:
92  if (FixedAttributeSize)
93  ++FixedAttributeSize->NumDwarfOffsets;
94  break;
95 
96  default:
97  // The form has a byte size that doesn't depend on Params.
98  // If it's a fixed size, keep track of it.
99  if ((ByteSize =
101  if (FixedAttributeSize)
102  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  AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
113  } 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  clear();
123  return false;
124  }
125  }
126  return true;
127 }
128 
130  auto tagString = TagString(getTag());
131  OS << '[' << getCode() << "] ";
132  if (!tagString.empty())
133  OS << tagString;
134  else
135  OS << format("DW_TAG_Unknown_%x", getTag());
136  OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
137  for (const AttributeSpec &Spec : AttributeSpecs) {
138  OS << '\t';
139  auto attrString = AttributeString(Spec.Attr);
140  if (!attrString.empty())
141  OS << attrString;
142  else
143  OS << format("DW_AT_Unknown_%x", Spec.Attr);
144  OS << '\t';
145  auto formString = FormEncodingString(Spec.Form);
146  if (!formString.empty())
147  OS << formString;
148  else
149  OS << format("DW_FORM_Unknown_%x", Spec.Form);
150  if (Spec.isImplicitConst())
151  OS << '\t' << Spec.getImplicitConstValue();
152  OS << '\n';
153  }
154  OS << '\n';
155 }
156 
159  for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
160  if (AttributeSpecs[i].Attr == Attr)
161  return i;
162  }
163  return None;
164 }
165 
167  const uint32_t DIEOffset, const dwarf::Attribute Attr,
168  const DWARFUnit &U) const {
169  Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
170  if (!MatchAttrIndex)
171  return None;
172 
173  auto DebugInfoData = U.getDebugInfoExtractor();
174 
175  // Add the byte size of ULEB that for the abbrev Code so we can start
176  // skipping the attribute data.
177  uint32_t Offset = DIEOffset + CodeByteSize;
178  uint32_t AttrIndex = 0;
179  for (const auto &Spec : AttributeSpecs) {
180  if (*MatchAttrIndex == AttrIndex) {
181  // We have arrived at the attribute to extract, extract if from Offset.
182  DWARFFormValue FormValue(Spec.Form);
183  if (Spec.isImplicitConst()) {
184  FormValue.setSValue(Spec.getImplicitConstValue());
185  return FormValue;
186  }
187  if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
188  return FormValue;
189  }
190  // March Offset along until we get to the attribute we want.
191  if (auto FixedSize = Spec.getByteSize(U))
192  Offset += *FixedSize;
193  else
194  DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
195  U.getFormParams());
196  ++AttrIndex;
197  }
198  return None;
199 }
200 
201 size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
202  const DWARFUnit &U) const {
203  size_t ByteSize = NumBytes;
204  if (NumAddrs)
205  ByteSize += NumAddrs * U.getAddressByteSize();
206  if (NumRefAddrs)
207  ByteSize += NumRefAddrs * U.getRefAddrByteSize();
208  if (NumDwarfOffsets)
209  ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
210  return ByteSize;
211 }
212 
214  const DWARFUnit &U) const {
215  if (isImplicitConst())
216  return 0;
217  if (ByteSize.HasByteSize)
218  return ByteSize.ByteSize;
220  auto FixedByteSize =
222  if (FixedByteSize)
223  S = *FixedByteSize;
224  return S;
225 }
226 
228  const DWARFUnit &U) const {
229  if (FixedAttributeSize)
230  return FixedAttributeSize->getByteSize(U);
231  return None;
232 }
const NoneType None
Definition: None.h:24
bool extract(DataExtractor Data, uint32_t *OffsetPtr)
uint64_t getULEB128(uint32_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Optional< int64_t > getByteSize(const DWARFUnit &U) const
Get the fixed byte size of this Form if possible.
Attribute
Attributes.
Definition: Dwarf.h:107
const DWARFFormParams & getFormParams() const
Definition: DWARFUnit.h:275
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
Optional< size_t > getFixedAttributesByteSize(const DWARFUnit &U) const
uint8_t getRefAddrByteSize() const
Definition: DWARFUnit.h:279
F(f)
Optional< uint32_t > findAttributeIndex(dwarf::Attribute attr) const
Get the index of the specified attribute.
static Optional< uint8_t > getFixedByteSize(dwarf::Form Form, const DWARFFormParams FormParams)
Get the fixed byte size for a given form.
StringRef FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:105
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:278
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, const DWARFFormParams Params) const
Skip a form&#39;s value in DebugInfoData at the offset specified by OffsetPtr.
int64_t getSLEB128(uint32_t *offset_ptr) const
Extract a signed LEB128 value from *offset_ptr.
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.
uint8_t getU8(uint32_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
A helper struct for DWARFFormValue methods, providing information that allows it to know the byte siz...
This file contains constants used for implementing Dwarf debug support.
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:210
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:64
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
void setSValue(int64_t V)
void reset()
Definition: Optional.h:112
bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, DWARFFormParams FormParams, const DWARFUnit *U=nullptr)
Extracts a value in Data at offset *OffsetPtr.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
uint8_t getDwarfOffsetByteSize() const
Definition: DWARFUnit.h:280