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;
84 assert(DwarfLineStrSection &&
"DwarfLineStrSection must not be NULL");
138static inline const MCExpr *
156 auto I = MCLineDivisions.
find(Sec);
157 if (
I != MCLineDivisions.
end()) {
158 auto &Entries =
I->second;
159 auto EndEntry = Entries.back();
160 EndEntry.setEndLabel(EndLabel);
161 Entries.push_back(EndEntry);
173 unsigned FileNum, LastLine, Column,
Flags, Isa, Discriminator;
187 bool EndEntryEmitted =
false;
189 MCSymbol *Label = LineEntry.getLabel();
191 if (LineEntry.IsEndEntry) {
195 EndEntryEmitted =
true;
199 int64_t LineDelta =
static_cast<int64_t
>(LineEntry.getLine()) - LastLine;
201 if (FileNum != LineEntry.getFileNum()) {
202 FileNum = LineEntry.getFileNum();
203 MCOS->
emitInt8(dwarf::DW_LNS_set_file);
206 if (Column != LineEntry.getColumn()) {
207 Column = LineEntry.getColumn();
208 MCOS->
emitInt8(dwarf::DW_LNS_set_column);
211 if (Discriminator != LineEntry.getDiscriminator() &&
213 Discriminator = LineEntry.getDiscriminator();
215 MCOS->
emitInt8(dwarf::DW_LNS_extended_op);
217 MCOS->
emitInt8(dwarf::DW_LNE_set_discriminator);
220 if (Isa != LineEntry.getIsa()) {
221 Isa = LineEntry.getIsa();
222 MCOS->
emitInt8(dwarf::DW_LNS_set_isa);
226 Flags = LineEntry.getFlags();
227 MCOS->
emitInt8(dwarf::DW_LNS_negate_stmt);
230 MCOS->
emitInt8(dwarf::DW_LNS_set_basic_block);
232 MCOS->
emitInt8(dwarf::DW_LNS_set_prologue_end);
234 MCOS->
emitInt8(dwarf::DW_LNS_set_epilogue_begin);
243 LastLine = LineEntry.getLine();
252 if (!EndEntryEmitted)
266 if (LineTables.empty())
270 std::optional<MCDwarfLineStr> LineStr;
272 LineStr.emplace(context);
278 for (
const auto &CUIDTablePair : LineTables) {
279 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
283 LineStr->emitSection(MCOS);
288 if (!HasSplitLineTable)
290 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
292 MCOS.
emitLabel(Header.
Emit(&MCOS, Params, std::nullopt, NoLineStr).second);
295std::pair<MCSymbol *, MCSymbol *>
297 std::optional<MCDwarfLineStr> &LineStr)
const {
298 static const char StandardOpcodeLengths[] = {
312 assert(std::size(StandardOpcodeLengths) >=
314 return Emit(MCOS, Params,
321 assert(!isa<MCSymbolRefExpr>(Expr));
322 if (
Context.getAsmInfo()->hasAggressiveSymbolFolding())
326 OS.emitAssignment(ABS, Expr);
349 LineStrings.
write((uint8_t *)
Data.data());
364void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
385 bool EmitMD5,
bool HasSource,
386 std::optional<MCDwarfLineStr> &LineStr) {
398 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
410void MCDwarfLineTableHeader::emitV5FileDirTables(
411 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
418 : dwarf::DW_FORM_string);
428 CompDir = LineStr->getSaver().save(CompDir);
432 LineStr->emitRef(MCOS, CompDir);
434 LineStr->emitRef(MCOS, Dir);
456 : dwarf::DW_FORM_string);
466 : dwarf::DW_FORM_string);
476 "No root file and no .file directives");
483std::pair<MCSymbol *, MCSymbol *>
486 std::optional<MCDwarfLineStr> &LineStr)
const {
506 if (LineTableVersion >= 5) {
526 if (LineTableVersion >= 4)
534 for (
char Length : StandardOpcodeLengths)
539 if (LineTableVersion >= 5)
540 emitV5FileDirTables(MCOS, LineStr);
542 emitV2FileDirTables(MCOS);
548 return std::make_pair(LineStartSym, LineEndSym);
552 std::optional<MCDwarfLineStr> &LineStr)
const {
553 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
557 emitOne(MCOS, LineSec.first, LineSec.second);
566 std::optional<MD5::MD5Result> Checksum,
567 std::optional<StringRef> Source,
568 uint16_t DwarfVersion,
unsigned FileNumber) {
569 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
575 std::optional<MD5::MD5Result> Checksum) {
578 return RootFile.
Checksum == Checksum;
583 std::optional<MD5::MD5Result> Checksum,
584 std::optional<StringRef> Source,
585 uint16_t DwarfVersion,
unsigned FileNumber) {
588 if (FileName.
empty()) {
589 FileName =
"<stdin>";
601 if (FileNumber == 0) {
609 if (!IterBool.second)
610 return IterBool.first->second;
620 if (!File.Name.empty())
621 return make_error<StringError>(
"file number already allocated",
625 if (
HasSource != (Source != std::nullopt))
626 return make_error<StringError>(
"inconsistent use of embedded source",
629 if (Directory.
empty()) {
632 if (!tFileName.
empty()) {
634 if (!Directory.
empty())
635 FileName = tFileName;
642 if (Directory.
empty()) {
656 File.Name = std::string(FileName);
657 File.DirIndex = DirIndex;
658 File.Checksum = Checksum;
660 File.Source = Source;
670 int64_t LineDelta,
uint64_t AddrDelta) {
685 int64_t LineDelta,
uint64_t AddrDelta,
689 bool NeedCopy =
false;
701 if (AddrDelta == MaxSpecialAddrDelta)
702 Out.
push_back(dwarf::DW_LNS_const_add_pc);
703 else if (AddrDelta) {
707 Out.
push_back(dwarf::DW_LNS_extended_op);
709 Out.
push_back(dwarf::DW_LNE_end_sequence);
720 Out.
push_back(dwarf::DW_LNS_advance_line);
729 if (LineDelta == 0 && AddrDelta == 0) {
738 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
747 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
749 Out.
push_back(dwarf::DW_LNS_const_add_pc);
762 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
785 ? dwarf::DW_FORM_sec_offset
787 : dwarf::DW_FORM_data4);
788 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
791 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
793 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
794 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
796 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
798 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
800 if (!DwarfDebugFlags.
empty())
801 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
802 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
803 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
810 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
811 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
812 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
813 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
825 const MCSymbol *InfoSectionSymbol) {
832 unsigned UnitLengthBytes =
838 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
844 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
845 if (Pad == 2 * AddrSize)
851 Length += 2 * AddrSize * Sections.size();
866 if (InfoSectionSymbol)
876 for(
int i = 0; i < Pad; i++)
882 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
883 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
884 assert(StartSymbol &&
"StartSymbol must not be NULL");
885 assert(EndSymbol &&
"EndSymbol must not be NULL");
904 const MCSymbol *AbbrevSectionSymbol,
919 unsigned UnitLengthBytes =
941 MCOS->
emitInt8(dwarf::DW_UT_compile);
946 if (AbbrevSectionSymbol)
962 if (LineSectionSymbol)
980 const auto TextSection = Sections.begin();
981 assert(TextSection != Sections.end() &&
"No text section found");
983 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
984 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
985 assert(StartSymbol &&
"StartSymbol must not be NULL");
986 assert(EndSymbol &&
"EndSymbol must not be NULL");
1002 if (MCDwarfDirs.
size() > 0) {
1011 MCDwarfFiles.
empty()
1025 if (!DwarfDebugFlags.
empty()){
1032 if (!DwarfDebugProducer.
empty())
1040 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1045 const std::vector<MCGenDwarfLabelEntry> &Entries =
1047 for (
const auto &Entry : Entries) {
1093 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1094 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1097 const MCExpr *SectionSize =
1099 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1100 MCOS->
emitValue(SectionStartAddr, AddrSize);
1103 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1110 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1111 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1117 MCOS->
emitValue(SectionStartAddr, AddrSize);
1120 const MCExpr *SectionSize =
1131 return RangesSymbol;
1143 bool CreateDwarfSectionSymbols =
1145 MCSymbol *LineSectionSymbol =
nullptr;
1146 if (CreateDwarfSectionSymbols)
1148 MCSymbol *AbbrevSectionSymbol =
nullptr;
1149 MCSymbol *InfoSectionSymbol =
nullptr;
1162 const bool UseRangesSection =
1165 CreateDwarfSectionSymbols |= UseRangesSection;
1168 if (CreateDwarfSectionSymbols) {
1173 if (CreateDwarfSectionSymbols) {
1183 if (UseRangesSection) {
1192 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1204 if (Symbol->isTemporary())
1215 if (Name.startswith(
"_"))
1216 Name = Name.substr(1, Name.size()-1);
1249 unsigned symbolEncoding) {
1251 unsigned format = symbolEncoding & 0x0f;
1270 unsigned symbolEncoding,
bool isEH) {
1284 unsigned symbolEncoding) {
1296class FrameEmitterImpl {
1298 int InitialCFAOffset = 0;
1304 : IsEH(IsEH), Streamer(Streamer) {}
1311 bool LastInSection,
const MCSymbol &SectionStart);
1325 auto *
MRI = Streamer.getContext().getRegisterInfo();
1332 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1333 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1335 Streamer.emitInt8(dwarf::DW_CFA_register);
1336 Streamer.emitULEB128IntValue(Reg1);
1337 Streamer.emitULEB128IntValue(Reg2);
1341 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1345 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1350 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1351 Streamer.emitULEB128IntValue(Reg);
1356 const bool IsRelative =
1359 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1366 Streamer.emitULEB128IntValue(CFAOffset);
1373 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1374 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1375 Streamer.emitULEB128IntValue(Reg);
1377 Streamer.emitULEB128IntValue(CFAOffset);
1384 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1385 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1386 Streamer.emitULEB128IntValue(Reg);
1394 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1395 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1396 Streamer.emitULEB128IntValue(Reg);
1398 Streamer.emitULEB128IntValue(CFAOffset);
1405 const bool IsRelative =
1410 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1418 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1419 Streamer.emitULEB128IntValue(Reg);
1420 Streamer.emitSLEB128IntValue(
Offset);
1421 }
else if (Reg < 64) {
1422 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1423 Streamer.emitULEB128IntValue(
Offset);
1425 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1426 Streamer.emitULEB128IntValue(Reg);
1427 Streamer.emitULEB128IntValue(
Offset);
1432 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1435 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1439 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1440 Streamer.emitULEB128IntValue(Reg);
1446 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1448 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1450 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1451 Streamer.emitULEB128IntValue(Reg);
1456 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1457 Streamer.emitULEB128IntValue(Instr.
getOffset());
1473 if (Label && !
Label->isDefined())
continue;
1476 if (BaseLabel && Label) {
1478 if (ThisSym != BaseLabel) {
1479 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
1480 BaseLabel = ThisSym;
1484 emitCFIInstruction(Instr);
1516 if (!Encoding)
return;
1520 if (!DwarfEHFrameOnly && Frame.
Lsda)
1521 Encoding |= 0x40000000;
1526 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1535 Streamer.emitIntValue(Encoding,
Size);
1542 Streamer.emitIntValue(0,
Size);
1546 if (!DwarfEHFrameOnly && Frame.
Lsda)
1547 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1549 Streamer.emitIntValue(0,
Size);
1555 switch (DwarfVersion) {
1568 MCContext &context = Streamer.getContext();
1573 Streamer.emitLabel(sectionStart);
1588 *sectionEnd, UnitLengthBytes);
1594 Streamer.emitIntValue(CIE_ID, OffsetSize);
1598 Streamer.emitInt8(CIEVersion);
1602 Augmentation +=
"z";
1604 Augmentation +=
"P";
1606 Augmentation +=
"L";
1607 Augmentation +=
"R";
1609 Augmentation +=
"S";
1611 Augmentation +=
"B";
1613 Augmentation +=
"G";
1614 Streamer.emitBytes(Augmentation);
1616 Streamer.emitInt8(0);
1618 if (CIEVersion >= 4) {
1623 Streamer.emitInt8(0);
1633 unsigned RAReg = Frame.
RAReg;
1634 if (RAReg ==
static_cast<unsigned>(INT_MAX))
1635 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1637 if (CIEVersion == 1) {
1639 "DWARF 2 encodes return_address_register in one byte");
1640 Streamer.emitInt8(RAReg);
1642 Streamer.emitULEB128IntValue(RAReg);
1646 unsigned augmentationLength = 0;
1650 augmentationLength += 1;
1652 augmentationLength +=
1656 augmentationLength += 1;
1658 augmentationLength += 1;
1660 Streamer.emitULEB128IntValue(augmentationLength);
1683 emitCFIInstructions(Instructions,
nullptr);
1686 InitialCFAOffset = CFAOffset;
1691 Streamer.emitLabel(sectionEnd);
1692 return *sectionStart;
1695void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1699 MCContext &context = Streamer.getContext();
1704 CFAOffset = InitialCFAOffset;
1717 Streamer.emitLabel(fdeStart);
1730 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1735 unsigned PCEncoding =
1747 unsigned augmentationLength = 0;
1752 Streamer.emitULEB128IntValue(augmentationLength);
1767 Streamer.emitValueToAlignment(
Align(Alignment));
1769 Streamer.emitLabel(fdeEnd);
1775 static const CIEKey getEmptyKey() {
1776 return CIEKey(
nullptr, 0, -1,
false,
false,
static_cast<unsigned>(INT_MAX),
1780 static const CIEKey getTombstoneKey() {
1781 return CIEKey(
nullptr, -1, 0,
false,
false,
static_cast<unsigned>(INT_MAX),
1785 CIEKey(
const MCSymbol *Personality,
unsigned PersonalityEncoding,
1786 unsigned LSDAEncoding,
bool IsSignalFrame,
bool IsSimple,
1787 unsigned RAReg,
bool IsBKeyFrame,
bool IsMTETaggedFrame)
1788 : Personality(Personality), PersonalityEncoding(PersonalityEncoding),
1789 LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
1790 IsSimple(IsSimple), RAReg(RAReg), IsBKeyFrame(IsBKeyFrame),
1791 IsMTETaggedFrame(IsMTETaggedFrame) {}
1794 : Personality(Frame.Personality),
1795 PersonalityEncoding(Frame.PersonalityEncoding),
1796 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1797 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1798 IsBKeyFrame(Frame.IsBKeyFrame),
1799 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1804 return Personality->getName();
1808 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1809 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1811 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1814 Other.IsMTETaggedFrame);
1818 unsigned PersonalityEncoding;
1819 unsigned LsdaEncoding;
1824 bool IsMTETaggedFrame;
1836 return static_cast<unsigned>(
1837 hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
1838 Key.IsSignalFrame, Key.IsSimple, Key.RAReg,
1839 Key.IsBKeyFrame, Key.IsMTETaggedFrame));
1842 static bool isEqual(
const CIEKey &LHS,
const CIEKey &RHS) {
1843 return LHS.Personality ==
RHS.Personality &&
1844 LHS.PersonalityEncoding ==
RHS.PersonalityEncoding &&
1845 LHS.LsdaEncoding ==
RHS.LsdaEncoding &&
1846 LHS.IsSignalFrame ==
RHS.IsSignalFrame &&
1847 LHS.IsSimple ==
RHS.IsSimple &&
LHS.RAReg ==
RHS.RAReg &&
1848 LHS.IsBKeyFrame ==
RHS.IsBKeyFrame &&
1849 LHS.IsMTETaggedFrame ==
RHS.IsMTETaggedFrame;
1860 FrameEmitterImpl
Emitter(IsEH, Streamer);
1867 bool SectionEmitted =
false;
1870 if (!SectionEmitted) {
1873 SectionEmitted =
true;
1875 NeedsEHFrameSection |=
1878 Emitter.EmitCompactUnwind(Frame);
1886 if (!NeedsEHFrameSection && IsEH)
return;
1898 const MCSymbol *DummyDebugKey =
nullptr;
1904 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1907 return CIEKey(
X) < CIEKey(
Y);
1909 for (
auto I = FrameArrayX.begin(),
E = FrameArrayX.end();
I !=
E;) {
1923 const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1925 CIEStart = &
Emitter.EmitCIE(Frame);
1927 Emitter.EmitFDE(*CIEStart, Frame,
I ==
E, *SectionStart);
1943 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1945 }
else if (isUInt<8>(AddrDelta)) {
1946 Out.
push_back(dwarf::DW_CFA_advance_loc1);
1948 }
else if (isUInt<16>(AddrDelta)) {
1949 Out.
push_back(dwarf::DW_CFA_advance_loc2);
1950 support::endian::write<uint16_t>(Out, AddrDelta,
E);
1952 assert(isUInt<32>(AddrDelta));
1953 Out.
push_back(dwarf::DW_CFA_advance_loc4);
1954 support::endian::write<uint32_t>(Out, 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
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 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.
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.
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 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.
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.
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...
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.