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