LLVM  8.0.1
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"
21 #include <cstddef>
22 #include <cstdint>
23 
24 using namespace llvm;
25 using namespace dwarf;
26 
27 void DWARFAbbreviationDeclaration::clear() {
28  Code = 0;
29  Tag = DW_TAG_null;
30  CodeByteSize = 0;
31  HasChildren = false;
32  AttributeSpecs.clear();
33  FixedAttributeSize.reset();
34 }
35 
37  clear();
38 }
39 
40 bool
42  uint32_t* OffsetPtr) {
43  clear();
44  const uint32_t Offset = *OffsetPtr;
45  Code = Data.getULEB128(OffsetPtr);
46  if (Code == 0) {
47  return false;
48  }
49  CodeByteSize = *OffsetPtr - Offset;
50  Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
51  if (Tag == DW_TAG_null) {
52  clear();
53  return false;
54  }
55  uint8_t ChildrenByte = Data.getU8(OffsetPtr);
56  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  FixedAttributeSize = FixedSizeInfo();
61 
62  // Read all of the abbreviation attributes and forms.
63  while (true) {
64  auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
65  auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
66  if (A && F) {
67  bool IsImplicitConst = (F == DW_FORM_implicit_const);
68  if (IsImplicitConst) {
69  int64_t V = Data.getSLEB128(OffsetPtr);
70  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  switch (F) {
77  case DW_FORM_addr:
78  if (FixedAttributeSize)
79  ++FixedAttributeSize->NumAddrs;
80  break;
81 
82  case DW_FORM_ref_addr:
83  if (FixedAttributeSize)
84  ++FixedAttributeSize->NumRefAddrs;
85  break;
86 
87  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  if (FixedAttributeSize)
94  ++FixedAttributeSize->NumDwarfOffsets;
95  break;
96 
97  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  if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
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  OS << '[' << getCode() << "] ";
131  OS << formatv("{0}", getTag());
132  OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
133  for (const AttributeSpec &Spec : AttributeSpecs) {
134  OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
135  if (Spec.isImplicitConst())
136  OS << '\t' << Spec.getImplicitConstValue();
137  OS << '\n';
138  }
139  OS << '\n';
140 }
141 
144  for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
145  if (AttributeSpecs[i].Attr == Attr)
146  return i;
147  }
148  return None;
149 }
150 
152  const uint32_t DIEOffset, const dwarf::Attribute Attr,
153  const DWARFUnit &U) const {
154  Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
155  if (!MatchAttrIndex)
156  return None;
157 
158  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  uint32_t Offset = DIEOffset + CodeByteSize;
163  uint32_t AttrIndex = 0;
164  for (const auto &Spec : AttributeSpecs) {
165  if (*MatchAttrIndex == AttrIndex) {
166  // We have arrived at the attribute to extract, extract if from Offset.
167  DWARFFormValue FormValue(Spec.Form);
168  if (Spec.isImplicitConst()) {
169  FormValue.setSValue(Spec.getImplicitConstValue());
170  return FormValue;
171  }
172  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  if (auto FixedSize = Spec.getByteSize(U))
177  Offset += *FixedSize;
178  else
179  DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
180  U.getFormParams());
181  ++AttrIndex;
182  }
183  return None;
184 }
185 
186 size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
187  const DWARFUnit &U) const {
188  size_t ByteSize = NumBytes;
189  if (NumAddrs)
190  ByteSize += NumAddrs * U.getAddressByteSize();
191  if (NumRefAddrs)
192  ByteSize += NumRefAddrs * U.getRefAddrByteSize();
193  if (NumDwarfOffsets)
194  ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
195  return ByteSize;
196 }
197 
199  const DWARFUnit &U) const {
200  if (isImplicitConst())
201  return 0;
202  if (ByteSize.HasByteSize)
203  return ByteSize.ByteSize;
205  auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
206  if (FixedByteSize)
207  S = *FixedByteSize;
208  return S;
209 }
210 
212  const DWARFUnit &U) const {
213  if (FixedAttributeSize)
214  return FixedAttributeSize->getByteSize(U);
215  return None;
216 }
const NoneType None
Definition: None.h:24
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:499
bool extract(DataExtractor Data, uint32_t *OffsetPtr)
uint64_t getULEB128(uint32_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
This class represents lattice values for constants.
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:115
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Optional< size_t > getFixedAttributesByteSize(const DWARFUnit &U) const
uint8_t getRefAddrByteSize() const
Definition: DWARFUnit.h:281
F(f)
Optional< uint32_t > findAttributeIndex(dwarf::Attribute attr) const
Get the index of the specified attribute.
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:276
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:280
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.
bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, const dwarf::FormParams Params) const
Skip a form&#39;s value in DebugInfoData at the offset specified by OffsetPtr.
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:33
This file contains constants used for implementing Dwarf debug support.
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:212
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:196
bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFContext *Context=nullptr, const DWARFUnit *Unit=nullptr)
Extracts a value in Data at offset *OffsetPtr.
Optional< uint8_t > getFixedFormByteSize(dwarf::Form Form, FormParams Params)
Get the fixed byte size for a given form.
Definition: Dwarf.cpp:626
void setSValue(int64_t V)
void reset()
Definition: Optional.h:151
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
uint8_t getDwarfOffsetByteSize() const
Definition: DWARFUnit.h:282