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());
354 return LineStrings.
add(Path);
368void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
389 bool EmitMD5,
bool HasAnySource,
390 std::optional<MCDwarfLineStr> &LineStr) {
402 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
414void MCDwarfLineTableHeader::emitV5FileDirTables(
415 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
422 : dwarf::DW_FORM_string);
432 CompDir = LineStr->getSaver().save(CompDir);
436 LineStr->emitRef(MCOS, CompDir);
438 LineStr->emitRef(MCOS, Dir);
460 : dwarf::DW_FORM_string);
470 : dwarf::DW_FORM_string);
480 "No root file and no .file directives");
487std::pair<MCSymbol *, MCSymbol *>
490 std::optional<MCDwarfLineStr> &LineStr)
const {
510 if (LineTableVersion >= 5) {
530 if (LineTableVersion >= 4)
538 for (
char Length : StandardOpcodeLengths)
543 if (LineTableVersion >= 5)
544 emitV5FileDirTables(MCOS, LineStr);
546 emitV2FileDirTables(MCOS);
552 return std::make_pair(LineStartSym, LineEndSym);
556 std::optional<MCDwarfLineStr> &LineStr)
const {
557 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
561 emitOne(MCOS, LineSec.first, LineSec.second);
570 std::optional<MD5::MD5Result> Checksum,
571 std::optional<StringRef> Source,
572 uint16_t DwarfVersion,
unsigned FileNumber) {
573 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
579 std::optional<MD5::MD5Result> Checksum) {
582 return RootFile.
Checksum == Checksum;
587 std::optional<MD5::MD5Result> Checksum,
588 std::optional<StringRef> Source,
589 uint16_t DwarfVersion,
unsigned FileNumber) {
592 if (FileName.
empty()) {
593 FileName =
"<stdin>";
605 if (FileNumber == 0) {
613 if (!IterBool.second)
614 return IterBool.first->second;
624 if (!File.Name.empty())
625 return make_error<StringError>(
"file number already allocated",
628 if (Directory.
empty()) {
631 if (!tFileName.
empty()) {
633 if (!Directory.
empty())
634 FileName = tFileName;
641 if (Directory.
empty()) {
655 File.Name = std::string(FileName);
656 File.DirIndex = DirIndex;
657 File.Checksum = Checksum;
659 File.Source = Source;
660 if (Source.has_value())
669 int64_t LineDelta,
uint64_t AddrDelta) {
684 int64_t LineDelta,
uint64_t AddrDelta,
688 bool NeedCopy =
false;
700 if (AddrDelta == MaxSpecialAddrDelta)
701 Out.
push_back(dwarf::DW_LNS_const_add_pc);
702 else if (AddrDelta) {
706 Out.
push_back(dwarf::DW_LNS_extended_op);
708 Out.
push_back(dwarf::DW_LNE_end_sequence);
719 Out.
push_back(dwarf::DW_LNS_advance_line);
728 if (LineDelta == 0 && AddrDelta == 0) {
737 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
748 Out.
push_back(dwarf::DW_LNS_const_add_pc);
761 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
784 ? dwarf::DW_FORM_sec_offset
786 : dwarf::DW_FORM_data4);
787 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
790 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
792 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
793 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
795 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
797 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
799 if (!DwarfDebugFlags.
empty())
800 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
801 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
802 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
809 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
810 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
811 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
812 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
824 const MCSymbol *InfoSectionSymbol) {
831 unsigned UnitLengthBytes =
837 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
843 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
844 if (Pad == 2 * AddrSize)
850 Length += 2 * AddrSize * Sections.size();
865 if (InfoSectionSymbol)
875 for(
int i = 0; i < Pad; i++)
881 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
882 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
883 assert(StartSymbol &&
"StartSymbol must not be NULL");
884 assert(EndSymbol &&
"EndSymbol must not be NULL");
903 const MCSymbol *AbbrevSectionSymbol,
918 unsigned UnitLengthBytes =
940 MCOS->
emitInt8(dwarf::DW_UT_compile);
945 if (AbbrevSectionSymbol)
961 if (LineSectionSymbol)
979 const auto TextSection = Sections.begin();
980 assert(TextSection != Sections.end() &&
"No text section found");
982 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
983 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
984 assert(StartSymbol &&
"StartSymbol must not be NULL");
985 assert(EndSymbol &&
"EndSymbol must not be NULL");
1001 if (MCDwarfDirs.
size() > 0) {
1010 MCDwarfFiles.
empty()
1024 if (!DwarfDebugFlags.
empty()){
1031 if (!DwarfDebugProducer.
empty())
1039 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1044 const std::vector<MCGenDwarfLabelEntry> &Entries =
1046 for (
const auto &Entry : Entries) {
1092 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1093 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1096 const MCExpr *SectionSize =
1098 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1099 MCOS->
emitValue(SectionStartAddr, AddrSize);
1102 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1109 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1110 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1116 MCOS->
emitValue(SectionStartAddr, AddrSize);
1119 const MCExpr *SectionSize =
1130 return RangesSymbol;
1142 bool CreateDwarfSectionSymbols =
1144 MCSymbol *LineSectionSymbol =
nullptr;
1145 if (CreateDwarfSectionSymbols)
1147 MCSymbol *AbbrevSectionSymbol =
nullptr;
1148 MCSymbol *InfoSectionSymbol =
nullptr;
1161 const bool UseRangesSection =
1164 CreateDwarfSectionSymbols |= UseRangesSection;
1167 if (CreateDwarfSectionSymbols) {
1172 if (CreateDwarfSectionSymbols) {
1182 if (UseRangesSection) {
1191 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1203 if (Symbol->isTemporary())
1214 if (Name.startswith(
"_"))
1215 Name = Name.substr(1, Name.size()-1);
1248 unsigned symbolEncoding) {
1250 unsigned format = symbolEncoding & 0x0f;
1269 unsigned symbolEncoding,
bool isEH) {
1283 unsigned symbolEncoding) {
1295class FrameEmitterImpl {
1297 int InitialCFAOffset = 0;
1303 : IsEH(IsEH), Streamer(Streamer) {}
1310 bool LastInSection,
const MCSymbol &SectionStart);
1324 auto *
MRI = Streamer.getContext().getRegisterInfo();
1326 switch (
Instr.getOperation()) {
1328 unsigned Reg1 =
Instr.getRegister();
1329 unsigned Reg2 =
Instr.getRegister2();
1331 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1332 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1334 Streamer.emitInt8(dwarf::DW_CFA_register);
1335 Streamer.emitULEB128IntValue(Reg1);
1336 Streamer.emitULEB128IntValue(Reg2);
1340 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1344 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1348 unsigned Reg =
Instr.getRegister();
1349 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1350 Streamer.emitULEB128IntValue(Reg);
1355 const bool IsRelative =
1358 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1361 CFAOffset +=
Instr.getOffset();
1363 CFAOffset =
Instr.getOffset();
1365 Streamer.emitULEB128IntValue(CFAOffset);
1370 unsigned Reg =
Instr.getRegister();
1372 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1373 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1374 Streamer.emitULEB128IntValue(Reg);
1375 CFAOffset =
Instr.getOffset();
1376 Streamer.emitULEB128IntValue(CFAOffset);
1381 unsigned Reg =
Instr.getRegister();
1383 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1384 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1385 Streamer.emitULEB128IntValue(Reg);
1391 unsigned Reg =
Instr.getRegister();
1393 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1394 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1395 Streamer.emitULEB128IntValue(Reg);
1396 CFAOffset =
Instr.getOffset();
1397 Streamer.emitULEB128IntValue(CFAOffset);
1398 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1404 const bool IsRelative =
1407 unsigned Reg =
Instr.getRegister();
1409 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1417 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1418 Streamer.emitULEB128IntValue(Reg);
1419 Streamer.emitSLEB128IntValue(
Offset);
1420 }
else if (Reg < 64) {
1421 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1422 Streamer.emitULEB128IntValue(
Offset);
1424 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1425 Streamer.emitULEB128IntValue(Reg);
1426 Streamer.emitULEB128IntValue(
Offset);
1431 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1434 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1437 unsigned Reg =
Instr.getRegister();
1438 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1439 Streamer.emitULEB128IntValue(Reg);
1443 unsigned Reg =
Instr.getRegister();
1445 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1447 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1449 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1450 Streamer.emitULEB128IntValue(Reg);
1455 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1456 Streamer.emitULEB128IntValue(
Instr.getOffset());
1460 Streamer.emitBytes(
Instr.getValues());
1472 if (Label && !
Label->isDefined())
continue;
1475 if (BaseLabel && Label) {
1477 if (ThisSym != BaseLabel) {
1478 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1479 BaseLabel = ThisSym;
1483 emitCFIInstruction(Instr);
1515 if (!Encoding)
return;
1519 if (!DwarfEHFrameOnly && Frame.
Lsda)
1520 Encoding |= 0x40000000;
1525 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1534 Streamer.emitIntValue(Encoding,
Size);
1541 Streamer.emitIntValue(0,
Size);
1545 if (!DwarfEHFrameOnly && Frame.
Lsda)
1546 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1548 Streamer.emitIntValue(0,
Size);
1554 switch (DwarfVersion) {
1567 MCContext &context = Streamer.getContext();
1572 Streamer.emitLabel(sectionStart);
1587 *sectionEnd, UnitLengthBytes);
1593 Streamer.emitIntValue(CIE_ID, OffsetSize);
1597 Streamer.emitInt8(CIEVersion);
1601 Augmentation +=
"z";
1603 Augmentation +=
"P";
1605 Augmentation +=
"L";
1606 Augmentation +=
"R";
1608 Augmentation +=
"S";
1610 Augmentation +=
"B";
1612 Augmentation +=
"G";
1613 Streamer.emitBytes(Augmentation);
1615 Streamer.emitInt8(0);
1617 if (CIEVersion >= 4) {
1622 Streamer.emitInt8(0);
1632 unsigned RAReg = Frame.
RAReg;
1633 if (RAReg ==
static_cast<unsigned>(INT_MAX))
1634 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1636 if (CIEVersion == 1) {
1638 "DWARF 2 encodes return_address_register in one byte");
1639 Streamer.emitInt8(RAReg);
1641 Streamer.emitULEB128IntValue(RAReg);
1645 unsigned augmentationLength = 0;
1649 augmentationLength += 1;
1651 augmentationLength +=
1655 augmentationLength += 1;
1657 augmentationLength += 1;
1659 Streamer.emitULEB128IntValue(augmentationLength);
1682 emitCFIInstructions(Instructions,
nullptr);
1685 InitialCFAOffset = CFAOffset;
1690 Streamer.emitLabel(sectionEnd);
1691 return *sectionStart;
1694void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1698 MCContext &context = Streamer.getContext();
1703 CFAOffset = InitialCFAOffset;
1716 Streamer.emitLabel(fdeStart);
1729 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1734 unsigned PCEncoding =
1746 unsigned augmentationLength = 0;
1751 Streamer.emitULEB128IntValue(augmentationLength);
1766 Streamer.emitValueToAlignment(
Align(Alignment));
1768 Streamer.emitLabel(fdeEnd);
1774 static const CIEKey getEmptyKey() {
1775 return CIEKey(
nullptr, 0, -1,
false,
false,
static_cast<unsigned>(INT_MAX),
1779 static const CIEKey getTombstoneKey() {
1780 return CIEKey(
nullptr, -1, 0,
false,
false,
static_cast<unsigned>(INT_MAX),
1784 CIEKey(
const MCSymbol *Personality,
unsigned PersonalityEncoding,
1785 unsigned LSDAEncoding,
bool IsSignalFrame,
bool IsSimple,
1786 unsigned RAReg,
bool IsBKeyFrame,
bool IsMTETaggedFrame)
1787 : Personality(Personality), PersonalityEncoding(PersonalityEncoding),
1788 LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
1789 IsSimple(IsSimple), RAReg(RAReg), IsBKeyFrame(IsBKeyFrame),
1790 IsMTETaggedFrame(IsMTETaggedFrame) {}
1793 : Personality(Frame.Personality),
1794 PersonalityEncoding(Frame.PersonalityEncoding),
1795 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1796 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1797 IsBKeyFrame(Frame.IsBKeyFrame),
1798 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1803 return Personality->getName();
1807 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1808 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1810 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1813 Other.IsMTETaggedFrame);
1817 unsigned PersonalityEncoding;
1818 unsigned LsdaEncoding;
1823 bool IsMTETaggedFrame;
1835 return static_cast<unsigned>(
1836 hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
1837 Key.IsSignalFrame, Key.IsSimple, Key.RAReg,
1838 Key.IsBKeyFrame, Key.IsMTETaggedFrame));
1841 static bool isEqual(
const CIEKey &LHS,
const CIEKey &RHS) {
1842 return LHS.Personality ==
RHS.Personality &&
1843 LHS.PersonalityEncoding ==
RHS.PersonalityEncoding &&
1844 LHS.LsdaEncoding ==
RHS.LsdaEncoding &&
1845 LHS.IsSignalFrame ==
RHS.IsSignalFrame &&
1846 LHS.IsSimple ==
RHS.IsSimple &&
LHS.RAReg ==
RHS.RAReg &&
1847 LHS.IsBKeyFrame ==
RHS.IsBKeyFrame &&
1848 LHS.IsMTETaggedFrame ==
RHS.IsMTETaggedFrame;
1859 FrameEmitterImpl
Emitter(IsEH, Streamer);
1866 bool SectionEmitted =
false;
1869 if (!SectionEmitted) {
1872 SectionEmitted =
true;
1874 NeedsEHFrameSection |=
1877 Emitter.EmitCompactUnwind(Frame);
1885 if (!NeedsEHFrameSection && IsEH)
return;
1897 const MCSymbol *DummyDebugKey =
nullptr;
1903 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1906 return CIEKey(
X) < CIEKey(
Y);
1908 for (
auto I = FrameArrayX.begin(),
E = FrameArrayX.end();
I !=
E;) {
1922 const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1924 CIEStart = &
Emitter.EmitCIE(Frame);
1926 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 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
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.
static constexpr uint32_t Opcode
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())
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.
size_t addString(StringRef Path)
Adds path Path to the line 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)
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...
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.