42#define DEBUG_TYPE "btf-debug"
44#define GET_CC_REGISTER_LISTS
45#include "BPFGenCallingConv.inc"
48#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
49#include "llvm/DebugInfo/BTF/BTF.def"
56 if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
57 return DerivedTy->getBaseType();
63 switch (DTy->getTag()) {
64 case dwarf::DW_TAG_atomic_type:
65 case dwarf::DW_TAG_const_type:
66 case dwarf::DW_TAG_restrict_type:
67 case dwarf::DW_TAG_typedef:
68 case dwarf::DW_TAG_volatile_type:
69 Ty = DTy->getBaseType();
84 return DTy->getTag() == dwarf::DW_TAG_pointer_type && IRTy->
isPointerTy();
87 uint64_t SizeInBits = BTy->getSizeInBits();
88 if (BTy->getEncoding() == dwarf::DW_ATE_float)
92 if (BTy->getEncoding() == dwarf::DW_ATE_boolean && IRTy->
isIntegerTy(1))
101 switch (CTy->getTag()) {
102 case dwarf::DW_TAG_enumeration_type:
144 if (
MI.isDebugValue()) {
147 if (
MI.isIndirectDebugValue())
168 if (
MI.mayStore() && !
MI.isCall() &&
MI.getOperand(0).isReg()) {
172 const Value *V = MMO->getValue();
175 auto It = AllocaToFI.
find(V);
176 if (It != AllocaToFI.
end())
183 if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical()) {
184 DefinedRegs.
insert(MO.getReg());
185 StackLoadRegs.
erase(MO.getReg());
189 if (
MI.getOpcode() == BPF::LDD &&
MI.getOperand(1).getReg() == BPF::R11)
190 StackLoadRegs.
insert(
MI.getOperand(0).getReg());
197 if (!VI.Var || !VI.Var->getArg() || !VI.inStackSlot())
199 if (VI.Var->getScope()->getSubprogram() != SP)
202 if (EntryRegMap.
count(Arg))
204 auto It = FrameIndexToReg.
find(VI.getStackSlot());
205 if (It != FrameIndexToReg.
end())
206 EntryRegMap[Arg] = It->second;
221 ArrayRef<std::pair<uint32_t, Register>> AliveArgs,
226 << AliveArgs.size() <<
")\n");
231 for (
unsigned I = 0,
N = AliveArgs.size();
I <
N; ++
I, ++ArgIt) {
232 auto [ArgNo,
Reg] = AliveArgs[
I];
235 <<
": type mismatch for source arg " << ArgNo
236 <<
" at IR position " <<
I <<
"\n");
240 if (
I >= std::size(CC_BPF64_ArgRegs))
243 int DwarfReg =
TRI.getDwarfRegNum(
Reg,
false);
244 if (DwarfReg !=
static_cast<int>(
I + 1)) {
246 <<
" in DWARF reg " << DwarfReg <<
", expected "
267 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->
getName()) {
269 case dwarf::DW_TAG_pointer_type:
270 Kind = BTF::BTF_KIND_PTR;
272 case dwarf::DW_TAG_const_type:
273 Kind = BTF::BTF_KIND_CONST;
275 case dwarf::DW_TAG_volatile_type:
276 Kind = BTF::BTF_KIND_VOLATILE;
278 case dwarf::DW_TAG_typedef:
279 Kind = BTF::BTF_KIND_TYPEDEF;
281 case dwarf::DW_TAG_restrict_type:
282 Kind = BTF::BTF_KIND_RESTRICT;
293 : DTy(nullptr), NeedsFixup(
false), Name(Name) {
295 case dwarf::DW_TAG_pointer_type:
296 Kind = BTF::BTF_KIND_PTR;
298 case dwarf::DW_TAG_typedef:
299 Kind = BTF::BTF_KIND_TYPEDEF;
315 case BTF::BTF_KIND_PTR:
316 case BTF::BTF_KIND_CONST:
317 case BTF::BTF_KIND_VOLATILE:
318 case BTF::BTF_KIND_RESTRICT:
333 if (NeedsFixup || !DTy)
339 assert((
Kind == BTF::BTF_KIND_PTR ||
Kind == BTF::BTF_KIND_CONST ||
340 Kind == BTF::BTF_KIND_VOLATILE) &&
341 "Invalid null basetype");
356 Kind = BTF::BTF_KIND_FWD;
377 case dwarf::DW_ATE_boolean:
380 case dwarf::DW_ATE_signed:
381 case dwarf::DW_ATE_signed_char:
384 case dwarf::DW_ATE_unsigned:
385 case dwarf::DW_ATE_unsigned_char:
386 case dwarf::DW_ATE_UTF:
393 Kind = BTF::BTF_KIND_INT;
396 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
414 bool IsSigned) : ETy(ETy) {
415 Kind = BTF::BTF_KIND_ENUM;
427 DINodeArray Elements = ETy->getElements();
428 for (
const auto Element : Elements) {
435 if (Enum->isUnsigned())
436 Value =
static_cast<uint32_t>(Enum->getValue().getZExtValue());
438 Value =
static_cast<uint32_t>(Enum->getValue().getSExtValue());
440 EnumValues.push_back(BTFEnum);
446 for (
const auto &Enum : EnumValues) {
453 bool IsSigned) : ETy(ETy) {
454 Kind = BTF::BTF_KIND_ENUM64;
466 DINodeArray Elements = ETy->getElements();
467 for (
const auto Element : Elements) {
473 if (Enum->isUnsigned())
474 Value = Enum->getValue().getZExtValue();
476 Value =
static_cast<uint64_t
>(Enum->getValue().getSExtValue());
479 EnumValues.push_back(BTFEnum);
485 for (
const auto &Enum : EnumValues) {
495 Kind = BTF::BTF_KIND_ARRAY;
500 ArrayInfo.ElemType = ElemTypeId;
501 ArrayInfo.Nelems = NumElems;
528 : STy(STy), Elements(Elements.begin(), Elements.end()),
529 HasBitField(HasBitField) {
530 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
532 BTFType.Info = (HasBitField << 31) | (
Kind << 24) | Vlen;
542 if (STy->getTag() == dwarf::DW_TAG_variant_part) {
551 const auto *DTy = STy->getDiscriminator();
555 Discriminator.NameOff = BDebug.
addString(DTy->getName());
556 Discriminator.Offset = DTy->getOffsetInBits();
557 const auto *BaseTy = DTy->getBaseType();
558 Discriminator.Type = BDebug.
getTypeId(BaseTy);
560 Members.push_back(Discriminator);
565 for (
const auto *Element : Elements) {
568 switch (Element->getTag()) {
569 case dwarf::DW_TAG_member: {
574 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
575 BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
577 BTFMember.
Offset = DDTy->getOffsetInBits();
583 case dwarf::DW_TAG_variant_part: {
587 BTFMember.
Offset = DCTy->getOffsetInBits();
594 Members.push_back(BTFMember);
600 for (
const auto &Member : Members) {
620 : STy(STy), FuncArgNames(FuncArgNames),
621 AliveParamIndices(AliveParamIndices),
622 UseFilteredParams(UseFilteredParams), VoidReturn(VoidReturn) {
623 Kind = BTF::BTF_KIND_FUNC_PROTO;
632 DITypeArray Elements = STy->getTypeArray();
645 auto It = FuncArgNames.find(
I);
647 It != FuncArgNames.end() ? BDebug.
addString(It->second) : 0;
653 Parameters.push_back(Param);
656 if (UseFilteredParams) {
662 for (
unsigned I = 1,
N = Elements.size();
I <
N; ++
I)
668 for (
const auto &Param : Parameters) {
677 Kind = BTF::BTF_KIND_FUNC;
694 Kind = BTF::BTF_KIND_VAR;
710 : Asm(AsmPrt), Name(SecName) {
711 Kind = BTF::BTF_KIND_DATASEC;
724 for (
const auto &V : Vars) {
726 Asm->emitLabelReference(std::get<1>(V), 4);
733 Kind = BTF::BTF_KIND_FLOAT;
749 Kind = BTF::BTF_KIND_DECL_TAG;
769 : DTy(nullptr), Tag(Tag) {
770 Kind = BTF::BTF_KIND_TYPE_TAG;
776 : DTy(DTy), Tag(Tag) {
777 Kind = BTF::BTF_KIND_TYPE_TAG;
797 for (
auto &OffsetM : OffsetToIdMap) {
798 if (Table[OffsetM.second] == S)
799 return OffsetM.first;
803 OffsetToIdMap[
Offset] = Table.size();
804 Table.push_back(std::string(S));
805 Size += S.
size() + 1;
811 LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0),
812 MapDefNotCollected(
true) {
816uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
818 TypeEntry->setId(TypeEntries.size() + 1);
821 TypeEntries.push_back(std::move(TypeEntry));
825uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
826 TypeEntry->setId(TypeEntries.size() + 1);
828 TypeEntries.push_back(std::move(TypeEntry));
832void BTFDebug::visitBasicType(
const DIBasicType *BTy, uint32_t &TypeId) {
837 case dwarf::DW_ATE_boolean:
838 case dwarf::DW_ATE_signed:
839 case dwarf::DW_ATE_signed_char:
840 case dwarf::DW_ATE_unsigned:
841 case dwarf::DW_ATE_unsigned_char:
842 case dwarf::DW_ATE_UTF:
845 TypeEntry = std::make_unique<BTFTypeInt>(
848 case dwarf::DW_ATE_float:
856 TypeId = addType(std::move(TypeEntry), BTy);
860void BTFDebug::visitSubroutineType(
865 uint32_t VLen =
Elements.size() - 1;
873 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
874 STy, VLen, FuncArgNames,
false, ArrayRef<uint32_t>(), VoidReturn);
876 TypeId = addType(std::move(TypeEntry));
878 TypeId = addType(std::move(TypeEntry), STy);
882 for (
const auto Element : Elements)
883 visitTypeEntry(Element);
886 visitTypeEntry(Elements[
I]);
890void BTFDebug::processDeclAnnotations(DINodeArray
Annotations,
896 for (
const Metadata *Annotation : Annotations->operands()) {
899 if (
Name->getString() !=
"btf_decl_tag")
903 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
905 addType(std::move(TypeEntry));
909uint32_t BTFDebug::processDISubprogram(
910 const DISubprogram *SP, uint32_t ProtoTypeId, uint8_t Scope,
913 std::make_unique<BTFTypeFunc>(
SP->getName(), ProtoTypeId, Scope);
914 uint32_t FuncId = addType(std::move(FuncTypeEntry));
917 for (
const MDNode *DN :
SP->getRetainedNodes()) {
919 uint32_t Arg = DV->getArg();
922 auto It = ArgIndexMap->
find(Arg);
923 if (It != ArgIndexMap->
end())
924 processDeclAnnotations(DV->getAnnotations(), FuncId, It->second);
926 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
931 processDeclAnnotations(
SP->getAnnotations(), FuncId, -1);
937int BTFDebug::genBTFTypeTags(
const DIDerivedType *DTy,
int BaseTypeId) {
943 for (
const Metadata *Annotations : Annots->operands()) {
946 if (
Name->getString() !=
"btf_type_tag")
952 if (MDStrs.
size() == 0)
960 std::unique_ptr<BTFTypeTypeTag>
TypeEntry;
963 std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
965 TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
966 TmpTypeId = addType(std::move(TypeEntry));
968 for (
unsigned I = 1;
I < MDStrs.
size();
I++) {
969 const MDString *
Value = MDStrs[
I];
970 TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId,
Value->getString());
971 TmpTypeId = addType(std::move(TypeEntry));
977void BTFDebug::visitStructType(
const DICompositeType *CTy,
bool IsStruct,
983 if (CTy->
getTag() == dwarf::DW_TAG_structure_type)
991 if (CTy->
getTag() == dwarf::DW_TAG_variant_part) {
1002 bool HasBitField =
false;
1003 for (
const auto *Element : Elements) {
1004 if (Element->getTag() == dwarf::DW_TAG_member) {
1006 if (
E->isBitField()) {
1013 auto TypeEntry = std::make_unique<BTFTypeStruct>(CTy, Elements, IsStruct,
1016 TypeId = addType(std::move(TypeEntry), CTy);
1023 for (
const auto *Element : Elements) {
1024 switch (Element->getTag()) {
1025 case dwarf::DW_TAG_member: {
1027 visitTypeEntry(Elem);
1028 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1031 case dwarf::DW_TAG_variant_part: {
1033 visitTypeEntry(Elem);
1034 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1044void BTFDebug::visitArrayType(
const DICompositeType *CTy, uint32_t &TypeId) {
1046 uint32_t ElemTypeId;
1048 visitTypeEntry(ElemType, ElemTypeId,
false,
false);
1055 auto TypeEntry = std::make_unique<BTFTypeArray>(ElemTypeId, 0);
1056 ElemTypeId = addType(std::move(TypeEntry), CTy);
1060 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
1063 int64_t
Count = CI->getSExtValue();
1068 std::make_unique<BTFTypeArray>(ElemTypeId,
1071 ElemTypeId = addType(std::move(TypeEntry), CTy);
1073 ElemTypeId = addType(std::move(TypeEntry));
1078 TypeId = ElemTypeId;
1082 if (!ArrayIndexTypeId) {
1083 auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
1084 0,
"__ARRAY_SIZE_TYPE__");
1085 ArrayIndexTypeId = addType(std::move(TypeEntry));
1089void BTFDebug::visitEnumType(
const DICompositeType *CTy, uint32_t &TypeId) {
1095 bool IsSigned =
false;
1096 unsigned NumBits = 32;
1101 IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
1106 if (NumBits <= 32) {
1107 auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
1108 TypeId = addType(std::move(TypeEntry), CTy);
1111 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
1112 TypeId = addType(std::move(TypeEntry), CTy);
1118void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion,
1121 TypeId = addType(std::move(TypeEntry), CTy);
1129 case dwarf::DW_TAG_structure_type:
1130 case dwarf::DW_TAG_union_type:
1131 case dwarf::DW_TAG_variant_part:
1134 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type, TypeId);
1136 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type, TypeId);
1138 case dwarf::DW_TAG_array_type:
1139 visitArrayType(CTy, TypeId);
1141 case dwarf::DW_TAG_enumeration_type:
1142 visitEnumType(CTy, TypeId);
1149bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
1151 auto CTag = CTy->
getTag();
1152 if ((CTag == dwarf::DW_TAG_structure_type ||
1153 CTag == dwarf::DW_TAG_union_type) &&
1161void BTFDebug::visitDerivedType(
const DIDerivedType *DTy, uint32_t &TypeId,
1162 bool CheckPointer,
bool SeenPointer) {
1165 if (
Tag == dwarf::DW_TAG_atomic_type)
1166 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
1171 if (CheckPointer && !SeenPointer) {
1175 if (CheckPointer && SeenPointer) {
1176 const DIType *
Base = DTy->getBaseType();
1178 if (IsForwardDeclCandidate(
Base)) {
1182 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
true);
1185 TypeId = addType(std::move(TypeEntry), DTy);
1191 if (
Tag == dwarf::DW_TAG_pointer_type ||
Tag == dwarf::DW_TAG_typedef) {
1192 int TmpTypeId = genBTFTypeTags(DTy, -1);
1193 if (TmpTypeId >= 0) {
1195 std::make_unique<BTFTypeDerived>(TmpTypeId,
Tag, DTy->
getName());
1196 TypeId = addType(std::move(TypeDEntry), DTy);
1198 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1199 TypeId = addType(std::move(TypeEntry), DTy);
1201 if (
Tag == dwarf::DW_TAG_typedef)
1203 }
else if (
Tag == dwarf::DW_TAG_const_type ||
1204 Tag == dwarf::DW_TAG_volatile_type ||
1205 Tag == dwarf::DW_TAG_restrict_type) {
1206 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1207 TypeId = addType(std::move(TypeEntry), DTy);
1208 }
else if (
Tag != dwarf::DW_TAG_member) {
1214 uint32_t TempTypeId = 0;
1215 if (
Tag == dwarf::DW_TAG_member)
1216 visitTypeEntry(DTy->getBaseType(), TempTypeId,
true,
false);
1218 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
1228void BTFDebug::visitTypeEntry(
const DIType *Ty, uint32_t &TypeId,
1229 bool CheckPointer,
bool SeenPointer) {
1230 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1231 TypeId = DIToIdMap[Ty];
1262 if (Ty && (!CheckPointer || !SeenPointer)) {
1265 const DIType *BaseTy = DTy->getBaseType();
1269 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1272 if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type &&
1275 if (IsForwardDeclCandidate(BaseTy))
1279 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1290 visitBasicType(BTy, TypeId);
1292 visitSubroutineType(STy,
false, SmallDenseMap<uint32_t, StringRef>(),
1295 visitCompositeType(CTy, TypeId);
1297 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
1302void BTFDebug::visitTypeEntry(
const DIType *Ty) {
1304 visitTypeEntry(Ty, TypeId,
false,
false);
1307void BTFDebug::visitMapDefType(
const DIType *Ty, uint32_t &TypeId) {
1308 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1309 TypeId = DIToIdMap[Ty];
1315 case dwarf::DW_TAG_typedef:
1316 case dwarf::DW_TAG_const_type:
1317 case dwarf::DW_TAG_volatile_type:
1318 case dwarf::DW_TAG_restrict_type:
1319 case dwarf::DW_TAG_pointer_type:
1322 case dwarf::DW_TAG_array_type:
1326 case dwarf::DW_TAG_structure_type: {
1330 for (
const auto *Element : Elements) {
1332 const DIType *MemberBaseType = MemberType->getBaseType();
1341 visitMapDefType(MemberBaseType, TmpId);
1343 visitTypeEntry(MemberBaseType);
1353 visitTypeEntry(Ty, TypeId,
false,
false);
1357std::string BTFDebug::populateFileContent(
const DIFile *File) {
1358 std::string FileName;
1360 if (!
File->getFilename().starts_with(
"/") &&
File->getDirectory().size())
1361 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
1363 FileName = std::string(
File->getFilename());
1366 if (FileContent.contains(FileName))
1369 std::vector<std::string> Content;
1371 Content.push_back(Line);
1373 auto LoadFile = [&
File](StringRef FileName) {
1374 return File->getContext().getVirtualFileSystem().getBufferForFile(FileName);
1377 std::unique_ptr<MemoryBuffer> Buf;
1381 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = LoadFile(FileName))
1382 Buf = std::move(*BufOrErr);
1384 for (line_iterator
I(*Buf,
false),
E;
I !=
E; ++
I)
1385 Content.push_back(std::string(*
I));
1387 FileContent[FileName] = std::move(Content);
1391void BTFDebug::constructLineInfo(
MCSymbol *Label,
const DIFile *File,
1392 uint32_t Line, uint32_t Column) {
1393 std::string FileName = populateFileContent(File);
1394 BTFLineInfo LineInfo;
1399 const auto &Content = FileContent[FileName];
1400 if (Line < Content.size())
1406 LineInfoTable[SecNameOff].push_back(LineInfo);
1409void BTFDebug::emitCommonHeader() {
1416void BTFDebug::emitBTFSection() {
1418 if (!TypeEntries.size() && StringTable.getSize() == 1)
1421 MCContext &Ctx = OS.getContext();
1424 OS.switchSection(Sec);
1430 uint32_t TypeLen = 0, StrLen;
1431 for (
const auto &TypeEntry : TypeEntries)
1433 StrLen = StringTable.getSize();
1436 OS.emitInt32(TypeLen);
1437 OS.emitInt32(TypeLen);
1438 OS.emitInt32(StrLen);
1441 for (
const auto &TypeEntry : TypeEntries)
1445 uint32_t StringOffset = 0;
1446 for (
const auto &S : StringTable.getTable()) {
1447 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1449 OS.emitBytes(StringRef(
"\0", 1));
1450 StringOffset += S.size() + 1;
1454void BTFDebug::emitBTFExtSection() {
1457 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1458 !FieldRelocTable.size())
1461 MCContext &Ctx = OS.getContext();
1464 OS.switchSection(Sec);
1471 uint32_t FuncLen = 4, LineLen = 4;
1473 uint32_t FieldRelocLen = 0;
1474 for (
const auto &FuncSec : FuncInfoTable) {
1478 for (
const auto &LineSec : LineInfoTable) {
1482 for (
const auto &FieldRelocSec : FieldRelocTable) {
1491 OS.emitInt32(FuncLen);
1492 OS.emitInt32(FuncLen);
1493 OS.emitInt32(LineLen);
1494 OS.emitInt32(FuncLen + LineLen);
1495 OS.emitInt32(FieldRelocLen);
1498 OS.AddComment(
"FuncInfo");
1500 for (
const auto &FuncSec : FuncInfoTable) {
1501 OS.AddComment(
"FuncInfo section string offset=" +
1502 std::to_string(FuncSec.first));
1503 OS.emitInt32(FuncSec.first);
1504 OS.emitInt32(FuncSec.second.size());
1505 for (
const auto &FuncInfo : FuncSec.second) {
1506 Asm->emitLabelReference(FuncInfo.Label, 4);
1507 OS.emitInt32(FuncInfo.TypeId);
1512 OS.AddComment(
"LineInfo");
1514 for (
const auto &LineSec : LineInfoTable) {
1515 OS.AddComment(
"LineInfo section string offset=" +
1516 std::to_string(LineSec.first));
1517 OS.emitInt32(LineSec.first);
1518 OS.emitInt32(LineSec.second.size());
1519 for (
const auto &LineInfo : LineSec.second) {
1520 Asm->emitLabelReference(LineInfo.
Label, 4);
1522 OS.emitInt32(LineInfo.
LineOff);
1523 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1530 if (FieldRelocLen) {
1531 OS.AddComment(
"FieldReloc");
1533 for (
const auto &FieldRelocSec : FieldRelocTable) {
1534 OS.AddComment(
"Field reloc section string offset=" +
1535 std::to_string(FieldRelocSec.first));
1536 OS.emitInt32(FieldRelocSec.first);
1537 OS.emitInt32(FieldRelocSec.second.size());
1538 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1539 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1540 OS.emitInt32(FieldRelocInfo.TypeID);
1541 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1542 OS.emitInt32(FieldRelocInfo.RelocKind);
1550 auto *Unit = SP->getUnit();
1553 SkipInstruction =
true;
1556 SkipInstruction =
false;
1577 if (MapDefNotCollected) {
1578 processGlobals(
true);
1579 MapDefNotCollected =
false;
1586 for (
const MDNode *DN : SP->getRetainedNodes()) {
1591 visitTypeEntry(DV->getType());
1592 FuncArgNames[Arg] = DV->getName();
1600 bool IsNocall = SP->getType()->getCC() == dwarf::DW_CC_nocall;
1601 bool UseFilteredParams =
false;
1609 DITypeArray Elements = SP->getType()->getTypeArray();
1617 if (UseFilteredParams) {
1621 AliveParamIndices.
push_back(ArgReg.first);
1622 ArgIndexMap[ArgReg.first] =
I;
1626 visitTypeEntry(Elements[0]);
1627 for (
uint32_t ArgNo : AliveParamIndices)
1628 visitTypeEntry(Elements[ArgNo]);
1630 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
1631 SP->getType(), AliveParamIndices.
size(), FuncArgNames,
true,
1632 AliveParamIndices, VoidReturn);
1633 ProtoTypeId = addType(std::move(TypeEntry));
1634 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope, &ArgIndexMap);
1638 if (!UseFilteredParams) {
1641 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId,
1643 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1646 for (
const auto &TypeEntry : TypeEntries)
1647 TypeEntry->completeType(*
this);
1652 FuncInfo.
Label = FuncLabel;
1653 FuncInfo.
TypeId = FuncTypeId;
1660 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1664 SkipInstruction =
false;
1665 LineInfoGenerated =
false;
1671unsigned BTFDebug::populateType(
const DIType *Ty) {
1673 visitTypeEntry(Ty, Id,
false,
false);
1674 for (
const auto &TypeEntry : TypeEntries)
1675 TypeEntry->completeType(*
this);
1680void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1683 FieldReloc.
Label = ORSym;
1684 FieldReloc.
TypeID = RootId;
1690 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
1693 SecondColon - FirstColon);
1695 FirstDollar - SecondColon);
1698 FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
1699 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1702 StringRef RelocStr = AccessPattern.
substr(FirstDollar + 1);
1704 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1705 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1707 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1713 const GlobalValue *GVal = MO.
getGlobal();
1725 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1726 OS.emitLabel(ORSym);
1728 MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
1730 generatePatchImmReloc(ORSym, RootId, GVar,
1738 if (SkipInstruction ||
MI->isMetaInstruction() ||
1742 if (
MI->isInlineAsm()) {
1744 unsigned NumDefs = 0;
1759 if (
MI->getOpcode() == BPF::LD_imm64) {
1774 processGlobalValue(
MI->getOperand(1));
1775 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1776 MI->getOpcode() == BPF::CORE_LD32 ||
1777 MI->getOpcode() == BPF::CORE_ST ||
1778 MI->getOpcode() == BPF::CORE_SHIFT) {
1780 processGlobalValue(
MI->getOperand(3));
1781 }
else if (
MI->getOpcode() == BPF::JAL) {
1798 if (LineInfoGenerated ==
false) {
1799 auto *S =
MI->getMF()->getFunction().getSubprogram();
1803 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1804 LineInfoGenerated =
true;
1811 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1812 OS.emitLabel(LineSym);
1815 constructLineInfo(LineSym,
DL->getFile(),
DL.getLine(),
DL.getCol());
1817 LineInfoGenerated =
true;
1821void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1827 std::optional<SectionKind> GVKind;
1829 if (!
Global.isDeclarationForLinker())
1832 if (
Global.isDeclarationForLinker())
1833 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1834 else if (GVKind->isCommon())
1842 if (ProcessingMapDef != SecName.
starts_with(
".maps"))
1848 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1849 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1851 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1852 DataSecEntries[std::string(SecName)] =
1853 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1858 Global.getDebugInfo(GVs);
1861 if (GVs.
size() == 0)
1864 uint32_t GVTypeId = 0;
1865 DIGlobalVariable *DIGlobal =
nullptr;
1866 for (
auto *GVE : GVs) {
1867 DIGlobal = GVE->getVariable();
1869 visitMapDefType(DIGlobal->
getType(), GVTypeId);
1872 visitTypeEntry(Ty, GVTypeId,
false,
false);
1895 }
else if (
Global.hasInitializer()) {
1902 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1903 uint32_t VarId = addType(std::move(VarEntry));
1908 if (SecName.
empty())
1912 auto [It,
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1914 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1917 const DataLayout &
DL =
Global.getDataLayout();
1920 It->second->addDataSecEntry(VarId,
Asm->getSymbol(&
Global),
Size);
1922 if (
Global.hasInitializer())
1923 processGlobalInitializer(
Global.getInitializer());
1938void BTFDebug::processGlobalInitializer(
const Constant *
C) {
1940 processFuncPrototypes(Fn);
1942 for (
unsigned I = 0,
N = CA->getNumOperands();
I <
N; ++
I)
1943 processGlobalInitializer(CA->getOperand(
I));
1949 if (
MI->getOpcode() == BPF::LD_imm64) {
1960 auto [
Imm,
Reloc] = PatchImms[GVar];
1971 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1972 MI->getOpcode() == BPF::CORE_LD32 ||
1973 MI->getOpcode() == BPF::CORE_ST ||
1974 MI->getOpcode() == BPF::CORE_SHIFT) {
1982 if (
MI->getOperand(0).isImm())
1995void BTFDebug::processFuncPrototypes(
const Function *
F) {
2000 if (!SP || SP->isDefinition())
2004 if (!ProtoFunctions.insert(
F).second)
2009 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
2012 if (
F->hasSection()) {
2015 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
2017 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
2026 if (MapDefNotCollected) {
2027 processGlobals(
true);
2028 MapDefNotCollected =
false;
2032 processGlobals(
false);
2038 processFuncPrototypes(&
F);
2041 for (
auto &DataSec : DataSecEntries)
2042 addType(std::move(DataSec.second));
2045 for (
auto &
Fixup : FixupDerivedTypes) {
2048 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
2059 if (StructTypeId == 0) {
2060 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
2061 StructTypeId = addType(std::move(FwdTypeEntry));
2064 for (
auto &TypeInfo :
Fixup.second) {
2068 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
2077 for (
const auto &TypeEntry : TypeEntries)
2078 TypeEntry->completeType(*
this);
2082 emitBTFExtSection();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static SmallVector< std::pair< uint32_t, Register >, 8 > collectNocallEntryArgRegs(const MachineFunction &MF)
Collect the physical register each source argument lives in by scanning DBG_VALUE instructions in the...
static bool sourceArgMatchesIRType(const DIType *SourceTy, Type *IRTy)
static const char * BTFKindStr[]
static const DIType * stripDITypeAttributes(const DIType *Ty)
static bool canUseNocallOptimizedSignature(const MachineFunction &MF, DITypeArray Elements, ArrayRef< std::pair< uint32_t, Register > > AliveArgs, const TargetRegisterInfo &TRI)
Check whether the optimized IR signature matches the surviving source arguments precisely enough to e...
static const DIType * tryRemoveAtomicType(const DIType *Ty)
This file contains support for writing BTF debug info.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
Register const TargetRegisterInfo * TRI
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,...
This file defines the SmallVector class.
Defines the virtual file system interface vfs::FileSystem.
an instruction to allocate memory on the stack
Annotations lets you mark points and ranges inside source code, for tests:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
static constexpr StringRef TypeIdAttr
The attribute attached to globals representing a type id.
static constexpr StringRef AmaAttr
The attribute attached to globals representing a field access.
Collect and emit BTF information.
void endFunctionImpl(const MachineFunction *MF) override
Post process after all instructions in this function are processed.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
bool InstLower(const MachineInstr *MI, MCInst &OutMI)
Emit proper patchable instructions.
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.
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
uint32_t addString(StringRef S)
Add a string to the string table and returns its offset in the table.
BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems)
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void completeType(BTFDebug &BDebug) override
Represent a BTF array.
struct BTF::CommonType BTFType
virtual void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
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...
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag)
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...
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void setPointeeType(uint32_t PointeeType)
BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup)
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, const SmallDenseMap< uint32_t, StringRef > &FuncArgNames, bool UseFilteredParams=false, ArrayRef< uint32_t > AliveParamIndices={}, bool VoidReturn=false)
The Func kind represents both subprogram and pointee of function pointers.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope)
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
BTFTypeFwd(StringRef Name, bool IsUnion)
Represent a struct/union forward declaration.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, StringRef TypeName)
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
BTFTypeStruct(const DICompositeType *STy, ArrayRef< const DINode * > Elements, bool IsStruct, bool HasBitField, uint32_t NumMembers)
Represent either a struct or a union.
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
void completeType(BTFDebug &BDebug) override
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)
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
LLVM_ABI DISubprogram * getSubprogram() const
Get the subprogram for this scope.
DILocalScope * getScope() const
Get the local scope for this variable.
LLVM_ABI dwarf::Tag getTag() const
Subprogram description. Uses SubclassData1.
LLVM_ABI BoundType getCount() const
Type array for a subprogram.
DITypeArray 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.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
DISubprogram * getSubprogram() const
Get the attached subprogram.
Type * getReturnType() const
Returns the type of the ret val.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
@ 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
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
VariableDbgInfoMapTy & getVariableDbgInfo()
const MachineBasicBlock & front() const
Representation of each machine instruction.
A description of a memory reference used in the backend.
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
Register getReg() const
getReg - Returns the register number.
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.
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Implements a dense probed hash-table based set with some number of buckets stored inline.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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
Check if the string is empty.
constexpr size_t size() const
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
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
static Twine utohexstr(uint64_t Val)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
#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.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
uint64_t getBTFRecordElementOffset(const DINode *Element)
Return the bit offset used to order an element of a BTF structure record.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Global
Append to llvm.global_dtors.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
decltype(auto) cast(const From &Val)
cast<X> - 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".
Function object to check whether the first component of a container supported by std::get (like std::...