34 std::string TripleName;
48 "no register info for target %s",
55 "no asm info for target %s", TripleName.c_str());
60 "no subtarget info for target %s",
63 MC.reset(
new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(),
nullptr,
64 nullptr,
true, Swift5ReflectionSegmentName));
66 MC->setObjectFileInfo(MOFI.get());
71 "no asm backend for target %s",
77 "no instr info info for target %s",
83 "no code emitter for target %s",
86 switch (OutFileType) {
91 *MC, std::make_unique<formatted_raw_ostream>(OutFile),
true,
true, MIP,
92 std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
98 TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
108 "no object streamer for target %s",
116 "no target machine for target %s",
119 Asm.reset(TheTarget->
createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
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;
143 MC->setDwarfVersion(DwarfVersion);
163 unsigned DwarfVersion) {
167 Unit.setLabelBegin(Asm->createTempSymbol(
"cu_begin"));
168 Asm->OutStreamer->emitLabel(Unit.getLabelBegin());
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());
182 DebugInfoSectionSize += 12;
187 Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
188 DebugInfoSectionSize += 11;
192 EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
198 const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
199 unsigned DwarfVersion) {
201 MC->setDwarfVersion(DwarfVersion);
202 Asm->emitDwarfAbbrevs(Abbrevs);
208 Asm->emitDwarfDIE(Die);
209 DebugInfoSectionSize += Die.
getSize();
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())
239 Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
241 for (
auto Entry : Entries) {
243 Asm->OutStreamer->emitBytes(Entry.getString());
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);
284 Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection());
286 for (
auto Entry : Entries) {
288 Asm->OutStreamer->emitBytes(Entry.getString());
295 if (EmittedUnits.empty())
299 std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;
302 for (
auto &
CU : EmittedUnits) {
303 CompUnits.push_back(
CU.LabelBegin);
305 UniqueIdToCuMap[
CU.ID] = Id++;
308 Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
315 Asm.get(), Table, CompUnits,
317 -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
318 if (UniqueIdToCuMap.size() > 1)
319 return {{UniqueIdToCuMap[Entry.getUnitID()],
320 {dwarf::DW_IDX_compile_unit, Form}}};
325void DwarfStreamer::emitAppleNamespaces(
327 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
328 auto *SectionBegin = Asm->createTempSymbol(
"namespac_begin");
329 Asm->OutStreamer->emitLabel(SectionBegin);
333void DwarfStreamer::emitAppleNames(
335 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
336 auto *SectionBegin = Asm->createTempSymbol(
"names_begin");
337 Asm->OutStreamer->emitLabel(SectionBegin);
341void DwarfStreamer::emitAppleObjc(
343 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
344 auto *SectionBegin = Asm->createTempSymbol(
"objc_begin");
345 Asm->OutStreamer->emitLabel(SectionBegin);
349void DwarfStreamer::emitAppleTypes(
351 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
352 auto *SectionBegin = Asm->createTempSymbol(
"types_begin");
353 Asm->OutStreamer->emitLabel(SectionBegin);
359 MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
361 MS->switchSection(SwiftASTSection);
362 MS->emitBytes(Buffer);
365void DwarfStreamer::emitSwiftReflectionSection(
369 MOFI->getSwift5ReflectionSection(ReflSectionKind);
370 if (ReflectionSection ==
nullptr)
373 MS->switchSection(ReflectionSection);
374 MS->emitBytes(Buffer);
377void DwarfStreamer::emitDwarfDebugArangesTable(
379 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
382 MS->switchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
385 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Barange");
386 MCSymbol *EndLabel = Asm->createTempSymbol(
"Earange");
388 unsigned HeaderSize =
395 unsigned TupleSize = AddressSize * 2;
398 Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
399 Asm->OutStreamer->emitLabel(BeginLabel);
400 Asm->emitInt16(dwarf::DW_ARANGES_VERSION);
401 Asm->emitInt32(Unit.getStartOffset());
402 Asm->emitInt8(AddressSize);
405 Asm->OutStreamer->emitFill(Padding, 0x0);
409 MS->emitIntValue(Range.start(), AddressSize);
410 MS->emitIntValue(Range.end() - Range.start(), AddressSize);
414 Asm->OutStreamer->emitIntValue(0, AddressSize);
415 Asm->OutStreamer->emitIntValue(0, AddressSize);
416 Asm->OutStreamer->emitLabel(EndLabel);
419void DwarfStreamer::emitDwarfDebugRangesTableFragment(
422 Patch.
set(RangesSectionSize);
425 MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
426 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
430 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
431 BaseAddress = *LowPC;
434 MS->emitIntValue(Range.start() - BaseAddress, AddressSize);
435 MS->emitIntValue(Range.end() - BaseAddress, AddressSize);
437 RangesSectionSize += AddressSize;
438 RangesSectionSize += AddressSize;
442 MS->emitIntValue(0, AddressSize);
443 MS->emitIntValue(0, AddressSize);
445 RangesSectionSize += AddressSize;
446 RangesSectionSize += AddressSize;
450DwarfStreamer::emitDwarfDebugRangeListHeader(
const CompileUnit &Unit) {
451 if (Unit.getOrigUnit().getVersion() < 5)
455 MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
457 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Brnglists");
458 MCSymbol *EndLabel = Asm->createTempSymbol(
"Ernglists");
459 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
462 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
463 Asm->OutStreamer->emitLabel(BeginLabel);
464 RngListsSectionSize +=
sizeof(
uint32_t);
468 RngListsSectionSize +=
sizeof(
uint16_t);
471 MS->emitInt8(AddressSize);
472 RngListsSectionSize++;
476 RngListsSectionSize++;
480 RngListsSectionSize +=
sizeof(
uint32_t);
485void DwarfStreamer::emitDwarfDebugRangeListFragment(
488 if (Unit.getOrigUnit().getVersion() < 5) {
489 emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
493 emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool);
496void DwarfStreamer::emitDwarfDebugRangeListFooter(
const CompileUnit &Unit,
498 if (Unit.getOrigUnit().getVersion() < 5)
502 MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
504 if (EndLabel !=
nullptr)
505 Asm->OutStreamer->emitLabel(EndLabel);
508void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
511 Patch.
set(RngListsSectionSize);
514 MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
515 std::optional<uint64_t> BaseAddress;
520 BaseAddress = Range.start();
523 MS->emitInt8(dwarf::DW_RLE_base_addressx);
524 RngListsSectionSize += 1;
525 RngListsSectionSize +=
526 MS->emitULEB128IntValue(AddrPool.
getValueIndex(*BaseAddress));
530 MS->emitInt8(dwarf::DW_RLE_offset_pair);
531 RngListsSectionSize += 1;
534 RngListsSectionSize +=
535 MS->emitULEB128IntValue(Range.start() - *BaseAddress);
538 RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - *BaseAddress);
542 MS->emitInt8(dwarf::DW_RLE_end_of_list);
543 RngListsSectionSize += 1;
548 if (Unit.getOrigUnit().getVersion() < 5)
552 MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
554 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Bloclists");
555 MCSymbol *EndLabel = Asm->createTempSymbol(
"Eloclists");
556 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
559 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
560 Asm->OutStreamer->emitLabel(BeginLabel);
561 LocListsSectionSize +=
sizeof(
uint32_t);
565 LocListsSectionSize +=
sizeof(
uint16_t);
568 MS->emitInt8(AddressSize);
569 LocListsSectionSize++;
573 LocListsSectionSize++;
577 LocListsSectionSize +=
sizeof(
uint32_t);
583void DwarfStreamer::emitDwarfDebugLocListFragment(
587 if (Unit.getOrigUnit().getVersion() < 5) {
588 emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
592 emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch,
597void DwarfStreamer::emitDwarfDebugLocListFooter(
const CompileUnit &Unit,
599 if (Unit.getOrigUnit().getVersion() < 5)
603 MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
605 if (EndLabel !=
nullptr)
606 Asm->OutStreamer->emitLabel(EndLabel);
610void DwarfStreamer::emitDwarfDebugLocTableFragment(
614 Patch.
set(LocSectionSize);
617 MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
618 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
622 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
623 BaseAddress = *LowPC;
626 LinkedLocationExpression) {
627 if (LocExpression.Range) {
628 MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize);
629 MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize);
631 LocSectionSize += AddressSize;
632 LocSectionSize += AddressSize;
635 Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2);
636 Asm->OutStreamer->emitBytes(StringRef(
637 (
const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
638 LocSectionSize += LocExpression.Expr.size() + 2;
642 MS->emitIntValue(0, AddressSize);
643 MS->emitIntValue(0, AddressSize);
645 LocSectionSize += AddressSize;
646 LocSectionSize += AddressSize;
653 MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
655 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Bdebugaddr");
656 MCSymbol *EndLabel = Asm->createTempSymbol(
"Edebugaddr");
657 unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize();
660 Asm->emitLabelDifference(EndLabel, BeginLabel,
sizeof(
uint32_t));
661 Asm->OutStreamer->emitLabel(BeginLabel);
662 AddrSectionSize +=
sizeof(
uint32_t);
666 AddrSectionSize += 2;
669 Asm->emitInt8(AddrSize);
670 AddrSectionSize += 1;
674 AddrSectionSize += 1;
682 Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection());
683 for (
auto Addr : Addrs) {
684 Asm->OutStreamer->emitIntValue(
Addr, AddrSize);
685 AddrSectionSize += AddrSize;
690void DwarfStreamer::emitDwarfDebugAddrsFooter(
const CompileUnit &Unit,
694 MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
696 if (EndLabel !=
nullptr)
697 Asm->OutStreamer->emitLabel(EndLabel);
701void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
705 Patch.
set(LocListsSectionSize);
708 MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
709 std::optional<uint64_t> BaseAddress;
712 LinkedLocationExpression) {
713 if (LocExpression.Range) {
717 BaseAddress = LocExpression.Range->LowPC;
720 MS->emitInt8(dwarf::DW_LLE_base_addressx);
721 LocListsSectionSize += 1;
722 LocListsSectionSize +=
723 MS->emitULEB128IntValue(AddrPool.
getValueIndex(*BaseAddress));
727 MS->emitInt8(dwarf::DW_LLE_offset_pair);
728 LocListsSectionSize += 1;
731 LocListsSectionSize +=
732 MS->emitULEB128IntValue(LocExpression.Range->LowPC - *BaseAddress);
735 LocListsSectionSize +=
736 MS->emitULEB128IntValue(LocExpression.Range->HighPC - *BaseAddress);
739 MS->emitInt8(dwarf::DW_LLE_default_location);
740 LocListsSectionSize += 1;
743 LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size());
744 Asm->OutStreamer->emitBytes(StringRef(
745 (
const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
746 LocListsSectionSize += LocExpression.Expr.size();
750 MS->emitInt8(dwarf::DW_LLE_end_of_list);
751 LocListsSectionSize += 1;
754void DwarfStreamer::emitLineTableForUnit(
758 MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection());
760 MCSymbol *LineStartSym = MC->createTempSymbol();
761 MCSymbol *LineEndSym = MC->createTempSymbol();
765 MS->emitInt32(dwarf::DW_LENGTH_DWARF64);
766 LineSectionSize += 4;
768 emitLabelDifference(LineEndSym, LineStartSym,
770 Asm->OutStreamer->emitLabel(LineStartSym);
773 emitLineTablePrologue(LineTable.
Prologue, DebugStrPool, DebugLineStrPool);
776 emitLineTableRows(LineTable, LineEndSym,
777 Unit.getOrigUnit().getAddressByteSize());
783 MCSymbol *PrologueStartSym = MC->createTempSymbol();
784 MCSymbol *PrologueEndSym = MC->createTempSymbol();
787 MS->emitInt16(
P.getVersion());
788 LineSectionSize += 2;
789 if (
P.getVersion() == 5) {
791 MS->emitInt8(
P.getAddressSize());
792 LineSectionSize += 1;
795 MS->emitInt8(
P.SegSelectorSize);
796 LineSectionSize += 1;
800 emitLabelDifference(PrologueEndSym, PrologueStartSym,
P.FormParams.Format,
803 Asm->OutStreamer->emitLabel(PrologueStartSym);
804 emitLineTableProloguePayload(
P, DebugStrPool, DebugLineStrPool);
805 Asm->OutStreamer->emitLabel(PrologueEndSym);
808void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
809 const DWARFDebugLine::Prologue &
P, OffsetsStringPool &DebugStrPool,
810 OffsetsStringPool &DebugLineStrPool) {
812 for (
const DWARFFormValue &Include :
P.IncludeDirectories)
813 emitLineTableString(
P, Include, DebugStrPool, DebugLineStrPool);
816 LineSectionSize += 1;
819 for (
const DWARFDebugLine::FileNameEntry &File :
P.FileNames) {
822 emitLineTableString(
P,
File.Name, DebugStrPool, DebugLineStrPool);
825 LineSectionSize += MS->emitULEB128IntValue(
File.DirIdx);
828 LineSectionSize += MS->emitULEB128IntValue(
File.ModTime);
831 LineSectionSize += MS->emitULEB128IntValue(
File.Length);
835 LineSectionSize += 1;
838void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
839 const DWARFDebugLine::Prologue &
P, OffsetsStringPool &DebugStrPool,
840 OffsetsStringPool &DebugLineStrPool) {
841 if (
P.IncludeDirectories.empty()) {
844 LineSectionSize += 1;
848 LineSectionSize += 1;
851 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
853 MS->emitULEB128IntValue(
P.IncludeDirectories[0].getForm());
857 LineSectionSize += MS->emitULEB128IntValue(
P.IncludeDirectories.size());
859 for (
auto Include :
P.IncludeDirectories)
860 emitLineTableString(
P, Include, DebugStrPool, DebugLineStrPool);
862 if (
P.FileNames.empty()) {
865 LineSectionSize += 1;
869 LineSectionSize += 1;
872 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
873 LineSectionSize += MS->emitULEB128IntValue(
P.FileNames[0].Name.getForm());
875 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
876 LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1);
880 LineSectionSize += MS->emitULEB128IntValue(
P.FileNames.size());
883 for (
auto File :
P.FileNames) {
884 emitLineTableString(
P,
File.Name, DebugStrPool, DebugLineStrPool);
885 MS->emitInt8(
File.DirIdx);
886 LineSectionSize += 1;
890void DwarfStreamer::emitLineTableString(
const DWARFDebugLine::Prologue &
P,
891 const DWARFFormValue &String,
892 OffsetsStringPool &DebugStrPool,
893 OffsetsStringPool &DebugLineStrPool) {
894 std::optional<const char *> StringVal = dwarf::toString(String);
896 warn(
"Cann't read string from line table.");
900 switch (
String.getForm()) {
901 case dwarf::DW_FORM_string: {
902 StringRef TranslatedString =
903 (Translator) ? Translator(*StringVal) : *StringVal;
904 Asm->OutStreamer->emitBytes(TranslatedString.data());
906 LineSectionSize += TranslatedString.size() + 1;
908 case dwarf::DW_FORM_strp:
909 case dwarf::DW_FORM_line_strp: {
910 DwarfStringPoolEntryRef StringRef =
911 String.getForm() == dwarf::DW_FORM_strp
912 ? DebugStrPool.getEntry(*StringVal)
913 : DebugLineStrPool.getEntry(*StringVal);
915 emitIntOffset(StringRef.getOffset(),
P.FormParams.Format, LineSectionSize);
918 warn(
"Unsupported string form inside line table.");
923void DwarfStreamer::emitLineTableProloguePayload(
924 const DWARFDebugLine::Prologue &
P, OffsetsStringPool &DebugStrPool,
925 OffsetsStringPool &DebugLineStrPool) {
927 MS->emitInt8(
P.MinInstLength);
928 LineSectionSize += 1;
929 if (
P.FormParams.Version >= 4) {
931 MS->emitInt8(
P.MaxOpsPerInst);
932 LineSectionSize += 1;
935 MS->emitInt8(
P.DefaultIsStmt);
936 LineSectionSize += 1;
938 MS->emitInt8(
P.LineBase);
939 LineSectionSize += 1;
941 MS->emitInt8(
P.LineRange);
942 LineSectionSize += 1;
944 MS->emitInt8(
P.OpcodeBase);
945 LineSectionSize += 1;
948 for (
auto Length :
P.StandardOpcodeLengths) {
949 MS->emitInt8(Length);
950 LineSectionSize += 1;
953 if (
P.FormParams.Version < 5)
954 emitLineTablePrologueV2IncludeAndFileTable(
P, DebugStrPool,
957 emitLineTablePrologueV5IncludeAndFileTable(
P, DebugStrPool,
961void DwarfStreamer::emitLineTableRows(
962 const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym,
963 unsigned AddressByteSize) {
965 MCDwarfLineTableParams Params;
966 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
967 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
968 Params.DWARF2LineRange = LineTable.Prologue.LineRange;
970 SmallString<128> EncodingBuffer;
972 if (LineTable.Rows.empty()) {
975 MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
977 MS->emitBytes(EncodingBuffer);
978 LineSectionSize += EncodingBuffer.size();
979 MS->emitLabel(LineEndSym);
984 unsigned FileNum = 1;
985 unsigned LastLine = 1;
987 unsigned IsStatement = 1;
991 unsigned RowsSinceLastSequence = 0;
993 for (
const DWARFDebugLine::Row &Row : LineTable.Rows) {
995 if (Address == -1ULL) {
996 MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
997 MS->emitULEB128IntValue(AddressByteSize + 1);
998 MS->emitIntValue(dwarf::DW_LNE_set_address, 1);
999 MS->emitIntValue(Row.Address.Address, AddressByteSize);
1005 (Row.Address.Address -
Address) / LineTable.Prologue.MinInstLength;
1013 if (FileNum != Row.File) {
1015 MS->emitIntValue(dwarf::DW_LNS_set_file, 1);
1016 MS->emitULEB128IntValue(FileNum);
1019 if (Column != Row.Column) {
1020 Column = Row.Column;
1021 MS->emitIntValue(dwarf::DW_LNS_set_column, 1);
1022 MS->emitULEB128IntValue(Column);
1029 if (Isa != Row.Isa) {
1031 MS->emitIntValue(dwarf::DW_LNS_set_isa, 1);
1032 MS->emitULEB128IntValue(Isa);
1035 if (IsStatement != Row.IsStmt) {
1036 IsStatement = Row.IsStmt;
1037 MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1);
1038 LineSectionSize += 1;
1040 if (Row.BasicBlock) {
1041 MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1);
1042 LineSectionSize += 1;
1045 if (Row.PrologueEnd) {
1046 MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
1047 LineSectionSize += 1;
1050 if (Row.EpilogueBegin) {
1051 MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
1052 LineSectionSize += 1;
1055 int64_t LineDelta = int64_t(Row.Line) - LastLine;
1056 if (!Row.EndSequence) {
1057 MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta,
1059 MS->emitBytes(EncodingBuffer);
1060 LineSectionSize += EncodingBuffer.size();
1061 EncodingBuffer.resize(0);
1062 Address = Row.Address.Address;
1063 LastLine = Row.Line;
1064 RowsSinceLastSequence++;
1067 MS->emitIntValue(dwarf::DW_LNS_advance_line, 1);
1068 MS->emitSLEB128IntValue(LineDelta);
1072 MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1);
1073 MS->emitULEB128IntValue(AddressDelta);
1076 MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(),
1078 MS->emitBytes(EncodingBuffer);
1079 LineSectionSize += EncodingBuffer.size();
1080 EncodingBuffer.resize(0);
1082 LastLine = FileNum = IsStatement = 1;
1083 RowsSinceLastSequence = Column = Isa = 0;
1087 if (RowsSinceLastSequence) {
1088 MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
1090 MS->emitBytes(EncodingBuffer);
1091 LineSectionSize += EncodingBuffer.size();
1092 EncodingBuffer.resize(0);
1095 MS->emitLabel(LineEndSym);
1098void DwarfStreamer::emitIntOffset(
uint64_t Offset, dwarf::DwarfFormat Format,
1100 uint8_t
Size = dwarf::getDwarfOffsetByteSize(Format);
1105void DwarfStreamer::emitLabelDifference(
const MCSymbol *
Hi,
const MCSymbol *
Lo,
1106 dwarf::DwarfFormat Format,
1108 uint8_t
Size = dwarf::getDwarfOffsetByteSize(Format);
1115void DwarfStreamer::emitPubSectionForUnit(
1116 MCSection *Sec, StringRef SecName,
const CompileUnit &Unit,
1117 const std::vector<CompileUnit::AccelInfo> &Names) {
1122 Asm->OutStreamer->switchSection(Sec);
1123 MCSymbol *BeginLabel =
Asm->createTempSymbol(
"pub" + SecName +
"_begin");
1124 MCSymbol *EndLabel =
Asm->createTempSymbol(
"pub" + SecName +
"_end");
1126 bool HeaderEmitted =
false;
1128 for (
const auto &
Name : Names) {
1129 if (
Name.SkipPubSection)
1132 if (!HeaderEmitted) {
1134 Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
1135 Asm->OutStreamer->emitLabel(BeginLabel);
1136 Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION);
1137 Asm->emitInt32(Unit.getStartOffset());
1138 Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset());
1139 HeaderEmitted =
true;
1141 Asm->emitInt32(
Name.Die->getOffset());
1144 Asm->OutStreamer->emitBytes(
Name.Name.getString());
1152 Asm->OutStreamer->emitLabel(EndLabel);
1157 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
1158 "names", Unit, Unit.getPubnames());
1163 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
1164 "types", Unit, Unit.getPubtypes());
1169 MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1171 MS->emitBytes(CIEBytes);
1172 FrameSectionSize += CIEBytes.
size();
1180 MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1182 MS->emitIntValue(FDEBytes.
size() + 4 + AddrSize, 4);
1183 MS->emitIntValue(CIEOffset, 4);
1184 MS->emitIntValue(Address, AddrSize);
1185 MS->emitBytes(FDEBytes);
1186 FrameSectionSize += FDEBytes.
size() + 8 + AddrSize;
1196 MS->switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection());
1197 emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacInfoSectionSize);
1202 MS->switchSection(MC->getObjectFileInfo()->getDwarfMacroSection());
1203 emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacroSectionSize);
1207void DwarfStreamer::emitMacroTableImpl(
const DWARFDebugMacro *MacroTable,
1211 bool DefAttributeIsReported =
false;
1212 bool UndefAttributeIsReported =
false;
1213 bool ImportAttributeIsReported =
false;
1214 for (
const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
1216 if (UnitIt == UnitMacroMap.
end()) {
1218 "couldn`t find compile unit for the macro table with offset = {0:x}",
1224 DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE();
1225 if (OutputUnitDIE ==
nullptr)
1230 bool hasDWARFv5Header =
false;
1231 for (
auto &V : OutputUnitDIE->values()) {
1232 if (V.getAttribute() == dwarf::DW_AT_macro_info) {
1233 V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
1235 }
else if (
V.getAttribute() == dwarf::DW_AT_macros) {
1236 hasDWARFv5Header =
true;
1237 V = DIEValue(
V.getAttribute(),
V.getForm(), DIEInteger(OutOffset));
1243 if (hasDWARFv5Header) {
1245 MS->emitIntValue(
List.Header.Version,
sizeof(
List.Header.Version));
1246 OutOffset +=
sizeof(
List.Header.Version);
1252 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
1253 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
1254 warn(
"opcode_operands_table is not supported yet.");
1258 std::optional<uint64_t> StmtListOffset;
1259 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
1261 for (
auto &V : OutputUnitDIE->values()) {
1262 if (
V.getAttribute() == dwarf::DW_AT_stmt_list) {
1263 StmtListOffset =
V.getDIEInteger().getValue();
1268 if (!StmtListOffset) {
1269 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
1270 warn(
"couldn`t find line table for macro table.");
1275 MS->emitIntValue(Flags,
sizeof(Flags));
1276 OutOffset +=
sizeof(
Flags);
1279 if (StmtListOffset) {
1280 MS->emitIntValue(*StmtListOffset,
List.Header.getOffsetByteSize());
1281 OutOffset +=
List.Header.getOffsetByteSize();
1286 for (
const DWARFDebugMacro::Entry &MacroEntry :
List.Macros) {
1287 if (MacroEntry.Type == 0) {
1288 OutOffset += MS->emitULEB128IntValue(MacroEntry.Type);
1292 uint8_t MacroType = MacroEntry.Type;
1293 switch (MacroType) {
1295 bool HasVendorSpecificExtension =
1296 (!hasDWARFv5Header && MacroType == dwarf::DW_MACINFO_vendor_ext) ||
1297 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
1298 MacroType <= dwarf::DW_MACRO_hi_user));
1300 if (HasVendorSpecificExtension) {
1302 MS->emitIntValue(MacroType, 1);
1306 OutOffset += MS->emitULEB128IntValue(MacroEntry.ExtConstant);
1309 StringRef
String = MacroEntry.ExtStr;
1310 MS->emitBytes(String);
1311 MS->emitIntValue(0, 1);
1312 OutOffset +=
String.size() + 1;
1314 warn(
"unknown macro type. skip.");
1322 case dwarf::DW_MACRO_define:
1323 case dwarf::DW_MACRO_undef: {
1325 MS->emitIntValue(MacroType, 1);
1329 OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
1332 StringRef
String = MacroEntry.MacroStr;
1333 MS->emitBytes(String);
1334 MS->emitIntValue(0, 1);
1335 OutOffset +=
String.size() + 1;
1337 case dwarf::DW_MACRO_define_strp:
1338 case dwarf::DW_MACRO_undef_strp:
1339 case dwarf::DW_MACRO_define_strx:
1340 case dwarf::DW_MACRO_undef_strx: {
1341 assert(UnitIt->second->getOrigUnit().getVersion() >= 5);
1345 switch (MacroType) {
1346 case dwarf::DW_MACRO_define_strx: {
1347 MacroType = dwarf::DW_MACRO_define_strp;
1348 if (!DefAttributeIsReported) {
1349 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1350 "DW_MACRO_define_strp.");
1351 DefAttributeIsReported =
true;
1354 case dwarf::DW_MACRO_undef_strx: {
1355 MacroType = dwarf::DW_MACRO_undef_strp;
1356 if (!UndefAttributeIsReported) {
1357 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1358 "DW_MACRO_undef_strp.");
1359 UndefAttributeIsReported =
true;
1368 MS->emitIntValue(MacroType, 1);
1372 OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
1375 DwarfStringPoolEntryRef EntryRef =
1376 StringPool.getEntry(MacroEntry.MacroStr);
1377 MS->emitIntValue(EntryRef.getOffset(),
List.Header.getOffsetByteSize());
1378 OutOffset +=
List.Header.getOffsetByteSize();
1381 case dwarf::DW_MACRO_start_file: {
1383 MS->emitIntValue(MacroType, 1);
1386 OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
1388 OutOffset += MS->emitULEB128IntValue(MacroEntry.File);
1390 case dwarf::DW_MACRO_end_file: {
1392 MS->emitIntValue(MacroType, 1);
1395 case dwarf::DW_MACRO_import:
1396 case dwarf::DW_MACRO_import_sup: {
1397 if (!ImportAttributeIsReported) {
1398 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
1400 ImportAttributeIsReported =
true;
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
support::ulittle16_t & Lo
support::ulittle16_t & Hi
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.
Stores all information relating to a compile unit, be it in its original instance in the object file ...
static dwarf::Form BestForm(bool IsSigned, uint64_t Int)
Choose the best form for integer.
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)
void emitDebugNames(DWARF5AccelTable &Table) override
Emit DWARF debug names.
void emitStrings(const NonRelocatableStringpool &Pool) override
Emit the string table described by Pool into .debug_str table.
void finish() override
Dump the file to the disk.
void emitStringOffsets(const SmallVector< uint64_t > &StringOffset, uint16_t TargetDWARFVersion) override
Emit the debug string offset table described by StringOffsets into the .debug_str_offsets table.
void emitSectionContents(StringRef SecData, StringRef SecName) override
Emit contents of section SecName From Obj.
void emitDIE(DIE &Die) override
Recursively emit the DIE tree rooted at Die.
void emitLineStrings(const NonRelocatableStringpool &Pool) override
Emit the string table described by Pool into .debug_line_str table.
void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override
Emit the compilation unit header for Unit in the debug_info section.
void emitAbbrevs(const std::vector< std::unique_ptr< DIEAbbrev > > &Abbrevs, unsigned DwarfVersion) override
Emit the abbreviation table Abbrevs to the debug_abbrev section.
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName)
void switchToDebugInfoSection(unsigned DwarfVersion)
Set the current output section to debug_info and change the MC Dwarf version to DwarfVersion.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
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.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
void emitInt16(uint64_t Value)
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool MCIncrementalLinkerCompatible
A string table that doesn't need relocations.
std::vector< DwarfStringPoolEntryRef > getEntriesForEmission() const
Return the list of strings to be emitted.
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.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
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
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(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.
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Represents a single DWARF expression, whose value is location-dependent.
uint64_t getValueIndex(uint64_t Value)
void set(uint64_t New) const
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.