36#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME, 
   37#include "llvm/DebugInfo/BTF/BTF.def" 
 
   44  if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
 
   45    return DerivedTy->getBaseType();
 
 
   61    : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->
getName()) {
 
   63  case dwarf::DW_TAG_pointer_type:
 
   64    Kind = BTF::BTF_KIND_PTR;
 
   66  case dwarf::DW_TAG_const_type:
 
   67    Kind = BTF::BTF_KIND_CONST;
 
   69  case dwarf::DW_TAG_volatile_type:
 
   70    Kind = BTF::BTF_KIND_VOLATILE;
 
   72  case dwarf::DW_TAG_typedef:
 
   73    Kind = BTF::BTF_KIND_TYPEDEF;
 
   75  case dwarf::DW_TAG_restrict_type:
 
   76    Kind = BTF::BTF_KIND_RESTRICT;
 
 
   87    : DTy(nullptr), NeedsFixup(
false), Name(Name) {
 
   88  Kind = BTF::BTF_KIND_PTR;
 
 
   99  case BTF::BTF_KIND_PTR:
 
  100  case BTF::BTF_KIND_CONST:
 
  101  case BTF::BTF_KIND_VOLATILE:
 
  102  case BTF::BTF_KIND_RESTRICT:
 
  117  if (NeedsFixup || !DTy)
 
  123    assert((
Kind == BTF::BTF_KIND_PTR || 
Kind == BTF::BTF_KIND_CONST ||
 
  124            Kind == BTF::BTF_KIND_VOLATILE) &&
 
  125           "Invalid null basetype");
 
 
  140  Kind = BTF::BTF_KIND_FWD;
 
 
  161  case dwarf::DW_ATE_boolean:
 
  164  case dwarf::DW_ATE_signed:
 
  165  case dwarf::DW_ATE_signed_char:
 
  168  case dwarf::DW_ATE_unsigned:
 
  169  case dwarf::DW_ATE_unsigned_char:
 
  176  Kind = BTF::BTF_KIND_INT;
 
  179  IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
 
 
  197    bool IsSigned) : ETy(ETy) {
 
  198  Kind = BTF::BTF_KIND_ENUM;
 
 
  210  DINodeArray Elements = ETy->getElements();
 
  211  for (
const auto Element : Elements) {
 
  218    if (Enum->isUnsigned())
 
  219      Value = 
static_cast<uint32_t>(Enum->getValue().getZExtValue());
 
  221      Value = 
static_cast<uint32_t>(Enum->getValue().getSExtValue());
 
  223    EnumValues.push_back(BTFEnum);
 
 
  229  for (
const auto &Enum : EnumValues) {
 
 
  236    bool IsSigned) : ETy(ETy) {
 
  237  Kind = BTF::BTF_KIND_ENUM64;
 
 
  249  DINodeArray Elements = ETy->getElements();
 
  250  for (
const auto Element : Elements) {
 
  256    if (Enum->isUnsigned())
 
  257      Value = Enum->getValue().getZExtValue();
 
  259      Value = 
static_cast<uint64_t>(Enum->getValue().getSExtValue());
 
  262    EnumValues.push_back(BTFEnum);
 
 
  268  for (
const auto &Enum : EnumValues) {
 
 
  278  Kind = BTF::BTF_KIND_ARRAY;
 
  283  ArrayInfo.ElemType = ElemTypeId;
 
  284  ArrayInfo.Nelems = NumElems;
 
 
  310    : STy(STy), HasBitField(HasBitField) {
 
  311  Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
 
  313  BTFType.Info = (HasBitField << 31) | (
Kind << 24) | Vlen;
 
 
  323  if (STy->getTag() == dwarf::DW_TAG_variant_part) {
 
  332    const auto *DTy = STy->getDiscriminator();
 
  336      Discriminator.NameOff = BDebug.
addString(DTy->getName());
 
  337      Discriminator.Offset = DTy->getOffsetInBits();
 
  338      const auto *BaseTy = DTy->getBaseType();
 
  339      Discriminator.Type = BDebug.
getTypeId(BaseTy);
 
  341      Members.push_back(Discriminator);
 
  346  const DINodeArray Elements = STy->getElements();
 
  347  for (
const auto *Element : Elements) {
 
  350    switch (Element->getTag()) {
 
  351    case dwarf::DW_TAG_member: {
 
  356        uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
 
  357        BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
 
  359        BTFMember.
Offset = DDTy->getOffsetInBits();
 
  365    case dwarf::DW_TAG_variant_part: {
 
  369      BTFMember.
Offset = DCTy->getOffsetInBits();
 
  376    Members.push_back(BTFMember);
 
 
  382  for (
const auto &Member : Members) {
 
 
  399    const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
 
  400    : STy(STy), FuncArgNames(FuncArgNames) {
 
  401  Kind = BTF::BTF_KIND_FUNC_PROTO;
 
 
  417  for (
unsigned I = 1, 
N = Elements.size(); 
I < 
N; ++
I) {
 
  421      Param.NameOff = BDebug.
addString(FuncArgNames[
I]);
 
  427    Parameters.push_back(Param);
 
 
  433  for (
const auto &Param : Parameters) {
 
 
  442  Kind = BTF::BTF_KIND_FUNC;
 
 
  459  Kind = BTF::BTF_KIND_VAR;
 
 
  475    : Asm(AsmPrt), Name(SecName) {
 
  476  Kind = BTF::BTF_KIND_DATASEC;
 
 
  489  for (
const auto &V : Vars) {
 
  491    Asm->emitLabelReference(std::get<1>(V), 4);
 
 
  498  Kind = BTF::BTF_KIND_FLOAT;
 
 
  514  Kind = BTF::BTF_KIND_DECL_TAG;
 
 
  534    : DTy(nullptr), Tag(Tag) {
 
  535  Kind = BTF::BTF_KIND_TYPE_TAG;
 
 
  541    : DTy(DTy), Tag(Tag) {
 
  542  Kind = BTF::BTF_KIND_TYPE_TAG;
 
 
  562  for (
auto &OffsetM : OffsetToIdMap) {
 
  563    if (Table[OffsetM.second] == S)
 
  564      return OffsetM.first;
 
  568  OffsetToIdMap[
Offset] = Table.size();
 
  569  Table.push_back(std::string(S));
 
  570  Size += S.
size() + 1;
 
 
  576      LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0),
 
  577      MapDefNotCollected(
true) {
 
 
  581uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
 
  583  TypeEntry->setId(TypeEntries.size() + 1);
 
  586  TypeEntries.push_back(std::move(TypeEntry));
 
  590uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
 
  591  TypeEntry->setId(TypeEntries.size() + 1);
 
  593  TypeEntries.push_back(std::move(TypeEntry));
 
  597void BTFDebug::visitBasicType(
const DIBasicType *BTy, uint32_t &TypeId) {
 
  602  case dwarf::DW_ATE_boolean:
 
  603  case dwarf::DW_ATE_signed:
 
  604  case dwarf::DW_ATE_signed_char:
 
  605  case dwarf::DW_ATE_unsigned:
 
  606  case dwarf::DW_ATE_unsigned_char:
 
  609    TypeEntry = std::make_unique<BTFTypeInt>(
 
  612  case dwarf::DW_ATE_float:
 
  620  TypeId = addType(std::move(TypeEntry), BTy);
 
  624void BTFDebug::visitSubroutineType(
 
  626    const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
 
  629  uint32_t VLen = 
Elements.size() - 1;
 
  637  auto TypeEntry = std::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
 
  639    TypeId = addType(std::move(TypeEntry)); 
 
  641    TypeId = addType(std::move(TypeEntry), STy); 
 
  644  for (
const auto Element : Elements) {
 
  645    visitTypeEntry(Element);
 
  649void BTFDebug::processDeclAnnotations(DINodeArray 
Annotations,
 
  655  for (
const Metadata *Annotation : Annotations->operands()) {
 
  658    if (
Name->getString() != 
"btf_decl_tag")
 
  662    auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
 
  664    addType(std::move(TypeEntry));
 
  668uint32_t BTFDebug::processDISubprogram(
const DISubprogram *SP,
 
  669                                       uint32_t ProtoTypeId, uint8_t Scope) {
 
  671      std::make_unique<BTFTypeFunc>(
SP->getName(), ProtoTypeId, Scope);
 
  672  uint32_t FuncId = addType(std::move(FuncTypeEntry));
 
  675  for (
const DINode *DN : 
SP->getRetainedNodes()) {
 
  677      uint32_t Arg = DV->getArg();
 
  679        processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
 
  682  processDeclAnnotations(
SP->getAnnotations(), FuncId, -1);
 
  688int BTFDebug::genBTFTypeTags(
const DIDerivedType *DTy, 
int BaseTypeId) {
 
  694    for (
const Metadata *Annotations : Annots->operands()) {
 
  697      if (
Name->getString() != 
"btf_type_tag")
 
  703  if (MDStrs.
size() == 0)
 
  711  std::unique_ptr<BTFTypeTypeTag> 
TypeEntry;
 
  714        std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
 
  716    TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
 
  717  TmpTypeId = addType(std::move(TypeEntry));
 
  719  for (
unsigned I = 1; 
I < MDStrs.
size(); 
I++) {
 
  720    const MDString *
Value = MDStrs[
I];
 
  721    TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId, 
Value->getString());
 
  722    TmpTypeId = addType(std::move(TypeEntry));
 
  728void BTFDebug::visitStructType(
const DICompositeType *CTy, 
bool IsStruct,
 
  735  if (CTy->
getTag() == dwarf::DW_TAG_variant_part) {
 
  746  bool HasBitField = 
false;
 
  747  for (
const auto *Element : Elements) {
 
  748    if (Element->getTag() == dwarf::DW_TAG_member) {
 
  750      if (
E->isBitField()) {
 
  758      std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
 
  760  TypeId = addType(std::move(TypeEntry), CTy);
 
  767  for (
const auto *Element : Elements) {
 
  768    switch (Element->getTag()) {
 
  769    case dwarf::DW_TAG_member: {
 
  771      visitTypeEntry(Elem);
 
  772      processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
 
  775    case dwarf::DW_TAG_variant_part: {
 
  777      visitTypeEntry(Elem);
 
  778      processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
 
  788void BTFDebug::visitArrayType(
const DICompositeType *CTy, uint32_t &TypeId) {
 
  792  visitTypeEntry(ElemType, ElemTypeId, 
false, 
false);
 
  798      if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
 
  801        int64_t 
Count = CI->getSExtValue();
 
  806            std::make_unique<BTFTypeArray>(ElemTypeId,
 
  809          ElemTypeId = addType(std::move(TypeEntry), CTy);
 
  811          ElemTypeId = addType(std::move(TypeEntry));
 
  820  if (!ArrayIndexTypeId) {
 
  821    auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
 
  822                                                   0, 
"__ARRAY_SIZE_TYPE__");
 
  823    ArrayIndexTypeId = addType(std::move(TypeEntry));
 
  827void BTFDebug::visitEnumType(
const DICompositeType *CTy, uint32_t &TypeId) {
 
  833  bool IsSigned = 
false;
 
  834  unsigned NumBits = 32;
 
  839    IsSigned = BTy->
getEncoding() == dwarf::DW_ATE_signed ||
 
  845    auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
 
  846    TypeId = addType(std::move(TypeEntry), CTy);
 
  849    auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
 
  850    TypeId = addType(std::move(TypeEntry), CTy);
 
  856void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy, 
bool IsUnion,
 
  859  TypeId = addType(std::move(TypeEntry), CTy);
 
  867  case dwarf::DW_TAG_structure_type:
 
  868  case dwarf::DW_TAG_union_type:
 
  869  case dwarf::DW_TAG_variant_part:
 
  872      visitFwdDeclType(CTy, 
Tag == dwarf::DW_TAG_union_type, TypeId);
 
  874      visitStructType(CTy, 
Tag == dwarf::DW_TAG_structure_type, TypeId);
 
  876  case dwarf::DW_TAG_array_type:
 
  877    visitArrayType(CTy, TypeId);
 
  879  case dwarf::DW_TAG_enumeration_type:
 
  880    visitEnumType(CTy, TypeId);
 
  887bool BTFDebug::IsForwardDeclCandidate(
const DIType *
Base) {
 
  889    auto CTag = CTy->
getTag();
 
  890    if ((CTag == dwarf::DW_TAG_structure_type ||
 
  891         CTag == dwarf::DW_TAG_union_type) &&
 
  899void BTFDebug::visitDerivedType(
const DIDerivedType *DTy, uint32_t &TypeId,
 
  900                                bool CheckPointer, 
bool SeenPointer) {
 
  903  if (
Tag == dwarf::DW_TAG_atomic_type)
 
  904    return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
 
  909  if (CheckPointer && !SeenPointer) {
 
  913  if (CheckPointer && SeenPointer) {
 
  914    const DIType *
Base = DTy->getBaseType();
 
  916      if (IsForwardDeclCandidate(
Base)) {
 
  920        auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, 
Tag, 
true);
 
  923        TypeId = addType(std::move(TypeEntry), DTy);
 
  929  if (
Tag == dwarf::DW_TAG_pointer_type) {
 
  930    int TmpTypeId = genBTFTypeTags(DTy, -1);
 
  931    if (TmpTypeId >= 0) {
 
  933          std::make_unique<BTFTypeDerived>(TmpTypeId, 
Tag, DTy->
getName());
 
  934      TypeId = addType(std::move(TypeDEntry), DTy);
 
  936      auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, 
Tag, 
false);
 
  937      TypeId = addType(std::move(TypeEntry), DTy);
 
  939  } 
else if (
Tag == dwarf::DW_TAG_typedef || 
Tag == dwarf::DW_TAG_const_type ||
 
  940             Tag == dwarf::DW_TAG_volatile_type ||
 
  941             Tag == dwarf::DW_TAG_restrict_type) {
 
  942    auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, 
Tag, 
false);
 
  943    TypeId = addType(std::move(TypeEntry), DTy);
 
  944    if (
Tag == dwarf::DW_TAG_typedef)
 
  946  } 
else if (
Tag != dwarf::DW_TAG_member) {
 
  952  uint32_t TempTypeId = 0;
 
  953  if (
Tag == dwarf::DW_TAG_member)
 
  954    visitTypeEntry(DTy->getBaseType(), TempTypeId, 
true, 
false);
 
  956    visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
 
  966void BTFDebug::visitTypeEntry(
const DIType *Ty, uint32_t &TypeId,
 
  967                              bool CheckPointer, 
bool SeenPointer) {
 
  968  if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
 
  969    TypeId = DIToIdMap[Ty];
 
 1000    if (Ty && (!CheckPointer || !SeenPointer)) {
 
 1003          const DIType *BaseTy = DTy->getBaseType();
 
 1007          if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
 
 1010            if (CheckPointer && DTy->
getTag() == dwarf::DW_TAG_pointer_type &&
 
 1013              if (IsForwardDeclCandidate(BaseTy))
 
 1017            visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
 
 1028    visitBasicType(BTy, TypeId);
 
 1030    visitSubroutineType(STy, 
false, std::unordered_map<uint32_t, StringRef>(),
 
 1033    visitCompositeType(CTy, TypeId);
 
 1035    visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
 
 1040void BTFDebug::visitTypeEntry(
const DIType *Ty) {
 
 1042  visitTypeEntry(Ty, TypeId, 
false, 
false);
 
 1045void BTFDebug::visitMapDefType(
const DIType *Ty, uint32_t &TypeId) {
 
 1046  if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
 
 1047    TypeId = DIToIdMap[Ty];
 
 1053  case dwarf::DW_TAG_typedef:
 
 1054  case dwarf::DW_TAG_const_type:
 
 1055  case dwarf::DW_TAG_volatile_type:
 
 1056  case dwarf::DW_TAG_restrict_type:
 
 1057  case dwarf::DW_TAG_pointer_type:
 
 1060  case dwarf::DW_TAG_array_type:
 
 1064  case dwarf::DW_TAG_structure_type: {
 
 1068    for (
const auto *Element : Elements) {
 
 1070      const DIType *MemberBaseType = MemberType->getBaseType();
 
 1079        visitMapDefType(MemberBaseType, TmpId);
 
 1081        visitTypeEntry(MemberBaseType);
 
 1091  visitTypeEntry(Ty, TypeId, 
false, 
false);
 
 1095std::string BTFDebug::populateFileContent(
const DIFile *File) {
 
 1096  std::string FileName;
 
 1098  if (!
File->getFilename().starts_with(
"/") && 
File->getDirectory().size())
 
 1099    FileName = 
File->getDirectory().str() + 
"/" + 
File->getFilename().str();
 
 1101    FileName = std::string(
File->getFilename());
 
 1104  if (FileContent.contains(FileName))
 
 1107  std::vector<std::string> Content;
 
 1109  Content.push_back(Line); 
 
 1111  std::unique_ptr<MemoryBuffer> Buf;
 
 1115  else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
 
 1117    Buf = std::move(*BufOrErr);
 
 1119    for (line_iterator 
I(*Buf, 
false), 
E; 
I != 
E; ++
I)
 
 1120      Content.push_back(std::string(*
I));
 
 1122  FileContent[FileName] = Content;
 
 1126void BTFDebug::constructLineInfo(
MCSymbol *Label, 
const DIFile *File,
 
 1127                                 uint32_t Line, uint32_t Column) {
 
 1128  std::string FileName = populateFileContent(File);
 
 1129  BTFLineInfo LineInfo;
 
 1134  const auto &Content = FileContent[FileName];
 
 1135  if (Line < Content.size())
 
 1141  LineInfoTable[SecNameOff].push_back(LineInfo);
 
 1144void BTFDebug::emitCommonHeader() {
 
 1151void BTFDebug::emitBTFSection() {
 
 1153  if (!TypeEntries.size() && StringTable.getSize() == 1)
 
 1156  MCContext &Ctx = OS.getContext();
 
 1159  OS.switchSection(Sec);
 
 1165  uint32_t TypeLen = 0, StrLen;
 
 1166  for (
const auto &TypeEntry : TypeEntries)
 
 1168  StrLen = StringTable.getSize();
 
 1171  OS.emitInt32(TypeLen);
 
 1172  OS.emitInt32(TypeLen);
 
 1173  OS.emitInt32(StrLen);
 
 1176  for (
const auto &TypeEntry : TypeEntries)
 
 1180  uint32_t StringOffset = 0;
 
 1181  for (
const auto &S : StringTable.getTable()) {
 
 1182    OS.AddComment(
"string offset=" + std::to_string(StringOffset));
 
 1184    OS.emitBytes(StringRef(
"\0", 1));
 
 1185    StringOffset += S.size() + 1;
 
 1189void BTFDebug::emitBTFExtSection() {
 
 1192  if (!FuncInfoTable.size() && !LineInfoTable.size() &&
 
 1193      !FieldRelocTable.size())
 
 1196  MCContext &Ctx = OS.getContext();
 
 1199  OS.switchSection(Sec);
 
 1206  uint32_t FuncLen = 4, LineLen = 4;
 
 1208  uint32_t FieldRelocLen = 0;
 
 1209  for (
const auto &FuncSec : FuncInfoTable) {
 
 1213  for (
const auto &LineSec : LineInfoTable) {
 
 1217  for (
const auto &FieldRelocSec : FieldRelocTable) {
 
 1226  OS.emitInt32(FuncLen);
 
 1227  OS.emitInt32(FuncLen);
 
 1228  OS.emitInt32(LineLen);
 
 1229  OS.emitInt32(FuncLen + LineLen);
 
 1230  OS.emitInt32(FieldRelocLen);
 
 1233  OS.AddComment(
"FuncInfo");
 
 1235  for (
const auto &FuncSec : FuncInfoTable) {
 
 1236    OS.AddComment(
"FuncInfo section string offset=" +
 
 1237                  std::to_string(FuncSec.first));
 
 1238    OS.emitInt32(FuncSec.first);
 
 1239    OS.emitInt32(FuncSec.second.size());
 
 1240    for (
const auto &FuncInfo : FuncSec.second) {
 
 1241      Asm->emitLabelReference(FuncInfo.Label, 4);
 
 1242      OS.emitInt32(FuncInfo.TypeId);
 
 1247  OS.AddComment(
"LineInfo");
 
 1249  for (
const auto &LineSec : LineInfoTable) {
 
 1250    OS.AddComment(
"LineInfo section string offset=" +
 
 1251                  std::to_string(LineSec.first));
 
 1252    OS.emitInt32(LineSec.first);
 
 1253    OS.emitInt32(LineSec.second.size());
 
 1254    for (
const auto &LineInfo : LineSec.second) {
 
 1255      Asm->emitLabelReference(LineInfo.
Label, 4);
 
 1257      OS.emitInt32(LineInfo.
LineOff);
 
 1258      OS.AddComment(
"Line " + std::to_string(LineInfo.
LineNum) + 
" Col " +
 
 1265  if (FieldRelocLen) {
 
 1266    OS.AddComment(
"FieldReloc");
 
 1268    for (
const auto &FieldRelocSec : FieldRelocTable) {
 
 1269      OS.AddComment(
"Field reloc section string offset=" +
 
 1270                    std::to_string(FieldRelocSec.first));
 
 1271      OS.emitInt32(FieldRelocSec.first);
 
 1272      OS.emitInt32(FieldRelocSec.second.size());
 
 1273      for (
const auto &FieldRelocInfo : FieldRelocSec.second) {
 
 1274        Asm->emitLabelReference(FieldRelocInfo.Label, 4);
 
 1275        OS.emitInt32(FieldRelocInfo.TypeID);
 
 1276        OS.emitInt32(FieldRelocInfo.OffsetNameOff);
 
 1277        OS.emitInt32(FieldRelocInfo.RelocKind);
 
 1285  auto *Unit = SP->getUnit();
 
 1288    SkipInstruction = 
true;
 
 1291  SkipInstruction = 
false;
 
 1312  if (MapDefNotCollected) {
 
 1313    processGlobals(
true);
 
 1314    MapDefNotCollected = 
false;
 
 1320  std::unordered_map<uint32_t, StringRef> FuncArgNames;
 
 1321  for (
const DINode *DN : SP->getRetainedNodes()) {
 
 1326        visitTypeEntry(DV->getType());
 
 1327        FuncArgNames[Arg] = DV->getName();
 
 1334  visitSubroutineType(SP->getType(), 
true, FuncArgNames, ProtoTypeId);
 
 1338  uint32_t FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
 
 1340  for (
const auto &TypeEntry : TypeEntries)
 
 1341    TypeEntry->completeType(*
this);
 
 1346  FuncInfo.
Label = FuncLabel;
 
 1347  FuncInfo.
TypeId = FuncTypeId;
 
 1354  FuncInfoTable[SecNameOff].push_back(FuncInfo);
 
 
 1358  SkipInstruction = 
false;
 
 1359  LineInfoGenerated = 
false;
 
 
 1365unsigned BTFDebug::populateType(
const DIType *Ty) {
 
 1367  visitTypeEntry(Ty, Id, 
false, 
false);
 
 1368  for (
const auto &TypeEntry : TypeEntries)
 
 1369    TypeEntry->completeType(*
this);
 
 1374void BTFDebug::generatePatchImmReloc(
const MCSymbol *ORSym, 
uint32_t RootId,
 
 1377  FieldReloc.
Label = ORSym;
 
 1378  FieldReloc.
TypeID = RootId;
 
 1384    size_t SecondColon = AccessPattern.
find_first_of(
':', FirstColon + 1);
 
 1387        SecondColon - FirstColon);
 
 1389        FirstDollar - SecondColon);
 
 1392    FieldReloc.
RelocKind = std::stoull(std::string(RelocKindStr));
 
 1393    PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
 
 1396    StringRef RelocStr = AccessPattern.
substr(FirstDollar + 1);
 
 1398    FieldReloc.
RelocKind = std::stoull(std::string(RelocStr));
 
 1399    PatchImms[GVar] = std::make_pair(RootId, FieldReloc.
RelocKind);
 
 1401  FieldRelocTable[SecNameOff].push_back(FieldReloc);
 
 1407    const GlobalValue *GVal = MO.
getGlobal();
 
 1419    MCSymbol *ORSym = OS.getContext().createTempSymbol();
 
 1420    OS.emitLabel(ORSym);
 
 1422    MDNode *MDN = GVar->
getMetadata(LLVMContext::MD_preserve_access_index);
 
 1424    generatePatchImmReloc(ORSym, RootId, GVar,
 
 1432  if (SkipInstruction || 
MI->isMetaInstruction() ||
 
 1436  if (
MI->isInlineAsm()) {
 
 1438    unsigned NumDefs = 0;
 
 1453  if (
MI->getOpcode() == BPF::LD_imm64) {
 
 1468    processGlobalValue(
MI->getOperand(1));
 
 1469  } 
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
 
 1470             MI->getOpcode() == BPF::CORE_LD32 ||
 
 1471             MI->getOpcode() == BPF::CORE_ST ||
 
 1472             MI->getOpcode() == BPF::CORE_SHIFT) {
 
 1474    processGlobalValue(
MI->getOperand(3));
 
 1475  } 
else if (
MI->getOpcode() == BPF::JAL) {
 
 1492    if (LineInfoGenerated == 
false) {
 
 1493      auto *S = 
MI->getMF()->getFunction().getSubprogram();
 
 1497      constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
 
 1498      LineInfoGenerated = 
true;
 
 1505  MCSymbol *LineSym = OS.getContext().createTempSymbol();
 
 1506  OS.emitLabel(LineSym);
 
 1509  constructLineInfo(LineSym, 
DL->getFile(), 
DL.getLine(), 
DL.getCol());
 
 1511  LineInfoGenerated = 
true;
 
 
 1515void BTFDebug::processGlobals(
bool ProcessingMapDef) {
 
 1521    std::optional<SectionKind> GVKind;
 
 1523    if (!
Global.isDeclarationForLinker())
 
 1526    if (
Global.isDeclarationForLinker())
 
 1527      SecName = 
Global.hasSection() ? 
Global.getSection() : 
"";
 
 1528    else if (GVKind->isCommon())
 
 1536    if (ProcessingMapDef != SecName.
starts_with(
".maps"))
 
 1542    if (SecName == 
".rodata" && 
Global.hasPrivateLinkage() &&
 
 1543        DataSecEntries.find(SecName) == DataSecEntries.end()) {
 
 1545      if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
 
 1546        DataSecEntries[std::string(SecName)] =
 
 1547            std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
 
 1552    Global.getDebugInfo(GVs);
 
 1555    if (GVs.
size() == 0)
 
 1558    uint32_t GVTypeId = 0;
 
 1559    DIGlobalVariable *DIGlobal = 
nullptr;
 
 1560    for (
auto *GVE : GVs) {
 
 1561      DIGlobal = GVE->getVariable();
 
 1563        visitMapDefType(DIGlobal->
getType(), GVTypeId);
 
 1566        visitTypeEntry(Ty, GVTypeId, 
false, 
false);
 
 1589    } 
else if (
Global.hasInitializer()) {
 
 1596        std::make_unique<BTFKindVar>(
Global.getName(), GVTypeId, GVarInfo);
 
 1597    uint32_t VarId = addType(std::move(VarEntry));
 
 1602    if (SecName.
empty())
 
 1606    auto [It, 
Inserted] = DataSecEntries.try_emplace(std::string(SecName));
 
 1608      It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
 
 1611    const DataLayout &
DL = 
Global.getDataLayout();
 
 1612    uint32_t 
Size = 
DL.getTypeAllocSize(
Global.getValueType());
 
 1614    It->second->addDataSecEntry(VarId, 
Asm->getSymbol(&
Global), 
Size);
 
 1616    if (
Global.hasInitializer())
 
 1617      processGlobalInitializer(
Global.getInitializer());
 
 1632void BTFDebug::processGlobalInitializer(
const Constant *
C) {
 
 1634    processFuncPrototypes(Fn);
 
 1636    for (
unsigned I = 0, 
N = CA->getNumOperands(); 
I < 
N; ++
I)
 
 1637      processGlobalInitializer(CA->getOperand(
I));
 
 1643  if (
MI->getOpcode() == BPF::LD_imm64) {
 
 1654        auto [Imm, 
Reloc] = PatchImms[GVar];
 
 1665  } 
else if (
MI->getOpcode() == BPF::CORE_LD64 ||
 
 1666             MI->getOpcode() == BPF::CORE_LD32 ||
 
 1667             MI->getOpcode() == BPF::CORE_ST ||
 
 1668             MI->getOpcode() == BPF::CORE_SHIFT) {
 
 1674        uint32_t Imm = PatchImms[GVar].first;
 
 1676        if (
MI->getOperand(0).isImm())
 
 
 1689void BTFDebug::processFuncPrototypes(
const Function *
F) {
 
 1694  if (!SP || SP->isDefinition())
 
 1698  if (!ProtoFunctions.insert(
F).second)
 
 1702  const std::unordered_map<uint32_t, StringRef> FuncArgNames;
 
 1703  visitSubroutineType(SP->getType(), 
false, FuncArgNames, ProtoTypeId);
 
 1706  if (
F->hasSection()) {
 
 1709    auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
 
 1711      It->second = std::make_unique<BTFKindDataSec>(
Asm, std::string(SecName));
 
 1720  if (MapDefNotCollected) {
 
 1721    processGlobals(
true);
 
 1722    MapDefNotCollected = 
false;
 
 1726  processGlobals(
false);
 
 1732      processFuncPrototypes(&
F);
 
 1735  for (
auto &DataSec : DataSecEntries)
 
 1736    addType(std::move(DataSec.second));
 
 1739  for (
auto &
Fixup : FixupDerivedTypes) {
 
 1742    bool IsUnion = CTy->
getTag() == dwarf::DW_TAG_union_type;
 
 1753    if (StructTypeId == 0) {
 
 1754      auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
 
 1755      StructTypeId = addType(std::move(FwdTypeEntry));
 
 1758    for (
auto &TypeInfo : 
Fixup.second) {
 
 1762      int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
 
 1771  for (
const auto &TypeEntry : TypeEntries)
 
 1772    TypeEntry->completeType(*
this);
 
 1776  emitBTFExtSection();
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const char * BTFKindStr[]
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.
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,...
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.
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 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 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
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.
DITypeRefArray 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.
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.
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
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)
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).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - 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
static Twine utohexstr(uint64_t Val)
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#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
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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)
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".