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",
70 "no asm info for target %s", TripleName.c_str());
75 "no subtarget info for target %s",
78 MC.reset(
new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(),
nullptr,
79 nullptr,
true, Swift5ReflectionSegmentName));
81 MC->setObjectFileInfo(MOFI.get());
86 "no asm backend for target %s",
92 "no instr info info for target %s",
98 "no code emitter for target %s",
101 switch (OutFileType) {
104 TheTriple, MAI->getAssemblerDialect(), *MAI, *MII, *MRI));
106 *MC, std::make_unique<formatted_raw_ostream>(OutFile), std::move(MIP),
107 std::unique_ptr<MCCodeEmitter>(MCE),
108 std::unique_ptr<MCAsmBackend>(MAB));
113 TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
122 "no object streamer for target %s",
130 "no target machine for target %s",
133 Asm.reset(TheTarget->
createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
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;
157 MC->setDwarfVersion(DwarfVersion);
177 unsigned DwarfVersion) {
181 Unit.setLabelBegin(Asm->createTempSymbol(
"cu_begin"));
182 Asm->OutStreamer->emitLabel(Unit.getLabelBegin());
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());
196 DebugInfoSectionSize += 12;
201 Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
202 DebugInfoSectionSize += 11;
206 EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
212 const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
213 unsigned DwarfVersion) {
215 MC->setDwarfVersion(DwarfVersion);
216 Asm->emitDwarfAbbrevs(Abbrevs);
222 Asm->emitDwarfDIE(Die);
223 DebugInfoSectionSize += Die.
getSize();
232 if (
MCSection *Section = getMCSection(SecKind)) {
242 return MC->getObjectFileInfo()->getDwarfInfoSection();
244 return MC->getObjectFileInfo()->getDwarfLineSection();
246 return MC->getObjectFileInfo()->getDwarfFrameSection();
248 return MC->getObjectFileInfo()->getDwarfRangesSection();
250 return MC->getObjectFileInfo()->getDwarfRnglistsSection();
252 return MC->getObjectFileInfo()->getDwarfLocSection();
254 return MC->getObjectFileInfo()->getDwarfLoclistsSection();
256 return MC->getObjectFileInfo()->getDwarfARangesSection();
258 return MC->getObjectFileInfo()->getDwarfAbbrevSection();
260 return MC->getObjectFileInfo()->getDwarfMacinfoSection();
262 return MC->getObjectFileInfo()->getDwarfMacroSection();
264 return MC->getObjectFileInfo()->getDwarfAddrSection();
266 return MC->getObjectFileInfo()->getDwarfStrSection();
268 return MC->getObjectFileInfo()->getDwarfLineStrSection();
270 return MC->getObjectFileInfo()->getDwarfStrOffSection();
272 return MC->getObjectFileInfo()->getDwarfPubNamesSection();
274 return MC->getObjectFileInfo()->getDwarfPubTypesSection();
276 return MC->getObjectFileInfo()->getDwarfDebugNamesSection();
278 return MC->getObjectFileInfo()->getDwarfAccelNamesSection();
280 return MC->getObjectFileInfo()->getDwarfAccelNamespaceSection();
282 return MC->getObjectFileInfo()->getDwarfAccelObjCSection();
284 return MC->getObjectFileInfo()->getDwarfAccelTypesSection();
295 Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
297 for (
auto Entry : Entries) {
299 Asm->OutStreamer->emitBytes(Entry.getString());
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);
340 Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection());
342 for (
auto Entry : Entries) {
344 Asm->OutStreamer->emitBytes(Entry.getString());
351 if (EmittedUnits.empty())
355 std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;
358 for (
auto &
CU : EmittedUnits) {
359 CompUnits.push_back(
CU.LabelBegin);
361 UniqueIdToCuMap[
CU.ID] = Id++;
364 Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
371 Asm.get(), Table, CompUnits,
373 -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
374 if (UniqueIdToCuMap.size() > 1)
375 return {{UniqueIdToCuMap[Entry.getUnitID()],
376 {dwarf::DW_IDX_compile_unit, Form}}};
383 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
384 auto *SectionBegin = Asm->createTempSymbol(
"namespac_begin");
385 Asm->OutStreamer->emitLabel(SectionBegin);
391 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
392 auto *SectionBegin = Asm->createTempSymbol(
"names_begin");
393 Asm->OutStreamer->emitLabel(SectionBegin);
399 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
400 auto *SectionBegin = Asm->createTempSymbol(
"objc_begin");
401 Asm->OutStreamer->emitLabel(SectionBegin);
407 Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
408 auto *SectionBegin = Asm->createTempSymbol(
"types_begin");
409 Asm->OutStreamer->emitLabel(SectionBegin);
415 MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
425 MOFI->getSwift5ReflectionSection(ReflSectionKind);
426 if (ReflectionSection ==
nullptr)
435 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
438 MS->
switchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
441 MCSymbol *BeginLabel = Asm->createTempSymbol(
"Barange");
442 MCSymbol *EndLabel = Asm->createTempSymbol(
"Earange");
444 unsigned HeaderSize =
451 unsigned TupleSize = AddressSize * 2;
454 Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
455 Asm->OutStreamer->emitLabel(BeginLabel);
457 Asm->emitInt32(Unit.getStartOffset());
458 Asm->emitInt8(AddressSize);
461 Asm->OutStreamer->emitFill(Padding, 0x0);
470 Asm->OutStreamer->emitIntValue(0, AddressSize);
471 Asm->OutStreamer->emitIntValue(0, AddressSize);
472 Asm->OutStreamer->emitLabel(EndLabel);
475void DwarfStreamer::emitDwarfDebugRangesTableFragment(
478 Patch.
set(RangesSectionSize);
481 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
482 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
486 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
487 BaseAddress = *LowPC;
493 RangesSectionSize += AddressSize;
494 RangesSectionSize += AddressSize;
501 RangesSectionSize += AddressSize;
502 RangesSectionSize += AddressSize;
507 if (Unit.getOrigUnit().getVersion() < 5)
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);
528 RngListsSectionSize++;
532 RngListsSectionSize++;
536 RngListsSectionSize +=
sizeof(
uint32_t);
544 if (Unit.getOrigUnit().getVersion() < 5) {
545 emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
549 emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool);
554 if (Unit.getOrigUnit().getVersion() < 5)
558 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
560 if (EndLabel !=
nullptr)
561 Asm->OutStreamer->emitLabel(EndLabel);
564void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
567 Patch.
set(RngListsSectionSize);
570 MS->
switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
571 std::optional<uint64_t> BaseAddress;
576 BaseAddress =
Range.start();
579 MS->
emitInt8(dwarf::DW_RLE_base_addressx);
580 RngListsSectionSize += 1;
581 RngListsSectionSize +=
586 MS->
emitInt8(dwarf::DW_RLE_offset_pair);
587 RngListsSectionSize += 1;
590 RngListsSectionSize +=
598 MS->
emitInt8(dwarf::DW_RLE_end_of_list);
599 RngListsSectionSize += 1;
604 if (Unit.getOrigUnit().getVersion() < 5)
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);
625 LocListsSectionSize++;
629 LocListsSectionSize++;
633 LocListsSectionSize +=
sizeof(
uint32_t);
643 if (Unit.getOrigUnit().getVersion() < 5) {
644 emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
648 emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch,
655 if (Unit.getOrigUnit().getVersion() < 5)
659 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
661 if (EndLabel !=
nullptr)
662 Asm->OutStreamer->emitLabel(EndLabel);
666void DwarfStreamer::emitDwarfDebugLocTableFragment(
670 Patch.
set(LocSectionSize);
673 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
674 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
678 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
679 BaseAddress = *LowPC;
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);
693 (
const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
694 LocSectionSize += LocExpression.Expr.size() + 2;
701 LocSectionSize += AddressSize;
702 LocSectionSize += AddressSize;
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;
725 Asm->emitInt8(AddrSize);
726 AddrSectionSize += 1;
730 AddrSectionSize += 1;
738 Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection());
739 for (
auto Addr : Addrs) {
740 Asm->OutStreamer->emitIntValue(
Addr, AddrSize);
741 AddrSectionSize += AddrSize;
750 MS->
switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
752 if (EndLabel !=
nullptr)
753 Asm->OutStreamer->emitLabel(EndLabel);
757void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
761 Patch.
set(LocListsSectionSize);
764 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
765 std::optional<uint64_t> BaseAddress;
768 LinkedLocationExpression) {
769 if (LocExpression.Range) {
773 BaseAddress = LocExpression.Range->LowPC;
776 MS->
emitInt8(dwarf::DW_LLE_base_addressx);
777 LocListsSectionSize += 1;
778 LocListsSectionSize +=
783 MS->
emitInt8(dwarf::DW_LLE_offset_pair);
784 LocListsSectionSize += 1;
787 LocListsSectionSize +=
791 LocListsSectionSize +=
795 MS->
emitInt8(dwarf::DW_LLE_default_location);
796 LocListsSectionSize += 1;
801 (
const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
802 LocListsSectionSize += LocExpression.Expr.size();
806 MS->
emitInt8(dwarf::DW_LLE_end_of_list);
807 LocListsSectionSize += 1;
813 std::vector<uint64_t> *RowOffsets) {
815 MS->
switchSection(MC->getObjectFileInfo()->getDwarfLineSection());
817 MCSymbol *LineStartSym = MC->createTempSymbol();
818 MCSymbol *LineEndSym = MC->createTempSymbol();
823 LineSectionSize += 4;
825 emitLabelDifference(LineEndSym, LineStartSym,
827 Asm->OutStreamer->emitLabel(LineStartSym);
830 emitLineTablePrologue(LineTable.
Prologue, DebugStrPool, DebugLineStrPool);
833 emitLineTableRows(LineTable, LineEndSym,
834 Unit.getOrigUnit().getAddressByteSize(), RowOffsets);
840 MCSymbol *PrologueStartSym = MC->createTempSymbol();
841 MCSymbol *PrologueEndSym = MC->createTempSymbol();
845 LineSectionSize += 2;
846 if (
P.getVersion() == 5) {
849 LineSectionSize += 1;
853 LineSectionSize += 1;
857 emitLabelDifference(PrologueEndSym, PrologueStartSym,
P.FormParams.Format,
860 Asm->OutStreamer->emitLabel(PrologueStartSym);
861 emitLineTableProloguePayload(
P, DebugStrPool, DebugLineStrPool);
862 Asm->OutStreamer->emitLabel(PrologueEndSym);
865void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
870 emitLineTableString(
P,
Include, DebugStrPool, DebugLineStrPool);
873 LineSectionSize += 1;
879 emitLineTableString(
P, File.Name, DebugStrPool, DebugLineStrPool);
892 LineSectionSize += 1;
895void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
898 if (
P.IncludeDirectories.empty()) {
901 LineSectionSize += 1;
905 LineSectionSize += 1;
916 for (
auto Include :
P.IncludeDirectories)
917 emitLineTableString(
P,
Include, DebugStrPool, DebugLineStrPool);
919 bool HasChecksums =
P.ContentTypes.HasMD5;
920 bool HasInlineSources =
P.ContentTypes.HasSource;
922 if (
P.FileNames.empty()) {
925 LineSectionSize += 1;
928 MS->
emitInt8(2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0));
929 LineSectionSize += 1;
932 auto StrForm =
P.FileNames[0].Name.getForm();
944 if (HasInlineSources) {
954 for (
auto File :
P.FileNames) {
955 emitLineTableString(
P,
File.Name, DebugStrPool, DebugLineStrPool);
959 StringRef(
reinterpret_cast<const char *
>(
File.Checksum.data()),
960 File.Checksum.size()));
961 LineSectionSize +=
File.Checksum.size();
963 if (HasInlineSources)
964 emitLineTableString(
P,
File.Source, DebugStrPool, DebugLineStrPool);
974 warn(
"Cann't read string from line table.");
978 switch (
String.getForm()) {
979 case dwarf::DW_FORM_string: {
981 Asm->OutStreamer->emitBytes(Str.data());
983 LineSectionSize += Str.size() + 1;
985 case dwarf::DW_FORM_strp:
986 case dwarf::DW_FORM_line_strp: {
988 String.getForm() == dwarf::DW_FORM_strp
989 ? DebugStrPool.getEntry(*StringVal)
990 : DebugLineStrPool.getEntry(*StringVal);
992 emitIntOffset(
StringRef.getOffset(),
P.FormParams.Format, LineSectionSize);
995 warn(
"Unsupported string form inside line table.");
1000void DwarfStreamer::emitLineTableProloguePayload(
1005 LineSectionSize += 1;
1006 if (
P.FormParams.Version >= 4) {
1009 LineSectionSize += 1;
1013 LineSectionSize += 1;
1016 LineSectionSize += 1;
1019 LineSectionSize += 1;
1022 LineSectionSize += 1;
1025 for (
auto Length :
P.StandardOpcodeLengths) {
1027 LineSectionSize += 1;
1030 if (
P.FormParams.Version < 5)
1031 emitLineTablePrologueV2IncludeAndFileTable(
P, DebugStrPool,
1034 emitLineTablePrologueV5IncludeAndFileTable(
P, DebugStrPool,
1038void DwarfStreamer::emitLineTableRows(
1040 unsigned AddressByteSize, std::vector<uint64_t> *RowOffsets) {
1049 if (LineTable.
Rows.empty()) {
1055 LineSectionSize += EncodingBuffer.
size();
1061 unsigned FileNum = 1;
1062 unsigned LastLine = 1;
1063 unsigned Column = 0;
1065 unsigned IsStatement = 1;
1069 unsigned RowsSinceLastSequence = 0;
1075 RowOffsets->push_back(LineSectionSize);
1082 MS->
emitIntValue(Row.Address.Address, AddressByteSize);
1096 if (FileNum != Row.File) {
1102 if (Column != Row.Column) {
1103 Column = Row.Column;
1108 if (Discriminator != Row.Discriminator &&
1121 if (Isa != Row.Isa) {
1127 if (IsStatement != Row.IsStmt) {
1128 IsStatement = Row.IsStmt;
1130 LineSectionSize += 1;
1132 if (Row.BasicBlock) {
1134 LineSectionSize += 1;
1137 if (Row.PrologueEnd) {
1139 LineSectionSize += 1;
1142 if (Row.EpilogueBegin) {
1144 LineSectionSize += 1;
1147 int64_t LineDelta = int64_t(Row.Line) - LastLine;
1148 if (!Row.EndSequence) {
1152 LineSectionSize += EncodingBuffer.
size();
1153 EncodingBuffer.
resize(0);
1154 Address = Row.Address.Address;
1155 LastLine = Row.Line;
1156 RowsSinceLastSequence++;
1171 LineSectionSize += EncodingBuffer.
size();
1172 EncodingBuffer.
resize(0);
1174 LastLine = FileNum = IsStatement = 1;
1179 if (RowsSinceLastSequence) {
1183 LineSectionSize += EncodingBuffer.
size();
1184 EncodingBuffer.
resize(0);
1201 Asm->emitLabelDifference(
Hi,
Lo,
Size);
1207void DwarfStreamer::emitPubSectionForUnit(
1209 const std::vector<CompileUnit::AccelInfo> &Names) {
1214 Asm->OutStreamer->switchSection(Sec);
1215 MCSymbol *BeginLabel = Asm->createTempSymbol(
"pub" + SecName +
"_begin");
1216 MCSymbol *EndLabel = Asm->createTempSymbol(
"pub" + SecName +
"_end");
1218 bool HeaderEmitted =
false;
1220 for (
const auto &
Name : Names) {
1221 if (
Name.SkipPubSection)
1224 if (!HeaderEmitted) {
1226 Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
1227 Asm->OutStreamer->emitLabel(BeginLabel);
1229 Asm->emitInt32(Unit.getStartOffset());
1230 Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset());
1231 HeaderEmitted =
true;
1233 Asm->emitInt32(
Name.Die->getOffset());
1236 Asm->OutStreamer->emitBytes(
Name.Name.getString());
1244 Asm->OutStreamer->emitLabel(EndLabel);
1249 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
1250 "names", Unit, Unit.getPubnames());
1255 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
1256 "types", Unit, Unit.getPubtypes());
1261 MS->
switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1264 FrameSectionSize += CIEBytes.
size();
1272 MS->
switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1278 FrameSectionSize += FDEBytes.
size() + 8 + AddrSize;
1288 MS->
switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection());
1289 emitMacroTableImpl(Table, UnitMacroMap,
StringPool, MacInfoSectionSize);
1294 MS->
switchSection(MC->getObjectFileInfo()->getDwarfMacroSection());
1295 emitMacroTableImpl(Table, UnitMacroMap,
StringPool, MacroSectionSize);
1299void DwarfStreamer::emitMacroTableImpl(
const DWARFDebugMacro *MacroTable,
1303 bool DefAttributeIsReported =
false;
1304 bool UndefAttributeIsReported =
false;
1305 bool ImportAttributeIsReported =
false;
1306 for (
const DWARFDebugMacro::MacroList &
List : MacroTable->MacroLists) {
1308 if (UnitIt == UnitMacroMap.
end()) {
1310 "couldn`t find compile unit for the macro table with offset = {0:x}",
1316 DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE();
1317 if (OutputUnitDIE ==
nullptr)
1322 bool hasDWARFv5Header =
false;
1323 for (
auto &V : OutputUnitDIE->
values()) {
1324 if (V.getAttribute() == dwarf::DW_AT_macro_info) {
1327 }
else if (V.getAttribute() == dwarf::DW_AT_macros) {
1328 hasDWARFv5Header =
true;
1335 if (hasDWARFv5Header) {
1338 OutOffset +=
sizeof(
List.Header.Version);
1344 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
1346 warn(
"opcode_operands_table is not supported yet.");
1350 std::optional<uint64_t> StmtListOffset;
1351 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
1353 for (
auto &V : OutputUnitDIE->
values()) {
1354 if (
V.getAttribute() == dwarf::DW_AT_stmt_list) {
1355 StmtListOffset =
V.getDIEInteger().getValue();
1360 if (!StmtListOffset) {
1362 warn(
"couldn`t find line table for macro table.");
1368 OutOffset +=
sizeof(
Flags);
1371 if (StmtListOffset) {
1373 OutOffset +=
List.Header.getOffsetByteSize();
1378 for (
const DWARFDebugMacro::Entry &MacroEntry :
List.Macros) {
1379 if (MacroEntry.Type == 0) {
1384 uint8_t MacroType = MacroEntry.Type;
1385 switch (MacroType) {
1387 bool HasVendorSpecificExtension =
1392 if (HasVendorSpecificExtension) {
1404 OutOffset +=
String.size() + 1;
1406 warn(
"unknown macro type. skip.");
1414 case dwarf::DW_MACRO_define:
1415 case dwarf::DW_MACRO_undef: {
1427 OutOffset +=
String.size() + 1;
1429 case dwarf::DW_MACRO_define_strp:
1430 case dwarf::DW_MACRO_undef_strp:
1431 case dwarf::DW_MACRO_define_strx:
1432 case dwarf::DW_MACRO_undef_strx: {
1433 assert(UnitIt->second->getOrigUnit().getVersion() >= 5);
1437 switch (MacroType) {
1438 case dwarf::DW_MACRO_define_strx: {
1439 MacroType = dwarf::DW_MACRO_define_strp;
1440 if (!DefAttributeIsReported) {
1441 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1442 "DW_MACRO_define_strp.");
1443 DefAttributeIsReported =
true;
1446 case dwarf::DW_MACRO_undef_strx: {
1447 MacroType = dwarf::DW_MACRO_undef_strp;
1448 if (!UndefAttributeIsReported) {
1449 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1450 "DW_MACRO_undef_strp.");
1451 UndefAttributeIsReported =
true;
1470 OutOffset +=
List.Header.getOffsetByteSize();
1473 case dwarf::DW_MACRO_start_file: {
1482 case dwarf::DW_MACRO_end_file: {
1487 case dwarf::DW_MACRO_import:
1488 case dwarf::DW_MACRO_import_sup: {
1489 if (!ImportAttributeIsReported) {
1490 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
1492 ImportAttributeIsReported =
true;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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.
uint16_t getDwarfVersion() const
static LLVM_ABI 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.
MCContext & getContext() const
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, uint32_t Subsec=0)
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 ...
DwarfDirectory MCUseDwarfDirectory
A string table that doesn't need relocations.
LLVM_ABI 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.
TargetMachine * createTargetMachine(const Triple &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.
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.
MCAsmBackend * createMCAsmBackend(const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) const
createMCAsmBackend - Create a target specific assembly parser.
LLVM_ABI MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, std::unique_ptr< MCInstPrinter > IP, std::unique_ptr< MCCodeEmitter > CE, std::unique_ptr< MCAsmBackend > TAB) const
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
LLVM_ABI 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) const
Create a target specific MCStreamer.
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
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 emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit, OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool, std::vector< uint64_t > *RowOffsets=nullptr) override
Emit .debug_line table entry for specified LineTable The optional parameter RowOffsets,...
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 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.
LLVM_ABI MCTargetOptions InitMCTargetOptionsFromFlags()
This is an optimization pass for GlobalISel generic memory operations.
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.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
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...
LLVM_ABI 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.
LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
LLVM_ABI 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 TripleStr, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
void set(uint64_t New) const