30using namespace dwarf_linker;
31using namespace dwarf_linker::classic;
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);
47 std::string TripleName;
61 "no register info for target %s",
68 "no asm info for target %s", TripleName.c_str());
73 "no subtarget info for target %s",
76 MC.reset(
new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(),
nullptr,
77 nullptr,
true, Swift5ReflectionSegmentName));
79 MC->setObjectFileInfo(MOFI.get());
84 "no asm backend for target %s",
90 "no instr info info for target %s",
96 "no code emitter for target %s",
99 switch (OutFileType) {
104 *MC, std::make_unique<formatted_raw_ostream>(OutFile),
true,
true, MIP,
105 std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
111 TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
121 "no object streamer for target %s",
129 "no target machine for target %s",
132 Asm.reset(TheTarget->
createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
135 "no asm printer for target %s",
137 Asm->setDwarfUsesRelocationsAcrossSections(
false);
139 RangesSectionSize = 0;
140 RngListsSectionSize = 0;
142 LocListsSectionSize = 0;
144 FrameSectionSize = 0;
145 DebugInfoSectionSize = 0;
146 MacInfoSectionSize = 0;
147 MacroSectionSize = 0;
156 MC->setDwarfVersion(DwarfVersion);
176 unsigned DwarfVersion) {
180 Unit.setLabelBegin(Asm->createTempSymbol(
"cu_begin"));
181 Asm->OutStreamer->emitLabel(Unit.getLabelBegin());
186 Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
187 Asm->emitInt16(DwarfVersion);
189 if (DwarfVersion >= 5) {
190 Asm->emitInt8(dwarf::DW_UT_compile);
191 Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
195 DebugInfoSectionSize += 12;
200 Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
201 DebugInfoSectionSize += 11;
205 EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
211 const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
212 unsigned DwarfVersion) {
214 MC->setDwarfVersion(DwarfVersion);
215 Asm->emitDwarfAbbrevs(Abbrevs);
221 Asm->emitDwarfDIE(Die);
222 DebugInfoSectionSize += Die.
getSize();
231 if (
MCSection *Section = getMCSection(SecKind)) {
241 return MC->getObjectFileInfo()->getDwarfInfoSection();
243 return MC->getObjectFileInfo()->getDwarfLineSection();
245 return MC->getObjectFileInfo()->getDwarfFrameSection();
247 return MC->getObjectFileInfo()->getDwarfRangesSection();
249 return MC->getObjectFileInfo()->getDwarfRnglistsSection();
251 return MC->getObjectFileInfo()->getDwarfLocSection();
253 return MC->getObjectFileInfo()->getDwarfLoclistsSection();
255 return MC->getObjectFileInfo()->getDwarfARangesSection();
257 return MC->getObjectFileInfo()->getDwarfAbbrevSection();
259 return MC->getObjectFileInfo()->getDwarfMacinfoSection();
261 return MC->getObjectFileInfo()->getDwarfMacroSection();
263 return MC->getObjectFileInfo()->getDwarfAddrSection();
265 return MC->getObjectFileInfo()->getDwarfStrSection();
267 return MC->getObjectFileInfo()->getDwarfLineStrSection();
269 return MC->getObjectFileInfo()->getDwarfStrOffSection();
271 return MC->getObjectFileInfo()->getDwarfPubNamesSection();
273 return MC->getObjectFileInfo()->getDwarfPubTypesSection();
275 return MC->getObjectFileInfo()->getDwarfDebugNamesSection();
277 return MC->getObjectFileInfo()->getDwarfAccelNamesSection();
279 return MC->getObjectFileInfo()->getDwarfAccelNamespaceSection();
281 return MC->getObjectFileInfo()->getDwarfAccelObjCSection();
283 return MC->getObjectFileInfo()->getDwarfAccelTypesSection();
294 Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
296 for (
auto Entry : Entries) {
298 Asm->OutStreamer->emitBytes(Entry.getString());
309 if (TargetDWARFVersion < 5 || StringOffsets.
empty())
312 Asm->OutStreamer->switchSection(MOFI->getDwarfStrOffSection());
314 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Bdebugstroff");
315 MCSymbol *EndLabel = Asm->createTempSymbol(
"Edebugstroff");
318 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
319 Asm->OutStreamer->emitLabel(BeginLabel);
320 StrOffsetSectionSize +=
sizeof(
uint32_t);
324 StrOffsetSectionSize +=
sizeof(
uint16_t);
328 StrOffsetSectionSize +=
sizeof(
uint16_t);
330 for (
auto Off : StringOffsets) {
331 Asm->OutStreamer->emitInt32(Off);
332 StrOffsetSectionSize +=
sizeof(
uint32_t);
334 Asm->OutStreamer->emitLabel(EndLabel);
339 Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection());
341 for (
auto Entry : Entries) {
343 Asm->OutStreamer->emitBytes(Entry.getString());
350 if (EmittedUnits.empty())
354 std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;
357 for (
auto &
CU : EmittedUnits) {
358 CompUnits.push_back(
CU.LabelBegin);
360 UniqueIdToCuMap[
CU.ID] = Id++;
363 Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
370 Asm.get(), Table, CompUnits,
372 -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
373 if (UniqueIdToCuMap.size() > 1)
374 return {{UniqueIdToCuMap[Entry.getUnitID()],
375 {dwarf::DW_IDX_compile_unit, Form}}};
382 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
383 auto *SectionBegin = Asm->createTempSymbol(
"namespac_begin");
384 Asm->OutStreamer->emitLabel(SectionBegin);
390 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
391 auto *SectionBegin = Asm->createTempSymbol(
"names_begin");
392 Asm->OutStreamer->emitLabel(SectionBegin);
398 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
399 auto *SectionBegin = Asm->createTempSymbol(
"objc_begin");
400 Asm->OutStreamer->emitLabel(SectionBegin);
406 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
407 auto *SectionBegin = Asm->createTempSymbol(
"types_begin");
408 Asm->OutStreamer->emitLabel(SectionBegin);
414 MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
424 MOFI->getSwift5ReflectionSection(ReflSectionKind);
425 if (ReflectionSection ==
nullptr)
434 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
437 MS->
switchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
440 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Barange");
441 MCSymbol *EndLabel = Asm->createTempSymbol(
"Earange");
443 unsigned HeaderSize =
450 unsigned TupleSize = AddressSize * 2;
453 Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
454 Asm->OutStreamer->emitLabel(BeginLabel);
456 Asm->emitInt32(Unit.getStartOffset());
457 Asm->emitInt8(AddressSize);
460 Asm->OutStreamer->emitFill(Padding, 0x0);
465 MS->
emitIntValue(Range.end() - Range.start(), AddressSize);
469 Asm->OutStreamer->emitIntValue(0, AddressSize);
470 Asm->OutStreamer->emitIntValue(0, AddressSize);
471 Asm->OutStreamer->emitLabel(EndLabel);
474void DwarfStreamer::emitDwarfDebugRangesTableFragment(
477 Patch.
set(RangesSectionSize);
480 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
481 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
485 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
486 BaseAddress = *LowPC;
489 MS->
emitIntValue(Range.start() - BaseAddress, AddressSize);
490 MS->
emitIntValue(Range.end() - BaseAddress, AddressSize);
492 RangesSectionSize += AddressSize;
493 RangesSectionSize += AddressSize;
500 RangesSectionSize += AddressSize;
501 RangesSectionSize += AddressSize;
506 if (Unit.getOrigUnit().getVersion() < 5)
510 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
512 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Brnglists");
513 MCSymbol *EndLabel = Asm->createTempSymbol(
"Ernglists");
514 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
517 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
518 Asm->OutStreamer->emitLabel(BeginLabel);
519 RngListsSectionSize +=
sizeof(
uint32_t);
523 RngListsSectionSize +=
sizeof(
uint16_t);
527 RngListsSectionSize++;
531 RngListsSectionSize++;
535 RngListsSectionSize +=
sizeof(
uint32_t);
543 if (Unit.getOrigUnit().getVersion() < 5) {
544 emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
548 emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool);
553 if (Unit.getOrigUnit().getVersion() < 5)
557 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
559 if (EndLabel !=
nullptr)
560 Asm->OutStreamer->emitLabel(EndLabel);
563void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
566 Patch.
set(RngListsSectionSize);
569 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
570 std::optional<uint64_t> BaseAddress;
575 BaseAddress = Range.start();
578 MS->
emitInt8(dwarf::DW_RLE_base_addressx);
579 RngListsSectionSize += 1;
580 RngListsSectionSize +=
585 MS->
emitInt8(dwarf::DW_RLE_offset_pair);
586 RngListsSectionSize += 1;
589 RngListsSectionSize +=
597 MS->
emitInt8(dwarf::DW_RLE_end_of_list);
598 RngListsSectionSize += 1;
603 if (Unit.getOrigUnit().getVersion() < 5)
607 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
609 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Bloclists");
610 MCSymbol *EndLabel = Asm->createTempSymbol(
"Eloclists");
611 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
614 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
615 Asm->OutStreamer->emitLabel(BeginLabel);
616 LocListsSectionSize +=
sizeof(
uint32_t);
620 LocListsSectionSize +=
sizeof(
uint16_t);
624 LocListsSectionSize++;
628 LocListsSectionSize++;
632 LocListsSectionSize +=
sizeof(
uint32_t);
642 if (Unit.getOrigUnit().getVersion() < 5) {
643 emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
647 emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch,
654 if (Unit.getOrigUnit().getVersion() < 5)
658 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
660 if (EndLabel !=
nullptr)
661 Asm->OutStreamer->emitLabel(EndLabel);
665void DwarfStreamer::emitDwarfDebugLocTableFragment(
669 Patch.
set(LocSectionSize);
672 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
673 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
677 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
678 BaseAddress = *LowPC;
681 LinkedLocationExpression) {
682 if (LocExpression.Range) {
683 MS->
emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize);
684 MS->
emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize);
686 LocSectionSize += AddressSize;
687 LocSectionSize += AddressSize;
690 Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2);
692 (
const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
693 LocSectionSize += LocExpression.Expr.size() + 2;
700 LocSectionSize += AddressSize;
701 LocSectionSize += AddressSize;
708 MS->
switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
710 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Bdebugaddr");
711 MCSymbol *EndLabel = Asm->createTempSymbol(
"Edebugaddr");
712 unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize();
715 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
716 Asm->OutStreamer->emitLabel(BeginLabel);
717 AddrSectionSize +=
sizeof(
uint32_t);
721 AddrSectionSize += 2;
724 Asm->emitInt8(AddrSize);
725 AddrSectionSize += 1;
729 AddrSectionSize += 1;
737 Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection());
738 for (
auto Addr : Addrs) {
739 Asm->OutStreamer->emitIntValue(
Addr, AddrSize);
740 AddrSectionSize += AddrSize;
749 MS->
switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
751 if (EndLabel !=
nullptr)
752 Asm->OutStreamer->emitLabel(EndLabel);
756void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
760 Patch.
set(LocListsSectionSize);
763 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
764 std::optional<uint64_t> BaseAddress;
767 LinkedLocationExpression) {
768 if (LocExpression.Range) {
772 BaseAddress = LocExpression.Range->LowPC;
775 MS->
emitInt8(dwarf::DW_LLE_base_addressx);
776 LocListsSectionSize += 1;
777 LocListsSectionSize +=
782 MS->
emitInt8(dwarf::DW_LLE_offset_pair);
783 LocListsSectionSize += 1;
786 LocListsSectionSize +=
790 LocListsSectionSize +=
794 MS->
emitInt8(dwarf::DW_LLE_default_location);
795 LocListsSectionSize += 1;
800 (
const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
801 LocListsSectionSize += LocExpression.Expr.size();
805 MS->
emitInt8(dwarf::DW_LLE_end_of_list);
806 LocListsSectionSize += 1;
813 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLineSection());
815 MCSymbol *LineStartSym = MC->createTempSymbol();
816 MCSymbol *LineEndSym = MC->createTempSymbol();
821 LineSectionSize += 4;
823 emitLabelDifference(LineEndSym, LineStartSym,
825 Asm->OutStreamer->emitLabel(LineStartSym);
828 emitLineTablePrologue(LineTable.
Prologue, DebugStrPool, DebugLineStrPool);
831 emitLineTableRows(LineTable, LineEndSym,
832 Unit.getOrigUnit().getAddressByteSize());
838 MCSymbol *PrologueStartSym = MC->createTempSymbol();
839 MCSymbol *PrologueEndSym = MC->createTempSymbol();
843 LineSectionSize += 2;
844 if (
P.getVersion() == 5) {
847 LineSectionSize += 1;
851 LineSectionSize += 1;
855 emitLabelDifference(PrologueEndSym, PrologueStartSym,
P.FormParams.Format,
858 Asm->OutStreamer->emitLabel(PrologueStartSym);
859 emitLineTableProloguePayload(
P, DebugStrPool, DebugLineStrPool);
860 Asm->OutStreamer->emitLabel(PrologueEndSym);
863void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
868 emitLineTableString(
P,
Include, DebugStrPool, DebugLineStrPool);
871 LineSectionSize += 1;
877 emitLineTableString(
P, File.Name, DebugStrPool, DebugLineStrPool);
890 LineSectionSize += 1;
893void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
896 if (
P.IncludeDirectories.empty()) {
899 LineSectionSize += 1;
903 LineSectionSize += 1;
914 for (
auto Include :
P.IncludeDirectories)
915 emitLineTableString(
P,
Include, DebugStrPool, DebugLineStrPool);
917 bool HasChecksums =
P.ContentTypes.HasMD5;
918 bool HasInlineSources =
P.ContentTypes.HasSource;
920 if (
P.FileNames.empty()) {
923 LineSectionSize += 1;
926 MS->
emitInt8(2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0));
927 LineSectionSize += 1;
930 auto StrForm =
P.FileNames[0].Name.getForm();
942 if (HasInlineSources) {
952 for (
auto File :
P.FileNames) {
953 emitLineTableString(
P,
File.Name, DebugStrPool, DebugLineStrPool);
955 LineSectionSize += 1;
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);
973 warn(
"Cann't read string from line table.");
977 switch (
String.getForm()) {
978 case dwarf::DW_FORM_string: {
980 Asm->OutStreamer->emitBytes(Str.data());
982 LineSectionSize += Str.size() + 1;
984 case dwarf::DW_FORM_strp:
985 case dwarf::DW_FORM_line_strp: {
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.");
999void DwarfStreamer::emitLineTableProloguePayload(
1004 LineSectionSize += 1;
1005 if (
P.FormParams.Version >= 4) {
1008 LineSectionSize += 1;
1012 LineSectionSize += 1;
1015 LineSectionSize += 1;
1018 LineSectionSize += 1;
1021 LineSectionSize += 1;
1024 for (
auto Length :
P.StandardOpcodeLengths) {
1026 LineSectionSize += 1;
1029 if (
P.FormParams.Version < 5)
1030 emitLineTablePrologueV2IncludeAndFileTable(
P, DebugStrPool,
1033 emitLineTablePrologueV5IncludeAndFileTable(
P, DebugStrPool,
1037void DwarfStreamer::emitLineTableRows(
1039 unsigned AddressByteSize) {
1048 if (LineTable.
Rows.empty()) {
1054 LineSectionSize += EncodingBuffer.
size();
1060 unsigned FileNum = 1;
1061 unsigned LastLine = 1;
1062 unsigned Column = 0;
1063 unsigned IsStatement = 1;
1067 unsigned RowsSinceLastSequence = 0;
1075 MS->
emitIntValue(Row.Address.Address, AddressByteSize);
1089 if (FileNum != Row.File) {
1095 if (Column != Row.Column) {
1096 Column = Row.Column;
1105 if (Isa != Row.Isa) {
1111 if (IsStatement != Row.IsStmt) {
1112 IsStatement = Row.IsStmt;
1114 LineSectionSize += 1;
1116 if (Row.BasicBlock) {
1118 LineSectionSize += 1;
1121 if (Row.PrologueEnd) {
1123 LineSectionSize += 1;
1126 if (Row.EpilogueBegin) {
1128 LineSectionSize += 1;
1131 int64_t LineDelta = int64_t(Row.Line) - LastLine;
1132 if (!Row.EndSequence) {
1136 LineSectionSize += EncodingBuffer.
size();
1137 EncodingBuffer.
resize(0);
1138 Address = Row.Address.Address;
1139 LastLine = Row.Line;
1140 RowsSinceLastSequence++;
1155 LineSectionSize += EncodingBuffer.
size();
1156 EncodingBuffer.
resize(0);
1158 LastLine = FileNum = IsStatement = 1;
1159 RowsSinceLastSequence = Column = Isa = 0;
1163 if (RowsSinceLastSequence) {
1167 LineSectionSize += EncodingBuffer.
size();
1168 EncodingBuffer.
resize(0);
1185 Asm->emitLabelDifference(
Hi,
Lo,
Size);
1191void DwarfStreamer::emitPubSectionForUnit(
1193 const std::vector<CompileUnit::AccelInfo> &Names) {
1198 Asm->OutStreamer->switchSection(Sec);
1199 MCSymbol *BeginLabel = Asm->createTempSymbol(
"pub" + SecName +
"_begin");
1200 MCSymbol *EndLabel = Asm->createTempSymbol(
"pub" + SecName +
"_end");
1202 bool HeaderEmitted =
false;
1204 for (
const auto &
Name : Names) {
1205 if (
Name.SkipPubSection)
1208 if (!HeaderEmitted) {
1210 Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
1211 Asm->OutStreamer->emitLabel(BeginLabel);
1213 Asm->emitInt32(Unit.getStartOffset());
1214 Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset());
1215 HeaderEmitted =
true;
1217 Asm->emitInt32(
Name.Die->getOffset());
1220 Asm->OutStreamer->emitBytes(
Name.Name.getString());
1228 Asm->OutStreamer->emitLabel(EndLabel);
1233 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
1234 "names", Unit, Unit.getPubnames());
1239 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
1240 "types", Unit, Unit.getPubtypes());
1245 MS->
switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1248 FrameSectionSize += CIEBytes.
size();
1256 MS->
switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1262 FrameSectionSize += FDEBytes.
size() + 8 + AddrSize;
1272 MS->
switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection());
1273 emitMacroTableImpl(Table, UnitMacroMap,
StringPool, MacInfoSectionSize);
1278 MS->
switchSection(MC->getObjectFileInfo()->getDwarfMacroSection());
1279 emitMacroTableImpl(Table, UnitMacroMap,
StringPool, MacroSectionSize);
1283void DwarfStreamer::emitMacroTableImpl(
const DWARFDebugMacro *MacroTable,
1287 bool DefAttributeIsReported =
false;
1288 bool UndefAttributeIsReported =
false;
1289 bool ImportAttributeIsReported =
false;
1290 for (
const DWARFDebugMacro::MacroList &
List : MacroTable->MacroLists) {
1292 if (UnitIt == UnitMacroMap.
end()) {
1294 "couldn`t find compile unit for the macro table with offset = {0:x}",
1300 DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE();
1301 if (OutputUnitDIE ==
nullptr)
1306 bool hasDWARFv5Header =
false;
1307 for (
auto &V : OutputUnitDIE->
values()) {
1308 if (V.getAttribute() == dwarf::DW_AT_macro_info) {
1311 }
else if (V.getAttribute() == dwarf::DW_AT_macros) {
1312 hasDWARFv5Header =
true;
1319 if (hasDWARFv5Header) {
1322 OutOffset +=
sizeof(
List.Header.Version);
1328 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
1330 warn(
"opcode_operands_table is not supported yet.");
1334 std::optional<uint64_t> StmtListOffset;
1335 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
1337 for (
auto &V : OutputUnitDIE->
values()) {
1338 if (
V.getAttribute() == dwarf::DW_AT_stmt_list) {
1339 StmtListOffset =
V.getDIEInteger().getValue();
1344 if (!StmtListOffset) {
1346 warn(
"couldn`t find line table for macro table.");
1352 OutOffset +=
sizeof(
Flags);
1355 if (StmtListOffset) {
1357 OutOffset +=
List.Header.getOffsetByteSize();
1362 for (
const DWARFDebugMacro::Entry &MacroEntry :
List.Macros) {
1363 if (MacroEntry.Type == 0) {
1368 uint8_t MacroType = MacroEntry.Type;
1369 switch (MacroType) {
1371 bool HasVendorSpecificExtension =
1376 if (HasVendorSpecificExtension) {
1388 OutOffset +=
String.size() + 1;
1390 warn(
"unknown macro type. skip.");
1398 case dwarf::DW_MACRO_define:
1399 case dwarf::DW_MACRO_undef: {
1411 OutOffset +=
String.size() + 1;
1413 case dwarf::DW_MACRO_define_strp:
1414 case dwarf::DW_MACRO_undef_strp:
1415 case dwarf::DW_MACRO_define_strx:
1416 case dwarf::DW_MACRO_undef_strx: {
1417 assert(UnitIt->second->getOrigUnit().getVersion() >= 5);
1421 switch (MacroType) {
1422 case dwarf::DW_MACRO_define_strx: {
1423 MacroType = dwarf::DW_MACRO_define_strp;
1424 if (!DefAttributeIsReported) {
1425 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1426 "DW_MACRO_define_strp.");
1427 DefAttributeIsReported =
true;
1430 case dwarf::DW_MACRO_undef_strx: {
1431 MacroType = dwarf::DW_MACRO_undef_strp;
1432 if (!UndefAttributeIsReported) {
1433 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1434 "DW_MACRO_undef_strp.");
1435 UndefAttributeIsReported =
true;
1454 OutOffset +=
List.Header.getOffsetByteSize();
1457 case dwarf::DW_MACRO_start_file: {
1466 case dwarf::DW_MACRO_end_file: {
1471 case dwarf::DW_MACRO_import:
1472 case dwarf::DW_MACRO_import_sup: {
1473 if (!ImportAttributeIsReported) {
1474 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
1476 ImportAttributeIsReported =
true;
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
A class that represents an address range.
The AddressRanges class helps normalize address range collections.
static dwarf::Form BestForm(bool IsSigned, uint64_t Int)
Choose the best form for integer.
A structured debug information entry.
The Data class implementation for DWARF v5 accelerator table.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
iterator find(const_arg_type_t< KeyT > Val)
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
uint64_t getOffset() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
std::unique_ptr< MCObjectWriter > createObjectWriter(raw_pwrite_stream &OS) const
Create a new MCObjectWriter instance for use by the assembler backend to emit the final object file.
Context object for machine code objects.
static void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
void emitInt16(uint64_t Value)
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
unsigned emitSLEB128IntValue(int64_t Value)
Special case of EmitSLEB128Value that avoids the client having to pass in a MCExpr for constant integ...
void emitInt8(uint64_t Value)
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool MCIncrementalLinkerCompatible
A string table that doesn't need relocations.
std::vector< DwarfStringPoolEntryRef > getEntriesForEmission() const
Return the list of strings to be emitted.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
Helper for making strong types.
Target - Wrapper for Target specific information.
MCCodeEmitter * createMCCodeEmitter(const MCInstrInfo &II, MCContext &Ctx) const
createMCCodeEmitter - Create a target specific code emitter.
MCObjectFileInfo * createMCObjectFileInfo(MCContext &Ctx, bool PIC, bool LargeCodeModel=false) const
Create a MCObjectFileInfo implementation for the specified target triple.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, bool IsVerboseAsm, bool UseDwarfDirectory, MCInstPrinter *InstPrint, std::unique_ptr< MCCodeEmitter > &&CE, std::unique_ptr< MCAsmBackend > &&TAB, bool ShowInst) const
MCAsmBackend * createMCAsmBackend(const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) const
createMCAsmBackend - Create a target specific assembly parser.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, const MCTargetOptions &Options) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
MCInstPrinter * createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) const
MCStreamer * createMCObjectStreamer(const Triple &T, MCContext &Ctx, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter, const MCSubtargetInfo &STI, bool RelaxAll, bool IncrementalLinkerCompatible, bool DWARFMustBeAtTheEnd) const
Create a target specific MCStreamer.
AsmPrinter * createAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > &&Streamer) const
createAsmPrinter - Create a target specific assembly printer pass.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Triple - Helper class for working with autoconf configuration names.
const std::string & getTriple() const
std::function< void(const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
OutputFileType
Type of output file.
uint64_t getValueIndex(T Value)
Stores all information relating to a compile unit, be it in its original instance in the object file ...
void emitDwarfDebugAddrsFooter(const CompileUnit &Unit, MCSymbol *EndLabel) override
Emit .debug_addr footer.
void emitDwarfDebugArangesTable(const CompileUnit &Unit, const AddressRanges &LinkedRanges) override
Emit .debug_aranges entries for Unit.
void emitAppleTypes(AccelTable< AppleAccelTableStaticTypeData > &Table) override
Emit Apple type accelerator table.
void emitDIE(DIE &Die) override
Recursively emit the DIE tree rooted at Die.
void emitDwarfDebugLocListFragment(const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool) override
Emit debug ranges(.debug_loc, .debug_loclists) fragment.
void emitStrings(const NonRelocatableStringpool &Pool) override
Emit the string table described by Pool into .debug_str table.
static Expected< std::unique_ptr< DwarfStreamer > > createStreamer(const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning)
void emitDebugNames(DWARF5AccelTable &Table) override
Emit DWARF debug names.
void emitDwarfDebugLocListFooter(const CompileUnit &Unit, MCSymbol *EndLabel) override
Emit debug ranges(.debug_loc, .debug_loclists) footer.
MCSymbol * emitDwarfDebugAddrsHeader(const CompileUnit &Unit) override
Emit .debug_addr header.
void emitStringOffsets(const SmallVector< uint64_t > &StringOffset, uint16_t TargetDWARFVersion) override
Emit the debug string offset table described by StringOffsets into the .debug_str_offsets table.
void emitLineStrings(const NonRelocatableStringpool &Pool) override
Emit the string table described by Pool into .debug_line_str table.
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName)
void emitSwiftReflectionSection(llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, StringRef Buffer, uint32_t Alignment, uint32_t Size)
Emit the swift reflection section stored in Buffer.
MCSymbol * emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override
Emit debug ranges(.debug_ranges, .debug_rnglists) header.
void emitCIE(StringRef CIEBytes) override
Emit a CIE.
void emitSectionContents(StringRef SecData, DebugSectionKind SecKind) override
Emit contents of section SecName From Obj.
void emitAppleNames(AccelTable< AppleAccelTableStaticOffsetData > &Table) override
Emit Apple names accelerator table.
void finish() override
Dump the file to the disk.
void emitAbbrevs(const std::vector< std::unique_ptr< DIEAbbrev > > &Abbrevs, unsigned DwarfVersion) override
Emit the abbreviation table Abbrevs to the debug_abbrev section.
MCSymbol * emitDwarfDebugLocListHeader(const CompileUnit &Unit) override
Emit debug locations(.debug_loc, .debug_loclists) header.
void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address, StringRef Bytes) override
Emit an FDE with data Bytes.
void emitPubNamesForUnit(const CompileUnit &Unit) override
Emit the .debug_pubnames contribution for Unit.
void emitDwarfDebugRangeListFragment(const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch, DebugDieValuePool &AddrPool) override
Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
void emitPubTypesForUnit(const CompileUnit &Unit) override
Emit the .debug_pubtypes contribution for Unit.
void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit, OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) override
Emit .debug_line table entry for specified LineTable.
void emitDwarfDebugAddrs(const SmallVector< uint64_t > &Addrs, uint8_t AddrSize) override
Emit the addresses described by Addrs into .debug_addr table.
void emitAppleObjc(AccelTable< AppleAccelTableStaticOffsetData > &Table) override
Emit Apple Objective-C accelerator table.
void emitAppleNamespaces(AccelTable< AppleAccelTableStaticOffsetData > &Table) override
Emit Apple namespaces accelerator table.
void emitMacroTables(DWARFContext *Context, const Offset2UnitMap &UnitMacroMap, OffsetsStringPool &StringPool) override
Emit all available macro tables(DWARFv4 and DWARFv5).
void switchToDebugInfoSection(unsigned DwarfVersion)
Set the current output section to debug_info and change the MC Dwarf version to DwarfVersion.
void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override
Emit the compilation unit header for Unit in the debug_info section.
void emitSwiftAST(StringRef Buffer)
Emit the swift_ast section stored in Buffer.
void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, MCSymbol *EndLabel) override
Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
An abstract base class for streams implementations that also support a pwrite operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
DebugSectionKind
List of tracked debug tables.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
MCTargetOptions InitMCTargetOptionsFromFlags()
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
unsigned getSLEB128Size(int64_t Value)
Utility function to get the size of the SLEB128-encoded value.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint8_t MinInstLength
The size in bytes of the smallest target machine instruction.
int8_t LineBase
This parameter affects the meaning of the special opcodes. See below.
uint8_t LineRange
This parameter affects the meaning of the special opcodes. See below.
uint8_t OpcodeBase
The number assigned to the first special opcode.
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Standard .debug_line state machine structure.
Represents a single DWARF expression, whose value is location-dependent.
uint8_t DWARF2LineOpcodeBase
First special line opcode - leave room for the standard opcodes.
uint8_t DWARF2LineRange
Range of line offsets in a special line info. opcode.
int8_t DWARF2LineBase
Minimum line offset in a special line info.
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
void set(uint64_t New) const