LLVM 20.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
12using namespace llvm;
13using namespace dwarf_linker;
14using namespace dwarf_linker::parallel;
15
17 // Extract and clone every attribute.
19
21 // Point to the next DIE (generally there is always at least a NULL
22 // entry after the current one). If this is a lone
23 // DW_TAG_compile_unit without any children, point to the next unit.
24 uint64_t NextOffset = (InputDIEIdx + 1 < InUnit.getOrigUnit().getNumDIEs())
27
28 // We could copy the data only if we need to apply a relocation to it. After
29 // testing, it seems there is no performance downside to doing the copy
30 // unconditionally, and it makes the code simpler.
31 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset));
32 Data =
33 DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
34
35 // Modify the copy with relocated addresses.
36 InUnit.getContaingFile().Addresses->applyValidRelocs(DIECopy, Offset,
37 Data.isLittleEndian());
38
39 // Reset the Offset to 0 as we will be working on the local copy of
40 // the data.
41 Offset = 0;
42
43 const auto *Abbrev = InputDieEntry->getAbbreviationDeclarationPtr();
44 Offset += getULEB128Size(Abbrev->getCode());
45
46 // Set current output offset.
48 for (const auto &AttrSpec : Abbrev->attributes()) {
49 // Check whether current attribute should be skipped.
50 if (shouldSkipAttribute(AttrSpec)) {
51 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
53 continue;
54 }
55
56 DWARFFormValue Val = AttrSpec.getFormValue();
59
60 // Clone current attribute.
61 switch (AttrSpec.Form) {
62 case dwarf::DW_FORM_strp:
63 case dwarf::DW_FORM_line_strp:
64 case dwarf::DW_FORM_string:
65 case dwarf::DW_FORM_strx:
66 case dwarf::DW_FORM_strx1:
67 case dwarf::DW_FORM_strx2:
68 case dwarf::DW_FORM_strx3:
69 case dwarf::DW_FORM_strx4:
70 AttrOutOffset += cloneStringAttr(Val, AttrSpec);
71 break;
72 case dwarf::DW_FORM_ref_addr:
73 case dwarf::DW_FORM_ref1:
74 case dwarf::DW_FORM_ref2:
75 case dwarf::DW_FORM_ref4:
76 case dwarf::DW_FORM_ref8:
77 case dwarf::DW_FORM_ref_udata:
78 AttrOutOffset += cloneDieRefAttr(Val, AttrSpec);
79 break;
80 case dwarf::DW_FORM_data1:
81 case dwarf::DW_FORM_data2:
82 case dwarf::DW_FORM_data4:
83 case dwarf::DW_FORM_data8:
84 case dwarf::DW_FORM_udata:
85 case dwarf::DW_FORM_sdata:
86 case dwarf::DW_FORM_sec_offset:
87 case dwarf::DW_FORM_flag:
88 case dwarf::DW_FORM_flag_present:
89 case dwarf::DW_FORM_rnglistx:
90 case dwarf::DW_FORM_loclistx:
91 case dwarf::DW_FORM_implicit_const:
92 AttrOutOffset += cloneScalarAttr(Val, AttrSpec);
93 break;
94 case dwarf::DW_FORM_block:
95 case dwarf::DW_FORM_block1:
96 case dwarf::DW_FORM_block2:
97 case dwarf::DW_FORM_block4:
98 case dwarf::DW_FORM_exprloc:
99 AttrOutOffset += cloneBlockAttr(Val, AttrSpec);
100 break;
101 case dwarf::DW_FORM_addr:
102 case dwarf::DW_FORM_addrx:
103 case dwarf::DW_FORM_addrx1:
104 case dwarf::DW_FORM_addrx2:
105 case dwarf::DW_FORM_addrx3:
106 case dwarf::DW_FORM_addrx4:
107 AttrOutOffset += cloneAddressAttr(Val, AttrSpec);
108 break;
109 default:
110 InUnit.warn("unsupported attribute form " +
111 dwarf::FormEncodingString(AttrSpec.Form) +
112 " in DieAttributeCloner::clone(). Dropping.",
114 }
115 }
116
117 // We convert source strings into the indexed form for DWARFv5.
118 // Check if original compile unit already has DW_AT_str_offsets_base
119 // attribute.
120 if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
126 true},
128
131 .addScalarAttribute(dwarf::DW_AT_str_offsets_base,
132 dwarf::DW_FORM_sec_offset,
134 .second;
135 }
136}
137
140 switch (AttrSpec.Attr) {
141 default:
142 return false;
143 case dwarf::DW_AT_low_pc:
144 case dwarf::DW_AT_high_pc:
145 case dwarf::DW_AT_ranges:
147 return false;
148
149 // Skip address attribute if we are in function scope and function does not
150 // reference live address.
151 return InUnit.getDIEInfo(InputDIEIdx).getIsInFunctionScope() &&
152 !FuncAddressAdjustment.has_value();
153 case dwarf::DW_AT_rnglists_base:
154 // In case !Update the .debug_addr table is not generated/preserved.
155 // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
156 // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
157 // DW_AT_rnglists_base is removed.
159 case dwarf::DW_AT_loclists_base:
160 // In case !Update the .debug_addr table is not generated/preserved.
161 // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
162 // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
163 // DW_AT_loclists_base is removed.
165 case dwarf::DW_AT_location:
166 case dwarf::DW_AT_frame_base:
168 return false;
169
170 // When location expression contains an address: skip this attribute
171 // if it does not reference live address.
173 return !VarAddressAdjustment.has_value();
174
175 // Skip location attribute if we are in function scope and function does not
176 // reference live address.
177 return InUnit.getDIEInfo(InputDIEIdx).getIsInFunctionScope() &&
178 !FuncAddressAdjustment.has_value();
179 }
180}
181
183 const DWARFFormValue &Val,
185 std::optional<const char *> String = dwarf::toString(Val);
186 if (!String) {
187 InUnit.warn("cann't read string attribute.");
188 return 0;
189 }
190
191 StringEntry *StringInPool =
192 InUnit.getGlobalData().getStringPool().insert(*String).first;
193
194 // Update attributes info.
195 if (AttrSpec.Attr == dwarf::DW_AT_name)
196 AttrInfo.Name = StringInPool;
197 else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
198 AttrSpec.Attr == dwarf::DW_AT_linkage_name)
199 AttrInfo.MangledName = StringInPool;
200
201 if (AttrSpec.Form == dwarf::DW_FORM_line_strp) {
202 if (OutUnit.isTypeUnit()) {
205 StringInPool});
206 } else {
209 }
210 return Generator
211 .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_line_strp)
212 .second;
213 }
214
215 if (Use_DW_FORM_strp) {
216 if (OutUnit.isTypeUnit()) {
217 DebugInfoOutputSection.notePatch(
219 InUnit.getDieTypeEntry(InputDIEIdx), StringInPool});
220 } else {
222 DebugStrPatch{{AttrOutOffset}, StringInPool}, PatchesOffsets);
223 }
224
225 return Generator
226 .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_strp)
227 .second;
228 }
229
230 return Generator
231 .addIndexedStringAttribute(AttrSpec.Attr, dwarf::DW_FORM_strx,
232 OutUnit->getDebugStrIndex(StringInPool))
233 .second;
234}
235
237 const DWARFFormValue &Val,
239 if (AttrSpec.Attr == dwarf::DW_AT_sibling)
240 return 0;
241
242 std::optional<UnitEntryPairTy> RefDiePair =
244 if (!RefDiePair || !RefDiePair->DieEntry) {
245 // If the referenced DIE is not found, drop the attribute.
246 InUnit.warn("cann't find referenced DIE.", InputDieEntry);
247 return 0;
248 }
249
250 TypeEntry *RefTypeName = nullptr;
251 const CompileUnit::DIEInfo &RefDIEInfo =
252 RefDiePair->CU->getDIEInfo(RefDiePair->DieEntry);
253 if (RefDIEInfo.needToPlaceInTypeTable())
254 RefTypeName = RefDiePair->CU->getDieTypeEntry(RefDiePair->DieEntry);
255
256 if (OutUnit.isTypeUnit()) {
257 assert(RefTypeName && "Type name for referenced DIE is not set");
259 "Type name for DIE is not set");
260
263 RefTypeName});
264
265 return Generator
266 .addScalarAttribute(AttrSpec.Attr, dwarf::DW_FORM_ref4, 0xBADDEF)
267 .second;
268 }
269
270 if (RefTypeName) {
273
274 return Generator
275 .addScalarAttribute(AttrSpec.Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
276 .second;
277 }
278
279 // Get output offset for referenced DIE.
280 uint64_t OutDieOffset = RefDiePair->CU->getDieOutOffset(RefDiePair->DieEntry);
281
282 // Examine whether referenced DIE is in current compile unit.
283 bool IsLocal = OutUnit->getUniqueID() == RefDiePair->CU->getUniqueID();
284
285 // Set attribute form basing on the kind of referenced DIE(local or not?).
286 dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr;
287
288 // Check whether current attribute references already cloned DIE inside
289 // the same compilation unit. If true - write the already known offset value.
290 if (IsLocal && (OutDieOffset != 0))
291 return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, OutDieOffset)
292 .second;
293
294 // If offset value is not known at this point then create patch for the
295 // reference value and write dummy value into the attribute.
298 RefDiePair->CU,
299 RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry)},
301 return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, 0xBADDEF).second;
302}
303
305 const DWARFFormValue &Val,
307
308 // Create patches for attribute referencing other non invariant section.
309 // Invariant section could not be updated here as this section and
310 // reference to it do not change value in case --update.
311 switch (AttrSpec.Attr) {
312 case dwarf::DW_AT_macro_info: {
313 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
314 const DWARFDebugMacro *Macro =
315 InUnit.getContaingFile().Dwarf->getDebugMacinfo();
316 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
317 return 0;
318
324 }
325 } break;
326 case dwarf::DW_AT_macros: {
327 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
328 const DWARFDebugMacro *Macro =
329 InUnit.getContaingFile().Dwarf->getDebugMacro();
330 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
331 return 0;
332
338 }
339 } break;
340 case dwarf::DW_AT_stmt_list: {
345 } break;
346 case dwarf::DW_AT_str_offsets_base: {
351 true},
353
354 // Use size of .debug_str_offsets header as attribute value. The offset
355 // to .debug_str_offsets would be added later while patching.
357 return Generator
358 .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form,
360 .second;
361 } break;
362 case dwarf::DW_AT_decl_file: {
363 // Value of DW_AT_decl_file may exceed original form. Longer
364 // form can affect offsets to the following attributes. To not
365 // update offsets of the following attributes we always remove
366 // original DW_AT_decl_file and attach it to the last position
367 // later.
368 if (OutUnit.isTypeUnit()) {
369 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
372 OutDIE,
376 .insert(DirAndFilename->first)
377 .first,
380 .insert(DirAndFilename->second)
381 .first,
382 });
383 return 0;
384 }
385 } break;
386 default: {
387 } break;
388 };
389
391 if (AttrSpec.Attr == dwarf::DW_AT_const_value &&
392 (InputDieEntry->getTag() == dwarf::DW_TAG_variable ||
393 InputDieEntry->getTag() == dwarf::DW_TAG_constant))
395
397 if (auto OptionalValue = Val.getAsUnsignedConstant())
398 Value = *OptionalValue;
399 else if (auto OptionalValue = Val.getAsSignedConstant())
400 Value = *OptionalValue;
401 else if (auto OptionalValue = Val.getAsSectionOffset())
402 Value = *OptionalValue;
403 else {
404 InUnit.warn("unsupported scalar attribute form. Dropping attribute.",
406 return 0;
407 }
408
409 if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
410 AttrInfo.IsDeclaration = true;
411
412 if (AttrSpec.Form == dwarf::DW_FORM_loclistx)
413 return Generator.addLocListAttribute(AttrSpec.Attr, AttrSpec.Form, Value)
414 .second;
415
416 return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Value)
417 .second;
418 }
419
420 dwarf::Form ResultingForm = AttrSpec.Form;
421 if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) {
422 // DWARFLinker does not generate .debug_addr table. Thus we need to change
423 // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx
424 // to DW_FORM_sec_offset here.
425 std::optional<uint64_t> Index = Val.getAsSectionOffset();
426 if (!Index) {
427 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
428 return 0;
429 }
430 std::optional<uint64_t> Offset =
432 if (!Offset) {
433 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
434 return 0;
435 }
436
437 Value = *Offset;
438 ResultingForm = dwarf::DW_FORM_sec_offset;
439 } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) {
440 // DWARFLinker does not generate .debug_addr table. Thus we need to change
441 // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx
442 // to DW_FORM_sec_offset here.
443 std::optional<uint64_t> Index = Val.getAsSectionOffset();
444 if (!Index) {
445 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
446 return 0;
447 }
448 std::optional<uint64_t> Offset =
450 if (!Offset) {
451 InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
452 return 0;
453 }
454
455 Value = *Offset;
456 ResultingForm = dwarf::DW_FORM_sec_offset;
457 } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
458 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) {
459 if (!OutUnit.isCompileUnit())
460 return 0;
461
462 std::optional<uint64_t> LowPC = OutUnit.getAsCompileUnit()->getLowPc();
463 if (!LowPC)
464 return 0;
465 // Dwarf >= 4 high_pc is an size, not an address.
466 Value = OutUnit.getAsCompileUnit()->getHighPc() - *LowPC;
467 } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
468 Value = *Val.getAsSectionOffset();
469 else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
470 Value = *Val.getAsSignedConstant();
471 else if (auto OptionalValue = Val.getAsUnsignedConstant())
472 Value = *OptionalValue;
473 else {
474 InUnit.warn("unsupported scalar attribute form. Dropping attribute.",
476 return 0;
477 }
478
479 if (AttrSpec.Attr == dwarf::DW_AT_ranges ||
480 AttrSpec.Attr == dwarf::DW_AT_start_scope) {
481 // Create patch for the range offset value.
484 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit},
486 AttrInfo.HasRanges = true;
487 } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) &&
491 int64_t AddrAdjustmentValue = 0;
493 AddrAdjustmentValue = *VarAddressAdjustment;
494 else if (FuncAddressAdjustment)
495 AddrAdjustmentValue = *FuncAddressAdjustment;
496
497 // Create patch for the location offset value.
499 DebugLocPatch{{AttrOutOffset}, AddrAdjustmentValue}, PatchesOffsets);
500 } else if (AttrSpec.Attr == dwarf::DW_AT_addr_base) {
505 true},
507
508 // Use size of .debug_addr header as attribute value. The offset to
509 // .debug_addr would be added later while patching.
510 return Generator
511 .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form,
513 .second;
514 } else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
515 AttrInfo.IsDeclaration = true;
516
517 return Generator.addScalarAttribute(AttrSpec.Attr, ResultingForm, Value)
518 .second;
519}
520
522 const DWARFFormValue &Val,
524
525 if (OutUnit.isTypeUnit())
526 return 0;
527
528 size_t NumberOfPatchesAtStart = PatchesOffsets.size();
529
530 // If the block is a DWARF Expression, clone it into the temporary
531 // buffer using cloneExpression(), otherwise copy the data directly.
533 ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
537 DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()),
542
545 Bytes = Buffer;
546 }
547
548 // The expression location data might be updated and exceed the original size.
549 // Check whether the new data fits into the original form.
550 dwarf::Form ResultForm = AttrSpec.Form;
551 if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.size() > UINT8_MAX) ||
552 (ResultForm == dwarf::DW_FORM_block2 && Bytes.size() > UINT16_MAX) ||
553 (ResultForm == dwarf::DW_FORM_block4 && Bytes.size() > UINT32_MAX))
554 ResultForm = dwarf::DW_FORM_block;
555
556 size_t FinalAttributeSize;
557 if (AttrSpec.Form == dwarf::DW_FORM_exprloc)
558 FinalAttributeSize =
559 Generator.addLocationAttribute(AttrSpec.Attr, ResultForm, Bytes).second;
560 else
561 FinalAttributeSize =
562 Generator.addBlockAttribute(AttrSpec.Attr, ResultForm, Bytes).second;
563
564 // Update patches offsets with the size of length field for Bytes.
565 for (size_t Idx = NumberOfPatchesAtStart; Idx < PatchesOffsets.size();
566 Idx++) {
567 assert(FinalAttributeSize > Bytes.size());
569 (AttrOutOffset + (FinalAttributeSize - Bytes.size()));
570 }
571
574 VarAddressAdjustment.has_value() ||
576
577 return FinalAttributeSize;
578}
579
581 const DWARFFormValue &Val,
583 if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
585
587 return Generator
588 .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Val.getRawUValue())
589 .second;
590
591 if (OutUnit.isTypeUnit())
592 return 0;
593
594 // Cloned Die may have address attributes relocated to a
595 // totally unrelated value. This can happen:
596 // - If high_pc is an address (Dwarf version == 2), then it might have been
597 // relocated to a totally unrelated value (because the end address in the
598 // object file might be start address of another function which got moved
599 // independently by the linker).
600 // - If address relocated in an inline_subprogram that happens at the
601 // beginning of its inlining function.
602 // To avoid above cases and to not apply relocation twice (in
603 // applyValidRelocs and here), read address attribute from InputDIE and apply
604 // Info.PCOffset here.
605
606 std::optional<DWARFFormValue> AddrAttribute =
607 InUnit.find(InputDieEntry, AttrSpec.Attr);
608 if (!AddrAttribute)
609 llvm_unreachable("Cann't find attribute");
610
611 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
612 if (!Addr) {
613 InUnit.warn("cann't read address attribute value.");
614 return 0;
615 }
616
617 if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
618 AttrSpec.Attr == dwarf::DW_AT_low_pc) {
619 if (std::optional<uint64_t> LowPC = OutUnit.getAsCompileUnit()->getLowPc())
620 Addr = *LowPC;
621 else
622 return 0;
623 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
624 AttrSpec.Attr == dwarf::DW_AT_high_pc) {
625 if (uint64_t HighPc = OutUnit.getAsCompileUnit()->getHighPc())
626 Addr = HighPc;
627 else
628 return 0;
629 } else {
632 else if (FuncAddressAdjustment)
634 }
635
636 if (AttrSpec.Form == dwarf::DW_FORM_addr) {
637 return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, *Addr)
638 .second;
639 }
640
641 return Generator
642 .addScalarAttribute(AttrSpec.Attr, dwarf::Form::DW_FORM_addrx,
644 .second;
645}
646
647unsigned DIEAttributeCloner::finalizeAbbreviations(bool HasChildrenToClone) {
648 // Add the size of the abbreviation number to the output offset.
650 Generator.finalizeAbbreviations(HasChildrenToClone, &PatchesOffsets);
651
652 return AttrOutOffset;
653}
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(PassOpts->AAPipeline)
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:505
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:209
std::optional< uint64_t > getRnglistOffset(uint32_t Index)
Return a rangelist's offset based on an index.
Definition: DWARFUnit.cpp:1208
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:326
std::optional< uint64_t > getLoclistOffset(uint32_t Index)
Definition: DWARFUnit.cpp:1219
uint16_t getVersion() const
Definition: DWARFUnit.h:325
bool isLittleEndian() const
Definition: DWARFUnit.h:317
uint64_t getNextUnitOffset() const
Definition: DWARFUnit.h:338
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:1209
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
std::unique_ptr< AddressesMap > Addresses
Helpful address information(list of valid address ranges, relocations).
Definition: DWARFFile.h:42
std::unique_ptr< DWARFContext > Dwarf
Source DWARF information.
Definition: DWARFFile.h:39
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.
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< uint64_t > getLowPc() const
Returns value of DW_AT_low_pc attribute.
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.
size_t cloneBlockAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone block or exprloc attribute.
AttributesInfo AttrInfo
Cannot be used concurrently.
CompileUnit & InUnit
Input compilation unit.
bool HasLocationExpressionAddress
Indicates whether InputDieEntry has an location attribute containg address expression.
SectionDescriptor & DebugInfoOutputSection
.debug_info section descriptor.
unsigned finalizeAbbreviations(bool HasChildrenToClone)
Create abbreviations for the output DIE after all attributes are cloned.
unsigned AttrOutOffset
Output offset after all attributes.
DIEGenerator & Generator
Output DIE generator.
size_t cloneScalarAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone scalar attribute.
OffsetsPtrVector PatchesOffsets
Patches for the cloned attributes.
void clone()
Clone attributes of input DIE.
size_t cloneDieRefAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone attribute referencing another DIE.
bool shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec)
Returns true if attribute should be skipped.
size_t cloneStringAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone string attribute.
const DWARFDebugInfoEntry * InputDieEntry
Input DIE entry.
std::optional< int64_t > FuncAddressAdjustment
Relocation adjustment for the function address ranges.
CompileUnit::OutputUnitVariantPtr OutUnit
Output unit(either "plain" compilation unit, either artificial type unit).
size_t cloneAddressAttr(const DWARFFormValue &Val, const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec)
Clone address attribute.
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.
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:57
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:93
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:109
std::pair< DIEValue &, size_t > addIndexedStringAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, uint64_t Idx)
Adds indexed string attribute.
Definition: DIEGenerator.h:100
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:71
size_t finalizeAbbreviations(bool CHILDREN_yes, OffsetsPtrVector *OffsetsList)
Creates appreviations for the current DIE.
Definition: DIEGenerator.h:137
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:50
unsigned getUniqueID() const
Unique id of the unit.
LinkingGlobalData & getGlobalData()
Return global data.
virtual uint64_t getDebugStrIndex(const StringEntry *String)
Returns index(inside .debug_str_offsets) of specified string.
const DWARFLinkerOptions & getOptions() const
Returns linking options.
StringPool & getStringPool()
Returns global string pool.
uint16_t getDebugStrOffsetsHeaderSize() const
Return size of header of debug_str_offsets table.
const dwarf::FormParams & getFormParams() const
Return size of address.
uint16_t getVersion() const
Return DWARF version.
uint16_t getDebugAddrHeaderSize() const
Return size of header of debug_ table.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
StringRef FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:105
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
DWARFUnit & getOrigUnit() const
Returns paired compile unit from input DWARF.
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
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:480
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:722
static bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition: DWARFDie.cpp:739
DwarfFormat Format
Definition: Dwarf.h:1080
bool IsDeclaration
Is this DIE only a declaration?
bool HasRanges
Does the DIE have a ranges attribute?
bool HasLiveAddress
Does the DIE have an address pointing to live code section?
bool HasStringOffsetBaseAttr
Does the DIE have a string offset attribute?
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...