1 //===- DwarfStreamer.cpp --------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DWARFLinker/DWARFStreamer.h"
10 #include "llvm/CodeGen/NonRelocatableStringpool.h"
11 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
12 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
13 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
14 #include "llvm/MC/MCAsmBackend.h"
15 #include "llvm/MC/MCCodeEmitter.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCObjectWriter.h"
18 #include "llvm/MC/MCSection.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCTargetOptions.h"
22 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
23 #include "llvm/MC/TargetRegistry.h"
24 #include "llvm/Support/FormatVariadic.h"
25 #include "llvm/Support/LEB128.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/TargetParser/Triple.h"
31 Error
DwarfStreamer::init(Triple TheTriple
,
32 StringRef Swift5ReflectionSegmentName
) {
34 std::string TripleName
;
37 const Target
*TheTarget
=
38 TargetRegistry::lookupTarget(TripleName
, TheTriple
, ErrorStr
);
40 return createStringError(std::errc::invalid_argument
, ErrorStr
.c_str());
42 TripleName
= TheTriple
.getTriple();
44 // Create all the MC Objects.
45 MRI
.reset(TheTarget
->createMCRegInfo(TripleName
));
47 return createStringError(std::errc::invalid_argument
,
48 "no register info for target %s",
51 MCTargetOptions MCOptions
= mc::InitMCTargetOptionsFromFlags();
52 MAI
.reset(TheTarget
->createMCAsmInfo(*MRI
, TripleName
, MCOptions
));
54 return createStringError(std::errc::invalid_argument
,
55 "no asm info for target %s", TripleName
.c_str());
57 MSTI
.reset(TheTarget
->createMCSubtargetInfo(TripleName
, "", ""));
59 return createStringError(std::errc::invalid_argument
,
60 "no subtarget info for target %s",
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());
68 MAB
= TheTarget
->createMCAsmBackend(*MSTI
, *MRI
, MCOptions
);
70 return createStringError(std::errc::invalid_argument
,
71 "no asm backend for target %s",
74 MII
.reset(TheTarget
->createMCInstrInfo());
76 return createStringError(std::errc::invalid_argument
,
77 "no instr info info for target %s",
80 MCE
= TheTarget
->createMCCodeEmitter(*MII
, *MC
);
82 return createStringError(std::errc::invalid_argument
,
83 "no code emitter for target %s",
86 switch (OutFileType
) {
87 case DWARFLinker::OutputFileType::Assembly
: {
88 MIP
= TheTarget
->createMCInstPrinter(TheTriple
, MAI
->getAssemblerDialect(),
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
),
96 case DWARFLinker::OutputFileType::Object
: {
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);
107 return createStringError(std::errc::invalid_argument
,
108 "no object streamer for target %s",
111 // Finally create the AsmPrinter we'll use to emit the DIEs.
112 TM
.reset(TheTarget
->createTargetMachine(TripleName
, "", "", TargetOptions(),
115 return createStringError(std::errc::invalid_argument
,
116 "no target machine for target %s",
119 Asm
.reset(TheTarget
->createAsmPrinter(*TM
, std::unique_ptr
<MCStreamer
>(MS
)));
121 return createStringError(std::errc::invalid_argument
,
122 "no asm printer for target %s",
124 Asm
->setDwarfUsesRelocationsAcrossSections(false);
126 RangesSectionSize
= 0;
127 RngListsSectionSize
= 0;
129 LocListsSectionSize
= 0;
131 FrameSectionSize
= 0;
132 DebugInfoSectionSize
= 0;
133 MacInfoSectionSize
= 0;
134 MacroSectionSize
= 0;
136 return Error::success();
139 void DwarfStreamer::finish() { MS
->finish(); }
141 void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion
) {
142 MS
->switchSection(MOFI
->getDwarfInfoSection());
143 MC
->setDwarfVersion(DwarfVersion
);
146 /// Emit the compilation unit header for \p Unit in the debug_info section.
148 /// A Dwarf 4 section header is encoded as:
149 /// uint32_t Unit length (omitting this field)
151 /// uint32_t Abbreviation table offset
152 /// uint8_t Address size
153 /// Leading to a total of 11 bytes.
155 /// A Dwarf 5 section header is encoded as:
156 /// uint32_t Unit length (omitting this field)
158 /// uint8_t Unit type
159 /// uint8_t Address size
160 /// uint32_t Abbreviation table offset
161 /// Leading to a total of 12 bytes.
162 void DwarfStreamer::emitCompileUnitHeader(CompileUnit
&Unit
,
163 unsigned DwarfVersion
) {
164 switchToDebugInfoSection(DwarfVersion
);
166 /// The start of the unit within its section.
167 Unit
.setLabelBegin(Asm
->createTempSymbol("cu_begin"));
168 Asm
->OutStreamer
->emitLabel(Unit
.getLabelBegin());
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
);
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.
182 DebugInfoSectionSize
+= 12;
184 // We share one abbreviations table across all units so it's always at the
185 // start of the section.
187 Asm
->emitInt8(Unit
.getOrigUnit().getAddressByteSize());
188 DebugInfoSectionSize
+= 11;
192 EmittedUnits
.push_back({Unit
.getUniqueID(), Unit
.getLabelBegin()});
195 /// Emit the \p Abbrevs array as the shared abbreviation table
196 /// for the linked Dwarf file.
197 void DwarfStreamer::emitAbbrevs(
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
);
205 /// Recursively emit the DIE tree rooted at \p Die.
206 void DwarfStreamer::emitDIE(DIE
&Die
) {
207 MS
->switchSection(MOFI
->getDwarfInfoSection());
208 Asm
->emitDwarfDIE(Die
);
209 DebugInfoSectionSize
+= Die
.getSize();
212 /// Emit contents of section SecName From Obj.
213 void DwarfStreamer::emitSectionContents(StringRef SecData
, StringRef SecName
) {
215 StringSwitch
<MCSection
*>(SecName
)
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())
231 MS
->switchSection(Section
);
233 MS
->emitBytes(SecData
);
237 /// Emit the debug_str section stored in \p Pool.
238 void DwarfStreamer::emitStrings(const NonRelocatableStringpool
&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.
249 /// Emit the debug string offset table described by \p StringOffsets into the
250 /// .debug_str_offsets table.
251 void DwarfStreamer::emitStringOffsets(
252 const SmallVector
<uint64_t> &StringOffsets
, uint16_t TargetDWARFVersion
) {
254 if (TargetDWARFVersion
< 5 || StringOffsets
.empty())
257 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfStrOffSection());
259 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Bdebugstroff");
260 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Edebugstroff");
263 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
264 Asm
->OutStreamer
->emitLabel(BeginLabel
);
265 StrOffsetSectionSize
+= sizeof(uint32_t);
269 StrOffsetSectionSize
+= sizeof(uint16_t);
273 StrOffsetSectionSize
+= sizeof(uint16_t);
275 for (auto Off
: StringOffsets
) {
276 Asm
->OutStreamer
->emitInt32(Off
);
277 StrOffsetSectionSize
+= sizeof(uint32_t);
279 Asm
->OutStreamer
->emitLabel(EndLabel
);
282 /// Emit the debug_line_str section stored in \p Pool.
283 void DwarfStreamer::emitLineStrings(const NonRelocatableStringpool
&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.
294 void DwarfStreamer::emitDebugNames(DWARF5AccelTable
&Table
) {
295 if (EmittedUnits
.empty())
298 // Build up data structures needed to emit this section.
299 std::vector
<std::variant
<MCSymbol
*, uint64_t>> CompUnits
;
300 DenseMap
<unsigned, size_t> UniqueIdToCuMap
;
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
++;
308 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfDebugNamesSection());
309 emitDWARF5AccelTable(Asm
.get(), Table
, CompUnits
,
310 [&UniqueIdToCuMap
](const DWARF5AccelTableData
&Entry
) {
311 return UniqueIdToCuMap
[Entry
.getUnitID()];
315 void DwarfStreamer::emitAppleNamespaces(
316 AccelTable
<AppleAccelTableStaticOffsetData
> &Table
) {
317 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelNamespaceSection());
318 auto *SectionBegin
= Asm
->createTempSymbol("namespac_begin");
319 Asm
->OutStreamer
->emitLabel(SectionBegin
);
320 emitAppleAccelTable(Asm
.get(), Table
, "namespac", SectionBegin
);
323 void DwarfStreamer::emitAppleNames(
324 AccelTable
<AppleAccelTableStaticOffsetData
> &Table
) {
325 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelNamesSection());
326 auto *SectionBegin
= Asm
->createTempSymbol("names_begin");
327 Asm
->OutStreamer
->emitLabel(SectionBegin
);
328 emitAppleAccelTable(Asm
.get(), Table
, "names", SectionBegin
);
331 void DwarfStreamer::emitAppleObjc(
332 AccelTable
<AppleAccelTableStaticOffsetData
> &Table
) {
333 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelObjCSection());
334 auto *SectionBegin
= Asm
->createTempSymbol("objc_begin");
335 Asm
->OutStreamer
->emitLabel(SectionBegin
);
336 emitAppleAccelTable(Asm
.get(), Table
, "objc", SectionBegin
);
339 void DwarfStreamer::emitAppleTypes(
340 AccelTable
<AppleAccelTableStaticTypeData
> &Table
) {
341 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelTypesSection());
342 auto *SectionBegin
= Asm
->createTempSymbol("types_begin");
343 Asm
->OutStreamer
->emitLabel(SectionBegin
);
344 emitAppleAccelTable(Asm
.get(), Table
, "types", SectionBegin
);
347 /// Emit the swift_ast section stored in \p Buffers.
348 void DwarfStreamer::emitSwiftAST(StringRef Buffer
) {
349 MCSection
*SwiftASTSection
= MOFI
->getDwarfSwiftASTSection();
350 SwiftASTSection
->setAlignment(Align(32));
351 MS
->switchSection(SwiftASTSection
);
352 MS
->emitBytes(Buffer
);
355 void DwarfStreamer::emitSwiftReflectionSection(
356 llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind
,
357 StringRef Buffer
, uint32_t Alignment
, uint32_t Size
) {
358 MCSection
*ReflectionSection
=
359 MOFI
->getSwift5ReflectionSection(ReflSectionKind
);
360 if (ReflectionSection
== nullptr)
362 ReflectionSection
->setAlignment(Align(Alignment
));
363 MS
->switchSection(ReflectionSection
);
364 MS
->emitBytes(Buffer
);
367 void DwarfStreamer::emitDwarfDebugArangesTable(
368 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
) {
369 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
371 // Make .debug_aranges to be current section.
372 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfARangesSection());
375 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Barange");
376 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Earange");
378 unsigned HeaderSize
=
379 sizeof(int32_t) + // Size of contents (w/o this field
380 sizeof(int16_t) + // DWARF ARange version number
381 sizeof(int32_t) + // Offset of CU in the .debug_info section
382 sizeof(int8_t) + // Pointer Size (in bytes)
383 sizeof(int8_t); // Segment Size (in bytes)
385 unsigned TupleSize
= AddressSize
* 2;
386 unsigned Padding
= offsetToAlignment(HeaderSize
, Align(TupleSize
));
388 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, 4); // Arange length
389 Asm
->OutStreamer
->emitLabel(BeginLabel
);
390 Asm
->emitInt16(dwarf::DW_ARANGES_VERSION
); // Version number
391 Asm
->emitInt32(Unit
.getStartOffset()); // Corresponding unit's offset
392 Asm
->emitInt8(AddressSize
); // Address size
393 Asm
->emitInt8(0); // Segment size
395 Asm
->OutStreamer
->emitFill(Padding
, 0x0);
397 // Emit linked ranges.
398 for (const AddressRange
&Range
: LinkedRanges
) {
399 MS
->emitIntValue(Range
.start(), AddressSize
);
400 MS
->emitIntValue(Range
.end() - Range
.start(), AddressSize
);
404 Asm
->OutStreamer
->emitIntValue(0, AddressSize
);
405 Asm
->OutStreamer
->emitIntValue(0, AddressSize
);
406 Asm
->OutStreamer
->emitLabel(EndLabel
);
409 void DwarfStreamer::emitDwarfDebugRangesTableFragment(
410 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
,
411 PatchLocation Patch
) {
412 Patch
.set(RangesSectionSize
);
414 // Make .debug_ranges to be current section.
415 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRangesSection());
416 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
419 uint64_t BaseAddress
= 0;
420 if (std::optional
<uint64_t> LowPC
= Unit
.getLowPc())
421 BaseAddress
= *LowPC
;
423 for (const AddressRange
&Range
: LinkedRanges
) {
424 MS
->emitIntValue(Range
.start() - BaseAddress
, AddressSize
);
425 MS
->emitIntValue(Range
.end() - BaseAddress
, AddressSize
);
427 RangesSectionSize
+= AddressSize
;
428 RangesSectionSize
+= AddressSize
;
431 // Add the terminator entry.
432 MS
->emitIntValue(0, AddressSize
);
433 MS
->emitIntValue(0, AddressSize
);
435 RangesSectionSize
+= AddressSize
;
436 RangesSectionSize
+= AddressSize
;
440 DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit
&Unit
) {
441 if (Unit
.getOrigUnit().getVersion() < 5)
444 // Make .debug_rnglists to be current section.
445 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRnglistsSection());
447 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Brnglists");
448 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Ernglists");
449 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
452 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
453 Asm
->OutStreamer
->emitLabel(BeginLabel
);
454 RngListsSectionSize
+= sizeof(uint32_t);
458 RngListsSectionSize
+= sizeof(uint16_t);
461 MS
->emitInt8(AddressSize
);
462 RngListsSectionSize
++;
466 RngListsSectionSize
++;
468 // Offset entry count
470 RngListsSectionSize
+= sizeof(uint32_t);
475 void DwarfStreamer::emitDwarfDebugRangeListFragment(
476 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
,
477 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
478 if (Unit
.getOrigUnit().getVersion() < 5) {
479 emitDwarfDebugRangesTableFragment(Unit
, LinkedRanges
, Patch
);
483 emitDwarfDebugRngListsTableFragment(Unit
, LinkedRanges
, Patch
, AddrPool
);
486 void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit
&Unit
,
487 MCSymbol
*EndLabel
) {
488 if (Unit
.getOrigUnit().getVersion() < 5)
491 // Make .debug_rnglists to be current section.
492 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRnglistsSection());
494 if (EndLabel
!= nullptr)
495 Asm
->OutStreamer
->emitLabel(EndLabel
);
498 void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
499 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
,
500 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
501 Patch
.set(RngListsSectionSize
);
503 // Make .debug_rnglists to be current section.
504 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRnglistsSection());
505 std::optional
<uint64_t> BaseAddress
;
507 for (const AddressRange
&Range
: LinkedRanges
) {
510 BaseAddress
= Range
.start();
512 // Emit base address.
513 MS
->emitInt8(dwarf::DW_RLE_base_addressx
);
514 RngListsSectionSize
+= 1;
515 RngListsSectionSize
+=
516 MS
->emitULEB128IntValue(AddrPool
.getValueIndex(*BaseAddress
));
519 // Emit type of entry.
520 MS
->emitInt8(dwarf::DW_RLE_offset_pair
);
521 RngListsSectionSize
+= 1;
523 // Emit start offset relative to base address.
524 RngListsSectionSize
+=
525 MS
->emitULEB128IntValue(Range
.start() - *BaseAddress
);
527 // Emit end offset relative to base address.
528 RngListsSectionSize
+= MS
->emitULEB128IntValue(Range
.end() - *BaseAddress
);
531 // Emit the terminator entry.
532 MS
->emitInt8(dwarf::DW_RLE_end_of_list
);
533 RngListsSectionSize
+= 1;
536 /// Emit debug locations(.debug_loc, .debug_loclists) header.
537 MCSymbol
*DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit
&Unit
) {
538 if (Unit
.getOrigUnit().getVersion() < 5)
541 // Make .debug_loclists the current section.
542 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLoclistsSection());
544 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Bloclists");
545 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Eloclists");
546 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
549 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
550 Asm
->OutStreamer
->emitLabel(BeginLabel
);
551 LocListsSectionSize
+= sizeof(uint32_t);
555 LocListsSectionSize
+= sizeof(uint16_t);
558 MS
->emitInt8(AddressSize
);
559 LocListsSectionSize
++;
563 LocListsSectionSize
++;
565 // Offset entry count
567 LocListsSectionSize
+= sizeof(uint32_t);
572 /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
573 void DwarfStreamer::emitDwarfDebugLocListFragment(
574 const CompileUnit
&Unit
,
575 const DWARFLocationExpressionsVector
&LinkedLocationExpression
,
576 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
577 if (Unit
.getOrigUnit().getVersion() < 5) {
578 emitDwarfDebugLocTableFragment(Unit
, LinkedLocationExpression
, Patch
);
582 emitDwarfDebugLocListsTableFragment(Unit
, LinkedLocationExpression
, Patch
,
586 /// Emit debug locations(.debug_loc, .debug_loclists) footer.
587 void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit
&Unit
,
588 MCSymbol
*EndLabel
) {
589 if (Unit
.getOrigUnit().getVersion() < 5)
592 // Make .debug_loclists the current section.
593 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLoclistsSection());
595 if (EndLabel
!= nullptr)
596 Asm
->OutStreamer
->emitLabel(EndLabel
);
599 /// Emit piece of .debug_loc for \p LinkedLocationExpression.
600 void DwarfStreamer::emitDwarfDebugLocTableFragment(
601 const CompileUnit
&Unit
,
602 const DWARFLocationExpressionsVector
&LinkedLocationExpression
,
603 PatchLocation Patch
) {
604 Patch
.set(LocSectionSize
);
606 // Make .debug_loc to be current section.
607 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLocSection());
608 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
611 uint64_t BaseAddress
= 0;
612 if (std::optional
<uint64_t> LowPC
= Unit
.getLowPc())
613 BaseAddress
= *LowPC
;
615 for (const DWARFLocationExpression
&LocExpression
:
616 LinkedLocationExpression
) {
617 if (LocExpression
.Range
) {
618 MS
->emitIntValue(LocExpression
.Range
->LowPC
- BaseAddress
, AddressSize
);
619 MS
->emitIntValue(LocExpression
.Range
->HighPC
- BaseAddress
, AddressSize
);
621 LocSectionSize
+= AddressSize
;
622 LocSectionSize
+= AddressSize
;
625 Asm
->OutStreamer
->emitIntValue(LocExpression
.Expr
.size(), 2);
626 Asm
->OutStreamer
->emitBytes(StringRef(
627 (const char *)LocExpression
.Expr
.data(), LocExpression
.Expr
.size()));
628 LocSectionSize
+= LocExpression
.Expr
.size() + 2;
631 // Add the terminator entry.
632 MS
->emitIntValue(0, AddressSize
);
633 MS
->emitIntValue(0, AddressSize
);
635 LocSectionSize
+= AddressSize
;
636 LocSectionSize
+= AddressSize
;
639 /// Emit .debug_addr header.
640 MCSymbol
*DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit
&Unit
) {
642 // Make .debug_addr the current section.
643 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfAddrSection());
645 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Bdebugaddr");
646 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Edebugaddr");
647 unsigned AddrSize
= Unit
.getOrigUnit().getAddressByteSize();
650 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
651 Asm
->OutStreamer
->emitLabel(BeginLabel
);
652 AddrSectionSize
+= sizeof(uint32_t);
656 AddrSectionSize
+= 2;
658 // Emit address size.
659 Asm
->emitInt8(AddrSize
);
660 AddrSectionSize
+= 1;
662 // Emit segment size.
664 AddrSectionSize
+= 1;
669 /// Emit the .debug_addr addresses stored in \p Addrs.
670 void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector
<uint64_t> &Addrs
,
672 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAddrSection());
673 for (auto Addr
: Addrs
) {
674 Asm
->OutStreamer
->emitIntValue(Addr
, AddrSize
);
675 AddrSectionSize
+= AddrSize
;
679 /// Emit .debug_addr footer.
680 void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit
&Unit
,
681 MCSymbol
*EndLabel
) {
683 // Make .debug_addr the current section.
684 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfAddrSection());
686 if (EndLabel
!= nullptr)
687 Asm
->OutStreamer
->emitLabel(EndLabel
);
690 /// Emit piece of .debug_loclists for \p LinkedLocationExpression.
691 void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
692 const CompileUnit
&Unit
,
693 const DWARFLocationExpressionsVector
&LinkedLocationExpression
,
694 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
695 Patch
.set(LocListsSectionSize
);
697 // Make .debug_loclists the current section.
698 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLoclistsSection());
699 std::optional
<uint64_t> BaseAddress
;
701 for (const DWARFLocationExpression
&LocExpression
:
702 LinkedLocationExpression
) {
703 if (LocExpression
.Range
) {
707 BaseAddress
= LocExpression
.Range
->LowPC
;
709 // Emit base address.
710 MS
->emitInt8(dwarf::DW_LLE_base_addressx
);
711 LocListsSectionSize
+= 1;
712 LocListsSectionSize
+=
713 MS
->emitULEB128IntValue(AddrPool
.getValueIndex(*BaseAddress
));
716 // Emit type of entry.
717 MS
->emitInt8(dwarf::DW_LLE_offset_pair
);
718 LocListsSectionSize
+= 1;
720 // Emit start offset relative to base address.
721 LocListsSectionSize
+=
722 MS
->emitULEB128IntValue(LocExpression
.Range
->LowPC
- *BaseAddress
);
724 // Emit end offset relative to base address.
725 LocListsSectionSize
+=
726 MS
->emitULEB128IntValue(LocExpression
.Range
->HighPC
- *BaseAddress
);
728 // Emit type of entry.
729 MS
->emitInt8(dwarf::DW_LLE_default_location
);
730 LocListsSectionSize
+= 1;
733 LocListsSectionSize
+= MS
->emitULEB128IntValue(LocExpression
.Expr
.size());
734 Asm
->OutStreamer
->emitBytes(StringRef(
735 (const char *)LocExpression
.Expr
.data(), LocExpression
.Expr
.size()));
736 LocListsSectionSize
+= LocExpression
.Expr
.size();
739 // Emit the terminator entry.
740 MS
->emitInt8(dwarf::DW_LLE_end_of_list
);
741 LocListsSectionSize
+= 1;
744 void DwarfStreamer::emitLineTableForUnit(
745 const DWARFDebugLine::LineTable
&LineTable
, const CompileUnit
&Unit
,
746 OffsetsStringPool
&DebugStrPool
, OffsetsStringPool
&DebugLineStrPool
) {
747 // Switch to the section where the table will be emitted into.
748 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLineSection());
750 MCSymbol
*LineStartSym
= MC
->createTempSymbol();
751 MCSymbol
*LineEndSym
= MC
->createTempSymbol();
754 if (LineTable
.Prologue
.FormParams
.Format
== dwarf::DwarfFormat::DWARF64
) {
755 MS
->emitInt32(dwarf::DW_LENGTH_DWARF64
);
756 LineSectionSize
+= 4;
758 emitLabelDifference(LineEndSym
, LineStartSym
,
759 LineTable
.Prologue
.FormParams
.Format
, LineSectionSize
);
760 Asm
->OutStreamer
->emitLabel(LineStartSym
);
763 emitLineTablePrologue(LineTable
.Prologue
, DebugStrPool
, DebugLineStrPool
);
766 emitLineTableRows(LineTable
, LineEndSym
,
767 Unit
.getOrigUnit().getAddressByteSize());
770 void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue
&P
,
771 OffsetsStringPool
&DebugStrPool
,
772 OffsetsStringPool
&DebugLineStrPool
) {
773 MCSymbol
*PrologueStartSym
= MC
->createTempSymbol();
774 MCSymbol
*PrologueEndSym
= MC
->createTempSymbol();
777 MS
->emitInt16(P
.getVersion());
778 LineSectionSize
+= 2;
779 if (P
.getVersion() == 5) {
780 // address_size (ubyte).
781 MS
->emitInt8(P
.getAddressSize());
782 LineSectionSize
+= 1;
784 // segment_selector_size (ubyte).
785 MS
->emitInt8(P
.SegSelectorSize
);
786 LineSectionSize
+= 1;
790 emitLabelDifference(PrologueEndSym
, PrologueStartSym
, P
.FormParams
.Format
,
793 Asm
->OutStreamer
->emitLabel(PrologueStartSym
);
794 emitLineTableProloguePayload(P
, DebugStrPool
, DebugLineStrPool
);
795 Asm
->OutStreamer
->emitLabel(PrologueEndSym
);
798 void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
799 const DWARFDebugLine::Prologue
&P
, OffsetsStringPool
&DebugStrPool
,
800 OffsetsStringPool
&DebugLineStrPool
) {
801 // include_directories (sequence of path names).
802 for (const DWARFFormValue
&Include
: P
.IncludeDirectories
)
803 emitLineTableString(P
, Include
, DebugStrPool
, DebugLineStrPool
);
804 // The last entry is followed by a single null byte.
806 LineSectionSize
+= 1;
808 // file_names (sequence of file entries).
809 for (const DWARFDebugLine::FileNameEntry
&File
: P
.FileNames
) {
810 // A null-terminated string containing the full or relative path name of a
812 emitLineTableString(P
, File
.Name
, DebugStrPool
, DebugLineStrPool
);
813 // An unsigned LEB128 number representing the directory index of a directory
814 // in the include_directories section.
815 LineSectionSize
+= MS
->emitULEB128IntValue(File
.DirIdx
);
816 // An unsigned LEB128 number representing the (implementation-defined) time
817 // of last modification for the file, or 0 if not available.
818 LineSectionSize
+= MS
->emitULEB128IntValue(File
.ModTime
);
819 // An unsigned LEB128 number representing the length in bytes of the file,
820 // or 0 if not available.
821 LineSectionSize
+= MS
->emitULEB128IntValue(File
.Length
);
823 // The last entry is followed by a single null byte.
825 LineSectionSize
+= 1;
828 void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
829 const DWARFDebugLine::Prologue
&P
, OffsetsStringPool
&DebugStrPool
,
830 OffsetsStringPool
&DebugLineStrPool
) {
831 if (P
.IncludeDirectories
.empty()) {
832 // directory_entry_format_count(ubyte).
834 LineSectionSize
+= 1;
836 // directory_entry_format_count(ubyte).
838 LineSectionSize
+= 1;
840 // directory_entry_format (sequence of ULEB128 pairs).
841 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_path
);
843 MS
->emitULEB128IntValue(P
.IncludeDirectories
[0].getForm());
846 // directories_count (ULEB128).
847 LineSectionSize
+= MS
->emitULEB128IntValue(P
.IncludeDirectories
.size());
848 // directories (sequence of directory names).
849 for (auto Include
: P
.IncludeDirectories
)
850 emitLineTableString(P
, Include
, DebugStrPool
, DebugLineStrPool
);
852 if (P
.FileNames
.empty()) {
853 // file_name_entry_format_count (ubyte).
855 LineSectionSize
+= 1;
857 // file_name_entry_format_count (ubyte).
859 LineSectionSize
+= 1;
861 // file_name_entry_format (sequence of ULEB128 pairs).
862 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_path
);
863 LineSectionSize
+= MS
->emitULEB128IntValue(P
.FileNames
[0].Name
.getForm());
865 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_directory_index
);
866 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_FORM_data1
);
869 // file_names_count (ULEB128).
870 LineSectionSize
+= MS
->emitULEB128IntValue(P
.FileNames
.size());
872 // file_names (sequence of file name entries).
873 for (auto File
: P
.FileNames
) {
874 emitLineTableString(P
, File
.Name
, DebugStrPool
, DebugLineStrPool
);
875 MS
->emitInt8(File
.DirIdx
);
876 LineSectionSize
+= 1;
880 void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue
&P
,
881 const DWARFFormValue
&String
,
882 OffsetsStringPool
&DebugStrPool
,
883 OffsetsStringPool
&DebugLineStrPool
) {
884 std::optional
<const char *> StringVal
= dwarf::toString(String
);
886 warn("Cann't read string from line table.");
890 switch (String
.getForm()) {
891 case dwarf::DW_FORM_string
: {
892 StringRef TranslatedString
=
893 (Translator
) ? Translator(*StringVal
) : *StringVal
;
894 Asm
->OutStreamer
->emitBytes(TranslatedString
.data());
896 LineSectionSize
+= TranslatedString
.size() + 1;
898 case dwarf::DW_FORM_strp
:
899 case dwarf::DW_FORM_line_strp
: {
900 DwarfStringPoolEntryRef StringRef
=
901 String
.getForm() == dwarf::DW_FORM_strp
902 ? DebugStrPool
.getEntry(*StringVal
)
903 : DebugLineStrPool
.getEntry(*StringVal
);
905 emitIntOffset(StringRef
.getOffset(), P
.FormParams
.Format
, LineSectionSize
);
908 warn("Unsupported string form inside line table.");
913 void DwarfStreamer::emitLineTableProloguePayload(
914 const DWARFDebugLine::Prologue
&P
, OffsetsStringPool
&DebugStrPool
,
915 OffsetsStringPool
&DebugLineStrPool
) {
916 // minimum_instruction_length (ubyte).
917 MS
->emitInt8(P
.MinInstLength
);
918 LineSectionSize
+= 1;
919 if (P
.FormParams
.Version
>= 4) {
920 // maximum_operations_per_instruction (ubyte).
921 MS
->emitInt8(P
.MaxOpsPerInst
);
922 LineSectionSize
+= 1;
924 // default_is_stmt (ubyte).
925 MS
->emitInt8(P
.DefaultIsStmt
);
926 LineSectionSize
+= 1;
927 // line_base (sbyte).
928 MS
->emitInt8(P
.LineBase
);
929 LineSectionSize
+= 1;
930 // line_range (ubyte).
931 MS
->emitInt8(P
.LineRange
);
932 LineSectionSize
+= 1;
933 // opcode_base (ubyte).
934 MS
->emitInt8(P
.OpcodeBase
);
935 LineSectionSize
+= 1;
937 // standard_opcode_lengths (array of ubyte).
938 for (auto Length
: P
.StandardOpcodeLengths
) {
939 MS
->emitInt8(Length
);
940 LineSectionSize
+= 1;
943 if (P
.FormParams
.Version
< 5)
944 emitLineTablePrologueV2IncludeAndFileTable(P
, DebugStrPool
,
947 emitLineTablePrologueV5IncludeAndFileTable(P
, DebugStrPool
,
951 void DwarfStreamer::emitLineTableRows(
952 const DWARFDebugLine::LineTable
&LineTable
, MCSymbol
*LineEndSym
,
953 unsigned AddressByteSize
) {
955 MCDwarfLineTableParams Params
;
956 Params
.DWARF2LineOpcodeBase
= LineTable
.Prologue
.OpcodeBase
;
957 Params
.DWARF2LineBase
= LineTable
.Prologue
.LineBase
;
958 Params
.DWARF2LineRange
= LineTable
.Prologue
.LineRange
;
960 SmallString
<128> EncodingBuffer
;
962 if (LineTable
.Rows
.empty()) {
963 // We only have the dummy entry, dsymutil emits an entry with a 0
964 // address in that case.
965 MCDwarfLineAddr::encode(*MC
, Params
, std::numeric_limits
<int64_t>::max(), 0,
967 MS
->emitBytes(EncodingBuffer
);
968 LineSectionSize
+= EncodingBuffer
.size();
969 MS
->emitLabel(LineEndSym
);
973 // Line table state machine fields
974 unsigned FileNum
= 1;
975 unsigned LastLine
= 1;
977 unsigned IsStatement
= 1;
979 uint64_t Address
= -1ULL;
981 unsigned RowsSinceLastSequence
= 0;
983 for (const DWARFDebugLine::Row
&Row
: LineTable
.Rows
) {
984 int64_t AddressDelta
;
985 if (Address
== -1ULL) {
986 MS
->emitIntValue(dwarf::DW_LNS_extended_op
, 1);
987 MS
->emitULEB128IntValue(AddressByteSize
+ 1);
988 MS
->emitIntValue(dwarf::DW_LNE_set_address
, 1);
989 MS
->emitIntValue(Row
.Address
.Address
, AddressByteSize
);
991 2 + AddressByteSize
+ getULEB128Size(AddressByteSize
+ 1);
995 (Row
.Address
.Address
- Address
) / LineTable
.Prologue
.MinInstLength
;
998 // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
999 // We should find a way to share this code, but the current compatibility
1000 // requirement with classic dsymutil makes it hard. Revisit that once this
1001 // requirement is dropped.
1003 if (FileNum
!= Row
.File
) {
1005 MS
->emitIntValue(dwarf::DW_LNS_set_file
, 1);
1006 MS
->emitULEB128IntValue(FileNum
);
1007 LineSectionSize
+= 1 + getULEB128Size(FileNum
);
1009 if (Column
!= Row
.Column
) {
1010 Column
= Row
.Column
;
1011 MS
->emitIntValue(dwarf::DW_LNS_set_column
, 1);
1012 MS
->emitULEB128IntValue(Column
);
1013 LineSectionSize
+= 1 + getULEB128Size(Column
);
1016 // FIXME: We should handle the discriminator here, but dsymutil doesn't
1017 // consider it, thus ignore it for now.
1019 if (Isa
!= Row
.Isa
) {
1021 MS
->emitIntValue(dwarf::DW_LNS_set_isa
, 1);
1022 MS
->emitULEB128IntValue(Isa
);
1023 LineSectionSize
+= 1 + getULEB128Size(Isa
);
1025 if (IsStatement
!= Row
.IsStmt
) {
1026 IsStatement
= Row
.IsStmt
;
1027 MS
->emitIntValue(dwarf::DW_LNS_negate_stmt
, 1);
1028 LineSectionSize
+= 1;
1030 if (Row
.BasicBlock
) {
1031 MS
->emitIntValue(dwarf::DW_LNS_set_basic_block
, 1);
1032 LineSectionSize
+= 1;
1035 if (Row
.PrologueEnd
) {
1036 MS
->emitIntValue(dwarf::DW_LNS_set_prologue_end
, 1);
1037 LineSectionSize
+= 1;
1040 if (Row
.EpilogueBegin
) {
1041 MS
->emitIntValue(dwarf::DW_LNS_set_epilogue_begin
, 1);
1042 LineSectionSize
+= 1;
1045 int64_t LineDelta
= int64_t(Row
.Line
) - LastLine
;
1046 if (!Row
.EndSequence
) {
1047 MCDwarfLineAddr::encode(*MC
, Params
, LineDelta
, AddressDelta
,
1049 MS
->emitBytes(EncodingBuffer
);
1050 LineSectionSize
+= EncodingBuffer
.size();
1051 EncodingBuffer
.resize(0);
1052 Address
= Row
.Address
.Address
;
1053 LastLine
= Row
.Line
;
1054 RowsSinceLastSequence
++;
1057 MS
->emitIntValue(dwarf::DW_LNS_advance_line
, 1);
1058 MS
->emitSLEB128IntValue(LineDelta
);
1059 LineSectionSize
+= 1 + getSLEB128Size(LineDelta
);
1062 MS
->emitIntValue(dwarf::DW_LNS_advance_pc
, 1);
1063 MS
->emitULEB128IntValue(AddressDelta
);
1064 LineSectionSize
+= 1 + getULEB128Size(AddressDelta
);
1066 MCDwarfLineAddr::encode(*MC
, Params
, std::numeric_limits
<int64_t>::max(),
1068 MS
->emitBytes(EncodingBuffer
);
1069 LineSectionSize
+= EncodingBuffer
.size();
1070 EncodingBuffer
.resize(0);
1072 LastLine
= FileNum
= IsStatement
= 1;
1073 RowsSinceLastSequence
= Column
= Isa
= 0;
1077 if (RowsSinceLastSequence
) {
1078 MCDwarfLineAddr::encode(*MC
, Params
, std::numeric_limits
<int64_t>::max(), 0,
1080 MS
->emitBytes(EncodingBuffer
);
1081 LineSectionSize
+= EncodingBuffer
.size();
1082 EncodingBuffer
.resize(0);
1085 MS
->emitLabel(LineEndSym
);
1088 void DwarfStreamer::emitIntOffset(uint64_t Offset
, dwarf::DwarfFormat Format
,
1089 uint64_t &SectionSize
) {
1090 uint8_t Size
= dwarf::getDwarfOffsetByteSize(Format
);
1091 MS
->emitIntValue(Offset
, Size
);
1092 SectionSize
+= Size
;
1095 void DwarfStreamer::emitLabelDifference(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1096 dwarf::DwarfFormat Format
,
1097 uint64_t &SectionSize
) {
1098 uint8_t Size
= dwarf::getDwarfOffsetByteSize(Format
);
1099 Asm
->emitLabelDifference(Hi
, Lo
, Size
);
1100 SectionSize
+= Size
;
1103 /// Emit the pubnames or pubtypes section contribution for \p
1104 /// Unit into \p Sec. The data is provided in \p Names.
1105 void DwarfStreamer::emitPubSectionForUnit(
1106 MCSection
*Sec
, StringRef SecName
, const CompileUnit
&Unit
,
1107 const std::vector
<CompileUnit::AccelInfo
> &Names
) {
1111 // Start the dwarf pubnames section.
1112 Asm
->OutStreamer
->switchSection(Sec
);
1113 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("pub" + SecName
+ "_begin");
1114 MCSymbol
*EndLabel
= Asm
->createTempSymbol("pub" + SecName
+ "_end");
1116 bool HeaderEmitted
= false;
1117 // Emit the pubnames for this compilation unit.
1118 for (const auto &Name
: Names
) {
1119 if (Name
.SkipPubSection
)
1122 if (!HeaderEmitted
) {
1124 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, 4); // Length
1125 Asm
->OutStreamer
->emitLabel(BeginLabel
);
1126 Asm
->emitInt16(dwarf::DW_PUBNAMES_VERSION
); // Version
1127 Asm
->emitInt32(Unit
.getStartOffset()); // Unit offset
1128 Asm
->emitInt32(Unit
.getNextUnitOffset() - Unit
.getStartOffset()); // Size
1129 HeaderEmitted
= true;
1131 Asm
->emitInt32(Name
.Die
->getOffset());
1133 // Emit the string itself.
1134 Asm
->OutStreamer
->emitBytes(Name
.Name
.getString());
1135 // Emit a null terminator.
1141 Asm
->emitInt32(0); // End marker.
1142 Asm
->OutStreamer
->emitLabel(EndLabel
);
1145 /// Emit .debug_pubnames for \p Unit.
1146 void DwarfStreamer::emitPubNamesForUnit(const CompileUnit
&Unit
) {
1147 emitPubSectionForUnit(MC
->getObjectFileInfo()->getDwarfPubNamesSection(),
1148 "names", Unit
, Unit
.getPubnames());
1151 /// Emit .debug_pubtypes for \p Unit.
1152 void DwarfStreamer::emitPubTypesForUnit(const CompileUnit
&Unit
) {
1153 emitPubSectionForUnit(MC
->getObjectFileInfo()->getDwarfPubTypesSection(),
1154 "types", Unit
, Unit
.getPubtypes());
1157 /// Emit a CIE into the debug_frame section.
1158 void DwarfStreamer::emitCIE(StringRef CIEBytes
) {
1159 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfFrameSection());
1161 MS
->emitBytes(CIEBytes
);
1162 FrameSectionSize
+= CIEBytes
.size();
1165 /// Emit a FDE into the debug_frame section. \p FDEBytes
1166 /// contains the FDE data without the length, CIE offset and address
1167 /// which will be replaced with the parameter values.
1168 void DwarfStreamer::emitFDE(uint32_t CIEOffset
, uint32_t AddrSize
,
1169 uint64_t Address
, StringRef FDEBytes
) {
1170 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfFrameSection());
1172 MS
->emitIntValue(FDEBytes
.size() + 4 + AddrSize
, 4);
1173 MS
->emitIntValue(CIEOffset
, 4);
1174 MS
->emitIntValue(Address
, AddrSize
);
1175 MS
->emitBytes(FDEBytes
);
1176 FrameSectionSize
+= FDEBytes
.size() + 8 + AddrSize
;
1179 void DwarfStreamer::emitMacroTables(DWARFContext
*Context
,
1180 const Offset2UnitMap
&UnitMacroMap
,
1181 OffsetsStringPool
&StringPool
) {
1182 assert(Context
!= nullptr && "Empty DWARF context");
1184 // Check for .debug_macinfo table.
1185 if (const DWARFDebugMacro
*Table
= Context
->getDebugMacinfo()) {
1186 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfMacinfoSection());
1187 emitMacroTableImpl(Table
, UnitMacroMap
, StringPool
, MacInfoSectionSize
);
1190 // Check for .debug_macro table.
1191 if (const DWARFDebugMacro
*Table
= Context
->getDebugMacro()) {
1192 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfMacroSection());
1193 emitMacroTableImpl(Table
, UnitMacroMap
, StringPool
, MacroSectionSize
);
1197 void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro
*MacroTable
,
1198 const Offset2UnitMap
&UnitMacroMap
,
1199 OffsetsStringPool
&StringPool
,
1200 uint64_t &OutOffset
) {
1201 bool DefAttributeIsReported
= false;
1202 bool UndefAttributeIsReported
= false;
1203 bool ImportAttributeIsReported
= false;
1204 for (const DWARFDebugMacro::MacroList
&List
: MacroTable
->MacroLists
) {
1205 Offset2UnitMap::const_iterator UnitIt
= UnitMacroMap
.find(List
.Offset
);
1206 if (UnitIt
== UnitMacroMap
.end()) {
1208 "couldn`t find compile unit for the macro table with offset = {0:x}",
1213 // Skip macro table if the unit was not cloned.
1214 DIE
*OutputUnitDIE
= UnitIt
->second
->getOutputUnitDIE();
1215 if (OutputUnitDIE
== nullptr)
1218 // Update macro attribute of cloned compile unit with the proper offset to
1220 bool hasDWARFv5Header
= false;
1221 for (auto &V
: OutputUnitDIE
->values()) {
1222 if (V
.getAttribute() == dwarf::DW_AT_macro_info
) {
1223 V
= DIEValue(V
.getAttribute(), V
.getForm(), DIEInteger(OutOffset
));
1225 } else if (V
.getAttribute() == dwarf::DW_AT_macros
) {
1226 hasDWARFv5Header
= true;
1227 V
= DIEValue(V
.getAttribute(), V
.getForm(), DIEInteger(OutOffset
));
1232 // Write DWARFv5 header.
1233 if (hasDWARFv5Header
) {
1234 // Write header version.
1235 MS
->emitIntValue(List
.Header
.Version
, sizeof(List
.Header
.Version
));
1236 OutOffset
+= sizeof(List
.Header
.Version
);
1238 uint8_t Flags
= List
.Header
.Flags
;
1240 // Check for OPCODE_OPERANDS_TABLE.
1242 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
) {
1243 Flags
&= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
;
1244 warn("opcode_operands_table is not supported yet.");
1247 // Check for DEBUG_LINE_OFFSET.
1248 std::optional
<uint64_t> StmtListOffset
;
1249 if (Flags
& DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
) {
1250 // Get offset to the line table from the cloned compile unit.
1251 for (auto &V
: OutputUnitDIE
->values()) {
1252 if (V
.getAttribute() == dwarf::DW_AT_stmt_list
) {
1253 StmtListOffset
= V
.getDIEInteger().getValue();
1258 if (!StmtListOffset
) {
1259 Flags
&= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
;
1260 warn("couldn`t find line table for macro table.");
1265 MS
->emitIntValue(Flags
, sizeof(Flags
));
1266 OutOffset
+= sizeof(Flags
);
1268 // Write offset to line table.
1269 if (StmtListOffset
) {
1270 MS
->emitIntValue(*StmtListOffset
, List
.Header
.getOffsetByteSize());
1271 OutOffset
+= List
.Header
.getOffsetByteSize();
1275 // Write macro entries.
1276 for (const DWARFDebugMacro::Entry
&MacroEntry
: List
.Macros
) {
1277 if (MacroEntry
.Type
== 0) {
1278 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Type
);
1282 uint8_t MacroType
= MacroEntry
.Type
;
1283 switch (MacroType
) {
1285 bool HasVendorSpecificExtension
=
1286 (!hasDWARFv5Header
&& MacroType
== dwarf::DW_MACINFO_vendor_ext
) ||
1287 (hasDWARFv5Header
&& (MacroType
>= dwarf::DW_MACRO_lo_user
&&
1288 MacroType
<= dwarf::DW_MACRO_hi_user
));
1290 if (HasVendorSpecificExtension
) {
1291 // Write macinfo type.
1292 MS
->emitIntValue(MacroType
, 1);
1295 // Write vendor extension constant.
1296 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.ExtConstant
);
1298 // Write vendor extension string.
1299 StringRef String
= MacroEntry
.ExtStr
;
1300 MS
->emitBytes(String
);
1301 MS
->emitIntValue(0, 1);
1302 OutOffset
+= String
.size() + 1;
1304 warn("unknown macro type. skip.");
1306 // debug_macro and debug_macinfo share some common encodings.
1307 // DW_MACRO_define == DW_MACINFO_define
1308 // DW_MACRO_undef == DW_MACINFO_undef
1309 // DW_MACRO_start_file == DW_MACINFO_start_file
1310 // DW_MACRO_end_file == DW_MACINFO_end_file
1311 // For readibility/uniformity we are using DW_MACRO_*.
1312 case dwarf::DW_MACRO_define
:
1313 case dwarf::DW_MACRO_undef
: {
1314 // Write macinfo type.
1315 MS
->emitIntValue(MacroType
, 1);
1318 // Write source line.
1319 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Line
);
1321 // Write macro string.
1322 StringRef String
= MacroEntry
.MacroStr
;
1323 MS
->emitBytes(String
);
1324 MS
->emitIntValue(0, 1);
1325 OutOffset
+= String
.size() + 1;
1327 case dwarf::DW_MACRO_define_strp
:
1328 case dwarf::DW_MACRO_undef_strp
:
1329 case dwarf::DW_MACRO_define_strx
:
1330 case dwarf::DW_MACRO_undef_strx
: {
1331 assert(UnitIt
->second
->getOrigUnit().getVersion() >= 5);
1333 // DW_MACRO_*_strx forms are not supported currently.
1334 // Convert to *_strp.
1335 switch (MacroType
) {
1336 case dwarf::DW_MACRO_define_strx
: {
1337 MacroType
= dwarf::DW_MACRO_define_strp
;
1338 if (!DefAttributeIsReported
) {
1339 warn("DW_MACRO_define_strx unsupported yet. Convert to "
1340 "DW_MACRO_define_strp.");
1341 DefAttributeIsReported
= true;
1344 case dwarf::DW_MACRO_undef_strx
: {
1345 MacroType
= dwarf::DW_MACRO_undef_strp
;
1346 if (!UndefAttributeIsReported
) {
1347 warn("DW_MACRO_undef_strx unsupported yet. Convert to "
1348 "DW_MACRO_undef_strp.");
1349 UndefAttributeIsReported
= true;
1357 // Write macinfo type.
1358 MS
->emitIntValue(MacroType
, 1);
1361 // Write source line.
1362 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Line
);
1364 // Write macro string.
1365 DwarfStringPoolEntryRef EntryRef
=
1366 StringPool
.getEntry(MacroEntry
.MacroStr
);
1367 MS
->emitIntValue(EntryRef
.getOffset(), List
.Header
.getOffsetByteSize());
1368 OutOffset
+= List
.Header
.getOffsetByteSize();
1371 case dwarf::DW_MACRO_start_file
: {
1372 // Write macinfo type.
1373 MS
->emitIntValue(MacroType
, 1);
1375 // Write source line.
1376 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Line
);
1377 // Write source file id.
1378 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.File
);
1380 case dwarf::DW_MACRO_end_file
: {
1381 // Write macinfo type.
1382 MS
->emitIntValue(MacroType
, 1);
1385 case dwarf::DW_MACRO_import
:
1386 case dwarf::DW_MACRO_import_sup
: {
1387 if (!ImportAttributeIsReported
) {
1388 warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
1390 ImportAttributeIsReported
= true;