17#include "llvm/Config/config.h"
66 unsigned MinInsnLength =
Context.getAsmInfo()->getMinInstAlignment();
67 if (MinInsnLength == 1)
69 if (AddrDelta % MinInsnLength != 0) {
73 return AddrDelta / MinInsnLength;
81 assert(DwarfLineStrSection &&
"DwarfLineStrSection must not be NULL");
134static inline const MCExpr *
153 auto I = MCLineDivisions.
find(Sec);
154 if (
I == MCLineDivisions.
end())
157 auto &Entries =
I->second;
171 Entries.push_back(EndEntry);
182 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
198 bool EndEntryEmitted =
false;
200 MCSymbol *Label = LineEntry.getLabel();
203 if (LineEntry.LineStreamLabel) {
209 MCOS->
emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
213 if (LineEntry.IsEndEntry) {
217 EndEntryEmitted =
true;
221 int64_t LineDelta =
static_cast<int64_t
>(LineEntry.getLine()) - LastLine;
223 if (FileNum != LineEntry.getFileNum()) {
224 FileNum = LineEntry.getFileNum();
225 MCOS->
emitInt8(dwarf::DW_LNS_set_file);
228 if (Column != LineEntry.getColumn()) {
229 Column = LineEntry.getColumn();
230 MCOS->
emitInt8(dwarf::DW_LNS_set_column);
233 if (Discriminator != LineEntry.getDiscriminator() &&
235 Discriminator = LineEntry.getDiscriminator();
237 MCOS->
emitInt8(dwarf::DW_LNS_extended_op);
239 MCOS->
emitInt8(dwarf::DW_LNE_set_discriminator);
242 if (Isa != LineEntry.getIsa()) {
243 Isa = LineEntry.getIsa();
244 MCOS->
emitInt8(dwarf::DW_LNS_set_isa);
248 Flags = LineEntry.getFlags();
249 MCOS->
emitInt8(dwarf::DW_LNS_negate_stmt);
252 MCOS->
emitInt8(dwarf::DW_LNS_set_basic_block);
254 MCOS->
emitInt8(dwarf::DW_LNS_set_prologue_end);
256 MCOS->
emitInt8(dwarf::DW_LNS_set_epilogue_begin);
265 LastLine = LineEntry.getLine();
267 IsAtStartSeq =
false;
275 if (!EndEntryEmitted && !IsAtStartSeq)
284 auto *LineSym = ctx.createTempSymbol();
286 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
305 if (LineTables.empty())
309 std::optional<MCDwarfLineStr> LineStr;
311 LineStr.emplace(context);
317 for (
const auto &CUIDTablePair : LineTables) {
318 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
322 LineStr->emitSection(MCOS);
327 if (!HasSplitLineTable)
329 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
331 MCOS.
emitLabel(Header.
Emit(&MCOS, Params, {}, NoLineStr).second);
334std::pair<MCSymbol *, MCSymbol *>
336 std::optional<MCDwarfLineStr> &LineStr)
const {
337 static const char StandardOpcodeLengths[] = {
351 assert(std::size(StandardOpcodeLengths) >=
353 return Emit(MCOS, Params,
360 assert(!isa<MCSymbolRefExpr>(Expr));
361 if (!
Context.getAsmInfo()->doesSetDirectiveSuppressReloc())
366 OS.emitAssignment(ABS, Expr);
394 return LineStrings.
add(Path);
413void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
434 bool EmitMD5,
bool HasAnySource,
435 std::optional<MCDwarfLineStr> &LineStr) {
447 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
458 LineStr->emitRef(MCOS, Source);
466void MCDwarfLineTableHeader::emitV5FileDirTables(
467 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
474 : dwarf::DW_FORM_string);
484 CompDir = LineStr->getSaver().save(CompDir);
488 LineStr->emitRef(MCOS, CompDir);
490 LineStr->emitRef(MCOS, Dir);
512 : dwarf::DW_FORM_string);
522 : dwarf::DW_FORM_string);
532 "No root file and no .file directives");
539std::pair<MCSymbol *, MCSymbol *>
542 std::optional<MCDwarfLineStr> &LineStr)
const {
562 if (LineTableVersion >= 5) {
582 if (LineTableVersion >= 4)
590 for (
char Length : StandardOpcodeLengths)
595 if (LineTableVersion >= 5)
596 emitV5FileDirTables(MCOS, LineStr);
598 emitV2FileDirTables(MCOS);
604 return std::make_pair(LineStartSym, LineEndSym);
608 std::optional<MCDwarfLineStr> &LineStr)
const {
609 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
613 emitOne(MCOS, LineSec.first, LineSec.second);
622 std::optional<MD5::MD5Result> Checksum,
623 std::optional<StringRef> Source,
624 uint16_t DwarfVersion,
unsigned FileNumber) {
625 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
631 std::optional<MD5::MD5Result> Checksum) {
634 return RootFile.
Checksum == Checksum;
639 std::optional<MD5::MD5Result> Checksum,
640 std::optional<StringRef> Source,
641 uint16_t DwarfVersion,
unsigned FileNumber) {
644 if (FileName.
empty()) {
645 FileName =
"<stdin>";
657 if (FileNumber == 0) {
663 std::make_pair((Directory +
Twine(
'\0') + FileName).toStringRef(Buffer),
665 if (!IterBool.second)
666 return IterBool.first->second;
676 if (!File.Name.empty())
677 return make_error<StringError>(
"file number already allocated",
680 if (Directory.
empty()) {
683 if (!tFileName.
empty()) {
685 if (!Directory.
empty())
686 FileName = tFileName;
693 if (Directory.
empty()) {
707 File.Name = std::string(FileName);
708 File.DirIndex = DirIndex;
709 File.Checksum = Checksum;
711 File.Source = Source;
712 if (Source.has_value())
721 int64_t LineDelta,
uint64_t AddrDelta) {
736 int64_t LineDelta,
uint64_t AddrDelta,
740 bool NeedCopy =
false;
752 if (AddrDelta == MaxSpecialAddrDelta)
753 Out.
push_back(dwarf::DW_LNS_const_add_pc);
754 else if (AddrDelta) {
758 Out.
push_back(dwarf::DW_LNS_extended_op);
760 Out.
push_back(dwarf::DW_LNE_end_sequence);
771 Out.
push_back(dwarf::DW_LNS_advance_line);
780 if (LineDelta == 0 && AddrDelta == 0) {
789 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
798 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
800 Out.
push_back(dwarf::DW_LNS_const_add_pc);
813 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
836 ? dwarf::DW_FORM_sec_offset
838 : dwarf::DW_FORM_data4);
839 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
842 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
844 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
845 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
847 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
849 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
851 if (!DwarfDebugFlags.
empty())
852 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
853 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
854 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
861 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
862 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
863 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
864 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
876 const MCSymbol *InfoSectionSymbol) {
883 unsigned UnitLengthBytes =
889 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
895 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
896 if (Pad == 2 * AddrSize)
902 Length += 2 * AddrSize * Sections.size();
917 if (InfoSectionSymbol)
927 for(
int i = 0; i < Pad; i++)
933 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
934 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
935 assert(StartSymbol &&
"StartSymbol must not be NULL");
936 assert(EndSymbol &&
"EndSymbol must not be NULL");
954 const MCSymbol *AbbrevSectionSymbol,
969 unsigned UnitLengthBytes =
991 MCOS->
emitInt8(dwarf::DW_UT_compile);
996 if (AbbrevSectionSymbol)
1012 if (LineSectionSymbol)
1030 const auto TextSection = Sections.begin();
1031 assert(TextSection != Sections.end() &&
"No text section found");
1033 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1034 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1035 assert(StartSymbol &&
"StartSymbol must not be NULL");
1036 assert(EndSymbol &&
"EndSymbol must not be NULL");
1050 if (MCDwarfDirs.
size() > 0) {
1059 MCDwarfFiles.
empty()
1073 if (!DwarfDebugFlags.
empty()){
1080 if (!DwarfDebugProducer.
empty())
1088 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1093 const std::vector<MCGenDwarfLabelEntry> &Entries =
1095 for (
const auto &Entry : Entries) {
1140 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1141 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1142 const MCExpr *SectionStartAddr =
1144 const MCExpr *SectionSize =
1146 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1147 MCOS->
emitValue(SectionStartAddr, AddrSize);
1150 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1157 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1158 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1161 const MCExpr *SectionStartAddr =
1164 MCOS->
emitValue(SectionStartAddr, AddrSize);
1167 const MCExpr *SectionSize =
1178 return RangesSymbol;
1190 bool CreateDwarfSectionSymbols =
1192 MCSymbol *LineSectionSymbol =
nullptr;
1193 if (CreateDwarfSectionSymbols)
1195 MCSymbol *AbbrevSectionSymbol =
nullptr;
1196 MCSymbol *InfoSectionSymbol =
nullptr;
1209 const bool UseRangesSection =
1212 CreateDwarfSectionSymbols |= UseRangesSection;
1215 if (CreateDwarfSectionSymbols) {
1220 if (CreateDwarfSectionSymbols) {
1230 if (UseRangesSection) {
1239 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1251 if (Symbol->isTemporary())
1262 if (Name.starts_with(
"_"))
1263 Name = Name.substr(1, Name.size()-1);
1296 unsigned symbolEncoding) {
1298 unsigned format = symbolEncoding & 0x0f;
1317 unsigned symbolEncoding,
bool isEH) {
1331 unsigned symbolEncoding) {
1343class FrameEmitterImpl {
1344 int64_t CFAOffset = 0;
1345 int64_t InitialCFAOffset = 0;
1351 : IsEH(IsEH), Streamer(Streamer) {}
1358 bool LastInSection,
const MCSymbol &SectionStart);
1372 auto *
MRI = Streamer.getContext().getRegisterInfo();
1374 switch (
Instr.getOperation()) {
1376 unsigned Reg1 =
Instr.getRegister();
1377 unsigned Reg2 =
Instr.getRegister2();
1379 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1380 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1382 Streamer.emitInt8(dwarf::DW_CFA_register);
1383 Streamer.emitULEB128IntValue(Reg1);
1384 Streamer.emitULEB128IntValue(Reg2);
1388 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1392 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1396 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1400 unsigned Reg =
Instr.getRegister();
1401 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1402 Streamer.emitULEB128IntValue(Reg);
1407 const bool IsRelative =
1410 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1413 CFAOffset +=
Instr.getOffset();
1415 CFAOffset =
Instr.getOffset();
1417 Streamer.emitULEB128IntValue(CFAOffset);
1422 unsigned Reg =
Instr.getRegister();
1424 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1425 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1426 Streamer.emitULEB128IntValue(Reg);
1427 CFAOffset =
Instr.getOffset();
1428 Streamer.emitULEB128IntValue(CFAOffset);
1433 unsigned Reg =
Instr.getRegister();
1435 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1436 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1437 Streamer.emitULEB128IntValue(Reg);
1443 unsigned Reg =
Instr.getRegister();
1445 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1446 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1447 Streamer.emitULEB128IntValue(Reg);
1448 CFAOffset =
Instr.getOffset();
1449 Streamer.emitULEB128IntValue(CFAOffset);
1450 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1456 const bool IsRelative =
1459 unsigned Reg =
Instr.getRegister();
1461 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1469 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1470 Streamer.emitULEB128IntValue(Reg);
1471 Streamer.emitSLEB128IntValue(
Offset);
1472 }
else if (Reg < 64) {
1473 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1474 Streamer.emitULEB128IntValue(
Offset);
1476 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1477 Streamer.emitULEB128IntValue(Reg);
1478 Streamer.emitULEB128IntValue(
Offset);
1483 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1486 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1489 unsigned Reg =
Instr.getRegister();
1490 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1491 Streamer.emitULEB128IntValue(Reg);
1495 unsigned Reg =
Instr.getRegister();
1497 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1499 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1501 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1502 Streamer.emitULEB128IntValue(Reg);
1507 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1508 Streamer.emitULEB128IntValue(
Instr.getOffset());
1512 Streamer.emitBytes(
Instr.getValues());
1515 Streamer.emitLabel(
Instr.getCfiLabel(),
Instr.getLoc());
1518 unsigned Reg =
Instr.getRegister();
1520 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1526 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1527 Streamer.emitULEB128IntValue(Reg);
1528 Streamer.emitSLEB128IntValue(
Offset);
1530 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1531 Streamer.emitULEB128IntValue(Reg);
1532 Streamer.emitULEB128IntValue(
Offset);
1546 if (Label && !
Label->isDefined())
continue;
1549 if (BaseLabel && Label) {
1551 if (ThisSym != BaseLabel) {
1552 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1553 BaseLabel = ThisSym;
1557 emitCFIInstruction(Instr);
1589 if (!Encoding)
return;
1593 if (!DwarfEHFrameOnly && Frame.
Lsda)
1594 Encoding |= 0x40000000;
1599 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1608 Streamer.emitIntValue(Encoding,
Size);
1615 Streamer.emitIntValue(0,
Size);
1619 if (!DwarfEHFrameOnly && Frame.
Lsda)
1620 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1622 Streamer.emitIntValue(0,
Size);
1628 switch (DwarfVersion) {
1641 MCContext &context = Streamer.getContext();
1646 Streamer.emitLabel(sectionStart);
1661 *sectionEnd, UnitLengthBytes);
1667 Streamer.emitIntValue(CIE_ID, OffsetSize);
1671 Streamer.emitInt8(CIEVersion);
1675 Augmentation +=
"z";
1677 Augmentation +=
"P";
1679 Augmentation +=
"L";
1680 Augmentation +=
"R";
1682 Augmentation +=
"S";
1684 Augmentation +=
"B";
1686 Augmentation +=
"G";
1687 Streamer.emitBytes(Augmentation);
1689 Streamer.emitInt8(0);
1691 if (CIEVersion >= 4) {
1696 Streamer.emitInt8(0);
1707 if (
RAReg ==
static_cast<unsigned>(INT_MAX))
1708 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1710 if (CIEVersion == 1) {
1712 "DWARF 2 encodes return_address_register in one byte");
1713 Streamer.emitInt8(
RAReg);
1715 Streamer.emitULEB128IntValue(
RAReg);
1719 unsigned augmentationLength = 0;
1723 augmentationLength += 1;
1725 augmentationLength +=
1729 augmentationLength += 1;
1731 augmentationLength += 1;
1733 Streamer.emitULEB128IntValue(augmentationLength);
1756 emitCFIInstructions(Instructions,
nullptr);
1759 InitialCFAOffset = CFAOffset;
1764 Streamer.emitLabel(sectionEnd);
1765 return *sectionStart;
1768void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1772 MCContext &context = Streamer.getContext();
1777 CFAOffset = InitialCFAOffset;
1790 Streamer.emitLabel(fdeStart);
1803 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1808 unsigned PCEncoding =
1820 unsigned augmentationLength = 0;
1825 Streamer.emitULEB128IntValue(augmentationLength);
1840 Streamer.emitValueToAlignment(
Align(Alignment));
1842 Streamer.emitLabel(fdeEnd);
1851 : Personality(Frame.Personality),
1852 PersonalityEncoding(Frame.PersonalityEncoding),
1853 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1854 IsSimple(Frame.IsSimple),
RAReg(Frame.
RAReg),
1855 IsBKeyFrame(Frame.IsBKeyFrame),
1856 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1861 return Personality->getName();
1865 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1866 IsSignalFrame, IsSimple,
RAReg, IsBKeyFrame,
1868 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1871 Other.IsMTETaggedFrame);
1875 return Personality ==
Other.Personality &&
1876 PersonalityEncoding ==
Other.PersonalityEncoding &&
1877 LsdaEncoding ==
Other.LsdaEncoding &&
1878 IsSignalFrame ==
Other.IsSignalFrame && IsSimple ==
Other.IsSimple &&
1880 IsMTETaggedFrame ==
Other.IsMTETaggedFrame;
1884 const MCSymbol *Personality =
nullptr;
1885 unsigned PersonalityEncoding = 0;
1886 unsigned LsdaEncoding = -1;
1887 bool IsSignalFrame =
false;
1888 bool IsSimple =
false;
1889 unsigned RAReg = UINT_MAX;
1890 bool IsBKeyFrame =
false;
1891 bool IsMTETaggedFrame =
false;
1901 FrameEmitterImpl
Emitter(IsEH, Streamer);
1908 bool SectionEmitted =
false;
1911 if (!SectionEmitted) {
1914 SectionEmitted =
true;
1916 NeedsEHFrameSection |=
1919 Emitter.EmitCompactUnwind(Frame);
1927 if (!NeedsEHFrameSection && IsEH)
return;
1942 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1945 return CIEKey(
X) < CIEKey(
Y);
1948 const MCSymbol *LastCIEStart =
nullptr;
1949 for (
auto I = FrameArrayX.begin(), E = FrameArrayX.end();
I != E;) {
1963 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1965 LastCIEStart = &
Emitter.EmitCIE(Frame);
1968 Emitter.EmitFDE(*LastCIEStart, Frame,
I == E, *SectionStart);
1985 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1987 }
else if (isUInt<8>(AddrDelta)) {
1988 Out.
push_back(dwarf::DW_CFA_advance_loc1);
1990 }
else if (isUInt<16>(AddrDelta)) {
1991 Out.
push_back(dwarf::DW_CFA_advance_loc2);
1992 support::endian::write<uint16_t>(Out, AddrDelta, E);
1994 assert(isUInt<32>(AddrDelta));
1995 Out.
push_back(dwarf::DW_CFA_advance_loc4);
1996 support::endian::write<uint32_t>(Out, AddrDelta, E);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
This file contains constants used for implementing Dwarf debug support.
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH)
static uint64_t SpecialAddr(MCDwarfLineTableParams Params, uint64_t op)
Given a special op, return the address skip amount (in units of DWARF2_LINE_MIN_INSN_LENGTH).
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum)
static uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta)
static const MCExpr * forceExpAbs(MCStreamer &OS, const MCExpr *Expr)
static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, bool EmitMD5, bool HasAnySource, std::optional< MCDwarfLineStr > &LineStr)
static const MCExpr * makeEndMinusStartExpr(MCContext &Ctx, const MCSymbol &Start, const MCSymbol &End, int IntVal)
static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion)
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
static int getDataAlignmentFactor(MCStreamer &streamer)
static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)
static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static constexpr MCPhysReg RAReg
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 LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI 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()
LLVM_ABI 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
LLVM_ABI void finalizeDwarfSections(MCStreamer &MCOS)
Remove empty sections from SectionsForRanges, to avoid generating useless debug info for them.
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
dwarf::DwarfFormat getDwarfFormat() const
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
LLVM_ABI void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
static LLVM_ABI void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
static LLVM_ABI void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
static LLVM_ABI 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.
void setEndLabel(MCSymbol *EndLabel)
MCSymbol * LineStreamLabel
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
LLVM_ABI void emitSection(MCStreamer *MCOS)
Emit the .debug_line_str section if appropriate.
LLVM_ABI MCDwarfLineStr(MCContext &Ctx)
Construct an instance that can emit .debug_line_str (for use in a normal v5 line table).
LLVM_ABI SmallString< 0 > getFinalizedData()
Returns finalized section.
LLVM_ABI void emitRef(MCStreamer *MCOS, StringRef Path)
Emit a reference to the string.
LLVM_ABI size_t addString(StringRef Path)
Adds path Path to the line string.
LLVM_ABI void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
MCDwarfFile & getRootFile()
const MCLineSection & getMCLineSections() const
static LLVM_ABI void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
static LLVM_ABI void emitOne(MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries)
LLVM_ABI Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
LLVM_ABI 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 LLVM_ABI void Emit(MCStreamer *MCOS)
static LLVM_ABI void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
const MCLineDivisionMap & getMCLineEntries() const
LLVM_ABI 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 Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
Streaming machine code generation interface.
void generateCompactUnwindEncodings(MCAsmBackend *MAB)
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
MCContext & getContext() const
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)
Emit the absolute difference between two symbols.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
If targets does not support representing debug line section by .loc/.file directives in assembly outp...
void emitInt16(uint64_t Value)
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
virtual void emitULEB128Value(const MCExpr *Value)
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
MCSection * getCurrentSectionOnly() const
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)
Emit the debug line end entry.
void emitInt8(uint64_t Value)
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
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.
LLVM_ABI 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.
LLVM_ABI void finalizeInOrder()
Finalize the string table without reording it.
LLVM_ABI size_t add(CachedHashStringRef S, uint8_t Priority=0)
Add a string to the builder.
LLVM_ABI void write(raw_ostream &OS) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Reg
All possible values of the reg field in the ModR/M byte.
const uint32_t DW_CIE_ID
Special ID values that distinguish a CIE from a FDE in DWARF CFI.
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
const uint64_t DW64_CIE_ID
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
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.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
bool operator!=(uint64_t V1, const APInt &V2)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
const MCSymbol * Personality
unsigned PersonalityEncoding
uint64_t CompactUnwindEncoding
std::vector< MCCFIInstruction > Instructions
uint8_t DWARF2LineOpcodeBase
First special line opcode - leave room for the standard opcodes.
uint8_t DWARF2LineRange
Range of line offsets in a special line info. opcode.
int8_t DWARF2LineBase
Minimum line offset in a special line info.