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