17#include "llvm/Config/config.h"
67 if (MinInsnLength == 1)
69 if (AddrDelta % MinInsnLength != 0) {
73 return AddrDelta / MinInsnLength;
81 assert(DwarfLineStrSection &&
"DwarfLineStrSection must not be NULL");
135static inline const MCExpr *
153 auto I = MCLineDivisions.
find(Sec);
154 if (
I != MCLineDivisions.
end()) {
155 auto &Entries =
I->second;
156 auto EndEntry = Entries.back();
157 EndEntry.setEndLabel(EndLabel);
158 Entries.push_back(EndEntry);
170 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
186 bool EndEntryEmitted =
false;
188 MCSymbol *Label = LineEntry.getLabel();
191 if (LineEntry.LineStreamLabel) {
197 MCOS->
emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
201 if (LineEntry.IsEndEntry) {
205 EndEntryEmitted =
true;
209 int64_t LineDelta =
static_cast<int64_t
>(LineEntry.getLine()) - LastLine;
211 if (FileNum != LineEntry.getFileNum()) {
212 FileNum = LineEntry.getFileNum();
213 MCOS->
emitInt8(dwarf::DW_LNS_set_file);
216 if (Column != LineEntry.getColumn()) {
217 Column = LineEntry.getColumn();
218 MCOS->
emitInt8(dwarf::DW_LNS_set_column);
221 if (Discriminator != LineEntry.getDiscriminator() &&
223 Discriminator = LineEntry.getDiscriminator();
225 MCOS->
emitInt8(dwarf::DW_LNS_extended_op);
227 MCOS->
emitInt8(dwarf::DW_LNE_set_discriminator);
230 if (Isa != LineEntry.getIsa()) {
231 Isa = LineEntry.getIsa();
232 MCOS->
emitInt8(dwarf::DW_LNS_set_isa);
236 Flags = LineEntry.getFlags();
237 MCOS->
emitInt8(dwarf::DW_LNS_negate_stmt);
240 MCOS->
emitInt8(dwarf::DW_LNS_set_basic_block);
242 MCOS->
emitInt8(dwarf::DW_LNS_set_prologue_end);
244 MCOS->
emitInt8(dwarf::DW_LNS_set_epilogue_begin);
253 LastLine = LineEntry.getLine();
255 IsAtStartSeq =
false;
263 if (!EndEntryEmitted && !IsAtStartSeq)
272 auto *LineSym = ctx.createTempSymbol();
274 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
293 if (LineTables.empty())
297 std::optional<MCDwarfLineStr> LineStr;
299 LineStr.emplace(context);
305 for (
const auto &CUIDTablePair : LineTables) {
306 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
310 LineStr->emitSection(MCOS);
315 if (!HasSplitLineTable)
317 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
319 MCOS.
emitLabel(Header.
Emit(&MCOS, Params, {}, NoLineStr).second);
322std::pair<MCSymbol *, MCSymbol *>
324 std::optional<MCDwarfLineStr> &LineStr)
const {
325 static const char StandardOpcodeLengths[] = {
339 assert(std::size(StandardOpcodeLengths) >=
341 return Emit(MCOS, Params,
348 assert(!isa<MCSymbolRefExpr>(Expr));
354 OS.emitAssignment(ABS, Expr);
382 return LineStrings.
add(Path);
401void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
422 bool EmitMD5,
bool HasAnySource,
423 std::optional<MCDwarfLineStr> &LineStr) {
435 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
447void MCDwarfLineTableHeader::emitV5FileDirTables(
448 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
455 : dwarf::DW_FORM_string);
465 CompDir = LineStr->getSaver().save(CompDir);
469 LineStr->emitRef(MCOS, CompDir);
471 LineStr->emitRef(MCOS, Dir);
493 : dwarf::DW_FORM_string);
503 : dwarf::DW_FORM_string);
513 "No root file and no .file directives");
520std::pair<MCSymbol *, MCSymbol *>
523 std::optional<MCDwarfLineStr> &LineStr)
const {
543 if (LineTableVersion >= 5) {
563 if (LineTableVersion >= 4)
571 for (
char Length : StandardOpcodeLengths)
576 if (LineTableVersion >= 5)
577 emitV5FileDirTables(MCOS, LineStr);
579 emitV2FileDirTables(MCOS);
585 return std::make_pair(LineStartSym, LineEndSym);
589 std::optional<MCDwarfLineStr> &LineStr)
const {
590 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
594 emitOne(MCOS, LineSec.first, LineSec.second);
603 std::optional<MD5::MD5Result> Checksum,
604 std::optional<StringRef> Source,
605 uint16_t DwarfVersion,
unsigned FileNumber) {
606 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
612 std::optional<MD5::MD5Result> Checksum) {
615 return RootFile.
Checksum == Checksum;
620 std::optional<MD5::MD5Result> Checksum,
621 std::optional<StringRef> Source,
622 uint16_t DwarfVersion,
unsigned FileNumber) {
625 if (FileName.
empty()) {
626 FileName =
"<stdin>";
638 if (FileNumber == 0) {
644 std::make_pair((Directory +
Twine(
'\0') + FileName).toStringRef(Buffer),
646 if (!IterBool.second)
647 return IterBool.first->second;
657 if (!File.Name.empty())
658 return make_error<StringError>(
"file number already allocated",
661 if (Directory.
empty()) {
664 if (!tFileName.
empty()) {
666 if (!Directory.
empty())
667 FileName = tFileName;
674 if (Directory.
empty()) {
688 File.Name = std::string(FileName);
689 File.DirIndex = DirIndex;
690 File.Checksum = Checksum;
692 File.Source = Source;
693 if (Source.has_value())
702 int64_t LineDelta,
uint64_t AddrDelta) {
717 int64_t LineDelta,
uint64_t AddrDelta,
721 bool NeedCopy =
false;
733 if (AddrDelta == MaxSpecialAddrDelta)
734 Out.
push_back(dwarf::DW_LNS_const_add_pc);
735 else if (AddrDelta) {
739 Out.
push_back(dwarf::DW_LNS_extended_op);
741 Out.
push_back(dwarf::DW_LNE_end_sequence);
752 Out.
push_back(dwarf::DW_LNS_advance_line);
761 if (LineDelta == 0 && AddrDelta == 0) {
770 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
779 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
781 Out.
push_back(dwarf::DW_LNS_const_add_pc);
794 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
817 ? dwarf::DW_FORM_sec_offset
819 : dwarf::DW_FORM_data4);
820 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
823 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
825 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
826 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
828 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
830 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
832 if (!DwarfDebugFlags.
empty())
833 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
834 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
835 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
842 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
843 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
844 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
845 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
857 const MCSymbol *InfoSectionSymbol) {
864 unsigned UnitLengthBytes =
870 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
876 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
877 if (Pad == 2 * AddrSize)
883 Length += 2 * AddrSize * Sections.size();
898 if (InfoSectionSymbol)
908 for(
int i = 0; i < Pad; i++)
914 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
915 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
916 assert(StartSymbol &&
"StartSymbol must not be NULL");
917 assert(EndSymbol &&
"EndSymbol must not be NULL");
936 const MCSymbol *AbbrevSectionSymbol,
951 unsigned UnitLengthBytes =
973 MCOS->
emitInt8(dwarf::DW_UT_compile);
978 if (AbbrevSectionSymbol)
994 if (LineSectionSymbol)
1012 const auto TextSection = Sections.begin();
1013 assert(TextSection != Sections.end() &&
"No text section found");
1015 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1016 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1017 assert(StartSymbol &&
"StartSymbol must not be NULL");
1018 assert(EndSymbol &&
"EndSymbol must not be NULL");
1034 if (MCDwarfDirs.
size() > 0) {
1043 MCDwarfFiles.
empty()
1057 if (!DwarfDebugFlags.
empty()){
1064 if (!DwarfDebugProducer.
empty())
1072 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1077 const std::vector<MCGenDwarfLabelEntry> &Entries =
1079 for (
const auto &Entry : Entries) {
1125 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1126 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1129 const MCExpr *SectionSize =
1131 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1132 MCOS->
emitValue(SectionStartAddr, AddrSize);
1135 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1142 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1143 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1149 MCOS->
emitValue(SectionStartAddr, AddrSize);
1152 const MCExpr *SectionSize =
1163 return RangesSymbol;
1175 bool CreateDwarfSectionSymbols =
1177 MCSymbol *LineSectionSymbol =
nullptr;
1178 if (CreateDwarfSectionSymbols)
1180 MCSymbol *AbbrevSectionSymbol =
nullptr;
1181 MCSymbol *InfoSectionSymbol =
nullptr;
1194 const bool UseRangesSection =
1197 CreateDwarfSectionSymbols |= UseRangesSection;
1200 if (CreateDwarfSectionSymbols) {
1205 if (CreateDwarfSectionSymbols) {
1215 if (UseRangesSection) {
1224 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1236 if (Symbol->isTemporary())
1247 if (Name.starts_with(
"_"))
1248 Name = Name.substr(1, Name.size()-1);
1281 unsigned symbolEncoding) {
1283 unsigned format = symbolEncoding & 0x0f;
1302 unsigned symbolEncoding,
bool isEH) {
1316 unsigned symbolEncoding) {
1328class FrameEmitterImpl {
1329 int64_t CFAOffset = 0;
1330 int64_t InitialCFAOffset = 0;
1336 : IsEH(IsEH), Streamer(Streamer) {}
1343 bool LastInSection,
const MCSymbol &SectionStart);
1357 auto *
MRI = Streamer.getContext().getRegisterInfo();
1359 switch (
Instr.getOperation()) {
1361 unsigned Reg1 =
Instr.getRegister();
1362 unsigned Reg2 =
Instr.getRegister2();
1364 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1365 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1367 Streamer.emitInt8(dwarf::DW_CFA_register);
1368 Streamer.emitULEB128IntValue(Reg1);
1369 Streamer.emitULEB128IntValue(Reg2);
1373 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1377 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1381 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1385 unsigned Reg =
Instr.getRegister();
1386 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1387 Streamer.emitULEB128IntValue(Reg);
1392 const bool IsRelative =
1395 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1398 CFAOffset +=
Instr.getOffset();
1400 CFAOffset =
Instr.getOffset();
1402 Streamer.emitULEB128IntValue(CFAOffset);
1407 unsigned Reg =
Instr.getRegister();
1409 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1410 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1411 Streamer.emitULEB128IntValue(Reg);
1412 CFAOffset =
Instr.getOffset();
1413 Streamer.emitULEB128IntValue(CFAOffset);
1418 unsigned Reg =
Instr.getRegister();
1420 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1421 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1422 Streamer.emitULEB128IntValue(Reg);
1428 unsigned Reg =
Instr.getRegister();
1430 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1431 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1432 Streamer.emitULEB128IntValue(Reg);
1433 CFAOffset =
Instr.getOffset();
1434 Streamer.emitULEB128IntValue(CFAOffset);
1435 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1441 const bool IsRelative =
1444 unsigned Reg =
Instr.getRegister();
1446 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1454 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1455 Streamer.emitULEB128IntValue(Reg);
1456 Streamer.emitSLEB128IntValue(
Offset);
1457 }
else if (Reg < 64) {
1458 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1459 Streamer.emitULEB128IntValue(
Offset);
1461 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1462 Streamer.emitULEB128IntValue(Reg);
1463 Streamer.emitULEB128IntValue(
Offset);
1468 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1471 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1474 unsigned Reg =
Instr.getRegister();
1475 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1476 Streamer.emitULEB128IntValue(Reg);
1480 unsigned Reg =
Instr.getRegister();
1482 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1484 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1486 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1487 Streamer.emitULEB128IntValue(Reg);
1492 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1493 Streamer.emitULEB128IntValue(
Instr.getOffset());
1497 Streamer.emitBytes(
Instr.getValues());
1500 Streamer.emitLabel(
Instr.getCfiLabel(),
Instr.getLoc());
1503 unsigned Reg =
Instr.getRegister();
1505 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1511 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1512 Streamer.emitULEB128IntValue(Reg);
1513 Streamer.emitSLEB128IntValue(
Offset);
1515 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1516 Streamer.emitULEB128IntValue(Reg);
1517 Streamer.emitULEB128IntValue(
Offset);
1531 if (Label && !
Label->isDefined())
continue;
1534 if (BaseLabel && Label) {
1536 if (ThisSym != BaseLabel) {
1537 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1538 BaseLabel = ThisSym;
1542 emitCFIInstruction(Instr);
1548 MCContext &Context = Streamer.getContext();
1574 if (!Encoding)
return;
1578 if (!DwarfEHFrameOnly && Frame.
Lsda)
1579 Encoding |= 0x40000000;
1584 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1593 Streamer.emitIntValue(Encoding,
Size);
1600 Streamer.emitIntValue(0,
Size);
1604 if (!DwarfEHFrameOnly && Frame.
Lsda)
1605 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1607 Streamer.emitIntValue(0,
Size);
1613 switch (DwarfVersion) {
1626 MCContext &context = Streamer.getContext();
1631 Streamer.emitLabel(sectionStart);
1646 *sectionEnd, UnitLengthBytes);
1652 Streamer.emitIntValue(CIE_ID, OffsetSize);
1656 Streamer.emitInt8(CIEVersion);
1660 Augmentation +=
"z";
1662 Augmentation +=
"P";
1664 Augmentation +=
"L";
1665 Augmentation +=
"R";
1667 Augmentation +=
"S";
1669 Augmentation +=
"B";
1671 Augmentation +=
"G";
1672 Streamer.emitBytes(Augmentation);
1674 Streamer.emitInt8(0);
1676 if (CIEVersion >= 4) {
1681 Streamer.emitInt8(0);
1692 if (
RAReg ==
static_cast<unsigned>(INT_MAX))
1693 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1695 if (CIEVersion == 1) {
1697 "DWARF 2 encodes return_address_register in one byte");
1698 Streamer.emitInt8(
RAReg);
1700 Streamer.emitULEB128IntValue(
RAReg);
1704 unsigned augmentationLength = 0;
1708 augmentationLength += 1;
1710 augmentationLength +=
1714 augmentationLength += 1;
1716 augmentationLength += 1;
1718 Streamer.emitULEB128IntValue(augmentationLength);
1741 emitCFIInstructions(Instructions,
nullptr);
1744 InitialCFAOffset = CFAOffset;
1749 Streamer.emitLabel(sectionEnd);
1750 return *sectionStart;
1753void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1757 MCContext &context = Streamer.getContext();
1762 CFAOffset = InitialCFAOffset;
1775 Streamer.emitLabel(fdeStart);
1788 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1793 unsigned PCEncoding =
1805 unsigned augmentationLength = 0;
1810 Streamer.emitULEB128IntValue(augmentationLength);
1825 Streamer.emitValueToAlignment(
Align(Alignment));
1827 Streamer.emitLabel(fdeEnd);
1836 : Personality(Frame.Personality),
1837 PersonalityEncoding(Frame.PersonalityEncoding),
1838 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1839 IsSimple(Frame.IsSimple),
RAReg(Frame.
RAReg),
1840 IsBKeyFrame(Frame.IsBKeyFrame),
1841 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1846 return Personality->getName();
1850 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1851 IsSignalFrame, IsSimple,
RAReg, IsBKeyFrame,
1853 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1856 Other.IsMTETaggedFrame);
1860 return Personality ==
Other.Personality &&
1861 PersonalityEncoding ==
Other.PersonalityEncoding &&
1862 LsdaEncoding ==
Other.LsdaEncoding &&
1863 IsSignalFrame ==
Other.IsSignalFrame && IsSimple ==
Other.IsSimple &&
1865 IsMTETaggedFrame ==
Other.IsMTETaggedFrame;
1869 const MCSymbol *Personality =
nullptr;
1870 unsigned PersonalityEncoding = 0;
1871 unsigned LsdaEncoding = -1;
1872 bool IsSignalFrame =
false;
1873 bool IsSimple =
false;
1874 unsigned RAReg =
static_cast<unsigned>(UINT_MAX);
1875 bool IsBKeyFrame =
false;
1876 bool IsMTETaggedFrame =
false;
1886 FrameEmitterImpl
Emitter(IsEH, Streamer);
1893 bool SectionEmitted =
false;
1896 if (!SectionEmitted) {
1899 SectionEmitted =
true;
1901 NeedsEHFrameSection |=
1904 Emitter.EmitCompactUnwind(Frame);
1912 if (!NeedsEHFrameSection && IsEH)
return;
1927 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1930 return CIEKey(
X) < CIEKey(
Y);
1933 const MCSymbol *LastCIEStart =
nullptr;
1934 for (
auto I = FrameArrayX.begin(), E = FrameArrayX.end();
I != E;) {
1948 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1950 LastCIEStart = &
Emitter.EmitCIE(Frame);
1953 Emitter.EmitFDE(*LastCIEStart, Frame,
I == E, *SectionStart);
1970 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1972 }
else if (isUInt<8>(AddrDelta)) {
1973 Out.
push_back(dwarf::DW_CFA_advance_loc1);
1975 }
else if (isUInt<16>(AddrDelta)) {
1976 Out.
push_back(dwarf::DW_CFA_advance_loc2);
1977 support::endian::write<uint16_t>(Out, AddrDelta, E);
1979 assert(isUInt<32>(AddrDelta));
1980 Out.
push_back(dwarf::DW_CFA_advance_loc4);
1981 support::endian::write<uint32_t>(Out, AddrDelta, E);
unsigned const MachineRegisterInfo * MRI
dxil DXContainer Global Emitter
This file contains constants used for implementing Dwarf debug support.
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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 GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static constexpr Register RAReg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector 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...
bool isLittleEndian() const
True if the target is little endian.
unsigned getMinInstAlignment() const
const std::vector< MCCFIInstruction > & getInitialFrameState() const
bool needsDwarfSectionOffsetDirective() const
bool doesSetDirectiveSuppressReloc() 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 const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
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()
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
void finalizeDwarfSections(MCStreamer &MCOS)
Remove empty sections from SectionsForRanges, to avoid generating useless debug info for them.
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E)
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
void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)
static void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
static void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
Instances of this class represent the line information for the dwarf line table entries.
static void make(MCStreamer *MCOS, MCSection *Section)
void emitSection(MCStreamer *MCOS)
Emit the .debug_line_str section if appropriate.
MCDwarfLineStr(MCContext &Ctx)
Construct an instance that can emit .debug_line_str (for use in a normal v5 line table).
SmallString< 0 > getFinalizedData()
Returns finalized section.
void emitRef(MCStreamer *MCOS, StringRef Path)
Emit a reference to the string.
size_t addString(StringRef Path)
Adds path Path to the line string.
void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
MCDwarfFile & getRootFile()
const MCLineSection & getMCLineSections() const
static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
static void emitOne(MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries)
Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
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 void Emit(MCStreamer *MCOS)
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
const MCLineDivisionMap & getMCLineEntries() const
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 Value=0, unsigned ValueSize=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.
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)
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.
iterator find(const KeyT &Key)
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 append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
void finalizeInOrder()
Finalize the string table without reording it.
void write(raw_ostream &OS) const
size_t add(CachedHashStringRef S)
Add a string to the builder.
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.
Reg
All possible values of the reg field in the ModR/M byte.
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.
MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
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.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
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)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
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.