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) {
291 Kind = BTF::BTF_KIND_PTR;
302 case BTF::BTF_KIND_PTR:
303 case BTF::BTF_KIND_CONST:
304 case BTF::BTF_KIND_VOLATILE:
305 case BTF::BTF_KIND_RESTRICT:
320 if (NeedsFixup || !DTy)
326 assert((
Kind == BTF::BTF_KIND_PTR ||
Kind == BTF::BTF_KIND_CONST ||
327 Kind == BTF::BTF_KIND_VOLATILE) &&
328 "Invalid null basetype");
343 Kind = BTF::BTF_KIND_FWD;
364 case dwarf::DW_ATE_boolean:
367 case dwarf::DW_ATE_signed:
368 case dwarf::DW_ATE_signed_char:
371 case dwarf::DW_ATE_unsigned:
372 case dwarf::DW_ATE_unsigned_char:
373 case dwarf::DW_ATE_UTF:
380 Kind = BTF::BTF_KIND_INT;
383 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
401 bool IsSigned) : ETy(ETy) {
402 Kind = BTF::BTF_KIND_ENUM;
414 DINodeArray Elements = ETy->getElements();
415 for (
const auto Element : Elements) {
422 if (Enum->isUnsigned())
423 Value =
static_cast<uint32_t>(Enum->getValue().getZExtValue());
425 Value =
static_cast<uint32_t>(Enum->getValue().getSExtValue());
427 EnumValues.push_back(BTFEnum);
433 for (
const auto &Enum : EnumValues) {
440 bool IsSigned) : ETy(ETy) {
441 Kind = BTF::BTF_KIND_ENUM64;
453 DINodeArray Elements = ETy->getElements();
454 for (
const auto Element : Elements) {
460 if (Enum->isUnsigned())
461 Value = Enum->getValue().getZExtValue();
463 Value =
static_cast<uint64_t>(Enum->getValue().getSExtValue());
466 EnumValues.push_back(BTFEnum);
472 for (
const auto &Enum : EnumValues) {
482 Kind = BTF::BTF_KIND_ARRAY;
487 ArrayInfo.ElemType = ElemTypeId;
488 ArrayInfo.Nelems = NumElems;
514 : STy(STy), HasBitField(HasBitField) {
515 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
517 BTFType.Info = (HasBitField << 31) | (
Kind << 24) | Vlen;
527 if (STy->getTag() == dwarf::DW_TAG_variant_part) {
536 const auto *DTy = STy->getDiscriminator();
540 Discriminator.NameOff = BDebug.
addString(DTy->getName());
541 Discriminator.Offset = DTy->getOffsetInBits();
542 const auto *BaseTy = DTy->getBaseType();
543 Discriminator.Type = BDebug.
getTypeId(BaseTy);
545 Members.push_back(Discriminator);
550 const DINodeArray Elements = STy->getElements();
551 for (
const auto *Element : Elements) {
554 switch (Element->getTag()) {
555 case dwarf::DW_TAG_member: {
560 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
561 BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
563 BTFMember.
Offset = DDTy->getOffsetInBits();
569 case dwarf::DW_TAG_variant_part: {
573 BTFMember.
Offset = DCTy->getOffsetInBits();
580 Members.push_back(BTFMember);
586 for (
const auto &Member : Members) {
606 : STy(STy), FuncArgNames(FuncArgNames),
607 AliveParamIndices(AliveParamIndices),
608 UseFilteredParams(UseFilteredParams), VoidReturn(VoidReturn) {
609 Kind = BTF::BTF_KIND_FUNC_PROTO;
618 DITypeArray Elements = STy->getTypeArray();
631 auto It = FuncArgNames.find(
I);
633 It != FuncArgNames.end() ? BDebug.
addString(It->second) : 0;
639 Parameters.push_back(Param);
642 if (UseFilteredParams) {
648 for (
unsigned I = 1,
N = Elements.size();
I <
N; ++
I)
654 for (
const auto &Param : Parameters) {
663 Kind = BTF::BTF_KIND_FUNC;
680 Kind = BTF::BTF_KIND_VAR;
696 : Asm(AsmPrt), Name(SecName) {
697 Kind = BTF::BTF_KIND_DATASEC;
710 for (
const auto &V : Vars) {
712 Asm->emitLabelReference(std::get<1>(V), 4);
719 Kind = BTF::BTF_KIND_FLOAT;
735 Kind = BTF::BTF_KIND_DECL_TAG;
755 : DTy(nullptr), Tag(Tag) {
756 Kind = BTF::BTF_KIND_TYPE_TAG;
762 : DTy(DTy), Tag(Tag) {
763 Kind = BTF::BTF_KIND_TYPE_TAG;
783 for (
auto &OffsetM : OffsetToIdMap) {
784 if (Table[OffsetM.second] == S)
785 return OffsetM.first;
789 OffsetToIdMap[
Offset] = Table.size();
790 Table.push_back(std::string(S));
791 Size += S.
size() + 1;
797 LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0),
798 MapDefNotCollected(
true) {
802uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
804 TypeEntry->setId(TypeEntries.size() + 1);
807 TypeEntries.push_back(std::move(TypeEntry));
811uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
812 TypeEntry->setId(TypeEntries.size() + 1);
814 TypeEntries.push_back(std::move(TypeEntry));
818void BTFDebug::visitBasicType(
const DIBasicType *BTy, uint32_t &TypeId) {
823 case dwarf::DW_ATE_boolean:
824 case dwarf::DW_ATE_signed:
825 case dwarf::DW_ATE_signed_char:
826 case dwarf::DW_ATE_unsigned:
827 case dwarf::DW_ATE_unsigned_char:
828 case dwarf::DW_ATE_UTF:
831 TypeEntry = std::make_unique<BTFTypeInt>(
834 case dwarf::DW_ATE_float:
842 TypeId = addType(std::move(TypeEntry), BTy);
846void BTFDebug::visitSubroutineType(
851 uint32_t VLen =
Elements.size() - 1;
859 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
860 STy, VLen, FuncArgNames,
false, ArrayRef<uint32_t>(), VoidReturn);
862 TypeId = addType(std::move(TypeEntry));
864 TypeId = addType(std::move(TypeEntry), STy);
868 for (
const auto Element : Elements)
869 visitTypeEntry(Element);
872 visitTypeEntry(Elements[
I]);
876void BTFDebug::processDeclAnnotations(DINodeArray
Annotations,
882 for (
const Metadata *Annotation : Annotations->operands()) {
885 if (
Name->getString() !=
"btf_decl_tag")
889 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
891 addType(std::move(TypeEntry));
895uint32_t BTFDebug::processDISubprogram(
896 const DISubprogram *SP, uint32_t ProtoTypeId, uint8_t Scope,
899 std::make_unique<BTFTypeFunc>(
SP->getName(), ProtoTypeId, Scope);
900 uint32_t FuncId = addType(std::move(FuncTypeEntry));
903 for (
const DINode *DN :
SP->getRetainedNodes()) {
905 uint32_t Arg = DV->getArg();
908 auto It = ArgIndexMap->
find(Arg);
909 if (It != ArgIndexMap->
end())
910 processDeclAnnotations(DV->getAnnotations(), FuncId, It->second);
912 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
917 processDeclAnnotations(
SP->getAnnotations(), FuncId, -1);
923int BTFDebug::genBTFTypeTags(
const DIDerivedType *DTy,
int BaseTypeId) {
929 for (
const Metadata *Annotations : Annots->operands()) {
932 if (
Name->getString() !=
"btf_type_tag")
938 if (MDStrs.
size() == 0)
946 std::unique_ptr<BTFTypeTypeTag>
TypeEntry;
949 std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
951 TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
952 TmpTypeId = addType(std::move(TypeEntry));
954 for (
unsigned I = 1;
I < MDStrs.
size();
I++) {
955 const MDString *
Value = MDStrs[
I];
956 TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId,
Value->getString());
957 TmpTypeId = addType(std::move(TypeEntry));
963void BTFDebug::visitStructType(
const DICompositeType *CTy,
bool IsStruct,
970 if (CTy->
getTag() == dwarf::DW_TAG_variant_part) {
981 bool HasBitField =
false;
982 for (
const auto *Element : Elements) {
983 if (Element->getTag() == dwarf::DW_TAG_member) {
985 if (
E->isBitField()) {
993 std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
995 TypeId = addType(std::move(TypeEntry), CTy);
1002 for (
const auto *Element : Elements) {
1003 switch (Element->getTag()) {
1004 case dwarf::DW_TAG_member: {
1006 visitTypeEntry(Elem);
1007 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1010 case dwarf::DW_TAG_variant_part: {
1012 visitTypeEntry(Elem);
1013 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1023void BTFDebug::visitArrayType(
const DICompositeType *CTy, uint32_t &TypeId) {
1025 uint32_t ElemTypeId;
1027 visitTypeEntry(ElemType, ElemTypeId,
false,
false);
1034 auto TypeEntry = std::make_unique<BTFTypeArray>(ElemTypeId, 0);
1035 ElemTypeId = addType(std::move(TypeEntry), CTy);
1039 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
1042 int64_t
Count = CI->getSExtValue();
1047 std::make_unique<BTFTypeArray>(ElemTypeId,
1050 ElemTypeId = addType(std::move(TypeEntry), CTy);
1052 ElemTypeId = addType(std::move(TypeEntry));
1057 TypeId = ElemTypeId;
1061 if (!ArrayIndexTypeId) {
1062 auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
1063 0,
"__ARRAY_SIZE_TYPE__");
1064 ArrayIndexTypeId = addType(std::move(TypeEntry));
1068void BTFDebug::visitEnumType(
const DICompositeType *CTy, uint32_t &TypeId) {
1074 bool IsSigned =
false;
1075 unsigned NumBits = 32;
1080 IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
1085 if (NumBits <= 32) {
1086 auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
1087 TypeId = addType(std::move(TypeEntry), CTy);
1090 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
1091 TypeId = addType(std::move(TypeEntry), CTy);
1097void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion,
1100 TypeId = addType(std::move(TypeEntry), CTy);
1108 case dwarf::DW_TAG_structure_type:
1109 case dwarf::DW_TAG_union_type:
1110 case dwarf::DW_TAG_variant_part:
1113 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type, TypeId);
1115 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type, TypeId);
1117 case dwarf::DW_TAG_array_type:
1118 visitArrayType(CTy, TypeId);
1120 case dwarf::DW_TAG_enumeration_type:
1121 visitEnumType(CTy, TypeId);
1128bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
1130 auto CTag = CTy->
getTag();
1131 if ((CTag == dwarf::DW_TAG_structure_type ||
1132 CTag == dwarf::DW_TAG_union_type) &&
1140void BTFDebug::visitDerivedType(
const DIDerivedType *DTy, uint32_t &TypeId,
1141 bool CheckPointer,
bool SeenPointer) {
1144 if (
Tag == dwarf::DW_TAG_atomic_type)
1145 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
1150 if (CheckPointer && !SeenPointer) {
1154 if (CheckPointer && SeenPointer) {
1155 const DIType *
Base = DTy->getBaseType();
1157 if (IsForwardDeclCandidate(
Base)) {
1161 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
true);
1164 TypeId = addType(std::move(TypeEntry), DTy);
1170 if (
Tag == dwarf::DW_TAG_pointer_type) {
1171 int TmpTypeId = genBTFTypeTags(DTy, -1);
1172 if (TmpTypeId >= 0) {
1174 std::make_unique<BTFTypeDerived>(TmpTypeId,
Tag, DTy->
getName());
1175 TypeId = addType(std::move(TypeDEntry), DTy);
1177 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1178 TypeId = addType(std::move(TypeEntry), DTy);
1180 }
else if (
Tag == dwarf::DW_TAG_typedef ||
Tag == dwarf::DW_TAG_const_type ||
1181 Tag == dwarf::DW_TAG_volatile_type ||
1182 Tag == dwarf::DW_TAG_restrict_type) {
1183 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1184 TypeId = addType(std::move(TypeEntry), DTy);
1185 if (
Tag == dwarf::DW_TAG_typedef)
1187 }
else if (
Tag != dwarf::DW_TAG_member) {
1193 uint32_t TempTypeId = 0;
1194 if (
Tag == dwarf::DW_TAG_member)
1195 visitTypeEntry(DTy->getBaseType(), TempTypeId,
true,
false);
1197 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
1207void BTFDebug::visitTypeEntry(
const DIType *Ty, uint32_t &TypeId,
1208 bool CheckPointer,
bool SeenPointer) {
1209 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1210 TypeId = DIToIdMap[Ty];
1241 if (Ty && (!CheckPointer || !SeenPointer)) {
1244 const DIType *BaseTy = DTy->getBaseType();
1248 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1251 if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type &&
1254 if (IsForwardDeclCandidate(BaseTy))
1258 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1269 visitBasicType(BTy, TypeId);
1271 visitSubroutineType(STy,
false, SmallDenseMap<uint32_t, StringRef>(),
1274 visitCompositeType(CTy, TypeId);
1276 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
1281void BTFDebug::visitTypeEntry(
const DIType *Ty) {
1283 visitTypeEntry(Ty, TypeId,
false,
false);
1286void BTFDebug::visitMapDefType(
const DIType *Ty, uint32_t &TypeId) {
1287 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1288 TypeId = DIToIdMap[Ty];
1294 case dwarf::DW_TAG_typedef:
1295 case dwarf::DW_TAG_const_type:
1296 case dwarf::DW_TAG_volatile_type:
1297 case dwarf::DW_TAG_restrict_type:
1298 case dwarf::DW_TAG_pointer_type:
1301 case dwarf::DW_TAG_array_type:
1305 case dwarf::DW_TAG_structure_type: {
1309 for (
const auto *Element : Elements) {
1311 const DIType *MemberBaseType = MemberType->getBaseType();
1320 visitMapDefType(MemberBaseType, TmpId);
1322 visitTypeEntry(MemberBaseType);
1332 visitTypeEntry(Ty, TypeId,
false,
false);
1336std::string BTFDebug::populateFileContent(
const DIFile *File) {
1337 std::string FileName;
1339 if (!
File->getFilename().starts_with(
"/") &&
File->getDirectory().size())
1340 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
1342 FileName = std::string(
File->getFilename());
1345 if (FileContent.contains(FileName))
1348 std::vector<std::string> Content;
1350 Content.push_back(Line);
1352 auto LoadFile = [](StringRef FileName) {
1358 std::unique_ptr<MemoryBuffer> Buf;
1362 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = LoadFile(FileName))
1363 Buf = std::move(*BufOrErr);
1365 for (line_iterator
I(*Buf,
false),
E;
I !=
E; ++
I)
1366 Content.push_back(std::string(*
I));
1368 FileContent[FileName] = std::move(Content);
1372void BTFDebug::constructLineInfo(
MCSymbol *Label,
const DIFile *File,
1373 uint32_t Line, uint32_t Column) {
1374 std::string FileName = populateFileContent(File);
1375 BTFLineInfo LineInfo;
1380 const auto &Content = FileContent[FileName];
1381 if (Line < Content.size())
1387 LineInfoTable[SecNameOff].push_back(LineInfo);
1390void BTFDebug::emitCommonHeader() {
1397void BTFDebug::emitBTFSection() {
1399 if (!TypeEntries.size() && StringTable.getSize() == 1)
1402 MCContext &Ctx = OS.getContext();
1405 OS.switchSection(Sec);
1411 uint32_t TypeLen = 0, StrLen;
1412 for (
const auto &TypeEntry : TypeEntries)
1414 StrLen = StringTable.getSize();
1417 OS.emitInt32(TypeLen);
1418 OS.emitInt32(TypeLen);
1419 OS.emitInt32(StrLen);
1422 for (
const auto &TypeEntry : TypeEntries)
1426 uint32_t StringOffset = 0;
1427 for (
const auto &S : StringTable.getTable()) {
1428 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1430 OS.emitBytes(StringRef(
"\0", 1));
1431 StringOffset += S.size() + 1;
1435void BTFDebug::emitBTFExtSection() {
1438 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1439 !FieldRelocTable.size())
1442 MCContext &Ctx = OS.getContext();
1445 OS.switchSection(Sec);
1452 uint32_t FuncLen = 4, LineLen = 4;
1454 uint32_t FieldRelocLen = 0;
1455 for (
const auto &FuncSec : FuncInfoTable) {
1459 for (
const auto &LineSec : LineInfoTable) {
1463 for (
const auto &FieldRelocSec : FieldRelocTable) {
1472 OS.emitInt32(FuncLen);
1473 OS.emitInt32(FuncLen);
1474 OS.emitInt32(LineLen);
1475 OS.emitInt32(FuncLen + LineLen);
1476 OS.emitInt32(FieldRelocLen);
1479 OS.AddComment(
"FuncInfo");
1481 for (
const auto &FuncSec : FuncInfoTable) {
1482 OS.AddComment(
"FuncInfo section string offset=" +
1483 std::to_string(FuncSec.first));
1484 OS.emitInt32(FuncSec.first);
1485 OS.emitInt32(FuncSec.second.size());
1486 for (
const auto &FuncInfo : FuncSec.second) {
1487 Asm->emitLabelReference(FuncInfo.Label, 4);
1488 OS.emitInt32(FuncInfo.TypeId);
1493 OS.AddComment(
"LineInfo");
1495 for (
const auto &LineSec : LineInfoTable) {
1496 OS.AddComment(
"LineInfo section string offset=" +
1497 std::to_string(LineSec.first));
1498 OS.emitInt32(LineSec.first);
1499 OS.emitInt32(LineSec.second.size());
1500 for (
const auto &LineInfo : LineSec.second) {
1501 Asm->emitLabelReference(LineInfo.
Label, 4);
1503 OS.emitInt32(LineInfo.
LineOff);
1504 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1511 if (FieldRelocLen) {
1512 OS.AddComment(
"FieldReloc");
1514 for (
const auto &FieldRelocSec : FieldRelocTable) {
1515 OS.AddComment(
"Field reloc section string offset=" +
1516 std::to_string(FieldRelocSec.first));
1517 OS.emitInt32(FieldRelocSec.first);
1518 OS.emitInt32(FieldRelocSec.second.size());
1519 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1520 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1521 OS.emitInt32(FieldRelocInfo.TypeID);
1522 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1523 OS.emitInt32(FieldRelocInfo.RelocKind);
1531 auto *Unit = SP->getUnit();
1534 SkipInstruction =
true;
1537 SkipInstruction =
false;
1558 if (MapDefNotCollected) {
1559 processGlobals(
true);
1560 MapDefNotCollected =
false;
1567 for (
const DINode *DN : SP->getRetainedNodes()) {
1572 visitTypeEntry(DV->getType());
1573 FuncArgNames[Arg] = DV->getName();
1581 bool IsNocall = SP->getType()->getCC() == dwarf::DW_CC_nocall;
1582 bool UseFilteredParams =
false;
1590 DITypeArray Elements = SP->getType()->getTypeArray();
1598 if (UseFilteredParams) {
1602 AliveParamIndices.
push_back(ArgReg.first);
1603 ArgIndexMap[ArgReg.first] =
I;
1607 visitTypeEntry(Elements[0]);
1608 for (
uint32_t ArgNo : AliveParamIndices)
1609 visitTypeEntry(Elements[ArgNo]);
1611 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
1612 SP->getType(), AliveParamIndices.
size(), FuncArgNames,
true,
1613 AliveParamIndices, VoidReturn);
1614 ProtoTypeId = addType(std::move(TypeEntry));
1615 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope, &ArgIndexMap);
1619 if (!UseFilteredParams) {
1622 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId,
1624 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1627 for (
const auto &TypeEntry : TypeEntries)
1628 TypeEntry->completeType(*
this);
1633 FuncInfo.
Label = FuncLabel;
1634 FuncInfo.
TypeId = FuncTypeId;
1641 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1645 SkipInstruction =
false;
1646 LineInfoGenerated =
false;
1652unsigned BTFDebug::populateType(
const DIType *Ty) {
1654 visitTypeEntry(Ty, Id,
false,
false);
1655 for (
const auto &TypeEntry : TypeEntries)
1656 TypeEntry->completeType(*
this);
1661void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1664 FieldReloc.
Label = ORSym;
1665 FieldReloc.
TypeID = RootId;
1671 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
1674 SecondColon - FirstColon);
1676 FirstDollar - SecondColon);
1679 FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
1680 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1683 StringRef RelocStr = AccessPattern.
substr(FirstDollar + 1);
1685 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1686 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1688 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1694 const GlobalValue *GVal = MO.
getGlobal();
1706 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1707 OS.emitLabel(ORSym);
1709 MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
1711 generatePatchImmReloc(ORSym, RootId, GVar,
1719 if (SkipInstruction ||
MI->isMetaInstruction() ||
1723 if (
MI->isInlineAsm()) {
1725 unsigned NumDefs = 0;
1740 if (
MI->getOpcode() == BPF::LD_imm64) {
1755 processGlobalValue(
MI->getOperand(1));
1756 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1757 MI->getOpcode() == BPF::CORE_LD32 ||
1758 MI->getOpcode() == BPF::CORE_ST ||
1759 MI->getOpcode() == BPF::CORE_SHIFT) {
1761 processGlobalValue(
MI->getOperand(3));
1762 }
else if (
MI->getOpcode() == BPF::JAL) {
1779 if (LineInfoGenerated ==
false) {
1780 auto *S =
MI->getMF()->getFunction().getSubprogram();
1784 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1785 LineInfoGenerated =
true;
1792 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1793 OS.emitLabel(LineSym);
1796 constructLineInfo(LineSym,
DL->getFile(),
DL.getLine(),
DL.getCol());
1798 LineInfoGenerated =
true;
1802void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1808 std::optional<SectionKind> GVKind;
1810 if (!
Global.isDeclarationForLinker())
1813 if (
Global.isDeclarationForLinker())
1814 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1815 else if (GVKind->isCommon())
1823 if (ProcessingMapDef != SecName.
starts_with(
".maps"))
1829 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1830 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1832 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1833 DataSecEntries[std::string(SecName)] =
1834 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1839 Global.getDebugInfo(GVs);
1842 if (GVs.
size() == 0)
1845 uint32_t GVTypeId = 0;
1846 DIGlobalVariable *DIGlobal =
nullptr;
1847 for (
auto *GVE : GVs) {
1848 DIGlobal = GVE->getVariable();
1850 visitMapDefType(DIGlobal->
getType(), GVTypeId);
1853 visitTypeEntry(Ty, GVTypeId,
false,
false);
1876 }
else if (
Global.hasInitializer()) {
1883 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1884 uint32_t VarId = addType(std::move(VarEntry));
1889 if (SecName.
empty())
1893 auto [It,
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1895 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1898 const DataLayout &
DL =
Global.getDataLayout();
1901 It->second->addDataSecEntry(VarId,
Asm->getSymbol(&
Global),
Size);
1903 if (
Global.hasInitializer())
1904 processGlobalInitializer(
Global.getInitializer());
1919void BTFDebug::processGlobalInitializer(
const Constant *
C) {
1921 processFuncPrototypes(Fn);
1923 for (
unsigned I = 0,
N = CA->getNumOperands();
I <
N; ++
I)
1924 processGlobalInitializer(CA->getOperand(
I));
1930 if (
MI->getOpcode() == BPF::LD_imm64) {
1941 auto [Imm,
Reloc] = PatchImms[GVar];
1952 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1953 MI->getOpcode() == BPF::CORE_LD32 ||
1954 MI->getOpcode() == BPF::CORE_ST ||
1955 MI->getOpcode() == BPF::CORE_SHIFT) {
1961 uint32_t Imm = PatchImms[GVar].first;
1963 if (
MI->getOperand(0).isImm())
1976void BTFDebug::processFuncPrototypes(
const Function *
F) {
1981 if (!SP || SP->isDefinition())
1985 if (!ProtoFunctions.insert(
F).second)
1990 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
1993 if (
F->hasSection()) {
1996 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1998 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
2007 if (MapDefNotCollected) {
2008 processGlobals(
true);
2009 MapDefNotCollected =
false;
2013 processGlobals(
false);
2019 processFuncPrototypes(&
F);
2022 for (
auto &DataSec : DataSecEntries)
2023 addType(std::move(DataSec.second));
2026 for (
auto &
Fixup : FixupDerivedTypes) {
2029 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
2040 if (StructTypeId == 0) {
2041 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
2042 StructTypeId = addType(std::move(FwdTypeEntry));
2045 for (
auto &TypeInfo :
Fixup.second) {
2049 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
2058 for (
const auto &TypeEntry : TypeEntries)
2059 TypeEntry->completeType(*
this);
2063 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::...