19#include "llvm/Config/config.h"
69 unsigned MinInsnLength =
Context.getAsmInfo()->getMinInstAlignment();
70 if (MinInsnLength == 1)
72 if (AddrDelta % MinInsnLength != 0) {
76 return AddrDelta / MinInsnLength;
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;
184 bool EndEntryEmitted =
false;
186 MCSymbol *Label = LineEntry.getLabel();
188 if (LineEntry.IsEndEntry) {
192 EndEntryEmitted =
true;
196 int64_t LineDelta =
static_cast<int64_t
>(LineEntry.getLine()) - LastLine;
198 if (FileNum != LineEntry.getFileNum()) {
199 FileNum = LineEntry.getFileNum();
200 MCOS->
emitInt8(dwarf::DW_LNS_set_file);
203 if (Column != LineEntry.getColumn()) {
204 Column = LineEntry.getColumn();
205 MCOS->
emitInt8(dwarf::DW_LNS_set_column);
208 if (Discriminator != LineEntry.getDiscriminator() &&
210 Discriminator = LineEntry.getDiscriminator();
212 MCOS->
emitInt8(dwarf::DW_LNS_extended_op);
214 MCOS->
emitInt8(dwarf::DW_LNE_set_discriminator);
217 if (Isa != LineEntry.getIsa()) {
218 Isa = LineEntry.getIsa();
219 MCOS->
emitInt8(dwarf::DW_LNS_set_isa);
223 Flags = LineEntry.getFlags();
224 MCOS->
emitInt8(dwarf::DW_LNS_negate_stmt);
227 MCOS->
emitInt8(dwarf::DW_LNS_set_basic_block);
229 MCOS->
emitInt8(dwarf::DW_LNS_set_prologue_end);
231 MCOS->
emitInt8(dwarf::DW_LNS_set_epilogue_begin);
240 LastLine = LineEntry.getLine();
249 if (!EndEntryEmitted)
263 if (LineTables.empty())
267 std::optional<MCDwarfLineStr> LineStr;
269 LineStr.emplace(context);
275 for (
const auto &CUIDTablePair : LineTables) {
276 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
280 LineStr->emitSection(MCOS);
285 if (!HasSplitLineTable)
287 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
289 MCOS.
emitLabel(Header.
Emit(&MCOS, Params, std::nullopt, NoLineStr).second);
292std::pair<MCSymbol *, MCSymbol *>
294 std::optional<MCDwarfLineStr> &LineStr)
const {
295 static const char StandardOpcodeLengths[] = {
309 assert(std::size(StandardOpcodeLengths) >=
311 return Emit(MCOS, Params,
318 assert(!isa<MCSymbolRefExpr>(Expr));
319 if (
Context.getAsmInfo()->hasAggressiveSymbolFolding())
346 LineStrings.
write((uint8_t *)
Data.data());
361void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
382 bool EmitMD5,
bool HasSource,
383 std::optional<MCDwarfLineStr> &LineStr) {
395 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
407void MCDwarfLineTableHeader::emitV5FileDirTables(
408 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
415 : dwarf::DW_FORM_string);
425 CompDir = LineStr->getSaver().save(CompDir);
429 LineStr->emitRef(MCOS, CompDir);
431 LineStr->emitRef(MCOS, Dir);
453 : dwarf::DW_FORM_string);
463 : dwarf::DW_FORM_string);
473 "No root file and no .file directives");
480std::pair<MCSymbol *, MCSymbol *>
483 std::optional<MCDwarfLineStr> &LineStr)
const {
503 if (LineTableVersion >= 5) {
523 if (LineTableVersion >= 4)
531 for (
char Length : StandardOpcodeLengths)
536 if (LineTableVersion >= 5)
537 emitV5FileDirTables(MCOS, LineStr);
539 emitV2FileDirTables(MCOS);
545 return std::make_pair(LineStartSym, LineEndSym);
549 std::optional<MCDwarfLineStr> &LineStr)
const {
550 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
554 emitOne(MCOS, LineSec.first, LineSec.second);
563 std::optional<MD5::MD5Result> Checksum,
564 std::optional<StringRef> Source,
565 uint16_t DwarfVersion,
unsigned FileNumber) {
566 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
572 std::optional<MD5::MD5Result> Checksum) {
575 return RootFile.
Checksum == Checksum;
580 std::optional<MD5::MD5Result> Checksum,
581 std::optional<StringRef> Source,
582 uint16_t DwarfVersion,
unsigned FileNumber) {
585 if (FileName.
empty()) {
586 FileName =
"<stdin>";
598 if (FileNumber == 0) {
606 if (!IterBool.second)
607 return IterBool.first->second;
617 if (!File.Name.empty())
618 return make_error<StringError>(
"file number already allocated",
622 if (
HasSource != (Source != std::nullopt))
623 return make_error<StringError>(
"inconsistent use of embedded source",
626 if (Directory.
empty()) {
629 if (!tFileName.
empty()) {
631 if (!Directory.
empty())
632 FileName = tFileName;
639 if (Directory.
empty()) {
653 File.Name = std::string(FileName);
654 File.DirIndex = DirIndex;
655 File.Checksum = Checksum;
657 File.Source = Source;
667 int64_t LineDelta,
uint64_t AddrDelta) {
683 int64_t LineDelta,
uint64_t AddrDelta,
686 bool NeedCopy =
false;
698 if (AddrDelta == MaxSpecialAddrDelta)
699 OS <<
char(dwarf::DW_LNS_const_add_pc);
700 else if (AddrDelta) {
701 OS <<
char(dwarf::DW_LNS_advance_pc);
704 OS <<
char(dwarf::DW_LNS_extended_op);
706 OS <<
char(dwarf::DW_LNE_end_sequence);
717 OS <<
char(dwarf::DW_LNS_advance_line);
726 if (LineDelta == 0 && AddrDelta == 0) {
727 OS <<
char(dwarf::DW_LNS_copy);
735 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
744 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
746 OS <<
char(dwarf::DW_LNS_const_add_pc);
753 OS <<
char(dwarf::DW_LNS_advance_pc);
757 OS <<
char(dwarf::DW_LNS_copy);
759 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
782 ? dwarf::DW_FORM_sec_offset
784 : dwarf::DW_FORM_data4);
785 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
788 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
790 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
791 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
793 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
795 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
797 if (!DwarfDebugFlags.
empty())
798 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
799 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
800 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
807 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
808 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
809 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
810 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
822 const MCSymbol *InfoSectionSymbol) {
829 unsigned UnitLengthBytes =
835 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
841 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
842 if (Pad == 2 * AddrSize)
848 Length += 2 * AddrSize * Sections.size();
863 if (InfoSectionSymbol)
873 for(
int i = 0; i < Pad; i++)
879 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
880 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
881 assert(StartSymbol &&
"StartSymbol must not be NULL");
882 assert(EndSymbol &&
"EndSymbol must not be NULL");
901 const MCSymbol *AbbrevSectionSymbol,
916 unsigned UnitLengthBytes =
938 MCOS->
emitInt8(dwarf::DW_UT_compile);
943 if (AbbrevSectionSymbol)
959 if (LineSectionSymbol)
977 const auto TextSection = Sections.begin();
978 assert(TextSection != Sections.end() &&
"No text section found");
980 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
981 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
982 assert(StartSymbol &&
"StartSymbol must not be NULL");
983 assert(EndSymbol &&
"EndSymbol must not be NULL");
999 if (MCDwarfDirs.
size() > 0) {
1008 MCDwarfFiles.
empty()
1022 if (!DwarfDebugFlags.
empty()){
1029 if (!DwarfDebugProducer.
empty())
1037 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1042 const std::vector<MCGenDwarfLabelEntry> &Entries =
1044 for (
const auto &Entry : Entries) {
1090 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1091 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1094 const MCExpr *SectionSize =
1096 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1097 MCOS->
emitValue(SectionStartAddr, AddrSize);
1100 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1107 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1108 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1114 MCOS->
emitValue(SectionStartAddr, AddrSize);
1117 const MCExpr *SectionSize =
1128 return RangesSymbol;
1140 bool CreateDwarfSectionSymbols =
1142 MCSymbol *LineSectionSymbol =
nullptr;
1143 if (CreateDwarfSectionSymbols)
1145 MCSymbol *AbbrevSectionSymbol =
nullptr;
1146 MCSymbol *InfoSectionSymbol =
nullptr;
1159 const bool UseRangesSection =
1162 CreateDwarfSectionSymbols |= UseRangesSection;
1165 if (CreateDwarfSectionSymbols) {
1170 if (CreateDwarfSectionSymbols) {
1180 if (UseRangesSection) {
1189 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1201 if (Symbol->isTemporary())
1212 if (Name.startswith(
"_"))
1213 Name = Name.substr(1, Name.size()-1);
1246 unsigned symbolEncoding) {
1248 unsigned format = symbolEncoding & 0x0f;
1267 unsigned symbolEncoding,
bool isEH) {
1281 unsigned symbolEncoding) {
1293class FrameEmitterImpl {
1295 int InitialCFAOffset = 0;
1301 : IsEH(IsEH), Streamer(Streamer) {}
1308 bool LastInSection,
const MCSymbol &SectionStart);
1322 auto *
MRI = Streamer.getContext().getRegisterInfo();
1329 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1330 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1332 Streamer.emitInt8(dwarf::DW_CFA_register);
1333 Streamer.emitULEB128IntValue(Reg1);
1334 Streamer.emitULEB128IntValue(Reg2);
1338 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1342 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1347 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1348 Streamer.emitULEB128IntValue(Reg);
1353 const bool IsRelative =
1356 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1363 Streamer.emitULEB128IntValue(CFAOffset);
1370 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1371 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1372 Streamer.emitULEB128IntValue(Reg);
1374 Streamer.emitULEB128IntValue(CFAOffset);
1381 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1382 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1383 Streamer.emitULEB128IntValue(Reg);
1391 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1392 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1393 Streamer.emitULEB128IntValue(Reg);
1395 Streamer.emitULEB128IntValue(CFAOffset);
1402 const bool IsRelative =
1407 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1415 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1416 Streamer.emitULEB128IntValue(Reg);
1417 Streamer.emitSLEB128IntValue(
Offset);
1418 }
else if (Reg < 64) {
1419 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1420 Streamer.emitULEB128IntValue(
Offset);
1422 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1423 Streamer.emitULEB128IntValue(Reg);
1424 Streamer.emitULEB128IntValue(
Offset);
1429 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1432 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1436 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1437 Streamer.emitULEB128IntValue(Reg);
1443 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1445 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1447 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1448 Streamer.emitULEB128IntValue(Reg);
1453 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1454 Streamer.emitULEB128IntValue(Instr.
getOffset());
1470 if (Label && !
Label->isDefined())
continue;
1473 if (BaseLabel && Label) {
1475 if (ThisSym != BaseLabel) {
1476 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
1477 BaseLabel = ThisSym;
1481 emitCFIInstruction(Instr);
1513 if (!Encoding)
return;
1517 if (!DwarfEHFrameOnly && Frame.
Lsda)
1518 Encoding |= 0x40000000;
1523 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1532 Streamer.emitIntValue(Encoding,
Size);
1539 Streamer.emitIntValue(0,
Size);
1543 if (!DwarfEHFrameOnly && Frame.
Lsda)
1544 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1546 Streamer.emitIntValue(0,
Size);
1552 switch (DwarfVersion) {
1565 MCContext &context = Streamer.getContext();
1570 Streamer.emitLabel(sectionStart);
1585 *sectionEnd, UnitLengthBytes);
1591 Streamer.emitIntValue(CIE_ID, OffsetSize);
1595 Streamer.emitInt8(CIEVersion);
1599 Augmentation +=
"z";
1601 Augmentation +=
"P";
1603 Augmentation +=
"L";
1604 Augmentation +=
"R";
1606 Augmentation +=
"S";
1608 Augmentation +=
"B";
1610 Augmentation +=
"G";
1611 Streamer.emitBytes(Augmentation);
1613 Streamer.emitInt8(0);
1615 if (CIEVersion >= 4) {
1620 Streamer.emitInt8(0);
1630 unsigned RAReg = Frame.
RAReg;
1631 if (RAReg ==
static_cast<unsigned>(INT_MAX))
1632 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1634 if (CIEVersion == 1) {
1636 "DWARF 2 encodes return_address_register in one byte");
1637 Streamer.emitInt8(RAReg);
1639 Streamer.emitULEB128IntValue(RAReg);
1643 unsigned augmentationLength = 0;
1647 augmentationLength += 1;
1649 augmentationLength +=
1653 augmentationLength += 1;
1655 augmentationLength += 1;
1657 Streamer.emitULEB128IntValue(augmentationLength);
1680 emitCFIInstructions(Instructions,
nullptr);
1683 InitialCFAOffset = CFAOffset;
1688 Streamer.emitLabel(sectionEnd);
1689 return *sectionStart;
1692void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1696 MCContext &context = Streamer.getContext();
1701 CFAOffset = InitialCFAOffset;
1714 Streamer.emitLabel(fdeStart);
1727 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1732 unsigned PCEncoding =
1744 unsigned augmentationLength = 0;
1749 Streamer.emitULEB128IntValue(augmentationLength);
1764 Streamer.emitValueToAlignment(
Align(Alignment));
1766 Streamer.emitLabel(fdeEnd);
1772 static const CIEKey getEmptyKey() {
1773 return CIEKey(
nullptr, 0, -1,
false,
false,
static_cast<unsigned>(INT_MAX),
1777 static const CIEKey getTombstoneKey() {
1778 return CIEKey(
nullptr, -1, 0,
false,
false,
static_cast<unsigned>(INT_MAX),
1782 CIEKey(
const MCSymbol *Personality,
unsigned PersonalityEncoding,
1783 unsigned LSDAEncoding,
bool IsSignalFrame,
bool IsSimple,
1784 unsigned RAReg,
bool IsBKeyFrame,
bool IsMTETaggedFrame)
1785 : Personality(Personality), PersonalityEncoding(PersonalityEncoding),
1786 LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
1787 IsSimple(IsSimple), RAReg(RAReg), IsBKeyFrame(IsBKeyFrame),
1788 IsMTETaggedFrame(IsMTETaggedFrame) {}
1791 : Personality(Frame.Personality),
1792 PersonalityEncoding(Frame.PersonalityEncoding),
1793 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1794 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1795 IsBKeyFrame(Frame.IsBKeyFrame),
1796 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1801 return Personality->getName();
1805 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1806 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1808 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1811 Other.IsMTETaggedFrame);
1815 unsigned PersonalityEncoding;
1816 unsigned LsdaEncoding;
1821 bool IsMTETaggedFrame;
1833 return static_cast<unsigned>(
1834 hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
1835 Key.IsSignalFrame, Key.IsSimple, Key.RAReg,
1836 Key.IsBKeyFrame, Key.IsMTETaggedFrame));
1839 static bool isEqual(
const CIEKey &LHS,
const CIEKey &RHS) {
1840 return LHS.Personality ==
RHS.Personality &&
1841 LHS.PersonalityEncoding ==
RHS.PersonalityEncoding &&
1842 LHS.LsdaEncoding ==
RHS.LsdaEncoding &&
1843 LHS.IsSignalFrame ==
RHS.IsSignalFrame &&
1844 LHS.IsSimple ==
RHS.IsSimple &&
LHS.RAReg ==
RHS.RAReg &&
1845 LHS.IsBKeyFrame ==
RHS.IsBKeyFrame &&
1846 LHS.IsMTETaggedFrame ==
RHS.IsMTETaggedFrame;
1857 FrameEmitterImpl
Emitter(IsEH, Streamer);
1864 bool SectionEmitted =
false;
1867 if (!SectionEmitted) {
1870 SectionEmitted =
true;
1872 NeedsEHFrameSection |=
1875 Emitter.EmitCompactUnwind(Frame);
1879 if (!NeedsEHFrameSection)
return;
1891 const MCSymbol *DummyDebugKey =
nullptr;
1897 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1900 return CIEKey(
X) < CIEKey(
Y);
1902 for (
auto I = FrameArrayX.begin(),
E = FrameArrayX.end();
I !=
E;) {
1912 const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1914 CIEStart = &
Emitter.EmitCIE(Frame);
1916 Emitter.EmitFDE(*CIEStart, Frame,
I ==
E, *SectionStart);
1941 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1943 }
else if (isUInt<8>(AddrDelta)) {
1944 OS << uint8_t(dwarf::DW_CFA_advance_loc1);
1945 OS << uint8_t(AddrDelta);
1946 }
else if (isUInt<16>(AddrDelta)) {
1947 OS << uint8_t(dwarf::DW_CFA_advance_loc2);
1948 support::endian::write<uint16_t>(OS, AddrDelta,
E);
1950 assert(isUInt<32>(AddrDelta));
1951 OS << uint8_t(dwarf::DW_CFA_advance_loc4);
1952 support::endian::write<uint32_t>(OS, AddrDelta,
E);
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
dxil DXContainer Global Emitter
This file defines the DenseMap class.
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 HasSource, 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
return ToRemove size() > 0
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
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...
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 const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol * getLabel() const
unsigned getAddressSpace() const
unsigned getRegister2() const
unsigned getRegister() const
OpType getOperation() const
StringRef getValues() const
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)
const MCDwarfLoc & getCurrentDwarfLoc()
dwarf::DwarfFormat getDwarfFormat() const
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, raw_ostream &OS)
static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)
static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta)
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, raw_ostream &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.
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 emitBytes(StringRef Data) override
Emit the bytes in Data into the output.
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.
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel)
Emit the debug line end entry.
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.
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, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
MCSection * getCurrentSectionOnly() const
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 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.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#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.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
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)
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.
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...
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.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static bool isEqual(const CIEKey &LHS, const CIEKey &RHS)
static CIEKey getTombstoneKey()
static unsigned getHashValue(const CIEKey &Key)
static CIEKey getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
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
uint32_t CompactUnwindEncoding
unsigned PersonalityEncoding
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.