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 HasSource,
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",
629 if (
HasSource != (Source != std::nullopt))
630 return make_error<StringError>(
"inconsistent use of embedded source",
633 if (Directory.
empty()) {
636 if (!tFileName.
empty()) {
638 if (!Directory.
empty())
639 FileName = tFileName;
646 if (Directory.
empty()) {
660 File.Name = std::string(FileName);
661 File.DirIndex = DirIndex;
662 File.Checksum = Checksum;
664 File.Source = Source;
674 int64_t LineDelta,
uint64_t AddrDelta) {
689 int64_t LineDelta,
uint64_t AddrDelta,
693 bool NeedCopy =
false;
705 if (AddrDelta == MaxSpecialAddrDelta)
706 Out.
push_back(dwarf::DW_LNS_const_add_pc);
707 else if (AddrDelta) {
711 Out.
push_back(dwarf::DW_LNS_extended_op);
713 Out.
push_back(dwarf::DW_LNE_end_sequence);
724 Out.
push_back(dwarf::DW_LNS_advance_line);
733 if (LineDelta == 0 && AddrDelta == 0) {
742 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
751 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
753 Out.
push_back(dwarf::DW_LNS_const_add_pc);
766 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
789 ? dwarf::DW_FORM_sec_offset
791 : dwarf::DW_FORM_data4);
792 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
795 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
797 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
798 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
800 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
802 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
804 if (!DwarfDebugFlags.
empty())
805 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
806 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
807 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
814 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
815 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
816 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
817 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
829 const MCSymbol *InfoSectionSymbol) {
836 unsigned UnitLengthBytes =
842 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
848 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
849 if (Pad == 2 * AddrSize)
855 Length += 2 * AddrSize * Sections.size();
870 if (InfoSectionSymbol)
880 for(
int i = 0; i < Pad; i++)
886 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
887 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
888 assert(StartSymbol &&
"StartSymbol must not be NULL");
889 assert(EndSymbol &&
"EndSymbol must not be NULL");
908 const MCSymbol *AbbrevSectionSymbol,
923 unsigned UnitLengthBytes =
945 MCOS->
emitInt8(dwarf::DW_UT_compile);
950 if (AbbrevSectionSymbol)
966 if (LineSectionSymbol)
984 const auto TextSection = Sections.begin();
985 assert(TextSection != Sections.end() &&
"No text section found");
987 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
988 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
989 assert(StartSymbol &&
"StartSymbol must not be NULL");
990 assert(EndSymbol &&
"EndSymbol must not be NULL");
1006 if (MCDwarfDirs.
size() > 0) {
1015 MCDwarfFiles.
empty()
1029 if (!DwarfDebugFlags.
empty()){
1036 if (!DwarfDebugProducer.
empty())
1044 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1049 const std::vector<MCGenDwarfLabelEntry> &Entries =
1051 for (
const auto &Entry : Entries) {
1097 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1098 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1101 const MCExpr *SectionSize =
1103 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1104 MCOS->
emitValue(SectionStartAddr, AddrSize);
1107 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1114 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1115 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1121 MCOS->
emitValue(SectionStartAddr, AddrSize);
1124 const MCExpr *SectionSize =
1135 return RangesSymbol;
1147 bool CreateDwarfSectionSymbols =
1149 MCSymbol *LineSectionSymbol =
nullptr;
1150 if (CreateDwarfSectionSymbols)
1152 MCSymbol *AbbrevSectionSymbol =
nullptr;
1153 MCSymbol *InfoSectionSymbol =
nullptr;
1166 const bool UseRangesSection =
1169 CreateDwarfSectionSymbols |= UseRangesSection;
1172 if (CreateDwarfSectionSymbols) {
1177 if (CreateDwarfSectionSymbols) {
1187 if (UseRangesSection) {
1196 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1208 if (Symbol->isTemporary())
1219 if (Name.startswith(
"_"))
1220 Name = Name.substr(1, Name.size()-1);
1253 unsigned symbolEncoding) {
1255 unsigned format = symbolEncoding & 0x0f;
1274 unsigned symbolEncoding,
bool isEH) {
1288 unsigned symbolEncoding) {
1300class FrameEmitterImpl {
1302 int InitialCFAOffset = 0;
1308 : IsEH(IsEH), Streamer(Streamer) {}
1315 bool LastInSection,
const MCSymbol &SectionStart);
1329 auto *
MRI = Streamer.getContext().getRegisterInfo();
1331 switch (
Instr.getOperation()) {
1333 unsigned Reg1 =
Instr.getRegister();
1334 unsigned Reg2 =
Instr.getRegister2();
1336 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1337 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1339 Streamer.emitInt8(dwarf::DW_CFA_register);
1340 Streamer.emitULEB128IntValue(Reg1);
1341 Streamer.emitULEB128IntValue(Reg2);
1345 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1349 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1353 unsigned Reg =
Instr.getRegister();
1354 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1355 Streamer.emitULEB128IntValue(Reg);
1360 const bool IsRelative =
1363 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1366 CFAOffset +=
Instr.getOffset();
1368 CFAOffset =
Instr.getOffset();
1370 Streamer.emitULEB128IntValue(CFAOffset);
1375 unsigned Reg =
Instr.getRegister();
1377 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1378 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1379 Streamer.emitULEB128IntValue(Reg);
1380 CFAOffset =
Instr.getOffset();
1381 Streamer.emitULEB128IntValue(CFAOffset);
1386 unsigned Reg =
Instr.getRegister();
1388 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1389 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1390 Streamer.emitULEB128IntValue(Reg);
1396 unsigned Reg =
Instr.getRegister();
1398 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1399 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1400 Streamer.emitULEB128IntValue(Reg);
1401 CFAOffset =
Instr.getOffset();
1402 Streamer.emitULEB128IntValue(CFAOffset);
1403 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1409 const bool IsRelative =
1412 unsigned Reg =
Instr.getRegister();
1414 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1422 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1423 Streamer.emitULEB128IntValue(Reg);
1424 Streamer.emitSLEB128IntValue(
Offset);
1425 }
else if (Reg < 64) {
1426 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1427 Streamer.emitULEB128IntValue(
Offset);
1429 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1430 Streamer.emitULEB128IntValue(Reg);
1431 Streamer.emitULEB128IntValue(
Offset);
1436 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1439 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1442 unsigned Reg =
Instr.getRegister();
1443 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1444 Streamer.emitULEB128IntValue(Reg);
1448 unsigned Reg =
Instr.getRegister();
1450 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1452 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1454 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1455 Streamer.emitULEB128IntValue(Reg);
1460 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1461 Streamer.emitULEB128IntValue(
Instr.getOffset());
1465 Streamer.emitBytes(
Instr.getValues());
1477 if (Label && !
Label->isDefined())
continue;
1480 if (BaseLabel && Label) {
1482 if (ThisSym != BaseLabel) {
1483 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1484 BaseLabel = ThisSym;
1488 emitCFIInstruction(Instr);
1520 if (!Encoding)
return;
1524 if (!DwarfEHFrameOnly && Frame.
Lsda)
1525 Encoding |= 0x40000000;
1530 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1539 Streamer.emitIntValue(Encoding,
Size);
1546 Streamer.emitIntValue(0,
Size);
1550 if (!DwarfEHFrameOnly && Frame.
Lsda)
1551 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1553 Streamer.emitIntValue(0,
Size);
1559 switch (DwarfVersion) {
1572 MCContext &context = Streamer.getContext();
1577 Streamer.emitLabel(sectionStart);
1592 *sectionEnd, UnitLengthBytes);
1598 Streamer.emitIntValue(CIE_ID, OffsetSize);
1602 Streamer.emitInt8(CIEVersion);
1606 Augmentation +=
"z";
1608 Augmentation +=
"P";
1610 Augmentation +=
"L";
1611 Augmentation +=
"R";
1613 Augmentation +=
"S";
1615 Augmentation +=
"B";
1617 Augmentation +=
"G";
1618 Streamer.emitBytes(Augmentation);
1620 Streamer.emitInt8(0);
1622 if (CIEVersion >= 4) {
1627 Streamer.emitInt8(0);
1637 unsigned RAReg = Frame.
RAReg;
1638 if (RAReg ==
static_cast<unsigned>(INT_MAX))
1639 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1641 if (CIEVersion == 1) {
1643 "DWARF 2 encodes return_address_register in one byte");
1644 Streamer.emitInt8(RAReg);
1646 Streamer.emitULEB128IntValue(RAReg);
1650 unsigned augmentationLength = 0;
1654 augmentationLength += 1;
1656 augmentationLength +=
1660 augmentationLength += 1;
1662 augmentationLength += 1;
1664 Streamer.emitULEB128IntValue(augmentationLength);
1687 emitCFIInstructions(Instructions,
nullptr);
1690 InitialCFAOffset = CFAOffset;
1695 Streamer.emitLabel(sectionEnd);
1696 return *sectionStart;
1699void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1703 MCContext &context = Streamer.getContext();
1708 CFAOffset = InitialCFAOffset;
1721 Streamer.emitLabel(fdeStart);
1734 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1739 unsigned PCEncoding =
1751 unsigned augmentationLength = 0;
1756 Streamer.emitULEB128IntValue(augmentationLength);
1771 Streamer.emitValueToAlignment(
Align(Alignment));
1773 Streamer.emitLabel(fdeEnd);
1779 static const CIEKey getEmptyKey() {
1780 return CIEKey(
nullptr, 0, -1,
false,
false,
static_cast<unsigned>(INT_MAX),
1784 static const CIEKey getTombstoneKey() {
1785 return CIEKey(
nullptr, -1, 0,
false,
false,
static_cast<unsigned>(INT_MAX),
1789 CIEKey(
const MCSymbol *Personality,
unsigned PersonalityEncoding,
1790 unsigned LSDAEncoding,
bool IsSignalFrame,
bool IsSimple,
1791 unsigned RAReg,
bool IsBKeyFrame,
bool IsMTETaggedFrame)
1792 : Personality(Personality), PersonalityEncoding(PersonalityEncoding),
1793 LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
1794 IsSimple(IsSimple), RAReg(RAReg), IsBKeyFrame(IsBKeyFrame),
1795 IsMTETaggedFrame(IsMTETaggedFrame) {}
1798 : Personality(Frame.Personality),
1799 PersonalityEncoding(Frame.PersonalityEncoding),
1800 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1801 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1802 IsBKeyFrame(Frame.IsBKeyFrame),
1803 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1808 return Personality->getName();
1812 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1813 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1815 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1818 Other.IsMTETaggedFrame);
1822 unsigned PersonalityEncoding;
1823 unsigned LsdaEncoding;
1828 bool IsMTETaggedFrame;
1840 return static_cast<unsigned>(
1841 hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
1842 Key.IsSignalFrame, Key.IsSimple, Key.RAReg,
1843 Key.IsBKeyFrame, Key.IsMTETaggedFrame));
1846 static bool isEqual(
const CIEKey &LHS,
const CIEKey &RHS) {
1847 return LHS.Personality ==
RHS.Personality &&
1848 LHS.PersonalityEncoding ==
RHS.PersonalityEncoding &&
1849 LHS.LsdaEncoding ==
RHS.LsdaEncoding &&
1850 LHS.IsSignalFrame ==
RHS.IsSignalFrame &&
1851 LHS.IsSimple ==
RHS.IsSimple &&
LHS.RAReg ==
RHS.RAReg &&
1852 LHS.IsBKeyFrame ==
RHS.IsBKeyFrame &&
1853 LHS.IsMTETaggedFrame ==
RHS.IsMTETaggedFrame;
1864 FrameEmitterImpl
Emitter(IsEH, Streamer);
1871 bool SectionEmitted =
false;
1874 if (!SectionEmitted) {
1877 SectionEmitted =
true;
1879 NeedsEHFrameSection |=
1882 Emitter.EmitCompactUnwind(Frame);
1890 if (!NeedsEHFrameSection && IsEH)
return;
1902 const MCSymbol *DummyDebugKey =
nullptr;
1908 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1911 return CIEKey(
X) < CIEKey(
Y);
1913 for (
auto I = FrameArrayX.begin(),
E = FrameArrayX.end();
I !=
E;) {
1927 const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1929 CIEStart = &
Emitter.EmitCIE(Frame);
1931 Emitter.EmitFDE(*CIEStart, Frame,
I ==
E, *SectionStart);
1947 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1949 }
else if (isUInt<8>(AddrDelta)) {
1950 Out.
push_back(dwarf::DW_CFA_advance_loc1);
1952 }
else if (isUInt<16>(AddrDelta)) {
1953 Out.
push_back(dwarf::DW_CFA_advance_loc2);
1954 support::endian::write<uint16_t>(Out, AddrDelta,
E);
1956 assert(isUInt<32>(AddrDelta));
1957 Out.
push_back(dwarf::DW_CFA_advance_loc4);
1958 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())
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.