xref: /llvm-project/llvm/lib/DWARFLinker/Parallel/OutputSections.cpp (revision 9ff4be640fb1b3a64a8bc73020d67816f1c09ea0)
1*2357e899Savl-llvm //=== OutputSections.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 "OutputSections.h"
10*2357e899Savl-llvm #include "DWARFLinkerCompileUnit.h"
11*2357e899Savl-llvm #include "DWARFLinkerTypeUnit.h"
12*2357e899Savl-llvm #include "llvm/ADT/StringSwitch.h"
13*2357e899Savl-llvm 
14*2357e899Savl-llvm using namespace llvm;
15*2357e899Savl-llvm using namespace dwarf_linker;
16*2357e899Savl-llvm using namespace dwarf_linker::parallel;
17*2357e899Savl-llvm 
DebugDieRefPatch(uint64_t PatchOffset,CompileUnit * SrcCU,CompileUnit * RefCU,uint32_t RefIdx)18*2357e899Savl-llvm DebugDieRefPatch::DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU,
19*2357e899Savl-llvm                                    CompileUnit *RefCU, uint32_t RefIdx)
20*2357e899Savl-llvm     : SectionPatch({PatchOffset}),
21*2357e899Savl-llvm       RefCU(RefCU, (SrcCU != nullptr) &&
22*2357e899Savl-llvm                        (SrcCU->getUniqueID() == RefCU->getUniqueID())),
23*2357e899Savl-llvm       RefDieIdxOrClonedOffset(RefIdx) {}
24*2357e899Savl-llvm 
DebugULEB128DieRefPatch(uint64_t PatchOffset,CompileUnit * SrcCU,CompileUnit * RefCU,uint32_t RefIdx)25*2357e899Savl-llvm DebugULEB128DieRefPatch::DebugULEB128DieRefPatch(uint64_t PatchOffset,
26*2357e899Savl-llvm                                                  CompileUnit *SrcCU,
27*2357e899Savl-llvm                                                  CompileUnit *RefCU,
28*2357e899Savl-llvm                                                  uint32_t RefIdx)
29*2357e899Savl-llvm     : SectionPatch({PatchOffset}),
30*2357e899Savl-llvm       RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()),
31*2357e899Savl-llvm       RefDieIdxOrClonedOffset(RefIdx) {}
32*2357e899Savl-llvm 
DebugDieTypeRefPatch(uint64_t PatchOffset,TypeEntry * RefTypeName)33*2357e899Savl-llvm DebugDieTypeRefPatch::DebugDieTypeRefPatch(uint64_t PatchOffset,
34*2357e899Savl-llvm                                            TypeEntry *RefTypeName)
35*2357e899Savl-llvm     : SectionPatch({PatchOffset}), RefTypeName(RefTypeName) {}
36*2357e899Savl-llvm 
DebugType2TypeDieRefPatch(uint64_t PatchOffset,DIE * Die,TypeEntry * TypeName,TypeEntry * RefTypeName)37*2357e899Savl-llvm DebugType2TypeDieRefPatch::DebugType2TypeDieRefPatch(uint64_t PatchOffset,
38*2357e899Savl-llvm                                                      DIE *Die,
39*2357e899Savl-llvm                                                      TypeEntry *TypeName,
40*2357e899Savl-llvm                                                      TypeEntry *RefTypeName)
41*2357e899Savl-llvm     : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
42*2357e899Savl-llvm       RefTypeName(RefTypeName) {}
43*2357e899Savl-llvm 
DebugTypeStrPatch(uint64_t PatchOffset,DIE * Die,TypeEntry * TypeName,StringEntry * String)44*2357e899Savl-llvm DebugTypeStrPatch::DebugTypeStrPatch(uint64_t PatchOffset, DIE *Die,
45*2357e899Savl-llvm                                      TypeEntry *TypeName, StringEntry *String)
46*2357e899Savl-llvm     : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
47*2357e899Savl-llvm       String(String) {}
48*2357e899Savl-llvm 
DebugTypeLineStrPatch(uint64_t PatchOffset,DIE * Die,TypeEntry * TypeName,StringEntry * String)49*2357e899Savl-llvm DebugTypeLineStrPatch::DebugTypeLineStrPatch(uint64_t PatchOffset, DIE *Die,
50*2357e899Savl-llvm                                              TypeEntry *TypeName,
51*2357e899Savl-llvm                                              StringEntry *String)
52*2357e899Savl-llvm     : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
53*2357e899Savl-llvm       String(String) {}
54*2357e899Savl-llvm 
DebugTypeDeclFilePatch(DIE * Die,TypeEntry * TypeName,StringEntry * Directory,StringEntry * FilePath)55*2357e899Savl-llvm DebugTypeDeclFilePatch::DebugTypeDeclFilePatch(DIE *Die, TypeEntry *TypeName,
56*2357e899Savl-llvm                                                StringEntry *Directory,
57*2357e899Savl-llvm                                                StringEntry *FilePath)
58*2357e899Savl-llvm     : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {}
59*2357e899Savl-llvm 
clearAllSectionData()60*2357e899Savl-llvm void SectionDescriptor::clearAllSectionData() {
61*2357e899Savl-llvm   StartOffset = 0;
62*2357e899Savl-llvm   clearSectionContent();
63*2357e899Savl-llvm   ListDebugStrPatch.erase();
64*2357e899Savl-llvm   ListDebugLineStrPatch.erase();
65*2357e899Savl-llvm   ListDebugRangePatch.erase();
66*2357e899Savl-llvm   ListDebugLocPatch.erase();
67*2357e899Savl-llvm   ListDebugDieRefPatch.erase();
68*2357e899Savl-llvm   ListDebugULEB128DieRefPatch.erase();
69*2357e899Savl-llvm   ListDebugOffsetPatch.erase();
70*2357e899Savl-llvm   ListDebugType2TypeDieRefPatch.erase();
71*2357e899Savl-llvm   ListDebugTypeDeclFilePatch.erase();
72*2357e899Savl-llvm   ListDebugTypeLineStrPatch.erase();
73*2357e899Savl-llvm   ListDebugTypeStrPatch.erase();
74*2357e899Savl-llvm }
75*2357e899Savl-llvm 
clearSectionContent()76*2357e899Savl-llvm void SectionDescriptor::clearSectionContent() { Contents = OutSectionDataTy(); }
77*2357e899Savl-llvm 
setSizesForSectionCreatedByAsmPrinter()78*2357e899Savl-llvm void SectionDescriptor::setSizesForSectionCreatedByAsmPrinter() {
79*2357e899Savl-llvm   if (Contents.empty())
80*2357e899Savl-llvm     return;
81*2357e899Savl-llvm 
82*2357e899Savl-llvm   MemoryBufferRef Mem(Contents, "obj");
83*2357e899Savl-llvm   Expected<std::unique_ptr<object::ObjectFile>> Obj =
84*2357e899Savl-llvm       object::ObjectFile::createObjectFile(Mem);
85*2357e899Savl-llvm   if (!Obj) {
86*2357e899Savl-llvm     consumeError(Obj.takeError());
87*2357e899Savl-llvm     Contents.clear();
88*2357e899Savl-llvm     return;
89*2357e899Savl-llvm   }
90*2357e899Savl-llvm 
91*2357e899Savl-llvm   for (const object::SectionRef &Sect : (*Obj).get()->sections()) {
92*2357e899Savl-llvm     Expected<StringRef> SectNameOrErr = Sect.getName();
93*2357e899Savl-llvm     if (!SectNameOrErr) {
94*2357e899Savl-llvm       consumeError(SectNameOrErr.takeError());
95*2357e899Savl-llvm       continue;
96*2357e899Savl-llvm     }
97*2357e899Savl-llvm     if (std::optional<DebugSectionKind> SectKind =
98*2357e899Savl-llvm             parseDebugTableName(*SectNameOrErr)) {
99*2357e899Savl-llvm       if (*SectKind == SectionKind) {
100*2357e899Savl-llvm         Expected<StringRef> Data = Sect.getContents();
101*2357e899Savl-llvm         if (!Data) {
102*2357e899Savl-llvm           consumeError(SectNameOrErr.takeError());
103*2357e899Savl-llvm           Contents.clear();
104*2357e899Savl-llvm           return;
105*2357e899Savl-llvm         }
106*2357e899Savl-llvm 
107*2357e899Savl-llvm         SectionOffsetInsideAsmPrinterOutputStart =
108*2357e899Savl-llvm             Data->data() - Contents.data();
109*2357e899Savl-llvm         SectionOffsetInsideAsmPrinterOutputEnd =
110*2357e899Savl-llvm             SectionOffsetInsideAsmPrinterOutputStart + Data->size();
111*2357e899Savl-llvm       }
112*2357e899Savl-llvm     }
113*2357e899Savl-llvm   }
114*2357e899Savl-llvm }
115*2357e899Savl-llvm 
emitString(dwarf::Form StringForm,const char * StringVal)116*2357e899Savl-llvm void SectionDescriptor::emitString(dwarf::Form StringForm,
117*2357e899Savl-llvm                                    const char *StringVal) {
118*2357e899Savl-llvm   assert(StringVal != nullptr);
119*2357e899Savl-llvm 
120*2357e899Savl-llvm   switch (StringForm) {
121*2357e899Savl-llvm   case dwarf::DW_FORM_string: {
122*2357e899Savl-llvm     emitInplaceString(StringVal);
123*2357e899Savl-llvm   } break;
124*2357e899Savl-llvm   case dwarf::DW_FORM_strp: {
125*2357e899Savl-llvm     notePatch(DebugStrPatch{
126*2357e899Savl-llvm         {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first});
127*2357e899Savl-llvm     emitStringPlaceholder();
128*2357e899Savl-llvm   } break;
129*2357e899Savl-llvm   case dwarf::DW_FORM_line_strp: {
130*2357e899Savl-llvm     notePatch(DebugLineStrPatch{
131*2357e899Savl-llvm         {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first});
132*2357e899Savl-llvm     emitStringPlaceholder();
133*2357e899Savl-llvm   } break;
134*2357e899Savl-llvm   default:
135*2357e899Savl-llvm     llvm_unreachable("Unsupported string form");
136*2357e899Savl-llvm     break;
137*2357e899Savl-llvm   };
138*2357e899Savl-llvm }
139*2357e899Savl-llvm 
emitIntVal(uint64_t Val,unsigned Size)140*2357e899Savl-llvm void SectionDescriptor::emitIntVal(uint64_t Val, unsigned Size) {
141*2357e899Savl-llvm   switch (Size) {
142*2357e899Savl-llvm   case 1: {
143*2357e899Savl-llvm     OS.write(static_cast<uint8_t>(Val));
144*2357e899Savl-llvm   } break;
145*2357e899Savl-llvm   case 2: {
146*2357e899Savl-llvm     uint16_t ShortVal = static_cast<uint16_t>(Val);
147*2357e899Savl-llvm     if (Endianess != llvm::endianness::native)
148*2357e899Savl-llvm       sys::swapByteOrder(ShortVal);
149*2357e899Savl-llvm     OS.write(reinterpret_cast<const char *>(&ShortVal), Size);
150*2357e899Savl-llvm   } break;
151*2357e899Savl-llvm   case 4: {
152*2357e899Savl-llvm     uint32_t ShortVal = static_cast<uint32_t>(Val);
153*2357e899Savl-llvm     if (Endianess != llvm::endianness::native)
154*2357e899Savl-llvm       sys::swapByteOrder(ShortVal);
155*2357e899Savl-llvm     OS.write(reinterpret_cast<const char *>(&ShortVal), Size);
156*2357e899Savl-llvm   } break;
157*2357e899Savl-llvm   case 8: {
158*2357e899Savl-llvm     if (Endianess != llvm::endianness::native)
159*2357e899Savl-llvm       sys::swapByteOrder(Val);
160*2357e899Savl-llvm     OS.write(reinterpret_cast<const char *>(&Val), Size);
161*2357e899Savl-llvm   } break;
162*2357e899Savl-llvm   default:
163*2357e899Savl-llvm     llvm_unreachable("Unsupported integer type size");
164*2357e899Savl-llvm   }
165*2357e899Savl-llvm }
166*2357e899Savl-llvm 
emitBinaryData(llvm::StringRef Data)167*2357e899Savl-llvm void SectionDescriptor::emitBinaryData(llvm::StringRef Data) {
168*2357e899Savl-llvm   OS.write(Data.data(), Data.size());
169*2357e899Savl-llvm }
170*2357e899Savl-llvm 
apply(uint64_t PatchOffset,dwarf::Form AttrForm,uint64_t Val)171*2357e899Savl-llvm void SectionDescriptor::apply(uint64_t PatchOffset, dwarf::Form AttrForm,
172*2357e899Savl-llvm                               uint64_t Val) {
173*2357e899Savl-llvm   switch (AttrForm) {
174*2357e899Savl-llvm   case dwarf::DW_FORM_strp:
175*2357e899Savl-llvm   case dwarf::DW_FORM_line_strp: {
176*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize());
177*2357e899Savl-llvm   } break;
178*2357e899Savl-llvm 
179*2357e899Savl-llvm   case dwarf::DW_FORM_ref_addr: {
180*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, Format.getRefAddrByteSize());
181*2357e899Savl-llvm   } break;
182*2357e899Savl-llvm   case dwarf::DW_FORM_ref1: {
183*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 1);
184*2357e899Savl-llvm   } break;
185*2357e899Savl-llvm   case dwarf::DW_FORM_ref2: {
186*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 2);
187*2357e899Savl-llvm   } break;
188*2357e899Savl-llvm   case dwarf::DW_FORM_ref4: {
189*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 4);
190*2357e899Savl-llvm   } break;
191*2357e899Savl-llvm   case dwarf::DW_FORM_ref8: {
192*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 8);
193*2357e899Savl-llvm   } break;
194*2357e899Savl-llvm 
195*2357e899Savl-llvm   case dwarf::DW_FORM_data1: {
196*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 1);
197*2357e899Savl-llvm   } break;
198*2357e899Savl-llvm   case dwarf::DW_FORM_data2: {
199*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 2);
200*2357e899Savl-llvm   } break;
201*2357e899Savl-llvm   case dwarf::DW_FORM_data4: {
202*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 4);
203*2357e899Savl-llvm   } break;
204*2357e899Savl-llvm   case dwarf::DW_FORM_data8: {
205*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 8);
206*2357e899Savl-llvm   } break;
207*2357e899Savl-llvm   case dwarf::DW_FORM_udata: {
208*2357e899Savl-llvm     applyULEB128(PatchOffset, Val);
209*2357e899Savl-llvm   } break;
210*2357e899Savl-llvm   case dwarf::DW_FORM_sdata: {
211*2357e899Savl-llvm     applySLEB128(PatchOffset, Val);
212*2357e899Savl-llvm   } break;
213*2357e899Savl-llvm   case dwarf::DW_FORM_sec_offset: {
214*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize());
215*2357e899Savl-llvm   } break;
216*2357e899Savl-llvm   case dwarf::DW_FORM_flag: {
217*2357e899Savl-llvm     applyIntVal(PatchOffset, Val, 1);
218*2357e899Savl-llvm   } break;
219*2357e899Savl-llvm 
220*2357e899Savl-llvm   default:
221*2357e899Savl-llvm     llvm_unreachable("Unsupported attribute form");
222*2357e899Savl-llvm     break;
223*2357e899Savl-llvm   }
224*2357e899Savl-llvm }
225*2357e899Savl-llvm 
getIntVal(uint64_t PatchOffset,unsigned Size)226*2357e899Savl-llvm uint64_t SectionDescriptor::getIntVal(uint64_t PatchOffset, unsigned Size) {
227*2357e899Savl-llvm   assert(PatchOffset < getContents().size());
228*2357e899Savl-llvm   switch (Size) {
229*2357e899Savl-llvm   case 1: {
230*2357e899Savl-llvm     return *reinterpret_cast<const uint8_t *>(
231*2357e899Savl-llvm         (getContents().data() + PatchOffset));
232*2357e899Savl-llvm   }
233*2357e899Savl-llvm   case 2: {
234*2357e899Savl-llvm     return support::endian::read16(getContents().data() + PatchOffset,
235*2357e899Savl-llvm                                    Endianess);
236*2357e899Savl-llvm   }
237*2357e899Savl-llvm   case 4: {
238*2357e899Savl-llvm     return support::endian::read32(getContents().data() + PatchOffset,
239*2357e899Savl-llvm                                    Endianess);
240*2357e899Savl-llvm   }
241*2357e899Savl-llvm   case 8: {
242*2357e899Savl-llvm     return support::endian::read64(getContents().data() + PatchOffset,
243*2357e899Savl-llvm                                    Endianess);
244*2357e899Savl-llvm   }
245*2357e899Savl-llvm   }
246*2357e899Savl-llvm   llvm_unreachable("Unsupported integer type size");
247*2357e899Savl-llvm   return 0;
248*2357e899Savl-llvm }
249*2357e899Savl-llvm 
applyIntVal(uint64_t PatchOffset,uint64_t Val,unsigned Size)250*2357e899Savl-llvm void SectionDescriptor::applyIntVal(uint64_t PatchOffset, uint64_t Val,
251*2357e899Savl-llvm                                     unsigned Size) {
252*2357e899Savl-llvm   assert(PatchOffset < getContents().size());
253*2357e899Savl-llvm 
254*2357e899Savl-llvm   switch (Size) {
255*2357e899Savl-llvm   case 1: {
256*2357e899Savl-llvm     support::endian::write(
257*2357e899Savl-llvm         const_cast<char *>(getContents().data() + PatchOffset),
258*2357e899Savl-llvm         static_cast<uint8_t>(Val), Endianess);
259*2357e899Savl-llvm   } break;
260*2357e899Savl-llvm   case 2: {
261*2357e899Savl-llvm     support::endian::write(
262*2357e899Savl-llvm         const_cast<char *>(getContents().data() + PatchOffset),
263*2357e899Savl-llvm         static_cast<uint16_t>(Val), Endianess);
264*2357e899Savl-llvm   } break;
265*2357e899Savl-llvm   case 4: {
266*2357e899Savl-llvm     support::endian::write(
267*2357e899Savl-llvm         const_cast<char *>(getContents().data() + PatchOffset),
268*2357e899Savl-llvm         static_cast<uint32_t>(Val), Endianess);
269*2357e899Savl-llvm   } break;
270*2357e899Savl-llvm   case 8: {
271*2357e899Savl-llvm     support::endian::write(
272*2357e899Savl-llvm         const_cast<char *>(getContents().data() + PatchOffset),
273*2357e899Savl-llvm         static_cast<uint64_t>(Val), Endianess);
274*2357e899Savl-llvm   } break;
275*2357e899Savl-llvm   default:
276*2357e899Savl-llvm     llvm_unreachable("Unsupported integer type size");
277*2357e899Savl-llvm   }
278*2357e899Savl-llvm }
279*2357e899Savl-llvm 
applyULEB128(uint64_t PatchOffset,uint64_t Val)280*2357e899Savl-llvm void SectionDescriptor::applyULEB128(uint64_t PatchOffset, uint64_t Val) {
281*2357e899Savl-llvm   assert(PatchOffset < getContents().size());
282*2357e899Savl-llvm 
283*2357e899Savl-llvm   uint8_t ULEB[16];
284*2357e899Savl-llvm   uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1;
285*2357e899Savl-llvm   uint8_t RealSize = encodeULEB128(Val, ULEB, DestSize);
286*2357e899Savl-llvm 
287*2357e899Savl-llvm   memcpy(const_cast<char *>(getContents().data() + PatchOffset), ULEB,
288*2357e899Savl-llvm          RealSize);
289*2357e899Savl-llvm }
290*2357e899Savl-llvm 
291*2357e899Savl-llvm /// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
applySLEB128(uint64_t PatchOffset,uint64_t Val)292*2357e899Savl-llvm void SectionDescriptor::applySLEB128(uint64_t PatchOffset, uint64_t Val) {
293*2357e899Savl-llvm   assert(PatchOffset < getContents().size());
294*2357e899Savl-llvm 
295*2357e899Savl-llvm   uint8_t SLEB[16];
296*2357e899Savl-llvm   uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1;
297*2357e899Savl-llvm   uint8_t RealSize = encodeSLEB128(Val, SLEB, DestSize);
298*2357e899Savl-llvm 
299*2357e899Savl-llvm   memcpy(const_cast<char *>(getContents().data() + PatchOffset), SLEB,
300*2357e899Savl-llvm          RealSize);
301*2357e899Savl-llvm }
302*2357e899Savl-llvm 
applyPatches(SectionDescriptor & Section,StringEntryToDwarfStringPoolEntryMap & DebugStrStrings,StringEntryToDwarfStringPoolEntryMap & DebugLineStrStrings,TypeUnit * TypeUnitPtr)303*2357e899Savl-llvm void OutputSections::applyPatches(
304*2357e899Savl-llvm     SectionDescriptor &Section,
305*2357e899Savl-llvm     StringEntryToDwarfStringPoolEntryMap &DebugStrStrings,
306*2357e899Savl-llvm     StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings,
307*2357e899Savl-llvm     TypeUnit *TypeUnitPtr) {
308*2357e899Savl-llvm   Section.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
309*2357e899Savl-llvm     DwarfStringPoolEntryWithExtString *Entry =
310*2357e899Savl-llvm         DebugStrStrings.getExistingEntry(Patch.String);
311*2357e899Savl-llvm     assert(Entry != nullptr);
312*2357e899Savl-llvm 
313*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
314*2357e899Savl-llvm   });
315*2357e899Savl-llvm   Section.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) {
316*2357e899Savl-llvm     assert(TypeUnitPtr != nullptr);
317*2357e899Savl-llvm     TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
318*2357e899Savl-llvm     assert(TypeEntry &&
319*2357e899Savl-llvm            formatv("No data for type {0}", Patch.TypeName->getKey())
320*2357e899Savl-llvm                .str()
321*2357e899Savl-llvm                .c_str());
322*2357e899Savl-llvm 
323*2357e899Savl-llvm     if (&TypeEntry->getFinalDie() != Patch.Die)
324*2357e899Savl-llvm       return;
325*2357e899Savl-llvm 
326*2357e899Savl-llvm     DwarfStringPoolEntryWithExtString *Entry =
327*2357e899Savl-llvm         DebugStrStrings.getExistingEntry(Patch.String);
328*2357e899Savl-llvm     assert(Entry != nullptr);
329*2357e899Savl-llvm 
330*2357e899Savl-llvm     Patch.PatchOffset +=
331*2357e899Savl-llvm         Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber());
332*2357e899Savl-llvm 
333*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
334*2357e899Savl-llvm   });
335*2357e899Savl-llvm 
336*2357e899Savl-llvm   Section.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
337*2357e899Savl-llvm     DwarfStringPoolEntryWithExtString *Entry =
338*2357e899Savl-llvm         DebugLineStrStrings.getExistingEntry(Patch.String);
339*2357e899Savl-llvm     assert(Entry != nullptr);
340*2357e899Savl-llvm 
341*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
342*2357e899Savl-llvm   });
343*2357e899Savl-llvm   Section.ListDebugTypeLineStrPatch.forEach([&](DebugTypeLineStrPatch &Patch) {
344*2357e899Savl-llvm     assert(TypeUnitPtr != nullptr);
345*2357e899Savl-llvm     TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
346*2357e899Savl-llvm     assert(TypeEntry &&
347*2357e899Savl-llvm            formatv("No data for type {0}", Patch.TypeName->getKey())
348*2357e899Savl-llvm                .str()
349*2357e899Savl-llvm                .c_str());
350*2357e899Savl-llvm 
351*2357e899Savl-llvm     if (&TypeEntry->getFinalDie() != Patch.Die)
352*2357e899Savl-llvm       return;
353*2357e899Savl-llvm 
354*2357e899Savl-llvm     DwarfStringPoolEntryWithExtString *Entry =
355*2357e899Savl-llvm         DebugLineStrStrings.getExistingEntry(Patch.String);
356*2357e899Savl-llvm     assert(Entry != nullptr);
357*2357e899Savl-llvm 
358*2357e899Savl-llvm     Patch.PatchOffset +=
359*2357e899Savl-llvm         Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber());
360*2357e899Savl-llvm 
361*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
362*2357e899Savl-llvm   });
363*2357e899Savl-llvm 
364*2357e899Savl-llvm   std::optional<SectionDescriptor *> RangeSection;
365*2357e899Savl-llvm   if (Format.Version >= 5)
366*2357e899Savl-llvm     RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRngLists);
367*2357e899Savl-llvm   else
368*2357e899Savl-llvm     RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRange);
369*2357e899Savl-llvm 
370*2357e899Savl-llvm   if (RangeSection) {
371*2357e899Savl-llvm     Section.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
372*2357e899Savl-llvm       uint64_t FinalValue =
373*2357e899Savl-llvm           Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
374*2357e899Savl-llvm       FinalValue += (*RangeSection)->StartOffset;
375*2357e899Savl-llvm 
376*2357e899Savl-llvm       Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
377*2357e899Savl-llvm     });
378*2357e899Savl-llvm   }
379*2357e899Savl-llvm 
380*2357e899Savl-llvm   std::optional<SectionDescriptor *> LocationSection;
381*2357e899Savl-llvm   if (Format.Version >= 5)
382*2357e899Savl-llvm     LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLocLists);
383*2357e899Savl-llvm   else
384*2357e899Savl-llvm     LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLoc);
385*2357e899Savl-llvm 
386*2357e899Savl-llvm   if (LocationSection) {
387*2357e899Savl-llvm     Section.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
388*2357e899Savl-llvm       uint64_t FinalValue =
389*2357e899Savl-llvm           Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
390*2357e899Savl-llvm       FinalValue += (*LocationSection)->StartOffset;
391*2357e899Savl-llvm 
392*2357e899Savl-llvm       Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
393*2357e899Savl-llvm     });
394*2357e899Savl-llvm   }
395*2357e899Savl-llvm 
396*2357e899Savl-llvm   Section.ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {
397*2357e899Savl-llvm     uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset;
398*2357e899Savl-llvm     dwarf::Form FinalForm = dwarf::DW_FORM_ref4;
399*2357e899Savl-llvm 
400*2357e899Savl-llvm     // Check whether it is local or inter-CU reference.
401*2357e899Savl-llvm     if (!Patch.RefCU.getInt()) {
402*2357e899Savl-llvm       SectionDescriptor &ReferencedSectionDescriptor =
403*2357e899Savl-llvm           Patch.RefCU.getPointer()->getSectionDescriptor(
404*2357e899Savl-llvm               DebugSectionKind::DebugInfo);
405*2357e899Savl-llvm 
406*2357e899Savl-llvm       FinalForm = dwarf::DW_FORM_ref_addr;
407*2357e899Savl-llvm       FinalOffset += ReferencedSectionDescriptor.StartOffset;
408*2357e899Savl-llvm     }
409*2357e899Savl-llvm 
410*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, FinalForm, FinalOffset);
411*2357e899Savl-llvm   });
412*2357e899Savl-llvm 
413*2357e899Savl-llvm   Section.ListDebugULEB128DieRefPatch.forEach(
414*2357e899Savl-llvm       [&](DebugULEB128DieRefPatch &Patch) {
415*2357e899Savl-llvm         assert(Patch.RefCU.getInt());
416*2357e899Savl-llvm         Section.apply(Patch.PatchOffset, dwarf::DW_FORM_udata,
417*2357e899Savl-llvm                       Patch.RefDieIdxOrClonedOffset);
418*2357e899Savl-llvm       });
419*2357e899Savl-llvm 
420*2357e899Savl-llvm   Section.ListDebugDieTypeRefPatch.forEach([&](DebugDieTypeRefPatch &Patch) {
421*2357e899Savl-llvm     assert(TypeUnitPtr != nullptr);
422*2357e899Savl-llvm     assert(Patch.RefTypeName != nullptr);
423*2357e899Savl-llvm 
424*2357e899Savl-llvm     TypeEntryBody *TypeEntry = Patch.RefTypeName->getValue().load();
425*2357e899Savl-llvm     assert(TypeEntry &&
426*2357e899Savl-llvm            formatv("No data for type {0}", Patch.RefTypeName->getKey())
427*2357e899Savl-llvm                .str()
428*2357e899Savl-llvm                .c_str());
429*2357e899Savl-llvm 
430*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref_addr,
431*2357e899Savl-llvm                   TypeEntry->getFinalDie().getOffset());
432*2357e899Savl-llvm   });
433*2357e899Savl-llvm 
434*2357e899Savl-llvm   Section.ListDebugType2TypeDieRefPatch.forEach(
435*2357e899Savl-llvm       [&](DebugType2TypeDieRefPatch &Patch) {
436*2357e899Savl-llvm         assert(TypeUnitPtr != nullptr);
437*2357e899Savl-llvm         TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
438*2357e899Savl-llvm         assert(TypeEntry &&
439*2357e899Savl-llvm                formatv("No data for type {0}", Patch.TypeName->getKey())
440*2357e899Savl-llvm                    .str()
441*2357e899Savl-llvm                    .c_str());
442*2357e899Savl-llvm 
443*2357e899Savl-llvm         if (&TypeEntry->getFinalDie() != Patch.Die)
444*2357e899Savl-llvm           return;
445*2357e899Savl-llvm 
446*2357e899Savl-llvm         Patch.PatchOffset += Patch.Die->getOffset() +
447*2357e899Savl-llvm                              getULEB128Size(Patch.Die->getAbbrevNumber());
448*2357e899Savl-llvm 
449*2357e899Savl-llvm         assert(Patch.RefTypeName != nullptr);
450*2357e899Savl-llvm         TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load();
451*2357e899Savl-llvm         assert(TypeEntry &&
452*2357e899Savl-llvm                formatv("No data for type {0}", Patch.RefTypeName->getKey())
453*2357e899Savl-llvm                    .str()
454*2357e899Savl-llvm                    .c_str());
455*2357e899Savl-llvm 
456*2357e899Savl-llvm         Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref4,
457*2357e899Savl-llvm                       RefTypeEntry->getFinalDie().getOffset());
458*2357e899Savl-llvm       });
459*2357e899Savl-llvm 
460*2357e899Savl-llvm   Section.ListDebugOffsetPatch.forEach([&](DebugOffsetPatch &Patch) {
461*2357e899Savl-llvm     uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset;
462*2357e899Savl-llvm 
463*2357e899Savl-llvm     // Check whether we need to read value from the original location.
464*2357e899Savl-llvm     if (Patch.SectionPtr.getInt())
465*2357e899Savl-llvm       FinalValue +=
466*2357e899Savl-llvm           Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
467*2357e899Savl-llvm 
468*2357e899Savl-llvm     Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
469*2357e899Savl-llvm   });
470*2357e899Savl-llvm }
471