LLVM 18.0.0git
DIEAttributeCloner.cpp
Go to the documentation of this file.
1//=== DIEAttributeCloner.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
11
12namespace llvm {
13namespace dwarflinker_parallel {
14
16 // Extract and clone every attribute.
18
20 // Point to the next DIE (generally there is always at least a NULL
21 // entry after the current one). If this is a lone
22 // DW_TAG_compile_unit without any children, point to the next unit.
23 uint64_t NextOffset = (InputDIEIdx + 1 < InUnit.getOrigUnit().getNumDIEs())
26
27 // We could copy the data only if we need to apply a relocation to it. After
28 // testing, it seems there is no performance downside to doing the copy
29 // unconditionally, and it makes the code simpler.
30 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset));
31 Data =
32 DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
33
34 // Modify the copy with relocated addresses.
35 InUnit.getContaingFile().Addresses->applyValidRelocs(DIECopy, Offset,
36 Data.isLittleEndian());
37
38 // Reset the Offset to 0 as we will be working on the local copy of
39 // the data.
40 Offset = 0;
41
42 const auto *Abbrev = InputDieEntry->getAbbreviationDeclarationPtr();
43 Offset += getULEB128Size(Abbrev->getCode());
44
45 // Set current output offset.
47 for (const auto &AttrSpec : Abbrev->attributes()) {
48 // Check whether current attribute should be skipped.
49 if (shouldSkipAttribute(AttrSpec)) {
50 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
52 continue;
53 }
54
55 DWARFFormValue Val = AttrSpec.getFormValue();
58
59 // Clone current attribute.
60 switch (AttrSpec.Form) {
61 case dwarf::DW_FORM_strp:
62 case dwarf::DW_FORM_line_strp:
63 case dwarf::DW_FORM_string:
64 case dwarf::DW_FORM_strx:
65 case dwarf::DW_FORM_strx1:
66 case dwarf::DW_FORM_strx2:
67 case dwarf::DW_FORM_strx3:
68 case dwarf::DW_FORM_strx4:
69 AttrOutOffset += cloneStringAttr(Val, AttrSpec);
70 break;
71 case dwarf::DW_FORM_ref_addr:
72 case dwarf::DW_FORM_ref1:
73 case dwarf::DW_FORM_ref2:
74 case dwarf::DW_FORM_ref4:
75 case dwarf::DW_FORM_ref8:
76 case dwarf::DW_FORM_ref_udata:
77 AttrOutOffset += cloneDieRefAttr(Val, AttrSpec);
78 break;
79 case dwarf::DW_FORM_data1:
80 case dwarf::DW_FORM_data2:
81 case dwarf::DW_FORM_data4:
82 case dwarf::DW_FORM_data8:
83 case dwarf::DW_FORM_udata:
84 case dwarf::DW_FORM_sdata:
85 case dwarf::DW_FORM_sec_offset:
86 case dwarf::DW_FORM_flag:
87 case dwarf::DW_FORM_flag_present:
88 case dwarf::DW_FORM_rnglistx:
89 case dwarf::DW_FORM_loclistx:
90 case dwarf::DW_FORM_implicit_const:
91 AttrOutOffset += cloneScalarAttr(Val, AttrSpec);
92 break;
93 case dwarf::DW_FORM_block:
94 case dwarf::DW_FORM_block1:
95 case dwarf::DW_FORM_block2:
96 case dwarf::DW_FORM_block4:
97 case dwarf::DW_FORM_exprloc:
98 AttrOutOffset += cloneBlockAttr(Val, AttrSpec);
99 break;
100 case dwarf::DW_FORM_addr:
101 case dwarf::DW_FORM_addrx:
102 case dwarf::DW_FORM_addrx1:
103 case dwarf::DW_FORM_addrx2:
104 case dwarf::DW_FORM_addrx3:
105 case dwarf::DW_FORM_addrx4:
106 AttrOutOffset += cloneAddressAttr(Val, AttrSpec);
107 break;
108 default:
109 InUnit.warn("unsupported attribute form " +
110 dwarf::FormEncodingString(AttrSpec.Form) +
111 " in DieAttributeCloner::clone(). Dropping.",
113 }
114 }
115
116 // We convert source strings into the indexed form for DWARFv5.
117 // Check if original compile unit already has DW_AT_str_offsets_base
118 // attribute.
119 if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
125 true},
127
130 .addScalarAttribute(dwarf::DW_AT_str_offsets_base,
131 dwarf::DW_FORM_sec_offset,
133 .second;
134 }
135}
136
139 switch (AttrSpec.Attr) {
140 default:
141 return false;
142 case dwarf::DW_AT_low_pc:
143 case dwarf::DW_AT_high_pc:
144 case dwarf::DW_AT_ranges:
146 return false;
147
148 // Skip address attribute if we are in function scope and function does not
149 // reference live address.
150 return InUnit.getDIEInfo(InputDIEIdx).getIsInFunctionScope() &&
151 !FuncAddressAdjustment.has_value();
152 case dwarf::DW_AT_rnglists_base:
153 // In case !Update the .debug_addr table is not generated/preserved.
154 // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
155 // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
156 // DW_AT_rnglists_base is removed.
158 case dwarf::DW_AT_loclists_base:
159 // In case !Update the .debug_addr table is not generated/preserved.
160 // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
161 // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
162 // DW_AT_loclists_base is removed.
164 case dwarf::DW_AT_location:
165 case dwarf::DW_AT_frame_base:
167 return false;
168
169 // When location expression contains an address: skip this attribute
170 // if it does not reference live address.
172 return !VarAddressAdjustment.has_value();
173
174 // Skip location attribute if we are in function scope and function does not
175 // reference live address.
176 return InUnit.getDIEInfo(InputDIEIdx).getIsInFunctionScope() &&
177 !FuncAddressAdjustment.has_value();
178 }
179}
180
182 const DWARFFormValue &Val,
184 std::optional<const char *> String = dwarf::toString(Val);
185 if (!String) {
186 InUnit.warn("cann't read string attribute.");
187 return 0;
188 }
189
190 StringEntry *StringInPool =
191 InUnit.getGlobalData().getStringPool().insert(*String).first;
192
193 // Update attributes info.
194 if (AttrSpec.Attr == dwarf::DW_AT_name)
195 AttrInfo.Name = StringInPool;
196 else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
197 AttrSpec.Attr == dwarf::DW_AT_linkage_name)
198 AttrInfo.MangledName = StringInPool;
199
200 if (AttrSpec.Form == dwarf::DW_FORM_line_strp) {
201 if (OutUnit.isTypeUnit()) {
204 StringInPool});
205 } else {
208 }
209 return Generator
210 .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_line_strp)
211 .second;
212 }
213
214 if (Use_DW_FORM_strp) {
215 if (OutUnit.isTypeUnit()) {
216 DebugInfoOutputSection.notePatch(
218 InUnit.getDieTypeEntry(InputDIEIdx), StringInPool});
219 } else {
221 DebugStrPatch{{AttrOutOffset}, StringInPool}, PatchesOffsets);
222 }
223
224 return Generator
225 .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_strp)
226 .second;
227 }
228
229 return Generator
230 .addIndexedStringAttribute(AttrSpec.Attr, dwarf::DW_FORM_strx,
231 OutUnit->getDebugStrIndex(StringInPool))
232 .second;
233}
234
236 const DWARFFormValue &Val,
238 if (AttrSpec.Attr == dwarf::DW_AT_sibling)
239 return 0;
240
241 std::optional<UnitEntryPairTy> RefDiePair =
243 if (!RefDiePair || !RefDiePair->DieEntry) {
244 // If the referenced DIE is not found, drop the attribute.
245 InUnit.warn("cann't find referenced DIE.", InputDieEntry);
246 return 0;
247 }
248
249 TypeEntry *RefTypeName = nullptr;
250 const CompileUnit::DIEInfo &RefDIEInfo =
251 RefDiePair->CU->getDIEInfo(RefDiePair->DieEntry);
252 if (RefDIEInfo.needToPlaceInTypeTable())
253 RefTypeName = RefDiePair->CU->getDieTypeEntry(RefDiePair->DieEntry);
254
255 if (OutUnit.isTypeUnit()) {
256 assert(RefTypeName && "Type name for referenced DIE is not set");
258 "Type name for DIE is not set");
259
262 RefTypeName});
263
264 return Generator
265 .addScalarAttribute(AttrSpec.Attr, dwarf::DW_FORM_ref4, 0xBADDEF)
266 .second;
267 }
268
269 if (RefTypeName) {
272
273 return Generator
274 .addScalarAttribute(AttrSpec.Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
275 .second;
276 }
277
278 // Get output offset for referenced DIE.
279 uint64_t OutDieOffset = RefDiePair->CU->getDieOutOffset(RefDiePair->DieEntry);
280
281 // Examine whether referenced DIE is in current compile unit.
282 bool IsLocal = OutUnit->getUniqueID() == RefDiePair->CU->getUniqueID();
283
284 // Set attribute form basing on the kind of referenced DIE(local or not?).
285 dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr;
286
287 // Check whether current attribute references already cloned DIE inside
288 // the same compilation unit. If true - write the already known offset value.
289 if (IsLocal && (OutDieOffset != 0))
290 return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, OutDieOffset)
291 .second;
292
293 // If offset value is not known at this point then create patch for the
294 // reference value and write dummy value into the attribute.
297 RefDiePair->CU,
298 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry)},
300 return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, 0xBADDEF).second;
301}
302
304 const DWARFFormValue &Val,
306
307 // Create patches for attribute referencing other non invariant section.
308 // Invariant section could not be updated here as this section and
309 // reference to it do not change value in case --update.
310 switch (AttrSpec.Attr) {
311 case dwarf::DW_AT_macro_info: {
312 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
313 const DWARFDebugMacro *Macro =
314 InUnit.getContaingFile().Dwarf->getDebugMacinfo();
315 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
316 return 0;
317
323 }
324 } break;
325 case dwarf::DW_AT_macros: {
326 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
327 const DWARFDebugMacro *Macro =
328 InUnit.getContaingFile().Dwarf->getDebugMacro();
329 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
330 return 0;
331
337 }
338 } break;
339 case dwarf::DW_AT_stmt_list: {
344 } break;
345 case dwarf::DW_AT_str_offsets_base: {
350 true},
352
353 // Use size of .debug_str_offsets header as attribute value. The offset
354 // to .debug_str_offsets would be added later while patching.
356 return Generator
357 .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form,
359 .second;
360 } break;
361 case dwarf::DW_AT_decl_file: {
362 // Value of DW_AT_decl_file may exceed original form. Longer
363 // form can affect offsets to the following attributes. To not
364 // update offsets of the following attributes we always remove
365 // original DW_AT_decl_file and attach it to the last position
366 // later.
367 if (OutUnit.isTypeUnit()) {
368 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
371 OutDIE,
375 .insert(DirAndFilename->first)
376 .first,
379 .insert(DirAndFilename->second)
380 .first,
381 });
382 return 0;
383 }
384 } break;
385 default: {
386 } break;
387 };
388
390 if (AttrSpec.Attr == dwarf::DW_AT_const_value &&
391 (InputDieEntry->getTag() == dwarf::DW_TAG_variable ||
392 InputDieEntry->getTag() == dwarf::DW_TAG_constant))
394
396 if (auto OptionalValue = Val.getAsUnsignedConstant())
397 Value = *OptionalValue;
398 else if (auto OptionalValue = Val.getAsSignedConstant())
399 Value = *OptionalValue;
400 else if (auto OptionalValue = Val.getAsSectionOffset())
401 Value = *OptionalValue;
402 else {
403 InUnit.warn("unsupported scalar attribute form. Dropping attribute.",
405 return 0;
406 }
407
408 if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
409 AttrInfo.IsDeclaration = true;
410
411 if (AttrSpec.Form == dwarf::DW_FORM_loclistx)
412 return Generator.addLocListAttribute(AttrSpec.Attr, AttrSpec.Form, Value)
413 .second;
414
415 return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Value)
416 .second;
417 }
418
419 dwarf::Form ResultingForm = AttrSpec.Form;
420 if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) {
421 // DWARFLinker does not generate .debug_addr table. Thus we need to change
422 // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx
423 // to DW_FORM_sec_offset here.
424 std::optional<uint64_t> Index = Val.getAsSectionOffset();
425 if (!Index) {
426 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
427 return 0;
428 }
429 std::optional<uint64_t> Offset =
431 if (!Offset) {
432 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
433 return 0;
434 }
435
436 Value = *Offset;
437 ResultingForm = dwarf::DW_FORM_sec_offset;
438 } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) {
439 // DWARFLinker does not generate .debug_addr table. Thus we need to change
440 // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx
441 // to DW_FORM_sec_offset here.
442 std::optional<uint64_t> Index = Val.getAsSectionOffset();
443 if (!Index) {
444 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
445 return 0;
446 }
447 std::optional<uint64_t> Offset =
449 if (!Offset) {
450 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
451 return 0;
452 }
453
454 Value = *Offset;
455 ResultingForm = dwarf::DW_FORM_sec_offset;
456 } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
457 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) {
458 if (!OutUnit.isCompileUnit())
459 return 0;
460
461 std::optional<uint64_t> LowPC = OutUnit.getAsCompileUnit()->getLowPc();
462 if (!LowPC)
463 return 0;
464 // Dwarf >= 4 high_pc is an size, not an address.
465 Value = OutUnit.getAsCompileUnit()->getHighPc() - *LowPC;
466 } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
467 Value = *Val.getAsSectionOffset();
468 else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
469 Value = *Val.getAsSignedConstant();
470 else if (auto OptionalValue = Val.getAsUnsignedConstant())
471 Value = *OptionalValue;
472 else {
473 InUnit.warn("unsupported scalar attribute form. Dropping attribute.",
475 return 0;
476 }
477
478 if (AttrSpec.Attr == dwarf::DW_AT_ranges ||
479 AttrSpec.Attr == dwarf::DW_AT_start_scope) {
480 // Create patch for the range offset value.
483 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit},
485 AttrInfo.HasRanges = true;
486 } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) &&
490 int64_t AddrAdjustmentValue = 0;
492 AddrAdjustmentValue = *VarAddressAdjustment;
493 else if (FuncAddressAdjustment)
494 AddrAdjustmentValue = *FuncAddressAdjustment;
495
496 // Create patch for the location offset value.
498 DebugLocPatch{{AttrOutOffset}, AddrAdjustmentValue}, PatchesOffsets);
499 } else if (AttrSpec.Attr == dwarf::DW_AT_addr_base) {
504 true},
506
507 // Use size of .debug_addr header as attribute value. The offset to
508 // .debug_addr would be added later while patching.
509 return Generator
510 .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form,
512 .second;
513 } else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
514 AttrInfo.IsDeclaration = true;
515
516 return Generator.addScalarAttribute(AttrSpec.Attr, ResultingForm, Value)
517 .second;
518}
519
521 const DWARFFormValue &Val,
523
524 if (OutUnit.isTypeUnit())
525 return 0;
526
527 size_t NumberOfPatchesAtStart = PatchesOffsets.size();
528
529 // If the block is a DWARF Expression, clone it into the temporary
530 // buffer using cloneExpression(), otherwise copy the data directly.
532 ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
536 DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()),
541
544 Bytes = Buffer;
545 }
546
547 // The expression location data might be updated and exceed the original size.
548 // Check whether the new data fits into the original form.
549 dwarf::Form ResultForm = AttrSpec.Form;
550 if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.size() > UINT8_MAX) ||
551 (ResultForm == dwarf::DW_FORM_block2 && Bytes.size() > UINT16_MAX) ||
552 (ResultForm == dwarf::DW_FORM_block4 && Bytes.size() > UINT32_MAX))
553 ResultForm = dwarf::DW_FORM_block;
554
555 size_t FinalAttributeSize;
556 if (AttrSpec.Form == dwarf::DW_FORM_exprloc)
557 FinalAttributeSize =
558 Generator.addLocationAttribute(AttrSpec.Attr, ResultForm, Bytes).second;
559 else
560 FinalAttributeSize =
561 Generator.addBlockAttribute(AttrSpec.Attr, ResultForm, Bytes).second;
562
563 // Update patches offsets with the size of length field for Bytes.
564 for (size_t Idx = NumberOfPatchesAtStart; Idx < PatchesOffsets.size();
565 Idx++) {
566 assert(FinalAttributeSize > Bytes.size());
568 (AttrOutOffset + (FinalAttributeSize - Bytes.size()));
569 }
570
573 VarAddressAdjustment.has_value() ||
575
576 return FinalAttributeSize;
577}
578
580 const DWARFFormValue &Val,
582 if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
584
586 return Generator
587 .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Val.getRawUValue())
588 .second;
589
590 if (OutUnit.isTypeUnit())
591 return 0;
592
593 // Cloned Die may have address attributes relocated to a
594 // totally unrelated value. This can happen:
595 // - If high_pc is an address (Dwarf version == 2), then it might have been
596 // relocated to a totally unrelated value (because the end address in the
597 // object file might be start address of another function which got moved
598 // independently by the linker).
599 // - If address relocated in an inline_subprogram that happens at the
600 // beginning of its inlining function.
601 // To avoid above cases and to not apply relocation twice (in
602 // applyValidRelocs and here), read address attribute from InputDIE and apply
603 // Info.PCOffset here.
604
605 std::optional<DWARFFormValue> AddrAttribute =
606 InUnit.find(InputDieEntry, AttrSpec.Attr);
607 if (!AddrAttribute)
608 llvm_unreachable("Cann't find attribute");
609
610 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
611 if (!Addr) {
612 InUnit.warn("cann't read address attribute value.");
613 return 0;
614 }
615
616 if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
617 AttrSpec.Attr == dwarf::DW_AT_low_pc) {
618 if (std::optional<uint64_t> LowPC = OutUnit.getAsCompileUnit()->getLowPc())
619 Addr = *LowPC;
620 else
621 return 0;
622 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
623 AttrSpec.Attr == dwarf::DW_AT_high_pc) {
624 if (uint64_t HighPc = OutUnit.getAsCompileUnit()->getHighPc())
625 Addr = HighPc;
626 else
627 return 0;
628 } else {
631 else if (FuncAddressAdjustment)
633 }
634
635 if (AttrSpec.Form == dwarf::DW_FORM_addr) {
636 return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, *Addr)
637 .second;
638 }
639
640 return Generator
641 .addScalarAttribute(AttrSpec.Attr, dwarf::Form::DW_FORM_addrx,
643 .second;
644}
645
646unsigned DIEAttributeCloner::finalizeAbbreviations(bool HasChildrenToClone) {
647 // Add the size of the abbreviation number to the output offset.
649 Generator.finalizeAbbreviations(HasChildrenToClone, &PatchesOffsets);
650
651 return AttrOutOffset;
652}
653
654} // end of namespace dwarflinker_parallel
655} // namespace llvm
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
if(VerifyEach)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
const T * data() const
Definition: ArrayRef.h:162
std::pair< KeyDataTy *, bool > insert(const KeyTy &NewValue)
Insert new value NewValue or return already existing entry.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:857
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
uint64_t getOffset() const
Get the absolute offset into the debug info or types section.
Definition: DWARFDie.h:66
std::optional< ArrayRef< uint8_t > > getAsBlock() const
std::optional< uint64_t > getAsSectionOffset() const
bool isFormClass(FormClass FC) const
std::optional< int64_t > getAsSignedConstant() const
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.
std::optional< uint64_t > getAsUnsignedConstant() const
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.
uint64_t getRawUValue() const
unsigned getNumDIEs()
Returns the number of DIEs in the unit.
Definition: DWARFUnit.h:503
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:205
std::optional< uint64_t > getRnglistOffset(uint32_t Index)
Return a rangelist's offset based on an index.
Definition: DWARFUnit.cpp:1185
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:324
std::optional< uint64_t > getLoclistOffset(uint32_t Index)
Definition: DWARFUnit.cpp:1196
uint16_t getVersion() const
Definition: DWARFUnit.h:323
bool isLittleEndian() const
Definition: DWARFUnit.h:315
uint64_t getNextUnitOffset() const
Definition: DWARFUnit.h:336
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
size_t size() const
Definition: SmallVector.h:91
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
LLVM Value Representation.
Definition: Value.h:74
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
void cloneDieAttrExpression(const DWARFExpression &InputExpression, SmallVectorImpl< uint8_t > &OutputExpression, SectionDescriptor &Section, std::optional< int64_t > VarAddressAdjustment, OffsetsPtrVector &PatchesOffsets)
Clone attribute location axpression.
uint64_t getHighPc() const
Returns value of DW_AT_high_pc attribute.
std::optional< uint64_t > getLowPc() const
Returns value of DW_AT_low_pc attribute.
uint64_t getDebugAddrIndex(uint64_t Addr)
Returns index(inside .debug_addr) of an address.
const DWARFFile & getContaingFile() const
Returns DWARFFile containing this compile unit.
std::optional< std::pair< StringRef, StringRef > > getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue)
Returns directory and file from the line table by index.
std::optional< UnitEntryPairTy > resolveDIEReference(const DWARFFormValue &RefValue, ResolveInterCUReferencesMode CanResolveInterCUReferences)
Resolve the DIE attribute reference that has been extracted in RefValue.
CompileUnit & InUnit
Input compilation unit.
void clone()
Clone attributes of input DIE.
bool shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec)
Returns true if attribute should be skipped.
bool HasLocationExpressionAddress
Indicates whether InputDieEntry has an location attribute containg address expression.
size_t cloneScalarAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone scalar attribute.
size_t cloneStringAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone string attribute.
size_t cloneAddressAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone address attribute.
unsigned finalizeAbbreviations(bool HasChildrenToClone)
Create abbreviations for the output DIE after all attributes are cloned.
OffsetsPtrVector PatchesOffsets
Patches for the cloned attributes.
std::optional< int64_t > VarAddressAdjustment
Relocation adjustment for the variable locations.
bool Use_DW_FORM_strp
This flag forces using DW_FORM_strp for string attributes.
size_t cloneBlockAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone block or exprloc attribute.
size_t cloneDieRefAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone attribute referencing another DIE.
CompileUnit::OutputUnitVariantPtr OutUnit
Output unit(either "plain" compilation unit, either artificial type unit).
AttributesInfo AttrInfo
Cannot be used concurrently.
const DWARFDebugInfoEntry * InputDieEntry
Input DIE entry.
DIEGenerator & Generator
Output DIE generator.
SectionDescriptor & DebugInfoOutputSection
.debug_info section descriptor.
std::optional< int64_t > FuncAddressAdjustment
Relocation adjustment for the function address ranges.
unsigned AttrOutOffset
Output offset after all attributes.
std::pair< DIEValue &, size_t > addBlockAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, ArrayRef< uint8_t > Bytes)
Adds specified block or exprloc attribute to the current DIE.
Definition: DIEGenerator.h:70
std::pair< DIEValue &, size_t > addLocationAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, ArrayRef< uint8_t > Bytes)
Adds specified location attribute to the current DIE.
Definition: DIEGenerator.h:56
size_t finalizeAbbreviations(bool CHILDREN_yes, OffsetsPtrVector *OffsetsList)
Creates appreviations for the current DIE.
Definition: DIEGenerator.h:136
std::pair< DIEValue &, size_t > addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm)
Adds string attribute with dummy offset to the current DIE.
Definition: DIEGenerator.h:108
std::pair< DIEValue &, size_t > addScalarAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, uint64_t Value)
Adds specified scalar attribute to the current DIE.
Definition: DIEGenerator.h:49
std::pair< DIEValue &, size_t > addIndexedStringAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, uint64_t Idx)
Adds indexed string attribute.
Definition: DIEGenerator.h:99
std::pair< DIEValue &, size_t > addLocListAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, uint64_t Value)
Adds specified location list attribute to the current DIE.
Definition: DIEGenerator.h:92
std::unique_ptr< DWARFContext > Dwarf
Source DWARF information.
Definition: DWARFFile.h:38
std::unique_ptr< AddressesMap > Addresses
Helpful address information(list of valid address ranges, relocations).
Definition: DWARFFile.h:41
unsigned getUniqueID() const
Unique id of the unit.
virtual uint64_t getDebugStrIndex(const StringEntry *String)
Returns index(inside .debug_str_offsets) of specified string.
LinkingGlobalData & getGlobalData()
Return global data.
StringPool & getStringPool()
Returns global string pool.
const DWARFLinkerOptions & getOptions() const
Returns linking options.
uint16_t getVersion() const
Return DWARF version.
uint16_t getDebugStrOffsetsHeaderSize() const
Return size of header of debug_str_offsets table.
uint16_t getDebugAddrHeaderSize() const
Return size of header of debug_ table.
const dwarf::FormParams & getFormParams() const
Return size of address.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
StringRef FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:105
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
DWARFUnit & getOrigUnit() const
Returns paired compile unit from input DWARF.
void warn(const Twine &Warning, const DWARFDie *DIE=nullptr)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC, uint16_t DwarfVersion)
Check whether specified Form belongs to the FC class.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19
static bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
Definition: DWARFDie.cpp:706
static bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition: DWARFDie.cpp:723
DwarfFormat Format
Definition: Dwarf.h:746
bool HasLiveAddress
Does the DIE have an address pointing to live code section?
bool IsDeclaration
Is this DIE only a declaration?
bool HasStringOffsetBaseAttr
Does the DIE have a string offset attribute?
bool HasRanges
Does the DIE have a ranges attribute?
Information gathered about source DIEs.
This structure is used to update reference to the DIE.
This structure is used to update reference to the type DIE.
This structure is used to update strings offsets into .debug_line_str.
This structure is used to update location list offset into .debug_loc/.debug_loclists.
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
This structure is used to update strings offsets into .debug_str.
This structure is used to update reference to the type DIE.
void notePatchWithOffsetUpdate(const T &Patch, OffsetsPtrVector &PatchesOffsetsList)
While creating patches, offsets to attributes may be partially unknown(because size of abbreviation n...