45#define DEBUG_TYPE "btf-debug"
47#define GET_CC_REGISTER_LISTS
48#include "BPFGenCallingConv.inc"
51#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
52#include "llvm/DebugInfo/BTF/BTF.def"
59 if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
60 return DerivedTy->getBaseType();
66 switch (DTy->getTag()) {
67 case dwarf::DW_TAG_atomic_type:
68 case dwarf::DW_TAG_const_type:
69 case dwarf::DW_TAG_restrict_type:
70 case dwarf::DW_TAG_typedef:
71 case dwarf::DW_TAG_volatile_type:
72 Ty = DTy->getBaseType();
87 return DTy->getTag() == dwarf::DW_TAG_pointer_type && IRTy->
isPointerTy();
90 uint64_t SizeInBits = BTy->getSizeInBits();
91 if (BTy->getEncoding() == dwarf::DW_ATE_float)
95 if (BTy->getEncoding() == dwarf::DW_ATE_boolean && IRTy->
isIntegerTy(1))
104 switch (CTy->getTag()) {
105 case dwarf::DW_TAG_enumeration_type:
147 if (
MI.isDebugValue()) {
150 if (
MI.isIndirectDebugValue())
171 if (
MI.mayStore() && !
MI.isCall() &&
MI.getOperand(0).isReg()) {
175 const Value *
V = MMO->getValue();
178 auto It = AllocaToFI.
find(
V);
179 if (It != AllocaToFI.
end())
186 if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical()) {
187 DefinedRegs.
insert(MO.getReg());
188 StackLoadRegs.
erase(MO.getReg());
192 if (
MI.getOpcode() == BPF::LDD &&
MI.getOperand(1).getReg() == BPF::R11)
193 StackLoadRegs.
insert(
MI.getOperand(0).getReg());
200 if (!VI.Var || !VI.Var->getArg() || !VI.inStackSlot())
202 if (VI.Var->getScope()->getSubprogram() != SP)
205 if (EntryRegMap.
count(Arg))
207 auto It = FrameIndexToReg.
find(VI.getStackSlot());
208 if (It != FrameIndexToReg.
end())
209 EntryRegMap[Arg] = It->second;
224 ArrayRef<std::pair<uint32_t, Register>> AliveArgs,
229 << AliveArgs.size() <<
")\n");
234 for (
unsigned I = 0,
N = AliveArgs.size();
I <
N; ++
I, ++ArgIt) {
235 auto [ArgNo,
Reg] = AliveArgs[
I];
238 <<
": type mismatch for source arg " << ArgNo
239 <<
" at IR position " <<
I <<
"\n");
243 if (
I >= std::size(CC_BPF64_ArgRegs))
246 int DwarfReg =
TRI.getDwarfRegNum(
Reg,
false);
247 if (DwarfReg !=
static_cast<int>(
I + 1)) {
249 <<
" in DWARF reg " << DwarfReg <<
", expected "
270 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->
getName()) {
272 case dwarf::DW_TAG_pointer_type:
273 Kind = BTF::BTF_KIND_PTR;
275 case dwarf::DW_TAG_const_type:
276 Kind = BTF::BTF_KIND_CONST;
278 case dwarf::DW_TAG_volatile_type:
279 Kind = BTF::BTF_KIND_VOLATILE;
281 case dwarf::DW_TAG_typedef:
282 Kind = BTF::BTF_KIND_TYPEDEF;
284 case dwarf::DW_TAG_restrict_type:
285 Kind = BTF::BTF_KIND_RESTRICT;
296 : DTy(nullptr), NeedsFixup(
false), Name(Name) {
298 case dwarf::DW_TAG_pointer_type:
299 Kind = BTF::BTF_KIND_PTR;
301 case dwarf::DW_TAG_typedef:
302 Kind = BTF::BTF_KIND_TYPEDEF;
318 case BTF::BTF_KIND_PTR:
319 case BTF::BTF_KIND_CONST:
320 case BTF::BTF_KIND_VOLATILE:
321 case BTF::BTF_KIND_RESTRICT:
336 if (NeedsFixup || !DTy)
352 Kind = BTF::BTF_KIND_FWD;
373 case dwarf::DW_ATE_boolean:
376 case dwarf::DW_ATE_signed:
377 case dwarf::DW_ATE_signed_char:
380 case dwarf::DW_ATE_unsigned:
381 case dwarf::DW_ATE_unsigned_char:
382 case dwarf::DW_ATE_UTF:
389 Kind = BTF::BTF_KIND_INT;
392 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
410 bool IsSigned) : ETy(ETy) {
411 Kind = BTF::BTF_KIND_ENUM;
423 DINodeArray Elements = ETy->getElements();
424 for (
const auto Element : Elements) {
431 if (Enum->isUnsigned())
432 Value =
static_cast<uint32_t>(Enum->getValue().getZExtValue());
434 Value =
static_cast<uint32_t>(Enum->getValue().getSExtValue());
436 EnumValues.push_back(BTFEnum);
442 for (
const auto &Enum : EnumValues) {
449 bool IsSigned) : ETy(ETy) {
450 Kind = BTF::BTF_KIND_ENUM64;
462 DINodeArray Elements = ETy->getElements();
463 for (
const auto Element : Elements) {
469 if (Enum->isUnsigned())
470 Value = Enum->getValue().getZExtValue();
472 Value =
static_cast<uint64_t
>(Enum->getValue().getSExtValue());
475 EnumValues.push_back(BTFEnum);
481 for (
const auto &Enum : EnumValues) {
491 Kind = BTF::BTF_KIND_ARRAY;
496 ArrayInfo.ElemType = ElemTypeId;
497 ArrayInfo.Nelems = NumElems;
524 : STy(STy), Elements(Elements.begin(), Elements.end()),
525 HasBitField(HasBitField) {
526 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
528 BTFType.Info = (HasBitField << 31) | (
Kind << 24) | Vlen;
538 if (STy->getTag() == dwarf::DW_TAG_variant_part) {
547 const auto *DTy = STy->getDiscriminator();
551 Discriminator.NameOff = BDebug.
addString(DTy->getName());
552 Discriminator.Offset = DTy->getOffsetInBits();
553 const auto *BaseTy = DTy->getBaseType();
554 Discriminator.Type = BDebug.
getTypeId(BaseTy);
556 Members.push_back(Discriminator);
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 MDNode *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,
979 if (CTy->
getTag() == dwarf::DW_TAG_structure_type)
987 if (CTy->
getTag() == dwarf::DW_TAG_variant_part) {
998 bool HasBitField =
false;
999 for (
const auto *Element : Elements) {
1000 if (Element->getTag() == dwarf::DW_TAG_member) {
1002 if (
E->isBitField()) {
1009 auto TypeEntry = std::make_unique<BTFTypeStruct>(CTy, Elements, IsStruct,
1012 TypeId = addType(std::move(TypeEntry), CTy);
1019 for (
const auto *Element : Elements) {
1020 switch (Element->getTag()) {
1021 case dwarf::DW_TAG_member: {
1023 visitTypeEntry(Elem);
1024 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1027 case dwarf::DW_TAG_variant_part: {
1029 visitTypeEntry(Elem);
1030 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1048 "BTF array dimension requires a constant element count");
1052 if (
Count->isMinusOne())
1054 if (!
Count->getValue().isIntN(32)) {
1055 Ctx.reportError({},
"BTF array length exceeds the 32-bit limit");
1058 return Count->getZExtValue();
1061void BTFDebug::visitArrayType(
const DICompositeType *CTy, uint32_t &TypeId) {
1063 uint32_t ElemTypeId = 0;
1065 visitTypeEntry(ElemType, ElemTypeId,
false,
false);
1067 SmallString<128> Message;
1068 raw_svector_ostream Err(Message);
1069 Err <<
"unsupported BTF array element type";
1071 Err <<
" '" << ElemType->
getName() <<
'\'';
1072 OS.getContext().reportError({}, Message);
1081 ElemTypeId = addType(std::make_unique<BTFTypeArray>(ElemTypeId,
Count));
1084 const uint32_t OuterCount =
1086 TypeId = addType(std::make_unique<BTFTypeArray>(ElemTypeId, OuterCount), CTy);
1090 if (!ArrayIndexTypeId) {
1091 auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
1092 0,
"__ARRAY_SIZE_TYPE__");
1093 ArrayIndexTypeId = addType(std::move(TypeEntry));
1097void BTFDebug::visitEnumType(
const DICompositeType *CTy, uint32_t &TypeId) {
1103 bool IsSigned =
false;
1104 unsigned NumBits = 32;
1109 IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
1114 if (NumBits <= 32) {
1115 auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
1116 TypeId = addType(std::move(TypeEntry), CTy);
1119 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
1120 TypeId = addType(std::move(TypeEntry), CTy);
1126void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion,
1129 TypeId = addType(std::move(TypeEntry), CTy);
1137 case dwarf::DW_TAG_structure_type:
1138 case dwarf::DW_TAG_union_type:
1139 case dwarf::DW_TAG_variant_part:
1142 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type, TypeId);
1144 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type, TypeId);
1146 case dwarf::DW_TAG_array_type:
1147 visitArrayType(CTy, TypeId);
1149 case dwarf::DW_TAG_enumeration_type:
1150 visitEnumType(CTy, TypeId);
1157bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
1159 auto CTag = CTy->
getTag();
1160 if ((CTag == dwarf::DW_TAG_structure_type ||
1161 CTag == dwarf::DW_TAG_union_type) &&
1169void BTFDebug::visitDerivedType(
const DIDerivedType *DTy, uint32_t &TypeId,
1170 bool CheckPointer,
bool SeenPointer) {
1173 if (
Tag == dwarf::DW_TAG_atomic_type)
1174 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
1179 if (CheckPointer && !SeenPointer) {
1183 if (CheckPointer && SeenPointer) {
1184 const DIType *
Base = DTy->getBaseType();
1186 if (IsForwardDeclCandidate(
Base)) {
1190 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
true);
1193 TypeId = addType(std::move(TypeEntry), DTy);
1199 if (
Tag == dwarf::DW_TAG_pointer_type ||
Tag == dwarf::DW_TAG_typedef) {
1200 int TmpTypeId = genBTFTypeTags(DTy, -1);
1201 if (TmpTypeId >= 0) {
1203 std::make_unique<BTFTypeDerived>(TmpTypeId,
Tag, DTy->
getName());
1204 TypeId = addType(std::move(TypeDEntry), DTy);
1206 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1207 TypeId = addType(std::move(TypeEntry), DTy);
1209 if (
Tag == dwarf::DW_TAG_typedef)
1211 }
else if (
Tag == dwarf::DW_TAG_const_type ||
1212 Tag == dwarf::DW_TAG_volatile_type ||
1213 Tag == dwarf::DW_TAG_restrict_type) {
1214 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1215 TypeId = addType(std::move(TypeEntry), DTy);
1216 }
else if (
Tag != dwarf::DW_TAG_member) {
1222 uint32_t TempTypeId = 0;
1223 if (
Tag == dwarf::DW_TAG_member)
1224 visitTypeEntry(DTy->getBaseType(), TempTypeId,
true,
false);
1226 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
1236void BTFDebug::visitTypeEntry(
const DIType *Ty, uint32_t &TypeId,
1237 bool CheckPointer,
bool SeenPointer) {
1238 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1239 TypeId = DIToIdMap[Ty];
1270 if (Ty && (!CheckPointer || !SeenPointer)) {
1273 const DIType *BaseTy = DTy->getBaseType();
1277 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1280 if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type &&
1283 if (IsForwardDeclCandidate(BaseTy))
1287 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1298 visitBasicType(BTy, TypeId);
1300 visitSubroutineType(STy,
false, SmallDenseMap<uint32_t, StringRef>(),
1303 visitCompositeType(CTy, TypeId);
1305 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
1310void BTFDebug::visitTypeEntry(
const DIType *Ty) {
1312 visitTypeEntry(Ty, TypeId,
false,
false);
1315void BTFDebug::visitMapDefType(
const DIType *Ty, uint32_t &TypeId) {
1316 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1317 TypeId = DIToIdMap[Ty];
1323 case dwarf::DW_TAG_typedef:
1324 case dwarf::DW_TAG_const_type:
1325 case dwarf::DW_TAG_volatile_type:
1326 case dwarf::DW_TAG_restrict_type:
1327 case dwarf::DW_TAG_pointer_type:
1330 case dwarf::DW_TAG_array_type:
1334 case dwarf::DW_TAG_structure_type: {
1338 for (
const auto *Element : Elements) {
1340 const DIType *MemberBaseType = MemberType->getBaseType();
1349 visitMapDefType(MemberBaseType, TmpId);
1351 visitTypeEntry(MemberBaseType);
1361 visitTypeEntry(Ty, TypeId,
false,
false);
1365std::string BTFDebug::populateFileContent(
const DIFile *File) {
1366 std::string FileName;
1368 if (!
File->getFilename().starts_with(
"/") &&
File->getDirectory().size())
1369 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
1371 FileName = std::string(
File->getFilename());
1374 if (FileContent.contains(FileName))
1377 std::vector<std::string> Content;
1379 Content.push_back(Line);
1381 auto LoadFile = [&
File](StringRef FileName) {
1382 return File->getContext().getVirtualFileSystem().getBufferForFile(FileName);
1385 std::unique_ptr<MemoryBuffer> Buf;
1389 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = LoadFile(FileName))
1390 Buf = std::move(*BufOrErr);
1392 for (line_iterator
I(*Buf,
false),
E;
I !=
E; ++
I)
1393 Content.push_back(std::string(*
I));
1395 FileContent[FileName] = std::move(Content);
1399void BTFDebug::constructLineInfo(
MCSymbol *Label,
const DIFile *File,
1400 uint32_t Line, uint32_t Column) {
1401 std::string FileName = populateFileContent(File);
1402 BTFLineInfo LineInfo;
1407 const auto &Content = FileContent[FileName];
1408 if (Line < Content.size())
1414 LineInfoTable[SecNameOff].push_back(LineInfo);
1417void BTFDebug::emitCommonHeader() {
1424void BTFDebug::emitBTFSection() {
1426 if (!TypeEntries.size() && StringTable.getSize() == 1)
1429 MCContext &Ctx = OS.getContext();
1432 OS.switchSection(Sec);
1438 uint32_t TypeLen = 0, StrLen;
1439 for (
const auto &TypeEntry : TypeEntries)
1441 StrLen = StringTable.getSize();
1444 OS.emitInt32(TypeLen);
1445 OS.emitInt32(TypeLen);
1446 OS.emitInt32(StrLen);
1449 for (
const auto &TypeEntry : TypeEntries)
1453 uint32_t StringOffset = 0;
1454 for (
const auto &S : StringTable.getTable()) {
1455 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1457 OS.emitBytes(StringRef(
"\0", 1));
1458 StringOffset += S.size() + 1;
1462void BTFDebug::emitBTFExtSection() {
1465 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1466 !FieldRelocTable.size())
1469 MCContext &Ctx = OS.getContext();
1472 OS.switchSection(Sec);
1479 uint32_t FuncLen = 4, LineLen = 4;
1481 uint32_t FieldRelocLen = 0;
1482 for (
const auto &FuncSec : FuncInfoTable) {
1486 for (
const auto &LineSec : LineInfoTable) {
1490 for (
const auto &FieldRelocSec : FieldRelocTable) {
1499 OS.emitInt32(FuncLen);
1500 OS.emitInt32(FuncLen);
1501 OS.emitInt32(LineLen);
1502 OS.emitInt32(FuncLen + LineLen);
1503 OS.emitInt32(FieldRelocLen);
1506 OS.AddComment(
"FuncInfo");
1508 for (
const auto &FuncSec : FuncInfoTable) {
1509 OS.AddComment(
"FuncInfo section string offset=" +
1510 std::to_string(FuncSec.first));
1511 OS.emitInt32(FuncSec.first);
1512 OS.emitInt32(FuncSec.second.size());
1513 for (
const auto &FuncInfo : FuncSec.second) {
1514 Asm->emitLabelReference(FuncInfo.Label, 4);
1515 OS.emitInt32(FuncInfo.TypeId);
1520 OS.AddComment(
"LineInfo");
1522 for (
const auto &LineSec : LineInfoTable) {
1523 OS.AddComment(
"LineInfo section string offset=" +
1524 std::to_string(LineSec.first));
1525 OS.emitInt32(LineSec.first);
1526 OS.emitInt32(LineSec.second.size());
1527 for (
const auto &LineInfo : LineSec.second) {
1528 Asm->emitLabelReference(LineInfo.
Label, 4);
1530 OS.emitInt32(LineInfo.
LineOff);
1531 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1538 if (FieldRelocLen) {
1539 OS.AddComment(
"FieldReloc");
1541 for (
const auto &FieldRelocSec : FieldRelocTable) {
1542 OS.AddComment(
"Field reloc section string offset=" +
1543 std::to_string(FieldRelocSec.first));
1544 OS.emitInt32(FieldRelocSec.first);
1545 OS.emitInt32(FieldRelocSec.second.size());
1546 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1547 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1548 OS.emitInt32(FieldRelocInfo.TypeID);
1549 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1550 OS.emitInt32(FieldRelocInfo.RelocKind);
1558 auto *Unit = SP->getUnit();
1561 SkipInstruction =
true;
1564 SkipInstruction =
false;
1585 if (MapDefNotCollected) {
1586 processGlobals(
true);
1587 MapDefNotCollected =
false;
1594 for (
const MDNode *DN : SP->getRetainedNodes()) {
1599 visitTypeEntry(DV->getType());
1600 FuncArgNames[Arg] = DV->getName();
1608 bool IsNocall = SP->getType()->getCC() == dwarf::DW_CC_nocall;
1609 bool UseFilteredParams =
false;
1617 DITypeArray Elements = SP->getType()->getTypeArray();
1625 if (UseFilteredParams) {
1629 AliveParamIndices.
push_back(ArgReg.first);
1630 ArgIndexMap[ArgReg.first] =
I;
1634 visitTypeEntry(Elements[0]);
1635 for (
uint32_t ArgNo : AliveParamIndices)
1636 visitTypeEntry(Elements[ArgNo]);
1638 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
1639 SP->getType(), AliveParamIndices.
size(), FuncArgNames,
true,
1640 AliveParamIndices, VoidReturn);
1641 ProtoTypeId = addType(std::move(TypeEntry));
1642 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope, &ArgIndexMap);
1646 if (!UseFilteredParams) {
1649 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId,
1651 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1654 for (
const auto &TypeEntry : TypeEntries)
1655 TypeEntry->completeType(*
this);
1660 FuncInfo.
Label = FuncLabel;
1661 FuncInfo.
TypeId = FuncTypeId;
1668 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1672 SkipInstruction =
false;
1673 LineInfoGenerated =
false;
1679unsigned BTFDebug::populateType(
const DIType *Ty) {
1681 visitTypeEntry(Ty, Id,
false,
false);
1682 for (
const auto &TypeEntry : TypeEntries)
1683 TypeEntry->completeType(*
this);
1688void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1691 FieldReloc.
Label = ORSym;
1692 FieldReloc.
TypeID = RootId;
1698 PatchImms[GVar] = {
Reloc.PatchImm,
Reloc.Kind};
1700 StringRef RelocStr = GVar->
getName().
split(
'$').second;
1702 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1703 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1705 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1711 const GlobalValue *GVal = MO.
getGlobal();
1723 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1724 OS.emitLabel(ORSym);
1726 MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
1728 generatePatchImmReloc(ORSym, RootId, GVar,
1736 if (SkipInstruction ||
MI->isMetaInstruction() ||
1740 if (
MI->isInlineAsm()) {
1742 unsigned NumDefs = 0;
1757 if (
MI->getOpcode() == BPF::LD_imm64) {
1772 processGlobalValue(
MI->getOperand(1));
1773 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1774 MI->getOpcode() == BPF::CORE_LD32 ||
1775 MI->getOpcode() == BPF::CORE_ST ||
1776 MI->getOpcode() == BPF::CORE_SHIFT) {
1778 processGlobalValue(
MI->getOperand(3));
1779 }
else if (
MI->getOpcode() == BPF::JAL) {
1796 if (LineInfoGenerated ==
false) {
1797 auto *S =
MI->getMF()->getFunction().getSubprogram();
1801 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1802 LineInfoGenerated =
true;
1809 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1810 OS.emitLabel(LineSym);
1813 constructLineInfo(LineSym,
DL->getFile(),
DL.getLine(),
DL.getCol());
1815 LineInfoGenerated =
true;
1819void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1825 std::optional<SectionKind> GVKind;
1827 if (!
Global.isDeclarationForLinker())
1830 if (
Global.isDeclarationForLinker())
1831 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1832 else if (GVKind->isCommon())
1840 if (ProcessingMapDef != SecName.
starts_with(
".maps"))
1846 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1847 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1849 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1850 DataSecEntries[std::string(SecName)] =
1851 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1856 Global.getDebugInfo(GVs);
1859 if (GVs.
size() == 0)
1862 uint32_t GVTypeId = 0;
1863 DIGlobalVariable *DIGlobal =
nullptr;
1864 for (
auto *GVE : GVs) {
1865 DIGlobal = GVE->getVariable();
1867 visitMapDefType(DIGlobal->
getType(), GVTypeId);
1870 visitTypeEntry(Ty, GVTypeId,
false,
false);
1893 }
else if (
Global.hasInitializer()) {
1900 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1901 uint32_t VarId = addType(std::move(VarEntry));
1906 if (SecName.
empty())
1910 auto [It,
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1912 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1915 const DataLayout &
DL =
Global.getDataLayout();
1918 It->second->addDataSecEntry(VarId,
Asm->getSymbol(&
Global),
Size);
1920 if (
Global.hasInitializer())
1921 processGlobalInitializer(
Global.getInitializer());
1936void BTFDebug::processGlobalInitializer(
const Constant *
C) {
1938 processFuncPrototypes(Fn);
1940 for (
unsigned I = 0,
N = CA->getNumOperands();
I <
N; ++
I)
1941 processGlobalInitializer(CA->getOperand(
I));
1947 if (
MI->getOpcode() == BPF::LD_imm64) {
1958 auto [
Imm,
Reloc] = PatchImms[GVar];
1969 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1970 MI->getOpcode() == BPF::CORE_LD32 ||
1971 MI->getOpcode() == BPF::CORE_ST ||
1972 MI->getOpcode() == BPF::CORE_SHIFT) {
1980 if (
MI->getOperand(0).isImm())
1993void BTFDebug::processFuncPrototypes(
const Function *
F) {
1998 if (!SP || SP->isDefinition())
2002 if (!ProtoFunctions.insert(
F).second)
2007 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
2010 if (
F->hasSection()) {
2013 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
2015 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
2024 if (MapDefNotCollected) {
2025 processGlobals(
true);
2026 MapDefNotCollected =
false;
2030 processGlobals(
false);
2036 processFuncPrototypes(&
F);
2039 for (
auto &DataSec : DataSecEntries)
2040 addType(std::move(DataSec.second));
2043 for (
auto &Fixup : FixupDerivedTypes) {
2046 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
2057 if (StructTypeId == 0) {
2058 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
2059 StructTypeId = addType(std::move(FwdTypeEntry));
2062 for (
auto &TypeInfo : Fixup.second) {
2066 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
2075 for (
const auto &TypeEntry : TypeEntries)
2076 TypeEntry->completeType(*
this);
2080 emitBTFExtSection();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static uint32_t getBTFArrayLength(const DINode *Dimension, MCContext &Ctx)
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
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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 SmallString class.
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.
Tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
Subprogram description. Uses SubclassData1.
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.
Context object for machine code objects.
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.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
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.
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.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
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.
static AmaRelocation decode(StringRef Name)
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::...