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