LLVM 18.0.0git
DWARFStreamer.cpp
Go to the documentation of this file.
1//===- DwarfStreamer.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
16#include "llvm/MC/MCDwarf.h"
18#include "llvm/MC/MCSection.h"
19#include "llvm/MC/MCStreamer.h"
25#include "llvm/Support/LEB128.h"
28
29namespace llvm {
30
32 StringRef Swift5ReflectionSegmentName) {
33 std::string ErrorStr;
34 std::string TripleName;
35
36 // Get the target.
37 const Target *TheTarget =
38 TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
39 if (!TheTarget)
40 return createStringError(std::errc::invalid_argument, ErrorStr.c_str());
41
42 TripleName = TheTriple.getTriple();
43
44 // Create all the MC Objects.
45 MRI.reset(TheTarget->createMCRegInfo(TripleName));
46 if (!MRI)
47 return createStringError(std::errc::invalid_argument,
48 "no register info for target %s",
49 TripleName.c_str());
50
52 MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
53 if (!MAI)
54 return createStringError(std::errc::invalid_argument,
55 "no asm info for target %s", TripleName.c_str());
56
57 MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
58 if (!MSTI)
59 return createStringError(std::errc::invalid_argument,
60 "no subtarget info for target %s",
61 TripleName.c_str());
62
63 MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
64 nullptr, true, Swift5ReflectionSegmentName));
65 MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));
66 MC->setObjectFileInfo(MOFI.get());
67
68 MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
69 if (!MAB)
70 return createStringError(std::errc::invalid_argument,
71 "no asm backend for target %s",
72 TripleName.c_str());
73
74 MII.reset(TheTarget->createMCInstrInfo());
75 if (!MII)
76 return createStringError(std::errc::invalid_argument,
77 "no instr info info for target %s",
78 TripleName.c_str());
79
80 MCE = TheTarget->createMCCodeEmitter(*MII, *MC);
81 if (!MCE)
82 return createStringError(std::errc::invalid_argument,
83 "no code emitter for target %s",
84 TripleName.c_str());
85
86 switch (OutFileType) {
88 MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
89 *MAI, *MII, *MRI);
90 MS = TheTarget->createAsmStreamer(
91 *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP,
92 std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
93 true);
94 break;
95 }
97 MS = TheTarget->createMCObjectStreamer(
98 TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
99 MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),
100 *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
101 /*DWARFMustBeAtTheEnd*/ false);
102 break;
103 }
104 }
105
106 if (!MS)
107 return createStringError(std::errc::invalid_argument,
108 "no object streamer for target %s",
109 TripleName.c_str());
110
111 // Finally create the AsmPrinter we'll use to emit the DIEs.
112 TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
113 std::nullopt));
114 if (!TM)
115 return createStringError(std::errc::invalid_argument,
116 "no target machine for target %s",
117 TripleName.c_str());
118
119 Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
120 if (!Asm)
121 return createStringError(std::errc::invalid_argument,
122 "no asm printer for target %s",
123 TripleName.c_str());
124 Asm->setDwarfUsesRelocationsAcrossSections(false);
125
126 RangesSectionSize = 0;
127 RngListsSectionSize = 0;
128 LocSectionSize = 0;
129 LocListsSectionSize = 0;
130 LineSectionSize = 0;
131 FrameSectionSize = 0;
132 DebugInfoSectionSize = 0;
133 MacInfoSectionSize = 0;
134 MacroSectionSize = 0;
135
136 return Error::success();
137}
138
140
141void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
142 MS->switchSection(MOFI->getDwarfInfoSection());
143 MC->setDwarfVersion(DwarfVersion);
144}
145
146/// Emit the compilation unit header for \p Unit in the debug_info section.
147///
148/// A Dwarf 4 section header is encoded as:
149/// uint32_t Unit length (omitting this field)
150/// uint16_t Version
151/// uint32_t Abbreviation table offset
152/// uint8_t Address size
153/// Leading to a total of 11 bytes.
154///
155/// A Dwarf 5 section header is encoded as:
156/// uint32_t Unit length (omitting this field)
157/// uint16_t Version
158/// uint8_t Unit type
159/// uint8_t Address size
160/// uint32_t Abbreviation table offset
161/// Leading to a total of 12 bytes.
163 unsigned DwarfVersion) {
164 switchToDebugInfoSection(DwarfVersion);
165
166 /// The start of the unit within its section.
167 Unit.setLabelBegin(Asm->createTempSymbol("cu_begin"));
168 Asm->OutStreamer->emitLabel(Unit.getLabelBegin());
169
170 // Emit size of content not including length itself. The size has already
171 // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
172 // account for the length field.
173 Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
174 Asm->emitInt16(DwarfVersion);
175
176 if (DwarfVersion >= 5) {
177 Asm->emitInt8(dwarf::DW_UT_compile);
178 Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
179 // We share one abbreviations table across all units so it's always at the
180 // start of the section.
181 Asm->emitInt32(0);
182 DebugInfoSectionSize += 12;
183 } else {
184 // We share one abbreviations table across all units so it's always at the
185 // start of the section.
186 Asm->emitInt32(0);
187 Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
188 DebugInfoSectionSize += 11;
189 }
190
191 // Remember this CU.
192 EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
193}
194
195/// Emit the \p Abbrevs array as the shared abbreviation table
196/// for the linked Dwarf file.
198 const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
199 unsigned DwarfVersion) {
200 MS->switchSection(MOFI->getDwarfAbbrevSection());
201 MC->setDwarfVersion(DwarfVersion);
202 Asm->emitDwarfAbbrevs(Abbrevs);
203}
204
205/// Recursively emit the DIE tree rooted at \p Die.
207 MS->switchSection(MOFI->getDwarfInfoSection());
208 Asm->emitDwarfDIE(Die);
209 DebugInfoSectionSize += Die.getSize();
210}
211
212/// Emit contents of section SecName From Obj.
214 MCSection *Section =
216 .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
217 .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
218 .Case("debug_ranges",
219 MC->getObjectFileInfo()->getDwarfRangesSection())
220 .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
221 .Case("debug_aranges",
222 MC->getObjectFileInfo()->getDwarfARangesSection())
223 .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
224 .Case("debug_rnglists",
225 MC->getObjectFileInfo()->getDwarfRnglistsSection())
226 .Case("debug_loclists",
227 MC->getObjectFileInfo()->getDwarfLoclistsSection())
228 .Default(nullptr);
229
230 if (Section) {
231 MS->switchSection(Section);
232
233 MS->emitBytes(SecData);
234 }
235}
236
237/// Emit the debug_str section stored in \p Pool.
239 Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
240 std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
241 for (auto Entry : Entries) {
242 // Emit the string itself.
243 Asm->OutStreamer->emitBytes(Entry.getString());
244 // Emit a null terminator.
245 Asm->emitInt8(0);
246 }
247}
248
249/// Emit the debug string offset table described by \p StringOffsets into the
250/// .debug_str_offsets table.
252 const SmallVector<uint64_t> &StringOffsets, uint16_t TargetDWARFVersion) {
253
254 if (TargetDWARFVersion < 5 || StringOffsets.empty())
255 return;
256
257 Asm->OutStreamer->switchSection(MOFI->getDwarfStrOffSection());
258
259 MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugstroff");
260 MCSymbol *EndLabel = Asm->createTempSymbol("Edebugstroff");
261
262 // Length.
263 Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
264 Asm->OutStreamer->emitLabel(BeginLabel);
265 StrOffsetSectionSize += sizeof(uint32_t);
266
267 // Version.
268 MS->emitInt16(5);
269 StrOffsetSectionSize += sizeof(uint16_t);
270
271 // Padding.
272 MS->emitInt16(0);
273 StrOffsetSectionSize += sizeof(uint16_t);
274
275 for (auto Off : StringOffsets) {
276 Asm->OutStreamer->emitInt32(Off);
277 StrOffsetSectionSize += sizeof(uint32_t);
278 }
279 Asm->OutStreamer->emitLabel(EndLabel);
280}
281
282/// Emit the debug_line_str section stored in \p Pool.
284 Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection());
285 std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
286 for (auto Entry : Entries) {
287 // Emit the string itself.
288 Asm->OutStreamer->emitBytes(Entry.getString());
289 // Emit a null terminator.
290 Asm->emitInt8(0);
291 }
292}
293
295 if (EmittedUnits.empty())
296 return;
297
298 // Build up data structures needed to emit this section.
299 std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;
300 DenseMap<unsigned, unsigned> UniqueIdToCuMap;
301 unsigned Id = 0;
302 for (auto &CU : EmittedUnits) {
303 CompUnits.push_back(CU.LabelBegin);
304 // We might be omitting CUs, so we need to remap them.
305 UniqueIdToCuMap[CU.ID] = Id++;
306 }
307
308 Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
309 dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false,
310 (uint64_t)UniqueIdToCuMap.size() - 1);
311 /// llvm-dwarfutil doesn't support type units + .debug_names right now.
312 // FIXME: add support for type units + .debug_names. For now the behavior is
313 // unsuported.
315 Asm.get(), Table, CompUnits,
316 [&](const DWARF5AccelTableData &Entry)
317 -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
318 if (UniqueIdToCuMap.size() > 1)
319 return {{UniqueIdToCuMap[Entry.getUnitID()],
320 {dwarf::DW_IDX_compile_unit, Form}}};
321 return std::nullopt;
322 });
323}
324
325void DwarfStreamer::emitAppleNamespaces(
327 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
328 auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
329 Asm->OutStreamer->emitLabel(SectionBegin);
330 emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);
331}
332
333void DwarfStreamer::emitAppleNames(
335 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
336 auto *SectionBegin = Asm->createTempSymbol("names_begin");
337 Asm->OutStreamer->emitLabel(SectionBegin);
338 emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);
339}
340
341void DwarfStreamer::emitAppleObjc(
343 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
344 auto *SectionBegin = Asm->createTempSymbol("objc_begin");
345 Asm->OutStreamer->emitLabel(SectionBegin);
346 emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);
347}
348
349void DwarfStreamer::emitAppleTypes(
351 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
352 auto *SectionBegin = Asm->createTempSymbol("types_begin");
353 Asm->OutStreamer->emitLabel(SectionBegin);
354 emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);
355}
356
357/// Emit the swift_ast section stored in \p Buffers.
358void DwarfStreamer::emitSwiftAST(StringRef Buffer) {
359 MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
360 SwiftASTSection->setAlignment(Align(32));
361 MS->switchSection(SwiftASTSection);
362 MS->emitBytes(Buffer);
363}
364
365void DwarfStreamer::emitSwiftReflectionSection(
367 StringRef Buffer, uint32_t Alignment, uint32_t Size) {
368 MCSection *ReflectionSection =
369 MOFI->getSwift5ReflectionSection(ReflSectionKind);
370 if (ReflectionSection == nullptr)
371 return;
372 ReflectionSection->setAlignment(Align(Alignment));
373 MS->switchSection(ReflectionSection);
374 MS->emitBytes(Buffer);
375}
376
377void DwarfStreamer::emitDwarfDebugArangesTable(
378 const CompileUnit &Unit, const AddressRanges &LinkedRanges) {
379 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
380
381 // Make .debug_aranges to be current section.
382 MS->switchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
383
384 // Emit Header.
385 MCSymbol *BeginLabel = Asm->createTempSymbol("Barange");
386 MCSymbol *EndLabel = Asm->createTempSymbol("Earange");
387
388 unsigned HeaderSize =
389 sizeof(int32_t) + // Size of contents (w/o this field
390 sizeof(int16_t) + // DWARF ARange version number
391 sizeof(int32_t) + // Offset of CU in the .debug_info section
392 sizeof(int8_t) + // Pointer Size (in bytes)
393 sizeof(int8_t); // Segment Size (in bytes)
394
395 unsigned TupleSize = AddressSize * 2;
396 unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
397
398 Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
399 Asm->OutStreamer->emitLabel(BeginLabel);
400 Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number
401 Asm->emitInt32(Unit.getStartOffset()); // Corresponding unit's offset
402 Asm->emitInt8(AddressSize); // Address size
403 Asm->emitInt8(0); // Segment size
404
405 Asm->OutStreamer->emitFill(Padding, 0x0);
406
407 // Emit linked ranges.
408 for (const AddressRange &Range : LinkedRanges) {
409 MS->emitIntValue(Range.start(), AddressSize);
410 MS->emitIntValue(Range.end() - Range.start(), AddressSize);
411 }
412
413 // Emit terminator.
414 Asm->OutStreamer->emitIntValue(0, AddressSize);
415 Asm->OutStreamer->emitIntValue(0, AddressSize);
416 Asm->OutStreamer->emitLabel(EndLabel);
417}
418
419void DwarfStreamer::emitDwarfDebugRangesTableFragment(
420 const CompileUnit &Unit, const AddressRanges &LinkedRanges,
421 PatchLocation Patch) {
422 Patch.set(RangesSectionSize);
423
424 // Make .debug_ranges to be current section.
425 MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
426 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
427
428 // Emit ranges.
429 uint64_t BaseAddress = 0;
430 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
431 BaseAddress = *LowPC;
432
433 for (const AddressRange &Range : LinkedRanges) {
434 MS->emitIntValue(Range.start() - BaseAddress, AddressSize);
435 MS->emitIntValue(Range.end() - BaseAddress, AddressSize);
436
437 RangesSectionSize += AddressSize;
438 RangesSectionSize += AddressSize;
439 }
440
441 // Add the terminator entry.
442 MS->emitIntValue(0, AddressSize);
443 MS->emitIntValue(0, AddressSize);
444
445 RangesSectionSize += AddressSize;
446 RangesSectionSize += AddressSize;
447}
448
449MCSymbol *
450DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) {
451 if (Unit.getOrigUnit().getVersion() < 5)
452 return nullptr;
453
454 // Make .debug_rnglists to be current section.
455 MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
456
457 MCSymbol *BeginLabel = Asm->createTempSymbol("Brnglists");
458 MCSymbol *EndLabel = Asm->createTempSymbol("Ernglists");
459 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
460
461 // Length
462 Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
463 Asm->OutStreamer->emitLabel(BeginLabel);
464 RngListsSectionSize += sizeof(uint32_t);
465
466 // Version.
467 MS->emitInt16(5);
468 RngListsSectionSize += sizeof(uint16_t);
469
470 // Address size.
471 MS->emitInt8(AddressSize);
472 RngListsSectionSize++;
473
474 // Seg_size
475 MS->emitInt8(0);
476 RngListsSectionSize++;
477
478 // Offset entry count
479 MS->emitInt32(0);
480 RngListsSectionSize += sizeof(uint32_t);
481
482 return EndLabel;
483}
484
485void DwarfStreamer::emitDwarfDebugRangeListFragment(
486 const CompileUnit &Unit, const AddressRanges &LinkedRanges,
487 PatchLocation Patch, DebugDieValuePool &AddrPool) {
488 if (Unit.getOrigUnit().getVersion() < 5) {
489 emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
490 return;
491 }
492
493 emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool);
494}
495
496void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
497 MCSymbol *EndLabel) {
498 if (Unit.getOrigUnit().getVersion() < 5)
499 return;
500
501 // Make .debug_rnglists to be current section.
502 MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
503
504 if (EndLabel != nullptr)
505 Asm->OutStreamer->emitLabel(EndLabel);
506}
507
508void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
509 const CompileUnit &Unit, const AddressRanges &LinkedRanges,
510 PatchLocation Patch, DebugDieValuePool &AddrPool) {
511 Patch.set(RngListsSectionSize);
512
513 // Make .debug_rnglists to be current section.
514 MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
515 std::optional<uint64_t> BaseAddress;
516
517 for (const AddressRange &Range : LinkedRanges) {
518
519 if (!BaseAddress) {
520 BaseAddress = Range.start();
521
522 // Emit base address.
523 MS->emitInt8(dwarf::DW_RLE_base_addressx);
524 RngListsSectionSize += 1;
525 RngListsSectionSize +=
526 MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress));
527 }
528
529 // Emit type of entry.
530 MS->emitInt8(dwarf::DW_RLE_offset_pair);
531 RngListsSectionSize += 1;
532
533 // Emit start offset relative to base address.
534 RngListsSectionSize +=
535 MS->emitULEB128IntValue(Range.start() - *BaseAddress);
536
537 // Emit end offset relative to base address.
538 RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - *BaseAddress);
539 }
540
541 // Emit the terminator entry.
542 MS->emitInt8(dwarf::DW_RLE_end_of_list);
543 RngListsSectionSize += 1;
544}
545
546/// Emit debug locations(.debug_loc, .debug_loclists) header.
547MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) {
548 if (Unit.getOrigUnit().getVersion() < 5)
549 return nullptr;
550
551 // Make .debug_loclists the current section.
552 MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
553
554 MCSymbol *BeginLabel = Asm->createTempSymbol("Bloclists");
555 MCSymbol *EndLabel = Asm->createTempSymbol("Eloclists");
556 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
557
558 // Length
559 Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
560 Asm->OutStreamer->emitLabel(BeginLabel);
561 LocListsSectionSize += sizeof(uint32_t);
562
563 // Version.
564 MS->emitInt16(5);
565 LocListsSectionSize += sizeof(uint16_t);
566
567 // Address size.
568 MS->emitInt8(AddressSize);
569 LocListsSectionSize++;
570
571 // Seg_size
572 MS->emitInt8(0);
573 LocListsSectionSize++;
574
575 // Offset entry count
576 MS->emitInt32(0);
577 LocListsSectionSize += sizeof(uint32_t);
578
579 return EndLabel;
580}
581
582/// Emit debug locations(.debug_loc, .debug_loclists) fragment.
583void DwarfStreamer::emitDwarfDebugLocListFragment(
584 const CompileUnit &Unit,
585 const DWARFLocationExpressionsVector &LinkedLocationExpression,
586 PatchLocation Patch, DebugDieValuePool &AddrPool) {
587 if (Unit.getOrigUnit().getVersion() < 5) {
588 emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
589 return;
590 }
591
592 emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch,
593 AddrPool);
594}
595
596/// Emit debug locations(.debug_loc, .debug_loclists) footer.
597void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit,
598 MCSymbol *EndLabel) {
599 if (Unit.getOrigUnit().getVersion() < 5)
600 return;
601
602 // Make .debug_loclists the current section.
603 MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
604
605 if (EndLabel != nullptr)
606 Asm->OutStreamer->emitLabel(EndLabel);
607}
608
609/// Emit piece of .debug_loc for \p LinkedLocationExpression.
610void DwarfStreamer::emitDwarfDebugLocTableFragment(
611 const CompileUnit &Unit,
612 const DWARFLocationExpressionsVector &LinkedLocationExpression,
613 PatchLocation Patch) {
614 Patch.set(LocSectionSize);
615
616 // Make .debug_loc to be current section.
617 MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
618 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
619
620 // Emit ranges.
621 uint64_t BaseAddress = 0;
622 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
623 BaseAddress = *LowPC;
624
625 for (const DWARFLocationExpression &LocExpression :
626 LinkedLocationExpression) {
627 if (LocExpression.Range) {
628 MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize);
629 MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize);
630
631 LocSectionSize += AddressSize;
632 LocSectionSize += AddressSize;
633 }
634
635 Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2);
636 Asm->OutStreamer->emitBytes(StringRef(
637 (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
638 LocSectionSize += LocExpression.Expr.size() + 2;
639 }
640
641 // Add the terminator entry.
642 MS->emitIntValue(0, AddressSize);
643 MS->emitIntValue(0, AddressSize);
644
645 LocSectionSize += AddressSize;
646 LocSectionSize += AddressSize;
647}
648
649/// Emit .debug_addr header.
650MCSymbol *DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit &Unit) {
651
652 // Make .debug_addr the current section.
653 MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
654
655 MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugaddr");
656 MCSymbol *EndLabel = Asm->createTempSymbol("Edebugaddr");
657 unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize();
658
659 // Emit length.
660 Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
661 Asm->OutStreamer->emitLabel(BeginLabel);
662 AddrSectionSize += sizeof(uint32_t);
663
664 // Emit version.
665 Asm->emitInt16(5);
666 AddrSectionSize += 2;
667
668 // Emit address size.
669 Asm->emitInt8(AddrSize);
670 AddrSectionSize += 1;
671
672 // Emit segment size.
673 Asm->emitInt8(0);
674 AddrSectionSize += 1;
675
676 return EndLabel;
677}
678
679/// Emit the .debug_addr addresses stored in \p Addrs.
680void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
681 uint8_t AddrSize) {
682 Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection());
683 for (auto Addr : Addrs) {
684 Asm->OutStreamer->emitIntValue(Addr, AddrSize);
685 AddrSectionSize += AddrSize;
686 }
687}
688
689/// Emit .debug_addr footer.
690void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
691 MCSymbol *EndLabel) {
692
693 // Make .debug_addr the current section.
694 MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
695
696 if (EndLabel != nullptr)
697 Asm->OutStreamer->emitLabel(EndLabel);
698}
699
700/// Emit piece of .debug_loclists for \p LinkedLocationExpression.
701void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
702 const CompileUnit &Unit,
703 const DWARFLocationExpressionsVector &LinkedLocationExpression,
704 PatchLocation Patch, DebugDieValuePool &AddrPool) {
705 Patch.set(LocListsSectionSize);
706
707 // Make .debug_loclists the current section.
708 MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
709 std::optional<uint64_t> BaseAddress;
710
711 for (const DWARFLocationExpression &LocExpression :
712 LinkedLocationExpression) {
713 if (LocExpression.Range) {
714
715 if (!BaseAddress) {
716
717 BaseAddress = LocExpression.Range->LowPC;
718
719 // Emit base address.
720 MS->emitInt8(dwarf::DW_LLE_base_addressx);
721 LocListsSectionSize += 1;
722 LocListsSectionSize +=
723 MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress));
724 }
725
726 // Emit type of entry.
727 MS->emitInt8(dwarf::DW_LLE_offset_pair);
728 LocListsSectionSize += 1;
729
730 // Emit start offset relative to base address.
731 LocListsSectionSize +=
732 MS->emitULEB128IntValue(LocExpression.Range->LowPC - *BaseAddress);
733
734 // Emit end offset relative to base address.
735 LocListsSectionSize +=
736 MS->emitULEB128IntValue(LocExpression.Range->HighPC - *BaseAddress);
737 } else {
738 // Emit type of entry.
739 MS->emitInt8(dwarf::DW_LLE_default_location);
740 LocListsSectionSize += 1;
741 }
742
743 LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size());
744 Asm->OutStreamer->emitBytes(StringRef(
745 (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
746 LocListsSectionSize += LocExpression.Expr.size();
747 }
748
749 // Emit the terminator entry.
750 MS->emitInt8(dwarf::DW_LLE_end_of_list);
751 LocListsSectionSize += 1;
752}
753
754void DwarfStreamer::emitLineTableForUnit(
755 const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit,
756 OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) {
757 // Switch to the section where the table will be emitted into.
758 MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection());
759
760 MCSymbol *LineStartSym = MC->createTempSymbol();
761 MCSymbol *LineEndSym = MC->createTempSymbol();
762
763 // unit_length.
764 if (LineTable.Prologue.FormParams.Format == dwarf::DwarfFormat::DWARF64) {
765 MS->emitInt32(dwarf::DW_LENGTH_DWARF64);
766 LineSectionSize += 4;
767 }
768 emitLabelDifference(LineEndSym, LineStartSym,
769 LineTable.Prologue.FormParams.Format, LineSectionSize);
770 Asm->OutStreamer->emitLabel(LineStartSym);
771
772 // Emit prologue.
773 emitLineTablePrologue(LineTable.Prologue, DebugStrPool, DebugLineStrPool);
774
775 // Emit rows.
776 emitLineTableRows(LineTable, LineEndSym,
777 Unit.getOrigUnit().getAddressByteSize());
778}
779
780void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
781 OffsetsStringPool &DebugStrPool,
782 OffsetsStringPool &DebugLineStrPool) {
783 MCSymbol *PrologueStartSym = MC->createTempSymbol();
784 MCSymbol *PrologueEndSym = MC->createTempSymbol();
785
786 // version (uhalf).
787 MS->emitInt16(P.getVersion());
788 LineSectionSize += 2;
789 if (P.getVersion() == 5) {
790 // address_size (ubyte).
791 MS->emitInt8(P.getAddressSize());
792 LineSectionSize += 1;
793
794 // segment_selector_size (ubyte).
795 MS->emitInt8(P.SegSelectorSize);
796 LineSectionSize += 1;
797 }
798
799 // header_length.
800 emitLabelDifference(PrologueEndSym, PrologueStartSym, P.FormParams.Format,
801 LineSectionSize);
802
803 Asm->OutStreamer->emitLabel(PrologueStartSym);
804 emitLineTableProloguePayload(P, DebugStrPool, DebugLineStrPool);
805 Asm->OutStreamer->emitLabel(PrologueEndSym);
806}
807
808void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
809 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
810 OffsetsStringPool &DebugLineStrPool) {
811 // include_directories (sequence of path names).
812 for (const DWARFFormValue &Include : P.IncludeDirectories)
813 emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
814 // The last entry is followed by a single null byte.
815 MS->emitInt8(0);
816 LineSectionSize += 1;
817
818 // file_names (sequence of file entries).
819 for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) {
820 // A null-terminated string containing the full or relative path name of a
821 // source file.
822 emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
823 // An unsigned LEB128 number representing the directory index of a directory
824 // in the include_directories section.
825 LineSectionSize += MS->emitULEB128IntValue(File.DirIdx);
826 // An unsigned LEB128 number representing the (implementation-defined) time
827 // of last modification for the file, or 0 if not available.
828 LineSectionSize += MS->emitULEB128IntValue(File.ModTime);
829 // An unsigned LEB128 number representing the length in bytes of the file,
830 // or 0 if not available.
831 LineSectionSize += MS->emitULEB128IntValue(File.Length);
832 }
833 // The last entry is followed by a single null byte.
834 MS->emitInt8(0);
835 LineSectionSize += 1;
836}
837
838void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
839 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
840 OffsetsStringPool &DebugLineStrPool) {
841 if (P.IncludeDirectories.empty()) {
842 // directory_entry_format_count(ubyte).
843 MS->emitInt8(0);
844 LineSectionSize += 1;
845 } else {
846 // directory_entry_format_count(ubyte).
847 MS->emitInt8(1);
848 LineSectionSize += 1;
849
850 // directory_entry_format (sequence of ULEB128 pairs).
851 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
852 LineSectionSize +=
853 MS->emitULEB128IntValue(P.IncludeDirectories[0].getForm());
854 }
855
856 // directories_count (ULEB128).
857 LineSectionSize += MS->emitULEB128IntValue(P.IncludeDirectories.size());
858 // directories (sequence of directory names).
859 for (auto Include : P.IncludeDirectories)
860 emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
861
862 if (P.FileNames.empty()) {
863 // file_name_entry_format_count (ubyte).
864 MS->emitInt8(0);
865 LineSectionSize += 1;
866 } else {
867 // file_name_entry_format_count (ubyte).
868 MS->emitInt8(2);
869 LineSectionSize += 1;
870
871 // file_name_entry_format (sequence of ULEB128 pairs).
872 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
873 LineSectionSize += MS->emitULEB128IntValue(P.FileNames[0].Name.getForm());
874
875 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
876 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1);
877 }
878
879 // file_names_count (ULEB128).
880 LineSectionSize += MS->emitULEB128IntValue(P.FileNames.size());
881
882 // file_names (sequence of file name entries).
883 for (auto File : P.FileNames) {
884 emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
885 MS->emitInt8(File.DirIdx);
886 LineSectionSize += 1;
887 }
888}
889
890void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P,
891 const DWARFFormValue &String,
892 OffsetsStringPool &DebugStrPool,
893 OffsetsStringPool &DebugLineStrPool) {
894 std::optional<const char *> StringVal = dwarf::toString(String);
895 if (!StringVal) {
896 warn("Cann't read string from line table.");
897 return;
898 }
899
900 switch (String.getForm()) {
901 case dwarf::DW_FORM_string: {
902 StringRef TranslatedString =
903 (Translator) ? Translator(*StringVal) : *StringVal;
904 Asm->OutStreamer->emitBytes(TranslatedString.data());
905 Asm->emitInt8(0);
906 LineSectionSize += TranslatedString.size() + 1;
907 } break;
908 case dwarf::DW_FORM_strp:
909 case dwarf::DW_FORM_line_strp: {
910 DwarfStringPoolEntryRef StringRef =
911 String.getForm() == dwarf::DW_FORM_strp
912 ? DebugStrPool.getEntry(*StringVal)
913 : DebugLineStrPool.getEntry(*StringVal);
914
915 emitIntOffset(StringRef.getOffset(), P.FormParams.Format, LineSectionSize);
916 } break;
917 default:
918 warn("Unsupported string form inside line table.");
919 break;
920 };
921}
922
923void DwarfStreamer::emitLineTableProloguePayload(
924 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
925 OffsetsStringPool &DebugLineStrPool) {
926 // minimum_instruction_length (ubyte).
927 MS->emitInt8(P.MinInstLength);
928 LineSectionSize += 1;
929 if (P.FormParams.Version >= 4) {
930 // maximum_operations_per_instruction (ubyte).
931 MS->emitInt8(P.MaxOpsPerInst);
932 LineSectionSize += 1;
933 }
934 // default_is_stmt (ubyte).
935 MS->emitInt8(P.DefaultIsStmt);
936 LineSectionSize += 1;
937 // line_base (sbyte).
938 MS->emitInt8(P.LineBase);
939 LineSectionSize += 1;
940 // line_range (ubyte).
941 MS->emitInt8(P.LineRange);
942 LineSectionSize += 1;
943 // opcode_base (ubyte).
944 MS->emitInt8(P.OpcodeBase);
945 LineSectionSize += 1;
946
947 // standard_opcode_lengths (array of ubyte).
948 for (auto Length : P.StandardOpcodeLengths) {
949 MS->emitInt8(Length);
950 LineSectionSize += 1;
951 }
952
953 if (P.FormParams.Version < 5)
954 emitLineTablePrologueV2IncludeAndFileTable(P, DebugStrPool,
955 DebugLineStrPool);
956 else
957 emitLineTablePrologueV5IncludeAndFileTable(P, DebugStrPool,
958 DebugLineStrPool);
959}
960
961void DwarfStreamer::emitLineTableRows(
962 const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym,
963 unsigned AddressByteSize) {
964
965 MCDwarfLineTableParams Params;
966 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
967 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
968 Params.DWARF2LineRange = LineTable.Prologue.LineRange;
969
970 SmallString<128> EncodingBuffer;
971
972 if (LineTable.Rows.empty()) {
973 // We only have the dummy entry, dsymutil emits an entry with a 0
974 // address in that case.
975 MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
976 EncodingBuffer);
977 MS->emitBytes(EncodingBuffer);
978 LineSectionSize += EncodingBuffer.size();
979 MS->emitLabel(LineEndSym);
980 return;
981 }
982
983 // Line table state machine fields
984 unsigned FileNum = 1;
985 unsigned LastLine = 1;
986 unsigned Column = 0;
987 unsigned IsStatement = 1;
988 unsigned Isa = 0;
989 uint64_t Address = -1ULL;
990
991 unsigned RowsSinceLastSequence = 0;
992
993 for (const DWARFDebugLine::Row &Row : LineTable.Rows) {
994 int64_t AddressDelta;
995 if (Address == -1ULL) {
996 MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
997 MS->emitULEB128IntValue(AddressByteSize + 1);
998 MS->emitIntValue(dwarf::DW_LNE_set_address, 1);
999 MS->emitIntValue(Row.Address.Address, AddressByteSize);
1000 LineSectionSize +=
1001 2 + AddressByteSize + getULEB128Size(AddressByteSize + 1);
1002 AddressDelta = 0;
1003 } else {
1004 AddressDelta =
1005 (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength;
1006 }
1007
1008 // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
1009 // We should find a way to share this code, but the current compatibility
1010 // requirement with classic dsymutil makes it hard. Revisit that once this
1011 // requirement is dropped.
1012
1013 if (FileNum != Row.File) {
1014 FileNum = Row.File;
1015 MS->emitIntValue(dwarf::DW_LNS_set_file, 1);
1016 MS->emitULEB128IntValue(FileNum);
1017 LineSectionSize += 1 + getULEB128Size(FileNum);
1018 }
1019 if (Column != Row.Column) {
1020 Column = Row.Column;
1021 MS->emitIntValue(dwarf::DW_LNS_set_column, 1);
1022 MS->emitULEB128IntValue(Column);
1023 LineSectionSize += 1 + getULEB128Size(Column);
1024 }
1025
1026 // FIXME: We should handle the discriminator here, but dsymutil doesn't
1027 // consider it, thus ignore it for now.
1028
1029 if (Isa != Row.Isa) {
1030 Isa = Row.Isa;
1031 MS->emitIntValue(dwarf::DW_LNS_set_isa, 1);
1032 MS->emitULEB128IntValue(Isa);
1033 LineSectionSize += 1 + getULEB128Size(Isa);
1034 }
1035 if (IsStatement != Row.IsStmt) {
1036 IsStatement = Row.IsStmt;
1037 MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1);
1038 LineSectionSize += 1;
1039 }
1040 if (Row.BasicBlock) {
1041 MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1);
1042 LineSectionSize += 1;
1043 }
1044
1045 if (Row.PrologueEnd) {
1046 MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
1047 LineSectionSize += 1;
1048 }
1049
1050 if (Row.EpilogueBegin) {
1051 MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
1052 LineSectionSize += 1;
1053 }
1054
1055 int64_t LineDelta = int64_t(Row.Line) - LastLine;
1056 if (!Row.EndSequence) {
1057 MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta,
1058 EncodingBuffer);
1059 MS->emitBytes(EncodingBuffer);
1060 LineSectionSize += EncodingBuffer.size();
1061 EncodingBuffer.resize(0);
1062 Address = Row.Address.Address;
1063 LastLine = Row.Line;
1064 RowsSinceLastSequence++;
1065 } else {
1066 if (LineDelta) {
1067 MS->emitIntValue(dwarf::DW_LNS_advance_line, 1);
1068 MS->emitSLEB128IntValue(LineDelta);
1069 LineSectionSize += 1 + getSLEB128Size(LineDelta);
1070 }
1071 if (AddressDelta) {
1072 MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1);
1073 MS->emitULEB128IntValue(AddressDelta);
1074 LineSectionSize += 1 + getULEB128Size(AddressDelta);
1075 }
1076 MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(),
1077 0, EncodingBuffer);
1078 MS->emitBytes(EncodingBuffer);
1079 LineSectionSize += EncodingBuffer.size();
1080 EncodingBuffer.resize(0);
1081 Address = -1ULL;
1082 LastLine = FileNum = IsStatement = 1;
1083 RowsSinceLastSequence = Column = Isa = 0;
1084 }
1085 }
1086
1087 if (RowsSinceLastSequence) {
1088 MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
1089 EncodingBuffer);
1090 MS->emitBytes(EncodingBuffer);
1091 LineSectionSize += EncodingBuffer.size();
1092 EncodingBuffer.resize(0);
1093 }
1094
1095 MS->emitLabel(LineEndSym);
1096}
1097
1098void DwarfStreamer::emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
1099 uint64_t &SectionSize) {
1100 uint8_t Size = dwarf::getDwarfOffsetByteSize(Format);
1101 MS->emitIntValue(Offset, Size);
1102 SectionSize += Size;
1103}
1104
1105void DwarfStreamer::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
1106 dwarf::DwarfFormat Format,
1107 uint64_t &SectionSize) {
1108 uint8_t Size = dwarf::getDwarfOffsetByteSize(Format);
1109 Asm->emitLabelDifference(Hi, Lo, Size);
1110 SectionSize += Size;
1111}
1112
1113/// Emit the pubnames or pubtypes section contribution for \p
1114/// Unit into \p Sec. The data is provided in \p Names.
1115void DwarfStreamer::emitPubSectionForUnit(
1116 MCSection *Sec, StringRef SecName, const CompileUnit &Unit,
1117 const std::vector<CompileUnit::AccelInfo> &Names) {
1118 if (Names.empty())
1119 return;
1120
1121 // Start the dwarf pubnames section.
1122 Asm->OutStreamer->switchSection(Sec);
1123 MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin");
1124 MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end");
1125
1126 bool HeaderEmitted = false;
1127 // Emit the pubnames for this compilation unit.
1128 for (const auto &Name : Names) {
1129 if (Name.SkipPubSection)
1130 continue;
1131
1132 if (!HeaderEmitted) {
1133 // Emit the header.
1134 Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Length
1135 Asm->OutStreamer->emitLabel(BeginLabel);
1136 Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); // Version
1137 Asm->emitInt32(Unit.getStartOffset()); // Unit offset
1138 Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size
1139 HeaderEmitted = true;
1140 }
1141 Asm->emitInt32(Name.Die->getOffset());
1142
1143 // Emit the string itself.
1144 Asm->OutStreamer->emitBytes(Name.Name.getString());
1145 // Emit a null terminator.
1146 Asm->emitInt8(0);
1147 }
1148
1149 if (!HeaderEmitted)
1150 return;
1151 Asm->emitInt32(0); // End marker.
1152 Asm->OutStreamer->emitLabel(EndLabel);
1153}
1154
1155/// Emit .debug_pubnames for \p Unit.
1156void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
1157 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
1158 "names", Unit, Unit.getPubnames());
1159}
1160
1161/// Emit .debug_pubtypes for \p Unit.
1162void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
1163 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
1164 "types", Unit, Unit.getPubtypes());
1165}
1166
1167/// Emit a CIE into the debug_frame section.
1168void DwarfStreamer::emitCIE(StringRef CIEBytes) {
1169 MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1170
1171 MS->emitBytes(CIEBytes);
1172 FrameSectionSize += CIEBytes.size();
1173}
1174
1175/// Emit a FDE into the debug_frame section. \p FDEBytes
1176/// contains the FDE data without the length, CIE offset and address
1177/// which will be replaced with the parameter values.
1178void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
1179 uint64_t Address, StringRef FDEBytes) {
1180 MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1181
1182 MS->emitIntValue(FDEBytes.size() + 4 + AddrSize, 4);
1183 MS->emitIntValue(CIEOffset, 4);
1184 MS->emitIntValue(Address, AddrSize);
1185 MS->emitBytes(FDEBytes);
1186 FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
1187}
1188
1189void DwarfStreamer::emitMacroTables(DWARFContext *Context,
1190 const Offset2UnitMap &UnitMacroMap,
1191 OffsetsStringPool &StringPool) {
1192 assert(Context != nullptr && "Empty DWARF context");
1193
1194 // Check for .debug_macinfo table.
1195 if (const DWARFDebugMacro *Table = Context->getDebugMacinfo()) {
1196 MS->switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection());
1197 emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacInfoSectionSize);
1198 }
1199
1200 // Check for .debug_macro table.
1201 if (const DWARFDebugMacro *Table = Context->getDebugMacro()) {
1202 MS->switchSection(MC->getObjectFileInfo()->getDwarfMacroSection());
1203 emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacroSectionSize);
1204 }
1205}
1206
1207void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
1208 const Offset2UnitMap &UnitMacroMap,
1209 OffsetsStringPool &StringPool,
1210 uint64_t &OutOffset) {
1211 bool DefAttributeIsReported = false;
1212 bool UndefAttributeIsReported = false;
1213 bool ImportAttributeIsReported = false;
1214 for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
1215 Offset2UnitMap::const_iterator UnitIt = UnitMacroMap.find(List.Offset);
1216 if (UnitIt == UnitMacroMap.end()) {
1217 warn(formatv(
1218 "couldn`t find compile unit for the macro table with offset = {0:x}",
1219 List.Offset));
1220 continue;
1221 }
1222
1223 // Skip macro table if the unit was not cloned.
1224 DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE();
1225 if (OutputUnitDIE == nullptr)
1226 continue;
1227
1228 // Update macro attribute of cloned compile unit with the proper offset to
1229 // the macro table.
1230 bool hasDWARFv5Header = false;
1231 for (auto &V : OutputUnitDIE->values()) {
1232 if (V.getAttribute() == dwarf::DW_AT_macro_info) {
1233 V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
1234 break;
1235 } else if (V.getAttribute() == dwarf::DW_AT_macros) {
1236 hasDWARFv5Header = true;
1237 V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
1238 break;
1239 }
1240 }
1241
1242 // Write DWARFv5 header.
1243 if (hasDWARFv5Header) {
1244 // Write header version.
1245 MS->emitIntValue(List.Header.Version, sizeof(List.Header.Version));
1246 OutOffset += sizeof(List.Header.Version);
1247
1248 uint8_t Flags = List.Header.Flags;
1249
1250 // Check for OPCODE_OPERANDS_TABLE.
1251 if (Flags &
1252 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
1253 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
1254 warn("opcode_operands_table is not supported yet.");
1255 }
1256
1257 // Check for DEBUG_LINE_OFFSET.
1258 std::optional<uint64_t> StmtListOffset;
1259 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
1260 // Get offset to the line table from the cloned compile unit.
1261 for (auto &V : OutputUnitDIE->values()) {
1262 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
1263 StmtListOffset = V.getDIEInteger().getValue();
1264 break;
1265 }
1266 }
1267
1268 if (!StmtListOffset) {
1269 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
1270 warn("couldn`t find line table for macro table.");
1271 }
1272 }
1273
1274 // Write flags.
1275 MS->emitIntValue(Flags, sizeof(Flags));
1276 OutOffset += sizeof(Flags);
1277
1278 // Write offset to line table.
1279 if (StmtListOffset) {
1280 MS->emitIntValue(*StmtListOffset, List.Header.getOffsetByteSize());
1281 OutOffset += List.Header.getOffsetByteSize();
1282 }
1283 }
1284
1285 // Write macro entries.
1286 for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
1287 if (MacroEntry.Type == 0) {
1288 OutOffset += MS->emitULEB128IntValue(MacroEntry.Type);
1289 continue;
1290 }
1291
1292 uint8_t MacroType = MacroEntry.Type;
1293 switch (MacroType) {
1294 default: {
1295 bool HasVendorSpecificExtension =
1296 (!hasDWARFv5Header && MacroType == dwarf::DW_MACINFO_vendor_ext) ||
1297 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
1298 MacroType <= dwarf::DW_MACRO_hi_user));
1299
1300 if (HasVendorSpecificExtension) {
1301 // Write macinfo type.
1302 MS->emitIntValue(MacroType, 1);
1303 OutOffset++;
1304
1305 // Write vendor extension constant.
1306 OutOffset += MS->emitULEB128IntValue(MacroEntry.ExtConstant);
1307
1308 // Write vendor extension string.
1309 StringRef String = MacroEntry.ExtStr;
1310 MS->emitBytes(String);
1311 MS->emitIntValue(0, 1);
1312 OutOffset += String.size() + 1;
1313 } else
1314 warn("unknown macro type. skip.");
1315 } break;
1316 // debug_macro and debug_macinfo share some common encodings.
1317 // DW_MACRO_define == DW_MACINFO_define
1318 // DW_MACRO_undef == DW_MACINFO_undef
1319 // DW_MACRO_start_file == DW_MACINFO_start_file
1320 // DW_MACRO_end_file == DW_MACINFO_end_file
1321 // For readibility/uniformity we are using DW_MACRO_*.
1322 case dwarf::DW_MACRO_define:
1323 case dwarf::DW_MACRO_undef: {
1324 // Write macinfo type.
1325 MS->emitIntValue(MacroType, 1);
1326 OutOffset++;
1327
1328 // Write source line.
1329 OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
1330
1331 // Write macro string.
1332 StringRef String = MacroEntry.MacroStr;
1333 MS->emitBytes(String);
1334 MS->emitIntValue(0, 1);
1335 OutOffset += String.size() + 1;
1336 } break;
1337 case dwarf::DW_MACRO_define_strp:
1338 case dwarf::DW_MACRO_undef_strp:
1339 case dwarf::DW_MACRO_define_strx:
1340 case dwarf::DW_MACRO_undef_strx: {
1341 assert(UnitIt->second->getOrigUnit().getVersion() >= 5);
1342
1343 // DW_MACRO_*_strx forms are not supported currently.
1344 // Convert to *_strp.
1345 switch (MacroType) {
1346 case dwarf::DW_MACRO_define_strx: {
1347 MacroType = dwarf::DW_MACRO_define_strp;
1348 if (!DefAttributeIsReported) {
1349 warn("DW_MACRO_define_strx unsupported yet. Convert to "
1350 "DW_MACRO_define_strp.");
1351 DefAttributeIsReported = true;
1352 }
1353 } break;
1354 case dwarf::DW_MACRO_undef_strx: {
1355 MacroType = dwarf::DW_MACRO_undef_strp;
1356 if (!UndefAttributeIsReported) {
1357 warn("DW_MACRO_undef_strx unsupported yet. Convert to "
1358 "DW_MACRO_undef_strp.");
1359 UndefAttributeIsReported = true;
1360 }
1361 } break;
1362 default:
1363 // Nothing to do.
1364 break;
1365 }
1366
1367 // Write macinfo type.
1368 MS->emitIntValue(MacroType, 1);
1369 OutOffset++;
1370
1371 // Write source line.
1372 OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
1373
1374 // Write macro string.
1375 DwarfStringPoolEntryRef EntryRef =
1376 StringPool.getEntry(MacroEntry.MacroStr);
1377 MS->emitIntValue(EntryRef.getOffset(), List.Header.getOffsetByteSize());
1378 OutOffset += List.Header.getOffsetByteSize();
1379 break;
1380 }
1381 case dwarf::DW_MACRO_start_file: {
1382 // Write macinfo type.
1383 MS->emitIntValue(MacroType, 1);
1384 OutOffset++;
1385 // Write source line.
1386 OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
1387 // Write source file id.
1388 OutOffset += MS->emitULEB128IntValue(MacroEntry.File);
1389 } break;
1390 case dwarf::DW_MACRO_end_file: {
1391 // Write macinfo type.
1392 MS->emitIntValue(MacroType, 1);
1393 OutOffset++;
1394 } break;
1395 case dwarf::DW_MACRO_import:
1396 case dwarf::DW_MACRO_import_sup: {
1397 if (!ImportAttributeIsReported) {
1398 warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
1399 "remove.");
1400 ImportAttributeIsReported = true;
1401 }
1402 } break;
1403 }
1404 }
1405 }
1406}
1407
1408} // namespace llvm
uint64_t Align
uint64_t Addr
std::string Name
uint64_t Size
uint64_t Offset
Definition: ELF_riscv.cpp:476
LLVMContext & Context
#define P(N)
const NodeList & List
Definition: RDFGraph.cpp:201
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
support::ulittle16_t & Lo
Definition: aarch32.cpp:205
support::ulittle16_t & Hi
Definition: aarch32.cpp:204
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:194
A class that represents an address range.
Definition: AddressRanges.h:22
The AddressRanges class helps normalize address range collections.
Stores all information relating to a compile unit, be it in its original instance in the object file ...
static dwarf::Form BestForm(bool IsSigned, uint64_t Int)
Choose the best form for integer.
Definition: DIE.h:175
A structured debug information entry.
Definition: DIE.h:819
unsigned getSize() const
Definition: DIE.h:862
The Data class implementation for DWARF v5 accelerator table.
Definition: AccelTable.h:254
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:48
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
unsigned size() const
Definition: DenseMap.h:99
iterator end()
Definition: DenseMap.h:84
void emitDebugNames(DWARF5AccelTable &Table) override
Emit DWARF debug names.
void emitStrings(const NonRelocatableStringpool &Pool) override
Emit the string table described by Pool into .debug_str table.
void finish() override
Dump the file to the disk.
void emitStringOffsets(const SmallVector< uint64_t > &StringOffset, uint16_t TargetDWARFVersion) override
Emit the debug string offset table described by StringOffsets into the .debug_str_offsets table.
void emitSectionContents(StringRef SecData, StringRef SecName) override
Emit contents of section SecName From Obj.
void emitDIE(DIE &Die) override
Recursively emit the DIE tree rooted at Die.
void emitLineStrings(const NonRelocatableStringpool &Pool) override
Emit the string table described by Pool into .debug_line_str table.
void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override
Emit the compilation unit header for Unit in the debug_info section.
void emitAbbrevs(const std::vector< std::unique_ptr< DIEAbbrev > > &Abbrevs, unsigned DwarfVersion) override
Emit the abbreviation table Abbrevs to the debug_abbrev section.
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName)
void switchToDebugInfoSection(unsigned DwarfVersion)
Set the current output section to debug_info and change the MC Dwarf version to DwarfVersion.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
std::unique_ptr< MCObjectWriter > createObjectWriter(raw_pwrite_stream &OS) const
Create a new MCObjectWriter instance for use by the assembler backend to emit the final object file.
Context object for machine code objects.
Definition: MCContext.h:76
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
void setAlignment(Align Value)
Definition: MCSection.h:141
void emitInt16(uint64_t Value)
Definition: MCStreamer.h:753
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
A string table that doesn't need relocations.
std::vector< DwarfStringPoolEntryRef > getEntriesForEmission() const
Return the list of strings to be emitted.
bool empty() const
Definition: SmallVector.h:94
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
Helper for making strong types.
Target - Wrapper for Target specific information.
MCCodeEmitter * createMCCodeEmitter(const MCInstrInfo &II, MCContext &Ctx) const
createMCCodeEmitter - Create a target specific code emitter.
MCObjectFileInfo * createMCObjectFileInfo(MCContext &Ctx, bool PIC, bool LargeCodeModel=false) const
Create a MCObjectFileInfo implementation for the specified target triple.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, bool IsVerboseAsm, bool UseDwarfDirectory, MCInstPrinter *InstPrint, std::unique_ptr< MCCodeEmitter > &&CE, std::unique_ptr< MCAsmBackend > &&TAB, bool ShowInst) const
MCAsmBackend * createMCAsmBackend(const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) const
createMCAsmBackend - Create a target specific assembly parser.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, const MCTargetOptions &Options) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
MCInstPrinter * createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) const
MCStreamer * createMCObjectStreamer(const Triple &T, MCContext &Ctx, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter, const MCSubtargetInfo &STI, bool RelaxAll, bool IncrementalLinkerCompatible, bool DWARFMustBeAtTheEnd) const
Create a target specific MCStreamer.
AsmPrinter * createAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > &&Streamer) const
createAsmPrinter - Create a target specific assembly printer pass.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
const std::string & getTriple() const
Definition: Triple.h:418
@ SectionSize
Definition: COFF.h:60
Swift5ReflectionSectionKind
Definition: Swift.h:14
MCTargetOptions InitMCTargetOptionsFromFlags()
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1244
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: Alignment.h:197
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
Definition: AccelTable.h:353
void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
Definition: AccelTable.cpp:584
unsigned getSLEB128Size(int64_t Value)
Utility function to get the size of the SLEB128-encoded value.
Definition: LEB128.cpp:29
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Represents a single DWARF expression, whose value is location-dependent.
uint64_t getValueIndex(uint64_t Value)
Definition: DWARFLinker.h:102
void set(uint64_t New) const
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
DwarfFormat Format
Definition: Dwarf.h:746