LLVM  17.0.0git
DWARFAbbreviationDeclaration.cpp
Go to the documentation of this file.
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 
10 
18 #include <cstddef>
19 #include <cstdint>
20 
21 using namespace llvm;
22 using namespace dwarf;
23 
24 void DWARFAbbreviationDeclaration::clear() {
25  Code = 0;
26  Tag = DW_TAG_null;
27  CodeByteSize = 0;
28  HasChildren = false;
29  AttributeSpecs.clear();
30  FixedAttributeSize.reset();
31 }
32 
34  clear();
35 }
36 
37 bool
39  uint64_t* OffsetPtr) {
40  clear();
41  const uint64_t Offset = *OffsetPtr;
42  Code = Data.getULEB128(OffsetPtr);
43  if (Code == 0) {
44  return false;
45  }
46  CodeByteSize = *OffsetPtr - Offset;
47  Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
48  if (Tag == DW_TAG_null) {
49  clear();
50  return false;
51  }
52  uint8_t ChildrenByte = Data.getU8(OffsetPtr);
53  HasChildren = (ChildrenByte == DW_CHILDREN_yes);
54  // Assign a value to our optional FixedAttributeSize member variable. If
55  // this member variable still has a value after the while loop below, then
56  // all attribute data in this abbreviation declaration has a fixed byte size.
57  FixedAttributeSize = FixedSizeInfo();
58 
59  // Read all of the abbreviation attributes and forms.
60  while (true) {
61  auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
62  auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
63  if (A && F) {
64  bool IsImplicitConst = (F == DW_FORM_implicit_const);
65  if (IsImplicitConst) {
66  int64_t V = Data.getSLEB128(OffsetPtr);
67  AttributeSpecs.push_back(AttributeSpec(A, F, V));
68  continue;
69  }
70  std::optional<uint8_t> ByteSize;
71  // If this abbrevation still has a fixed byte size, then update the
72  // FixedAttributeSize as needed.
73  switch (F) {
74  case DW_FORM_addr:
75  if (FixedAttributeSize)
76  ++FixedAttributeSize->NumAddrs;
77  break;
78 
79  case DW_FORM_ref_addr:
80  if (FixedAttributeSize)
81  ++FixedAttributeSize->NumRefAddrs;
82  break;
83 
84  case DW_FORM_strp:
85  case DW_FORM_GNU_ref_alt:
86  case DW_FORM_GNU_strp_alt:
87  case DW_FORM_line_strp:
88  case DW_FORM_sec_offset:
89  case DW_FORM_strp_sup:
90  if (FixedAttributeSize)
91  ++FixedAttributeSize->NumDwarfOffsets;
92  break;
93 
94  default:
95  // The form has a byte size that doesn't depend on Params.
96  // If it's a fixed size, keep track of it.
97  if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
98  if (FixedAttributeSize)
99  FixedAttributeSize->NumBytes += *ByteSize;
100  break;
101  }
102  // Indicate we no longer have a fixed byte size for this
103  // abbreviation by clearing the FixedAttributeSize optional value
104  // so it doesn't have a value.
105  FixedAttributeSize.reset();
106  break;
107  }
108  // Record this attribute and its fixed size if it has one.
109  AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
110  } else if (A == 0 && F == 0) {
111  // We successfully reached the end of this abbreviation declaration
112  // since both attribute and form are zero.
113  break;
114  } else {
115  // Attribute and form pairs must either both be non-zero, in which case
116  // they are added to the abbreviation declaration, or both be zero to
117  // terminate the abbrevation declaration. In this case only one was
118  // zero which is an error.
119  clear();
120  return false;
121  }
122  }
123  return true;
124 }
125 
127  OS << '[' << getCode() << "] ";
128  OS << formatv("{0}", getTag());
129  OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
130  for (const AttributeSpec &Spec : AttributeSpecs) {
131  OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
132  if (Spec.isImplicitConst())
133  OS << '\t' << Spec.getImplicitConstValue();
134  OS << '\n';
135  }
136  OS << '\n';
137 }
138 
139 std::optional<uint32_t>
141  for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
142  if (AttributeSpecs[i].Attr == Attr)
143  return i;
144  }
145  return std::nullopt;
146 }
147 
149  uint32_t AttrIndex, uint64_t DIEOffset, const DWARFUnit &U) const {
150  DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
151 
152  // Add the byte size of ULEB that for the abbrev Code so we can start
153  // skipping the attribute data.
154  uint64_t Offset = DIEOffset + CodeByteSize;
155  for (uint32_t CurAttrIdx = 0; CurAttrIdx != AttrIndex; ++CurAttrIdx)
156  // Match Offset along until we get to the attribute we want.
157  if (auto FixedSize = AttributeSpecs[CurAttrIdx].getByteSize(U))
158  Offset += *FixedSize;
159  else
160  DWARFFormValue::skipValue(AttributeSpecs[CurAttrIdx].Form, DebugInfoData,
161  &Offset, U.getFormParams());
162  return Offset;
163 }
164 
165 std::optional<DWARFFormValue>
167  uint32_t AttrIndex, uint64_t Offset, const DWARFUnit &U) const {
168  assert(AttributeSpecs.size() > AttrIndex &&
169  "Attribute Index is out of bounds.");
170 
171  // We have arrived at the attribute to extract, extract if from Offset.
172  const AttributeSpec &Spec = AttributeSpecs[AttrIndex];
173  if (Spec.isImplicitConst())
175  Spec.getImplicitConstValue());
176 
177  DWARFFormValue FormValue(Spec.Form);
178  DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
179  if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
180  return FormValue;
181  return std::nullopt;
182 }
183 
184 std::optional<DWARFFormValue>
186  const dwarf::Attribute Attr,
187  const DWARFUnit &U) const {
188  // Check if this abbreviation has this attribute without needing to skip
189  // any data so we can return quickly if it doesn't.
190  std::optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
191  if (!MatchAttrIndex)
192  return std::nullopt;
193 
194  uint64_t Offset = getAttributeOffsetFromIndex(*MatchAttrIndex, DIEOffset, U);
195 
196  return getAttributeValueFromOffset(*MatchAttrIndex, Offset, U);
197 }
198 
199 size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
200  const DWARFUnit &U) const {
201  size_t ByteSize = NumBytes;
202  if (NumAddrs)
203  ByteSize += NumAddrs * U.getAddressByteSize();
204  if (NumRefAddrs)
205  ByteSize += NumRefAddrs * U.getRefAddrByteSize();
206  if (NumDwarfOffsets)
207  ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
208  return ByteSize;
209 }
210 
212  const DWARFUnit &U) const {
213  if (isImplicitConst())
214  return 0;
215  if (ByteSize.HasByteSize)
216  return ByteSize.ByteSize;
217  std::optional<int64_t> S;
218  auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
219  if (FixedByteSize)
220  S = *FixedByteSize;
221  return S;
222 }
223 
225  const DWARFUnit &U) const {
226  if (FixedAttributeSize)
227  return FixedAttributeSize->getByteSize(U);
228  return std::nullopt;
229 }
i
i
Definition: README.txt:29
DWARFFormValue.h
llvm::DWARFAbbreviationDeclaration::getFixedAttributesByteSize
std::optional< size_t > getFixedAttributesByteSize(const DWARFUnit &U) const
Definition: DWARFAbbreviationDeclaration.cpp:224
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::DWARFAbbreviationDeclaration::dump
void dump(raw_ostream &OS) const
Definition: DWARFAbbreviationDeclaration.cpp:126
llvm::Attribute
Definition: Attributes.h:67
llvm::DWARFAbbreviationDeclaration::AttributeSpec
Definition: DWARFAbbreviationDeclaration.h:28
llvm::tgtok::Code
@ Code
Definition: TGLexer.h:50
llvm::DWARFAbbreviationDeclaration::findAttributeIndex
std::optional< uint32_t > findAttributeIndex(dwarf::Attribute attr) const
Get the index of the specified attribute.
Definition: DWARFAbbreviationDeclaration.cpp:140
llvm::dwarf::Form
Form
Definition: Dwarf.h:130
llvm::dwarf::DW_CHILDREN_yes
@ DW_CHILDREN_yes
Definition: Dwarf.h:513
llvm::DWARFUnit::getFormParams
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:315
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:103
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::dwarf::Attribute
Attribute
Attributes.
Definition: Dwarf.h:123
F
#define F(x, y, z)
Definition: MD5.cpp:55
clear
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:149
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
llvm::DWARFFormValue::createFromSValue
static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V)
Definition: DWARFFormValue.cpp:82
llvm::dwarf::getTag
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::DWARFFormValue
Definition: DWARFFormValue.h:26
llvm::logicalview::AttributeSpec
DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec
Definition: LVELFReader.h:31
FormatVariadic.h
llvm::DWARFFormValue::skipValue
bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, const dwarf::FormParams Params) const
Skip a form's value in DebugInfoData at the offset specified by OffsetPtr.
Definition: DWARFFormValue.h:145
llvm::DWARFAbbreviationDeclaration::extract
bool extract(DataExtractor Data, uint64_t *OffsetPtr)
Definition: DWARFAbbreviationDeclaration.cpp:38
llvm::DWARFUnit::getDebugInfoExtractor
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:202
uint64_t
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:31
DWARFUnit.h
llvm::dwarf::FormParams
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:731
DWARFAbbreviationDeclaration.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DWARFUnit::getRefAddrByteSize
uint8_t getRefAddrByteSize() const
Definition: DWARFUnit.h:320
llvm::DWARFAbbreviationDeclaration::getAttributeValueFromOffset
std::optional< DWARFFormValue > getAttributeValueFromOffset(uint32_t AttrIndex, uint64_t Offset, const DWARFUnit &U) const
Extract a DWARF form value from a DIE speccified by attribute index and its offset.
Definition: DWARFAbbreviationDeclaration.cpp:166
llvm::dwarf::getFixedFormByteSize
std::optional< uint8_t > getFixedFormByteSize(dwarf::Form Form, FormParams Params)
Get the fixed byte size for a given form.
Definition: Dwarf.cpp:695
Dwarf.h
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::DWARFUnit::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize() const
Definition: DWARFUnit.h:321
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:319
llvm::DWARFUnit
Definition: DWARFUnit.h:206
DataExtractor.h
llvm::Spec
Definition: FunctionSpecialization.h:87
llvm::DWARFFormValue::extractValue
bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFContext *Context=nullptr, const DWARFUnit *Unit=nullptr)
Extracts a value in Data at offset *OffsetPtr.
Definition: DWARFFormValue.cpp:246
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration
DWARFAbbreviationDeclaration()
Definition: DWARFAbbreviationDeclaration.cpp:33
llvm::DWARFAbbreviationDeclaration::getAttributeOffsetFromIndex
uint64_t getAttributeOffsetFromIndex(uint32_t AttrIndex, uint64_t DIEOffset, const DWARFUnit &U) const
Compute an offset from a DIE specified by DIE offset and attribute index.
Definition: DWARFAbbreviationDeclaration.cpp:148
raw_ostream.h
llvm::DWARFAbbreviationDeclaration::AttributeSpec::getByteSize
std::optional< int64_t > getByteSize(const DWARFUnit &U) const
Get the fixed byte size of this Form if possible.
Definition: DWARFAbbreviationDeclaration.cpp:211
llvm::DWARFAbbreviationDeclaration::getAttributeValue
std::optional< DWARFFormValue > getAttributeValue(const uint64_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U) const
Extract a DWARF form value from a DIE specified by DIE offset.
Definition: DWARFAbbreviationDeclaration.cpp:185
DWARFDataExtractor.h