xref: /llvm-project/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.cpp (revision 2357e899cb11e05312c54b689ebd0355487be6bc)
1*2357e899Savl-llvm //=== DIEAttributeCloner.cpp ----------------------------------------------===//
2*2357e899Savl-llvm //
3*2357e899Savl-llvm // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2357e899Savl-llvm // See https://llvm.org/LICENSE.txt for license information.
5*2357e899Savl-llvm // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*2357e899Savl-llvm //
7*2357e899Savl-llvm //===----------------------------------------------------------------------===//
8*2357e899Savl-llvm 
9*2357e899Savl-llvm #include "DIEAttributeCloner.h"
10*2357e899Savl-llvm #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
11*2357e899Savl-llvm 
12*2357e899Savl-llvm using namespace llvm;
13*2357e899Savl-llvm using namespace dwarf_linker;
14*2357e899Savl-llvm using namespace dwarf_linker::parallel;
15*2357e899Savl-llvm 
clone()16*2357e899Savl-llvm void DIEAttributeCloner::clone() {
17*2357e899Savl-llvm   // Extract and clone every attribute.
18*2357e899Savl-llvm   DWARFDataExtractor Data = InUnit.getOrigUnit().getDebugInfoExtractor();
19*2357e899Savl-llvm 
20*2357e899Savl-llvm   uint64_t Offset = InputDieEntry->getOffset();
21*2357e899Savl-llvm   // Point to the next DIE (generally there is always at least a NULL
22*2357e899Savl-llvm   // entry after the current one). If this is a lone
23*2357e899Savl-llvm   // DW_TAG_compile_unit without any children, point to the next unit.
24*2357e899Savl-llvm   uint64_t NextOffset = (InputDIEIdx + 1 < InUnit.getOrigUnit().getNumDIEs())
25*2357e899Savl-llvm                             ? InUnit.getDIEAtIndex(InputDIEIdx + 1).getOffset()
26*2357e899Savl-llvm                             : InUnit.getOrigUnit().getNextUnitOffset();
27*2357e899Savl-llvm 
28*2357e899Savl-llvm   // We could copy the data only if we need to apply a relocation to it. After
29*2357e899Savl-llvm   // testing, it seems there is no performance downside to doing the copy
30*2357e899Savl-llvm   // unconditionally, and it makes the code simpler.
31*2357e899Savl-llvm   SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset));
32*2357e899Savl-llvm   Data =
33*2357e899Savl-llvm       DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
34*2357e899Savl-llvm 
35*2357e899Savl-llvm   // Modify the copy with relocated addresses.
36*2357e899Savl-llvm   InUnit.getContaingFile().Addresses->applyValidRelocs(DIECopy, Offset,
37*2357e899Savl-llvm                                                        Data.isLittleEndian());
38*2357e899Savl-llvm 
39*2357e899Savl-llvm   // Reset the Offset to 0 as we will be working on the local copy of
40*2357e899Savl-llvm   // the data.
41*2357e899Savl-llvm   Offset = 0;
42*2357e899Savl-llvm 
43*2357e899Savl-llvm   const auto *Abbrev = InputDieEntry->getAbbreviationDeclarationPtr();
44*2357e899Savl-llvm   Offset += getULEB128Size(Abbrev->getCode());
45*2357e899Savl-llvm 
46*2357e899Savl-llvm   // Set current output offset.
47*2357e899Savl-llvm   AttrOutOffset = OutUnit.isCompileUnit() ? OutDIE->getOffset() : 0;
48*2357e899Savl-llvm   for (const auto &AttrSpec : Abbrev->attributes()) {
49*2357e899Savl-llvm     // Check whether current attribute should be skipped.
50*2357e899Savl-llvm     if (shouldSkipAttribute(AttrSpec)) {
51*2357e899Savl-llvm       DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
52*2357e899Savl-llvm                                 InUnit.getFormParams());
53*2357e899Savl-llvm       continue;
54*2357e899Savl-llvm     }
55*2357e899Savl-llvm 
56*2357e899Savl-llvm     DWARFFormValue Val = AttrSpec.getFormValue();
57*2357e899Savl-llvm     Val.extractValue(Data, &Offset, InUnit.getFormParams(),
58*2357e899Savl-llvm                      &InUnit.getOrigUnit());
59*2357e899Savl-llvm 
60*2357e899Savl-llvm     // Clone current attribute.
61*2357e899Savl-llvm     switch (AttrSpec.Form) {
62*2357e899Savl-llvm     case dwarf::DW_FORM_strp:
63*2357e899Savl-llvm     case dwarf::DW_FORM_line_strp:
64*2357e899Savl-llvm     case dwarf::DW_FORM_string:
65*2357e899Savl-llvm     case dwarf::DW_FORM_strx:
66*2357e899Savl-llvm     case dwarf::DW_FORM_strx1:
67*2357e899Savl-llvm     case dwarf::DW_FORM_strx2:
68*2357e899Savl-llvm     case dwarf::DW_FORM_strx3:
69*2357e899Savl-llvm     case dwarf::DW_FORM_strx4:
70*2357e899Savl-llvm       AttrOutOffset += cloneStringAttr(Val, AttrSpec);
71*2357e899Savl-llvm       break;
72*2357e899Savl-llvm     case dwarf::DW_FORM_ref_addr:
73*2357e899Savl-llvm     case dwarf::DW_FORM_ref1:
74*2357e899Savl-llvm     case dwarf::DW_FORM_ref2:
75*2357e899Savl-llvm     case dwarf::DW_FORM_ref4:
76*2357e899Savl-llvm     case dwarf::DW_FORM_ref8:
77*2357e899Savl-llvm     case dwarf::DW_FORM_ref_udata:
78*2357e899Savl-llvm       AttrOutOffset += cloneDieRefAttr(Val, AttrSpec);
79*2357e899Savl-llvm       break;
80*2357e899Savl-llvm     case dwarf::DW_FORM_data1:
81*2357e899Savl-llvm     case dwarf::DW_FORM_data2:
82*2357e899Savl-llvm     case dwarf::DW_FORM_data4:
83*2357e899Savl-llvm     case dwarf::DW_FORM_data8:
84*2357e899Savl-llvm     case dwarf::DW_FORM_udata:
85*2357e899Savl-llvm     case dwarf::DW_FORM_sdata:
86*2357e899Savl-llvm     case dwarf::DW_FORM_sec_offset:
87*2357e899Savl-llvm     case dwarf::DW_FORM_flag:
88*2357e899Savl-llvm     case dwarf::DW_FORM_flag_present:
89*2357e899Savl-llvm     case dwarf::DW_FORM_rnglistx:
90*2357e899Savl-llvm     case dwarf::DW_FORM_loclistx:
91*2357e899Savl-llvm     case dwarf::DW_FORM_implicit_const:
92*2357e899Savl-llvm       AttrOutOffset += cloneScalarAttr(Val, AttrSpec);
93*2357e899Savl-llvm       break;
94*2357e899Savl-llvm     case dwarf::DW_FORM_block:
95*2357e899Savl-llvm     case dwarf::DW_FORM_block1:
96*2357e899Savl-llvm     case dwarf::DW_FORM_block2:
97*2357e899Savl-llvm     case dwarf::DW_FORM_block4:
98*2357e899Savl-llvm     case dwarf::DW_FORM_exprloc:
99*2357e899Savl-llvm       AttrOutOffset += cloneBlockAttr(Val, AttrSpec);
100*2357e899Savl-llvm       break;
101*2357e899Savl-llvm     case dwarf::DW_FORM_addr:
102*2357e899Savl-llvm     case dwarf::DW_FORM_addrx:
103*2357e899Savl-llvm     case dwarf::DW_FORM_addrx1:
104*2357e899Savl-llvm     case dwarf::DW_FORM_addrx2:
105*2357e899Savl-llvm     case dwarf::DW_FORM_addrx3:
106*2357e899Savl-llvm     case dwarf::DW_FORM_addrx4:
107*2357e899Savl-llvm       AttrOutOffset += cloneAddressAttr(Val, AttrSpec);
108*2357e899Savl-llvm       break;
109*2357e899Savl-llvm     default:
110*2357e899Savl-llvm       InUnit.warn("unsupported attribute form " +
111*2357e899Savl-llvm                       dwarf::FormEncodingString(AttrSpec.Form) +
112*2357e899Savl-llvm                       " in DieAttributeCloner::clone(). Dropping.",
113*2357e899Savl-llvm                   InputDieEntry);
114*2357e899Savl-llvm     }
115*2357e899Savl-llvm   }
116*2357e899Savl-llvm 
117*2357e899Savl-llvm   // We convert source strings into the indexed form for DWARFv5.
118*2357e899Savl-llvm   // Check if original compile unit already has DW_AT_str_offsets_base
119*2357e899Savl-llvm   // attribute.
120*2357e899Savl-llvm   if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
121*2357e899Savl-llvm       InUnit.getVersion() >= 5 && !AttrInfo.HasStringOffsetBaseAttr) {
122*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
123*2357e899Savl-llvm         DebugOffsetPatch{AttrOutOffset,
124*2357e899Savl-llvm                          &OutUnit->getOrCreateSectionDescriptor(
125*2357e899Savl-llvm                              DebugSectionKind::DebugStrOffsets),
126*2357e899Savl-llvm                          true},
127*2357e899Savl-llvm         PatchesOffsets);
128*2357e899Savl-llvm 
129*2357e899Savl-llvm     AttrOutOffset +=
130*2357e899Savl-llvm         Generator
131*2357e899Savl-llvm             .addScalarAttribute(dwarf::DW_AT_str_offsets_base,
132*2357e899Savl-llvm                                 dwarf::DW_FORM_sec_offset,
133*2357e899Savl-llvm                                 OutUnit->getDebugStrOffsetsHeaderSize())
134*2357e899Savl-llvm             .second;
135*2357e899Savl-llvm   }
136*2357e899Savl-llvm }
137*2357e899Savl-llvm 
shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec)138*2357e899Savl-llvm bool DIEAttributeCloner::shouldSkipAttribute(
139*2357e899Savl-llvm     DWARFAbbreviationDeclaration::AttributeSpec AttrSpec) {
140*2357e899Savl-llvm   switch (AttrSpec.Attr) {
141*2357e899Savl-llvm   default:
142*2357e899Savl-llvm     return false;
143*2357e899Savl-llvm   case dwarf::DW_AT_low_pc:
144*2357e899Savl-llvm   case dwarf::DW_AT_high_pc:
145*2357e899Savl-llvm   case dwarf::DW_AT_ranges:
146*2357e899Savl-llvm     if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
147*2357e899Savl-llvm       return false;
148*2357e899Savl-llvm 
149*2357e899Savl-llvm     // Skip address attribute if we are in function scope and function does not
150*2357e899Savl-llvm     // reference live address.
151*2357e899Savl-llvm     return InUnit.getDIEInfo(InputDIEIdx).getIsInFunctionScope() &&
152*2357e899Savl-llvm            !FuncAddressAdjustment.has_value();
153*2357e899Savl-llvm   case dwarf::DW_AT_rnglists_base:
154*2357e899Savl-llvm     // In case !Update the .debug_addr table is not generated/preserved.
155*2357e899Savl-llvm     // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
156*2357e899Savl-llvm     // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
157*2357e899Savl-llvm     // DW_AT_rnglists_base is removed.
158*2357e899Savl-llvm     return !InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
159*2357e899Savl-llvm   case dwarf::DW_AT_loclists_base:
160*2357e899Savl-llvm     // In case !Update the .debug_addr table is not generated/preserved.
161*2357e899Savl-llvm     // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
162*2357e899Savl-llvm     // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
163*2357e899Savl-llvm     // DW_AT_loclists_base is removed.
164*2357e899Savl-llvm     return !InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
165*2357e899Savl-llvm   case dwarf::DW_AT_location:
166*2357e899Savl-llvm   case dwarf::DW_AT_frame_base:
167*2357e899Savl-llvm     if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
168*2357e899Savl-llvm       return false;
169*2357e899Savl-llvm 
170*2357e899Savl-llvm     // When location expression contains an address: skip this attribute
171*2357e899Savl-llvm     // if it does not reference live address.
172*2357e899Savl-llvm     if (HasLocationExpressionAddress)
173*2357e899Savl-llvm       return !VarAddressAdjustment.has_value();
174*2357e899Savl-llvm 
175*2357e899Savl-llvm     // Skip location attribute if we are in function scope and function does not
176*2357e899Savl-llvm     // reference live address.
177*2357e899Savl-llvm     return InUnit.getDIEInfo(InputDIEIdx).getIsInFunctionScope() &&
178*2357e899Savl-llvm            !FuncAddressAdjustment.has_value();
179*2357e899Savl-llvm   }
180*2357e899Savl-llvm }
181*2357e899Savl-llvm 
cloneStringAttr(const DWARFFormValue & Val,const DWARFAbbreviationDeclaration::AttributeSpec & AttrSpec)182*2357e899Savl-llvm size_t DIEAttributeCloner::cloneStringAttr(
183*2357e899Savl-llvm     const DWARFFormValue &Val,
184*2357e899Savl-llvm     const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) {
185*2357e899Savl-llvm   std::optional<const char *> String = dwarf::toString(Val);
186*2357e899Savl-llvm   if (!String) {
187*2357e899Savl-llvm     InUnit.warn("cann't read string attribute.");
188*2357e899Savl-llvm     return 0;
189*2357e899Savl-llvm   }
190*2357e899Savl-llvm 
191*2357e899Savl-llvm   StringEntry *StringInPool =
192*2357e899Savl-llvm       InUnit.getGlobalData().getStringPool().insert(*String).first;
193*2357e899Savl-llvm 
194*2357e899Savl-llvm   // Update attributes info.
195*2357e899Savl-llvm   if (AttrSpec.Attr == dwarf::DW_AT_name)
196*2357e899Savl-llvm     AttrInfo.Name = StringInPool;
197*2357e899Savl-llvm   else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
198*2357e899Savl-llvm            AttrSpec.Attr == dwarf::DW_AT_linkage_name)
199*2357e899Savl-llvm     AttrInfo.MangledName = StringInPool;
200*2357e899Savl-llvm 
201*2357e899Savl-llvm   if (AttrSpec.Form == dwarf::DW_FORM_line_strp) {
202*2357e899Savl-llvm     if (OutUnit.isTypeUnit()) {
203*2357e899Savl-llvm       DebugInfoOutputSection.notePatch(DebugTypeLineStrPatch{
204*2357e899Savl-llvm           AttrOutOffset, OutDIE, InUnit.getDieTypeEntry(InputDIEIdx),
205*2357e899Savl-llvm           StringInPool});
206*2357e899Savl-llvm     } else {
207*2357e899Savl-llvm       DebugInfoOutputSection.notePatchWithOffsetUpdate(
208*2357e899Savl-llvm           DebugLineStrPatch{{AttrOutOffset}, StringInPool}, PatchesOffsets);
209*2357e899Savl-llvm     }
210*2357e899Savl-llvm     return Generator
211*2357e899Savl-llvm         .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_line_strp)
212*2357e899Savl-llvm         .second;
213*2357e899Savl-llvm   }
214*2357e899Savl-llvm 
215*2357e899Savl-llvm   if (Use_DW_FORM_strp) {
216*2357e899Savl-llvm     if (OutUnit.isTypeUnit()) {
217*2357e899Savl-llvm       DebugInfoOutputSection.notePatch(
218*2357e899Savl-llvm           DebugTypeStrPatch{AttrOutOffset, OutDIE,
219*2357e899Savl-llvm                             InUnit.getDieTypeEntry(InputDIEIdx), StringInPool});
220*2357e899Savl-llvm     } else {
221*2357e899Savl-llvm       DebugInfoOutputSection.notePatchWithOffsetUpdate(
222*2357e899Savl-llvm           DebugStrPatch{{AttrOutOffset}, StringInPool}, PatchesOffsets);
223*2357e899Savl-llvm     }
224*2357e899Savl-llvm 
225*2357e899Savl-llvm     return Generator
226*2357e899Savl-llvm         .addStringPlaceholderAttribute(AttrSpec.Attr, dwarf::DW_FORM_strp)
227*2357e899Savl-llvm         .second;
228*2357e899Savl-llvm   }
229*2357e899Savl-llvm 
230*2357e899Savl-llvm   return Generator
231*2357e899Savl-llvm       .addIndexedStringAttribute(AttrSpec.Attr, dwarf::DW_FORM_strx,
232*2357e899Savl-llvm                                  OutUnit->getDebugStrIndex(StringInPool))
233*2357e899Savl-llvm       .second;
234*2357e899Savl-llvm }
235*2357e899Savl-llvm 
cloneDieRefAttr(const DWARFFormValue & Val,const DWARFAbbreviationDeclaration::AttributeSpec & AttrSpec)236*2357e899Savl-llvm size_t DIEAttributeCloner::cloneDieRefAttr(
237*2357e899Savl-llvm     const DWARFFormValue &Val,
238*2357e899Savl-llvm     const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) {
239*2357e899Savl-llvm   if (AttrSpec.Attr == dwarf::DW_AT_sibling)
240*2357e899Savl-llvm     return 0;
241*2357e899Savl-llvm 
242*2357e899Savl-llvm   std::optional<UnitEntryPairTy> RefDiePair =
243*2357e899Savl-llvm       InUnit.resolveDIEReference(Val, ResolveInterCUReferencesMode::Resolve);
244*2357e899Savl-llvm   if (!RefDiePair || !RefDiePair->DieEntry) {
245*2357e899Savl-llvm     // If the referenced DIE is not found,  drop the attribute.
246*2357e899Savl-llvm     InUnit.warn("cann't find referenced DIE.", InputDieEntry);
247*2357e899Savl-llvm     return 0;
248*2357e899Savl-llvm   }
249*2357e899Savl-llvm 
250*2357e899Savl-llvm   TypeEntry *RefTypeName = nullptr;
251*2357e899Savl-llvm   const CompileUnit::DIEInfo &RefDIEInfo =
252*2357e899Savl-llvm       RefDiePair->CU->getDIEInfo(RefDiePair->DieEntry);
253*2357e899Savl-llvm   if (RefDIEInfo.needToPlaceInTypeTable())
254*2357e899Savl-llvm     RefTypeName = RefDiePair->CU->getDieTypeEntry(RefDiePair->DieEntry);
255*2357e899Savl-llvm 
256*2357e899Savl-llvm   if (OutUnit.isTypeUnit()) {
257*2357e899Savl-llvm     assert(RefTypeName && "Type name for referenced DIE is not set");
258*2357e899Savl-llvm     assert(InUnit.getDieTypeEntry(InputDIEIdx) &&
259*2357e899Savl-llvm            "Type name for DIE is not set");
260*2357e899Savl-llvm 
261*2357e899Savl-llvm     DebugInfoOutputSection.notePatch(DebugType2TypeDieRefPatch{
262*2357e899Savl-llvm         AttrOutOffset, OutDIE, InUnit.getDieTypeEntry(InputDIEIdx),
263*2357e899Savl-llvm         RefTypeName});
264*2357e899Savl-llvm 
265*2357e899Savl-llvm     return Generator
266*2357e899Savl-llvm         .addScalarAttribute(AttrSpec.Attr, dwarf::DW_FORM_ref4, 0xBADDEF)
267*2357e899Savl-llvm         .second;
268*2357e899Savl-llvm   }
269*2357e899Savl-llvm 
270*2357e899Savl-llvm   if (RefTypeName) {
271*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
272*2357e899Savl-llvm         DebugDieTypeRefPatch{AttrOutOffset, RefTypeName}, PatchesOffsets);
273*2357e899Savl-llvm 
274*2357e899Savl-llvm     return Generator
275*2357e899Savl-llvm         .addScalarAttribute(AttrSpec.Attr, dwarf::DW_FORM_ref_addr, 0xBADDEF)
276*2357e899Savl-llvm         .second;
277*2357e899Savl-llvm   }
278*2357e899Savl-llvm 
279*2357e899Savl-llvm   // Get output offset for referenced DIE.
280*2357e899Savl-llvm   uint64_t OutDieOffset = RefDiePair->CU->getDieOutOffset(RefDiePair->DieEntry);
281*2357e899Savl-llvm 
282*2357e899Savl-llvm   // Examine whether referenced DIE is in current compile unit.
283*2357e899Savl-llvm   bool IsLocal = OutUnit->getUniqueID() == RefDiePair->CU->getUniqueID();
284*2357e899Savl-llvm 
285*2357e899Savl-llvm   // Set attribute form basing on the kind of referenced DIE(local or not?).
286*2357e899Savl-llvm   dwarf::Form NewForm = IsLocal ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr;
287*2357e899Savl-llvm 
288*2357e899Savl-llvm   // Check whether current attribute references already cloned DIE inside
289*2357e899Savl-llvm   // the same compilation unit. If true - write the already known offset value.
290*2357e899Savl-llvm   if (IsLocal && (OutDieOffset != 0))
291*2357e899Savl-llvm     return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, OutDieOffset)
292*2357e899Savl-llvm         .second;
293*2357e899Savl-llvm 
294*2357e899Savl-llvm   // If offset value is not known at this point then create patch for the
295*2357e899Savl-llvm   // reference value and write dummy value into the attribute.
296*2357e899Savl-llvm   DebugInfoOutputSection.notePatchWithOffsetUpdate(
297*2357e899Savl-llvm       DebugDieRefPatch{AttrOutOffset, OutUnit.getAsCompileUnit(),
298*2357e899Savl-llvm                        RefDiePair->CU,
299*2357e899Savl-llvm                        RefDiePair->CU->getDIEIndex(RefDiePair->DieEntry)},
300*2357e899Savl-llvm       PatchesOffsets);
301*2357e899Savl-llvm   return Generator.addScalarAttribute(AttrSpec.Attr, NewForm, 0xBADDEF).second;
302*2357e899Savl-llvm }
303*2357e899Savl-llvm 
cloneScalarAttr(const DWARFFormValue & Val,const DWARFAbbreviationDeclaration::AttributeSpec & AttrSpec)304*2357e899Savl-llvm size_t DIEAttributeCloner::cloneScalarAttr(
305*2357e899Savl-llvm     const DWARFFormValue &Val,
306*2357e899Savl-llvm     const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) {
307*2357e899Savl-llvm 
308*2357e899Savl-llvm   // Create patches for attribute referencing other non invariant section.
309*2357e899Savl-llvm   // Invariant section could not be updated here as this section and
310*2357e899Savl-llvm   // reference to it do not change value in case --update.
311*2357e899Savl-llvm   switch (AttrSpec.Attr) {
312*2357e899Savl-llvm   case dwarf::DW_AT_macro_info: {
313*2357e899Savl-llvm     if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
314*2357e899Savl-llvm       const DWARFDebugMacro *Macro =
315*2357e899Savl-llvm           InUnit.getContaingFile().Dwarf->getDebugMacinfo();
316*2357e899Savl-llvm       if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
317*2357e899Savl-llvm         return 0;
318*2357e899Savl-llvm 
319*2357e899Savl-llvm       DebugInfoOutputSection.notePatchWithOffsetUpdate(
320*2357e899Savl-llvm           DebugOffsetPatch{AttrOutOffset,
321*2357e899Savl-llvm                            &OutUnit->getOrCreateSectionDescriptor(
322*2357e899Savl-llvm                                DebugSectionKind::DebugMacinfo)},
323*2357e899Savl-llvm           PatchesOffsets);
324*2357e899Savl-llvm     }
325*2357e899Savl-llvm   } break;
326*2357e899Savl-llvm   case dwarf::DW_AT_macros: {
327*2357e899Savl-llvm     if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
328*2357e899Savl-llvm       const DWARFDebugMacro *Macro =
329*2357e899Savl-llvm           InUnit.getContaingFile().Dwarf->getDebugMacro();
330*2357e899Savl-llvm       if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
331*2357e899Savl-llvm         return 0;
332*2357e899Savl-llvm 
333*2357e899Savl-llvm       DebugInfoOutputSection.notePatchWithOffsetUpdate(
334*2357e899Savl-llvm           DebugOffsetPatch{AttrOutOffset,
335*2357e899Savl-llvm                            &OutUnit->getOrCreateSectionDescriptor(
336*2357e899Savl-llvm                                DebugSectionKind::DebugMacro)},
337*2357e899Savl-llvm           PatchesOffsets);
338*2357e899Savl-llvm     }
339*2357e899Savl-llvm   } break;
340*2357e899Savl-llvm   case dwarf::DW_AT_stmt_list: {
341*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
342*2357e899Savl-llvm         DebugOffsetPatch{AttrOutOffset, &OutUnit->getOrCreateSectionDescriptor(
343*2357e899Savl-llvm                                             DebugSectionKind::DebugLine)},
344*2357e899Savl-llvm         PatchesOffsets);
345*2357e899Savl-llvm   } break;
346*2357e899Savl-llvm   case dwarf::DW_AT_str_offsets_base: {
347*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
348*2357e899Savl-llvm         DebugOffsetPatch{AttrOutOffset,
349*2357e899Savl-llvm                          &OutUnit->getOrCreateSectionDescriptor(
350*2357e899Savl-llvm                              DebugSectionKind::DebugStrOffsets),
351*2357e899Savl-llvm                          true},
352*2357e899Savl-llvm         PatchesOffsets);
353*2357e899Savl-llvm 
354*2357e899Savl-llvm     // Use size of .debug_str_offsets header as attribute value. The offset
355*2357e899Savl-llvm     // to .debug_str_offsets would be added later while patching.
356*2357e899Savl-llvm     AttrInfo.HasStringOffsetBaseAttr = true;
357*2357e899Savl-llvm     return Generator
358*2357e899Savl-llvm         .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form,
359*2357e899Savl-llvm                             OutUnit->getDebugStrOffsetsHeaderSize())
360*2357e899Savl-llvm         .second;
361*2357e899Savl-llvm   } break;
362*2357e899Savl-llvm   case dwarf::DW_AT_decl_file: {
363*2357e899Savl-llvm     // Value of DW_AT_decl_file may exceed original form. Longer
364*2357e899Savl-llvm     // form can affect offsets to the following attributes. To not
365*2357e899Savl-llvm     // update offsets of the following attributes we always remove
366*2357e899Savl-llvm     // original DW_AT_decl_file and attach it to the last position
367*2357e899Savl-llvm     // later.
368*2357e899Savl-llvm     if (OutUnit.isTypeUnit()) {
369*2357e899Savl-llvm       if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
370*2357e899Savl-llvm               InUnit.getDirAndFilenameFromLineTable(Val))
371*2357e899Savl-llvm         DebugInfoOutputSection.notePatch(DebugTypeDeclFilePatch{
372*2357e899Savl-llvm             OutDIE,
373*2357e899Savl-llvm             InUnit.getDieTypeEntry(InputDIEIdx),
374*2357e899Savl-llvm             OutUnit->getGlobalData()
375*2357e899Savl-llvm                 .getStringPool()
376*2357e899Savl-llvm                 .insert(DirAndFilename->first)
377*2357e899Savl-llvm                 .first,
378*2357e899Savl-llvm             OutUnit->getGlobalData()
379*2357e899Savl-llvm                 .getStringPool()
380*2357e899Savl-llvm                 .insert(DirAndFilename->second)
381*2357e899Savl-llvm                 .first,
382*2357e899Savl-llvm         });
383*2357e899Savl-llvm       return 0;
384*2357e899Savl-llvm     }
385*2357e899Savl-llvm   } break;
386*2357e899Savl-llvm   default: {
387*2357e899Savl-llvm   } break;
388*2357e899Savl-llvm   };
389*2357e899Savl-llvm 
390*2357e899Savl-llvm   uint64_t Value;
391*2357e899Savl-llvm   if (AttrSpec.Attr == dwarf::DW_AT_const_value &&
392*2357e899Savl-llvm       (InputDieEntry->getTag() == dwarf::DW_TAG_variable ||
393*2357e899Savl-llvm        InputDieEntry->getTag() == dwarf::DW_TAG_constant))
394*2357e899Savl-llvm     AttrInfo.HasLiveAddress = true;
395*2357e899Savl-llvm 
396*2357e899Savl-llvm   if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly) {
397*2357e899Savl-llvm     if (auto OptionalValue = Val.getAsUnsignedConstant())
398*2357e899Savl-llvm       Value = *OptionalValue;
399*2357e899Savl-llvm     else if (auto OptionalValue = Val.getAsSignedConstant())
400*2357e899Savl-llvm       Value = *OptionalValue;
401*2357e899Savl-llvm     else if (auto OptionalValue = Val.getAsSectionOffset())
402*2357e899Savl-llvm       Value = *OptionalValue;
403*2357e899Savl-llvm     else {
404*2357e899Savl-llvm       InUnit.warn("unsupported scalar attribute form. Dropping attribute.",
405*2357e899Savl-llvm                   InputDieEntry);
406*2357e899Savl-llvm       return 0;
407*2357e899Savl-llvm     }
408*2357e899Savl-llvm 
409*2357e899Savl-llvm     if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
410*2357e899Savl-llvm       AttrInfo.IsDeclaration = true;
411*2357e899Savl-llvm 
412*2357e899Savl-llvm     if (AttrSpec.Form == dwarf::DW_FORM_loclistx)
413*2357e899Savl-llvm       return Generator.addLocListAttribute(AttrSpec.Attr, AttrSpec.Form, Value)
414*2357e899Savl-llvm           .second;
415*2357e899Savl-llvm 
416*2357e899Savl-llvm     return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Value)
417*2357e899Savl-llvm         .second;
418*2357e899Savl-llvm   }
419*2357e899Savl-llvm 
420*2357e899Savl-llvm   dwarf::Form ResultingForm = AttrSpec.Form;
421*2357e899Savl-llvm   if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) {
422*2357e899Savl-llvm     // DWARFLinker does not generate .debug_addr table. Thus we need to change
423*2357e899Savl-llvm     // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx
424*2357e899Savl-llvm     // to DW_FORM_sec_offset here.
425*2357e899Savl-llvm     std::optional<uint64_t> Index = Val.getAsSectionOffset();
426*2357e899Savl-llvm     if (!Index) {
427*2357e899Savl-llvm       InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
428*2357e899Savl-llvm       return 0;
429*2357e899Savl-llvm     }
430*2357e899Savl-llvm     std::optional<uint64_t> Offset =
431*2357e899Savl-llvm         InUnit.getOrigUnit().getRnglistOffset(*Index);
432*2357e899Savl-llvm     if (!Offset) {
433*2357e899Savl-llvm       InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
434*2357e899Savl-llvm       return 0;
435*2357e899Savl-llvm     }
436*2357e899Savl-llvm 
437*2357e899Savl-llvm     Value = *Offset;
438*2357e899Savl-llvm     ResultingForm = dwarf::DW_FORM_sec_offset;
439*2357e899Savl-llvm   } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) {
440*2357e899Savl-llvm     // DWARFLinker does not generate .debug_addr table. Thus we need to change
441*2357e899Savl-llvm     // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx
442*2357e899Savl-llvm     // to DW_FORM_sec_offset here.
443*2357e899Savl-llvm     std::optional<uint64_t> Index = Val.getAsSectionOffset();
444*2357e899Savl-llvm     if (!Index) {
445*2357e899Savl-llvm       InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
446*2357e899Savl-llvm       return 0;
447*2357e899Savl-llvm     }
448*2357e899Savl-llvm     std::optional<uint64_t> Offset =
449*2357e899Savl-llvm         InUnit.getOrigUnit().getLoclistOffset(*Index);
450*2357e899Savl-llvm     if (!Offset) {
451*2357e899Savl-llvm       InUnit.warn("cann't read the attribute. Dropping.", InputDieEntry);
452*2357e899Savl-llvm       return 0;
453*2357e899Savl-llvm     }
454*2357e899Savl-llvm 
455*2357e899Savl-llvm     Value = *Offset;
456*2357e899Savl-llvm     ResultingForm = dwarf::DW_FORM_sec_offset;
457*2357e899Savl-llvm   } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
458*2357e899Savl-llvm              InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) {
459*2357e899Savl-llvm     if (!OutUnit.isCompileUnit())
460*2357e899Savl-llvm       return 0;
461*2357e899Savl-llvm 
462*2357e899Savl-llvm     std::optional<uint64_t> LowPC = OutUnit.getAsCompileUnit()->getLowPc();
463*2357e899Savl-llvm     if (!LowPC)
464*2357e899Savl-llvm       return 0;
465*2357e899Savl-llvm     // Dwarf >= 4 high_pc is an size, not an address.
466*2357e899Savl-llvm     Value = OutUnit.getAsCompileUnit()->getHighPc() - *LowPC;
467*2357e899Savl-llvm   } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
468*2357e899Savl-llvm     Value = *Val.getAsSectionOffset();
469*2357e899Savl-llvm   else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
470*2357e899Savl-llvm     Value = *Val.getAsSignedConstant();
471*2357e899Savl-llvm   else if (auto OptionalValue = Val.getAsUnsignedConstant())
472*2357e899Savl-llvm     Value = *OptionalValue;
473*2357e899Savl-llvm   else {
474*2357e899Savl-llvm     InUnit.warn("unsupported scalar attribute form. Dropping attribute.",
475*2357e899Savl-llvm                 InputDieEntry);
476*2357e899Savl-llvm     return 0;
477*2357e899Savl-llvm   }
478*2357e899Savl-llvm 
479*2357e899Savl-llvm   if (AttrSpec.Attr == dwarf::DW_AT_ranges ||
480*2357e899Savl-llvm       AttrSpec.Attr == dwarf::DW_AT_start_scope) {
481*2357e899Savl-llvm     // Create patch for the range offset value.
482*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
483*2357e899Savl-llvm         DebugRangePatch{{AttrOutOffset},
484*2357e899Savl-llvm                         InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit},
485*2357e899Savl-llvm         PatchesOffsets);
486*2357e899Savl-llvm     AttrInfo.HasRanges = true;
487*2357e899Savl-llvm   } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) &&
488*2357e899Savl-llvm              dwarf::doesFormBelongToClass(AttrSpec.Form,
489*2357e899Savl-llvm                                           DWARFFormValue::FC_SectionOffset,
490*2357e899Savl-llvm                                           InUnit.getOrigUnit().getVersion())) {
491*2357e899Savl-llvm     int64_t AddrAdjustmentValue = 0;
492*2357e899Savl-llvm     if (VarAddressAdjustment)
493*2357e899Savl-llvm       AddrAdjustmentValue = *VarAddressAdjustment;
494*2357e899Savl-llvm     else if (FuncAddressAdjustment)
495*2357e899Savl-llvm       AddrAdjustmentValue = *FuncAddressAdjustment;
496*2357e899Savl-llvm 
497*2357e899Savl-llvm     // Create patch for the location offset value.
498*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
499*2357e899Savl-llvm         DebugLocPatch{{AttrOutOffset}, AddrAdjustmentValue}, PatchesOffsets);
500*2357e899Savl-llvm   } else if (AttrSpec.Attr == dwarf::DW_AT_addr_base) {
501*2357e899Savl-llvm     DebugInfoOutputSection.notePatchWithOffsetUpdate(
502*2357e899Savl-llvm         DebugOffsetPatch{
503*2357e899Savl-llvm             AttrOutOffset,
504*2357e899Savl-llvm             &OutUnit->getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr),
505*2357e899Savl-llvm             true},
506*2357e899Savl-llvm         PatchesOffsets);
507*2357e899Savl-llvm 
508*2357e899Savl-llvm     // Use size of .debug_addr header as attribute value. The offset to
509*2357e899Savl-llvm     // .debug_addr would be added later while patching.
510*2357e899Savl-llvm     return Generator
511*2357e899Savl-llvm         .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form,
512*2357e899Savl-llvm                             OutUnit->getDebugAddrHeaderSize())
513*2357e899Savl-llvm         .second;
514*2357e899Savl-llvm   } else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
515*2357e899Savl-llvm     AttrInfo.IsDeclaration = true;
516*2357e899Savl-llvm 
517*2357e899Savl-llvm   return Generator.addScalarAttribute(AttrSpec.Attr, ResultingForm, Value)
518*2357e899Savl-llvm       .second;
519*2357e899Savl-llvm }
520*2357e899Savl-llvm 
cloneBlockAttr(const DWARFFormValue & Val,const DWARFAbbreviationDeclaration::AttributeSpec & AttrSpec)521*2357e899Savl-llvm size_t DIEAttributeCloner::cloneBlockAttr(
522*2357e899Savl-llvm     const DWARFFormValue &Val,
523*2357e899Savl-llvm     const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) {
524*2357e899Savl-llvm 
525*2357e899Savl-llvm   if (OutUnit.isTypeUnit())
526*2357e899Savl-llvm     return 0;
527*2357e899Savl-llvm 
528*2357e899Savl-llvm   size_t NumberOfPatchesAtStart = PatchesOffsets.size();
529*2357e899Savl-llvm 
530*2357e899Savl-llvm   // If the block is a DWARF Expression, clone it into the temporary
531*2357e899Savl-llvm   // buffer using cloneExpression(), otherwise copy the data directly.
532*2357e899Savl-llvm   SmallVector<uint8_t, 32> Buffer;
533*2357e899Savl-llvm   ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
534*2357e899Savl-llvm   if (DWARFAttribute::mayHaveLocationExpr(AttrSpec.Attr) &&
535*2357e899Savl-llvm       (Val.isFormClass(DWARFFormValue::FC_Block) ||
536*2357e899Savl-llvm        Val.isFormClass(DWARFFormValue::FC_Exprloc))) {
537*2357e899Savl-llvm     DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()),
538*2357e899Savl-llvm                        InUnit.getOrigUnit().isLittleEndian(),
539*2357e899Savl-llvm                        InUnit.getOrigUnit().getAddressByteSize());
540*2357e899Savl-llvm     DWARFExpression Expr(Data, InUnit.getOrigUnit().getAddressByteSize(),
541*2357e899Savl-llvm                          InUnit.getFormParams().Format);
542*2357e899Savl-llvm 
543*2357e899Savl-llvm     InUnit.cloneDieAttrExpression(Expr, Buffer, DebugInfoOutputSection,
544*2357e899Savl-llvm                                   VarAddressAdjustment, PatchesOffsets);
545*2357e899Savl-llvm     Bytes = Buffer;
546*2357e899Savl-llvm   }
547*2357e899Savl-llvm 
548*2357e899Savl-llvm   // The expression location data might be updated and exceed the original size.
549*2357e899Savl-llvm   // Check whether the new data fits into the original form.
550*2357e899Savl-llvm   dwarf::Form ResultForm = AttrSpec.Form;
551*2357e899Savl-llvm   if ((ResultForm == dwarf::DW_FORM_block1 && Bytes.size() > UINT8_MAX) ||
552*2357e899Savl-llvm       (ResultForm == dwarf::DW_FORM_block2 && Bytes.size() > UINT16_MAX) ||
553*2357e899Savl-llvm       (ResultForm == dwarf::DW_FORM_block4 && Bytes.size() > UINT32_MAX))
554*2357e899Savl-llvm     ResultForm = dwarf::DW_FORM_block;
555*2357e899Savl-llvm 
556*2357e899Savl-llvm   size_t FinalAttributeSize;
557*2357e899Savl-llvm   if (AttrSpec.Form == dwarf::DW_FORM_exprloc)
558*2357e899Savl-llvm     FinalAttributeSize =
559*2357e899Savl-llvm         Generator.addLocationAttribute(AttrSpec.Attr, ResultForm, Bytes).second;
560*2357e899Savl-llvm   else
561*2357e899Savl-llvm     FinalAttributeSize =
562*2357e899Savl-llvm         Generator.addBlockAttribute(AttrSpec.Attr, ResultForm, Bytes).second;
563*2357e899Savl-llvm 
564*2357e899Savl-llvm   // Update patches offsets with the size of length field for Bytes.
565*2357e899Savl-llvm   for (size_t Idx = NumberOfPatchesAtStart; Idx < PatchesOffsets.size();
566*2357e899Savl-llvm        Idx++) {
567*2357e899Savl-llvm     assert(FinalAttributeSize > Bytes.size());
568*2357e899Savl-llvm     *PatchesOffsets[Idx] +=
569*2357e899Savl-llvm         (AttrOutOffset + (FinalAttributeSize - Bytes.size()));
570*2357e899Savl-llvm   }
571*2357e899Savl-llvm 
572*2357e899Savl-llvm   if (HasLocationExpressionAddress)
573*2357e899Savl-llvm     AttrInfo.HasLiveAddress =
574*2357e899Savl-llvm         VarAddressAdjustment.has_value() ||
575*2357e899Savl-llvm         InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
576*2357e899Savl-llvm 
577*2357e899Savl-llvm   return FinalAttributeSize;
578*2357e899Savl-llvm }
579*2357e899Savl-llvm 
cloneAddressAttr(const DWARFFormValue & Val,const DWARFAbbreviationDeclaration::AttributeSpec & AttrSpec)580*2357e899Savl-llvm size_t DIEAttributeCloner::cloneAddressAttr(
581*2357e899Savl-llvm     const DWARFFormValue &Val,
582*2357e899Savl-llvm     const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) {
583*2357e899Savl-llvm   if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
584*2357e899Savl-llvm     AttrInfo.HasLiveAddress = true;
585*2357e899Savl-llvm 
586*2357e899Savl-llvm   if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
587*2357e899Savl-llvm     return Generator
588*2357e899Savl-llvm         .addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Val.getRawUValue())
589*2357e899Savl-llvm         .second;
590*2357e899Savl-llvm 
591*2357e899Savl-llvm   if (OutUnit.isTypeUnit())
592*2357e899Savl-llvm     return 0;
593*2357e899Savl-llvm 
594*2357e899Savl-llvm   // Cloned Die may have address attributes relocated to a
595*2357e899Savl-llvm   // totally unrelated value. This can happen:
596*2357e899Savl-llvm   //   - If high_pc is an address (Dwarf version == 2), then it might have been
597*2357e899Savl-llvm   //     relocated to a totally unrelated value (because the end address in the
598*2357e899Savl-llvm   //     object file might be start address of another function which got moved
599*2357e899Savl-llvm   //     independently by the linker).
600*2357e899Savl-llvm   //   - If address relocated in an inline_subprogram that happens at the
601*2357e899Savl-llvm   //     beginning of its inlining function.
602*2357e899Savl-llvm   //  To avoid above cases and to not apply relocation twice (in
603*2357e899Savl-llvm   //  applyValidRelocs and here), read address attribute from InputDIE and apply
604*2357e899Savl-llvm   //  Info.PCOffset here.
605*2357e899Savl-llvm 
606*2357e899Savl-llvm   std::optional<DWARFFormValue> AddrAttribute =
607*2357e899Savl-llvm       InUnit.find(InputDieEntry, AttrSpec.Attr);
608*2357e899Savl-llvm   if (!AddrAttribute)
609*2357e899Savl-llvm     llvm_unreachable("Cann't find attribute");
610*2357e899Savl-llvm 
611*2357e899Savl-llvm   std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
612*2357e899Savl-llvm   if (!Addr) {
613*2357e899Savl-llvm     InUnit.warn("cann't read address attribute value.");
614*2357e899Savl-llvm     return 0;
615*2357e899Savl-llvm   }
616*2357e899Savl-llvm 
617*2357e899Savl-llvm   if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
618*2357e899Savl-llvm       AttrSpec.Attr == dwarf::DW_AT_low_pc) {
619*2357e899Savl-llvm     if (std::optional<uint64_t> LowPC = OutUnit.getAsCompileUnit()->getLowPc())
620*2357e899Savl-llvm       Addr = *LowPC;
621*2357e899Savl-llvm     else
622*2357e899Savl-llvm       return 0;
623*2357e899Savl-llvm   } else if (InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
624*2357e899Savl-llvm              AttrSpec.Attr == dwarf::DW_AT_high_pc) {
625*2357e899Savl-llvm     if (uint64_t HighPc = OutUnit.getAsCompileUnit()->getHighPc())
626*2357e899Savl-llvm       Addr = HighPc;
627*2357e899Savl-llvm     else
628*2357e899Savl-llvm       return 0;
629*2357e899Savl-llvm   } else {
630*2357e899Savl-llvm     if (VarAddressAdjustment)
631*2357e899Savl-llvm       *Addr += *VarAddressAdjustment;
632*2357e899Savl-llvm     else if (FuncAddressAdjustment)
633*2357e899Savl-llvm       *Addr += *FuncAddressAdjustment;
634*2357e899Savl-llvm   }
635*2357e899Savl-llvm 
636*2357e899Savl-llvm   if (AttrSpec.Form == dwarf::DW_FORM_addr) {
637*2357e899Savl-llvm     return Generator.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, *Addr)
638*2357e899Savl-llvm         .second;
639*2357e899Savl-llvm   }
640*2357e899Savl-llvm 
641*2357e899Savl-llvm   return Generator
642*2357e899Savl-llvm       .addScalarAttribute(AttrSpec.Attr, dwarf::Form::DW_FORM_addrx,
643*2357e899Savl-llvm                           OutUnit.getAsCompileUnit()->getDebugAddrIndex(*Addr))
644*2357e899Savl-llvm       .second;
645*2357e899Savl-llvm }
646*2357e899Savl-llvm 
finalizeAbbreviations(bool HasChildrenToClone)647*2357e899Savl-llvm unsigned DIEAttributeCloner::finalizeAbbreviations(bool HasChildrenToClone) {
648*2357e899Savl-llvm   // Add the size of the abbreviation number to the output offset.
649*2357e899Savl-llvm   AttrOutOffset +=
650*2357e899Savl-llvm       Generator.finalizeAbbreviations(HasChildrenToClone, &PatchesOffsets);
651*2357e899Savl-llvm 
652*2357e899Savl-llvm   return AttrOutOffset;
653*2357e899Savl-llvm }
654