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