LLVM: lib/ObjectYAML/DWARFEmitter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
31#include
32#include
33#include
34#include
35#include
36#include
37#include
38
39using namespace llvm;
40
41template
47
50 if (8 == Size)
52 else if (4 == Size)
54 else if (2 == Size)
56 else if (1 == Size)
58 else
60 "invalid integer write size: %zu", Size);
61
63}
64
66 std::vector<uint8_t> FillData(Size, 0);
67 OS.write(reinterpret_cast<char *>(FillData.data()), Size);
68}
69
72 bool IsLittleEndian) {
74 if (IsDWARF64)
76 IsLittleEndian));
79}
80
84 OS, IsLittleEndian));
85}
86
89 OS.write(Str.data(), Str.size());
91 }
92
94}
95
98 "Index should be less than the size of DebugAbbrev array");
99 auto [It, Inserted] = AbbrevTableContents.try_emplace(Index);
100 if (!Inserted)
101 return It->second;
102
104
107 AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
110 OS.write(AbbrevDecl.Children);
111 for (const auto &Attr : AbbrevDecl.Attributes) {
114 if (Attr.Form == dwarf::DW_FORM_implicit_const)
116 }
119 }
120
121
122
124
125 return It->second;
126}
127
131 OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
132 }
133
135}
136
141 if (Range.AddrSize)
142 AddrSize = *Range.AddrSize;
143 else
145
147
150
151 const uint64_t HeaderLength =
153 ? 12
154 : 4);
155 const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2);
156
157 if (Range.Length) {
159 } else {
160 Length += PaddedHeaderLength - HeaderLength;
161 Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
162 }
163
169 ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength);
170
171 for (const auto &Descriptor : Range.Descriptors) {
175 "unable to write debug_aranges address: %s",
179 }
181 }
182
184}
185
187 const size_t RangesOffset = OS.tell();
189 for (const auto &DebugRanges : *DI.DebugRanges) {
190 const size_t CurrOffset = OS.tell() - RangesOffset;
191 if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset)
193 "'Offset' for 'debug_ranges' with index " +
194 Twine(EntryIndex) +
195 " must be greater than or equal to the "
196 "number of bytes written already (0x" +
198 if (DebugRanges.Offset)
199 ZeroFillBytes(OS, *DebugRanges.Offset - CurrOffset);
200
202 if (DebugRanges.AddrSize)
203 AddrSize = *DebugRanges.AddrSize;
204 else
206 for (const auto &Entry : DebugRanges.Entries) {
211 "unable to write debug_ranges address offset: %s",
215 }
217 ++EntryIndex;
218 }
219
221}
222
224 bool IsLittleEndian, bool IsGNUPubSec = false) {
229 for (const auto &Entry : Sect.Entries) {
231 if (IsGNUPubSec)
233 OS.write(Entry.Name.data(), Entry.Name.size());
235 }
237}
238
240 assert(DI.PubNames && "unexpected emitDebugPubnames() call");
242}
243
245 assert(DI.PubTypes && "unexpected emitDebugPubtypes() call");
247}
248
250 assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call");
252 true);
253}
254
256 assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call");
258 true);
259}
260
268 uint32_t AbbrCode = Entry.AbbrCode;
269 if (AbbrCode == 0 || Entry.Values.empty())
270 return OS.tell() - EntryBegin;
271
274 if (!AbbrevTableInfoOrErr)
277 " for compilation unit with index " +
279
281 DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
282
283 if (AbbrCode > AbbrevDecls.size())
286 "abbrev code must be less than or equal to the number of "
287 "entries in abbreviation table");
289 auto FormVal = Entry.Values.begin();
290 auto AbbrForm = Abbrev.Attributes.begin();
291 for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
292 ++FormVal, ++AbbrForm) {
294 bool Indirect;
295 do {
296 Indirect = false;
297 switch (Form) {
298 case dwarf::DW_FORM_addr:
299
301 FormVal->Value, Params.AddrSize, OS, IsLittleEndian))
302 return std::move(Err);
303 break;
304 case dwarf::DW_FORM_ref_addr:
305
308 OS, IsLittleEndian))
309 return std::move(Err);
310 break;
311 case dwarf::DW_FORM_exprloc:
312 case dwarf::DW_FORM_block:
314 OS.write((const char *)FormVal->BlockData.data(),
315 FormVal->BlockData.size());
316 break;
317 case dwarf::DW_FORM_block1: {
319 OS.write((const char *)FormVal->BlockData.data(),
320 FormVal->BlockData.size());
321 break;
322 }
323 case dwarf::DW_FORM_block2: {
325 OS.write((const char *)FormVal->BlockData.data(),
326 FormVal->BlockData.size());
327 break;
328 }
329 case dwarf::DW_FORM_block4: {
331 OS.write((const char *)FormVal->BlockData.data(),
332 FormVal->BlockData.size());
333 break;
334 }
335 case dwarf::DW_FORM_strx:
336 case dwarf::DW_FORM_addrx:
337 case dwarf::DW_FORM_rnglistx:
338 case dwarf::DW_FORM_loclistx:
339 case dwarf::DW_FORM_udata:
340 case dwarf::DW_FORM_ref_udata:
341 case dwarf::DW_FORM_GNU_addr_index:
342 case dwarf::DW_FORM_GNU_str_index:
344 break;
345 case dwarf::DW_FORM_data1:
346 case dwarf::DW_FORM_ref1:
347 case dwarf::DW_FORM_flag:
348 case dwarf::DW_FORM_strx1:
349 case dwarf::DW_FORM_addrx1:
351 break;
352 case dwarf::DW_FORM_data2:
353 case dwarf::DW_FORM_ref2:
354 case dwarf::DW_FORM_strx2:
355 case dwarf::DW_FORM_addrx2:
357 break;
358 case dwarf::DW_FORM_data4:
359 case dwarf::DW_FORM_ref4:
360 case dwarf::DW_FORM_ref_sup4:
361 case dwarf::DW_FORM_strx4:
362 case dwarf::DW_FORM_addrx4:
364 break;
365 case dwarf::DW_FORM_data8:
366 case dwarf::DW_FORM_ref8:
367 case dwarf::DW_FORM_ref_sup8:
368 case dwarf::DW_FORM_ref_sig8:
370 break;
371 case dwarf::DW_FORM_sdata:
373 break;
374 case dwarf::DW_FORM_string:
375 OS.write(FormVal->CStr.data(), FormVal->CStr.size());
377 break;
378 case dwarf::DW_FORM_indirect:
380 Indirect = true;
382 ++FormVal;
383 break;
384 case dwarf::DW_FORM_strp:
385 case dwarf::DW_FORM_sec_offset:
386 case dwarf::DW_FORM_GNU_ref_alt:
387 case dwarf::DW_FORM_GNU_strp_alt:
388 case dwarf::DW_FORM_line_strp:
389 case dwarf::DW_FORM_strp_sup:
392 IsLittleEndian));
393 break;
394 default:
395 break;
396 }
397 } while (Indirect);
398 }
399
400 return OS.tell() - EntryBegin;
401}
402
409 else
415 ++Length;
417 case dwarf::DW_UT_compile:
418 case dwarf::DW_UT_partial:
419 default:
420 break;
421 case dwarf::DW_UT_type:
422 case dwarf::DW_UT_split_type:
423
425 break;
426 case dwarf::DW_UT_skeleton:
427 case dwarf::DW_UT_split_compile:
428 Length += 8;
429 }
430 }
431
432
433
434
435
436 std::string EntryBuffer;
438
442 writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS,
444 Length += *EntryLength;
445 else
446 return EntryLength.takeError();
447 }
448
449
450
453
456
457 uint64_t AbbrevTableOffset = 0;
460 } else {
463 AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
464 } else {
465
466
467
468 consumeError(AbbrevTableInfoOrErr.takeError());
469 }
470 }
471
477 case dwarf::DW_UT_compile:
478 case dwarf::DW_UT_partial:
479 default:
480 break;
481 case dwarf::DW_UT_type:
482 case dwarf::DW_UT_split_type:
485 break;
486 case dwarf::DW_UT_skeleton:
487 case dwarf::DW_UT_split_compile:
489 break;
490 }
491 } else {
494 }
495
496 OS.write(EntryBuffer.data(), EntryBuffer.size());
497 }
498
500}
501
503 OS.write(File.Name.data(), File.Name.size());
508}
509
511 uint8_t AddrSize, bool IsLittleEndian,
513
514
515
516
517
518 std::string OpBuffer;
521 switch (Op.SubOpcode) {
522 case dwarf::DW_LNE_set_address:
524 IsLittleEndian));
525 break;
526 case dwarf::DW_LNE_define_file:
528 break;
529 case dwarf::DW_LNE_set_discriminator:
531 break;
532 case dwarf::DW_LNE_end_sequence:
533 break;
534 default:
535 for (auto OpByte : Op.UnknownOpcodeData)
537 }
538 uint64_t ExtLen = Op.ExtLen.value_or(OpBuffer.size());
540 OS.write(OpBuffer.data(), OpBuffer.size());
541}
542
547 if (Op.Opcode == 0) {
549 } else if (Op.Opcode < OpcodeBase) {
550 switch (Op.Opcode) {
551 case dwarf::DW_LNS_copy:
552 case dwarf::DW_LNS_negate_stmt:
553 case dwarf::DW_LNS_set_basic_block:
554 case dwarf::DW_LNS_const_add_pc:
555 case dwarf::DW_LNS_set_prologue_end:
556 case dwarf::DW_LNS_set_epilogue_begin:
557 break;
558
559 case dwarf::DW_LNS_advance_pc:
560 case dwarf::DW_LNS_set_file:
561 case dwarf::DW_LNS_set_column:
562 case dwarf::DW_LNS_set_isa:
564 break;
565
566 case dwarf::DW_LNS_advance_line:
568 break;
569
570 case dwarf::DW_LNS_fixed_advance_pc:
572 break;
573
574 default:
575 for (auto OpData : Op.StandardOpcodeData) {
577 }
578 }
579 }
580}
581
582static std::vector<uint8_t>
584
585
586 std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
587 0, 0, 1, 0, 0, 1};
588 if (Version == 2) {
589
590 StandardOpcodeLengths.resize(9);
591 } else if (OpcodeBase) {
592 StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
593 }
594 return StandardOpcodeLengths;
595}
596
599
600
601 std::string Buffer;
603
605
611
612 std::vector<uint8_t> StandardOpcodeLengths =
617 : StandardOpcodeLengths.size() + 1;
619 for (uint8_t OpcodeLength : StandardOpcodeLengths)
621
623 BufferOS.write(IncludeDir.data(), IncludeDir.size());
624 BufferOS.write('\0');
625 }
626 BufferOS.write('\0');
627
630 BufferOS.write('\0');
631
634
638
642 } else {
643 Length = 2;
646 Length += Buffer.size();
647 }
648
652 OS.write(Buffer.data(), Buffer.size());
653 }
654
656}
657
661 if (TableEntry.AddrSize)
662 AddrSize = *TableEntry.AddrSize;
663 else
665
667 if (TableEntry.Length)
669 else
670
671 Length = 4 + (AddrSize + TableEntry.SegSelectorSize) *
672 TableEntry.SegAddrPairs.size();
673
678
679 for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) {
680 if (TableEntry.SegSelectorSize != yaml::Hex8{0})
682 TableEntry.SegSelectorSize,
685 "unable to write debug_addr segment: %s",
687 if (AddrSize != 0)
691 "unable to write debug_addr address: %s",
693 }
694 }
695
697}
698
705 else
706
709
713
716 }
717
719}
720
721namespace {
722
723void emitDebugNamesHeader(raw_ostream &OS, bool IsLittleEndian,
725 uint32_t CombinedSizeOtherParts) {
726
727 StringRef AugmentationString = "LLVM0700";
728 size_t TotalSize = CombinedSizeOtherParts + 5 * sizeof(uint32_t) +
729 2 * sizeof(uint16_t) + sizeof(NameCount) +
730 sizeof(AbbrevSize) + AugmentationString.size();
732
733
741 writeInteger(AbbrevSize, OS, IsLittleEndian);
743 OS.write(AugmentationString.data(), AugmentationString.size());
744}
745
746
747std::string
749 std::string Data;
754 for (auto [Idx, Form] : Abbrev.Indices) {
757 }
760 }
763}
764
765
766
767std::string emitDebugNamesCUOffsets(bool IsLittleEndian) {
768 std::string Data;
769 raw_string_ostream OS(Data);
770 writeInteger(uint32_t(0), OS, IsLittleEndian);
772}
773
774
775
776
777
778std::string emitDebugNamesNameTable(
779 bool IsLittleEndian,
780 const DenseMap<uint32_t, std::vectorDWARFYAML::DebugNameEntry> &Entries,
781 ArrayRef<uint32_t> EntryPoolOffsets) {
782 assert(Entries.size() == EntryPoolOffsets.size());
783
784 std::string Data;
785 raw_string_ostream OS(Data);
786
789 for (uint32_t PoolOffset : EntryPoolOffsets)
790 writeInteger(PoolOffset, OS, IsLittleEndian);
792}
793
794
795DenseMap<uint32_t, std::vectorDWARFYAML::DebugNameEntry>
797 DenseMap<uint32_t, std::vectorDWARFYAML::DebugNameEntry> StrpToEntries;
798 for (const DWARFYAML::DebugNameEntry &Entry : Entries)
799 StrpToEntries[Entry.NameStrp].push_back(Entry);
800 return StrpToEntries;
801}
802
803
804
805Expected<SmallVector<uint8_t>>
806getNonZeroDataSizesFor(uint32_t AbbrevCode,
808 const auto *AbbrevIt = find_if(Abbrevs, [&](const auto &Abbrev) {
809 return Abbrev.Code.value == AbbrevCode;
810 });
811 if (AbbrevIt == Abbrevs.end())
813 "did not find an Abbreviation for this code");
814
815 SmallVector<uint8_t> DataSizes;
816 dwarf::FormParams Params{5, 4, dwarf::DWARF32};
817 for (auto [Idx, Form] : AbbrevIt->Indices) {
819 if (!FormSize)
821 "unsupported Form for YAML debug_names emitter");
822 if (FormSize == 0)
823 continue;
825 }
826 return DataSizes;
827}
828
829struct PoolOffsetsAndData {
830 std::string PoolData;
831 std::vector<uint32_t> PoolOffsets;
832};
833
834
835
836
837
838Expected emitDebugNamesEntryPool(
839 bool IsLittleEndian,
840 const DenseMap<uint32_t, std::vectorDWARFYAML::DebugNameEntry>
841 &StrpToEntries,
843 PoolOffsetsAndData Result;
844 raw_string_ostream OS(Result.PoolData);
845
848 Result.PoolOffsets.push_back(Result.PoolData.size());
849
850 for (const DWARFYAML::DebugNameEntry &Entry : EntriesWithSameName) {
852
853 Expected<SmallVector<uint8_t>> DataSizes =
854 getNonZeroDataSizesFor(Entry.Code, Abbrevs);
855 if (!DataSizes)
857 if (DataSizes->size() != Entry.Values.size())
860 "mismatch between provided and required number of values");
861
865 return std::move(E);
866 }
868 }
869
871}
872}
873
877
880
881
882
885 if (!PoolInfo)
887 std::string NamesTableData = emitDebugNamesNameTable(
888 DI.IsLittleEndian, StrpToEntries, PoolInfo->PoolOffsets);
889
890 std::string AbbrevData = emitDebugNamesAbbrev(DebugNames.Abbrevs);
891 std::string CUOffsetsData = emitDebugNamesCUOffsets(DI.IsLittleEndian);
892
893 size_t TotalSize = PoolInfo->PoolData.size() + NamesTableData.size() +
894 AbbrevData.size() + CUOffsetsData.size();
895
896
898 AbbrevData.size(), TotalSize);
899 OS.write(CUOffsetsData.data(), CUOffsetsData.size());
900
901 OS.write(NamesTableData.data(), NamesTableData.size());
902 OS.write(AbbrevData.data(), AbbrevData.size());
903 OS.write(PoolInfo->PoolData.data(), PoolInfo->PoolData.size());
904
906}
907
911 if (Values.size() != ExpectedOperands)
914 "invalid number (%zu) of operands for the operator: %s, %" PRIu64
915 " expected",
916 Values.size(), EncodingString.str().c_str(), ExpectedOperands);
917
919}
920
923 bool IsLittleEndian) {
926 "unable to write address for the operator %s: %s",
927 EncodingName.str().c_str(),
929
931}
932
933static Expected<uint64_t>
936 uint8_t AddrSize, bool IsLittleEndian) {
937 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
939 Operation.Values, ExpectedOperands);
940 };
941
945 case dwarf::DW_OP_consts:
946 if (Error Err = CheckOperands(1))
947 return std::move(Err);
949 break;
950 case dwarf::DW_OP_stack_value:
951 if (Error Err = CheckOperands(0))
952 return std::move(Err);
953 break;
954 default:
957 "DWARF expression: " +
958 (EncodingStr.empty()
960 : EncodingStr) +
961 " is not supported");
962 }
963 return OS.tell() - ExpressionBegin;
964}
965
969 bool IsLittleEndian) {
972
974
975 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
976 return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
977 };
978
979 auto WriteAddress = [&](uint64_t Addr) -> Error {
981 IsLittleEndian);
982 };
983
984 switch (Entry.Operator) {
985 case dwarf::DW_RLE_end_of_list:
986 if (Error Err = CheckOperands(0))
987 return std::move(Err);
988 break;
989 case dwarf::DW_RLE_base_addressx:
990 if (Error Err = CheckOperands(1))
991 return std::move(Err);
993 break;
994 case dwarf::DW_RLE_startx_endx:
995 case dwarf::DW_RLE_startx_length:
996 case dwarf::DW_RLE_offset_pair:
997 if (Error Err = CheckOperands(2))
998 return std::move(Err);
1001 break;
1002 case dwarf::DW_RLE_base_address:
1003 if (Error Err = CheckOperands(1))
1004 return std::move(Err);
1005 if (Error Err = WriteAddress(Entry.Values[0]))
1006 return std::move(Err);
1007 break;
1008 case dwarf::DW_RLE_start_end:
1009 if (Error Err = CheckOperands(2))
1010 return std::move(Err);
1011 if (Error Err = WriteAddress(Entry.Values[0]))
1012 return std::move(Err);
1013 cantFail(WriteAddress(Entry.Values[1]));
1014 break;
1015 case dwarf::DW_RLE_start_length:
1016 if (Error Err = CheckOperands(2))
1017 return std::move(Err);
1018 if (Error Err = WriteAddress(Entry.Values[0]))
1019 return std::move(Err);
1021 break;
1022 }
1023
1024 return OS.tell() - BeginOffset;
1025}
1026
1030 bool IsLittleEndian) {
1033
1035
1036 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
1037 return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
1038 };
1039
1040 auto WriteAddress = [&](uint64_t Addr) -> Error {
1042 IsLittleEndian);
1043 };
1044
1045 auto WriteDWARFOperations = [&]() -> Error {
1046 std::string OpBuffer;
1048 uint64_t DescriptionsLength = 0;
1049
1053 DescriptionsLength += *OpSize;
1054 else
1055 return OpSize.takeError();
1056 }
1057
1058 if (Entry.DescriptionsLength)
1059 DescriptionsLength = *Entry.DescriptionsLength;
1060 else
1061 DescriptionsLength = OpBuffer.size();
1062
1064 OS.write(OpBuffer.data(), OpBuffer.size());
1065
1067 };
1068
1069 switch (Entry.Operator) {
1070 case dwarf::DW_LLE_end_of_list:
1071 if (Error Err = CheckOperands(0))
1072 return std::move(Err);
1073 break;
1074 case dwarf::DW_LLE_base_addressx:
1075 if (Error Err = CheckOperands(1))
1076 return std::move(Err);
1078 break;
1079 case dwarf::DW_LLE_startx_endx:
1080 case dwarf::DW_LLE_startx_length:
1081 case dwarf::DW_LLE_offset_pair:
1082 if (Error Err = CheckOperands(2))
1083 return std::move(Err);
1086 if (Error Err = WriteDWARFOperations())
1087 return std::move(Err);
1088 break;
1089 case dwarf::DW_LLE_default_location:
1090 if (Error Err = CheckOperands(0))
1091 return std::move(Err);
1092 if (Error Err = WriteDWARFOperations())
1093 return std::move(Err);
1094 break;
1095 case dwarf::DW_LLE_base_address:
1096 if (Error Err = CheckOperands(1))
1097 return std::move(Err);
1098 if (Error Err = WriteAddress(Entry.Values[0]))
1099 return std::move(Err);
1100 break;
1101 case dwarf::DW_LLE_start_end:
1102 if (Error Err = CheckOperands(2))
1103 return std::move(Err);
1104 if (Error Err = WriteAddress(Entry.Values[0]))
1105 return std::move(Err);
1106 cantFail(WriteAddress(Entry.Values[1]));
1107 if (Error Err = WriteDWARFOperations())
1108 return std::move(Err);
1109 break;
1110 case dwarf::DW_LLE_start_length:
1111 if (Error Err = CheckOperands(2))
1112 return std::move(Err);
1113 if (Error Err = WriteAddress(Entry.Values[0]))
1114 return std::move(Err);
1116 if (Error Err = WriteDWARFOperations())
1117 return std::move(Err);
1118 break;
1119 }
1120
1121 return OS.tell() - BeginOffset;
1122}
1123
1124template
1127 bool IsLittleEndian, bool Is64BitAddrSize) {
1129
1130
1132
1134 if (Table.AddrSize)
1135 AddrSize = *Table.AddrSize;
1136 else
1137 AddrSize = Is64BitAddrSize ? 8 : 4;
1138
1139
1140
1141
1142
1143 std::string ListBuffer;
1145
1146
1147
1148
1149 std::vector<uint64_t> Offsets;
1150
1152 Offsets.push_back(ListBufferOS.tell());
1153 if (List.Content) {
1154 List.Content->writeAsBinary(ListBufferOS, UINT64_MAX);
1155 Length += List.Content->binary_size();
1156 } else if (List.Entries) {
1157 for (const EntryType &Entry : *List.Entries) {
1159 writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
1160 if (!EntrySize)
1162 Length += *EntrySize;
1163 }
1164 }
1165 }
1166
1167
1168
1169
1170
1172 if (Table.OffsetEntryCount)
1173 OffsetEntryCount = *Table.OffsetEntryCount;
1174 else
1175 OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
1177 OffsetEntryCount * (Table.Format == dwarf::DWARF64 ? 8 : 4);
1178 Length += OffsetsSize;
1179
1180
1181
1182 if (Table.Length)
1183 Length = *Table.Length;
1184
1190
1194 IsLittleEndian);
1195 };
1196
1197 if (Table.Offsets)
1199 Table.Offsets->size()),
1200 0);
1201 else if (OffsetEntryCount != 0)
1202 EmitOffsets(Offsets, OffsetsSize);
1203
1204 OS.write(ListBuffer.data(), ListBuffer.size());
1205 }
1206
1208}
1209
1215
1221
1224 auto EmitFunc =
1244 SecName + " is not supported");
1245 });
1246
1247 return EmitFunc;
1248}
1249
1252 StringMap<std::unique_ptr> &OutputBuffers) {
1253 std::string Data;
1255
1257
1258 if (Error Err = EmitFunc(DebugInfoStream, DI))
1259 return Err;
1260 DebugInfoStream.flush();
1261 if (.empty())
1263
1265}
1266
1267Expected<StringMap<std::unique_ptr>>
1269 bool Is64BitAddrSize) {
1270 auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
1271 *static_cast<SMDiagnostic *>(DiagContext) = Diag;
1272 };
1273
1275 yaml::Input YIn(YAMLString, nullptr, CollectDiagnostic,
1276 &GeneratedDiag);
1277
1281
1282 YIn >> DI;
1283 if (YIn.error())
1285
1288
1292
1293 if (Err)
1294 return std::move(Err);
1295 return std::move(DebugSections);
1296}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, raw_ostream &OS, bool IsLittleEndian)
Definition DWARFEmitter.cpp:81
static Error emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec, StringMap< std::unique_ptr< MemoryBuffer > > &OutputBuffers)
Definition DWARFEmitter.cpp:1251
static void ZeroFillBytes(raw_ostream &OS, size_t Size)
Definition DWARFEmitter.cpp:65
static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File)
Definition DWARFEmitter.cpp:502
static Error writeDWARFLists(raw_ostream &OS, ArrayRef< DWARFYAML::ListTable< EntryType > > Tables, bool IsLittleEndian, bool Is64BitAddrSize)
Definition DWARFEmitter.cpp:1125
static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t OpcodeBase, uint8_t AddrSize, raw_ostream &OS, bool IsLittleEndian)
Definition DWARFEmitter.cpp:543
static Error writeVariableSizedInteger(uint64_t Integer, size_t Size, raw_ostream &OS, bool IsLittleEndian)
Definition DWARFEmitter.cpp:48
static Expected< uint64_t > writeListEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry, uint8_t AddrSize, bool IsLittleEndian)
Definition DWARFEmitter.cpp:966
static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian)
Definition DWARFEmitter.cpp:42
static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t AddrSize, bool IsLittleEndian, raw_ostream &OS)
Definition DWARFEmitter.cpp:510
static Error checkOperandCount(StringRef EncodingString, ArrayRef< yaml::Hex64 > Values, uint64_t ExpectedOperands)
Definition DWARFEmitter.cpp:908
static Expected< uint64_t > writeDWARFExpression(raw_ostream &OS, const DWARFYAML::DWARFOperation &Operation, uint8_t AddrSize, bool IsLittleEndian)
Definition DWARFEmitter.cpp:934
static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, bool IsLittleEndian, bool IsGNUPubSec=false)
Definition DWARFEmitter.cpp:223
static Expected< uint64_t > writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex, uint64_t AbbrevTableID, const dwarf::FormParams &Params, const DWARFYAML::Entry &Entry, raw_ostream &OS, bool IsLittleEndian)
Definition DWARFEmitter.cpp:261
static void writeInitialLength(const dwarf::DwarfFormat Format, const uint64_t Length, raw_ostream &OS, bool IsLittleEndian)
Definition DWARFEmitter.cpp:70
static std::vector< uint8_t > getStandardOpcodeLengths(uint16_t Version, std::optional< uint8_t > OpcodeBase)
Definition DWARFEmitter.cpp:583
static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS, uint64_t Addr, uint8_t AddrSize, bool IsLittleEndian)
Definition DWARFEmitter.cpp:921
Common declarations for yaml2obj.
This file declares classes for handling the YAML representation of DWARF Debug Info.
This file contains constants used for implementing Dwarf debug support.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
PowerPC Reduce CR logical Operation
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
StringRef getMessage() const
void push_back(const T &Elt)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(uint64_t Val)
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an std::string.
The Input class is used to parse a yaml document into in-memory structs and vectors.
std::error_code error() override
LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)
LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:699
LLVM_ABI Error emitDebugInfo(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:403
LLVM_ABI Error emitDebugRanges(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:186
LLVM_ABI Error emitDebugAranges(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:137
LLVM_ABI Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:249
LLVM_ABI Error emitDebugAbbrev(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:128
LLVM_ABI Error emitDebugRnglists(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:1210
LLVM_ABI Error emitDebugLoclists(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:1216
LLVM_ABI std::function< Error(raw_ostream &, const Data &)> getDWARFEmitterByName(StringRef SecName)
Definition DWARFEmitter.cpp:1223
LLVM_ABI Expected< StringMap< std::unique_ptr< MemoryBuffer > > > emitDebugSections(StringRef YAMLString, bool IsLittleEndian=sys::IsLittleEndianHost, bool Is64BitAddrSize=true)
Definition DWARFEmitter.cpp:1268
LLVM_ABI Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:255
LLVM_ABI Error emitDebugStr(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:87
LLVM_ABI Error emitDebugPubnames(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:239
LLVM_ABI Error emitDebugAddr(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:658
LLVM_ABI Error emitDebugNames(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:874
LLVM_ABI Error emitDebugPubtypes(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:244
LLVM_ABI Error emitDebugLine(raw_ostream &OS, const Data &DI)
Definition DWARFEmitter.cpp:597
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
LLVM_ABI std::optional< uint8_t > getFixedFormByteSize(dwarf::Form Form, FormParams Params)
Get the fixed byte size for a given form.
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
constexpr bool IsLittleEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
std::string utostr(uint64_t X, bool isNeg=false)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
void consumeError(Error Err)
Consume a Error without doing anything.
std::vector< AttributeAbbrev > Attributes
std::optional< yaml::Hex64 > Code
std::vector< Unit > Units
std::vector< LineTable > DebugLines
std::optional< std::vector< AddrTableEntry > > DebugAddr
std::optional< std::vector< Ranges > > DebugRanges
std::optional< std::vector< ListTable< LoclistEntry > > > DebugLoclists
std::vector< AbbrevTable > DebugAbbrev
LLVM_ABI Expected< AbbrevTableInfo > getAbbrevTableInfoByID(uint64_t ID) const
std::optional< PubSection > GNUPubNames
std::optional< std::vector< ARange > > DebugAranges
LLVM_ABI StringRef getAbbrevTableContentByIndex(uint64_t Index) const
Definition DWARFEmitter.cpp:96
std::optional< PubSection > GNUPubTypes
LLVM_ABI SetVector< StringRef > getNonEmptySectionNames() const
std::optional< std::vector< StringOffsetsTable > > DebugStrOffsets
std::optional< std::vector< StringRef > > DebugStrings
std::optional< std::vector< ListTable< RnglistEntry > > > DebugRnglists
std::optional< PubSection > PubNames
std::optional< DebugNamesSection > DebugNames
std::optional< PubSection > PubTypes
std::vector< FormValue > Values
std::optional< uint64_t > Length
std::optional< uint8_t > OpcodeBase
std::vector< LineTableOpcode > Opcodes
std::optional< uint64_t > PrologueLength
dwarf::DwarfFormat Format
std::vector< File > Files
std::vector< StringRef > IncludeDirs
std::optional< std::vector< uint8_t > > StandardOpcodeLengths
dwarf::DwarfFormat Format
std::vector< PubEntry > Entries
std::optional< yaml::Hex64 > Length
std::vector< yaml::Hex64 > Offsets
dwarf::DwarfFormat Format
std::optional< uint64_t > AbbrevTableID
dwarf::DwarfFormat Format
std::optional< yaml::Hex64 > Length
yaml::Hex64 TypeSignatureOrDwoID
std::optional< uint8_t > AddrSize
llvm::dwarf::UnitType Type
std::vector< Entry > Entries
std::optional< yaml::Hex64 > AbbrOffset
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
uint8_t getRefAddrByteSize() const
The definition of the size of form DW_FORM_ref_addr depends on the version.