17#include "llvm/Config/config.h"
66 unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
67 if (MinInsnLength == 1)
69 if (AddrDelta % MinInsnLength != 0) {
73 return AddrDelta / MinInsnLength;
77 UseRelocs = Ctx.getAsmInfo()->doesDwarfUseRelocationsAcrossSections();
80 Ctx.getObjectFileInfo()->getDwarfLineStrSection();
81 assert(DwarfLineStrSection &&
"DwarfLineStrSection must not be NULL");
134static inline const MCExpr *
153 auto I = MCLineDivisions.find(Sec);
154 if (
I == MCLineDivisions.end())
157 auto &Entries =
I->second;
171 Entries.push_back(EndEntry);
182 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
198 bool EndEntryEmitted =
false;
199 for (
auto It = LineEntries.begin(); It != LineEntries.end(); ++It) {
200 auto LineEntry = *It;
201 MCSymbol *CurrLabel = LineEntry.getLabel();
204 if (LineEntry.LineStreamLabel) {
206 auto *Label = CurrLabel;
207 auto NextIt = It + 1;
212 if (!Label && NextIt != LineEntries.end()) {
213 Label = NextIt->getLabel();
219 MCOS->
emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
223 if (LineEntry.IsEndEntry) {
227 EndEntryEmitted =
true;
231 int64_t LineDelta =
static_cast<int64_t
>(LineEntry.getLine()) - LastLine;
233 if (FileNum != LineEntry.getFileNum()) {
234 FileNum = LineEntry.getFileNum();
235 MCOS->
emitInt8(dwarf::DW_LNS_set_file);
238 if (Column != LineEntry.getColumn()) {
239 Column = LineEntry.getColumn();
240 MCOS->
emitInt8(dwarf::DW_LNS_set_column);
243 if (Discriminator != LineEntry.getDiscriminator() &&
245 Discriminator = LineEntry.getDiscriminator();
247 MCOS->
emitInt8(dwarf::DW_LNS_extended_op);
249 MCOS->
emitInt8(dwarf::DW_LNE_set_discriminator);
252 if (Isa != LineEntry.getIsa()) {
253 Isa = LineEntry.getIsa();
254 MCOS->
emitInt8(dwarf::DW_LNS_set_isa);
258 Flags = LineEntry.getFlags();
259 MCOS->
emitInt8(dwarf::DW_LNS_negate_stmt);
262 MCOS->
emitInt8(dwarf::DW_LNS_set_basic_block);
264 MCOS->
emitInt8(dwarf::DW_LNS_set_prologue_end);
266 MCOS->
emitInt8(dwarf::DW_LNS_set_epilogue_begin);
275 LastLine = LineEntry.getLine();
276 PrevLabel = CurrLabel;
277 IsAtStartSeq =
false;
285 if (!EndEntryEmitted && !IsAtStartSeq)
294 auto *LineSym = ctx.createTempSymbol();
296 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
315 if (LineTables.empty())
319 std::optional<MCDwarfLineStr> LineStr;
321 LineStr.emplace(context);
327 for (
const auto &CUIDTablePair : LineTables) {
328 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
332 LineStr->emitSection(MCOS);
337 if (!HasSplitLineTable)
339 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
341 MCOS.
emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);
344std::pair<MCSymbol *, MCSymbol *>
346 std::optional<MCDwarfLineStr> &LineStr)
const {
347 static const char StandardOpcodeLengths[] = {
361 assert(std::size(StandardOpcodeLengths) >=
363 return Emit(MCOS, Params,
371 if (!Context.getAsmInfo()->doesSetDirectiveSuppressReloc())
375 MCSymbol *ABS = Context.createTempSymbol();
395 if (!LineStrings.isFinalized())
396 LineStrings.finalizeInOrder();
398 Data.resize(LineStrings.getSize());
404 return LineStrings.add(Path);
413 if (Ctx.getAsmInfo()->needsDwarfSectionOffsetDirective()) {
423void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
444 bool EmitMD5,
bool HasAnySource,
445 std::optional<MCDwarfLineStr> &LineStr) {
457 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
468 LineStr->emitRef(MCOS, Source);
476void MCDwarfLineTableHeader::emitV5FileDirTables(
477 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
484 : dwarf::DW_FORM_string);
487 SmallString<256> Dir;
494 CompDir = LineStr->getSaver().save(CompDir);
498 LineStr->emitRef(MCOS, CompDir);
500 LineStr->emitRef(MCOS, Dir);
514 uint64_t Entries = 2;
522 : dwarf::DW_FORM_string);
532 : dwarf::DW_FORM_string);
542 "No root file and no .file directives");
549std::pair<MCSymbol *, MCSymbol *>
552 std::optional<MCDwarfLineStr> &LineStr)
const {
572 if (LineTableVersion >= 5) {
592 if (LineTableVersion >= 4)
600 for (
char Length : StandardOpcodeLengths)
605 if (LineTableVersion >= 5)
606 emitV5FileDirTables(MCOS, LineStr);
608 emitV2FileDirTables(MCOS);
614 return std::make_pair(LineStartSym, LineEndSym);
618 std::optional<MCDwarfLineStr> &LineStr)
const {
619 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
622 for (
const auto &LineSec : MCLineSections.getMCLineEntries())
623 emitOne(MCOS, LineSec.first, LineSec.second);
632 std::optional<MD5::MD5Result> Checksum,
633 std::optional<StringRef> Source,
634 uint16_t DwarfVersion,
unsigned FileNumber) {
635 return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
641 std::optional<MD5::MD5Result> Checksum) {
644 return RootFile.
Checksum == Checksum;
649 std::optional<MD5::MD5Result> Checksum,
650 std::optional<StringRef> Source,
651 uint16_t DwarfVersion,
unsigned FileNumber) {
654 if (FileName.
empty()) {
655 FileName =
"<stdin>";
667 if (FileNumber == 0) {
675 if (!IterBool.second)
676 return IterBool.first->second;
686 if (!File.Name.empty())
690 if (Directory.
empty()) {
693 if (!tFileName.
empty()) {
695 if (!Directory.
empty())
696 FileName = tFileName;
703 if (Directory.
empty()) {
717 File.Name = std::string(FileName);
718 File.DirIndex = DirIndex;
719 File.Checksum = Checksum;
721 File.Source = Source;
722 if (Source.has_value())
731 int64_t LineDelta,
uint64_t AddrDelta) {
746 int64_t LineDelta,
uint64_t AddrDelta,
749 bool NeedCopy =
false;
761 if (AddrDelta == MaxSpecialAddrDelta)
762 Out.
push_back(dwarf::DW_LNS_const_add_pc);
763 else if (AddrDelta) {
767 Out.
push_back(dwarf::DW_LNS_extended_op);
769 Out.
push_back(dwarf::DW_LNE_end_sequence);
780 Out.
push_back(dwarf::DW_LNS_advance_line);
789 if (LineDelta == 0 && AddrDelta == 0) {
798 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
807 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
809 Out.
push_back(dwarf::DW_LNS_const_add_pc);
822 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
845 ? dwarf::DW_FORM_sec_offset
847 : dwarf::DW_FORM_data4);
848 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
851 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
853 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
854 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
856 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
858 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
860 if (!DwarfDebugFlags.
empty())
861 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
862 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
863 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
870 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
871 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
872 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
873 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
885 const MCSymbol *InfoSectionSymbol) {
892 unsigned UnitLengthBytes =
898 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
904 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
905 if (Pad == 2 * AddrSize)
911 Length += 2 * AddrSize * Sections.size();
926 if (InfoSectionSymbol)
936 for(
int i = 0; i < Pad; i++)
942 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
943 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
944 assert(StartSymbol &&
"StartSymbol must not be NULL");
945 assert(EndSymbol &&
"EndSymbol must not be NULL");
963 const MCSymbol *AbbrevSectionSymbol,
978 unsigned UnitLengthBytes =
1000 MCOS->
emitInt8(dwarf::DW_UT_compile);
1005 if (AbbrevSectionSymbol)
1021 if (LineSectionSymbol)
1039 const auto TextSection = Sections.begin();
1040 assert(TextSection != Sections.end() &&
"No text section found");
1042 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1043 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1044 assert(StartSymbol &&
"StartSymbol must not be NULL");
1045 assert(EndSymbol &&
"EndSymbol must not be NULL");
1059 if (MCDwarfDirs.
size() > 0) {
1068 MCDwarfFiles.
empty()
1082 if (!DwarfDebugFlags.
empty()){
1089 if (!DwarfDebugProducer.
empty())
1097 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1102 const std::vector<MCGenDwarfLabelEntry> &Entries =
1104 for (
const auto &Entry : Entries) {
1149 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1150 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1151 const MCExpr *SectionStartAddr =
1153 const MCExpr *SectionSize =
1155 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1156 MCOS->
emitValue(SectionStartAddr, AddrSize);
1159 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1166 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1167 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1170 const MCExpr *SectionStartAddr =
1173 MCOS->
emitValue(SectionStartAddr, AddrSize);
1176 const MCExpr *SectionSize =
1187 return RangesSymbol;
1199 bool CreateDwarfSectionSymbols =
1201 MCSymbol *LineSectionSymbol =
nullptr;
1202 if (CreateDwarfSectionSymbols)
1204 MCSymbol *AbbrevSectionSymbol =
nullptr;
1205 MCSymbol *InfoSectionSymbol =
nullptr;
1218 const bool UseRangesSection =
1221 CreateDwarfSectionSymbols |= UseRangesSection;
1224 if (CreateDwarfSectionSymbols) {
1229 if (CreateDwarfSectionSymbols) {
1239 if (UseRangesSection) {
1248 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1260 if (Symbol->isTemporary())
1271 if (Name.starts_with(
"_"))
1272 Name = Name.
substr(1, Name.size()-1);
1279 unsigned CurBuffer =
SrcMgr.FindBufferContainingLoc(
Loc);
1280 unsigned LineNumber =
SrcMgr.FindLineNumber(
Loc, CurBuffer);
1305 unsigned symbolEncoding) {
1307 unsigned format = symbolEncoding & 0x0f;
1326 unsigned symbolEncoding,
bool isEH) {
1340 unsigned symbolEncoding) {
1352class FrameEmitterImpl {
1353 int64_t CFAOffset = 0;
1354 int64_t InitialCFAOffset = 0;
1356 MCObjectStreamer &Streamer;
1359 FrameEmitterImpl(
bool IsEH, MCObjectStreamer &Streamer)
1360 : IsEH(IsEH), Streamer(Streamer) {}
1363 void EmitCompactUnwind(
const MCDwarfFrameInfo &frame);
1365 const MCSymbol &EmitCIE(
const MCDwarfFrameInfo &
F);
1366 void EmitFDE(
const MCSymbol &cieStart,
const MCDwarfFrameInfo &frame,
1367 bool LastInSection,
const MCSymbol &SectionStart);
1369 MCSymbol *BaseLabel);
1370 void emitCFIInstruction(
const MCCFIInstruction &Instr);
1381 auto *
MRI = Streamer.getContext().getRegisterInfo();
1383 switch (
Instr.getOperation()) {
1385 unsigned Reg1 =
Instr.getRegister();
1386 unsigned Reg2 =
Instr.getRegister2();
1388 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1389 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1391 Streamer.emitInt8(dwarf::DW_CFA_register);
1392 Streamer.emitULEB128IntValue(Reg1);
1393 Streamer.emitULEB128IntValue(Reg2);
1397 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1401 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1405 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1409 unsigned Reg =
Instr.getRegister();
1410 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1411 Streamer.emitULEB128IntValue(
Reg);
1416 const bool IsRelative =
1419 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1422 CFAOffset +=
Instr.getOffset();
1424 CFAOffset =
Instr.getOffset();
1426 Streamer.emitULEB128IntValue(CFAOffset);
1431 unsigned Reg =
Instr.getRegister();
1433 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(
Reg);
1434 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1435 Streamer.emitULEB128IntValue(
Reg);
1436 CFAOffset =
Instr.getOffset();
1437 Streamer.emitULEB128IntValue(CFAOffset);
1442 unsigned Reg =
Instr.getRegister();
1444 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(
Reg);
1445 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1446 Streamer.emitULEB128IntValue(
Reg);
1452 unsigned Reg =
Instr.getRegister();
1454 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(
Reg);
1455 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1456 Streamer.emitULEB128IntValue(
Reg);
1457 CFAOffset =
Instr.getOffset();
1458 Streamer.emitULEB128IntValue(CFAOffset);
1459 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1465 const bool IsRelative =
1468 unsigned Reg =
Instr.getRegister();
1470 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(
Reg);
1478 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1479 Streamer.emitULEB128IntValue(
Reg);
1480 Streamer.emitSLEB128IntValue(
Offset);
1481 }
else if (
Reg < 64) {
1482 Streamer.emitInt8(dwarf::DW_CFA_offset +
Reg);
1483 Streamer.emitULEB128IntValue(
Offset);
1485 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1486 Streamer.emitULEB128IntValue(
Reg);
1487 Streamer.emitULEB128IntValue(
Offset);
1492 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1495 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1498 unsigned Reg =
Instr.getRegister();
1499 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1500 Streamer.emitULEB128IntValue(
Reg);
1504 unsigned Reg =
Instr.getRegister();
1506 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(
Reg);
1508 Streamer.emitInt8(dwarf::DW_CFA_restore |
Reg);
1510 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1511 Streamer.emitULEB128IntValue(
Reg);
1516 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1517 Streamer.emitULEB128IntValue(
Instr.getOffset());
1521 Streamer.emitBytes(
Instr.getValues());
1524 Streamer.emitLabel(
Instr.getCfiLabel(),
Instr.getLoc());
1527 unsigned Reg =
Instr.getRegister();
1529 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(
Reg);
1535 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1536 Streamer.emitULEB128IntValue(
Reg);
1537 Streamer.emitSLEB128IntValue(
Offset);
1539 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1540 Streamer.emitULEB128IntValue(
Reg);
1541 Streamer.emitULEB128IntValue(
Offset);
1555 if (Label && !
Label->isDefined())
continue;
1558 if (BaseLabel && Label) {
1560 if (ThisSym != BaseLabel) {
1561 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1562 BaseLabel = ThisSym;
1566 emitCFIInstruction(Instr);
1598 if (!Encoding)
return;
1602 if (!DwarfEHFrameOnly && Frame.
Lsda)
1603 Encoding |= 0x40000000;
1608 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1617 Streamer.emitIntValue(Encoding,
Size);
1624 Streamer.emitIntValue(0,
Size);
1628 if (!DwarfEHFrameOnly && Frame.
Lsda)
1629 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1631 Streamer.emitIntValue(0,
Size);
1637 switch (DwarfVersion) {
1650 MCContext &context = Streamer.getContext();
1655 Streamer.emitLabel(sectionStart);
1670 *sectionEnd, UnitLengthBytes);
1676 Streamer.emitIntValue(CIE_ID, OffsetSize);
1680 Streamer.emitInt8(CIEVersion);
1684 Augmentation +=
"z";
1686 Augmentation +=
"P";
1688 Augmentation +=
"L";
1689 Augmentation +=
"R";
1691 Augmentation +=
"S";
1693 Augmentation +=
"B";
1695 Augmentation +=
"G";
1696 Streamer.emitBytes(Augmentation);
1698 Streamer.emitInt8(0);
1700 if (CIEVersion >= 4) {
1705 Streamer.emitInt8(0);
1716 if (
RAReg ==
static_cast<unsigned>(INT_MAX))
1717 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1719 if (CIEVersion == 1) {
1721 "DWARF 2 encodes return_address_register in one byte");
1722 Streamer.emitInt8(
RAReg);
1724 Streamer.emitULEB128IntValue(
RAReg);
1728 unsigned augmentationLength = 0;
1732 augmentationLength += 1;
1734 augmentationLength +=
1738 augmentationLength += 1;
1740 augmentationLength += 1;
1742 Streamer.emitULEB128IntValue(augmentationLength);
1765 emitCFIInstructions(Instructions,
nullptr);
1768 InitialCFAOffset = CFAOffset;
1773 Streamer.emitLabel(sectionEnd);
1774 return *sectionStart;
1777void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1781 MCContext &context = Streamer.getContext();
1786 CFAOffset = InitialCFAOffset;
1799 Streamer.emitLabel(fdeStart);
1812 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1817 unsigned PCEncoding =
1829 unsigned augmentationLength = 0;
1834 Streamer.emitULEB128IntValue(augmentationLength);
1849 Streamer.emitValueToAlignment(
Align(Alignment));
1851 Streamer.emitLabel(fdeEnd);
1859 explicit CIEKey(
const MCDwarfFrameInfo &Frame)
1860 : Personality(Frame.Personality),
1861 PersonalityEncoding(Frame.PersonalityEncoding),
1862 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1863 IsSimple(Frame.IsSimple),
RAReg(Frame.
RAReg),
1864 IsBKeyFrame(Frame.IsBKeyFrame),
1865 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1867 StringRef PersonalityName()
const {
1870 return Personality->getName();
1874 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1875 IsSignalFrame, IsSimple,
RAReg, IsBKeyFrame,
1877 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1880 Other.IsMTETaggedFrame);
1884 return Personality ==
Other.Personality &&
1885 PersonalityEncoding ==
Other.PersonalityEncoding &&
1886 LsdaEncoding ==
Other.LsdaEncoding &&
1887 IsSignalFrame ==
Other.IsSignalFrame && IsSimple ==
Other.IsSimple &&
1889 IsMTETaggedFrame ==
Other.IsMTETaggedFrame;
1893 const MCSymbol *Personality =
nullptr;
1894 unsigned PersonalityEncoding = 0;
1895 unsigned LsdaEncoding = -1;
1896 bool IsSignalFrame =
false;
1897 bool IsSimple =
false;
1898 unsigned RAReg = UINT_MAX;
1899 bool IsBKeyFrame =
false;
1900 bool IsMTETaggedFrame =
false;
1909 const MCAsmInfo *AsmInfo = Context.getAsmInfo();
1910 FrameEmitterImpl
Emitter(IsEH, Streamer);
1917 bool SectionEmitted =
false;
1920 if (!SectionEmitted) {
1923 SectionEmitted =
true;
1925 NeedsEHFrameSection |=
1928 Emitter.EmitCompactUnwind(Frame);
1936 if (!NeedsEHFrameSection && IsEH)
return;
1943 MCSymbol *SectionStart = Context.createTempSymbol();
1951 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1954 return CIEKey(
X) < CIEKey(
Y);
1957 const MCSymbol *LastCIEStart =
nullptr;
1958 for (
auto I = FrameArrayX.begin(), E = FrameArrayX.end();
I != E;) {
1972 if (!LastCIEStart || (IsEH &&
Key != LastKey)) {
1974 LastCIEStart = &
Emitter.EmitCIE(Frame);
1977 Emitter.EmitFDE(*LastCIEStart, Frame,
I == E, *SectionStart);
1994 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1997 Out.
push_back(dwarf::DW_CFA_advance_loc1);
2000 Out.
push_back(dwarf::DW_CFA_advance_loc2);
2004 Out.
push_back(dwarf::DW_CFA_advance_loc4);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
This file contains constants used for implementing Dwarf debug support.
static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH)
static uint64_t SpecialAddr(MCDwarfLineTableParams Params, uint64_t op)
Given a special op, return the address skip amount (in units of DWARF2_LINE_MIN_INSN_LENGTH).
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum)
static uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta)
static const MCExpr * forceExpAbs(MCStreamer &OS, const MCExpr *Expr)
static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, bool EmitMD5, bool HasAnySource, std::optional< MCDwarfLineStr > &LineStr)
static const MCExpr * makeEndMinusStartExpr(MCContext &Ctx, const MCSymbol &Start, const MCSymbol &End, int IntVal)
static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion)
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
static int getDataAlignmentFactor(MCStreamer &streamer)
static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)
static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr MCPhysReg RAReg
This file defines the SmallString class.
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Tagged union holding either a T or a Error.
Generic interface to target specific assembler backends.
This class is intended to be used as a base class for asm properties and features specific to the tar...
unsigned getMinInstAlignment() const
const std::vector< MCCFIInstruction > & getInitialFrameState() const
bool needsDwarfSectionOffsetDirective() const
bool doesDwarfUseRelocationsAcrossSections() const
virtual const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
bool isStackGrowthDirectionUp() const
True if target stack grow up.
unsigned getCalleeSaveStackSlotSize() const
Get the callee-saved register stack slot size in bytes.
bool doDwarfFDESymbolsUseAbsDiff() const
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI void remapDebugPath(SmallVectorImpl< char > &Path)
Remap one path in-place as per the debug prefix map.
const SetVector< MCSection * > & getGenDwarfSectionSyms()
const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)
StringRef getDwarfDebugProducer()
StringRef getDwarfDebugFlags()
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
StringRef getCompilationDir() const
Get the compilation directory for DW_AT_comp_dir The compilation directory should be set with setComp...
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
unsigned getDwarfCompileUnitID()
const MCRegisterInfo * getRegisterInfo() const
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)
const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const
unsigned getGenDwarfFileNumber()
uint16_t getDwarfVersion() const
const MCAsmInfo * getAsmInfo() const
LLVM_ABI void finalizeDwarfSections(MCStreamer &MCOS)
Remove empty sections from SectionsForRanges, to avoid generating useless debug info for them.
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
dwarf::DwarfFormat getDwarfFormat() const
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
LLVM_ABI void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
static LLVM_ABI void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
static LLVM_ABI void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
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 the line information for the dwarf line table entries.
void setEndLabel(MCSymbol *EndLabel)
MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc, MCSymbol *lineStreamLabel=nullptr, SMLoc streamLabelDefLoc={})
MCSymbol * LineStreamLabel
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
LLVM_ABI void emitSection(MCStreamer *MCOS)
Emit the .debug_line_str section if appropriate.
LLVM_ABI MCDwarfLineStr(MCContext &Ctx)
Construct an instance that can emit .debug_line_str (for use in a normal v5 line table).
LLVM_ABI SmallString< 0 > getFinalizedData()
Returns finalized section.
LLVM_ABI void emitRef(MCStreamer *MCOS, StringRef Path)
Emit a reference to the string.
LLVM_ABI size_t addString(StringRef Path)
Adds path Path to the line string.
LLVM_ABI void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
MCDwarfFile & getRootFile()
const MCLineSection & getMCLineSections() const
static LLVM_ABI void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
static LLVM_ABI void emitOne(MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries)
LLVM_ABI Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
LLVM_ABI void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, std::optional< MCDwarfLineStr > &LineStr) const
Instances of this class represent the information from a dwarf .loc directive.
Base class for the full range of assembler expressions which are needed for parsing.
static LLVM_ABI void Emit(MCStreamer *MCOS)
MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, MCSymbol *label)
static LLVM_ABI void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
LLVM_ABI void addEndEntry(MCSymbol *EndLabel)
void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec)
std::vector< MCDwarfLineEntry > MCDwarfLineEntryCollection
MCSection * getDwarfRangesSection() const
bool getSupportsCompactUnwindWithoutEHFrame() const
MCSection * getDwarfLineStrSection() const
unsigned getCompactUnwindDwarfEHFrameOnly() const
MCSection * getDwarfRnglistsSection() const
MCSection * getDwarfLineSection() const
MCSection * getDwarfInfoSection() const
MCSection * getDwarfFrameSection() const
unsigned getFDEEncoding() const
MCSection * getDwarfAbbrevSection() const
bool getOmitDwarfIfHaveCompactUnwind() const
MCSection * getDwarfARangesSection() const
MCSection * getCompactUnwindSection() const
Streaming object file generation interface.
void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
Streaming machine code generation interface.
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
void generateCompactUnwindEncodings(MCAsmBackend *MAB)
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
MCContext & getContext() const
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)
Emit the absolute difference between two symbols.
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.
virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
If targets does not support representing debug line section by .loc/.file directives in assembly outp...
void emitInt16(uint64_t Value)
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
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 emitULEB128Value(const MCExpr *Value)
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
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)
MCSection * getCurrentSectionOnly() const
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)
Emit the debug line end entry.
void emitInt8(uint64_t Value)
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Represents a location in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const uint32_t DW_CIE_ID
Special ID values that distinguish a CIE from a FDE in DWARF CFI.
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
const uint64_t DW64_CIE_ID
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_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
void stable_sort(R &&Range)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
ArrayRef(const T &OneElt) -> ArrayRef< T >
void appendLEB128(SmallVectorImpl< U > &Buffer, T Value)
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
const MCSymbol * Personality
unsigned PersonalityEncoding
uint64_t CompactUnwindEncoding
std::vector< MCCFIInstruction > Instructions
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.