20#include "llvm/Config/config.h"
71 if (MinInsnLength == 1)
73 if (AddrDelta % MinInsnLength != 0) {
77 return AddrDelta / MinInsnLength;
85 assert(DwarfLineStrSection &&
"DwarfLineStrSection must not be NULL");
139static inline const MCExpr *
157 auto I = MCLineDivisions.
find(Sec);
158 if (
I != MCLineDivisions.
end()) {
159 auto &Entries =
I->second;
160 auto EndEntry = Entries.back();
161 EndEntry.setEndLabel(EndLabel);
162 Entries.push_back(EndEntry);
174 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
188 bool EndEntryEmitted =
false;
190 MCSymbol *Label = LineEntry.getLabel();
192 if (LineEntry.IsEndEntry) {
196 EndEntryEmitted =
true;
200 int64_t LineDelta =
static_cast<int64_t
>(LineEntry.getLine()) - LastLine;
202 if (FileNum != LineEntry.getFileNum()) {
203 FileNum = LineEntry.getFileNum();
204 MCOS->
emitInt8(dwarf::DW_LNS_set_file);
207 if (Column != LineEntry.getColumn()) {
208 Column = LineEntry.getColumn();
209 MCOS->
emitInt8(dwarf::DW_LNS_set_column);
212 if (Discriminator != LineEntry.getDiscriminator() &&
214 Discriminator = LineEntry.getDiscriminator();
216 MCOS->
emitInt8(dwarf::DW_LNS_extended_op);
218 MCOS->
emitInt8(dwarf::DW_LNE_set_discriminator);
221 if (Isa != LineEntry.getIsa()) {
222 Isa = LineEntry.getIsa();
223 MCOS->
emitInt8(dwarf::DW_LNS_set_isa);
227 Flags = LineEntry.getFlags();
228 MCOS->
emitInt8(dwarf::DW_LNS_negate_stmt);
231 MCOS->
emitInt8(dwarf::DW_LNS_set_basic_block);
233 MCOS->
emitInt8(dwarf::DW_LNS_set_prologue_end);
235 MCOS->
emitInt8(dwarf::DW_LNS_set_epilogue_begin);
244 LastLine = LineEntry.getLine();
253 if (!EndEntryEmitted)
267 if (LineTables.empty())
271 std::optional<MCDwarfLineStr> LineStr;
273 LineStr.emplace(context);
279 for (
const auto &CUIDTablePair : LineTables) {
280 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
284 LineStr->emitSection(MCOS);
289 if (!HasSplitLineTable)
291 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
293 MCOS.
emitLabel(Header.
Emit(&MCOS, Params, std::nullopt, NoLineStr).second);
296std::pair<MCSymbol *, MCSymbol *>
298 std::optional<MCDwarfLineStr> &LineStr)
const {
299 static const char StandardOpcodeLengths[] = {
313 assert(std::size(StandardOpcodeLengths) >=
315 return Emit(MCOS, Params,
322 assert(!isa<MCSymbolRefExpr>(Expr));
328 OS.emitAssignment(ABS, Expr);
351 LineStrings.
write((uint8_t *)
Data.data());
356 return LineStrings.
add(Path);
375void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
396 bool EmitMD5,
bool HasAnySource,
397 std::optional<MCDwarfLineStr> &LineStr) {
409 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
421void MCDwarfLineTableHeader::emitV5FileDirTables(
422 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
429 : dwarf::DW_FORM_string);
439 CompDir = LineStr->getSaver().save(CompDir);
443 LineStr->emitRef(MCOS, CompDir);
445 LineStr->emitRef(MCOS, Dir);
467 : dwarf::DW_FORM_string);
477 : dwarf::DW_FORM_string);
487 "No root file and no .file directives");
494std::pair<MCSymbol *, MCSymbol *>
497 std::optional<MCDwarfLineStr> &LineStr)
const {
517 if (LineTableVersion >= 5) {
537 if (LineTableVersion >= 4)
545 for (
char Length : StandardOpcodeLengths)
550 if (LineTableVersion >= 5)
551 emitV5FileDirTables(MCOS, LineStr);
553 emitV2FileDirTables(MCOS);
559 return std::make_pair(LineStartSym, LineEndSym);
563 std::optional<MCDwarfLineStr> &LineStr)
const {
564 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
568 emitOne(MCOS, LineSec.first, LineSec.second);
577 std::optional<MD5::MD5Result> Checksum,
578 std::optional<StringRef> Source,
579 uint16_t DwarfVersion,
unsigned FileNumber) {
580 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
586 std::optional<MD5::MD5Result> Checksum) {
589 return RootFile.
Checksum == Checksum;
594 std::optional<MD5::MD5Result> Checksum,
595 std::optional<StringRef> Source,
596 uint16_t DwarfVersion,
unsigned FileNumber) {
599 if (FileName.
empty()) {
600 FileName =
"<stdin>";
612 if (FileNumber == 0) {
620 if (!IterBool.second)
621 return IterBool.first->second;
631 if (!File.Name.empty())
632 return make_error<StringError>(
"file number already allocated",
635 if (Directory.
empty()) {
638 if (!tFileName.
empty()) {
640 if (!Directory.
empty())
641 FileName = tFileName;
648 if (Directory.
empty()) {
662 File.Name = std::string(FileName);
663 File.DirIndex = DirIndex;
664 File.Checksum = Checksum;
666 File.Source = Source;
667 if (Source.has_value())
676 int64_t LineDelta,
uint64_t AddrDelta) {
691 int64_t LineDelta,
uint64_t AddrDelta,
695 bool NeedCopy =
false;
707 if (AddrDelta == MaxSpecialAddrDelta)
708 Out.
push_back(dwarf::DW_LNS_const_add_pc);
709 else if (AddrDelta) {
713 Out.
push_back(dwarf::DW_LNS_extended_op);
715 Out.
push_back(dwarf::DW_LNE_end_sequence);
726 Out.
push_back(dwarf::DW_LNS_advance_line);
735 if (LineDelta == 0 && AddrDelta == 0) {
744 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
753 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
755 Out.
push_back(dwarf::DW_LNS_const_add_pc);
768 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
791 ? dwarf::DW_FORM_sec_offset
793 : dwarf::DW_FORM_data4);
794 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
797 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
799 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
800 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
802 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
804 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
806 if (!DwarfDebugFlags.
empty())
807 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
808 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
809 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
816 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
817 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
818 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
819 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
831 const MCSymbol *InfoSectionSymbol) {
838 unsigned UnitLengthBytes =
844 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
850 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
851 if (Pad == 2 * AddrSize)
857 Length += 2 * AddrSize * Sections.size();
872 if (InfoSectionSymbol)
882 for(
int i = 0; i < Pad; i++)
888 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
889 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
890 assert(StartSymbol &&
"StartSymbol must not be NULL");
891 assert(EndSymbol &&
"EndSymbol must not be NULL");
910 const MCSymbol *AbbrevSectionSymbol,
925 unsigned UnitLengthBytes =
947 MCOS->
emitInt8(dwarf::DW_UT_compile);
952 if (AbbrevSectionSymbol)
968 if (LineSectionSymbol)
986 const auto TextSection = Sections.begin();
987 assert(TextSection != Sections.end() &&
"No text section found");
989 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
990 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
991 assert(StartSymbol &&
"StartSymbol must not be NULL");
992 assert(EndSymbol &&
"EndSymbol must not be NULL");
1008 if (MCDwarfDirs.
size() > 0) {
1017 MCDwarfFiles.
empty()
1031 if (!DwarfDebugFlags.
empty()){
1038 if (!DwarfDebugProducer.
empty())
1046 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1051 const std::vector<MCGenDwarfLabelEntry> &Entries =
1053 for (
const auto &Entry : Entries) {
1099 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1100 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1103 const MCExpr *SectionSize =
1105 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1106 MCOS->
emitValue(SectionStartAddr, AddrSize);
1109 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1116 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1117 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1123 MCOS->
emitValue(SectionStartAddr, AddrSize);
1126 const MCExpr *SectionSize =
1137 return RangesSymbol;
1149 bool CreateDwarfSectionSymbols =
1151 MCSymbol *LineSectionSymbol =
nullptr;
1152 if (CreateDwarfSectionSymbols)
1154 MCSymbol *AbbrevSectionSymbol =
nullptr;
1155 MCSymbol *InfoSectionSymbol =
nullptr;
1168 const bool UseRangesSection =
1171 CreateDwarfSectionSymbols |= UseRangesSection;
1174 if (CreateDwarfSectionSymbols) {
1179 if (CreateDwarfSectionSymbols) {
1189 if (UseRangesSection) {
1198 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1210 if (Symbol->isTemporary())
1221 if (Name.starts_with(
"_"))
1222 Name = Name.substr(1, Name.size()-1);
1255 unsigned symbolEncoding) {
1257 unsigned format = symbolEncoding & 0x0f;
1276 unsigned symbolEncoding,
bool isEH) {
1290 unsigned symbolEncoding) {
1302class FrameEmitterImpl {
1303 int64_t CFAOffset = 0;
1304 int64_t InitialCFAOffset = 0;
1310 : IsEH(IsEH), Streamer(Streamer) {}
1317 bool LastInSection,
const MCSymbol &SectionStart);
1331 auto *
MRI = Streamer.getContext().getRegisterInfo();
1333 switch (
Instr.getOperation()) {
1335 unsigned Reg1 =
Instr.getRegister();
1336 unsigned Reg2 =
Instr.getRegister2();
1338 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1339 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1341 Streamer.emitInt8(dwarf::DW_CFA_register);
1342 Streamer.emitULEB128IntValue(Reg1);
1343 Streamer.emitULEB128IntValue(Reg2);
1347 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1351 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1355 unsigned Reg =
Instr.getRegister();
1356 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1357 Streamer.emitULEB128IntValue(Reg);
1362 const bool IsRelative =
1365 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1368 CFAOffset +=
Instr.getOffset();
1370 CFAOffset =
Instr.getOffset();
1372 Streamer.emitULEB128IntValue(CFAOffset);
1377 unsigned Reg =
Instr.getRegister();
1379 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1380 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1381 Streamer.emitULEB128IntValue(Reg);
1382 CFAOffset =
Instr.getOffset();
1383 Streamer.emitULEB128IntValue(CFAOffset);
1388 unsigned Reg =
Instr.getRegister();
1390 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1391 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1392 Streamer.emitULEB128IntValue(Reg);
1398 unsigned Reg =
Instr.getRegister();
1400 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1401 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1402 Streamer.emitULEB128IntValue(Reg);
1403 CFAOffset =
Instr.getOffset();
1404 Streamer.emitULEB128IntValue(CFAOffset);
1405 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1411 const bool IsRelative =
1414 unsigned Reg =
Instr.getRegister();
1416 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1424 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1425 Streamer.emitULEB128IntValue(Reg);
1426 Streamer.emitSLEB128IntValue(
Offset);
1427 }
else if (Reg < 64) {
1428 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1429 Streamer.emitULEB128IntValue(
Offset);
1431 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1432 Streamer.emitULEB128IntValue(Reg);
1433 Streamer.emitULEB128IntValue(
Offset);
1438 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1441 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1444 unsigned Reg =
Instr.getRegister();
1445 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1446 Streamer.emitULEB128IntValue(Reg);
1450 unsigned Reg =
Instr.getRegister();
1452 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1454 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1456 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1457 Streamer.emitULEB128IntValue(Reg);
1462 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1463 Streamer.emitULEB128IntValue(
Instr.getOffset());
1467 Streamer.emitBytes(
Instr.getValues());
1470 Streamer.emitLabel(
Instr.getCfiLabel(),
Instr.getLoc());
1482 if (Label && !
Label->isDefined())
continue;
1485 if (BaseLabel && Label) {
1487 if (ThisSym != BaseLabel) {
1488 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1489 BaseLabel = ThisSym;
1493 emitCFIInstruction(Instr);
1499 MCContext &Context = Streamer.getContext();
1525 if (!Encoding)
return;
1529 if (!DwarfEHFrameOnly && Frame.
Lsda)
1530 Encoding |= 0x40000000;
1535 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1544 Streamer.emitIntValue(Encoding,
Size);
1551 Streamer.emitIntValue(0,
Size);
1555 if (!DwarfEHFrameOnly && Frame.
Lsda)
1556 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1558 Streamer.emitIntValue(0,
Size);
1564 switch (DwarfVersion) {
1577 MCContext &context = Streamer.getContext();
1582 Streamer.emitLabel(sectionStart);
1597 *sectionEnd, UnitLengthBytes);
1603 Streamer.emitIntValue(CIE_ID, OffsetSize);
1607 Streamer.emitInt8(CIEVersion);
1611 Augmentation +=
"z";
1613 Augmentation +=
"P";
1615 Augmentation +=
"L";
1616 Augmentation +=
"R";
1618 Augmentation +=
"S";
1620 Augmentation +=
"B";
1622 Augmentation +=
"G";
1623 Streamer.emitBytes(Augmentation);
1625 Streamer.emitInt8(0);
1627 if (CIEVersion >= 4) {
1632 Streamer.emitInt8(0);
1642 unsigned RAReg = Frame.
RAReg;
1643 if (RAReg ==
static_cast<unsigned>(INT_MAX))
1644 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1646 if (CIEVersion == 1) {
1648 "DWARF 2 encodes return_address_register in one byte");
1649 Streamer.emitInt8(RAReg);
1651 Streamer.emitULEB128IntValue(RAReg);
1655 unsigned augmentationLength = 0;
1659 augmentationLength += 1;
1661 augmentationLength +=
1665 augmentationLength += 1;
1667 augmentationLength += 1;
1669 Streamer.emitULEB128IntValue(augmentationLength);
1692 emitCFIInstructions(Instructions,
nullptr);
1695 InitialCFAOffset = CFAOffset;
1700 Streamer.emitLabel(sectionEnd);
1701 return *sectionStart;
1704void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1708 MCContext &context = Streamer.getContext();
1713 CFAOffset = InitialCFAOffset;
1726 Streamer.emitLabel(fdeStart);
1739 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1744 unsigned PCEncoding =
1756 unsigned augmentationLength = 0;
1761 Streamer.emitULEB128IntValue(augmentationLength);
1776 Streamer.emitValueToAlignment(
Align(Alignment));
1778 Streamer.emitLabel(fdeEnd);
1787 : Personality(Frame.Personality),
1788 PersonalityEncoding(Frame.PersonalityEncoding),
1789 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1790 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1791 IsBKeyFrame(Frame.IsBKeyFrame),
1792 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1797 return Personality->getName();
1801 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1802 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1804 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1807 Other.IsMTETaggedFrame);
1811 return Personality ==
Other.Personality &&
1812 PersonalityEncoding ==
Other.PersonalityEncoding &&
1813 LsdaEncoding ==
Other.LsdaEncoding &&
1814 IsSignalFrame ==
Other.IsSignalFrame && IsSimple ==
Other.IsSimple &&
1815 RAReg ==
Other.RAReg && IsBKeyFrame ==
Other.IsBKeyFrame &&
1816 IsMTETaggedFrame ==
Other.IsMTETaggedFrame;
1820 const MCSymbol *Personality =
nullptr;
1821 unsigned PersonalityEncoding = 0;
1822 unsigned LsdaEncoding = -1;
1823 bool IsSignalFrame =
false;
1824 bool IsSimple =
false;
1825 unsigned RAReg =
static_cast<unsigned>(UINT_MAX);
1826 bool IsBKeyFrame =
false;
1827 bool IsMTETaggedFrame =
false;
1837 FrameEmitterImpl
Emitter(IsEH, Streamer);
1844 bool SectionEmitted =
false;
1847 if (!SectionEmitted) {
1850 SectionEmitted =
true;
1852 NeedsEHFrameSection |=
1855 Emitter.EmitCompactUnwind(Frame);
1863 if (!NeedsEHFrameSection && IsEH)
return;
1878 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1881 return CIEKey(
X) < CIEKey(
Y);
1884 const MCSymbol *LastCIEStart =
nullptr;
1885 for (
auto I = FrameArrayX.begin(), E = FrameArrayX.end();
I != E;) {
1899 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1901 LastCIEStart = &
Emitter.EmitCIE(Frame);
1904 Emitter.EmitFDE(*LastCIEStart, Frame,
I == E, *SectionStart);
1921 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1923 }
else if (isUInt<8>(AddrDelta)) {
1924 Out.
push_back(dwarf::DW_CFA_advance_loc1);
1926 }
else if (isUInt<16>(AddrDelta)) {
1927 Out.
push_back(dwarf::DW_CFA_advance_loc2);
1928 support::endian::write<uint16_t>(Out, AddrDelta, E);
1930 assert(isUInt<32>(AddrDelta));
1931 Out.
push_back(dwarf::DW_CFA_advance_loc4);
1932 support::endian::write<uint32_t>(Out, AddrDelta, E);
unsigned const MachineRegisterInfo * MRI
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
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
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...
bool isLittleEndian() const
True if the target is little endian.
unsigned getMinInstAlignment() const
const std::vector< MCCFIInstruction > & getInitialFrameState() const
bool needsDwarfSectionOffsetDirective() const
bool doesSetDirectiveSuppressReloc() 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.
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
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...
bool operator!=(uint64_t V1, const APInt &V2)
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.
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.