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 = [](StringRef FileName) {
1379 std::unique_ptr<MemoryBuffer> Buf;
1383 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = LoadFile(FileName))
1384 Buf = std::move(*BufOrErr);
1386 for (line_iterator
I(*Buf,
false),
E;
I !=
E; ++
I)
1387 Content.push_back(std::string(*
I));
1389 FileContent[FileName] = std::move(Content);
1393void BTFDebug::constructLineInfo(
MCSymbol *Label,
const DIFile *File,
1394 uint32_t Line, uint32_t Column) {
1395 std::string FileName = populateFileContent(File);
1396 BTFLineInfo LineInfo;
1401 const auto &Content = FileContent[FileName];
1402 if (Line < Content.size())
1408 LineInfoTable[SecNameOff].push_back(LineInfo);
1411void BTFDebug::emitCommonHeader() {
1418void BTFDebug::emitBTFSection() {
1420 if (!TypeEntries.size() && StringTable.getSize() == 1)
1423 MCContext &Ctx = OS.getContext();
1426 OS.switchSection(Sec);
1432 uint32_t TypeLen = 0, StrLen;
1433 for (
const auto &TypeEntry : TypeEntries)
1435 StrLen = StringTable.getSize();
1438 OS.emitInt32(TypeLen);
1439 OS.emitInt32(TypeLen);
1440 OS.emitInt32(StrLen);
1443 for (
const auto &TypeEntry : TypeEntries)
1447 uint32_t StringOffset = 0;
1448 for (
const auto &S : StringTable.getTable()) {
1449 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1451 OS.emitBytes(StringRef(
"\0", 1));
1452 StringOffset += S.size() + 1;
1456void BTFDebug::emitBTFExtSection() {
1459 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1460 !FieldRelocTable.size())
1463 MCContext &Ctx = OS.getContext();
1466 OS.switchSection(Sec);
1473 uint32_t FuncLen = 4, LineLen = 4;
1475 uint32_t FieldRelocLen = 0;
1476 for (
const auto &FuncSec : FuncInfoTable) {
1480 for (
const auto &LineSec : LineInfoTable) {
1484 for (
const auto &FieldRelocSec : FieldRelocTable) {
1493 OS.emitInt32(FuncLen);
1494 OS.emitInt32(FuncLen);
1495 OS.emitInt32(LineLen);
1496 OS.emitInt32(FuncLen + LineLen);
1497 OS.emitInt32(FieldRelocLen);
1500 OS.AddComment(
"FuncInfo");
1502 for (
const auto &FuncSec : FuncInfoTable) {
1503 OS.AddComment(
"FuncInfo section string offset=" +
1504 std::to_string(FuncSec.first));
1505 OS.emitInt32(FuncSec.first);
1506 OS.emitInt32(FuncSec.second.size());
1507 for (
const auto &FuncInfo : FuncSec.second) {
1508 Asm->emitLabelReference(FuncInfo.Label, 4);
1509 OS.emitInt32(FuncInfo.TypeId);
1514 OS.AddComment(
"LineInfo");
1516 for (
const auto &LineSec : LineInfoTable) {
1517 OS.AddComment(
"LineInfo section string offset=" +
1518 std::to_string(LineSec.first));
1519 OS.emitInt32(LineSec.first);
1520 OS.emitInt32(LineSec.second.size());
1521 for (
const auto &LineInfo : LineSec.second) {
1522 Asm->emitLabelReference(LineInfo.
Label, 4);
1524 OS.emitInt32(LineInfo.
LineOff);
1525 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1532 if (FieldRelocLen) {
1533 OS.AddComment(
"FieldReloc");
1535 for (
const auto &FieldRelocSec : FieldRelocTable) {
1536 OS.AddComment(
"Field reloc section string offset=" +
1537 std::to_string(FieldRelocSec.first));
1538 OS.emitInt32(FieldRelocSec.first);
1539 OS.emitInt32(FieldRelocSec.second.size());
1540 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1541 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1542 OS.emitInt32(FieldRelocInfo.TypeID);
1543 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1544 OS.emitInt32(FieldRelocInfo.RelocKind);
1552 auto *Unit = SP->getUnit();
1555 SkipInstruction =
true;
1558 SkipInstruction =
false;
1579 if (MapDefNotCollected) {
1580 processGlobals(
true);
1581 MapDefNotCollected =
false;
1588 for (
const MDNode *DN : SP->getRetainedNodes()) {
1593 visitTypeEntry(DV->getType());
1594 FuncArgNames[Arg] = DV->getName();
1602 bool IsNocall = SP->getType()->getCC() == dwarf::DW_CC_nocall;
1603 bool UseFilteredParams =
false;
1611 DITypeArray Elements = SP->getType()->getTypeArray();
1619 if (UseFilteredParams) {
1623 AliveParamIndices.
push_back(ArgReg.first);
1624 ArgIndexMap[ArgReg.first] =
I;
1628 visitTypeEntry(Elements[0]);
1629 for (
uint32_t ArgNo : AliveParamIndices)
1630 visitTypeEntry(Elements[ArgNo]);
1632 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
1633 SP->getType(), AliveParamIndices.
size(), FuncArgNames,
true,
1634 AliveParamIndices, VoidReturn);
1635 ProtoTypeId = addType(std::move(TypeEntry));
1636 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope, &ArgIndexMap);
1640 if (!UseFilteredParams) {
1643 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId,
1645 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1648 for (
const auto &TypeEntry : TypeEntries)
1649 TypeEntry->completeType(*
this);
1654 FuncInfo.
Label = FuncLabel;
1655 FuncInfo.
TypeId = FuncTypeId;
1662 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1666 SkipInstruction =
false;
1667 LineInfoGenerated =
false;
1673unsigned BTFDebug::populateType(
const DIType *Ty) {
1675 visitTypeEntry(Ty, Id,
false,
false);
1676 for (
const auto &TypeEntry : TypeEntries)
1677 TypeEntry->completeType(*
this);
1682void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1685 FieldReloc.
Label = ORSym;
1686 FieldReloc.
TypeID = RootId;
1692 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
1695 SecondColon - FirstColon);
1697 FirstDollar - SecondColon);
1700 FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
1701 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1704 StringRef RelocStr = AccessPattern.
substr(FirstDollar + 1);
1706 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1707 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1709 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1715 const GlobalValue *GVal = MO.
getGlobal();
1727 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1728 OS.emitLabel(ORSym);
1730 MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
1732 generatePatchImmReloc(ORSym, RootId, GVar,
1740 if (SkipInstruction ||
MI->isMetaInstruction() ||
1744 if (
MI->isInlineAsm()) {
1746 unsigned NumDefs = 0;
1761 if (
MI->getOpcode() == BPF::LD_imm64) {
1776 processGlobalValue(
MI->getOperand(1));
1777 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1778 MI->getOpcode() == BPF::CORE_LD32 ||
1779 MI->getOpcode() == BPF::CORE_ST ||
1780 MI->getOpcode() == BPF::CORE_SHIFT) {
1782 processGlobalValue(
MI->getOperand(3));
1783 }
else if (
MI->getOpcode() == BPF::JAL) {
1800 if (LineInfoGenerated ==
false) {
1801 auto *S =
MI->getMF()->getFunction().getSubprogram();
1805 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1806 LineInfoGenerated =
true;
1813 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1814 OS.emitLabel(LineSym);
1817 constructLineInfo(LineSym,
DL->getFile(),
DL.getLine(),
DL.getCol());
1819 LineInfoGenerated =
true;
1823void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1829 std::optional<SectionKind> GVKind;
1831 if (!
Global.isDeclarationForLinker())
1834 if (
Global.isDeclarationForLinker())
1835 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1836 else if (GVKind->isCommon())
1844 if (ProcessingMapDef != SecName.
starts_with(
".maps"))
1850 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1851 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1853 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1854 DataSecEntries[std::string(SecName)] =
1855 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1860 Global.getDebugInfo(GVs);
1863 if (GVs.
size() == 0)
1866 uint32_t GVTypeId = 0;
1867 DIGlobalVariable *DIGlobal =
nullptr;
1868 for (
auto *GVE : GVs) {
1869 DIGlobal = GVE->getVariable();
1871 visitMapDefType(DIGlobal->
getType(), GVTypeId);
1874 visitTypeEntry(Ty, GVTypeId,
false,
false);
1897 }
else if (
Global.hasInitializer()) {
1904 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1905 uint32_t VarId = addType(std::move(VarEntry));
1910 if (SecName.
empty())
1914 auto [It,
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1916 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1919 const DataLayout &
DL =
Global.getDataLayout();
1922 It->second->addDataSecEntry(VarId,
Asm->getSymbol(&
Global),
Size);
1924 if (
Global.hasInitializer())
1925 processGlobalInitializer(
Global.getInitializer());
1940void BTFDebug::processGlobalInitializer(
const Constant *
C) {
1942 processFuncPrototypes(Fn);
1944 for (
unsigned I = 0,
N = CA->getNumOperands();
I <
N; ++
I)
1945 processGlobalInitializer(CA->getOperand(
I));
1951 if (
MI->getOpcode() == BPF::LD_imm64) {
1962 auto [
Imm,
Reloc] = PatchImms[GVar];
1973 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1974 MI->getOpcode() == BPF::CORE_LD32 ||
1975 MI->getOpcode() == BPF::CORE_ST ||
1976 MI->getOpcode() == BPF::CORE_SHIFT) {
1984 if (
MI->getOperand(0).isImm())
1997void BTFDebug::processFuncPrototypes(
const Function *
F) {
2002 if (!SP || SP->isDefinition())
2006 if (!ProtoFunctions.insert(
F).second)
2011 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
2014 if (
F->hasSection()) {
2017 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
2019 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
2028 if (MapDefNotCollected) {
2029 processGlobals(
true);
2030 MapDefNotCollected =
false;
2034 processGlobals(
false);
2040 processFuncPrototypes(&
F);
2043 for (
auto &DataSec : DataSecEntries)
2044 addType(std::move(DataSec.second));
2047 for (
auto &
Fixup : FixupDerivedTypes) {
2050 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
2061 if (StructTypeId == 0) {
2062 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
2063 StructTypeId = addType(std::move(FwdTypeEntry));
2066 for (
auto &TypeInfo :
Fixup.second) {
2070 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
2079 for (
const auto &TypeEntry : TypeEntries)
2080 TypeEntry->completeType(*
this);
2084 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.
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.
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.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
ScopedSetting scopedDisable()
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::...