LLVM: lib/Target/BPF/BTFDebug.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
31#include
32
33using namespace llvm;
34
36#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
37#include "llvm/DebugInfo/BTF/BTF.def"
38};
39
41 if (!Ty)
42 return Ty;
44 if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
45 return DerivedTy->getBaseType();
46 return Ty;
47}
48
49
58
60 bool NeedsFixup)
61 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->getName()) {
62 switch (Tag) {
63 case dwarf::DW_TAG_pointer_type:
64 Kind = BTF::BTF_KIND_PTR;
65 break;
66 case dwarf::DW_TAG_const_type:
67 Kind = BTF::BTF_KIND_CONST;
68 break;
69 case dwarf::DW_TAG_volatile_type:
70 Kind = BTF::BTF_KIND_VOLATILE;
71 break;
72 case dwarf::DW_TAG_typedef:
73 Kind = BTF::BTF_KIND_TYPEDEF;
74 break;
75 case dwarf::DW_TAG_restrict_type:
76 Kind = BTF::BTF_KIND_RESTRICT;
77 break;
78 default:
80 }
82}
83
84
87 : DTy(nullptr), NeedsFixup(false), Name(Name) {
88 Kind = BTF::BTF_KIND_PTR;
90 BTFType.Type = NextTypeId;
91}
92
95 return;
97
98 switch (Kind) {
99 case BTF::BTF_KIND_PTR:
100 case BTF::BTF_KIND_CONST:
101 case BTF::BTF_KIND_VOLATILE:
102 case BTF::BTF_KIND_RESTRICT:
103
104
105
106
107
108
109
111 break;
112 default:
114 break;
115 }
116
117 if (NeedsFixup || !DTy)
118 return;
119
120
122 if (!ResolvedType) {
123 assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
124 Kind == BTF::BTF_KIND_VOLATILE) &&
125 "Invalid null basetype");
127 } else {
129 }
130}
131
133
135 BTFType.Type = PointeeType;
136}
137
138
140 Kind = BTF::BTF_KIND_FWD;
141 BTFType.Info = IsUnion << 31 | Kind << 24;
143}
144
152
154
157 : Name(TypeName) {
158
160 switch (Encoding) {
161 case dwarf::DW_ATE_boolean:
163 break;
164 case dwarf::DW_ATE_signed:
165 case dwarf::DW_ATE_signed_char:
167 break;
168 case dwarf::DW_ATE_unsigned:
169 case dwarf::DW_ATE_unsigned_char:
170 BTFEncoding = 0;
171 break;
172 default:
174 }
175
176 Kind = BTF::BTF_KIND_INT;
179 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
180}
181
189
195
197 bool IsSigned) : ETy(ETy) {
198 Kind = BTF::BTF_KIND_ENUM;
199 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
201}
202
205 return;
207
209
210 DINodeArray Elements = ETy->getElements();
211 for (const auto Element : Elements) {
213
216
218 if (Enum->isUnsigned())
219 Value = static_cast<uint32_t>(Enum->getValue().getZExtValue());
220 else
221 Value = static_cast<uint32_t>(Enum->getValue().getSExtValue());
223 EnumValues.push_back(BTFEnum);
224 }
225}
226
229 for (const auto &Enum : EnumValues) {
232 }
233}
234
236 bool IsSigned) : ETy(ETy) {
237 Kind = BTF::BTF_KIND_ENUM64;
238 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
240}
241
244 return;
246
248
249 DINodeArray Elements = ETy->getElements();
250 for (const auto Element : Elements) {
252
256 if (Enum->isUnsigned())
257 Value = Enum->getValue().getZExtValue();
258 else
259 Value = static_cast<uint64_t>(Enum->getValue().getSExtValue());
262 EnumValues.push_back(BTFEnum);
263 }
264}
265
268 for (const auto &Enum : EnumValues) {
274 }
275}
276
278 Kind = BTF::BTF_KIND_ARRAY;
282
283 ArrayInfo.ElemType = ElemTypeId;
284 ArrayInfo.Nelems = NumElems;
285}
286
287
290 return;
292
293
294
295
296
298}
299
306
307
309 bool HasBitField, uint32_t Vlen)
310 : STy(STy), HasBitField(HasBitField) {
311 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
313 BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
314}
315
318 return;
320
322
323 if (STy->getTag() == dwarf::DW_TAG_variant_part) {
324
325
326
327
328
329
330
331
332 const auto *DTy = STy->getDiscriminator();
333 if (DTy) {
335
336 Discriminator.NameOff = BDebug.addString(DTy->getName());
337 Discriminator.Offset = DTy->getOffsetInBits();
338 const auto *BaseTy = DTy->getBaseType();
339 Discriminator.Type = BDebug.getTypeId(BaseTy);
340
341 Members.push_back(Discriminator);
342 }
343 }
344
345
346 const DINodeArray Elements = STy->getElements();
347 for (const auto *Element : Elements) {
349
350 switch (Element->getTag()) {
351 case dwarf::DW_TAG_member: {
353
355 if (HasBitField) {
356 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
357 BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
358 } else {
359 BTFMember.Offset = DDTy->getOffsetInBits();
360 }
363 break;
364 }
365 case dwarf::DW_TAG_variant_part: {
367
369 BTFMember.Offset = DCTy->getOffsetInBits();
371 break;
372 }
373 default:
374 llvm_unreachable("Unexpected DI tag of a struct/union element");
375 }
376 Members.push_back(BTFMember);
377 }
378}
379
382 for (const auto &Member : Members) {
387 }
388}
389
391
392
393
394
395
396
399 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
400 : STy(STy), FuncArgNames(FuncArgNames) {
401 Kind = BTF::BTF_KIND_FUNC_PROTO;
403}
404
407 return;
409
414
415
416
417 for (unsigned I = 1, N = Elements.size(); I < N; ++I) {
420 if (Element) {
421 Param.NameOff = BDebug.addString(FuncArgNames[I]);
422 Param.Type = BDebug.getTypeId(Element);
423 } else {
424 Param.NameOff = 0;
425 Param.Type = 0;
426 }
427 Parameters.push_back(Param);
428 }
429}
430
433 for (const auto &Param : Parameters) {
436 }
437}
438
441 : Name(FuncName) {
442 Kind = BTF::BTF_KIND_FUNC;
444 BTFType.Type = ProtoTypeId;
445}
446
454
456
458 : Name(VarName) {
459 Kind = BTF::BTF_KIND_VAR;
462 Info = VarInfo;
463}
464
468
473
475 : Asm(AsmPrt), Name(SecName) {
476 Kind = BTF::BTF_KIND_DATASEC;
479}
480
483 BTFType.Info |= Vars.size();
484}
485
488
489 for (const auto &V : Vars) {
491 Asm->emitLabelReference(std::get<1>(V), 4);
493 }
494}
495
497 : Name(TypeName) {
498 Kind = BTF::BTF_KIND_FLOAT;
501}
502
510
513 : Tag(Tag) {
514 Kind = BTF::BTF_KIND_DECL_TAG;
516 BTFType.Type = BaseTypeId;
517 Info = ComponentIdx;
518}
519
527
532
534 : DTy(nullptr), Tag(Tag) {
535 Kind = BTF::BTF_KIND_TYPE_TAG;
537 BTFType.Type = NextTypeId;
538}
539
541 : DTy(DTy), Tag(Tag) {
542 Kind = BTF::BTF_KIND_TYPE_TAG;
544}
545
548 return;
551 if (DTy) {
553 if (!ResolvedType)
555 else
557 }
558}
559
561
562 for (auto &OffsetM : OffsetToIdMap) {
563 if (Table[OffsetM.second] == S)
564 return OffsetM.first;
565 }
566
568 OffsetToIdMap[Offset] = Table.size();
569 Table.push_back(std::string(S));
570 Size += S.size() + 1;
572}
573
576 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
577 MapDefNotCollected(true) {
579}
580
581uint32_t BTFDebug::addType(std::unique_ptr TypeEntry,
583 TypeEntry->setId(TypeEntries.size() + 1);
584 uint32_t Id = TypeEntry->getId();
585 DIToIdMap[Ty] = Id;
586 TypeEntries.push_back(std::move(TypeEntry));
587 return Id;
588}
589
590uint32_t BTFDebug::addType(std::unique_ptr TypeEntry) {
591 TypeEntry->setId(TypeEntries.size() + 1);
592 uint32_t Id = TypeEntry->getId();
593 TypeEntries.push_back(std::move(TypeEntry));
594 return Id;
595}
596
597void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
598
600 std::unique_ptr TypeEntry;
601 switch (Encoding) {
602 case dwarf::DW_ATE_boolean:
603 case dwarf::DW_ATE_signed:
604 case dwarf::DW_ATE_signed_char:
605 case dwarf::DW_ATE_unsigned:
606 case dwarf::DW_ATE_unsigned_char:
607
608
609 TypeEntry = std::make_unique(
611 break;
612 case dwarf::DW_ATE_float:
615 break;
616 default:
617 return;
618 }
619
620 TypeId = addType(std::move(TypeEntry), BTy);
621}
622
623
624void BTFDebug::visitSubroutineType(
626 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
627 uint32_t &TypeId) {
629 uint32_t VLen = Elements.size() - 1;
631 return;
632
633
634
635
636
637 auto TypeEntry = std::make_unique(STy, VLen, FuncArgNames);
638 if (ForSubprog)
639 TypeId = addType(std::move(TypeEntry));
640 else
641 TypeId = addType(std::move(TypeEntry), STy);
642
643
644 for (const auto Element : Elements) {
645 visitTypeEntry(Element);
646 }
647}
648
649void BTFDebug::processDeclAnnotations(DINodeArray Annotations,
650 uint32_t BaseTypeId,
651 int ComponentIdx) {
652 if (!Annotations)
653 return;
654
655 for (const Metadata *Annotation : Annotations->operands()) {
658 if (Name->getString() != "btf_decl_tag")
659 continue;
660
662 auto TypeEntry = std::make_unique(BaseTypeId, ComponentIdx,
663 Value->getString());
664 addType(std::move(TypeEntry));
665 }
666}
667
668uint32_t BTFDebug::processDISubprogram(const DISubprogram *SP,
669 uint32_t ProtoTypeId, uint8_t Scope) {
670 auto FuncTypeEntry =
671 std::make_unique(SP->getName(), ProtoTypeId, Scope);
672 uint32_t FuncId = addType(std::move(FuncTypeEntry));
673
674
675 for (const DINode *DN : SP->getRetainedNodes()) {
677 uint32_t Arg = DV->getArg();
678 if (Arg)
679 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
680 }
681 }
682 processDeclAnnotations(SP->getAnnotations(), FuncId, -1);
683
684 return FuncId;
685}
686
687
688int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) {
691 if (Annots) {
692
693
694 for (const Metadata *Annotations : Annots->operands()) {
695 const MDNode *MD = cast(Annotations);
697 if (Name->getString() != "btf_type_tag")
698 continue;
700 }
701 }
702
703 if (MDStrs.size() == 0)
704 return -1;
705
706
707
708
709
710 unsigned TmpTypeId;
711 std::unique_ptr TypeEntry;
712 if (BaseTypeId >= 0)
714 std::make_unique(BaseTypeId, MDStrs[0]->getString());
715 else
716 TypeEntry = std::make_unique(DTy, MDStrs[0]->getString());
717 TmpTypeId = addType(std::move(TypeEntry));
718
719 for (unsigned I = 1; I < MDStrs.size(); I++) {
720 const MDString *Value = MDStrs[I];
721 TypeEntry = std::make_unique(TmpTypeId, Value->getString());
722 TmpTypeId = addType(std::move(TypeEntry));
723 }
724 return TmpTypeId;
725}
726
727
728void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
729 uint32_t &TypeId) {
731 uint32_t VLen = Elements.size();
732
733
734
735 if (CTy->getTag() == dwarf::DW_TAG_variant_part) {
737 if (DTy) {
738 visitTypeEntry(DTy);
739 VLen++;
740 }
741 }
743 return;
744
745
746 bool HasBitField = false;
747 for (const auto *Element : Elements) {
748 if (Element->getTag() == dwarf::DW_TAG_member) {
750 if (E->isBitField()) {
751 HasBitField = true;
752 break;
753 }
754 }
755 }
756
758 std::make_unique(CTy, IsStruct, HasBitField, VLen);
759 StructTypes.push_back(TypeEntry.get());
760 TypeId = addType(std::move(TypeEntry), CTy);
761
762
763 processDeclAnnotations(CTy->getAnnotations(), TypeId, -1);
764
765
766 int FieldNo = 0;
767 for (const auto *Element : Elements) {
768 switch (Element->getTag()) {
769 case dwarf::DW_TAG_member: {
771 visitTypeEntry(Elem);
772 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
773 break;
774 }
775 case dwarf::DW_TAG_variant_part: {
777 visitTypeEntry(Elem);
778 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
779 break;
780 }
781 default:
782 llvm_unreachable("Unexpected DI tag of a struct/union element");
783 }
784 FieldNo++;
785 }
786}
787
788void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
789
790 uint32_t ElemTypeId;
791 const DIType *ElemType = CTy->getBaseType();
792 visitTypeEntry(ElemType, ElemTypeId, false, false);
793
794
796 for (int I = Elements.size() - 1; I >= 0; --I) {
798 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
801 int64_t Count = CI->getSExtValue();
802
803
804
806 std::make_unique(ElemTypeId,
808 if (I == 0)
809 ElemTypeId = addType(std::move(TypeEntry), CTy);
810 else
811 ElemTypeId = addType(std::move(TypeEntry));
812 }
813 }
814
815
816 TypeId = ElemTypeId;
817
818
819
820 if (!ArrayIndexTypeId) {
821 auto TypeEntry = std::make_unique(dwarf::DW_ATE_unsigned, 32,
822 0, "__ARRAY_SIZE_TYPE__");
823 ArrayIndexTypeId = addType(std::move(TypeEntry));
824 }
825}
826
827void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {
829 uint32_t VLen = Elements.size();
831 return;
832
833 bool IsSigned = false;
834 unsigned NumBits = 32;
835
836
839 IsSigned = BTy->getEncoding() == dwarf::DW_ATE_signed ||
840 BTy->getEncoding() == dwarf::DW_ATE_signed_char;
842 }
843
844 if (NumBits <= 32) {
845 auto TypeEntry = std::make_unique(CTy, VLen, IsSigned);
846 TypeId = addType(std::move(TypeEntry), CTy);
847 } else {
848 assert(NumBits == 64);
849 auto TypeEntry = std::make_unique(CTy, VLen, IsSigned);
850 TypeId = addType(std::move(TypeEntry), CTy);
851 }
852
853}
854
855
856void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
857 uint32_t &TypeId) {
858 auto TypeEntry = std::make_unique(CTy->getName(), IsUnion);
859 TypeId = addType(std::move(TypeEntry), CTy);
860}
861
862
863void BTFDebug::visitCompositeType(const DICompositeType *CTy,
864 uint32_t &TypeId) {
866 switch (Tag) {
867 case dwarf::DW_TAG_structure_type:
868 case dwarf::DW_TAG_union_type:
869 case dwarf::DW_TAG_variant_part:
870
872 visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId);
873 else
874 visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId);
875 break;
876 case dwarf::DW_TAG_array_type:
877 visitArrayType(CTy, TypeId);
878 break;
879 case dwarf::DW_TAG_enumeration_type:
880 visitEnumType(CTy, TypeId);
881 break;
882 default:
884 }
885}
886
887bool BTFDebug::IsForwardDeclCandidate(const DIType *Base) {
889 auto CTag = CTy->getTag();
890 if ((CTag == dwarf::DW_TAG_structure_type ||
891 CTag == dwarf::DW_TAG_union_type) &&
893 return true;
894 }
895 return false;
896}
897
898
899void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
900 bool CheckPointer, bool SeenPointer) {
902
903 if (Tag == dwarf::DW_TAG_atomic_type)
904 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
905 SeenPointer);
906
907
908
909 if (CheckPointer && !SeenPointer) {
910 SeenPointer = Tag == dwarf::DW_TAG_pointer_type && !DTy->getAnnotations();
911 }
912
913 if (CheckPointer && SeenPointer) {
914 const DIType *Base = DTy->getBaseType();
916 if (IsForwardDeclCandidate(Base)) {
917
918
919
920 auto TypeEntry = std::make_unique(DTy, Tag, true);
922 Fixup.push_back(std::make_pair(DTy, TypeEntry.get()));
923 TypeId = addType(std::move(TypeEntry), DTy);
924 return;
925 }
926 }
927 }
928
929 if (Tag == dwarf::DW_TAG_pointer_type) {
930 int TmpTypeId = genBTFTypeTags(DTy, -1);
931 if (TmpTypeId >= 0) {
932 auto TypeDEntry =
933 std::make_unique(TmpTypeId, Tag, DTy->getName());
934 TypeId = addType(std::move(TypeDEntry), DTy);
935 } else {
936 auto TypeEntry = std::make_unique(DTy, Tag, false);
937 TypeId = addType(std::move(TypeEntry), DTy);
938 }
939 } else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type ||
940 Tag == dwarf::DW_TAG_volatile_type ||
941 Tag == dwarf::DW_TAG_restrict_type) {
942 auto TypeEntry = std::make_unique(DTy, Tag, false);
943 TypeId = addType(std::move(TypeEntry), DTy);
944 if (Tag == dwarf::DW_TAG_typedef)
945 processDeclAnnotations(DTy->getAnnotations(), TypeId, -1);
946 } else if (Tag != dwarf::DW_TAG_member) {
947 return;
948 }
949
950
951
952 uint32_t TempTypeId = 0;
953 if (Tag == dwarf::DW_TAG_member)
954 visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false);
955 else
956 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
957}
958
959
960
961
962
963
964
965
966void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId,
967 bool CheckPointer, bool SeenPointer) {
968 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
969 TypeId = DIToIdMap[Ty];
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000 if (Ty && (!CheckPointer || !SeenPointer)) {
1002 while (DTy) {
1003 const DIType *BaseTy = DTy->getBaseType();
1004 if (!BaseTy)
1005 break;
1006
1007 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1009 } else {
1010 if (CheckPointer && DTy->getTag() == dwarf::DW_TAG_pointer_type &&
1012 SeenPointer = true;
1013 if (IsForwardDeclCandidate(BaseTy))
1014 break;
1015 }
1016 uint32_t TmpTypeId;
1017 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1018 break;
1019 }
1020 }
1021 }
1022 }
1023
1024 return;
1025 }
1026
1028 visitBasicType(BTy, TypeId);
1030 visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),
1031 TypeId);
1033 visitCompositeType(CTy, TypeId);
1035 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
1036 else
1038}
1039
1040void BTFDebug::visitTypeEntry(const DIType *Ty) {
1041 uint32_t TypeId;
1042 visitTypeEntry(Ty, TypeId, false, false);
1043}
1044
1045void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
1046 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1047 TypeId = DIToIdMap[Ty];
1048 return;
1049 }
1050
1051 uint32_t TmpId;
1052 switch (Ty->getTag()) {
1053 case dwarf::DW_TAG_typedef:
1054 case dwarf::DW_TAG_const_type:
1055 case dwarf::DW_TAG_volatile_type:
1056 case dwarf::DW_TAG_restrict_type:
1057 case dwarf::DW_TAG_pointer_type:
1059 break;
1060 case dwarf::DW_TAG_array_type:
1061
1063 break;
1064 case dwarf::DW_TAG_structure_type: {
1065
1068 for (const auto *Element : Elements) {
1070 const DIType *MemberBaseType = MemberType->getBaseType();
1071
1072
1073
1074
1075
1076
1078 if (MemberCTy) {
1079 visitMapDefType(MemberBaseType, TmpId);
1080 } else {
1081 visitTypeEntry(MemberBaseType);
1082 }
1083 }
1084 break;
1085 }
1086 default:
1087 break;
1088 }
1089
1090
1091 visitTypeEntry(Ty, TypeId, false, false);
1092}
1093
1094
1095std::string BTFDebug::populateFileContent(const DIFile *File) {
1096 std::string FileName;
1097
1098 if (->getFilename().starts_with("/") && File->getDirectory().size())
1099 FileName = File->getDirectory().str() + "/" + File->getFilename().str();
1100 else
1101 FileName = std::string(File->getFilename());
1102
1103
1104 if (FileContent.contains(FileName))
1105 return FileName;
1106
1107 std::vectorstd::string Content;
1108 std::string Line;
1109 Content.push_back(Line);
1110
1111 std::unique_ptr Buf;
1113 if (Source)
1115 else if (ErrorOr<std::unique_ptr> BufOrErr =
1117 Buf = std::move(*BufOrErr);
1118 if (Buf)
1119 for (line_iterator I(*Buf, false), E; I != E; ++I)
1120 Content.push_back(std::string(*I));
1121
1122 FileContent[FileName] = Content;
1123 return FileName;
1124}
1125
1126void BTFDebug::constructLineInfo(MCSymbol *Label, const DIFile *File,
1127 uint32_t Line, uint32_t Column) {
1128 std::string FileName = populateFileContent(File);
1129 BTFLineInfo LineInfo;
1130
1133
1134 const auto &Content = FileContent[FileName];
1135 if (Line < Content.size())
1137 else
1141 LineInfoTable[SecNameOff].push_back(LineInfo);
1142}
1143
1144void BTFDebug::emitCommonHeader() {
1148 OS.emitInt8(0);
1149}
1150
1151void BTFDebug::emitBTFSection() {
1152
1153 if (!TypeEntries.size() && StringTable.getSize() == 1)
1154 return;
1155
1156 MCContext &Ctx = OS.getContext();
1159 OS.switchSection(Sec);
1160
1161
1162 emitCommonHeader();
1164
1165 uint32_t TypeLen = 0, StrLen;
1166 for (const auto &TypeEntry : TypeEntries)
1167 TypeLen += TypeEntry->getSize();
1168 StrLen = StringTable.getSize();
1169
1170 OS.emitInt32(0);
1171 OS.emitInt32(TypeLen);
1172 OS.emitInt32(TypeLen);
1173 OS.emitInt32(StrLen);
1174
1175
1176 for (const auto &TypeEntry : TypeEntries)
1178
1179
1180 uint32_t StringOffset = 0;
1181 for (const auto &S : StringTable.getTable()) {
1182 OS.AddComment("string offset=" + std::to_string(StringOffset));
1183 OS.emitBytes(S);
1184 OS.emitBytes(StringRef("\0", 1));
1185 StringOffset += S.size() + 1;
1186 }
1187}
1188
1189void BTFDebug::emitBTFExtSection() {
1190
1191
1192 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1193 !FieldRelocTable.size())
1194 return;
1195
1196 MCContext &Ctx = OS.getContext();
1199 OS.switchSection(Sec);
1200
1201
1202 emitCommonHeader();
1204
1205
1206 uint32_t FuncLen = 4, LineLen = 4;
1207
1208 uint32_t FieldRelocLen = 0;
1209 for (const auto &FuncSec : FuncInfoTable) {
1212 }
1213 for (const auto &LineSec : LineInfoTable) {
1216 }
1217 for (const auto &FieldRelocSec : FieldRelocTable) {
1220 }
1221
1222 if (FieldRelocLen)
1223 FieldRelocLen += 4;
1224
1225 OS.emitInt32(0);
1226 OS.emitInt32(FuncLen);
1227 OS.emitInt32(FuncLen);
1228 OS.emitInt32(LineLen);
1229 OS.emitInt32(FuncLen + LineLen);
1230 OS.emitInt32(FieldRelocLen);
1231
1232
1233 OS.AddComment("FuncInfo");
1235 for (const auto &FuncSec : FuncInfoTable) {
1236 OS.AddComment("FuncInfo section string offset=" +
1237 std::to_string(FuncSec.first));
1238 OS.emitInt32(FuncSec.first);
1239 OS.emitInt32(FuncSec.second.size());
1240 for (const auto &FuncInfo : FuncSec.second) {
1241 Asm->emitLabelReference(FuncInfo.Label, 4);
1242 OS.emitInt32(FuncInfo.TypeId);
1243 }
1244 }
1245
1246
1247 OS.AddComment("LineInfo");
1249 for (const auto &LineSec : LineInfoTable) {
1250 OS.AddComment("LineInfo section string offset=" +
1251 std::to_string(LineSec.first));
1252 OS.emitInt32(LineSec.first);
1253 OS.emitInt32(LineSec.second.size());
1254 for (const auto &LineInfo : LineSec.second) {
1255 Asm->emitLabelReference(LineInfo.Label, 4);
1257 OS.emitInt32(LineInfo.LineOff);
1258 OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +
1259 std::to_string(LineInfo.ColumnNum));
1261 }
1262 }
1263
1264
1265 if (FieldRelocLen) {
1266 OS.AddComment("FieldReloc");
1268 for (const auto &FieldRelocSec : FieldRelocTable) {
1269 OS.AddComment("Field reloc section string offset=" +
1270 std::to_string(FieldRelocSec.first));
1271 OS.emitInt32(FieldRelocSec.first);
1272 OS.emitInt32(FieldRelocSec.second.size());
1273 for (const auto &FieldRelocInfo : FieldRelocSec.second) {
1274 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1275 OS.emitInt32(FieldRelocInfo.TypeID);
1276 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1277 OS.emitInt32(FieldRelocInfo.RelocKind);
1278 }
1279 }
1280 }
1281}
1282
1285 auto *Unit = SP->getUnit();
1286
1288 SkipInstruction = true;
1289 return;
1290 }
1291 SkipInstruction = false;
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312 if (MapDefNotCollected) {
1313 processGlobals(true);
1314 MapDefNotCollected = false;
1315 }
1316
1317
1318
1319
1320 std::unordered_map<uint32_t, StringRef> FuncArgNames;
1321 for (const DINode *DN : SP->getRetainedNodes()) {
1323
1324 uint32_t Arg = DV->getArg();
1325 if (Arg) {
1326 visitTypeEntry(DV->getType());
1327 FuncArgNames[Arg] = DV->getName();
1328 }
1329 }
1330 }
1331
1332
1334 visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);
1335
1336
1338 uint32_t FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1339
1340 for (const auto &TypeEntry : TypeEntries)
1341 TypeEntry->completeType(*this);
1342
1343
1344 MCSymbol *FuncLabel = Asm->getFunctionBegin();
1346 FuncInfo.Label = FuncLabel;
1347 FuncInfo.TypeId = FuncTypeId;
1351 } else {
1352 SecNameOff = addString(".text");
1353 }
1354 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1355}
1356
1358 SkipInstruction = false;
1359 LineInfoGenerated = false;
1360 SecNameOff = 0;
1361}
1362
1363
1364
1365unsigned BTFDebug::populateType(const DIType *Ty) {
1366 unsigned Id;
1367 visitTypeEntry(Ty, Id, false, false);
1368 for (const auto &TypeEntry : TypeEntries)
1369 TypeEntry->completeType(*this);
1370 return Id;
1371}
1372
1373
1374void BTFDebug::generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
1377 FieldReloc.Label = ORSym;
1378 FieldReloc.TypeID = RootId;
1379
1381 size_t FirstDollar = AccessPattern.find_first_of('$');
1382 if (IsAma) {
1383 size_t FirstColon = AccessPattern.find_first_of(':');
1384 size_t SecondColon = AccessPattern.find_first_of(':', FirstColon + 1);
1385 StringRef IndexPattern = AccessPattern.substr(FirstDollar + 1);
1386 StringRef RelocKindStr = AccessPattern.substr(FirstColon + 1,
1387 SecondColon - FirstColon);
1388 StringRef PatchImmStr = AccessPattern.substr(SecondColon + 1,
1389 FirstDollar - SecondColon);
1390
1392 FieldReloc.RelocKind = std::stoull(std::string(RelocKindStr));
1393 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1395 } else {
1396 StringRef RelocStr = AccessPattern.substr(FirstDollar + 1);
1398 FieldReloc.RelocKind = std::stoull(std::string(RelocStr));
1399 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.RelocKind);
1400 }
1401 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1402}
1403
1404void BTFDebug::processGlobalValue(const MachineOperand &MO) {
1405
1407 const GlobalValue *GVal = MO.getGlobal();
1409 if (!GVar) {
1410
1412 return;
1413 }
1414
1417 return;
1418
1419 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1420 OS.emitLabel(ORSym);
1421
1422 MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1424 generatePatchImmReloc(ORSym, RootId, GVar,
1426 }
1427}
1428
1431
1432 if (SkipInstruction || MI->isMetaInstruction() ||
1434 return;
1435
1436 if (MI->isInlineAsm()) {
1437
1438 unsigned NumDefs = 0;
1439 while (true) {
1442 ++NumDefs;
1443 continue;
1444 }
1445
1447 if (AsmStr[0] == 0)
1448 return;
1449 break;
1450 }
1451 }
1452
1453 if (MI->getOpcode() == BPF::LD_imm64) {
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468 processGlobalValue(MI->getOperand(1));
1469 } else if (MI->getOpcode() == BPF::CORE_LD64 ||
1470 MI->getOpcode() == BPF::CORE_LD32 ||
1471 MI->getOpcode() == BPF::CORE_ST ||
1472 MI->getOpcode() == BPF::CORE_SHIFT) {
1473
1474 processGlobalValue(MI->getOperand(3));
1475 } else if (MI->getOpcode() == BPF::JAL) {
1476
1480 }
1481 }
1482
1483 if ()
1484 return;
1485
1486
1487
1490
1491
1492 if (LineInfoGenerated == false) {
1493 auto *S = MI->getMF()->getFunction().getSubprogram();
1494 if (!S)
1495 return;
1496 MCSymbol *FuncLabel = Asm->getFunctionBegin();
1497 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1498 LineInfoGenerated = true;
1499 }
1500
1501 return;
1502 }
1503
1504
1505 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1506 OS.emitLabel(LineSym);
1507
1508
1509 constructLineInfo(LineSym, DL->getFile(), DL.getLine(), DL.getCol());
1510
1511 LineInfoGenerated = true;
1513}
1514
1515void BTFDebug::processGlobals(bool ProcessingMapDef) {
1516
1519
1521 std::optional GVKind;
1522
1523 if (.isDeclarationForLinker())
1525
1526 if (Global.isDeclarationForLinker())
1527 SecName = Global.hasSection() ? Global.getSection() : "";
1528 else if (GVKind->isCommon())
1529 SecName = ".bss";
1530 else {
1533 SecName = Sec->getName();
1534 }
1535
1536 if (ProcessingMapDef != SecName.starts_with(".maps"))
1537 continue;
1538
1539
1540
1541
1542 if (SecName == ".rodata" && Global.hasPrivateLinkage() &&
1543 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1544
1545 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1546 DataSecEntries[std::string(SecName)] =
1547 std::make_unique(Asm, std::string(SecName));
1548 }
1549 }
1550
1552 Global.getDebugInfo(GVs);
1553
1554
1555 if (GVs.size() == 0)
1556 continue;
1557
1558 uint32_t GVTypeId = 0;
1559 DIGlobalVariable *DIGlobal = nullptr;
1560 for (auto *GVE : GVs) {
1561 DIGlobal = GVE->getVariable();
1563 visitMapDefType(DIGlobal->getType(), GVTypeId);
1564 else {
1566 visitTypeEntry(Ty, GVTypeId, false, false);
1567 }
1568 break;
1569 }
1570
1571
1572
1573
1574
1575
1576
1577
1584 continue;
1585
1586 uint32_t GVarInfo;
1589 } else if (Global.hasInitializer()) {
1591 } else {
1593 }
1594
1595 auto VarEntry =
1596 std::make_unique(Global.getName(), GVTypeId, GVarInfo);
1597 uint32_t VarId = addType(std::move(VarEntry));
1598
1599 processDeclAnnotations(DIGlobal->getAnnotations(), VarId, -1);
1600
1601
1602 if (SecName.empty())
1603 continue;
1604
1605
1606 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1607 if (Inserted)
1608 It->second = std::make_unique(Asm, std::string(SecName));
1609
1610
1611 const DataLayout &DL = Global.getDataLayout();
1612 uint32_t Size = DL.getTypeAllocSize(Global.getValueType());
1613
1614 It->second->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size);
1615
1616 if (Global.hasInitializer())
1617 processGlobalInitializer(Global.getInitializer());
1618 }
1619}
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632void BTFDebug::processGlobalInitializer(const Constant *C) {
1634 processFuncPrototypes(Fn);
1636 for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I)
1637 processGlobalInitializer(CA->getOperand(I));
1638 }
1639}
1640
1641
1643 if (MI->getOpcode() == BPF::LD_imm64) {
1648 if (GVar) {
1651 return false;
1652
1653
1654 auto [Imm, Reloc] = PatchImms[GVar];
1658 else
1662 return true;
1663 }
1664 }
1665 } else if (MI->getOpcode() == BPF::CORE_LD64 ||
1666 MI->getOpcode() == BPF::CORE_LD32 ||
1667 MI->getOpcode() == BPF::CORE_ST ||
1668 MI->getOpcode() == BPF::CORE_SHIFT) {
1674 uint32_t Imm = PatchImms[GVar].first;
1675 OutMI.setOpcode(MI->getOperand(1).getImm());
1676 if (MI->getOperand(0).isImm())
1678 else
1682 return true;
1683 }
1684 }
1685 }
1686 return false;
1687}
1688
1689void BTFDebug::processFuncPrototypes(const Function *F) {
1690 if ()
1691 return;
1692
1694 if (!SP || SP->isDefinition())
1695 return;
1696
1697
1698 if (!ProtoFunctions.insert(F).second)
1699 return;
1700
1702 const std::unordered_map<uint32_t, StringRef> FuncArgNames;
1703 visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);
1705
1706 if (F->hasSection()) {
1707 StringRef SecName = F->getSection();
1708
1709 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1710 if (Inserted)
1711 It->second = std::make_unique(Asm, std::string(SecName));
1712
1713
1714 It->second->addDataSecEntry(FuncId, Asm->getSymbol(F), 0);
1715 }
1716}
1717
1719
1720 if (MapDefNotCollected) {
1721 processGlobals(true);
1722 MapDefNotCollected = false;
1723 }
1724
1725
1726 processGlobals(false);
1727
1728
1729
1730 for (const Function &F : *MMI->getModule()) {
1732 processFuncPrototypes(&F);
1733 }
1734
1735 for (auto &DataSec : DataSecEntries)
1736 addType(std::move(DataSec.second));
1737
1738
1739 for (auto &Fixup : FixupDerivedTypes) {
1742 bool IsUnion = CTy->getTag() == dwarf::DW_TAG_union_type;
1743
1744
1746 for (const auto &StructType : StructTypes) {
1749 break;
1750 }
1751 }
1752
1753 if (StructTypeId == 0) {
1754 auto FwdTypeEntry = std::make_unique(TypeName, IsUnion);
1755 StructTypeId = addType(std::move(FwdTypeEntry));
1756 }
1757
1758 for (auto &TypeInfo : Fixup.second) {
1761
1762 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
1763 if (TmpTypeId >= 0)
1765 else
1767 }
1768 }
1769
1770
1771 for (const auto &TypeEntry : TypeEntries)
1772 TypeEntry->completeType(*this);
1773
1774
1775 emitBTFSection();
1776 emitBTFExtSection();
1777}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const char * BTFKindStr[]
Definition BTFDebug.cpp:35
static const DIType * tryRemoveAtomicType(const DIType *Ty)
Definition BTFDebug.cpp:40
This file contains support for writing BTF debug info.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
PowerPC TLS Dynamic Call Fixup
static StringRef getName(Value *V)
static enum BaseType getBaseType(const Value *Val)
Return the baseType for Val which states whether Val is exclusively derived from constant/null,...
Annotations lets you mark points and ranges inside source code, for tests:
This class is intended to be used as a driving class for all asm writers.
MCSymbol * getSymbol(const GlobalValue *GV) const
TargetMachine & TM
Target machine description.
Collect and emit BTF information.
void endFunctionImpl(const MachineFunction *MF) override
Post process after all instructions in this function are processed.
Definition BTFDebug.cpp:1357
BTFDebug(AsmPrinter *AP)
Definition BTFDebug.cpp:574
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
Definition BTFDebug.cpp:1429
bool InstLower(const MachineInstr *MI, MCInst &OutMI)
Emit proper patchable instructions.
Definition BTFDebug.cpp:1642
size_t addString(StringRef S)
Add string to the string table.
uint32_t getArrayIndexTypeId()
Get the special array index type id.
uint32_t getTypeId(const DIType *Ty)
Get the type id for a particular DIType.
void endModule() override
Complete all the types and emit the BTF sections.
Definition BTFDebug.cpp:1718
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
Definition BTFDebug.cpp:1283
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:486
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:481
BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
Definition BTFDebug.cpp:474
BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
Definition BTFDebug.cpp:457
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:469
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:465
uint32_t addString(StringRef S)
Add a string to the string table and returns its offset in the table.
Definition BTFDebug.cpp:560
BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems)
Definition BTFDebug.cpp:277
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:300
void completeType(BTFDebug &BDebug) override
Represent a BTF array.
Definition BTFDebug.cpp:288
struct BTF::CommonType BTFType
virtual void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
Definition BTFDebug.cpp:50
uint32_t roundupToBytes(uint32_t NumBits)
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:520
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:528
BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag)
Definition BTFDebug.cpp:511
Handle several derived types include pointer, const, volatile, typedef and restrict.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:93
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:132
void setPointeeType(uint32_t PointeeType)
Definition BTFDebug.cpp:134
BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup)
Definition BTFDebug.cpp:59
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:242
BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)
Definition BTFDebug.cpp:235
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:266
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:203
BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)
Definition BTFDebug.cpp:196
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:227
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:503
BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
Definition BTFDebug.cpp:496
BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, const std::unordered_map< uint32_t, StringRef > &FuncArgNames)
The Func kind represents both subprogram and pointee of function pointers.
Definition BTFDebug.cpp:397
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:405
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:431
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:455
BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope)
Definition BTFDebug.cpp:439
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:447
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:153
BTFTypeFwd(StringRef Name, bool IsUnion)
Represent a struct/union forward declaration.
Definition BTFDebug.cpp:139
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:145
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:190
BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, StringRef TypeName)
Definition BTFDebug.cpp:155
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:182
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:380
BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, uint32_t NumMembers)
Represent either a struct or a union.
Definition BTFDebug.cpp:308
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:316
std::string getName()
Definition BTFDebug.cpp:390
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
Definition BTFDebug.cpp:546
BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)
Definition BTFDebug.cpp:533
This is an important base class in LLVM.
Basic type, like 'int' or 'float'.
unsigned getEncoding() const
DIDerivedType * getDiscriminator() const
DINodeArray getElements() const
DINodeArray getAnnotations() const
DIType * getBaseType() const
DINodeArray getAnnotations() const
Get annotations associated with this derived type.
DINodeArray getAnnotations() const
Tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
Subprogram description. Uses SubclassData1.
LLVM_ABI BoundType getCount() const
Type array for a subprogram.
DITypeRefArray getTypeArray() const
uint64_t getOffsetInBits() const
StringRef getName() const
bool isForwardDecl() const
uint64_t getSizeInBits() const
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
MachineModuleInfo * MMI
Collected machine module information.
DebugLoc PrevInstLoc
Previous instruction's location information.
DebugHandlerBase(AsmPrinter *A)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
DISubprogram * getSubprogram() const
Get the attached subprogram.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
@ InternalLinkage
Rename collisions when linking (static functions).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ ExternalWeakLinkage
ExternalWeak linkage description.
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
This represents a section on linux, lots of unix variants and some bare metal systems.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
StringRef getName() const
Streaming machine code generation interface.
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
void emitInt32(uint64_t Value)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
const MDOperand & getOperand(unsigned I) const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
const Module * getModule() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
const char * getSymbolName() const
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.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
A Module instance is used to store all the information related to an LLVM module.
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Class to represent struct types.
LLVM_ABI StringRef getName() const
Return the name for this struct type if it has an identity.
static SectionKind getKindForGlobal(const GlobalObject *GO, const TargetMachine &TM)
Classify the specified global variable into a set of target independent categories embodied in Sectio...
MCSection * SectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const
This method computes the appropriate section to emit the specified global variable or function defini...
virtual TargetLoweringObjectFile * getObjFileLowering() const
static Twine utohexstr(uint64_t Val)
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ VAR_GLOBAL_ALLOCATED
Linkage: ExternalLinkage.
@ VAR_STATIC
Linkage: InternalLinkage.
@ VAR_GLOBAL_EXTERNAL
Linkage: ExternalLinkage.
@ MAX_VLEN
Max # of struct/union/enum members or func args.
@ C
The default llvm calling convention, compatible with C.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto dyn_cast_or_null(const Y &Val)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Global
Append to llvm.global_dtors.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
Represent one field relocation.
uint32_t RelocKind
What to patch the instruction.
const MCSymbol * Label
MCSymbol identifying insn for the reloc.
uint32_t OffsetNameOff
The string to traverse types.
Represent one func and its type id.
uint32_t TypeId
Type id referring to .BTF type section.
const MCSymbol * Label
Func MCSymbol.
uint32_t LineOff
line offset in the .BTF string table
MCSymbol * Label
MCSymbol identifying insn for the lineinfo.
uint32_t ColumnNum
the column number
uint32_t FileNameOff
file name offset in the .BTF string table
uint32_t LineNum
the line number
BTF_KIND_ENUM64 is followed by multiple "struct BTFEnum64".
uint32_t NameOff
Enum name offset in the string table.
uint32_t Val_Hi32
Enum member hi32 value.
uint32_t Val_Lo32
Enum member lo32 value.
BTF_KIND_ENUM is followed by multiple "struct BTFEnum".
int32_t Val
Enum member value.
uint32_t NameOff
Enum name offset in the string table.
BTF_KIND_STRUCT and BTF_KIND_UNION are followed by multiple "struct BTFMember".
uint32_t NameOff
Member name offset in the string table.
uint32_t Offset
BitOffset or BitFieldSize+BitOffset.
uint32_t Type
Member type.
BTF_KIND_FUNC_PROTO are followed by multiple "struct BTFParam".