40#define DEBUG_TYPE "btf-debug"
42#define GET_CC_REGISTER_LISTS
43#include "BPFGenCallingConv.inc"
46#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
47#include "llvm/DebugInfo/BTF/BTF.def"
54 if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
55 return DerivedTy->getBaseType();
61 switch (DTy->getTag()) {
62 case dwarf::DW_TAG_atomic_type:
63 case dwarf::DW_TAG_const_type:
64 case dwarf::DW_TAG_restrict_type:
65 case dwarf::DW_TAG_typedef:
66 case dwarf::DW_TAG_volatile_type:
67 Ty = DTy->getBaseType();
82 return DTy->getTag() == dwarf::DW_TAG_pointer_type && IRTy->
isPointerTy();
85 uint64_t SizeInBits = BTy->getSizeInBits();
86 if (BTy->getEncoding() == dwarf::DW_ATE_float)
90 if (BTy->getEncoding() == dwarf::DW_ATE_boolean && IRTy->
isIntegerTy(1))
99 switch (CTy->getTag()) {
100 case dwarf::DW_TAG_enumeration_type:
141 if (
MI.isDebugValue()) {
144 if (
MI.isIndirectDebugValue())
158 EntryRegMap[Arg] = MO.
getReg();
165 if (
MI.mayStore() && !
MI.isCall() &&
MI.getOperand(0).isReg()) {
169 const Value *V = MMO->getValue();
172 auto It = AllocaToFI.
find(V);
173 if (It != AllocaToFI.
end())
180 if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical()) {
181 DefinedRegs.
insert(MO.getReg());
182 StackLoadRegs.
erase(MO.getReg());
186 if (
MI.getOpcode() == BPF::LDD &&
MI.getOperand(1).getReg() == BPF::R11)
187 StackLoadRegs.
insert(
MI.getOperand(0).getReg());
194 if (!VI.Var || !VI.Var->getArg() || !VI.inStackSlot())
196 if (VI.Var->getScope()->getSubprogram() != SP)
199 if (EntryRegMap.
count(Arg))
201 auto It = FrameIndexToReg.
find(VI.getStackSlot());
202 if (It != FrameIndexToReg.
end())
203 EntryRegMap[Arg] = It->second;
218 ArrayRef<std::pair<uint32_t, Register>> AliveArgs,
223 << AliveArgs.size() <<
")\n");
228 for (
unsigned I = 0,
N = AliveArgs.size();
I <
N; ++
I, ++ArgIt) {
229 auto [ArgNo,
Reg] = AliveArgs[
I];
232 <<
": type mismatch for source arg " << ArgNo
233 <<
" at IR position " <<
I <<
"\n");
237 if (
I >= std::size(CC_BPF64_ArgRegs))
240 int DwarfReg =
TRI.getDwarfRegNum(
Reg,
false);
241 if (DwarfReg !=
static_cast<int>(
I + 1)) {
243 <<
" in DWARF reg " << DwarfReg <<
", expected "
264 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->
getName()) {
266 case dwarf::DW_TAG_pointer_type:
267 Kind = BTF::BTF_KIND_PTR;
269 case dwarf::DW_TAG_const_type:
270 Kind = BTF::BTF_KIND_CONST;
272 case dwarf::DW_TAG_volatile_type:
273 Kind = BTF::BTF_KIND_VOLATILE;
275 case dwarf::DW_TAG_typedef:
276 Kind = BTF::BTF_KIND_TYPEDEF;
278 case dwarf::DW_TAG_restrict_type:
279 Kind = BTF::BTF_KIND_RESTRICT;
290 : DTy(nullptr), NeedsFixup(
false), Name(Name) {
292 case dwarf::DW_TAG_pointer_type:
293 Kind = BTF::BTF_KIND_PTR;
295 case dwarf::DW_TAG_typedef:
296 Kind = BTF::BTF_KIND_TYPEDEF;
312 case BTF::BTF_KIND_PTR:
313 case BTF::BTF_KIND_CONST:
314 case BTF::BTF_KIND_VOLATILE:
315 case BTF::BTF_KIND_RESTRICT:
330 if (NeedsFixup || !DTy)
336 assert((
Kind == BTF::BTF_KIND_PTR ||
Kind == BTF::BTF_KIND_CONST ||
337 Kind == BTF::BTF_KIND_VOLATILE) &&
338 "Invalid null basetype");
353 Kind = BTF::BTF_KIND_FWD;
374 case dwarf::DW_ATE_boolean:
377 case dwarf::DW_ATE_signed:
378 case dwarf::DW_ATE_signed_char:
381 case dwarf::DW_ATE_unsigned:
382 case dwarf::DW_ATE_unsigned_char:
383 case dwarf::DW_ATE_UTF:
390 Kind = BTF::BTF_KIND_INT;
393 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
411 bool IsSigned) : ETy(ETy) {
412 Kind = BTF::BTF_KIND_ENUM;
424 DINodeArray Elements = ETy->getElements();
425 for (
const auto Element : Elements) {
432 if (Enum->isUnsigned())
433 Value =
static_cast<uint32_t>(Enum->getValue().getZExtValue());
435 Value =
static_cast<uint32_t>(Enum->getValue().getSExtValue());
437 EnumValues.push_back(BTFEnum);
443 for (
const auto &Enum : EnumValues) {
450 bool IsSigned) : ETy(ETy) {
451 Kind = BTF::BTF_KIND_ENUM64;
463 DINodeArray Elements = ETy->getElements();
464 for (
const auto Element : Elements) {
470 if (Enum->isUnsigned())
471 Value = Enum->getValue().getZExtValue();
473 Value =
static_cast<uint64_t>(Enum->getValue().getSExtValue());
476 EnumValues.push_back(BTFEnum);
482 for (
const auto &Enum : EnumValues) {
492 Kind = BTF::BTF_KIND_ARRAY;
497 ArrayInfo.ElemType = ElemTypeId;
498 ArrayInfo.Nelems = NumElems;
524 : STy(STy), HasBitField(HasBitField) {
525 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
527 BTFType.Info = (HasBitField << 31) | (
Kind << 24) | Vlen;
537 if (STy->getTag() == dwarf::DW_TAG_variant_part) {
546 const auto *DTy = STy->getDiscriminator();
550 Discriminator.NameOff = BDebug.
addString(DTy->getName());
551 Discriminator.Offset = DTy->getOffsetInBits();
552 const auto *BaseTy = DTy->getBaseType();
553 Discriminator.Type = BDebug.
getTypeId(BaseTy);
555 Members.push_back(Discriminator);
560 const DINodeArray Elements = STy->getElements();
561 for (
const auto *Element : Elements) {
564 switch (Element->getTag()) {
565 case dwarf::DW_TAG_member: {
570 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
571 BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
573 BTFMember.
Offset = DDTy->getOffsetInBits();
579 case dwarf::DW_TAG_variant_part: {
583 BTFMember.
Offset = DCTy->getOffsetInBits();
590 Members.push_back(BTFMember);
596 for (
const auto &Member : Members) {
616 : STy(STy), FuncArgNames(FuncArgNames),
617 AliveParamIndices(AliveParamIndices),
618 UseFilteredParams(UseFilteredParams), VoidReturn(VoidReturn) {
619 Kind = BTF::BTF_KIND_FUNC_PROTO;
628 DITypeArray Elements = STy->getTypeArray();
641 auto It = FuncArgNames.find(
I);
643 It != FuncArgNames.end() ? BDebug.
addString(It->second) : 0;
649 Parameters.push_back(Param);
652 if (UseFilteredParams) {
658 for (
unsigned I = 1,
N = Elements.size();
I <
N; ++
I)
664 for (
const auto &Param : Parameters) {
673 Kind = BTF::BTF_KIND_FUNC;
690 Kind = BTF::BTF_KIND_VAR;
706 : Asm(AsmPrt), Name(SecName) {
707 Kind = BTF::BTF_KIND_DATASEC;
720 for (
const auto &V : Vars) {
722 Asm->emitLabelReference(std::get<1>(V), 4);
729 Kind = BTF::BTF_KIND_FLOAT;
745 Kind = BTF::BTF_KIND_DECL_TAG;
765 : DTy(nullptr), Tag(Tag) {
766 Kind = BTF::BTF_KIND_TYPE_TAG;
772 : DTy(DTy), Tag(Tag) {
773 Kind = BTF::BTF_KIND_TYPE_TAG;
793 for (
auto &OffsetM : OffsetToIdMap) {
794 if (Table[OffsetM.second] == S)
795 return OffsetM.first;
799 OffsetToIdMap[
Offset] = Table.size();
800 Table.push_back(std::string(S));
801 Size += S.
size() + 1;
807 LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0),
808 MapDefNotCollected(
true) {
812uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
814 TypeEntry->setId(TypeEntries.size() + 1);
817 TypeEntries.push_back(std::move(TypeEntry));
821uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
822 TypeEntry->setId(TypeEntries.size() + 1);
824 TypeEntries.push_back(std::move(TypeEntry));
828void BTFDebug::visitBasicType(
const DIBasicType *BTy, uint32_t &TypeId) {
833 case dwarf::DW_ATE_boolean:
834 case dwarf::DW_ATE_signed:
835 case dwarf::DW_ATE_signed_char:
836 case dwarf::DW_ATE_unsigned:
837 case dwarf::DW_ATE_unsigned_char:
838 case dwarf::DW_ATE_UTF:
841 TypeEntry = std::make_unique<BTFTypeInt>(
844 case dwarf::DW_ATE_float:
852 TypeId = addType(std::move(TypeEntry), BTy);
856void BTFDebug::visitSubroutineType(
861 uint32_t VLen =
Elements.size() - 1;
869 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
870 STy, VLen, FuncArgNames,
false, ArrayRef<uint32_t>(), VoidReturn);
872 TypeId = addType(std::move(TypeEntry));
874 TypeId = addType(std::move(TypeEntry), STy);
878 for (
const auto Element : Elements)
879 visitTypeEntry(Element);
882 visitTypeEntry(Elements[
I]);
886void BTFDebug::processDeclAnnotations(DINodeArray
Annotations,
892 for (
const Metadata *Annotation : Annotations->operands()) {
895 if (
Name->getString() !=
"btf_decl_tag")
899 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
901 addType(std::move(TypeEntry));
905uint32_t BTFDebug::processDISubprogram(
906 const DISubprogram *SP, uint32_t ProtoTypeId, uint8_t Scope,
909 std::make_unique<BTFTypeFunc>(
SP->getName(), ProtoTypeId, Scope);
910 uint32_t FuncId = addType(std::move(FuncTypeEntry));
913 for (
const DINode *DN :
SP->getRetainedNodes()) {
915 uint32_t Arg = DV->getArg();
918 auto It = ArgIndexMap->
find(Arg);
919 if (It != ArgIndexMap->
end())
920 processDeclAnnotations(DV->getAnnotations(), FuncId, It->second);
922 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
927 processDeclAnnotations(
SP->getAnnotations(), FuncId, -1);
933int BTFDebug::genBTFTypeTags(
const DIDerivedType *DTy,
int BaseTypeId) {
939 for (
const Metadata *Annotations : Annots->operands()) {
942 if (
Name->getString() !=
"btf_type_tag")
948 if (MDStrs.
size() == 0)
956 std::unique_ptr<BTFTypeTypeTag>
TypeEntry;
959 std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
961 TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
962 TmpTypeId = addType(std::move(TypeEntry));
964 for (
unsigned I = 1;
I < MDStrs.
size();
I++) {
965 const MDString *
Value = MDStrs[
I];
966 TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId,
Value->getString());
967 TmpTypeId = addType(std::move(TypeEntry));
973void BTFDebug::visitStructType(
const DICompositeType *CTy,
bool IsStruct,
980 if (CTy->
getTag() == dwarf::DW_TAG_variant_part) {
991 bool HasBitField =
false;
992 for (
const auto *Element : Elements) {
993 if (Element->getTag() == dwarf::DW_TAG_member) {
995 if (
E->isBitField()) {
1003 std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
1005 TypeId = addType(std::move(TypeEntry), CTy);
1012 for (
const auto *Element : Elements) {
1013 switch (Element->getTag()) {
1014 case dwarf::DW_TAG_member: {
1016 visitTypeEntry(Elem);
1017 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1020 case dwarf::DW_TAG_variant_part: {
1022 visitTypeEntry(Elem);
1023 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1033void BTFDebug::visitArrayType(
const DICompositeType *CTy, uint32_t &TypeId) {
1035 uint32_t ElemTypeId;
1037 visitTypeEntry(ElemType, ElemTypeId,
false,
false);
1044 auto TypeEntry = std::make_unique<BTFTypeArray>(ElemTypeId, 0);
1045 ElemTypeId = addType(std::move(TypeEntry), CTy);
1049 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
1052 int64_t
Count = CI->getSExtValue();
1057 std::make_unique<BTFTypeArray>(ElemTypeId,
1060 ElemTypeId = addType(std::move(TypeEntry), CTy);
1062 ElemTypeId = addType(std::move(TypeEntry));
1067 TypeId = ElemTypeId;
1071 if (!ArrayIndexTypeId) {
1072 auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
1073 0,
"__ARRAY_SIZE_TYPE__");
1074 ArrayIndexTypeId = addType(std::move(TypeEntry));
1078void BTFDebug::visitEnumType(
const DICompositeType *CTy, uint32_t &TypeId) {
1084 bool IsSigned =
false;
1085 unsigned NumBits = 32;
1090 IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
1095 if (NumBits <= 32) {
1096 auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
1097 TypeId = addType(std::move(TypeEntry), CTy);
1100 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
1101 TypeId = addType(std::move(TypeEntry), CTy);
1107void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion,
1110 TypeId = addType(std::move(TypeEntry), CTy);
1118 case dwarf::DW_TAG_structure_type:
1119 case dwarf::DW_TAG_union_type:
1120 case dwarf::DW_TAG_variant_part:
1123 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type, TypeId);
1125 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type, TypeId);
1127 case dwarf::DW_TAG_array_type:
1128 visitArrayType(CTy, TypeId);
1130 case dwarf::DW_TAG_enumeration_type:
1131 visitEnumType(CTy, TypeId);
1138bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
1140 auto CTag = CTy->
getTag();
1141 if ((CTag == dwarf::DW_TAG_structure_type ||
1142 CTag == dwarf::DW_TAG_union_type) &&
1150void BTFDebug::visitDerivedType(
const DIDerivedType *DTy, uint32_t &TypeId,
1151 bool CheckPointer,
bool SeenPointer) {
1154 if (
Tag == dwarf::DW_TAG_atomic_type)
1155 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
1160 if (CheckPointer && !SeenPointer) {
1164 if (CheckPointer && SeenPointer) {
1165 const DIType *
Base = DTy->getBaseType();
1167 if (IsForwardDeclCandidate(
Base)) {
1171 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
true);
1174 TypeId = addType(std::move(TypeEntry), DTy);
1180 if (
Tag == dwarf::DW_TAG_pointer_type ||
Tag == dwarf::DW_TAG_typedef) {
1181 int TmpTypeId = genBTFTypeTags(DTy, -1);
1182 if (TmpTypeId >= 0) {
1184 std::make_unique<BTFTypeDerived>(TmpTypeId,
Tag, DTy->
getName());
1185 TypeId = addType(std::move(TypeDEntry), DTy);
1187 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1188 TypeId = addType(std::move(TypeEntry), DTy);
1190 if (
Tag == dwarf::DW_TAG_typedef)
1192 }
else if (
Tag == dwarf::DW_TAG_const_type ||
1193 Tag == dwarf::DW_TAG_volatile_type ||
1194 Tag == dwarf::DW_TAG_restrict_type) {
1195 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1196 TypeId = addType(std::move(TypeEntry), DTy);
1197 }
else if (
Tag != dwarf::DW_TAG_member) {
1203 uint32_t TempTypeId = 0;
1204 if (
Tag == dwarf::DW_TAG_member)
1205 visitTypeEntry(DTy->getBaseType(), TempTypeId,
true,
false);
1207 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
1217void BTFDebug::visitTypeEntry(
const DIType *Ty, uint32_t &TypeId,
1218 bool CheckPointer,
bool SeenPointer) {
1219 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1220 TypeId = DIToIdMap[Ty];
1251 if (Ty && (!CheckPointer || !SeenPointer)) {
1254 const DIType *BaseTy = DTy->getBaseType();
1258 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1261 if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type &&
1264 if (IsForwardDeclCandidate(BaseTy))
1268 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1279 visitBasicType(BTy, TypeId);
1281 visitSubroutineType(STy,
false, SmallDenseMap<uint32_t, StringRef>(),
1284 visitCompositeType(CTy, TypeId);
1286 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
1291void BTFDebug::visitTypeEntry(
const DIType *Ty) {
1293 visitTypeEntry(Ty, TypeId,
false,
false);
1296void BTFDebug::visitMapDefType(
const DIType *Ty, uint32_t &TypeId) {
1297 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1298 TypeId = DIToIdMap[Ty];
1304 case dwarf::DW_TAG_typedef:
1305 case dwarf::DW_TAG_const_type:
1306 case dwarf::DW_TAG_volatile_type:
1307 case dwarf::DW_TAG_restrict_type:
1308 case dwarf::DW_TAG_pointer_type:
1311 case dwarf::DW_TAG_array_type:
1315 case dwarf::DW_TAG_structure_type: {
1319 for (
const auto *Element : Elements) {
1321 const DIType *MemberBaseType = MemberType->getBaseType();
1330 visitMapDefType(MemberBaseType, TmpId);
1332 visitTypeEntry(MemberBaseType);
1342 visitTypeEntry(Ty, TypeId,
false,
false);
1346std::string BTFDebug::populateFileContent(
const DIFile *File) {
1347 std::string FileName;
1349 if (!
File->getFilename().starts_with(
"/") &&
File->getDirectory().size())
1350 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
1352 FileName = std::string(
File->getFilename());
1355 if (FileContent.contains(FileName))
1358 std::vector<std::string> Content;
1360 Content.push_back(Line);
1362 auto LoadFile = [](StringRef FileName) {
1368 std::unique_ptr<MemoryBuffer> Buf;
1372 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = LoadFile(FileName))
1373 Buf = std::move(*BufOrErr);
1375 for (line_iterator
I(*Buf,
false),
E;
I !=
E; ++
I)
1376 Content.push_back(std::string(*
I));
1378 FileContent[FileName] = std::move(Content);
1382void BTFDebug::constructLineInfo(
MCSymbol *Label,
const DIFile *File,
1383 uint32_t Line, uint32_t Column) {
1384 std::string FileName = populateFileContent(File);
1385 BTFLineInfo LineInfo;
1390 const auto &Content = FileContent[FileName];
1391 if (Line < Content.size())
1397 LineInfoTable[SecNameOff].push_back(LineInfo);
1400void BTFDebug::emitCommonHeader() {
1407void BTFDebug::emitBTFSection() {
1409 if (!TypeEntries.size() && StringTable.getSize() == 1)
1412 MCContext &Ctx = OS.getContext();
1415 OS.switchSection(Sec);
1421 uint32_t TypeLen = 0, StrLen;
1422 for (
const auto &TypeEntry : TypeEntries)
1424 StrLen = StringTable.getSize();
1427 OS.emitInt32(TypeLen);
1428 OS.emitInt32(TypeLen);
1429 OS.emitInt32(StrLen);
1432 for (
const auto &TypeEntry : TypeEntries)
1436 uint32_t StringOffset = 0;
1437 for (
const auto &S : StringTable.getTable()) {
1438 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1440 OS.emitBytes(StringRef(
"\0", 1));
1441 StringOffset += S.size() + 1;
1445void BTFDebug::emitBTFExtSection() {
1448 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1449 !FieldRelocTable.size())
1452 MCContext &Ctx = OS.getContext();
1455 OS.switchSection(Sec);
1462 uint32_t FuncLen = 4, LineLen = 4;
1464 uint32_t FieldRelocLen = 0;
1465 for (
const auto &FuncSec : FuncInfoTable) {
1469 for (
const auto &LineSec : LineInfoTable) {
1473 for (
const auto &FieldRelocSec : FieldRelocTable) {
1482 OS.emitInt32(FuncLen);
1483 OS.emitInt32(FuncLen);
1484 OS.emitInt32(LineLen);
1485 OS.emitInt32(FuncLen + LineLen);
1486 OS.emitInt32(FieldRelocLen);
1489 OS.AddComment(
"FuncInfo");
1491 for (
const auto &FuncSec : FuncInfoTable) {
1492 OS.AddComment(
"FuncInfo section string offset=" +
1493 std::to_string(FuncSec.first));
1494 OS.emitInt32(FuncSec.first);
1495 OS.emitInt32(FuncSec.second.size());
1496 for (
const auto &FuncInfo : FuncSec.second) {
1497 Asm->emitLabelReference(FuncInfo.Label, 4);
1498 OS.emitInt32(FuncInfo.TypeId);
1503 OS.AddComment(
"LineInfo");
1505 for (
const auto &LineSec : LineInfoTable) {
1506 OS.AddComment(
"LineInfo section string offset=" +
1507 std::to_string(LineSec.first));
1508 OS.emitInt32(LineSec.first);
1509 OS.emitInt32(LineSec.second.size());
1510 for (
const auto &LineInfo : LineSec.second) {
1511 Asm->emitLabelReference(LineInfo.
Label, 4);
1513 OS.emitInt32(LineInfo.
LineOff);
1514 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1521 if (FieldRelocLen) {
1522 OS.AddComment(
"FieldReloc");
1524 for (
const auto &FieldRelocSec : FieldRelocTable) {
1525 OS.AddComment(
"Field reloc section string offset=" +
1526 std::to_string(FieldRelocSec.first));
1527 OS.emitInt32(FieldRelocSec.first);
1528 OS.emitInt32(FieldRelocSec.second.size());
1529 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1530 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1531 OS.emitInt32(FieldRelocInfo.TypeID);
1532 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1533 OS.emitInt32(FieldRelocInfo.RelocKind);
1541 auto *Unit = SP->getUnit();
1544 SkipInstruction =
true;
1547 SkipInstruction =
false;
1568 if (MapDefNotCollected) {
1569 processGlobals(
true);
1570 MapDefNotCollected =
false;
1577 for (
const DINode *DN : SP->getRetainedNodes()) {
1582 visitTypeEntry(DV->getType());
1583 FuncArgNames[Arg] = DV->getName();
1591 bool IsNocall = SP->getType()->getCC() == dwarf::DW_CC_nocall;
1592 bool UseFilteredParams =
false;
1600 DITypeArray Elements = SP->getType()->getTypeArray();
1608 if (UseFilteredParams) {
1612 AliveParamIndices.
push_back(ArgReg.first);
1613 ArgIndexMap[ArgReg.first] =
I;
1617 visitTypeEntry(Elements[0]);
1618 for (
uint32_t ArgNo : AliveParamIndices)
1619 visitTypeEntry(Elements[ArgNo]);
1621 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
1622 SP->getType(), AliveParamIndices.
size(), FuncArgNames,
true,
1623 AliveParamIndices, VoidReturn);
1624 ProtoTypeId = addType(std::move(TypeEntry));
1625 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope, &ArgIndexMap);
1629 if (!UseFilteredParams) {
1632 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId,
1634 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1637 for (
const auto &TypeEntry : TypeEntries)
1638 TypeEntry->completeType(*
this);
1643 FuncInfo.
Label = FuncLabel;
1644 FuncInfo.
TypeId = FuncTypeId;
1651 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1655 SkipInstruction =
false;
1656 LineInfoGenerated =
false;
1662unsigned BTFDebug::populateType(
const DIType *Ty) {
1664 visitTypeEntry(Ty, Id,
false,
false);
1665 for (
const auto &TypeEntry : TypeEntries)
1666 TypeEntry->completeType(*
this);
1671void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1674 FieldReloc.
Label = ORSym;
1675 FieldReloc.
TypeID = RootId;
1681 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
1684 SecondColon - FirstColon);
1686 FirstDollar - SecondColon);
1689 FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
1690 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1693 StringRef RelocStr = AccessPattern.
substr(FirstDollar + 1);
1695 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1696 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1698 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1704 const GlobalValue *GVal = MO.
getGlobal();
1716 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1717 OS.emitLabel(ORSym);
1719 MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
1721 generatePatchImmReloc(ORSym, RootId, GVar,
1729 if (SkipInstruction ||
MI->isMetaInstruction() ||
1733 if (
MI->isInlineAsm()) {
1735 unsigned NumDefs = 0;
1750 if (
MI->getOpcode() == BPF::LD_imm64) {
1765 processGlobalValue(
MI->getOperand(1));
1766 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1767 MI->getOpcode() == BPF::CORE_LD32 ||
1768 MI->getOpcode() == BPF::CORE_ST ||
1769 MI->getOpcode() == BPF::CORE_SHIFT) {
1771 processGlobalValue(
MI->getOperand(3));
1772 }
else if (
MI->getOpcode() == BPF::JAL) {
1789 if (LineInfoGenerated ==
false) {
1790 auto *S =
MI->getMF()->getFunction().getSubprogram();
1794 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1795 LineInfoGenerated =
true;
1802 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1803 OS.emitLabel(LineSym);
1806 constructLineInfo(LineSym,
DL->getFile(),
DL.getLine(),
DL.getCol());
1808 LineInfoGenerated =
true;
1812void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1818 std::optional<SectionKind> GVKind;
1820 if (!
Global.isDeclarationForLinker())
1823 if (
Global.isDeclarationForLinker())
1824 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1825 else if (GVKind->isCommon())
1833 if (ProcessingMapDef != SecName.
starts_with(
".maps"))
1839 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1840 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1842 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1843 DataSecEntries[std::string(SecName)] =
1844 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1849 Global.getDebugInfo(GVs);
1852 if (GVs.
size() == 0)
1855 uint32_t GVTypeId = 0;
1856 DIGlobalVariable *DIGlobal =
nullptr;
1857 for (
auto *GVE : GVs) {
1858 DIGlobal = GVE->getVariable();
1860 visitMapDefType(DIGlobal->
getType(), GVTypeId);
1863 visitTypeEntry(Ty, GVTypeId,
false,
false);
1886 }
else if (
Global.hasInitializer()) {
1893 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1894 uint32_t VarId = addType(std::move(VarEntry));
1899 if (SecName.
empty())
1903 auto [It,
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1905 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1908 const DataLayout &
DL =
Global.getDataLayout();
1911 It->second->addDataSecEntry(VarId,
Asm->getSymbol(&
Global),
Size);
1913 if (
Global.hasInitializer())
1914 processGlobalInitializer(
Global.getInitializer());
1929void BTFDebug::processGlobalInitializer(
const Constant *
C) {
1931 processFuncPrototypes(Fn);
1933 for (
unsigned I = 0,
N = CA->getNumOperands();
I <
N; ++
I)
1934 processGlobalInitializer(CA->getOperand(
I));
1940 if (
MI->getOpcode() == BPF::LD_imm64) {
1951 auto [Imm,
Reloc] = PatchImms[GVar];
1962 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1963 MI->getOpcode() == BPF::CORE_LD32 ||
1964 MI->getOpcode() == BPF::CORE_ST ||
1965 MI->getOpcode() == BPF::CORE_SHIFT) {
1971 uint32_t Imm = PatchImms[GVar].first;
1973 if (
MI->getOperand(0).isImm())
1986void BTFDebug::processFuncPrototypes(
const Function *
F) {
1991 if (!SP || SP->isDefinition())
1995 if (!ProtoFunctions.insert(
F).second)
2000 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
2003 if (
F->hasSection()) {
2006 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
2008 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
2017 if (MapDefNotCollected) {
2018 processGlobals(
true);
2019 MapDefNotCollected =
false;
2023 processGlobals(
false);
2029 processFuncPrototypes(&
F);
2032 for (
auto &DataSec : DataSecEntries)
2033 addType(std::move(DataSec.second));
2036 for (
auto &
Fixup : FixupDerivedTypes) {
2039 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
2050 if (StructTypeId == 0) {
2051 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
2052 StructTypeId = addType(std::move(FwdTypeEntry));
2055 for (
auto &TypeInfo :
Fixup.second) {
2059 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
2068 for (
const auto &TypeEntry : TypeEntries)
2069 TypeEntry->completeType(*
this);
2073 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< 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,...
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, 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.
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.
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.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
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.
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.
@ C
The default llvm calling convention, compatible with C.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
ScopedSetting scopedDisable()
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
auto dyn_cast_or_null(const Y &Val)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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<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::...