33#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
34#include "llvm/DebugInfo/BTF/BTF.def"
49 : DTy(DTy), NeedsFixup(NeedsFixup),
Name(DTy->
getName()) {
51 case dwarf::DW_TAG_pointer_type:
52 Kind = BTF::BTF_KIND_PTR;
54 case dwarf::DW_TAG_const_type:
55 Kind = BTF::BTF_KIND_CONST;
57 case dwarf::DW_TAG_volatile_type:
58 Kind = BTF::BTF_KIND_VOLATILE;
60 case dwarf::DW_TAG_typedef:
61 Kind = BTF::BTF_KIND_TYPEDEF;
63 case dwarf::DW_TAG_restrict_type:
64 Kind = BTF::BTF_KIND_RESTRICT;
76 Kind = BTF::BTF_KIND_PTR;
88 if (NeedsFixup || !DTy)
92 const DIType *ResolvedType = DTy->getBaseType();
94 assert((
Kind == BTF::BTF_KIND_PTR ||
Kind == BTF::BTF_KIND_CONST ||
95 Kind == BTF::BTF_KIND_VOLATILE) &&
96 "Invalid null basetype");
111 Kind = BTF::BTF_KIND_FWD;
132 case dwarf::DW_ATE_boolean:
135 case dwarf::DW_ATE_signed:
136 case dwarf::DW_ATE_signed_char:
139 case dwarf::DW_ATE_unsigned:
140 case dwarf::DW_ATE_unsigned_char:
147 Kind = BTF::BTF_KIND_INT;
150 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
164 OS.emitInt32(IntVal);
168 bool IsSigned) : ETy(ETy) {
169 Kind = BTF::BTF_KIND_ENUM;
182 for (
const auto Element : Elements) {
183 const auto *Enum = cast<DIEnumerator>(Element);
189 if (Enum->isUnsigned())
190 Value =
static_cast<uint32_t>(Enum->getValue().getZExtValue());
192 Value =
static_cast<uint32_t>(Enum->getValue().getSExtValue());
194 EnumValues.push_back(BTFEnum);
200 for (
const auto &Enum : EnumValues) {
201 OS.emitInt32(Enum.NameOff);
202 OS.emitInt32(Enum.Val);
207 bool IsSigned) : ETy(ETy) {
208 Kind = BTF::BTF_KIND_ENUM64;
221 for (
const auto Element : Elements) {
222 const auto *Enum = cast<DIEnumerator>(Element);
227 if (Enum->isUnsigned())
228 Value =
static_cast<uint64_t>(Enum->getValue().getZExtValue());
230 Value =
static_cast<uint64_t>(Enum->getValue().getSExtValue());
233 EnumValues.push_back(BTFEnum);
239 for (
const auto &Enum : EnumValues) {
240 OS.emitInt32(Enum.NameOff);
242 OS.emitInt32(Enum.Val_Lo32);
244 OS.emitInt32(Enum.Val_Hi32);
249 Kind = BTF::BTF_KIND_ARRAY;
255 ArrayInfo.
Nelems = NumElems;
281 : STy(STy), HasBitField(HasBitField) {
282 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
296 for (
const auto *Element : Elements) {
298 const auto *DDTy = cast<DIDerivedType>(Element);
302 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
303 BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
305 BTFMember.
Offset = DDTy->getOffsetInBits();
307 const auto *
BaseTy = DDTy->getBaseType();
309 Members.push_back(BTFMember);
315 for (
const auto &Member : Members) {
316 OS.emitInt32(Member.NameOff);
317 OS.emitInt32(Member.Type);
319 OS.emitInt32(Member.Offset);
332 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
333 : STy(STy), FuncArgNames(FuncArgNames) {
334 Kind = BTF::BTF_KIND_FUNC_PROTO;
344 auto RetType = Elements[0];
350 for (
unsigned I = 1,
N = Elements.size();
I <
N; ++
I) {
352 auto Element = Elements[
I];
354 Param.NameOff = BDebug.
addString(FuncArgNames[
I]);
360 Parameters.push_back(Param);
366 for (
const auto &Param : Parameters) {
367 OS.emitInt32(Param.NameOff);
368 OS.emitInt32(Param.Type);
375 Kind = BTF::BTF_KIND_FUNC;
392 Kind = BTF::BTF_KIND_VAR;
408 : Asm(AsmPrt),
Name(SecName) {
409 Kind = BTF::BTF_KIND_DATASEC;
422 for (
const auto &V : Vars) {
423 OS.emitInt32(std::get<0>(V));
425 OS.emitInt32(std::get<2>(V));
431 Kind = BTF::BTF_KIND_FLOAT;
447 Kind = BTF::BTF_KIND_DECL_TAG;
467 : DTy(nullptr),
Tag(
Tag) {
468 Kind = BTF::BTF_KIND_TYPE_TAG;
475 Kind = BTF::BTF_KIND_TYPE_TAG;
485 const DIType *ResolvedType = DTy->getBaseType();
495 for (
auto &OffsetM : OffsetToIdMap) {
496 if (Table[OffsetM.second] == S)
497 return OffsetM.first;
501 OffsetToIdMap[
Offset] = Table.size();
502 Table.push_back(std::string(S));
509 LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0),
510 MapDefNotCollected(
true) {
514uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
516 TypeEntry->setId(TypeEntries.size() + 1);
519 TypeEntries.push_back(std::move(TypeEntry));
523uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
524 TypeEntry->setId(TypeEntries.size() + 1);
526 TypeEntries.push_back(std::move(TypeEntry));
535 case dwarf::DW_ATE_boolean:
536 case dwarf::DW_ATE_signed:
537 case dwarf::DW_ATE_signed_char:
538 case dwarf::DW_ATE_unsigned:
539 case dwarf::DW_ATE_unsigned_char:
542 TypeEntry = std::make_unique<BTFTypeInt>(
545 case dwarf::DW_ATE_float:
553 TypeId = addType(std::move(TypeEntry), BTy);
557void BTFDebug::visitSubroutineType(
559 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
570 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
572 TypeId = addType(std::move(TypeEntry));
574 TypeId = addType(std::move(TypeEntry), STy);
577 for (
const auto Element : Elements) {
578 visitTypeEntry(Element);
582void BTFDebug::processDeclAnnotations(DINodeArray
Annotations,
589 const MDNode *MD = cast<MDNode>(Annotation);
591 if (!
Name->getString().equals(
"btf_decl_tag"))
595 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
597 addType(std::move(TypeEntry));
602 uint32_t ProtoTypeId, uint8_t Scope) {
604 std::make_unique<BTFTypeFunc>(SP->
getName(), ProtoTypeId, Scope);
608 for (
const DINode *DN : SP->getRetainedNodes()) {
609 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
612 processDeclAnnotations(DV->getAnnotations(),
FuncId, Arg - 1);
615 processDeclAnnotations(SP->getAnnotations(),
FuncId, -1);
621int BTFDebug::genBTFTypeTags(
const DIDerivedType *DTy,
int BaseTypeId) {
623 DINodeArray Annots = DTy->getAnnotations();
630 if (!
Name->getString().equals(
"btf_type_tag"))
636 if (MDStrs.
size() == 0)
644 std::unique_ptr<BTFTypeTypeTag>
TypeEntry;
647 std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
649 TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
650 TmpTypeId = addType(std::move(TypeEntry));
652 for (
unsigned I = 1;
I < MDStrs.
size();
I++) {
654 TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId,
Value->getString());
655 TmpTypeId = addType(std::move(TypeEntry));
661void BTFDebug::visitStructType(
const DICompositeType *CTy,
bool IsStruct,
669 bool HasBitField =
false;
670 for (
const auto *Element : Elements) {
671 auto E = cast<DIDerivedType>(Element);
672 if (
E->isBitField()) {
679 std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
681 TypeId = addType(std::move(TypeEntry), CTy);
688 for (
const auto *Element : Elements) {
689 const auto Elem = cast<DIDerivedType>(Element);
690 visitTypeEntry(Elem);
691 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
700 visitTypeEntry(ElemType, ElemTypeId,
false,
false);
705 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[
I]))
706 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
707 const DISubrange *SR = cast<DISubrange>(Element);
714 std::make_unique<BTFTypeArray>(ElemTypeId,
715 Count >= 0 ? Count : 0);
717 ElemTypeId = addType(std::move(TypeEntry), CTy);
719 ElemTypeId = addType(std::move(TypeEntry));
728 if (!ArrayIndexTypeId) {
729 auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
730 0,
"__ARRAY_SIZE_TYPE__");
731 ArrayIndexTypeId = addType(std::move(TypeEntry));
741 bool IsSigned =
false;
742 unsigned NumBits = 32;
746 const auto *BTy = cast<DIBasicType>(CTy->
getBaseType());
747 IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
753 auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
754 TypeId = addType(std::move(TypeEntry), CTy);
757 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
758 TypeId = addType(std::move(TypeEntry), CTy);
764void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion,
767 TypeId = addType(std::move(TypeEntry), CTy);
774 if (
Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type) {
777 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type, TypeId);
779 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type, TypeId);
780 }
else if (
Tag == dwarf::DW_TAG_array_type)
781 visitArrayType(CTy, TypeId);
782 else if (
Tag == dwarf::DW_TAG_enumeration_type)
783 visitEnumType(CTy, TypeId);
786bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
787 if (
const auto *CTy = dyn_cast<DICompositeType>(
Base)) {
788 auto CTag = CTy->
getTag();
789 if ((CTag == dwarf::DW_TAG_structure_type ||
790 CTag == dwarf::DW_TAG_union_type) &&
799 bool CheckPointer,
bool SeenPointer) {
804 if (CheckPointer && !SeenPointer) {
805 SeenPointer =
Tag == dwarf::DW_TAG_pointer_type;
808 if (CheckPointer && SeenPointer) {
811 if (IsForwardDeclCandidate(
Base)) {
815 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
true);
816 auto &
Fixup = FixupDerivedTypes[cast<DICompositeType>(
Base)];
818 TypeId = addType(std::move(TypeEntry), DTy);
824 if (
Tag == dwarf::DW_TAG_pointer_type) {
825 int TmpTypeId = genBTFTypeTags(DTy, -1);
826 if (TmpTypeId >= 0) {
828 std::make_unique<BTFTypeDerived>(TmpTypeId,
Tag, DTy->
getName());
829 TypeId = addType(std::move(TypeDEntry), DTy);
831 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
832 TypeId = addType(std::move(TypeEntry), DTy);
834 }
else if (
Tag == dwarf::DW_TAG_typedef ||
Tag == dwarf::DW_TAG_const_type ||
835 Tag == dwarf::DW_TAG_volatile_type ||
836 Tag == dwarf::DW_TAG_restrict_type) {
837 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy,
Tag,
false);
838 TypeId = addType(std::move(TypeEntry), DTy);
839 if (
Tag == dwarf::DW_TAG_typedef)
840 processDeclAnnotations(DTy->getAnnotations(), TypeId, -1);
841 }
else if (
Tag != dwarf::DW_TAG_member) {
848 if (
Tag == dwarf::DW_TAG_member)
849 visitTypeEntry(DTy->getBaseType(), TempTypeId,
true,
false);
851 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
862 bool CheckPointer,
bool SeenPointer) {
863 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
864 TypeId = DIToIdMap[Ty];
895 if (Ty && (!CheckPointer || !SeenPointer)) {
896 if (
const auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
902 if (DIToIdMap.find(
BaseTy) != DIToIdMap.end()) {
903 DTy = dyn_cast<DIDerivedType>(
BaseTy);
905 if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type) {
907 if (IsForwardDeclCandidate(
BaseTy))
911 visitTypeEntry(
BaseTy, TmpTypeId, CheckPointer, SeenPointer);
921 if (
const auto *BTy = dyn_cast<DIBasicType>(Ty))
922 visitBasicType(BTy, TypeId);
923 else if (
const auto *STy = dyn_cast<DISubroutineType>(Ty))
924 visitSubroutineType(STy,
false, std::unordered_map<uint32_t, StringRef>(),
926 else if (
const auto *CTy = dyn_cast<DICompositeType>(Ty))
927 visitCompositeType(CTy, TypeId);
928 else if (
const auto *DTy = dyn_cast<DIDerivedType>(Ty))
929 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
934void BTFDebug::visitTypeEntry(
const DIType *Ty) {
936 visitTypeEntry(Ty, TypeId,
false,
false);
939void BTFDebug::visitMapDefType(
const DIType *Ty,
uint32_t &TypeId) {
940 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
941 TypeId = DIToIdMap[Ty];
946 const DIType *OrigTy = Ty;
947 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
949 if (
Tag != dwarf::DW_TAG_typedef &&
Tag != dwarf::DW_TAG_const_type &&
950 Tag != dwarf::DW_TAG_volatile_type &&
951 Tag != dwarf::DW_TAG_restrict_type)
953 Ty = DTy->getBaseType();
956 const auto *CTy = dyn_cast<DICompositeType>(Ty);
966 for (
const auto *Element : Elements) {
967 const auto *MemberType = cast<DIDerivedType>(Element);
968 visitTypeEntry(MemberType->getBaseType());
972 visitTypeEntry(OrigTy, TypeId,
false,
false);
976std::string BTFDebug::populateFileContent(
const DISubprogram *SP) {
978 std::string FileName;
980 if (!
File->getFilename().startswith(
"/") &&
File->getDirectory().size())
981 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
983 FileName = std::string(
File->getFilename());
989 std::vector<std::string>
Content;
993 std::unique_ptr<MemoryBuffer> Buf;
997 else if (
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
999 Buf = std::move(*BufOrErr);
1002 Content.push_back(std::string(*
I));
1004 FileContent[FileName] =
Content;
1010 std::string FileName = populateFileContent(SP);
1016 if (Line < FileContent[FileName].
size())
1022 LineInfoTable[SecNameOff].push_back(LineInfo);
1025void BTFDebug::emitCommonHeader() {
1032void BTFDebug::emitBTFSection() {
1034 if (!TypeEntries.size() && StringTable.
getSize() == 1)
1040 OS.switchSection(Sec);
1047 for (
const auto &TypeEntry : TypeEntries)
1049 StrLen = StringTable.
getSize();
1052 OS.emitInt32(TypeLen);
1053 OS.emitInt32(TypeLen);
1054 OS.emitInt32(StrLen);
1057 for (
const auto &TypeEntry : TypeEntries)
1062 for (
const auto &S : StringTable.
getTable()) {
1063 OS.AddComment(
"string offset=" + std::to_string(StringOffset));
1066 StringOffset += S.size() + 1;
1070void BTFDebug::emitBTFExtSection() {
1073 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1074 !FieldRelocTable.size())
1080 OS.switchSection(Sec);
1090 for (
const auto &FuncSec : FuncInfoTable) {
1094 for (
const auto &LineSec : LineInfoTable) {
1098 for (
const auto &FieldRelocSec : FieldRelocTable) {
1107 OS.emitInt32(FuncLen);
1108 OS.emitInt32(FuncLen);
1109 OS.emitInt32(LineLen);
1110 OS.emitInt32(FuncLen + LineLen);
1111 OS.emitInt32(FieldRelocLen);
1114 OS.AddComment(
"FuncInfo");
1116 for (
const auto &FuncSec : FuncInfoTable) {
1117 OS.AddComment(
"FuncInfo section string offset=" +
1118 std::to_string(FuncSec.first));
1119 OS.emitInt32(FuncSec.first);
1120 OS.emitInt32(FuncSec.second.size());
1121 for (
const auto &FuncInfo : FuncSec.second) {
1123 OS.emitInt32(FuncInfo.TypeId);
1128 OS.AddComment(
"LineInfo");
1130 for (
const auto &LineSec : LineInfoTable) {
1131 OS.AddComment(
"LineInfo section string offset=" +
1132 std::to_string(LineSec.first));
1133 OS.emitInt32(LineSec.first);
1134 OS.emitInt32(LineSec.second.size());
1135 for (
const auto &LineInfo : LineSec.second) {
1139 OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) +
" Col " +
1146 if (FieldRelocLen) {
1147 OS.AddComment(
"FieldReloc");
1149 for (
const auto &FieldRelocSec : FieldRelocTable) {
1150 OS.AddComment(
"Field reloc section string offset=" +
1151 std::to_string(FieldRelocSec.first));
1152 OS.emitInt32(FieldRelocSec.first);
1153 OS.emitInt32(FieldRelocSec.second.size());
1154 for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
1156 OS.emitInt32(FieldRelocInfo.TypeID);
1157 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1158 OS.emitInt32(FieldRelocInfo.RelocKind);
1166 auto *Unit = SP->getUnit();
1169 SkipInstruction =
true;
1172 SkipInstruction =
false;
1193 if (MapDefNotCollected) {
1194 processGlobals(
true);
1195 MapDefNotCollected =
false;
1201 std::unordered_map<uint32_t, StringRef> FuncArgNames;
1202 for (
const DINode *DN : SP->getRetainedNodes()) {
1203 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
1207 visitTypeEntry(DV->getType());
1208 FuncArgNames[Arg] = DV->getName();
1215 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId);
1219 uint32_t FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1221 for (
const auto &TypeEntry : TypeEntries)
1222 TypeEntry->completeType(*
this);
1227 FuncInfo.
Label = FuncLabel;
1228 FuncInfo.
TypeId = FuncTypeId;
1231 const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
1232 assert(SectionELF &&
"Null section for Function Label");
1237 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1241 SkipInstruction =
false;
1242 LineInfoGenerated =
false;
1248unsigned BTFDebug::populateType(
const DIType *Ty) {
1250 visitTypeEntry(Ty, Id,
false,
false);
1251 for (
const auto &TypeEntry : TypeEntries)
1252 TypeEntry->completeType(*
this);
1257void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym,
uint32_t RootId,
1260 FieldReloc.
Label = ORSym;
1261 FieldReloc.
TypeID = RootId;
1267 size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
1270 SecondColon - FirstColon);
1272 FirstDollar - SecondColon);
1275 FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
1276 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1281 FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
1282 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
1284 FieldRelocTable[SecNameOff].push_back(FieldReloc);
1291 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1294 processFuncPrototypes(dyn_cast<Function>(GVal));
1302 MCSymbol *ORSym =
OS.getContext().createTempSymbol();
1303 OS.emitLabel(ORSym);
1306 uint32_t RootId = populateType(dyn_cast<DIType>(MDN));
1307 generatePatchImmReloc(ORSym, RootId, GVar,
1315 if (SkipInstruction ||
MI->isMetaInstruction() ||
1319 if (
MI->isInlineAsm()) {
1321 unsigned NumDefs = 0;
1336 if (
MI->getOpcode() == BPF::LD_imm64) {
1351 processGlobalValue(
MI->getOperand(1));
1352 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1353 MI->getOpcode() == BPF::CORE_LD32 ||
1354 MI->getOpcode() == BPF::CORE_ST ||
1355 MI->getOpcode() == BPF::CORE_SHIFT) {
1357 processGlobalValue(
MI->getOperand(3));
1358 }
else if (
MI->getOpcode() == BPF::JAL) {
1362 processFuncPrototypes(dyn_cast<Function>(MO.
getGlobal()));
1375 if (LineInfoGenerated ==
false) {
1376 auto *S =
MI->getMF()->getFunction().getSubprogram();
1380 constructLineInfo(S, FuncLabel, S->getLine(), 0);
1381 LineInfoGenerated =
true;
1388 MCSymbol *LineSym =
OS.getContext().createTempSymbol();
1389 OS.emitLabel(LineSym);
1392 auto SP =
DL->getScope()->getSubprogram();
1393 constructLineInfo(SP, LineSym,
DL.getLine(),
DL.getCol());
1395 LineInfoGenerated =
true;
1399void BTFDebug::processGlobals(
bool ProcessingMapDef) {
1405 std::optional<SectionKind> GVKind;
1407 if (!
Global.isDeclarationForLinker())
1410 if (
Global.isDeclarationForLinker())
1411 SecName =
Global.hasSection() ?
Global.getSection() :
"";
1412 else if (GVKind->isCommon())
1420 if (ProcessingMapDef != SecName.
startswith(
".maps"))
1426 if (SecName ==
".rodata" &&
Global.hasPrivateLinkage() &&
1427 DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
1429 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1430 DataSecEntries[std::string(SecName)] =
1431 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1436 Global.getDebugInfo(GVs);
1439 if (GVs.
size() == 0)
1444 for (
auto *GVE : GVs) {
1447 visitMapDefType(
DIGlobal->getType(), GVTypeId);
1449 visitTypeEntry(
DIGlobal->getType(), GVTypeId,
false,
false);
1471 }
else if (
Global.hasInitializer()) {
1478 std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
1479 uint32_t VarId = addType(std::move(VarEntry));
1481 processDeclAnnotations(
DIGlobal->getAnnotations(), VarId, -1);
1484 if (SecName.
empty())
1488 if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
1489 DataSecEntries[std::string(SecName)] =
1490 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1497 DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId,
1504 if (
MI->getOpcode() == BPF::LD_imm64) {
1508 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1515 Imm = PatchImms[GVar].first;
1516 Reloc = PatchImms[GVar].second;
1531 }
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
1532 MI->getOpcode() == BPF::CORE_LD32 ||
1533 MI->getOpcode() == BPF::CORE_ST ||
1534 MI->getOpcode() == BPF::CORE_SHIFT) {
1538 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1540 uint32_t Imm = PatchImms[GVar].first;
1542 if (
MI->getOperand(0).isImm())
1555void BTFDebug::processFuncPrototypes(
const Function *
F) {
1560 if (!SP || SP->isDefinition())
1564 if (!ProtoFunctions.insert(
F).second)
1568 const std::unordered_map<uint32_t, StringRef> FuncArgNames;
1569 visitSubroutineType(SP->getType(),
false, FuncArgNames, ProtoTypeId);
1572 if (
F->hasSection()) {
1575 if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
1576 DataSecEntries[std::string(SecName)] =
1577 std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
1581 DataSecEntries[std::string(SecName)]->addDataSecEntry(
FuncId,
1588 if (MapDefNotCollected) {
1589 processGlobals(
true);
1590 MapDefNotCollected =
false;
1594 processGlobals(
false);
1596 for (
auto &DataSec : DataSecEntries)
1597 addType(std::move(DataSec.second));
1600 for (
auto &
Fixup : FixupDerivedTypes) {
1603 bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
1614 if (StructTypeId == 0) {
1615 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
1616 StructTypeId = addType(std::move(FwdTypeEntry));
1619 for (
auto &TypeInfo :
Fixup.second) {
1623 int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
1632 for (
const auto &TypeEntry : TypeEntries)
1633 TypeEntry->completeType(*
this);
1637 emitBTFExtSection();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const char * BTFKindStr[]
This file contains support for writing BTF debug info.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
PowerPC TLS Dynamic Call Fixup
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Annotations lets you mark points and ranges inside source code, for tests:
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.
MCSymbol * getFunctionBegin() const
void emitLabelReference(const MCSymbol *Label, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label" where the size in bytes of the directive is specified by Size and L...
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.
std::vector< std::string > & getTable()
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 std::unordered_map< uint32_t, StringRef > &FuncArgNames)
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 the shared class of boolean and integer constants.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Basic type, like 'int' or 'float'.
unsigned getEncoding() const
DINodeArray getElements() const
DINodeArray getAnnotations() const
DIType * getBaseType() const
Tagged DWARF-like metadata node.
dwarf::Tag getTag() const
StringRef getName() const
BoundType getCount() const
Type array for a subprogram.
DITypeRefArray getTypeArray() const
uint64_t getOffsetInBits() const
StringRef getName() const
bool isForwardDecl() const
uint64_t getSizeInBits() const
A parsed version of the target data layout string in and methods for querying it.
Base class for debug information backends.
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.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
Represents either an error or a value T.
DISubprogram * getSubprogram() const
Get the attached subprogram.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
@ 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(unsigned 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.
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
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
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
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.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
StringRef - 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).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
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.
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
static Twine utohexstr(const uint64_t &Val)
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
A forward iterator which reads text lines from a buffer.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MAX_VLEN
Max # of struct/union/enum members or func args.
@ VAR_GLOBAL_ALLOCATED
Linkage: ExternalLinkage.
@ VAR_STATIC
Linkage: InternalLinkage.
@ VAR_GLOBAL_EXTERNAL
Linkage: ExternalLinkage.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
@ Global
Append to llvm.global_dtors.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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
uint32_t Nelems
Number of elements for this array.
uint32_t IndexType
Index type.
uint32_t ElemType
Element type.
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".
uint32_t NameOff
Type name offset in the string table.
uint32_t Info
"Info" bits arrangement: Bits 0-15: vlen (e.g.
Container for description of a global variable.