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:
143 if (
MI.isDebugValue()) {
146 if (
MI.isIndirectDebugValue())
160 EntryRegMap[Arg] = MO.
getReg();
167 if (
MI.mayStore() && !
MI.isCall() &&
MI.getOperand(0).isReg()) {
171 const Value *V = MMO->getValue();
174 auto It = AllocaToFI.
find(V);
175 if (It != AllocaToFI.
end())
182 if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical()) {
183 DefinedRegs.
insert(MO.getReg());
184 StackLoadRegs.
erase(MO.getReg());
188 if (
MI.getOpcode() == BPF::LDD &&
MI.getOperand(1).getReg() == BPF::R11)
189 StackLoadRegs.
insert(
MI.getOperand(0).getReg());
196 if (!VI.Var || !VI.Var->getArg() || !VI.inStackSlot())
198 if (VI.Var->getScope()->getSubprogram() != SP)
201 if (EntryRegMap.
count(Arg))
203 auto It = FrameIndexToReg.
find(VI.getStackSlot());
204 if (It != FrameIndexToReg.
end())
205 EntryRegMap[Arg] = It->second;
220 ArrayRef<std::pair<uint32_t, Register>> AliveArgs,
225 << AliveArgs.size() <<
")\n");
230 for (
unsigned I = 0,
N = AliveArgs.size();
I <
N; ++
I, ++ArgIt) {
231 auto [ArgNo,
Reg] = AliveArgs[
I];
234 <<
": type mismatch for source arg " << ArgNo
235 <<
" at IR position " <<
I <<
"\n");
239 if (
I >= std::size(CC_BPF64_ArgRegs))
242 int DwarfReg =
TRI.getDwarfRegNum(
Reg,
false);
243 if (DwarfReg !=
static_cast<int>(
I + 1)) {
245 <<
" in DWARF reg " << DwarfReg <<
", expected "
266 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->
getName()) {
268 case dwarf::DW_TAG_pointer_type:
269 Kind = BTF::BTF_KIND_PTR;
271 case dwarf::DW_TAG_const_type:
272 Kind = BTF::BTF_KIND_CONST;
274 case dwarf::DW_TAG_volatile_type:
275 Kind = BTF::BTF_KIND_VOLATILE;
277 case dwarf::DW_TAG_typedef:
278 Kind = BTF::BTF_KIND_TYPEDEF;
280 case dwarf::DW_TAG_restrict_type:
281 Kind = BTF::BTF_KIND_RESTRICT;
292 : DTy(nullptr), NeedsFixup(
false), Name(Name) {
294 case dwarf::DW_TAG_pointer_type:
295 Kind = BTF::BTF_KIND_PTR;
297 case dwarf::DW_TAG_typedef:
298 Kind = BTF::BTF_KIND_TYPEDEF;
314 case BTF::BTF_KIND_PTR:
315 case BTF::BTF_KIND_CONST:
316 case BTF::BTF_KIND_VOLATILE:
317 case BTF::BTF_KIND_RESTRICT:
332 if (NeedsFixup || !DTy)
338 assert((
Kind == BTF::BTF_KIND_PTR ||
Kind == BTF::BTF_KIND_CONST ||
339 Kind == BTF::BTF_KIND_VOLATILE) &&
340 "Invalid null basetype");
355 Kind = BTF::BTF_KIND_FWD;
376 case dwarf::DW_ATE_boolean:
379 case dwarf::DW_ATE_signed:
380 case dwarf::DW_ATE_signed_char:
383 case dwarf::DW_ATE_unsigned:
384 case dwarf::DW_ATE_unsigned_char:
385 case dwarf::DW_ATE_UTF:
392 Kind = BTF::BTF_KIND_INT;
395 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
413 bool IsSigned) : ETy(ETy) {
414 Kind = BTF::BTF_KIND_ENUM;
426 DINodeArray Elements = ETy->getElements();
427 for (
const auto Element : Elements) {
434 if (Enum->isUnsigned())
435 Value =
static_cast<uint32_t>(Enum->getValue().getZExtValue());
437 Value =
static_cast<uint32_t>(Enum->getValue().getSExtValue());
439 EnumValues.push_back(BTFEnum);
445 for (
const auto &Enum : EnumValues) {
452 bool IsSigned) : ETy(ETy) {
453 Kind = BTF::BTF_KIND_ENUM64;
465 DINodeArray Elements = ETy->getElements();
466 for (
const auto Element : Elements) {
472 if (Enum->isUnsigned())
473 Value = Enum->getValue().getZExtValue();
475 Value =
static_cast<uint64_t>(Enum->getValue().getSExtValue());
478 EnumValues.push_back(BTFEnum);
484 for (
const auto &Enum : EnumValues) {
494 Kind = BTF::BTF_KIND_ARRAY;
499 ArrayInfo.ElemType = ElemTypeId;
500 ArrayInfo.Nelems = NumElems;
527 : STy(STy), Elements(Elements.begin(), Elements.end()),
528 HasBitField(HasBitField) {
529 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
531 BTFType.Info = (HasBitField << 31) | (
Kind << 24) | Vlen;
541 if (STy->getTag() == dwarf::DW_TAG_variant_part) {
550 const auto *DTy = STy->getDiscriminator();
554 Discriminator.NameOff = BDebug.
addString(DTy->getName());
555 Discriminator.Offset = DTy->getOffsetInBits();
556 const auto *BaseTy = DTy->getBaseType();
557 Discriminator.Type = BDebug.
getTypeId(BaseTy);
559 Members.push_back(Discriminator);
564 for (
const auto *Element : Elements) {
567 switch (Element->getTag()) {
568 case dwarf::DW_TAG_member: {
573 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
574 BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
576 BTFMember.
Offset = DDTy->getOffsetInBits();
582 case dwarf::DW_TAG_variant_part: {
586 BTFMember.
Offset = DCTy->getOffsetInBits();
593 Members.push_back(BTFMember);
599 for (
const auto &Member : Members) {
619 : STy(STy), FuncArgNames(FuncArgNames),
620 AliveParamIndices(AliveParamIndices),
621 UseFilteredParams(UseFilteredParams), VoidReturn(VoidReturn) {
622 Kind = BTF::BTF_KIND_FUNC_PROTO;
631 DITypeArray Elements = STy->getTypeArray();
644 auto It = FuncArgNames.find(
I);
646 It != FuncArgNames.end() ? BDebug.
addString(It->second) : 0;
652 Parameters.push_back(Param);
655 if (UseFilteredParams) {
661 for (
unsigned I = 1,
N = Elements.size();
I <
N; ++
I)
667 for (
const auto &Param : Parameters) {
676 Kind = BTF::BTF_KIND_FUNC;
693 Kind = BTF::BTF_KIND_VAR;
709 : Asm(AsmPrt), Name(SecName) {
710 Kind = BTF::BTF_KIND_DATASEC;
723 for (
const auto &V : Vars) {
725 Asm->emitLabelReference(std::get<1>(V), 4);
732 Kind = BTF::BTF_KIND_FLOAT;
748 Kind = BTF::BTF_KIND_DECL_TAG;
768 : DTy(nullptr), Tag(Tag) {
769 Kind = BTF::BTF_KIND_TYPE_TAG;
775 : DTy(DTy), Tag(Tag) {
776 Kind = BTF::BTF_KIND_TYPE_TAG;
796 for (
auto &OffsetM : OffsetToIdMap) {
797 if (Table[OffsetM.second] == S)
798 return OffsetM.first;
802 OffsetToIdMap[
Offset] = Table.size();
803 Table.push_back(std::string(S));
804 Size += S.
size() + 1;
810 LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0),
811 MapDefNotCollected(
true) {
815uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
817 TypeEntry->setId(TypeEntries.size() + 1);
820 TypeEntries.push_back(std::move(TypeEntry));
824uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
825 TypeEntry->setId(TypeEntries.size() + 1);
827 TypeEntries.push_back(std::move(TypeEntry));
831void BTFDebug::visitBasicType(
const DIBasicType *BTy, uint32_t &TypeId) {
836 case dwarf::DW_ATE_boolean:
837 case dwarf::DW_ATE_signed:
838 case dwarf::DW_ATE_signed_char:
839 case dwarf::DW_ATE_unsigned:
840 case dwarf::DW_ATE_unsigned_char:
841 case dwarf::DW_ATE_UTF:
844 TypeEntry = std::make_unique<BTFTypeInt>(
847 case dwarf::DW_ATE_float:
855 TypeId = addType(std::move(TypeEntry), BTy);
859void BTFDebug::visitSubroutineType(
864 uint32_t VLen =
Elements.size() - 1;
872 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
873 STy, VLen, FuncArgNames,
false, ArrayRef<uint32_t>(), VoidReturn);
875 TypeId = addType(std::move(TypeEntry));
877 TypeId = addType(std::move(TypeEntry), STy);
881 for (
const auto Element : Elements)
882 visitTypeEntry(Element);
885 visitTypeEntry(Elements[
I]);
889void BTFDebug::processDeclAnnotations(DINodeArray
Annotations,
895 for (
const Metadata *Annotation : Annotations->operands()) {
898 if (
Name->getString() !=
"btf_decl_tag")
902 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
904 addType(std::move(TypeEntry));
908uint32_t BTFDebug::processDISubprogram(
909 const DISubprogram *SP, uint32_t ProtoTypeId, uint8_t Scope,
912 std::make_unique<BTFTypeFunc>(
SP->getName(), ProtoTypeId, Scope);
913 uint32_t FuncId = addType(std::move(FuncTypeEntry));
916 for (
const DINode *DN :
SP->getRetainedNodes()) {
918 uint32_t Arg = DV->getArg();
921 auto It = ArgIndexMap->
find(Arg);
922 if (It != ArgIndexMap->
end())
923 processDeclAnnotations(DV->getAnnotations(), FuncId, It->second);
925 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
930 processDeclAnnotations(
SP->getAnnotations(), FuncId, -1);
936int BTFDebug::genBTFTypeTags(
const DIDerivedType *DTy,
int BaseTypeId) {
942 for (
const Metadata *Annotations : Annots->operands()) {
945 if (
Name->getString() !=
"btf_type_tag")
951 if (MDStrs.
size() == 0)
959 std::unique_ptr<BTFTypeTypeTag>
TypeEntry;
962 std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
964 TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
965 TmpTypeId = addType(std::move(TypeEntry));
967 for (
unsigned I = 1;
I < MDStrs.
size();
I++) {
968 const MDString *
Value = MDStrs[
I];
969 TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId,
Value->getString());
970 TmpTypeId = addType(std::move(TypeEntry));
976void BTFDebug::visitStructType(
const DICompositeType *CTy,
bool IsStruct,
982 if (CTy->
getTag() == dwarf::DW_TAG_structure_type)
990 if (CTy->
getTag() == dwarf::DW_TAG_variant_part) {
1001 bool HasBitField =
false;
1002 for (
const auto *Element : Elements) {
1003 if (Element->getTag() == dwarf::DW_TAG_member) {
1005 if (
E->isBitField()) {
1012 auto TypeEntry = std::make_unique<BTFTypeStruct>(CTy, Elements, IsStruct,
1015 TypeId = addType(std::move(TypeEntry), CTy);
1022 for (
const auto *Element : Elements) {
1023 switch (Element->getTag()) {
1024 case dwarf::DW_TAG_member: {
1026 visitTypeEntry(Elem);
1027 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1030 case dwarf::DW_TAG_variant_part: {
1032 visitTypeEntry(Elem);
1033 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
1043void BTFDebug::visitArrayType(
const DICompositeType *CTy, uint32_t &TypeId) {
1045 uint32_t ElemTypeId;
1047 visitTypeEntry(ElemType, ElemTypeId,
false,
false);
1054 auto TypeEntry = std::make_unique<BTFTypeArray>(ElemTypeId, 0);
1055 ElemTypeId = addType(std::move(TypeEntry), CTy);
1059 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
1062 int64_t
Count = CI->getSExtValue();
1067 std::make_unique<BTFTypeArray>(ElemTypeId,
1070 ElemTypeId = addType(std::move(TypeEntry), CTy);
1072 ElemTypeId = addType(std::move(TypeEntry));
1077 TypeId = ElemTypeId;
1081 if (!ArrayIndexTypeId) {
1082 auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
1083 0,
"__ARRAY_SIZE_TYPE__");
1084 ArrayIndexTypeId = addType(std::move(TypeEntry));
1088void BTFDebug::visitEnumType(
const DICompositeType *CTy, uint32_t &TypeId) {
1094 bool IsSigned =
false;
1095 unsigned NumBits = 32;
1100 IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
1105 if (NumBits <= 32) {
1106 auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
1107 TypeId = addType(std::move(TypeEntry), CTy);
1110 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
1111 TypeId = addType(std::move(TypeEntry), CTy);
1117void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion,
1120 TypeId = addType(std::move(TypeEntry), CTy);
1128 case dwarf::DW_TAG_structure_type:
1129 case dwarf::DW_TAG_union_type:
1130 case dwarf::DW_TAG_variant_part:
1133 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type, TypeId);
1135 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type, TypeId);
1137 case dwarf::DW_TAG_array_type:
1138 visitArrayType(CTy, TypeId);
1140 case dwarf::DW_TAG_enumeration_type:
1141 visitEnumType(CTy, TypeId);
1148bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
1150 auto CTag = CTy->
getTag();
1151 if ((CTag == dwarf::DW_TAG_structure_type ||
1152 CTag == dwarf::DW_TAG_union_type) &&
1160void BTFDebug::visitDerivedType(
const DIDerivedType *DTy, uint32_t &TypeId,
1161 bool CheckPointer,
bool SeenPointer) {
1164 if (
Tag == dwarf::DW_TAG_atomic_type)
1165 return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
1170 if (CheckPointer && !SeenPointer) {
1174 if (CheckPointer && SeenPointer) {
1175 const DIType *
Base = DTy->getBaseType();
1177 if (IsForwardDeclCandidate(
Base)) {
1181 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
true);
1184 TypeId = addType(std::move(TypeEntry), DTy);
1190 if (
Tag == dwarf::DW_TAG_pointer_type ||
Tag == dwarf::DW_TAG_typedef) {
1191 int TmpTypeId = genBTFTypeTags(DTy, -1);
1192 if (TmpTypeId >= 0) {
1194 std::make_unique<BTFTypeDerived>(TmpTypeId,
Tag, DTy->
getName());
1195 TypeId = addType(std::move(TypeDEntry), DTy);
1197 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1198 TypeId = addType(std::move(TypeEntry), DTy);
1200 if (
Tag == dwarf::DW_TAG_typedef)
1202 }
else if (
Tag == dwarf::DW_TAG_const_type ||
1203 Tag == dwarf::DW_TAG_volatile_type ||
1204 Tag == dwarf::DW_TAG_restrict_type) {
1205 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
1206 TypeId = addType(std::move(TypeEntry), DTy);
1207 }
else if (
Tag != dwarf::DW_TAG_member) {
1213 uint32_t TempTypeId = 0;
1214 if (
Tag == dwarf::DW_TAG_member)
1215 visitTypeEntry(DTy->getBaseType(), TempTypeId,
true,
false);
1217 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
1227void BTFDebug::visitTypeEntry(
const DIType *Ty, uint32_t &TypeId,
1228 bool CheckPointer,
bool SeenPointer) {
1229 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1230 TypeId = DIToIdMap[Ty];
1261 if (Ty && (!CheckPointer || !SeenPointer)) {
1264 const DIType *BaseTy = DTy->getBaseType();
1268 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1271 if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type &&
1274 if (IsForwardDeclCandidate(BaseTy))
1278 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1289 visitBasicType(BTy, TypeId);
1291 visitSubroutineType(STy,
false, SmallDenseMap<uint32_t, StringRef>(),
1294 visitCompositeType(CTy, TypeId);
1296 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
1301void BTFDebug::visitTypeEntry(
const DIType *Ty) {
1303 visitTypeEntry(Ty, TypeId,
false,
false);
1306void BTFDebug::visitMapDefType(
const DIType *Ty, uint32_t &TypeId) {
1307 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
1308 TypeId = DIToIdMap[Ty];
1314 case dwarf::DW_TAG_typedef:
1315 case dwarf::DW_TAG_const_type:
1316 case dwarf::DW_TAG_volatile_type:
1317 case dwarf::DW_TAG_restrict_type:
1318 case dwarf::DW_TAG_pointer_type:
1321 case dwarf::DW_TAG_array_type:
1325 case dwarf::DW_TAG_structure_type: {
1329 for (
const auto *Element : Elements) {
1331 const DIType *MemberBaseType = MemberType->getBaseType();
1340 visitMapDefType(MemberBaseType, TmpId);
1342 visitTypeEntry(MemberBaseType);
1352 visitTypeEntry(Ty, TypeId,
false,
false);
1356std::string BTFDebug::populateFileContent(
const DIFile *File) {
1357 std::string FileName;
1359 if (!
File->getFilename().starts_with(
"/") &&
File->getDirectory().size())
1360 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
1362 FileName = std::string(
File->getFilename());
1365 if (FileContent.contains(FileName))
1368 std::vector<std::string> Content;
1370 Content.push_back(Line);
1372 auto LoadFile = [](StringRef FileName) {
1378 std::unique_ptr<MemoryBuffer> Buf;
1382 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = LoadFile(FileName))
1383 Buf = std::move(*BufOrErr);
1385 for (line_iterator
I(*Buf,
false),
E;
I !=
E; ++
I)
1386 Content.push_back(std::string(*
I));
1388 FileContent[FileName] = std::move(Content);
1392void BTFDebug::constructLineInfo(
MCSymbol *Label,
const DIFile *File,
1393 uint32_t Line, uint32_t Column) {
1394 std::string FileName = populateFileContent(File);
1395 BTFLineInfo LineInfo;
1400 const auto &Content = FileContent[FileName];
1401 if (Line < Content.size())
1407 LineInfoTable[SecNameOff].push_back(LineInfo);
1410void BTFDebug::emitCommonHeader() {
1417void BTFDebug::emitBTFSection() {
1419 if (!TypeEntries.size() && StringTable.getSize() == 1)
1422 MCContext &Ctx = OS.getContext();
1425 OS.switchSection(Sec);
1431 uint32_t TypeLen = 0, StrLen;
1432 for (
const auto &TypeEntry : TypeEntries)
1434 StrLen = StringTable.getSize();
1437 OS.emitInt32(TypeLen);
1438 OS.emitInt32(TypeLen);
1439 OS.emitInt32(StrLen);
1442 for (
const auto &TypeEntry : TypeEntries)
1446 uint32_t StringOffset = 0;
1447 for (
const auto &S : StringTable.getTable()) {
1448 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1450 OS.emitBytes(StringRef(
"\0", 1));
1451 StringOffset += S.size() + 1;
1455void BTFDebug::emitBTFExtSection() {
1458 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1459 !FieldRelocTable.size())
1462 MCContext &Ctx = OS.getContext();
1465 OS.switchSection(Sec);
1472 uint32_t FuncLen = 4, LineLen = 4;
1474 uint32_t FieldRelocLen = 0;
1475 for (
const auto &FuncSec : FuncInfoTable) {
1479 for (
const auto &LineSec : LineInfoTable) {
1483 for (
const auto &FieldRelocSec : FieldRelocTable) {
1492 OS.emitInt32(FuncLen);
1493 OS.emitInt32(FuncLen);
1494 OS.emitInt32(LineLen);
1495 OS.emitInt32(FuncLen + LineLen);
1496 OS.emitInt32(FieldRelocLen);
1499 OS.AddComment(
"FuncInfo");
1501 for (
const auto &FuncSec : FuncInfoTable) {
1502 OS.AddComment(
"FuncInfo section string offset=" +
1503 std::to_string(FuncSec.first));
1504 OS.emitInt32(FuncSec.first);
1505 OS.emitInt32(FuncSec.second.size());
1506 for (
const auto &FuncInfo : FuncSec.second) {
1507 Asm->emitLabelReference(FuncInfo.Label, 4);
1508 OS.emitInt32(FuncInfo.TypeId);
1513 OS.AddComment(
"LineInfo");
1515 for (
const auto &LineSec : LineInfoTable) {
1516 OS.AddComment(
"LineInfo section string offset=" +
1517 std::to_string(LineSec.first));
1518 OS.emitInt32(LineSec.first);
1519 OS.emitInt32(LineSec.second.size());
1520 for (
const auto &LineInfo : LineSec.second) {
1521 Asm->emitLabelReference(LineInfo.
Label, 4);
1523 OS.emitInt32(LineInfo.
LineOff);
1524 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1531 if (FieldRelocLen) {
1532 OS.AddComment(
"FieldReloc");
1534 for (
const auto &FieldRelocSec : FieldRelocTable) {
1535 OS.AddComment(
"Field reloc section string offset=" +
1536 std::to_string(FieldRelocSec.first));
1537 OS.emitInt32(FieldRelocSec.first);
1538 OS.emitInt32(FieldRelocSec.second.size());
1539 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1540 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1541 OS.emitInt32(FieldRelocInfo.TypeID);
1542 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1543 OS.emitInt32(FieldRelocInfo.RelocKind);
1551 auto *Unit = SP->getUnit();
1554 SkipInstruction =
true;
1557 SkipInstruction =
false;
1578 if (MapDefNotCollected) {
1579 processGlobals(
true);
1580 MapDefNotCollected =
false;
1587 for (
const DINode *DN : SP->getRetainedNodes()) {
1592 visitTypeEntry(DV->getType());
1593 FuncArgNames[Arg] = DV->getName();
1601 bool IsNocall = SP->getType()->getCC() == dwarf::DW_CC_nocall;
1602 bool UseFilteredParams =
false;
1610 DITypeArray Elements = SP->getType()->getTypeArray();
1618 if (UseFilteredParams) {
1622 AliveParamIndices.
push_back(ArgReg.first);
1623 ArgIndexMap[ArgReg.first] =
I;
1627 visitTypeEntry(Elements[0]);
1628 for (
uint32_t ArgNo : AliveParamIndices)
1629 visitTypeEntry(Elements[ArgNo]);
1631 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(
1632 SP->getType(), AliveParamIndices.
size(), FuncArgNames,
true,
1633 AliveParamIndices, VoidReturn);
1634 ProtoTypeId = addType(std::move(TypeEntry));
1635 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope, &ArgIndexMap);
1639 if (!UseFilteredParams) {
1642 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId,
1644 FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1647 for (
const auto &TypeEntry : TypeEntries)
1648 TypeEntry->completeType(*
this);
1653 FuncInfo.
Label = FuncLabel;
1654 FuncInfo.
TypeId = FuncTypeId;
1661 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1665 SkipInstruction =
false;
1666 LineInfoGenerated =
false;
1672unsigned BTFDebug::populateType(
const DIType *Ty) {
1674 visitTypeEntry(Ty, Id,
false,
false);
1675 for (
const auto &TypeEntry : TypeEntries)
1676 TypeEntry->completeType(*
this);
1681void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1684 FieldReloc.
Label = ORSym;
1685 FieldReloc.
TypeID = RootId;
1691 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
1694 SecondColon - FirstColon);
1696 FirstDollar - SecondColon);
1699 FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
1700 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1703 StringRef RelocStr = AccessPattern.
substr(FirstDollar + 1);
1705 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1706 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1708 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1714 const GlobalValue *GVal = MO.
getGlobal();
1726 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1727 OS.emitLabel(ORSym);
1729 MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
1731 generatePatchImmReloc(ORSym, RootId, GVar,
1739 if (SkipInstruction ||
MI->isMetaInstruction() ||
1743 if (
MI->isInlineAsm()) {
1745 unsigned NumDefs = 0;
1760 if (
MI->getOpcode() == BPF::LD_imm64) {
1775 processGlobalValue(
MI->getOperand(1));
1776 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1777 MI->getOpcode() == BPF::CORE_LD32 ||
1778 MI->getOpcode() == BPF::CORE_ST ||
1779 MI->getOpcode() == BPF::CORE_SHIFT) {
1781 processGlobalValue(
MI->getOperand(3));
1782 }
else if (
MI->getOpcode() == BPF::JAL) {
1799 if (LineInfoGenerated ==
false) {
1800 auto *S =
MI->getMF()->getFunction().getSubprogram();
1804 constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1805 LineInfoGenerated =
true;
1812 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1813 OS.emitLabel(LineSym);
1816 constructLineInfo(LineSym,
DL->getFile(),
DL.getLine(),
DL.getCol());
1818 LineInfoGenerated =
true;
1822void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1828 std::optional<SectionKind> GVKind;
1830 if (!
Global.isDeclarationForLinker())
1833 if (
Global.isDeclarationForLinker())
1834 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1835 else if (GVKind->isCommon())
1843 if (ProcessingMapDef != SecName.
starts_with(
".maps"))
1849 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1850 DataSecEntries.find(SecName) == DataSecEntries.end()) {
1852 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1853 DataSecEntries[std::string(SecName)] =
1854 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1859 Global.getDebugInfo(GVs);
1862 if (GVs.
size() == 0)
1865 uint32_t GVTypeId = 0;
1866 DIGlobalVariable *DIGlobal =
nullptr;
1867 for (
auto *GVE : GVs) {
1868 DIGlobal = GVE->getVariable();
1870 visitMapDefType(DIGlobal->
getType(), GVTypeId);
1873 visitTypeEntry(Ty, GVTypeId,
false,
false);
1896 }
else if (
Global.hasInitializer()) {
1903 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1904 uint32_t VarId = addType(std::move(VarEntry));
1909 if (SecName.
empty())
1913 auto [It,
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1915 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1918 const DataLayout &
DL =
Global.getDataLayout();
1921 It->second->addDataSecEntry(VarId,
Asm->getSymbol(&
Global),
Size);
1923 if (
Global.hasInitializer())
1924 processGlobalInitializer(
Global.getInitializer());
1939void BTFDebug::processGlobalInitializer(
const Constant *
C) {
1941 processFuncPrototypes(Fn);
1943 for (
unsigned I = 0,
N = CA->getNumOperands();
I <
N; ++
I)
1944 processGlobalInitializer(CA->getOperand(
I));
1950 if (
MI->getOpcode() == BPF::LD_imm64) {
1961 auto [Imm,
Reloc] = PatchImms[GVar];
1972 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1973 MI->getOpcode() == BPF::CORE_LD32 ||
1974 MI->getOpcode() == BPF::CORE_ST ||
1975 MI->getOpcode() == BPF::CORE_SHIFT) {
1981 uint32_t Imm = PatchImms[GVar].first;
1983 if (
MI->getOperand(0).isImm())
1996void BTFDebug::processFuncPrototypes(
const Function *
F) {
2001 if (!SP || SP->isDefinition())
2005 if (!ProtoFunctions.insert(
F).second)
2010 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
2013 if (
F->hasSection()) {
2016 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
2018 It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
2027 if (MapDefNotCollected) {
2028 processGlobals(
true);
2029 MapDefNotCollected =
false;
2033 processGlobals(
false);
2039 processFuncPrototypes(&
F);
2042 for (
auto &DataSec : DataSecEntries)
2043 addType(std::move(DataSec.second));
2046 for (
auto &
Fixup : FixupDerivedTypes) {
2049 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
2060 if (StructTypeId == 0) {
2061 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
2062 StructTypeId = addType(std::move(FwdTypeEntry));
2065 for (
auto &TypeInfo :
Fixup.second) {
2069 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
2078 for (
const auto &TypeEntry : TypeEntries)
2079 TypeEntry->completeType(*
this);
2083 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,...
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.
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.
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::...