LLVM: lib/MC/MCDwarf.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17#include "llvm/Config/config.h"
35#include
36#include
37#include
38#include
39#include
40#include
41
42using namespace llvm;
43
51 }
60 S.AddComment("Segment selector size");
62 return End;
63}
64
67 if (MinInsnLength == 1)
68 return AddrDelta;
69 if (AddrDelta % MinInsnLength != 0) {
70
71 ;
72 }
73 return AddrDelta / MinInsnLength;
74}
75
78 if (UseRelocs) {
81 assert(DwarfLineStrSection && "DwarfLineStrSection must not be NULL");
83 }
84}
85
86
87
88
89
90
93 return;
94
95
97
99
100
102
103
105
106
108
109
114}
115
116
117
118
122 int IntVal) {
129 return Res3;
130}
131
132
133
134
135static inline const MCExpr *
141 return Res;
142}
143
146
147
148
149
150
151
152
153 auto I = MCLineDivisions.find(Sec);
154 if (I != MCLineDivisions.end()) {
155 auto &Entries = I->second;
156 auto EndEntry = Entries.back();
157 EndEntry.setEndLabel(EndLabel);
158 Entries.push_back(EndEntry);
159 }
160}
161
162
163
164
165
169
170 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
171 bool IsAtStartSeq;
173 auto init = [&]() {
174 FileNum = 1;
175 LastLine = 1;
176 Column = 0;
178 Isa = 0;
179 Discriminator = 0;
180 LastLabel = nullptr;
181 IsAtStartSeq = true;
182 };
183 init();
184
185
186 bool EndEntryEmitted = false;
188 MCSymbol *Label = LineEntry.getLabel();
190
191 if (LineEntry.LineStreamLabel) {
192 if (!IsAtStartSeq) {
194 LastLabel);
195 init();
196 }
197 MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
198 continue;
199 }
200
201 if (LineEntry.IsEndEntry) {
204 init();
205 EndEntryEmitted = true;
206 continue;
207 }
208
209 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
210
211 if (FileNum != LineEntry.getFileNum()) {
212 FileNum = LineEntry.getFileNum();
213 MCOS->emitInt8(dwarf::DW_LNS_set_file);
215 }
216 if (Column != LineEntry.getColumn()) {
217 Column = LineEntry.getColumn();
218 MCOS->emitInt8(dwarf::DW_LNS_set_column);
220 }
221 if (Discriminator != LineEntry.getDiscriminator() &&
223 Discriminator = LineEntry.getDiscriminator();
225 MCOS->emitInt8(dwarf::DW_LNS_extended_op);
227 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
229 }
230 if (Isa != LineEntry.getIsa()) {
231 Isa = LineEntry.getIsa();
232 MCOS->emitInt8(dwarf::DW_LNS_set_isa);
234 }
236 Flags = LineEntry.getFlags();
237 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
238 }
240 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
242 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
244 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
245
246
247
248
251
252 Discriminator = 0;
253 LastLine = LineEntry.getLine();
254 LastLabel = Label;
255 IsAtStartSeq = false;
256 }
257
258
259
260
261
262
263 if (!EndEntryEmitted && !IsAtStartSeq)
265}
266
272 auto *LineSym = ctx.createTempSymbol();
274 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
275
276
277
278
279 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);
281}
282
283
284
285
288
290
291
292
293 if (LineTables.empty())
294 return;
295
296
297 std::optional LineStr;
299 LineStr.emplace(context);
300
301
303
304
305 for (const auto &CUIDTablePair : LineTables) {
306 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
307 }
308
309 if (LineStr)
310 LineStr->emitSection(MCOS);
311}
312
315 if (!HasSplitLineTable)
316 return;
317 std::optional NoLineStr(std::nullopt);
319 MCOS.emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);
320}
321
322std::pair<MCSymbol *, MCSymbol *>
324 std::optional &LineStr) const {
325 static const char StandardOpcodeLengths[] = {
326 0,
327 1,
328 1,
329 1,
330 1,
331 0,
332 0,
333 0,
334 1,
335 0,
336 0,
337 1
338 };
339 assert(std::size(StandardOpcodeLengths) >=
341 return Emit(MCOS, Params,
343 LineStr);
344}
345
348 assert(!isa(Expr));
350 return Expr;
351
352
354 OS.emitAssignment(ABS, Expr);
356}
357
361}
362
364
369}
370
372
379}
380
382 return LineStrings.add(Path);
383}
384
386 int RefSize =
389 if (UseRelocs) {
393 } else {
395 RefSize);
396 }
397 } else
399}
400
401void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
402
404 MCOS->emitBytes(Dir);
406 }
407 MCOS->emitInt8(0);
408
409
410 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
415 MCOS->emitInt8(0);
416 MCOS->emitInt8(0);
417 }
418 MCOS->emitInt8(0);
419}
420
422 bool EmitMD5, bool HasAnySource,
423 std::optional &LineStr) {
425 if (LineStr)
426 LineStr->emitRef(MCOS, DwarfFile.Name);
427 else {
430 }
432 if (EmitMD5) {
435 StringRef(reinterpret_cast<const char *>(Cksum.data()), Cksum.size()));
436 }
437 if (HasAnySource) {
438 if (LineStr)
440 else {
443 }
444 }
445}
446
447void MCDwarfLineTableHeader::emitV5FileDirTables(
448 MCStreamer *MCOS, std::optional &LineStr) const {
449
450
451
455 : dwarf::DW_FORM_string);
457
463 CompDir = Dir.str();
464 if (LineStr)
465 CompDir = LineStr->getSaver().save(CompDir);
466 }
467 if (LineStr) {
468
469 LineStr->emitRef(MCOS, CompDir);
471 LineStr->emitRef(MCOS, Dir);
472 } else {
473
477 MCOS->emitBytes(Dir);
479 }
480 }
481
482
483
484
486 if (HasAllMD5)
487 Entries += 1;
489 Entries += 1;
493 : dwarf::DW_FORM_string);
496 if (HasAllMD5) {
499 }
503 : dwarf::DW_FORM_string);
504 }
505
506
507
508
510
511
513 "No root file and no .file directives");
516 for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
518}
519
520std::pair<MCSymbol *, MCSymbol *>
523 std::optional &LineStr) const {
525
526
528 if (!LineStartSym)
530
531
533
535
537
538
540 MCOS->emitInt16(LineTableVersion);
541
542
543 if (LineTableVersion >= 5) {
545 MCOS->emitInt8(0);
546 }
547
548
551
552
553
555
557
558
560
561
562
563 if (LineTableVersion >= 4)
568 MCOS->emitInt8(StandardOpcodeLengths.size() + 1);
569
570
571 for (char Length : StandardOpcodeLengths)
573
574
575
576 if (LineTableVersion >= 5)
577 emitV5FileDirTables(MCOS, LineStr);
578 else
579 emitV2FileDirTables(MCOS);
580
581
582
584
585 return std::make_pair(LineStartSym, LineEndSym);
586}
587
589 std::optional &LineStr) const {
590 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
591
592
593 for (const auto &LineSec : MCLineSections.getMCLineEntries())
594 emitOne(MCOS, LineSec.first, LineSec.second);
595
596
597
599}
600
603 std::optionalMD5::MD5Result Checksum,
604 std::optional Source,
605 uint16_t DwarfVersion, unsigned FileNumber) {
606 return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
607 FileNumber);
608}
609
612 std::optionalMD5::MD5Result Checksum) {
613 if (RootFile.Name.empty() || StringRef(RootFile.Name) != FileName)
614 return false;
615 return RootFile.Checksum == Checksum;
616}
617
620 std::optionalMD5::MD5Result Checksum,
621 std::optional Source,
622 uint16_t DwarfVersion, unsigned FileNumber) {
624 Directory = "";
625 if (FileName.empty()) {
626 FileName = "";
627 Directory = "";
628 }
630
631
635 }
636 if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))
637 return 0;
638 if (FileNumber == 0) {
639
640
644 std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),
645 FileNumber));
646 if (!IterBool.second)
647 return IterBool.first->second;
648 }
649
652
653
655
656
657 if (!File.Name.empty())
658 return make_error("file number already allocated",
660
661 if (Directory.empty()) {
662
664 if (!tFileName.empty()) {
666 if (!Directory.empty())
667 FileName = tFileName;
668 }
669 }
670
671
672
673 unsigned DirIndex;
674 if (Directory.empty()) {
675
676 DirIndex = 0;
677 } else {
681
682
683
684
685 DirIndex++;
686 }
687
688 File.Name = std::string(FileName);
689 File.DirIndex = DirIndex;
690 File.Checksum = Checksum;
692 File.Source = Source;
693 if (Source.has_value())
695
696
697 return FileNumber;
698}
699
700
702 int64_t LineDelta, uint64_t AddrDelta) {
707}
708
709
710
713}
714
715
717 int64_t LineDelta, uint64_t AddrDelta,
721 bool NeedCopy = false;
722
723
725
726
728
729
730
731
733 if (AddrDelta == MaxSpecialAddrDelta)
734 Out.push_back(dwarf::DW_LNS_const_add_pc);
735 else if (AddrDelta) {
736 Out.push_back(dwarf::DW_LNS_advance_pc);
738 }
739 Out.push_back(dwarf::DW_LNS_extended_op);
741 Out.push_back(dwarf::DW_LNE_end_sequence);
742 return;
743 }
744
745
747
748
749
752 Out.push_back(dwarf::DW_LNS_advance_line);
754
755 LineDelta = 0;
757 NeedCopy = true;
758 }
759
760
761 if (LineDelta == 0 && AddrDelta == 0) {
762 Out.push_back(dwarf::DW_LNS_copy);
763 return;
764 }
765
766
768
769
770 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
771
773 if (Opcode <= 255) {
775 return;
776 }
777
778
779 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;
780 if (Opcode <= 255) {
781 Out.push_back(dwarf::DW_LNS_const_add_pc);
783 return;
784 }
785 }
786
787
788 Out.push_back(dwarf::DW_LNS_advance_pc);
790
791 if (NeedCopy)
792 Out.push_back(dwarf::DW_LNS_copy);
793 else {
794 assert(Temp <= 255 && "Buggy special opcode encoding.");
796 }
797}
798
799
803}
804
805
806
810
811
817 ? dwarf::DW_FORM_sec_offset
819 : dwarf::DW_FORM_data4);
820 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
823 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
824 } else {
825 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
826 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
827 }
828 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
830 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
832 if (!DwarfDebugFlags.empty())
833 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
834 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
835 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
837
838
842 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
843 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
844 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
845 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
847
848
850}
851
852
853
854
855
857 const MCSymbol *InfoSectionSymbol) {
859
861
863
864 unsigned UnitLengthBytes =
867
868
869
870 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
871
872
873
876 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
877 if (Pad == 2 * AddrSize)
878 Pad = 0;
880
881
882
883 Length += 2 * AddrSize * Sections.size();
884
885 Length += 2 * AddrSize;
886
887
889
891
892
894
896
897
898 if (InfoSectionSymbol)
901 else
903
905
907
908 for(int i = 0; i < Pad; i++)
910
911
912
913 for (MCSection *Sec : Sections) {
914 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
915 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
916 assert(StartSymbol && "StartSymbol must not be NULL");
917 assert(EndSymbol && "EndSymbol must not be NULL");
918
925 }
926
927
930}
931
932
933
934
936 const MCSymbol *AbbrevSectionSymbol,
937 const MCSymbol *LineSectionSymbol,
938 const MCSymbol *RangesSymbol) {
940
942
943
944
948
949
950
951 unsigned UnitLengthBytes =
954
956
958
959
960
964
965
967
968
969
973 MCOS->emitInt8(dwarf::DW_UT_compile);
975 }
976
977
978 if (AbbrevSectionSymbol)
981 else
982
986
987
988
989
991
992
993
994 if (LineSectionSymbol)
997 else
998
1000
1001 if (RangesSymbol) {
1002
1003
1004
1006 } else {
1007
1008
1009
1010
1012 const auto TextSection = Sections.begin();
1013 assert(TextSection != Sections.end() && "No text section found");
1014
1015 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1016 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1017 assert(StartSymbol && "StartSymbol must not be NULL");
1018 assert(EndSymbol && "EndSymbol must not be NULL");
1019
1020
1023 MCOS->emitValue(Start, AddrSize);
1024
1025
1029 }
1030
1031
1032
1034 if (MCDwarfDirs.size() > 0) {
1035 MCOS->emitBytes(MCDwarfDirs[0]);
1037 }
1039
1040
1041 assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
1043 MCDwarfFiles.empty()
1045 : MCDwarfFiles[1];
1047 MCOS->emitInt8(0);
1048
1049
1052 MCOS->emitInt8(0);
1053 }
1054
1055
1057 if (!DwarfDebugFlags.empty()){
1058 MCOS->emitBytes(DwarfDebugFlags);
1059 MCOS->emitInt8(0);
1060 }
1061
1062
1064 if (!DwarfDebugProducer.empty())
1065 MCOS->emitBytes(DwarfDebugProducer);
1066 else
1067 MCOS->emitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
1068 MCOS->emitInt8(0);
1069
1070
1071
1072 MCOS->emitInt16(dwarf::DW_LANG_Mips_Assembler);
1073
1074
1075
1076
1077 const std::vector &Entries =
1079 for (const auto &Entry : Entries) {
1080
1082
1083
1084 MCOS->emitBytes(Entry.getName());
1085 MCOS->emitInt8(0);
1086
1087
1088 MCOS->emitInt32(Entry.getFileNumber());
1089
1090
1091 MCOS->emitInt32(Entry.getLineNumber());
1092
1093
1096 MCOS->emitValue(AT_low_pc, AddrSize);
1097 }
1098
1099
1101
1102
1104}
1105
1106
1107
1108
1112
1116
1120 MCOS->AddComment("Offset entry count");
1122 RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
1124 for (MCSection *Sec : Sections) {
1125 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1126 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1129 const MCExpr *SectionSize =
1131 MCOS->emitInt8(dwarf::DW_RLE_start_length);
1132 MCOS->emitValue(SectionStartAddr, AddrSize);
1134 }
1135 MCOS->emitInt8(dwarf::DW_RLE_end_of_list);
1137 } else {
1139 RangesSymbol = context.createTempSymbol("debug_ranges_start");
1141 for (MCSection *Sec : Sections) {
1142 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1143 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1144
1145
1148 MCOS->emitFill(AddrSize, 0xFF);
1149 MCOS->emitValue(SectionStartAddr, AddrSize);
1150
1151
1152 const MCExpr *SectionSize =
1156 }
1157
1158
1161 }
1162
1163 return RangesSymbol;
1164}
1165
1166
1167
1168
1169
1172
1173
1175 bool CreateDwarfSectionSymbols =
1177 MCSymbol *LineSectionSymbol = nullptr;
1178 if (CreateDwarfSectionSymbols)
1180 MCSymbol *AbbrevSectionSymbol = nullptr;
1181 MCSymbol *InfoSectionSymbol = nullptr;
1182 MCSymbol *RangesSymbol = nullptr;
1183
1184
1186
1187
1188
1190 return;
1191
1192
1193
1194 const bool UseRangesSection =
1197 CreateDwarfSectionSymbols |= UseRangesSection;
1198
1200 if (CreateDwarfSectionSymbols) {
1202 MCOS->emitLabel(InfoSectionSymbol);
1203 }
1205 if (CreateDwarfSectionSymbols) {
1207 MCOS->emitLabel(AbbrevSectionSymbol);
1208 }
1209
1211
1212
1214
1215 if (UseRangesSection) {
1217 assert(RangesSymbol);
1218 }
1219
1220
1222
1223
1224 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1225}
1226
1227
1228
1229
1230
1231
1232
1235
1236 if (Symbol->isTemporary())
1237 return;
1239
1240
1242 return;
1243
1244
1245
1246 StringRef Name = Symbol->getName();
1247 if (Name.starts_with("_"))
1248 Name = Name.substr(1, Name.size()-1);
1249
1250
1252
1253
1254
1257
1258
1259
1260
1261
1264
1265
1268}
1269
1275 return size;
1276 else
1277 return -size;
1278}
1279
1281 unsigned symbolEncoding) {
1283 unsigned format = symbolEncoding & 0x0f;
1291 return 2;
1294 return 4;
1297 return 8;
1298 }
1299}
1300
1302 unsigned symbolEncoding, bool isEH) {
1306 symbolEncoding,
1307 streamer);
1311 else
1313}
1314
1316 unsigned symbolEncoding) {
1320 symbolEncoding,
1321 streamer);
1324}
1325
1326namespace {
1327
1328class FrameEmitterImpl {
1329 int64_t CFAOffset = 0;
1330 int64_t InitialCFAOffset = 0;
1331 bool IsEH;
1333
1334public:
1336 : IsEH(IsEH), Streamer(Streamer) {}
1337
1338
1340
1343 bool LastInSection, const MCSymbol &SectionStart);
1347};
1348
1349}
1350
1352 Streamer.emitInt8(Encoding);
1353}
1354
1355void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
1357 auto *MRI = Streamer.getContext().getRegisterInfo();
1358
1359 switch (Instr.getOperation()) {
1361 unsigned Reg1 = Instr.getRegister();
1362 unsigned Reg2 = Instr.getRegister2();
1363 if (!IsEH) {
1364 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1365 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1366 }
1367 Streamer.emitInt8(dwarf::DW_CFA_register);
1368 Streamer.emitULEB128IntValue(Reg1);
1369 Streamer.emitULEB128IntValue(Reg2);
1370 return;
1371 }
1373 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1374 return;
1375
1377 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1378 return;
1379
1381 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1382 return;
1383
1385 unsigned Reg = Instr.getRegister();
1386 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1387 Streamer.emitULEB128IntValue(Reg);
1388 return;
1389 }
1392 const bool IsRelative =
1394
1395 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1396
1397 if (IsRelative)
1398 CFAOffset += Instr.getOffset();
1399 else
1400 CFAOffset = Instr.getOffset();
1401
1402 Streamer.emitULEB128IntValue(CFAOffset);
1403
1404 return;
1405 }
1407 unsigned Reg = Instr.getRegister();
1408 if (!IsEH)
1409 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1410 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1411 Streamer.emitULEB128IntValue(Reg);
1412 CFAOffset = Instr.getOffset();
1413 Streamer.emitULEB128IntValue(CFAOffset);
1414
1415 return;
1416 }
1418 unsigned Reg = Instr.getRegister();
1419 if (!IsEH)
1420 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1421 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1422 Streamer.emitULEB128IntValue(Reg);
1423
1424 return;
1425 }
1426
1428 unsigned Reg = Instr.getRegister();
1429 if (!IsEH)
1430 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1431 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1432 Streamer.emitULEB128IntValue(Reg);
1433 CFAOffset = Instr.getOffset();
1434 Streamer.emitULEB128IntValue(CFAOffset);
1435 Streamer.emitULEB128IntValue(Instr.getAddressSpace());
1436
1437 return;
1438 }
1441 const bool IsRelative =
1443
1444 unsigned Reg = Instr.getRegister();
1445 if (!IsEH)
1446 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1447
1449 if (IsRelative)
1450 Offset -= CFAOffset;
1452
1454 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1455 Streamer.emitULEB128IntValue(Reg);
1456 Streamer.emitSLEB128IntValue(Offset);
1457 } else if (Reg < 64) {
1458 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1459 Streamer.emitULEB128IntValue(Offset);
1460 } else {
1461 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1462 Streamer.emitULEB128IntValue(Reg);
1463 Streamer.emitULEB128IntValue(Offset);
1464 }
1465 return;
1466 }
1468 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1469 return;
1471 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1472 return;
1474 unsigned Reg = Instr.getRegister();
1475 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1476 Streamer.emitULEB128IntValue(Reg);
1477 return;
1478 }
1480 unsigned Reg = Instr.getRegister();
1481 if (!IsEH)
1482 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1483 if (Reg < 64) {
1484 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1485 } else {
1486 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1487 Streamer.emitULEB128IntValue(Reg);
1488 }
1489 return;
1490 }
1492 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1493 Streamer.emitULEB128IntValue(Instr.getOffset());
1494 return;
1495
1497 Streamer.emitBytes(Instr.getValues());
1498 return;
1500 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
1501 return;
1503 unsigned Reg = Instr.getRegister();
1504 if (!IsEH)
1505 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1506
1509
1511 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1512 Streamer.emitULEB128IntValue(Reg);
1513 Streamer.emitSLEB128IntValue(Offset);
1514 } else {
1515 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1516 Streamer.emitULEB128IntValue(Reg);
1517 Streamer.emitULEB128IntValue(Offset);
1518 }
1519 return;
1520 }
1521 }
1523}
1524
1525
1530
1531 if (Label && ->isDefined()) continue;
1532
1533
1534 if (BaseLabel && Label) {
1536 if (ThisSym != BaseLabel) {
1537 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());
1538 BaseLabel = ThisSym;
1539 }
1540 }
1541
1542 emitCFIInstruction(Instr);
1543 }
1544}
1545
1546
1547void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1548 MCContext &Context = Streamer.getContext();
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1574 if (!Encoding) return;
1576
1577
1578 if (!DwarfEHFrameOnly && Frame.Lsda)
1579 Encoding |= 0x40000000;
1580
1581
1584 Streamer.emitSymbolValue(Frame.Begin, Size);
1585
1586
1590
1591
1593 Streamer.emitIntValue(Encoding, Size);
1594
1595
1597 if (!DwarfEHFrameOnly && Frame.Personality)
1599 else
1600 Streamer.emitIntValue(0, Size);
1601
1602
1604 if (!DwarfEHFrameOnly && Frame.Lsda)
1605 Streamer.emitSymbolValue(Frame.Lsda, Size);
1606 else
1607 Streamer.emitIntValue(0, Size);
1608}
1609
1610static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1611 if (IsEH)
1612 return 1;
1613 switch (DwarfVersion) {
1614 case 2:
1615 return 1;
1616 case 3:
1617 return 3;
1618 case 4:
1619 case 5:
1620 return 4;
1621 }
1623}
1624
1626 MCContext &context = Streamer.getContext();
1629
1631 Streamer.emitLabel(sectionStart);
1632
1634
1639
1640 if (IsDwarf64)
1641
1643
1644
1646 *sectionEnd, UnitLengthBytes);
1648
1649
1652 Streamer.emitIntValue(CIE_ID, OffsetSize);
1653
1654
1656 Streamer.emitInt8(CIEVersion);
1657
1658 if (IsEH) {
1660 Augmentation += "z";
1662 Augmentation += "P";
1663 if (Frame.Lsda)
1664 Augmentation += "L";
1665 Augmentation += "R";
1667 Augmentation += "S";
1669 Augmentation += "B";
1671 Augmentation += "G";
1672 Streamer.emitBytes(Augmentation);
1673 }
1674 Streamer.emitInt8(0);
1675
1676 if (CIEVersion >= 4) {
1677
1679
1680
1681 Streamer.emitInt8(0);
1682 }
1683
1684
1686
1687
1689
1690
1692 if (RAReg == static_cast<unsigned>(INT_MAX))
1693 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1694
1695 if (CIEVersion == 1) {
1697 "DWARF 2 encodes return_address_register in one byte");
1698 Streamer.emitInt8(RAReg);
1699 } else {
1700 Streamer.emitULEB128IntValue(RAReg);
1701 }
1702
1703
1704 unsigned augmentationLength = 0;
1705 if (IsEH) {
1707
1708 augmentationLength += 1;
1709
1710 augmentationLength +=
1712 }
1713 if (Frame.Lsda)
1714 augmentationLength += 1;
1715
1716 augmentationLength += 1;
1717
1718 Streamer.emitULEB128IntValue(augmentationLength);
1719
1720
1722
1724
1726 }
1727
1728 if (Frame.Lsda)
1730
1731
1733 }
1734
1735
1736
1739 const std::vector &Instructions =
1741 emitCFIInstructions(Instructions, nullptr);
1742 }
1743
1744 InitialCFAOffset = CFAOffset;
1745
1746
1748
1749 Streamer.emitLabel(sectionEnd);
1750 return *sectionStart;
1751}
1752
1753void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
1755 bool LastInSection,
1756 const MCSymbol &SectionStart) {
1757 MCContext &context = Streamer.getContext();
1761
1762 CFAOffset = InitialCFAOffset;
1763
1766
1768
1770
1771
1774
1775 Streamer.emitLabel(fdeStart);
1776
1777
1779 if (IsEH) {
1780 const MCExpr *offset =
1784 const MCExpr *offset =
1787 } else {
1788 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1790 }
1791
1792
1793 unsigned PCEncoding =
1797
1798
1802
1803 if (IsEH) {
1804
1805 unsigned augmentationLength = 0;
1806
1807 if (frame.Lsda)
1809
1810 Streamer.emitULEB128IntValue(augmentationLength);
1811
1812
1813 if (frame.Lsda)
1815 }
1816
1817
1819
1820
1821
1822
1823
1824 unsigned Alignment = LastInSection ? asmInfo->getCodePointerSize() : PCSize;
1825 Streamer.emitValueToAlignment(Align(Alignment));
1826
1827 Streamer.emitLabel(fdeEnd);
1828}
1829
1830namespace {
1831
1832struct CIEKey {
1833 CIEKey() = default;
1834
1836 : Personality(Frame.Personality),
1837 PersonalityEncoding(Frame.PersonalityEncoding),
1838 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1839 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1840 IsBKeyFrame(Frame.IsBKeyFrame),
1841 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1842
1843 StringRef PersonalityName() const {
1844 if (!Personality)
1846 return Personality->getName();
1847 }
1848
1850 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1851 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1852 IsMTETaggedFrame) <
1853 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
1854 Other.LsdaEncoding, Other.IsSignalFrame,
1856 Other.IsMTETaggedFrame);
1857 }
1858
1860 return Personality == Other.Personality &&
1861 PersonalityEncoding == Other.PersonalityEncoding &&
1862 LsdaEncoding == Other.LsdaEncoding &&
1863 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&
1864 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
1865 IsMTETaggedFrame == Other.IsMTETaggedFrame;
1866 }
1868
1869 const MCSymbol *Personality = nullptr;
1870 unsigned PersonalityEncoding = 0;
1871 unsigned LsdaEncoding = -1;
1872 bool IsSignalFrame = false;
1873 bool IsSimple = false;
1874 unsigned RAReg = static_cast<unsigned>(UINT_MAX);
1875 bool IsBKeyFrame = false;
1876 bool IsMTETaggedFrame = false;
1877};
1878
1879}
1880
1882 bool IsEH) {
1886 FrameEmitterImpl Emitter(IsEH, Streamer);
1888
1889
1893 bool SectionEmitted = false;
1896 if (!SectionEmitted) {
1899 SectionEmitted = true;
1900 }
1901 NeedsEHFrameSection |=
1904 Emitter.EmitCompactUnwind(Frame);
1905 }
1906 }
1907
1908
1909
1910
1911
1912 if (!NeedsEHFrameSection && IsEH) return;
1913
1915 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
1917
1920 Streamer.emitLabel(SectionStart);
1921
1923
1924
1925
1926
1927 std::vector FrameArrayX(FrameArray.begin(), FrameArray.end());
1930 return CIEKey(X) < CIEKey(Y);
1931 });
1932 CIEKey LastKey;
1933 const MCSymbol *LastCIEStart = nullptr;
1934 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
1936 ++I;
1939
1940
1941
1942
1943
1944
1945 continue;
1946
1947 CIEKey Key(Frame);
1948 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1949 LastKey = Key;
1950 LastCIEStart = &Emitter.EmitCIE(Frame);
1951 }
1952
1953 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);
1954 }
1955}
1956
1960
1962 if (AddrDelta == 0)
1963 return;
1964
1968
1969 if (isUIntN(6, AddrDelta)) {
1970 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1972 } else if (isUInt<8>(AddrDelta)) {
1973 Out.push_back(dwarf::DW_CFA_advance_loc1);
1975 } else if (isUInt<16>(AddrDelta)) {
1976 Out.push_back(dwarf::DW_CFA_advance_loc2);
1977 support::endian::write<uint16_t>(Out, AddrDelta, E);
1978 } else {
1979 assert(isUInt<32>(AddrDelta));
1980 Out.push_back(dwarf::DW_CFA_advance_loc4);
1981 support::endian::write<uint32_t>(Out, AddrDelta, E);
1982 }
1983}
unsigned const MachineRegisterInfo * MRI
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 Register RAReg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Tagged union holding either a T or a Error.
Generic interface to target specific assembler backends.
This class is intended to be used as a base class for asm properties and features specific to the tar...
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)
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
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.
void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
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.
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)
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.
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 parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
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.
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.