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));
327 OS.emitAssignment(ABS, Expr);
350 LineStrings.
write((uint8_t *)
Data.data());
355 return LineStrings.
add(Path);
374void MCDwarfLineTableHeader::emitV2FileDirTables(
MCStreamer *MCOS)
const {
395 bool EmitMD5,
bool HasAnySource,
396 std::optional<MCDwarfLineStr> &LineStr) {
408 StringRef(
reinterpret_cast<const char *
>(Cksum.data()), Cksum.size()));
420void MCDwarfLineTableHeader::emitV5FileDirTables(
421 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr)
const {
428 : dwarf::DW_FORM_string);
438 CompDir = LineStr->getSaver().save(CompDir);
442 LineStr->emitRef(MCOS, CompDir);
444 LineStr->emitRef(MCOS, Dir);
466 : dwarf::DW_FORM_string);
476 : dwarf::DW_FORM_string);
486 "No root file and no .file directives");
493std::pair<MCSymbol *, MCSymbol *>
496 std::optional<MCDwarfLineStr> &LineStr)
const {
516 if (LineTableVersion >= 5) {
536 if (LineTableVersion >= 4)
544 for (
char Length : StandardOpcodeLengths)
549 if (LineTableVersion >= 5)
550 emitV5FileDirTables(MCOS, LineStr);
552 emitV2FileDirTables(MCOS);
558 return std::make_pair(LineStartSym, LineEndSym);
562 std::optional<MCDwarfLineStr> &LineStr)
const {
563 MCSymbol *LineEndSym = Header.
Emit(MCOS, Params, LineStr).second;
567 emitOne(MCOS, LineSec.first, LineSec.second);
576 std::optional<MD5::MD5Result> Checksum,
577 std::optional<StringRef> Source,
578 uint16_t DwarfVersion,
unsigned FileNumber) {
579 return Header.
tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
585 std::optional<MD5::MD5Result> Checksum) {
588 return RootFile.
Checksum == Checksum;
593 std::optional<MD5::MD5Result> Checksum,
594 std::optional<StringRef> Source,
595 uint16_t DwarfVersion,
unsigned FileNumber) {
598 if (FileName.
empty()) {
599 FileName =
"<stdin>";
611 if (FileNumber == 0) {
619 if (!IterBool.second)
620 return IterBool.first->second;
630 if (!File.Name.empty())
631 return make_error<StringError>(
"file number already allocated",
634 if (Directory.
empty()) {
637 if (!tFileName.
empty()) {
639 if (!Directory.
empty())
640 FileName = tFileName;
647 if (Directory.
empty()) {
661 File.Name = std::string(FileName);
662 File.DirIndex = DirIndex;
663 File.Checksum = Checksum;
665 File.Source = Source;
666 if (Source.has_value())
675 int64_t LineDelta,
uint64_t AddrDelta) {
690 int64_t LineDelta,
uint64_t AddrDelta,
694 bool NeedCopy =
false;
706 if (AddrDelta == MaxSpecialAddrDelta)
707 Out.
push_back(dwarf::DW_LNS_const_add_pc);
708 else if (AddrDelta) {
712 Out.
push_back(dwarf::DW_LNS_extended_op);
714 Out.
push_back(dwarf::DW_LNE_end_sequence);
725 Out.
push_back(dwarf::DW_LNS_advance_line);
734 if (LineDelta == 0 && AddrDelta == 0) {
743 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
752 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.
DWARF2LineRange;
754 Out.
push_back(dwarf::DW_LNS_const_add_pc);
767 assert(Temp <= 255 &&
"Buggy special opcode encoding.");
790 ? dwarf::DW_FORM_sec_offset
792 : dwarf::DW_FORM_data4);
793 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
796 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
798 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
799 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
801 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
803 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
805 if (!DwarfDebugFlags.
empty())
806 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
807 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
808 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
815 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
816 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
817 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
818 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
830 const MCSymbol *InfoSectionSymbol) {
837 unsigned UnitLengthBytes =
843 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
849 int Pad = 2 * AddrSize - (
Length & (2 * AddrSize - 1));
850 if (Pad == 2 * AddrSize)
856 Length += 2 * AddrSize * Sections.size();
871 if (InfoSectionSymbol)
881 for(
int i = 0; i < Pad; i++)
887 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
888 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
889 assert(StartSymbol &&
"StartSymbol must not be NULL");
890 assert(EndSymbol &&
"EndSymbol must not be NULL");
909 const MCSymbol *AbbrevSectionSymbol,
924 unsigned UnitLengthBytes =
946 MCOS->
emitInt8(dwarf::DW_UT_compile);
951 if (AbbrevSectionSymbol)
967 if (LineSectionSymbol)
985 const auto TextSection = Sections.begin();
986 assert(TextSection != Sections.end() &&
"No text section found");
988 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
989 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
990 assert(StartSymbol &&
"StartSymbol must not be NULL");
991 assert(EndSymbol &&
"EndSymbol must not be NULL");
1007 if (MCDwarfDirs.
size() > 0) {
1016 MCDwarfFiles.
empty()
1030 if (!DwarfDebugFlags.
empty()){
1037 if (!DwarfDebugProducer.
empty())
1045 MCOS->
emitInt16(dwarf::DW_LANG_Mips_Assembler);
1050 const std::vector<MCGenDwarfLabelEntry> &Entries =
1052 for (
const auto &Entry : Entries) {
1098 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1099 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1102 const MCExpr *SectionSize =
1104 MCOS->
emitInt8(dwarf::DW_RLE_start_length);
1105 MCOS->
emitValue(SectionStartAddr, AddrSize);
1108 MCOS->
emitInt8(dwarf::DW_RLE_end_of_list);
1115 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1116 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1122 MCOS->
emitValue(SectionStartAddr, AddrSize);
1125 const MCExpr *SectionSize =
1136 return RangesSymbol;
1148 bool CreateDwarfSectionSymbols =
1150 MCSymbol *LineSectionSymbol =
nullptr;
1151 if (CreateDwarfSectionSymbols)
1153 MCSymbol *AbbrevSectionSymbol =
nullptr;
1154 MCSymbol *InfoSectionSymbol =
nullptr;
1167 const bool UseRangesSection =
1170 CreateDwarfSectionSymbols |= UseRangesSection;
1173 if (CreateDwarfSectionSymbols) {
1178 if (CreateDwarfSectionSymbols) {
1188 if (UseRangesSection) {
1197 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1209 if (Symbol->isTemporary())
1220 if (Name.starts_with(
"_"))
1221 Name = Name.substr(1, Name.size()-1);
1254 unsigned symbolEncoding) {
1256 unsigned format = symbolEncoding & 0x0f;
1275 unsigned symbolEncoding,
bool isEH) {
1289 unsigned symbolEncoding) {
1301class FrameEmitterImpl {
1302 int64_t CFAOffset = 0;
1303 int64_t InitialCFAOffset = 0;
1309 : IsEH(IsEH), Streamer(Streamer) {}
1316 bool LastInSection,
const MCSymbol &SectionStart);
1330 auto *
MRI = Streamer.getContext().getRegisterInfo();
1332 switch (
Instr.getOperation()) {
1334 unsigned Reg1 =
Instr.getRegister();
1335 unsigned Reg2 =
Instr.getRegister2();
1337 Reg1 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1338 Reg2 =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1340 Streamer.emitInt8(dwarf::DW_CFA_register);
1341 Streamer.emitULEB128IntValue(Reg1);
1342 Streamer.emitULEB128IntValue(Reg2);
1346 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1350 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1354 unsigned Reg =
Instr.getRegister();
1355 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1356 Streamer.emitULEB128IntValue(Reg);
1361 const bool IsRelative =
1364 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1367 CFAOffset +=
Instr.getOffset();
1369 CFAOffset =
Instr.getOffset();
1371 Streamer.emitULEB128IntValue(CFAOffset);
1376 unsigned Reg =
Instr.getRegister();
1378 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1379 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1380 Streamer.emitULEB128IntValue(Reg);
1381 CFAOffset =
Instr.getOffset();
1382 Streamer.emitULEB128IntValue(CFAOffset);
1387 unsigned Reg =
Instr.getRegister();
1389 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1390 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1391 Streamer.emitULEB128IntValue(Reg);
1397 unsigned Reg =
Instr.getRegister();
1399 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1400 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1401 Streamer.emitULEB128IntValue(Reg);
1402 CFAOffset =
Instr.getOffset();
1403 Streamer.emitULEB128IntValue(CFAOffset);
1404 Streamer.emitULEB128IntValue(
Instr.getAddressSpace());
1410 const bool IsRelative =
1413 unsigned Reg =
Instr.getRegister();
1415 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1423 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1424 Streamer.emitULEB128IntValue(Reg);
1425 Streamer.emitSLEB128IntValue(
Offset);
1426 }
else if (Reg < 64) {
1427 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1428 Streamer.emitULEB128IntValue(
Offset);
1430 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1431 Streamer.emitULEB128IntValue(Reg);
1432 Streamer.emitULEB128IntValue(
Offset);
1437 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1440 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1443 unsigned Reg =
Instr.getRegister();
1444 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1445 Streamer.emitULEB128IntValue(Reg);
1449 unsigned Reg =
Instr.getRegister();
1451 Reg =
MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1453 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1455 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1456 Streamer.emitULEB128IntValue(Reg);
1461 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1462 Streamer.emitULEB128IntValue(
Instr.getOffset());
1466 Streamer.emitBytes(
Instr.getValues());
1469 Streamer.emitLabel(
Instr.getCfiLabel(),
Instr.getLoc());
1481 if (Label && !
Label->isDefined())
continue;
1484 if (BaseLabel && Label) {
1486 if (ThisSym != BaseLabel) {
1487 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym,
Instr.getLoc());
1488 BaseLabel = ThisSym;
1492 emitCFIInstruction(Instr);
1498 MCContext &Context = Streamer.getContext();
1524 if (!Encoding)
return;
1528 if (!DwarfEHFrameOnly && Frame.
Lsda)
1529 Encoding |= 0x40000000;
1534 Streamer.emitSymbolValue(Frame.
Begin,
Size);
1543 Streamer.emitIntValue(Encoding,
Size);
1550 Streamer.emitIntValue(0,
Size);
1554 if (!DwarfEHFrameOnly && Frame.
Lsda)
1555 Streamer.emitSymbolValue(Frame.
Lsda,
Size);
1557 Streamer.emitIntValue(0,
Size);
1563 switch (DwarfVersion) {
1576 MCContext &context = Streamer.getContext();
1581 Streamer.emitLabel(sectionStart);
1596 *sectionEnd, UnitLengthBytes);
1602 Streamer.emitIntValue(CIE_ID, OffsetSize);
1606 Streamer.emitInt8(CIEVersion);
1610 Augmentation +=
"z";
1612 Augmentation +=
"P";
1614 Augmentation +=
"L";
1615 Augmentation +=
"R";
1617 Augmentation +=
"S";
1619 Augmentation +=
"B";
1621 Augmentation +=
"G";
1622 Streamer.emitBytes(Augmentation);
1624 Streamer.emitInt8(0);
1626 if (CIEVersion >= 4) {
1631 Streamer.emitInt8(0);
1641 unsigned RAReg = Frame.
RAReg;
1642 if (RAReg ==
static_cast<unsigned>(INT_MAX))
1643 RAReg =
MRI->getDwarfRegNum(
MRI->getRARegister(), IsEH);
1645 if (CIEVersion == 1) {
1647 "DWARF 2 encodes return_address_register in one byte");
1648 Streamer.emitInt8(RAReg);
1650 Streamer.emitULEB128IntValue(RAReg);
1654 unsigned augmentationLength = 0;
1658 augmentationLength += 1;
1660 augmentationLength +=
1664 augmentationLength += 1;
1666 augmentationLength += 1;
1668 Streamer.emitULEB128IntValue(augmentationLength);
1691 emitCFIInstructions(Instructions,
nullptr);
1694 InitialCFAOffset = CFAOffset;
1699 Streamer.emitLabel(sectionEnd);
1700 return *sectionStart;
1703void FrameEmitterImpl::EmitFDE(
const MCSymbol &cieStart,
1707 MCContext &context = Streamer.getContext();
1712 CFAOffset = InitialCFAOffset;
1725 Streamer.emitLabel(fdeStart);
1738 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1743 unsigned PCEncoding =
1755 unsigned augmentationLength = 0;
1760 Streamer.emitULEB128IntValue(augmentationLength);
1775 Streamer.emitValueToAlignment(
Align(Alignment));
1777 Streamer.emitLabel(fdeEnd);
1786 : Personality(Frame.Personality),
1787 PersonalityEncoding(Frame.PersonalityEncoding),
1788 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1789 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1790 IsBKeyFrame(Frame.IsBKeyFrame),
1791 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1796 return Personality->getName();
1800 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1801 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1803 std::make_tuple(
Other.PersonalityName(),
Other.PersonalityEncoding,
1806 Other.IsMTETaggedFrame);
1810 return Personality ==
Other.Personality &&
1811 PersonalityEncoding ==
Other.PersonalityEncoding &&
1812 LsdaEncoding ==
Other.LsdaEncoding &&
1813 IsSignalFrame ==
Other.IsSignalFrame && IsSimple ==
Other.IsSimple &&
1814 RAReg ==
Other.RAReg && IsBKeyFrame ==
Other.IsBKeyFrame &&
1815 IsMTETaggedFrame ==
Other.IsMTETaggedFrame;
1819 const MCSymbol *Personality =
nullptr;
1820 unsigned PersonalityEncoding = 0;
1821 unsigned LsdaEncoding = -1;
1822 bool IsSignalFrame =
false;
1823 bool IsSimple =
false;
1824 unsigned RAReg =
static_cast<unsigned>(UINT_MAX);
1825 bool IsBKeyFrame =
false;
1826 bool IsMTETaggedFrame =
false;
1836 FrameEmitterImpl
Emitter(IsEH, Streamer);
1843 bool SectionEmitted =
false;
1846 if (!SectionEmitted) {
1849 SectionEmitted =
true;
1851 NeedsEHFrameSection |=
1854 Emitter.EmitCompactUnwind(Frame);
1862 if (!NeedsEHFrameSection && IsEH)
return;
1877 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.
begin(), FrameArray.
end());
1880 return CIEKey(
X) < CIEKey(
Y);
1883 const MCSymbol *LastCIEStart =
nullptr;
1884 for (
auto I = FrameArrayX.begin(), E = FrameArrayX.end();
I != E;) {
1898 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1900 LastCIEStart = &
Emitter.EmitCIE(Frame);
1903 Emitter.EmitFDE(*LastCIEStart, Frame,
I == E, *SectionStart);
1920 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1922 }
else if (isUInt<8>(AddrDelta)) {
1923 Out.
push_back(dwarf::DW_CFA_advance_loc1);
1925 }
else if (isUInt<16>(AddrDelta)) {
1926 Out.
push_back(dwarf::DW_CFA_advance_loc2);
1927 support::endian::write<uint16_t>(Out, AddrDelta, E);
1929 assert(isUInt<32>(AddrDelta));
1930 Out.
push_back(dwarf::DW_CFA_advance_loc4);
1931 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 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
bool hasAggressiveSymbolFolding() 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.