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/Classic/DWARFStreamer.h"
10 #include "llvm/CodeGen/NonRelocatableStringpool.h"
11 #include "llvm/DWARFLinker/Classic/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"
30 using namespace dwarf_linker
;
31 using namespace dwarf_linker::classic
;
33 Expected
<std::unique_ptr
<DwarfStreamer
>> DwarfStreamer::createStreamer(
34 const Triple
&TheTriple
, DWARFLinkerBase::OutputFileType FileType
,
35 raw_pwrite_stream
&OutFile
, DWARFLinkerBase::MessageHandlerTy Warning
) {
36 std::unique_ptr
<DwarfStreamer
> Streamer
=
37 std::make_unique
<DwarfStreamer
>(FileType
, OutFile
, Warning
);
38 if (Error Err
= Streamer
->init(TheTriple
, "__DWARF"))
39 return std::move(Err
);
41 return std::move(Streamer
);
44 Error
DwarfStreamer::init(Triple TheTriple
,
45 StringRef Swift5ReflectionSegmentName
) {
47 std::string TripleName
;
50 const Target
*TheTarget
=
51 TargetRegistry::lookupTarget(TripleName
, TheTriple
, ErrorStr
);
53 return createStringError(std::errc::invalid_argument
, ErrorStr
.c_str());
55 TripleName
= TheTriple
.getTriple();
57 // Create all the MC Objects.
58 MRI
.reset(TheTarget
->createMCRegInfo(TripleName
));
60 return createStringError(std::errc::invalid_argument
,
61 "no register info for target %s",
64 MCTargetOptions MCOptions
= mc::InitMCTargetOptionsFromFlags();
65 MCOptions
.AsmVerbose
= true;
66 MCOptions
.MCUseDwarfDirectory
= MCTargetOptions::EnableDwarfDirectory
;
67 MAI
.reset(TheTarget
->createMCAsmInfo(*MRI
, TripleName
, MCOptions
));
69 return createStringError(std::errc::invalid_argument
,
70 "no asm info for target %s", TripleName
.c_str());
72 MSTI
.reset(TheTarget
->createMCSubtargetInfo(TripleName
, "", ""));
74 return createStringError(std::errc::invalid_argument
,
75 "no subtarget info for target %s",
78 MC
.reset(new MCContext(TheTriple
, MAI
.get(), MRI
.get(), MSTI
.get(), nullptr,
79 nullptr, true, Swift5ReflectionSegmentName
));
80 MOFI
.reset(TheTarget
->createMCObjectFileInfo(*MC
, /*PIC=*/false, false));
81 MC
->setObjectFileInfo(MOFI
.get());
83 MAB
= TheTarget
->createMCAsmBackend(*MSTI
, *MRI
, MCOptions
);
85 return createStringError(std::errc::invalid_argument
,
86 "no asm backend for target %s",
89 MII
.reset(TheTarget
->createMCInstrInfo());
91 return createStringError(std::errc::invalid_argument
,
92 "no instr info info for target %s",
95 MCE
= TheTarget
->createMCCodeEmitter(*MII
, *MC
);
97 return createStringError(std::errc::invalid_argument
,
98 "no code emitter for target %s",
101 switch (OutFileType
) {
102 case DWARFLinker::OutputFileType::Assembly
: {
103 MIP
= TheTarget
->createMCInstPrinter(TheTriple
, MAI
->getAssemblerDialect(),
105 MS
= TheTarget
->createAsmStreamer(
106 *MC
, std::make_unique
<formatted_raw_ostream
>(OutFile
), MIP
,
107 std::unique_ptr
<MCCodeEmitter
>(MCE
),
108 std::unique_ptr
<MCAsmBackend
>(MAB
));
111 case DWARFLinker::OutputFileType::Object
: {
112 MS
= TheTarget
->createMCObjectStreamer(
113 TheTriple
, *MC
, std::unique_ptr
<MCAsmBackend
>(MAB
),
114 MAB
->createObjectWriter(OutFile
), std::unique_ptr
<MCCodeEmitter
>(MCE
),
121 return createStringError(std::errc::invalid_argument
,
122 "no object streamer for target %s",
125 // Finally create the AsmPrinter we'll use to emit the DIEs.
126 TM
.reset(TheTarget
->createTargetMachine(TripleName
, "", "", TargetOptions(),
129 return createStringError(std::errc::invalid_argument
,
130 "no target machine for target %s",
133 Asm
.reset(TheTarget
->createAsmPrinter(*TM
, std::unique_ptr
<MCStreamer
>(MS
)));
135 return createStringError(std::errc::invalid_argument
,
136 "no asm printer for target %s",
138 Asm
->setDwarfUsesRelocationsAcrossSections(false);
140 RangesSectionSize
= 0;
141 RngListsSectionSize
= 0;
143 LocListsSectionSize
= 0;
145 FrameSectionSize
= 0;
146 DebugInfoSectionSize
= 0;
147 MacInfoSectionSize
= 0;
148 MacroSectionSize
= 0;
150 return Error::success();
153 void DwarfStreamer::finish() { MS
->finish(); }
155 void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion
) {
156 MS
->switchSection(MOFI
->getDwarfInfoSection());
157 MC
->setDwarfVersion(DwarfVersion
);
160 /// Emit the compilation unit header for \p Unit in the debug_info section.
162 /// A Dwarf 4 section header is encoded as:
163 /// uint32_t Unit length (omitting this field)
165 /// uint32_t Abbreviation table offset
166 /// uint8_t Address size
167 /// Leading to a total of 11 bytes.
169 /// A Dwarf 5 section header is encoded as:
170 /// uint32_t Unit length (omitting this field)
172 /// uint8_t Unit type
173 /// uint8_t Address size
174 /// uint32_t Abbreviation table offset
175 /// Leading to a total of 12 bytes.
176 void DwarfStreamer::emitCompileUnitHeader(CompileUnit
&Unit
,
177 unsigned DwarfVersion
) {
178 switchToDebugInfoSection(DwarfVersion
);
180 /// The start of the unit within its section.
181 Unit
.setLabelBegin(Asm
->createTempSymbol("cu_begin"));
182 Asm
->OutStreamer
->emitLabel(Unit
.getLabelBegin());
184 // Emit size of content not including length itself. The size has already
185 // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
186 // account for the length field.
187 Asm
->emitInt32(Unit
.getNextUnitOffset() - Unit
.getStartOffset() - 4);
188 Asm
->emitInt16(DwarfVersion
);
190 if (DwarfVersion
>= 5) {
191 Asm
->emitInt8(dwarf::DW_UT_compile
);
192 Asm
->emitInt8(Unit
.getOrigUnit().getAddressByteSize());
193 // We share one abbreviations table across all units so it's always at the
194 // start of the section.
196 DebugInfoSectionSize
+= 12;
198 // We share one abbreviations table across all units so it's always at the
199 // start of the section.
201 Asm
->emitInt8(Unit
.getOrigUnit().getAddressByteSize());
202 DebugInfoSectionSize
+= 11;
206 EmittedUnits
.push_back({Unit
.getUniqueID(), Unit
.getLabelBegin()});
209 /// Emit the \p Abbrevs array as the shared abbreviation table
210 /// for the linked Dwarf file.
211 void DwarfStreamer::emitAbbrevs(
212 const std::vector
<std::unique_ptr
<DIEAbbrev
>> &Abbrevs
,
213 unsigned DwarfVersion
) {
214 MS
->switchSection(MOFI
->getDwarfAbbrevSection());
215 MC
->setDwarfVersion(DwarfVersion
);
216 Asm
->emitDwarfAbbrevs(Abbrevs
);
219 /// Recursively emit the DIE tree rooted at \p Die.
220 void DwarfStreamer::emitDIE(DIE
&Die
) {
221 MS
->switchSection(MOFI
->getDwarfInfoSection());
222 Asm
->emitDwarfDIE(Die
);
223 DebugInfoSectionSize
+= Die
.getSize();
226 /// Emit contents of section SecName From Obj.
227 void DwarfStreamer::emitSectionContents(StringRef SecData
,
228 DebugSectionKind SecKind
) {
232 if (MCSection
*Section
= getMCSection(SecKind
)) {
233 MS
->switchSection(Section
);
235 MS
->emitBytes(SecData
);
239 MCSection
*DwarfStreamer::getMCSection(DebugSectionKind SecKind
) {
241 case DebugSectionKind::DebugInfo
:
242 return MC
->getObjectFileInfo()->getDwarfInfoSection();
243 case DebugSectionKind::DebugLine
:
244 return MC
->getObjectFileInfo()->getDwarfLineSection();
245 case DebugSectionKind::DebugFrame
:
246 return MC
->getObjectFileInfo()->getDwarfFrameSection();
247 case DebugSectionKind::DebugRange
:
248 return MC
->getObjectFileInfo()->getDwarfRangesSection();
249 case DebugSectionKind::DebugRngLists
:
250 return MC
->getObjectFileInfo()->getDwarfRnglistsSection();
251 case DebugSectionKind::DebugLoc
:
252 return MC
->getObjectFileInfo()->getDwarfLocSection();
253 case DebugSectionKind::DebugLocLists
:
254 return MC
->getObjectFileInfo()->getDwarfLoclistsSection();
255 case DebugSectionKind::DebugARanges
:
256 return MC
->getObjectFileInfo()->getDwarfARangesSection();
257 case DebugSectionKind::DebugAbbrev
:
258 return MC
->getObjectFileInfo()->getDwarfAbbrevSection();
259 case DebugSectionKind::DebugMacinfo
:
260 return MC
->getObjectFileInfo()->getDwarfMacinfoSection();
261 case DebugSectionKind::DebugMacro
:
262 return MC
->getObjectFileInfo()->getDwarfMacroSection();
263 case DebugSectionKind::DebugAddr
:
264 return MC
->getObjectFileInfo()->getDwarfAddrSection();
265 case DebugSectionKind::DebugStr
:
266 return MC
->getObjectFileInfo()->getDwarfStrSection();
267 case DebugSectionKind::DebugLineStr
:
268 return MC
->getObjectFileInfo()->getDwarfLineStrSection();
269 case DebugSectionKind::DebugStrOffsets
:
270 return MC
->getObjectFileInfo()->getDwarfStrOffSection();
271 case DebugSectionKind::DebugPubNames
:
272 return MC
->getObjectFileInfo()->getDwarfPubNamesSection();
273 case DebugSectionKind::DebugPubTypes
:
274 return MC
->getObjectFileInfo()->getDwarfPubTypesSection();
275 case DebugSectionKind::DebugNames
:
276 return MC
->getObjectFileInfo()->getDwarfDebugNamesSection();
277 case DebugSectionKind::AppleNames
:
278 return MC
->getObjectFileInfo()->getDwarfAccelNamesSection();
279 case DebugSectionKind::AppleNamespaces
:
280 return MC
->getObjectFileInfo()->getDwarfAccelNamespaceSection();
281 case DebugSectionKind::AppleObjC
:
282 return MC
->getObjectFileInfo()->getDwarfAccelObjCSection();
283 case DebugSectionKind::AppleTypes
:
284 return MC
->getObjectFileInfo()->getDwarfAccelTypesSection();
285 case DebugSectionKind::NumberOfEnumEntries
:
286 llvm_unreachable("Unknown DebugSectionKind value");
293 /// Emit the debug_str section stored in \p Pool.
294 void DwarfStreamer::emitStrings(const NonRelocatableStringpool
&Pool
) {
295 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfStrSection());
296 std::vector
<DwarfStringPoolEntryRef
> Entries
= Pool
.getEntriesForEmission();
297 for (auto Entry
: Entries
) {
298 // Emit the string itself.
299 Asm
->OutStreamer
->emitBytes(Entry
.getString());
300 // Emit a null terminator.
305 /// Emit the debug string offset table described by \p StringOffsets into the
306 /// .debug_str_offsets table.
307 void DwarfStreamer::emitStringOffsets(
308 const SmallVector
<uint64_t> &StringOffsets
, uint16_t TargetDWARFVersion
) {
310 if (TargetDWARFVersion
< 5 || StringOffsets
.empty())
313 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfStrOffSection());
315 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Bdebugstroff");
316 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Edebugstroff");
319 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
320 Asm
->OutStreamer
->emitLabel(BeginLabel
);
321 StrOffsetSectionSize
+= sizeof(uint32_t);
325 StrOffsetSectionSize
+= sizeof(uint16_t);
329 StrOffsetSectionSize
+= sizeof(uint16_t);
331 for (auto Off
: StringOffsets
) {
332 Asm
->OutStreamer
->emitInt32(Off
);
333 StrOffsetSectionSize
+= sizeof(uint32_t);
335 Asm
->OutStreamer
->emitLabel(EndLabel
);
338 /// Emit the debug_line_str section stored in \p Pool.
339 void DwarfStreamer::emitLineStrings(const NonRelocatableStringpool
&Pool
) {
340 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfLineStrSection());
341 std::vector
<DwarfStringPoolEntryRef
> Entries
= Pool
.getEntriesForEmission();
342 for (auto Entry
: Entries
) {
343 // Emit the string itself.
344 Asm
->OutStreamer
->emitBytes(Entry
.getString());
345 // Emit a null terminator.
350 void DwarfStreamer::emitDebugNames(DWARF5AccelTable
&Table
) {
351 if (EmittedUnits
.empty())
354 // Build up data structures needed to emit this section.
355 std::vector
<std::variant
<MCSymbol
*, uint64_t>> CompUnits
;
356 DenseMap
<unsigned, unsigned> UniqueIdToCuMap
;
358 for (auto &CU
: EmittedUnits
) {
359 CompUnits
.push_back(CU
.LabelBegin
);
360 // We might be omitting CUs, so we need to remap them.
361 UniqueIdToCuMap
[CU
.ID
] = Id
++;
364 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfDebugNamesSection());
365 dwarf::Form Form
= DIEInteger::BestForm(/*IsSigned*/ false,
366 (uint64_t)UniqueIdToCuMap
.size() - 1);
367 /// llvm-dwarfutil doesn't support type units + .debug_names right now.
368 // FIXME: add support for type units + .debug_names. For now the behavior is
370 emitDWARF5AccelTable(
371 Asm
.get(), Table
, CompUnits
,
372 [&](const DWARF5AccelTableData
&Entry
)
373 -> std::optional
<DWARF5AccelTable::UnitIndexAndEncoding
> {
374 if (UniqueIdToCuMap
.size() > 1)
375 return {{UniqueIdToCuMap
[Entry
.getUnitID()],
376 {dwarf::DW_IDX_compile_unit
, Form
}}};
381 void DwarfStreamer::emitAppleNamespaces(
382 AccelTable
<AppleAccelTableStaticOffsetData
> &Table
) {
383 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelNamespaceSection());
384 auto *SectionBegin
= Asm
->createTempSymbol("namespac_begin");
385 Asm
->OutStreamer
->emitLabel(SectionBegin
);
386 emitAppleAccelTable(Asm
.get(), Table
, "namespac", SectionBegin
);
389 void DwarfStreamer::emitAppleNames(
390 AccelTable
<AppleAccelTableStaticOffsetData
> &Table
) {
391 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelNamesSection());
392 auto *SectionBegin
= Asm
->createTempSymbol("names_begin");
393 Asm
->OutStreamer
->emitLabel(SectionBegin
);
394 emitAppleAccelTable(Asm
.get(), Table
, "names", SectionBegin
);
397 void DwarfStreamer::emitAppleObjc(
398 AccelTable
<AppleAccelTableStaticOffsetData
> &Table
) {
399 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelObjCSection());
400 auto *SectionBegin
= Asm
->createTempSymbol("objc_begin");
401 Asm
->OutStreamer
->emitLabel(SectionBegin
);
402 emitAppleAccelTable(Asm
.get(), Table
, "objc", SectionBegin
);
405 void DwarfStreamer::emitAppleTypes(
406 AccelTable
<AppleAccelTableStaticTypeData
> &Table
) {
407 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAccelTypesSection());
408 auto *SectionBegin
= Asm
->createTempSymbol("types_begin");
409 Asm
->OutStreamer
->emitLabel(SectionBegin
);
410 emitAppleAccelTable(Asm
.get(), Table
, "types", SectionBegin
);
413 /// Emit the swift_ast section stored in \p Buffers.
414 void DwarfStreamer::emitSwiftAST(StringRef Buffer
) {
415 MCSection
*SwiftASTSection
= MOFI
->getDwarfSwiftASTSection();
416 SwiftASTSection
->setAlignment(Align(32));
417 MS
->switchSection(SwiftASTSection
);
418 MS
->emitBytes(Buffer
);
421 void DwarfStreamer::emitSwiftReflectionSection(
422 llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind
,
423 StringRef Buffer
, uint32_t Alignment
, uint32_t Size
) {
424 MCSection
*ReflectionSection
=
425 MOFI
->getSwift5ReflectionSection(ReflSectionKind
);
426 if (ReflectionSection
== nullptr)
428 ReflectionSection
->setAlignment(Align(Alignment
));
429 MS
->switchSection(ReflectionSection
);
430 MS
->emitBytes(Buffer
);
433 void DwarfStreamer::emitDwarfDebugArangesTable(
434 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
) {
435 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
437 // Make .debug_aranges to be current section.
438 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfARangesSection());
441 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Barange");
442 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Earange");
444 unsigned HeaderSize
=
445 sizeof(int32_t) + // Size of contents (w/o this field
446 sizeof(int16_t) + // DWARF ARange version number
447 sizeof(int32_t) + // Offset of CU in the .debug_info section
448 sizeof(int8_t) + // Pointer Size (in bytes)
449 sizeof(int8_t); // Segment Size (in bytes)
451 unsigned TupleSize
= AddressSize
* 2;
452 unsigned Padding
= offsetToAlignment(HeaderSize
, Align(TupleSize
));
454 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, 4); // Arange length
455 Asm
->OutStreamer
->emitLabel(BeginLabel
);
456 Asm
->emitInt16(dwarf::DW_ARANGES_VERSION
); // Version number
457 Asm
->emitInt32(Unit
.getStartOffset()); // Corresponding unit's offset
458 Asm
->emitInt8(AddressSize
); // Address size
459 Asm
->emitInt8(0); // Segment size
461 Asm
->OutStreamer
->emitFill(Padding
, 0x0);
463 // Emit linked ranges.
464 for (const AddressRange
&Range
: LinkedRanges
) {
465 MS
->emitIntValue(Range
.start(), AddressSize
);
466 MS
->emitIntValue(Range
.end() - Range
.start(), AddressSize
);
470 Asm
->OutStreamer
->emitIntValue(0, AddressSize
);
471 Asm
->OutStreamer
->emitIntValue(0, AddressSize
);
472 Asm
->OutStreamer
->emitLabel(EndLabel
);
475 void DwarfStreamer::emitDwarfDebugRangesTableFragment(
476 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
,
477 PatchLocation Patch
) {
478 Patch
.set(RangesSectionSize
);
480 // Make .debug_ranges to be current section.
481 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRangesSection());
482 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
485 uint64_t BaseAddress
= 0;
486 if (std::optional
<uint64_t> LowPC
= Unit
.getLowPc())
487 BaseAddress
= *LowPC
;
489 for (const AddressRange
&Range
: LinkedRanges
) {
490 MS
->emitIntValue(Range
.start() - BaseAddress
, AddressSize
);
491 MS
->emitIntValue(Range
.end() - BaseAddress
, AddressSize
);
493 RangesSectionSize
+= AddressSize
;
494 RangesSectionSize
+= AddressSize
;
497 // Add the terminator entry.
498 MS
->emitIntValue(0, AddressSize
);
499 MS
->emitIntValue(0, AddressSize
);
501 RangesSectionSize
+= AddressSize
;
502 RangesSectionSize
+= AddressSize
;
506 DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit
&Unit
) {
507 if (Unit
.getOrigUnit().getVersion() < 5)
510 // Make .debug_rnglists to be current section.
511 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRnglistsSection());
513 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Brnglists");
514 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Ernglists");
515 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
518 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
519 Asm
->OutStreamer
->emitLabel(BeginLabel
);
520 RngListsSectionSize
+= sizeof(uint32_t);
524 RngListsSectionSize
+= sizeof(uint16_t);
527 MS
->emitInt8(AddressSize
);
528 RngListsSectionSize
++;
532 RngListsSectionSize
++;
534 // Offset entry count
536 RngListsSectionSize
+= sizeof(uint32_t);
541 void DwarfStreamer::emitDwarfDebugRangeListFragment(
542 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
,
543 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
544 if (Unit
.getOrigUnit().getVersion() < 5) {
545 emitDwarfDebugRangesTableFragment(Unit
, LinkedRanges
, Patch
);
549 emitDwarfDebugRngListsTableFragment(Unit
, LinkedRanges
, Patch
, AddrPool
);
552 void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit
&Unit
,
553 MCSymbol
*EndLabel
) {
554 if (Unit
.getOrigUnit().getVersion() < 5)
557 // Make .debug_rnglists to be current section.
558 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRnglistsSection());
560 if (EndLabel
!= nullptr)
561 Asm
->OutStreamer
->emitLabel(EndLabel
);
564 void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
565 const CompileUnit
&Unit
, const AddressRanges
&LinkedRanges
,
566 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
567 Patch
.set(RngListsSectionSize
);
569 // Make .debug_rnglists to be current section.
570 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfRnglistsSection());
571 std::optional
<uint64_t> BaseAddress
;
573 for (const AddressRange
&Range
: LinkedRanges
) {
576 BaseAddress
= Range
.start();
578 // Emit base address.
579 MS
->emitInt8(dwarf::DW_RLE_base_addressx
);
580 RngListsSectionSize
+= 1;
581 RngListsSectionSize
+=
582 MS
->emitULEB128IntValue(AddrPool
.getValueIndex(*BaseAddress
));
585 // Emit type of entry.
586 MS
->emitInt8(dwarf::DW_RLE_offset_pair
);
587 RngListsSectionSize
+= 1;
589 // Emit start offset relative to base address.
590 RngListsSectionSize
+=
591 MS
->emitULEB128IntValue(Range
.start() - *BaseAddress
);
593 // Emit end offset relative to base address.
594 RngListsSectionSize
+= MS
->emitULEB128IntValue(Range
.end() - *BaseAddress
);
597 // Emit the terminator entry.
598 MS
->emitInt8(dwarf::DW_RLE_end_of_list
);
599 RngListsSectionSize
+= 1;
602 /// Emit debug locations(.debug_loc, .debug_loclists) header.
603 MCSymbol
*DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit
&Unit
) {
604 if (Unit
.getOrigUnit().getVersion() < 5)
607 // Make .debug_loclists the current section.
608 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLoclistsSection());
610 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Bloclists");
611 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Eloclists");
612 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
615 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
616 Asm
->OutStreamer
->emitLabel(BeginLabel
);
617 LocListsSectionSize
+= sizeof(uint32_t);
621 LocListsSectionSize
+= sizeof(uint16_t);
624 MS
->emitInt8(AddressSize
);
625 LocListsSectionSize
++;
629 LocListsSectionSize
++;
631 // Offset entry count
633 LocListsSectionSize
+= sizeof(uint32_t);
638 /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
639 void DwarfStreamer::emitDwarfDebugLocListFragment(
640 const CompileUnit
&Unit
,
641 const DWARFLocationExpressionsVector
&LinkedLocationExpression
,
642 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
643 if (Unit
.getOrigUnit().getVersion() < 5) {
644 emitDwarfDebugLocTableFragment(Unit
, LinkedLocationExpression
, Patch
);
648 emitDwarfDebugLocListsTableFragment(Unit
, LinkedLocationExpression
, Patch
,
652 /// Emit debug locations(.debug_loc, .debug_loclists) footer.
653 void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit
&Unit
,
654 MCSymbol
*EndLabel
) {
655 if (Unit
.getOrigUnit().getVersion() < 5)
658 // Make .debug_loclists the current section.
659 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLoclistsSection());
661 if (EndLabel
!= nullptr)
662 Asm
->OutStreamer
->emitLabel(EndLabel
);
665 /// Emit piece of .debug_loc for \p LinkedLocationExpression.
666 void DwarfStreamer::emitDwarfDebugLocTableFragment(
667 const CompileUnit
&Unit
,
668 const DWARFLocationExpressionsVector
&LinkedLocationExpression
,
669 PatchLocation Patch
) {
670 Patch
.set(LocSectionSize
);
672 // Make .debug_loc to be current section.
673 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLocSection());
674 unsigned AddressSize
= Unit
.getOrigUnit().getAddressByteSize();
677 uint64_t BaseAddress
= 0;
678 if (std::optional
<uint64_t> LowPC
= Unit
.getLowPc())
679 BaseAddress
= *LowPC
;
681 for (const DWARFLocationExpression
&LocExpression
:
682 LinkedLocationExpression
) {
683 if (LocExpression
.Range
) {
684 MS
->emitIntValue(LocExpression
.Range
->LowPC
- BaseAddress
, AddressSize
);
685 MS
->emitIntValue(LocExpression
.Range
->HighPC
- BaseAddress
, AddressSize
);
687 LocSectionSize
+= AddressSize
;
688 LocSectionSize
+= AddressSize
;
691 Asm
->OutStreamer
->emitIntValue(LocExpression
.Expr
.size(), 2);
692 Asm
->OutStreamer
->emitBytes(StringRef(
693 (const char *)LocExpression
.Expr
.data(), LocExpression
.Expr
.size()));
694 LocSectionSize
+= LocExpression
.Expr
.size() + 2;
697 // Add the terminator entry.
698 MS
->emitIntValue(0, AddressSize
);
699 MS
->emitIntValue(0, AddressSize
);
701 LocSectionSize
+= AddressSize
;
702 LocSectionSize
+= AddressSize
;
705 /// Emit .debug_addr header.
706 MCSymbol
*DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit
&Unit
) {
708 // Make .debug_addr the current section.
709 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfAddrSection());
711 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("Bdebugaddr");
712 MCSymbol
*EndLabel
= Asm
->createTempSymbol("Edebugaddr");
713 unsigned AddrSize
= Unit
.getOrigUnit().getAddressByteSize();
716 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, sizeof(uint32_t));
717 Asm
->OutStreamer
->emitLabel(BeginLabel
);
718 AddrSectionSize
+= sizeof(uint32_t);
722 AddrSectionSize
+= 2;
724 // Emit address size.
725 Asm
->emitInt8(AddrSize
);
726 AddrSectionSize
+= 1;
728 // Emit segment size.
730 AddrSectionSize
+= 1;
735 /// Emit the .debug_addr addresses stored in \p Addrs.
736 void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector
<uint64_t> &Addrs
,
738 Asm
->OutStreamer
->switchSection(MOFI
->getDwarfAddrSection());
739 for (auto Addr
: Addrs
) {
740 Asm
->OutStreamer
->emitIntValue(Addr
, AddrSize
);
741 AddrSectionSize
+= AddrSize
;
745 /// Emit .debug_addr footer.
746 void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit
&Unit
,
747 MCSymbol
*EndLabel
) {
749 // Make .debug_addr the current section.
750 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfAddrSection());
752 if (EndLabel
!= nullptr)
753 Asm
->OutStreamer
->emitLabel(EndLabel
);
756 /// Emit piece of .debug_loclists for \p LinkedLocationExpression.
757 void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
758 const CompileUnit
&Unit
,
759 const DWARFLocationExpressionsVector
&LinkedLocationExpression
,
760 PatchLocation Patch
, DebugDieValuePool
&AddrPool
) {
761 Patch
.set(LocListsSectionSize
);
763 // Make .debug_loclists the current section.
764 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLoclistsSection());
765 std::optional
<uint64_t> BaseAddress
;
767 for (const DWARFLocationExpression
&LocExpression
:
768 LinkedLocationExpression
) {
769 if (LocExpression
.Range
) {
773 BaseAddress
= LocExpression
.Range
->LowPC
;
775 // Emit base address.
776 MS
->emitInt8(dwarf::DW_LLE_base_addressx
);
777 LocListsSectionSize
+= 1;
778 LocListsSectionSize
+=
779 MS
->emitULEB128IntValue(AddrPool
.getValueIndex(*BaseAddress
));
782 // Emit type of entry.
783 MS
->emitInt8(dwarf::DW_LLE_offset_pair
);
784 LocListsSectionSize
+= 1;
786 // Emit start offset relative to base address.
787 LocListsSectionSize
+=
788 MS
->emitULEB128IntValue(LocExpression
.Range
->LowPC
- *BaseAddress
);
790 // Emit end offset relative to base address.
791 LocListsSectionSize
+=
792 MS
->emitULEB128IntValue(LocExpression
.Range
->HighPC
- *BaseAddress
);
794 // Emit type of entry.
795 MS
->emitInt8(dwarf::DW_LLE_default_location
);
796 LocListsSectionSize
+= 1;
799 LocListsSectionSize
+= MS
->emitULEB128IntValue(LocExpression
.Expr
.size());
800 Asm
->OutStreamer
->emitBytes(StringRef(
801 (const char *)LocExpression
.Expr
.data(), LocExpression
.Expr
.size()));
802 LocListsSectionSize
+= LocExpression
.Expr
.size();
805 // Emit the terminator entry.
806 MS
->emitInt8(dwarf::DW_LLE_end_of_list
);
807 LocListsSectionSize
+= 1;
810 void DwarfStreamer::emitLineTableForUnit(
811 const DWARFDebugLine::LineTable
&LineTable
, const CompileUnit
&Unit
,
812 OffsetsStringPool
&DebugStrPool
, OffsetsStringPool
&DebugLineStrPool
) {
813 // Switch to the section where the table will be emitted into.
814 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfLineSection());
816 MCSymbol
*LineStartSym
= MC
->createTempSymbol();
817 MCSymbol
*LineEndSym
= MC
->createTempSymbol();
820 if (LineTable
.Prologue
.FormParams
.Format
== dwarf::DwarfFormat::DWARF64
) {
821 MS
->emitInt32(dwarf::DW_LENGTH_DWARF64
);
822 LineSectionSize
+= 4;
824 emitLabelDifference(LineEndSym
, LineStartSym
,
825 LineTable
.Prologue
.FormParams
.Format
, LineSectionSize
);
826 Asm
->OutStreamer
->emitLabel(LineStartSym
);
829 emitLineTablePrologue(LineTable
.Prologue
, DebugStrPool
, DebugLineStrPool
);
832 emitLineTableRows(LineTable
, LineEndSym
,
833 Unit
.getOrigUnit().getAddressByteSize());
836 void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue
&P
,
837 OffsetsStringPool
&DebugStrPool
,
838 OffsetsStringPool
&DebugLineStrPool
) {
839 MCSymbol
*PrologueStartSym
= MC
->createTempSymbol();
840 MCSymbol
*PrologueEndSym
= MC
->createTempSymbol();
843 MS
->emitInt16(P
.getVersion());
844 LineSectionSize
+= 2;
845 if (P
.getVersion() == 5) {
846 // address_size (ubyte).
847 MS
->emitInt8(P
.getAddressSize());
848 LineSectionSize
+= 1;
850 // segment_selector_size (ubyte).
851 MS
->emitInt8(P
.SegSelectorSize
);
852 LineSectionSize
+= 1;
856 emitLabelDifference(PrologueEndSym
, PrologueStartSym
, P
.FormParams
.Format
,
859 Asm
->OutStreamer
->emitLabel(PrologueStartSym
);
860 emitLineTableProloguePayload(P
, DebugStrPool
, DebugLineStrPool
);
861 Asm
->OutStreamer
->emitLabel(PrologueEndSym
);
864 void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
865 const DWARFDebugLine::Prologue
&P
, OffsetsStringPool
&DebugStrPool
,
866 OffsetsStringPool
&DebugLineStrPool
) {
867 // include_directories (sequence of path names).
868 for (const DWARFFormValue
&Include
: P
.IncludeDirectories
)
869 emitLineTableString(P
, Include
, DebugStrPool
, DebugLineStrPool
);
870 // The last entry is followed by a single null byte.
872 LineSectionSize
+= 1;
874 // file_names (sequence of file entries).
875 for (const DWARFDebugLine::FileNameEntry
&File
: P
.FileNames
) {
876 // A null-terminated string containing the full or relative path name of a
878 emitLineTableString(P
, File
.Name
, DebugStrPool
, DebugLineStrPool
);
879 // An unsigned LEB128 number representing the directory index of a directory
880 // in the include_directories section.
881 LineSectionSize
+= MS
->emitULEB128IntValue(File
.DirIdx
);
882 // An unsigned LEB128 number representing the (implementation-defined) time
883 // of last modification for the file, or 0 if not available.
884 LineSectionSize
+= MS
->emitULEB128IntValue(File
.ModTime
);
885 // An unsigned LEB128 number representing the length in bytes of the file,
886 // or 0 if not available.
887 LineSectionSize
+= MS
->emitULEB128IntValue(File
.Length
);
889 // The last entry is followed by a single null byte.
891 LineSectionSize
+= 1;
894 void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
895 const DWARFDebugLine::Prologue
&P
, OffsetsStringPool
&DebugStrPool
,
896 OffsetsStringPool
&DebugLineStrPool
) {
897 if (P
.IncludeDirectories
.empty()) {
898 // directory_entry_format_count(ubyte).
900 LineSectionSize
+= 1;
902 // directory_entry_format_count(ubyte).
904 LineSectionSize
+= 1;
906 // directory_entry_format (sequence of ULEB128 pairs).
907 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_path
);
909 MS
->emitULEB128IntValue(P
.IncludeDirectories
[0].getForm());
912 // directories_count (ULEB128).
913 LineSectionSize
+= MS
->emitULEB128IntValue(P
.IncludeDirectories
.size());
914 // directories (sequence of directory names).
915 for (auto Include
: P
.IncludeDirectories
)
916 emitLineTableString(P
, Include
, DebugStrPool
, DebugLineStrPool
);
918 bool HasChecksums
= P
.ContentTypes
.HasMD5
;
919 bool HasInlineSources
= P
.ContentTypes
.HasSource
;
921 if (P
.FileNames
.empty()) {
922 // file_name_entry_format_count (ubyte).
924 LineSectionSize
+= 1;
926 // file_name_entry_format_count (ubyte).
927 MS
->emitInt8(2 + (HasChecksums
? 1 : 0) + (HasInlineSources
? 1 : 0));
928 LineSectionSize
+= 1;
930 // file_name_entry_format (sequence of ULEB128 pairs).
931 auto StrForm
= P
.FileNames
[0].Name
.getForm();
932 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_path
);
933 LineSectionSize
+= MS
->emitULEB128IntValue(StrForm
);
935 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_directory_index
);
936 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_FORM_udata
);
939 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_MD5
);
940 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_FORM_data16
);
943 if (HasInlineSources
) {
944 LineSectionSize
+= MS
->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source
);
945 LineSectionSize
+= MS
->emitULEB128IntValue(StrForm
);
949 // file_names_count (ULEB128).
950 LineSectionSize
+= MS
->emitULEB128IntValue(P
.FileNames
.size());
952 // file_names (sequence of file name entries).
953 for (auto File
: P
.FileNames
) {
954 emitLineTableString(P
, File
.Name
, DebugStrPool
, DebugLineStrPool
);
955 LineSectionSize
+= MS
->emitULEB128IntValue(File
.DirIdx
);
958 StringRef(reinterpret_cast<const char *>(File
.Checksum
.data()),
959 File
.Checksum
.size()));
960 LineSectionSize
+= File
.Checksum
.size();
962 if (HasInlineSources
)
963 emitLineTableString(P
, File
.Source
, DebugStrPool
, DebugLineStrPool
);
967 void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue
&P
,
968 const DWARFFormValue
&String
,
969 OffsetsStringPool
&DebugStrPool
,
970 OffsetsStringPool
&DebugLineStrPool
) {
971 std::optional
<const char *> StringVal
= dwarf::toString(String
);
973 warn("Cann't read string from line table.");
977 switch (String
.getForm()) {
978 case dwarf::DW_FORM_string
: {
979 StringRef Str
= *StringVal
;
980 Asm
->OutStreamer
->emitBytes(Str
.data());
982 LineSectionSize
+= Str
.size() + 1;
984 case dwarf::DW_FORM_strp
:
985 case dwarf::DW_FORM_line_strp
: {
986 DwarfStringPoolEntryRef StringRef
=
987 String
.getForm() == dwarf::DW_FORM_strp
988 ? DebugStrPool
.getEntry(*StringVal
)
989 : DebugLineStrPool
.getEntry(*StringVal
);
991 emitIntOffset(StringRef
.getOffset(), P
.FormParams
.Format
, LineSectionSize
);
994 warn("Unsupported string form inside line table.");
999 void DwarfStreamer::emitLineTableProloguePayload(
1000 const DWARFDebugLine::Prologue
&P
, OffsetsStringPool
&DebugStrPool
,
1001 OffsetsStringPool
&DebugLineStrPool
) {
1002 // minimum_instruction_length (ubyte).
1003 MS
->emitInt8(P
.MinInstLength
);
1004 LineSectionSize
+= 1;
1005 if (P
.FormParams
.Version
>= 4) {
1006 // maximum_operations_per_instruction (ubyte).
1007 MS
->emitInt8(P
.MaxOpsPerInst
);
1008 LineSectionSize
+= 1;
1010 // default_is_stmt (ubyte).
1011 MS
->emitInt8(P
.DefaultIsStmt
);
1012 LineSectionSize
+= 1;
1013 // line_base (sbyte).
1014 MS
->emitInt8(P
.LineBase
);
1015 LineSectionSize
+= 1;
1016 // line_range (ubyte).
1017 MS
->emitInt8(P
.LineRange
);
1018 LineSectionSize
+= 1;
1019 // opcode_base (ubyte).
1020 MS
->emitInt8(P
.OpcodeBase
);
1021 LineSectionSize
+= 1;
1023 // standard_opcode_lengths (array of ubyte).
1024 for (auto Length
: P
.StandardOpcodeLengths
) {
1025 MS
->emitInt8(Length
);
1026 LineSectionSize
+= 1;
1029 if (P
.FormParams
.Version
< 5)
1030 emitLineTablePrologueV2IncludeAndFileTable(P
, DebugStrPool
,
1033 emitLineTablePrologueV5IncludeAndFileTable(P
, DebugStrPool
,
1037 void DwarfStreamer::emitLineTableRows(
1038 const DWARFDebugLine::LineTable
&LineTable
, MCSymbol
*LineEndSym
,
1039 unsigned AddressByteSize
) {
1041 MCDwarfLineTableParams Params
;
1042 Params
.DWARF2LineOpcodeBase
= LineTable
.Prologue
.OpcodeBase
;
1043 Params
.DWARF2LineBase
= LineTable
.Prologue
.LineBase
;
1044 Params
.DWARF2LineRange
= LineTable
.Prologue
.LineRange
;
1046 SmallString
<128> EncodingBuffer
;
1048 if (LineTable
.Rows
.empty()) {
1049 // We only have the dummy entry, dsymutil emits an entry with a 0
1050 // address in that case.
1051 MCDwarfLineAddr::encode(*MC
, Params
, std::numeric_limits
<int64_t>::max(), 0,
1053 MS
->emitBytes(EncodingBuffer
);
1054 LineSectionSize
+= EncodingBuffer
.size();
1055 MS
->emitLabel(LineEndSym
);
1059 // Line table state machine fields
1060 unsigned FileNum
= 1;
1061 unsigned LastLine
= 1;
1062 unsigned Column
= 0;
1063 unsigned Discriminator
= 0;
1064 unsigned IsStatement
= 1;
1066 uint64_t Address
= -1ULL;
1068 unsigned RowsSinceLastSequence
= 0;
1070 for (const DWARFDebugLine::Row
&Row
: LineTable
.Rows
) {
1071 int64_t AddressDelta
;
1072 if (Address
== -1ULL) {
1073 MS
->emitIntValue(dwarf::DW_LNS_extended_op
, 1);
1074 MS
->emitULEB128IntValue(AddressByteSize
+ 1);
1075 MS
->emitIntValue(dwarf::DW_LNE_set_address
, 1);
1076 MS
->emitIntValue(Row
.Address
.Address
, AddressByteSize
);
1078 2 + AddressByteSize
+ getULEB128Size(AddressByteSize
+ 1);
1082 (Row
.Address
.Address
- Address
) / LineTable
.Prologue
.MinInstLength
;
1085 // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
1086 // We should find a way to share this code, but the current compatibility
1087 // requirement with classic dsymutil makes it hard. Revisit that once this
1088 // requirement is dropped.
1090 if (FileNum
!= Row
.File
) {
1092 MS
->emitIntValue(dwarf::DW_LNS_set_file
, 1);
1093 MS
->emitULEB128IntValue(FileNum
);
1094 LineSectionSize
+= 1 + getULEB128Size(FileNum
);
1096 if (Column
!= Row
.Column
) {
1097 Column
= Row
.Column
;
1098 MS
->emitIntValue(dwarf::DW_LNS_set_column
, 1);
1099 MS
->emitULEB128IntValue(Column
);
1100 LineSectionSize
+= 1 + getULEB128Size(Column
);
1102 if (Discriminator
!= Row
.Discriminator
&&
1103 MS
->getContext().getDwarfVersion() >= 4) {
1104 Discriminator
= Row
.Discriminator
;
1105 unsigned Size
= getULEB128Size(Discriminator
);
1106 MS
->emitIntValue(dwarf::DW_LNS_extended_op
, 1);
1107 MS
->emitULEB128IntValue(Size
+ 1);
1108 MS
->emitIntValue(dwarf::DW_LNE_set_discriminator
, 1);
1109 MS
->emitULEB128IntValue(Discriminator
);
1110 LineSectionSize
+= /* extended op */ 1 + getULEB128Size(Size
+ 1) +
1111 /* discriminator */ 1 + Size
;
1115 if (Isa
!= Row
.Isa
) {
1117 MS
->emitIntValue(dwarf::DW_LNS_set_isa
, 1);
1118 MS
->emitULEB128IntValue(Isa
);
1119 LineSectionSize
+= 1 + getULEB128Size(Isa
);
1121 if (IsStatement
!= Row
.IsStmt
) {
1122 IsStatement
= Row
.IsStmt
;
1123 MS
->emitIntValue(dwarf::DW_LNS_negate_stmt
, 1);
1124 LineSectionSize
+= 1;
1126 if (Row
.BasicBlock
) {
1127 MS
->emitIntValue(dwarf::DW_LNS_set_basic_block
, 1);
1128 LineSectionSize
+= 1;
1131 if (Row
.PrologueEnd
) {
1132 MS
->emitIntValue(dwarf::DW_LNS_set_prologue_end
, 1);
1133 LineSectionSize
+= 1;
1136 if (Row
.EpilogueBegin
) {
1137 MS
->emitIntValue(dwarf::DW_LNS_set_epilogue_begin
, 1);
1138 LineSectionSize
+= 1;
1141 int64_t LineDelta
= int64_t(Row
.Line
) - LastLine
;
1142 if (!Row
.EndSequence
) {
1143 MCDwarfLineAddr::encode(*MC
, Params
, LineDelta
, AddressDelta
,
1145 MS
->emitBytes(EncodingBuffer
);
1146 LineSectionSize
+= EncodingBuffer
.size();
1147 EncodingBuffer
.resize(0);
1148 Address
= Row
.Address
.Address
;
1149 LastLine
= Row
.Line
;
1150 RowsSinceLastSequence
++;
1153 MS
->emitIntValue(dwarf::DW_LNS_advance_line
, 1);
1154 MS
->emitSLEB128IntValue(LineDelta
);
1155 LineSectionSize
+= 1 + getSLEB128Size(LineDelta
);
1158 MS
->emitIntValue(dwarf::DW_LNS_advance_pc
, 1);
1159 MS
->emitULEB128IntValue(AddressDelta
);
1160 LineSectionSize
+= 1 + getULEB128Size(AddressDelta
);
1162 MCDwarfLineAddr::encode(*MC
, Params
, std::numeric_limits
<int64_t>::max(),
1164 MS
->emitBytes(EncodingBuffer
);
1165 LineSectionSize
+= EncodingBuffer
.size();
1166 EncodingBuffer
.resize(0);
1168 LastLine
= FileNum
= IsStatement
= 1;
1169 RowsSinceLastSequence
= Column
= Discriminator
= Isa
= 0;
1173 if (RowsSinceLastSequence
) {
1174 MCDwarfLineAddr::encode(*MC
, Params
, std::numeric_limits
<int64_t>::max(), 0,
1176 MS
->emitBytes(EncodingBuffer
);
1177 LineSectionSize
+= EncodingBuffer
.size();
1178 EncodingBuffer
.resize(0);
1181 MS
->emitLabel(LineEndSym
);
1184 void DwarfStreamer::emitIntOffset(uint64_t Offset
, dwarf::DwarfFormat Format
,
1185 uint64_t &SectionSize
) {
1186 uint8_t Size
= dwarf::getDwarfOffsetByteSize(Format
);
1187 MS
->emitIntValue(Offset
, Size
);
1188 SectionSize
+= Size
;
1191 void DwarfStreamer::emitLabelDifference(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1192 dwarf::DwarfFormat Format
,
1193 uint64_t &SectionSize
) {
1194 uint8_t Size
= dwarf::getDwarfOffsetByteSize(Format
);
1195 Asm
->emitLabelDifference(Hi
, Lo
, Size
);
1196 SectionSize
+= Size
;
1199 /// Emit the pubnames or pubtypes section contribution for \p
1200 /// Unit into \p Sec. The data is provided in \p Names.
1201 void DwarfStreamer::emitPubSectionForUnit(
1202 MCSection
*Sec
, StringRef SecName
, const CompileUnit
&Unit
,
1203 const std::vector
<CompileUnit::AccelInfo
> &Names
) {
1207 // Start the dwarf pubnames section.
1208 Asm
->OutStreamer
->switchSection(Sec
);
1209 MCSymbol
*BeginLabel
= Asm
->createTempSymbol("pub" + SecName
+ "_begin");
1210 MCSymbol
*EndLabel
= Asm
->createTempSymbol("pub" + SecName
+ "_end");
1212 bool HeaderEmitted
= false;
1213 // Emit the pubnames for this compilation unit.
1214 for (const auto &Name
: Names
) {
1215 if (Name
.SkipPubSection
)
1218 if (!HeaderEmitted
) {
1220 Asm
->emitLabelDifference(EndLabel
, BeginLabel
, 4); // Length
1221 Asm
->OutStreamer
->emitLabel(BeginLabel
);
1222 Asm
->emitInt16(dwarf::DW_PUBNAMES_VERSION
); // Version
1223 Asm
->emitInt32(Unit
.getStartOffset()); // Unit offset
1224 Asm
->emitInt32(Unit
.getNextUnitOffset() - Unit
.getStartOffset()); // Size
1225 HeaderEmitted
= true;
1227 Asm
->emitInt32(Name
.Die
->getOffset());
1229 // Emit the string itself.
1230 Asm
->OutStreamer
->emitBytes(Name
.Name
.getString());
1231 // Emit a null terminator.
1237 Asm
->emitInt32(0); // End marker.
1238 Asm
->OutStreamer
->emitLabel(EndLabel
);
1241 /// Emit .debug_pubnames for \p Unit.
1242 void DwarfStreamer::emitPubNamesForUnit(const CompileUnit
&Unit
) {
1243 emitPubSectionForUnit(MC
->getObjectFileInfo()->getDwarfPubNamesSection(),
1244 "names", Unit
, Unit
.getPubnames());
1247 /// Emit .debug_pubtypes for \p Unit.
1248 void DwarfStreamer::emitPubTypesForUnit(const CompileUnit
&Unit
) {
1249 emitPubSectionForUnit(MC
->getObjectFileInfo()->getDwarfPubTypesSection(),
1250 "types", Unit
, Unit
.getPubtypes());
1253 /// Emit a CIE into the debug_frame section.
1254 void DwarfStreamer::emitCIE(StringRef CIEBytes
) {
1255 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfFrameSection());
1257 MS
->emitBytes(CIEBytes
);
1258 FrameSectionSize
+= CIEBytes
.size();
1261 /// Emit a FDE into the debug_frame section. \p FDEBytes
1262 /// contains the FDE data without the length, CIE offset and address
1263 /// which will be replaced with the parameter values.
1264 void DwarfStreamer::emitFDE(uint32_t CIEOffset
, uint32_t AddrSize
,
1265 uint64_t Address
, StringRef FDEBytes
) {
1266 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfFrameSection());
1268 MS
->emitIntValue(FDEBytes
.size() + 4 + AddrSize
, 4);
1269 MS
->emitIntValue(CIEOffset
, 4);
1270 MS
->emitIntValue(Address
, AddrSize
);
1271 MS
->emitBytes(FDEBytes
);
1272 FrameSectionSize
+= FDEBytes
.size() + 8 + AddrSize
;
1275 void DwarfStreamer::emitMacroTables(DWARFContext
*Context
,
1276 const Offset2UnitMap
&UnitMacroMap
,
1277 OffsetsStringPool
&StringPool
) {
1278 assert(Context
!= nullptr && "Empty DWARF context");
1280 // Check for .debug_macinfo table.
1281 if (const DWARFDebugMacro
*Table
= Context
->getDebugMacinfo()) {
1282 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfMacinfoSection());
1283 emitMacroTableImpl(Table
, UnitMacroMap
, StringPool
, MacInfoSectionSize
);
1286 // Check for .debug_macro table.
1287 if (const DWARFDebugMacro
*Table
= Context
->getDebugMacro()) {
1288 MS
->switchSection(MC
->getObjectFileInfo()->getDwarfMacroSection());
1289 emitMacroTableImpl(Table
, UnitMacroMap
, StringPool
, MacroSectionSize
);
1293 void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro
*MacroTable
,
1294 const Offset2UnitMap
&UnitMacroMap
,
1295 OffsetsStringPool
&StringPool
,
1296 uint64_t &OutOffset
) {
1297 bool DefAttributeIsReported
= false;
1298 bool UndefAttributeIsReported
= false;
1299 bool ImportAttributeIsReported
= false;
1300 for (const DWARFDebugMacro::MacroList
&List
: MacroTable
->MacroLists
) {
1301 Offset2UnitMap::const_iterator UnitIt
= UnitMacroMap
.find(List
.Offset
);
1302 if (UnitIt
== UnitMacroMap
.end()) {
1304 "couldn`t find compile unit for the macro table with offset = {0:x}",
1309 // Skip macro table if the unit was not cloned.
1310 DIE
*OutputUnitDIE
= UnitIt
->second
->getOutputUnitDIE();
1311 if (OutputUnitDIE
== nullptr)
1314 // Update macro attribute of cloned compile unit with the proper offset to
1316 bool hasDWARFv5Header
= false;
1317 for (auto &V
: OutputUnitDIE
->values()) {
1318 if (V
.getAttribute() == dwarf::DW_AT_macro_info
) {
1319 V
= DIEValue(V
.getAttribute(), V
.getForm(), DIEInteger(OutOffset
));
1321 } else if (V
.getAttribute() == dwarf::DW_AT_macros
) {
1322 hasDWARFv5Header
= true;
1323 V
= DIEValue(V
.getAttribute(), V
.getForm(), DIEInteger(OutOffset
));
1328 // Write DWARFv5 header.
1329 if (hasDWARFv5Header
) {
1330 // Write header version.
1331 MS
->emitIntValue(List
.Header
.Version
, sizeof(List
.Header
.Version
));
1332 OutOffset
+= sizeof(List
.Header
.Version
);
1334 uint8_t Flags
= List
.Header
.Flags
;
1336 // Check for OPCODE_OPERANDS_TABLE.
1338 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
) {
1339 Flags
&= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
;
1340 warn("opcode_operands_table is not supported yet.");
1343 // Check for DEBUG_LINE_OFFSET.
1344 std::optional
<uint64_t> StmtListOffset
;
1345 if (Flags
& DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
) {
1346 // Get offset to the line table from the cloned compile unit.
1347 for (auto &V
: OutputUnitDIE
->values()) {
1348 if (V
.getAttribute() == dwarf::DW_AT_stmt_list
) {
1349 StmtListOffset
= V
.getDIEInteger().getValue();
1354 if (!StmtListOffset
) {
1355 Flags
&= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
;
1356 warn("couldn`t find line table for macro table.");
1361 MS
->emitIntValue(Flags
, sizeof(Flags
));
1362 OutOffset
+= sizeof(Flags
);
1364 // Write offset to line table.
1365 if (StmtListOffset
) {
1366 MS
->emitIntValue(*StmtListOffset
, List
.Header
.getOffsetByteSize());
1367 OutOffset
+= List
.Header
.getOffsetByteSize();
1371 // Write macro entries.
1372 for (const DWARFDebugMacro::Entry
&MacroEntry
: List
.Macros
) {
1373 if (MacroEntry
.Type
== 0) {
1374 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Type
);
1378 uint8_t MacroType
= MacroEntry
.Type
;
1379 switch (MacroType
) {
1381 bool HasVendorSpecificExtension
=
1382 (!hasDWARFv5Header
&& MacroType
== dwarf::DW_MACINFO_vendor_ext
) ||
1383 (hasDWARFv5Header
&& (MacroType
>= dwarf::DW_MACRO_lo_user
&&
1384 MacroType
<= dwarf::DW_MACRO_hi_user
));
1386 if (HasVendorSpecificExtension
) {
1387 // Write macinfo type.
1388 MS
->emitIntValue(MacroType
, 1);
1391 // Write vendor extension constant.
1392 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.ExtConstant
);
1394 // Write vendor extension string.
1395 StringRef String
= MacroEntry
.ExtStr
;
1396 MS
->emitBytes(String
);
1397 MS
->emitIntValue(0, 1);
1398 OutOffset
+= String
.size() + 1;
1400 warn("unknown macro type. skip.");
1402 // debug_macro and debug_macinfo share some common encodings.
1403 // DW_MACRO_define == DW_MACINFO_define
1404 // DW_MACRO_undef == DW_MACINFO_undef
1405 // DW_MACRO_start_file == DW_MACINFO_start_file
1406 // DW_MACRO_end_file == DW_MACINFO_end_file
1407 // For readibility/uniformity we are using DW_MACRO_*.
1408 case dwarf::DW_MACRO_define
:
1409 case dwarf::DW_MACRO_undef
: {
1410 // Write macinfo type.
1411 MS
->emitIntValue(MacroType
, 1);
1414 // Write source line.
1415 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Line
);
1417 // Write macro string.
1418 StringRef String
= MacroEntry
.MacroStr
;
1419 MS
->emitBytes(String
);
1420 MS
->emitIntValue(0, 1);
1421 OutOffset
+= String
.size() + 1;
1423 case dwarf::DW_MACRO_define_strp
:
1424 case dwarf::DW_MACRO_undef_strp
:
1425 case dwarf::DW_MACRO_define_strx
:
1426 case dwarf::DW_MACRO_undef_strx
: {
1427 assert(UnitIt
->second
->getOrigUnit().getVersion() >= 5);
1429 // DW_MACRO_*_strx forms are not supported currently.
1430 // Convert to *_strp.
1431 switch (MacroType
) {
1432 case dwarf::DW_MACRO_define_strx
: {
1433 MacroType
= dwarf::DW_MACRO_define_strp
;
1434 if (!DefAttributeIsReported
) {
1435 warn("DW_MACRO_define_strx unsupported yet. Convert to "
1436 "DW_MACRO_define_strp.");
1437 DefAttributeIsReported
= true;
1440 case dwarf::DW_MACRO_undef_strx
: {
1441 MacroType
= dwarf::DW_MACRO_undef_strp
;
1442 if (!UndefAttributeIsReported
) {
1443 warn("DW_MACRO_undef_strx unsupported yet. Convert to "
1444 "DW_MACRO_undef_strp.");
1445 UndefAttributeIsReported
= true;
1453 // Write macinfo type.
1454 MS
->emitIntValue(MacroType
, 1);
1457 // Write source line.
1458 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Line
);
1460 // Write macro string.
1461 DwarfStringPoolEntryRef EntryRef
=
1462 StringPool
.getEntry(MacroEntry
.MacroStr
);
1463 MS
->emitIntValue(EntryRef
.getOffset(), List
.Header
.getOffsetByteSize());
1464 OutOffset
+= List
.Header
.getOffsetByteSize();
1467 case dwarf::DW_MACRO_start_file
: {
1468 // Write macinfo type.
1469 MS
->emitIntValue(MacroType
, 1);
1471 // Write source line.
1472 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.Line
);
1473 // Write source file id.
1474 OutOffset
+= MS
->emitULEB128IntValue(MacroEntry
.File
);
1476 case dwarf::DW_MACRO_end_file
: {
1477 // Write macinfo type.
1478 MS
->emitIntValue(MacroType
, 1);
1481 case dwarf::DW_MACRO_import
:
1482 case dwarf::DW_MACRO_import_sup
: {
1483 if (!ImportAttributeIsReported
) {
1484 warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
1486 ImportAttributeIsReported
= true;