1 //===- BTFDebug.cpp - BTF Generator ---------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains support for writing BTF debug info.
11 //===----------------------------------------------------------------------===//
16 #include "MCTargetDesc/BPFMCTargetDesc.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/CodeGen/AsmPrinter.h"
19 #include "llvm/CodeGen/MachineModuleInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCObjectFileInfo.h"
22 #include "llvm/MC/MCSectionELF.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/Support/LineIterator.h"
28 static const char *BTFKindStr[] = {
29 #define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
33 static const DIType * stripQualifiers(const DIType *Ty) {
34 while (const auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
35 unsigned Tag = DTy->getTag();
36 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
37 Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_restrict_type)
39 Ty = DTy->getBaseType();
45 /// Emit a BTF common type.
46 void BTFTypeBase::emitType(MCStreamer &OS) {
47 OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) +
49 OS.EmitIntValue(BTFType.NameOff, 4);
50 OS.AddComment("0x" + Twine::utohexstr(BTFType.Info));
51 OS.EmitIntValue(BTFType.Info, 4);
52 OS.EmitIntValue(BTFType.Size, 4);
55 BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag,
57 : DTy(DTy), NeedsFixup(NeedsFixup) {
59 case dwarf::DW_TAG_pointer_type:
60 Kind = BTF::BTF_KIND_PTR;
62 case dwarf::DW_TAG_const_type:
63 Kind = BTF::BTF_KIND_CONST;
65 case dwarf::DW_TAG_volatile_type:
66 Kind = BTF::BTF_KIND_VOLATILE;
68 case dwarf::DW_TAG_typedef:
69 Kind = BTF::BTF_KIND_TYPEDEF;
71 case dwarf::DW_TAG_restrict_type:
72 Kind = BTF::BTF_KIND_RESTRICT;
75 llvm_unreachable("Unknown DIDerivedType Tag");
77 BTFType.Info = Kind << 24;
80 void BTFTypeDerived::completeType(BTFDebug &BDebug) {
85 BTFType.NameOff = BDebug.addString(DTy->getName());
90 // The base type for PTR/CONST/VOLATILE could be void.
91 const DIType *ResolvedType = DTy->getBaseType();
93 assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
94 Kind == BTF::BTF_KIND_VOLATILE) &&
95 "Invalid null basetype");
98 BTFType.Type = BDebug.getTypeId(ResolvedType);
102 void BTFTypeDerived::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
104 void BTFTypeDerived::setPointeeType(uint32_t PointeeType) {
105 BTFType.Type = PointeeType;
108 /// Represent a struct/union forward declaration.
109 BTFTypeFwd::BTFTypeFwd(StringRef Name, bool IsUnion) : Name(Name) {
110 Kind = BTF::BTF_KIND_FWD;
111 BTFType.Info = IsUnion << 31 | Kind << 24;
115 void BTFTypeFwd::completeType(BTFDebug &BDebug) {
120 BTFType.NameOff = BDebug.addString(Name);
123 void BTFTypeFwd::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
125 BTFTypeInt::BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits,
126 uint32_t OffsetInBits, StringRef TypeName)
128 // Translate IR int encoding to BTF int encoding.
131 case dwarf::DW_ATE_boolean:
132 BTFEncoding = BTF::INT_BOOL;
134 case dwarf::DW_ATE_signed:
135 case dwarf::DW_ATE_signed_char:
136 BTFEncoding = BTF::INT_SIGNED;
138 case dwarf::DW_ATE_unsigned:
139 case dwarf::DW_ATE_unsigned_char:
143 llvm_unreachable("Unknown BTFTypeInt Encoding");
146 Kind = BTF::BTF_KIND_INT;
147 BTFType.Info = Kind << 24;
148 BTFType.Size = roundupToBytes(SizeInBits);
149 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
152 void BTFTypeInt::completeType(BTFDebug &BDebug) {
157 BTFType.NameOff = BDebug.addString(Name);
160 void BTFTypeInt::emitType(MCStreamer &OS) {
161 BTFTypeBase::emitType(OS);
162 OS.AddComment("0x" + Twine::utohexstr(IntVal));
163 OS.EmitIntValue(IntVal, 4);
166 BTFTypeEnum::BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen) : ETy(ETy) {
167 Kind = BTF::BTF_KIND_ENUM;
168 BTFType.Info = Kind << 24 | VLen;
169 BTFType.Size = roundupToBytes(ETy->getSizeInBits());
172 void BTFTypeEnum::completeType(BTFDebug &BDebug) {
177 BTFType.NameOff = BDebug.addString(ETy->getName());
179 DINodeArray Elements = ETy->getElements();
180 for (const auto Element : Elements) {
181 const auto *Enum = cast<DIEnumerator>(Element);
183 struct BTF::BTFEnum BTFEnum;
184 BTFEnum.NameOff = BDebug.addString(Enum->getName());
185 // BTF enum value is 32bit, enforce it.
186 BTFEnum.Val = static_cast<uint32_t>(Enum->getValue());
187 EnumValues.push_back(BTFEnum);
191 void BTFTypeEnum::emitType(MCStreamer &OS) {
192 BTFTypeBase::emitType(OS);
193 for (const auto &Enum : EnumValues) {
194 OS.EmitIntValue(Enum.NameOff, 4);
195 OS.EmitIntValue(Enum.Val, 4);
199 BTFTypeArray::BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId,
200 uint32_t ElemSize, uint32_t NumElems)
201 : ElemTyNoQual(Ty), ElemSize(ElemSize) {
202 Kind = BTF::BTF_KIND_ARRAY;
204 BTFType.Info = Kind << 24;
207 ArrayInfo.ElemType = ElemTypeId;
208 ArrayInfo.Nelems = NumElems;
211 /// Represent a BTF array.
212 void BTFTypeArray::completeType(BTFDebug &BDebug) {
217 // The IR does not really have a type for the index.
218 // A special type for array index should have been
219 // created during initial type traversal. Just
220 // retrieve that type id.
221 ArrayInfo.IndexType = BDebug.getArrayIndexTypeId();
223 ElemTypeNoQual = ElemTyNoQual ? BDebug.getTypeId(ElemTyNoQual)
224 : ArrayInfo.ElemType;
227 void BTFTypeArray::emitType(MCStreamer &OS) {
228 BTFTypeBase::emitType(OS);
229 OS.EmitIntValue(ArrayInfo.ElemType, 4);
230 OS.EmitIntValue(ArrayInfo.IndexType, 4);
231 OS.EmitIntValue(ArrayInfo.Nelems, 4);
234 void BTFTypeArray::getLocInfo(uint32_t Loc, uint32_t &LocOffset,
235 uint32_t &ElementTypeId) {
236 ElementTypeId = ElemTypeNoQual;
237 LocOffset = Loc * ElemSize;
240 /// Represent either a struct or a union.
241 BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct,
242 bool HasBitField, uint32_t Vlen)
243 : STy(STy), HasBitField(HasBitField) {
244 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
245 BTFType.Size = roundupToBytes(STy->getSizeInBits());
246 BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
249 void BTFTypeStruct::completeType(BTFDebug &BDebug) {
254 BTFType.NameOff = BDebug.addString(STy->getName());
256 // Add struct/union members.
257 const DINodeArray Elements = STy->getElements();
258 for (const auto *Element : Elements) {
259 struct BTF::BTFMember BTFMember;
260 const auto *DDTy = cast<DIDerivedType>(Element);
262 BTFMember.NameOff = BDebug.addString(DDTy->getName());
264 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
265 BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
267 BTFMember.Offset = DDTy->getOffsetInBits();
269 const auto *BaseTy = DDTy->getBaseType();
270 BTFMember.Type = BDebug.getTypeId(BaseTy);
271 MemberTypeNoQual.push_back(BDebug.getTypeId(stripQualifiers(BaseTy)));
272 Members.push_back(BTFMember);
276 void BTFTypeStruct::emitType(MCStreamer &OS) {
277 BTFTypeBase::emitType(OS);
278 for (const auto &Member : Members) {
279 OS.EmitIntValue(Member.NameOff, 4);
280 OS.EmitIntValue(Member.Type, 4);
281 OS.AddComment("0x" + Twine::utohexstr(Member.Offset));
282 OS.EmitIntValue(Member.Offset, 4);
286 std::string BTFTypeStruct::getName() { return STy->getName(); }
288 void BTFTypeStruct::getMemberInfo(uint32_t Loc, uint32_t &MemberOffset,
289 uint32_t &MemberType) {
290 MemberType = MemberTypeNoQual[Loc];
292 HasBitField ? Members[Loc].Offset & 0xffffff : Members[Loc].Offset;
295 uint32_t BTFTypeStruct::getStructSize() { return STy->getSizeInBits() >> 3; }
297 /// The Func kind represents both subprogram and pointee of function
298 /// pointers. If the FuncName is empty, it represents a pointee of function
299 /// pointer. Otherwise, it represents a subprogram. The func arg names
300 /// are empty for pointee of function pointer case, and are valid names
302 BTFTypeFuncProto::BTFTypeFuncProto(
303 const DISubroutineType *STy, uint32_t VLen,
304 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
305 : STy(STy), FuncArgNames(FuncArgNames) {
306 Kind = BTF::BTF_KIND_FUNC_PROTO;
307 BTFType.Info = (Kind << 24) | VLen;
310 void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
315 DITypeRefArray Elements = STy->getTypeArray();
316 auto RetType = Elements[0];
317 BTFType.Type = RetType ? BDebug.getTypeId(RetType) : 0;
320 // For null parameter which is typically the last one
321 // to represent the vararg, encode the NameOff/Type to be 0.
322 for (unsigned I = 1, N = Elements.size(); I < N; ++I) {
323 struct BTF::BTFParam Param;
324 auto Element = Elements[I];
326 Param.NameOff = BDebug.addString(FuncArgNames[I]);
327 Param.Type = BDebug.getTypeId(Element);
332 Parameters.push_back(Param);
336 void BTFTypeFuncProto::emitType(MCStreamer &OS) {
337 BTFTypeBase::emitType(OS);
338 for (const auto &Param : Parameters) {
339 OS.EmitIntValue(Param.NameOff, 4);
340 OS.EmitIntValue(Param.Type, 4);
344 BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId)
346 Kind = BTF::BTF_KIND_FUNC;
347 BTFType.Info = Kind << 24;
348 BTFType.Type = ProtoTypeId;
351 void BTFTypeFunc::completeType(BTFDebug &BDebug) {
356 BTFType.NameOff = BDebug.addString(Name);
359 void BTFTypeFunc::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
361 BTFKindVar::BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
363 Kind = BTF::BTF_KIND_VAR;
364 BTFType.Info = Kind << 24;
365 BTFType.Type = TypeId;
369 void BTFKindVar::completeType(BTFDebug &BDebug) {
370 BTFType.NameOff = BDebug.addString(Name);
373 void BTFKindVar::emitType(MCStreamer &OS) {
374 BTFTypeBase::emitType(OS);
375 OS.EmitIntValue(Info, 4);
378 BTFKindDataSec::BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
379 : Asm(AsmPrt), Name(SecName) {
380 Kind = BTF::BTF_KIND_DATASEC;
381 BTFType.Info = Kind << 24;
385 void BTFKindDataSec::completeType(BTFDebug &BDebug) {
386 BTFType.NameOff = BDebug.addString(Name);
387 BTFType.Info |= Vars.size();
390 void BTFKindDataSec::emitType(MCStreamer &OS) {
391 BTFTypeBase::emitType(OS);
393 for (const auto &V : Vars) {
394 OS.EmitIntValue(std::get<0>(V), 4);
395 Asm->EmitLabelReference(std::get<1>(V), 4);
396 OS.EmitIntValue(std::get<2>(V), 4);
400 uint32_t BTFStringTable::addString(StringRef S) {
401 // Check whether the string already exists.
402 for (auto &OffsetM : OffsetToIdMap) {
403 if (Table[OffsetM.second] == S)
404 return OffsetM.first;
406 // Not find, add to the string table.
407 uint32_t Offset = Size;
408 OffsetToIdMap[Offset] = Table.size();
410 Size += S.size() + 1;
414 BTFDebug::BTFDebug(AsmPrinter *AP)
415 : DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false),
416 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
417 MapDefNotCollected(true) {
421 uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
423 TypeEntry->setId(TypeEntries.size() + 1);
424 uint32_t Id = TypeEntry->getId();
426 TypeEntries.push_back(std::move(TypeEntry));
430 uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
431 TypeEntry->setId(TypeEntries.size() + 1);
432 uint32_t Id = TypeEntry->getId();
433 TypeEntries.push_back(std::move(TypeEntry));
437 void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
438 // Only int types are supported in BTF.
439 uint32_t Encoding = BTy->getEncoding();
440 if (Encoding != dwarf::DW_ATE_boolean && Encoding != dwarf::DW_ATE_signed &&
441 Encoding != dwarf::DW_ATE_signed_char &&
442 Encoding != dwarf::DW_ATE_unsigned &&
443 Encoding != dwarf::DW_ATE_unsigned_char)
446 // Create a BTF type instance for this DIBasicType and put it into
447 // DIToIdMap for cross-type reference check.
448 auto TypeEntry = llvm::make_unique<BTFTypeInt>(
449 Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
450 TypeId = addType(std::move(TypeEntry), BTy);
453 /// Handle subprogram or subroutine types.
454 void BTFDebug::visitSubroutineType(
455 const DISubroutineType *STy, bool ForSubprog,
456 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
458 DITypeRefArray Elements = STy->getTypeArray();
459 uint32_t VLen = Elements.size() - 1;
460 if (VLen > BTF::MAX_VLEN)
463 // Subprogram has a valid non-zero-length name, and the pointee of
464 // a function pointer has an empty name. The subprogram type will
465 // not be added to DIToIdMap as it should not be referenced by
467 auto TypeEntry = llvm::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
469 TypeId = addType(std::move(TypeEntry)); // For subprogram
471 TypeId = addType(std::move(TypeEntry), STy); // For func ptr
473 // Visit return type and func arg types.
474 for (const auto Element : Elements) {
475 visitTypeEntry(Element);
479 /// Handle structure/union types.
480 void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
482 const DINodeArray Elements = CTy->getElements();
483 uint32_t VLen = Elements.size();
484 if (VLen > BTF::MAX_VLEN)
487 // Check whether we have any bitfield members or not
488 bool HasBitField = false;
489 for (const auto *Element : Elements) {
490 auto E = cast<DIDerivedType>(Element);
491 if (E->isBitField()) {
498 llvm::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
499 StructTypes.push_back(TypeEntry.get());
500 TypeId = addType(std::move(TypeEntry), CTy);
502 // Visit all struct members.
503 for (const auto *Element : Elements)
504 visitTypeEntry(cast<DIDerivedType>(Element));
507 void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
508 // Visit array element type.
509 uint32_t ElemTypeId, ElemSize;
510 const DIType *ElemType = CTy->getBaseType();
511 visitTypeEntry(ElemType, ElemTypeId, false, false);
513 // Strip qualifiers from element type to get accurate element size.
514 ElemType = stripQualifiers(ElemType);
515 ElemSize = ElemType->getSizeInBits() >> 3;
517 if (!CTy->getSizeInBits()) {
518 auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemType, ElemTypeId, 0, 0);
519 ArrayTypes.push_back(TypeEntry.get());
520 ElemTypeId = addType(std::move(TypeEntry), CTy);
522 // Visit array dimensions.
523 DINodeArray Elements = CTy->getElements();
524 for (int I = Elements.size() - 1; I >= 0; --I) {
525 if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
526 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
527 const DISubrange *SR = cast<DISubrange>(Element);
528 auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
529 int64_t Count = CI->getSExtValue();
530 const DIType *ArrayElemTy = (I == 0) ? ElemType : nullptr;
533 llvm::make_unique<BTFTypeArray>(ArrayElemTy, ElemTypeId,
535 ArrayTypes.push_back(TypeEntry.get());
537 ElemTypeId = addType(std::move(TypeEntry), CTy);
539 ElemTypeId = addType(std::move(TypeEntry));
540 ElemSize = ElemSize * Count;
545 // The array TypeId is the type id of the outermost dimension.
548 // The IR does not have a type for array index while BTF wants one.
549 // So create an array index type if there is none.
550 if (!ArrayIndexTypeId) {
551 auto TypeEntry = llvm::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
552 0, "__ARRAY_SIZE_TYPE__");
553 ArrayIndexTypeId = addType(std::move(TypeEntry));
557 void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {
558 DINodeArray Elements = CTy->getElements();
559 uint32_t VLen = Elements.size();
560 if (VLen > BTF::MAX_VLEN)
563 auto TypeEntry = llvm::make_unique<BTFTypeEnum>(CTy, VLen);
564 TypeId = addType(std::move(TypeEntry), CTy);
565 // No need to visit base type as BTF does not encode it.
568 /// Handle structure/union forward declarations.
569 void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
571 auto TypeEntry = llvm::make_unique<BTFTypeFwd>(CTy->getName(), IsUnion);
572 TypeId = addType(std::move(TypeEntry), CTy);
575 /// Handle structure, union, array and enumeration types.
576 void BTFDebug::visitCompositeType(const DICompositeType *CTy,
578 auto Tag = CTy->getTag();
579 if (Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
580 // Handle forward declaration differently as it does not have members.
581 if (CTy->isForwardDecl())
582 visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId);
584 visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId);
585 } else if (Tag == dwarf::DW_TAG_array_type)
586 visitArrayType(CTy, TypeId);
587 else if (Tag == dwarf::DW_TAG_enumeration_type)
588 visitEnumType(CTy, TypeId);
591 /// Handle pointer, typedef, const, volatile, restrict and member types.
592 void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
593 bool CheckPointer, bool SeenPointer) {
594 unsigned Tag = DTy->getTag();
596 /// Try to avoid chasing pointees, esp. structure pointees which may
597 /// unnecessary bring in a lot of types.
598 if (CheckPointer && !SeenPointer) {
599 SeenPointer = Tag == dwarf::DW_TAG_pointer_type;
602 if (CheckPointer && SeenPointer) {
603 const DIType *Base = DTy->getBaseType();
605 if (const auto *CTy = dyn_cast<DICompositeType>(Base)) {
606 auto CTag = CTy->getTag();
607 if ((CTag == dwarf::DW_TAG_structure_type ||
608 CTag == dwarf::DW_TAG_union_type) &&
609 !CTy->isForwardDecl()) {
610 /// Find a candidate, generate a fixup. Later on the struct/union
611 /// pointee type will be replaced with either a real type or
612 /// a forward declaration.
613 auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag, true);
614 auto &Fixup = FixupDerivedTypes[CTy->getName()];
615 Fixup.first = CTag == dwarf::DW_TAG_union_type;
616 Fixup.second.push_back(TypeEntry.get());
617 TypeId = addType(std::move(TypeEntry), DTy);
624 if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef ||
625 Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
626 Tag == dwarf::DW_TAG_restrict_type) {
627 auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag, false);
628 TypeId = addType(std::move(TypeEntry), DTy);
629 } else if (Tag != dwarf::DW_TAG_member) {
633 // Visit base type of pointer, typedef, const, volatile, restrict or
634 // struct/union member.
635 uint32_t TempTypeId = 0;
636 if (Tag == dwarf::DW_TAG_member)
637 visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false);
639 visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
642 void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId,
643 bool CheckPointer, bool SeenPointer) {
644 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
645 TypeId = DIToIdMap[Ty];
649 if (const auto *BTy = dyn_cast<DIBasicType>(Ty))
650 visitBasicType(BTy, TypeId);
651 else if (const auto *STy = dyn_cast<DISubroutineType>(Ty))
652 visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),
654 else if (const auto *CTy = dyn_cast<DICompositeType>(Ty))
655 visitCompositeType(CTy, TypeId);
656 else if (const auto *DTy = dyn_cast<DIDerivedType>(Ty))
657 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
659 llvm_unreachable("Unknown DIType");
662 void BTFDebug::visitTypeEntry(const DIType *Ty) {
664 visitTypeEntry(Ty, TypeId, false, false);
667 void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
668 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
669 TypeId = DIToIdMap[Ty];
673 // MapDef type is a struct type
674 const auto *CTy = dyn_cast<DICompositeType>(Ty);
678 auto Tag = CTy->getTag();
679 if (Tag != dwarf::DW_TAG_structure_type || CTy->isForwardDecl())
683 const DINodeArray Elements = CTy->getElements();
684 bool HasBitField = false;
685 for (const auto *Element : Elements) {
686 auto E = cast<DIDerivedType>(Element);
687 if (E->isBitField()) {
694 llvm::make_unique<BTFTypeStruct>(CTy, true, HasBitField, Elements.size());
695 StructTypes.push_back(TypeEntry.get());
696 TypeId = addType(std::move(TypeEntry), CTy);
698 // Visit all struct members
699 for (const auto *Element : Elements) {
700 const auto *MemberType = cast<DIDerivedType>(Element);
701 visitTypeEntry(MemberType->getBaseType());
705 /// Read file contents from the actual file or from the source
706 std::string BTFDebug::populateFileContent(const DISubprogram *SP) {
707 auto File = SP->getFile();
708 std::string FileName;
710 if (!File->getFilename().startswith("/") && File->getDirectory().size())
711 FileName = File->getDirectory().str() + "/" + File->getFilename().str();
713 FileName = File->getFilename();
715 // No need to populate the contends if it has been populated!
716 if (FileContent.find(FileName) != FileContent.end())
719 std::vector<std::string> Content;
721 Content.push_back(Line); // Line 0 for empty string
723 std::unique_ptr<MemoryBuffer> Buf;
724 auto Source = File->getSource();
726 Buf = MemoryBuffer::getMemBufferCopy(*Source);
727 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
728 MemoryBuffer::getFile(FileName))
729 Buf = std::move(*BufOrErr);
731 for (line_iterator I(*Buf, false), E; I != E; ++I)
732 Content.push_back(*I);
734 FileContent[FileName] = Content;
738 void BTFDebug::constructLineInfo(const DISubprogram *SP, MCSymbol *Label,
739 uint32_t Line, uint32_t Column) {
740 std::string FileName = populateFileContent(SP);
741 BTFLineInfo LineInfo;
743 LineInfo.Label = Label;
744 LineInfo.FileNameOff = addString(FileName);
745 // If file content is not available, let LineOff = 0.
746 if (Line < FileContent[FileName].size())
747 LineInfo.LineOff = addString(FileContent[FileName][Line]);
749 LineInfo.LineOff = 0;
750 LineInfo.LineNum = Line;
751 LineInfo.ColumnNum = Column;
752 LineInfoTable[SecNameOff].push_back(LineInfo);
755 void BTFDebug::emitCommonHeader() {
756 OS.AddComment("0x" + Twine::utohexstr(BTF::MAGIC));
757 OS.EmitIntValue(BTF::MAGIC, 2);
758 OS.EmitIntValue(BTF::VERSION, 1);
759 OS.EmitIntValue(0, 1);
762 void BTFDebug::emitBTFSection() {
763 // Do not emit section if no types and only "" string.
764 if (!TypeEntries.size() && StringTable.getSize() == 1)
767 MCContext &Ctx = OS.getContext();
768 OS.SwitchSection(Ctx.getELFSection(".BTF", ELF::SHT_PROGBITS, 0));
772 OS.EmitIntValue(BTF::HeaderSize, 4);
774 uint32_t TypeLen = 0, StrLen;
775 for (const auto &TypeEntry : TypeEntries)
776 TypeLen += TypeEntry->getSize();
777 StrLen = StringTable.getSize();
779 OS.EmitIntValue(0, 4);
780 OS.EmitIntValue(TypeLen, 4);
781 OS.EmitIntValue(TypeLen, 4);
782 OS.EmitIntValue(StrLen, 4);
785 for (const auto &TypeEntry : TypeEntries)
786 TypeEntry->emitType(OS);
788 // Emit string table.
789 uint32_t StringOffset = 0;
790 for (const auto &S : StringTable.getTable()) {
791 OS.AddComment("string offset=" + std::to_string(StringOffset));
793 OS.EmitBytes(StringRef("\0", 1));
794 StringOffset += S.size() + 1;
798 void BTFDebug::emitBTFExtSection() {
799 // Do not emit section if empty FuncInfoTable and LineInfoTable.
800 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
801 !OffsetRelocTable.size() && !ExternRelocTable.size())
804 MCContext &Ctx = OS.getContext();
805 OS.SwitchSection(Ctx.getELFSection(".BTF.ext", ELF::SHT_PROGBITS, 0));
809 OS.EmitIntValue(BTF::ExtHeaderSize, 4);
811 // Account for FuncInfo/LineInfo record size as well.
812 uint32_t FuncLen = 4, LineLen = 4;
813 // Do not account for optional OffsetReloc/ExternReloc.
814 uint32_t OffsetRelocLen = 0, ExternRelocLen = 0;
815 for (const auto &FuncSec : FuncInfoTable) {
816 FuncLen += BTF::SecFuncInfoSize;
817 FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize;
819 for (const auto &LineSec : LineInfoTable) {
820 LineLen += BTF::SecLineInfoSize;
821 LineLen += LineSec.second.size() * BTF::BPFLineInfoSize;
823 for (const auto &OffsetRelocSec : OffsetRelocTable) {
824 OffsetRelocLen += BTF::SecOffsetRelocSize;
825 OffsetRelocLen += OffsetRelocSec.second.size() * BTF::BPFOffsetRelocSize;
827 for (const auto &ExternRelocSec : ExternRelocTable) {
828 ExternRelocLen += BTF::SecExternRelocSize;
829 ExternRelocLen += ExternRelocSec.second.size() * BTF::BPFExternRelocSize;
837 OS.EmitIntValue(0, 4);
838 OS.EmitIntValue(FuncLen, 4);
839 OS.EmitIntValue(FuncLen, 4);
840 OS.EmitIntValue(LineLen, 4);
841 OS.EmitIntValue(FuncLen + LineLen, 4);
842 OS.EmitIntValue(OffsetRelocLen, 4);
843 OS.EmitIntValue(FuncLen + LineLen + OffsetRelocLen, 4);
844 OS.EmitIntValue(ExternRelocLen, 4);
846 // Emit func_info table.
847 OS.AddComment("FuncInfo");
848 OS.EmitIntValue(BTF::BPFFuncInfoSize, 4);
849 for (const auto &FuncSec : FuncInfoTable) {
850 OS.AddComment("FuncInfo section string offset=" +
851 std::to_string(FuncSec.first));
852 OS.EmitIntValue(FuncSec.first, 4);
853 OS.EmitIntValue(FuncSec.second.size(), 4);
854 for (const auto &FuncInfo : FuncSec.second) {
855 Asm->EmitLabelReference(FuncInfo.Label, 4);
856 OS.EmitIntValue(FuncInfo.TypeId, 4);
860 // Emit line_info table.
861 OS.AddComment("LineInfo");
862 OS.EmitIntValue(BTF::BPFLineInfoSize, 4);
863 for (const auto &LineSec : LineInfoTable) {
864 OS.AddComment("LineInfo section string offset=" +
865 std::to_string(LineSec.first));
866 OS.EmitIntValue(LineSec.first, 4);
867 OS.EmitIntValue(LineSec.second.size(), 4);
868 for (const auto &LineInfo : LineSec.second) {
869 Asm->EmitLabelReference(LineInfo.Label, 4);
870 OS.EmitIntValue(LineInfo.FileNameOff, 4);
871 OS.EmitIntValue(LineInfo.LineOff, 4);
872 OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +
873 std::to_string(LineInfo.ColumnNum));
874 OS.EmitIntValue(LineInfo.LineNum << 10 | LineInfo.ColumnNum, 4);
878 // Emit offset reloc table.
879 if (OffsetRelocLen) {
880 OS.AddComment("OffsetReloc");
881 OS.EmitIntValue(BTF::BPFOffsetRelocSize, 4);
882 for (const auto &OffsetRelocSec : OffsetRelocTable) {
883 OS.AddComment("Offset reloc section string offset=" +
884 std::to_string(OffsetRelocSec.first));
885 OS.EmitIntValue(OffsetRelocSec.first, 4);
886 OS.EmitIntValue(OffsetRelocSec.second.size(), 4);
887 for (const auto &OffsetRelocInfo : OffsetRelocSec.second) {
888 Asm->EmitLabelReference(OffsetRelocInfo.Label, 4);
889 OS.EmitIntValue(OffsetRelocInfo.TypeID, 4);
890 OS.EmitIntValue(OffsetRelocInfo.OffsetNameOff, 4);
895 // Emit extern reloc table.
896 if (ExternRelocLen) {
897 OS.AddComment("ExternReloc");
898 OS.EmitIntValue(BTF::BPFExternRelocSize, 4);
899 for (const auto &ExternRelocSec : ExternRelocTable) {
900 OS.AddComment("Extern reloc section string offset=" +
901 std::to_string(ExternRelocSec.first));
902 OS.EmitIntValue(ExternRelocSec.first, 4);
903 OS.EmitIntValue(ExternRelocSec.second.size(), 4);
904 for (const auto &ExternRelocInfo : ExternRelocSec.second) {
905 Asm->EmitLabelReference(ExternRelocInfo.Label, 4);
906 OS.EmitIntValue(ExternRelocInfo.ExternNameOff, 4);
912 void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
913 auto *SP = MF->getFunction().getSubprogram();
914 auto *Unit = SP->getUnit();
916 if (Unit->getEmissionKind() == DICompileUnit::NoDebug) {
917 SkipInstruction = true;
920 SkipInstruction = false;
922 // Collect MapDef types. Map definition needs to collect
923 // pointee types. Do it first. Otherwise, for the following
929 // foo(struct t *arg);
935 // } __attribute__((section(".maps"))) hash_map;
937 // If subroutine foo is traversed first, a type chain
938 // "ptr->struct m(fwd)" will be created and later on
939 // when traversing mapdef, since "ptr->struct m" exists,
940 // the traversal of "struct m" will be omitted.
941 if (MapDefNotCollected) {
942 processGlobals(true);
943 MapDefNotCollected = false;
946 // Collect all types locally referenced in this function.
947 // Use RetainedNodes so we can collect all argument names
948 // even if the argument is not used.
949 std::unordered_map<uint32_t, StringRef> FuncArgNames;
950 for (const DINode *DN : SP->getRetainedNodes()) {
951 if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
952 // Collect function arguments for subprogram func type.
953 uint32_t Arg = DV->getArg();
955 visitTypeEntry(DV->getType());
956 FuncArgNames[Arg] = DV->getName();
961 // Construct subprogram func proto type.
962 uint32_t ProtoTypeId;
963 visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);
965 // Construct subprogram func type
967 llvm::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId);
968 uint32_t FuncTypeId = addType(std::move(FuncTypeEntry));
970 for (const auto &TypeEntry : TypeEntries)
971 TypeEntry->completeType(*this);
973 // Construct funcinfo and the first lineinfo for the function.
974 MCSymbol *FuncLabel = Asm->getFunctionBegin();
975 BTFFuncInfo FuncInfo;
976 FuncInfo.Label = FuncLabel;
977 FuncInfo.TypeId = FuncTypeId;
978 if (FuncLabel->isInSection()) {
979 MCSection &Section = FuncLabel->getSection();
980 const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
981 assert(SectionELF && "Null section for Function Label");
982 SecNameOff = addString(SectionELF->getSectionName());
984 SecNameOff = addString(".text");
986 FuncInfoTable[SecNameOff].push_back(FuncInfo);
989 void BTFDebug::endFunctionImpl(const MachineFunction *MF) {
990 SkipInstruction = false;
991 LineInfoGenerated = false;
995 /// On-demand populate struct types as requested from abstract member
997 unsigned BTFDebug::populateStructType(const DIType *Ty) {
999 visitTypeEntry(Ty, Id, false, false);
1000 for (const auto &TypeEntry : TypeEntries)
1001 TypeEntry->completeType(*this);
1005 // Find struct/array debuginfo types given a type id.
1006 void BTFDebug::setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType,
1007 BTFTypeArray **PrevArrayType) {
1008 for (const auto &StructType : StructTypes) {
1009 if (StructType->getId() == TypeId) {
1010 *PrevStructType = StructType;
1014 for (const auto &ArrayType : ArrayTypes) {
1015 if (ArrayType->getId() == TypeId) {
1016 *PrevArrayType = ArrayType;
1022 /// Generate a struct member offset relocation.
1023 void BTFDebug::generateOffsetReloc(const MachineInstr *MI,
1024 const MCSymbol *ORSym, DIType *RootTy,
1025 StringRef AccessPattern) {
1026 BTFTypeStruct *PrevStructType = nullptr;
1027 BTFTypeArray *PrevArrayType = nullptr;
1028 unsigned RootId = populateStructType(RootTy);
1029 setTypeFromId(RootId, &PrevStructType, &PrevArrayType);
1030 unsigned RootTySize = PrevStructType->getStructSize();
1031 StringRef IndexPattern = AccessPattern.substr(AccessPattern.find_first_of(':') + 1);
1033 BTFOffsetReloc OffsetReloc;
1034 OffsetReloc.Label = ORSym;
1035 OffsetReloc.OffsetNameOff = addString(IndexPattern.drop_back());
1036 OffsetReloc.TypeID = RootId;
1038 uint32_t Start = 0, End = 0, Offset = 0;
1039 bool FirstAccess = true;
1040 for (auto C : IndexPattern) {
1044 std::string SubStr = IndexPattern.substr(Start, End - Start);
1045 int Loc = std::stoi(SubStr);
1048 Offset = Loc * RootTySize;
1049 FirstAccess = false;
1050 } else if (PrevStructType) {
1051 uint32_t MemberOffset, MemberTypeId;
1052 PrevStructType->getMemberInfo(Loc, MemberOffset, MemberTypeId);
1054 Offset += MemberOffset >> 3;
1055 PrevStructType = nullptr;
1056 setTypeFromId(MemberTypeId, &PrevStructType, &PrevArrayType);
1057 } else if (PrevArrayType) {
1058 uint32_t LocOffset, ElementTypeId;
1059 PrevArrayType->getLocInfo(Loc, LocOffset, ElementTypeId);
1061 Offset += LocOffset;
1062 PrevArrayType = nullptr;
1063 setTypeFromId(ElementTypeId, &PrevStructType, &PrevArrayType);
1065 llvm_unreachable("Internal Error: BTF offset relocation type traversal error");
1072 AccessOffsets[AccessPattern.str()] = Offset;
1073 OffsetRelocTable[SecNameOff].push_back(OffsetReloc);
1076 void BTFDebug::processLDimm64(const MachineInstr *MI) {
1077 // If the insn is an LD_imm64, the following two cases
1078 // will generate an .BTF.ext record.
1080 // If the insn is "r2 = LD_imm64 @__BTF_...",
1081 // add this insn into the .BTF.ext OffsetReloc subsection.
1082 // Relocation looks like:
1087 // Later, the insn is replaced with "r2 = <offset>"
1088 // where "<offset>" equals to the offset based on current
1089 // type definitions.
1091 // If the insn is "r2 = LD_imm64 @VAR" and VAR is
1092 // a patchable external global, add this insn into the .BTF.ext
1093 // ExternReloc subsection.
1094 // Relocation looks like:
1098 // Later, the insn is replaced with "r2 = <value>" or
1099 // "LD_imm64 r2, <value>" where "<value>" = 0.
1101 // check whether this is a candidate or not
1102 const MachineOperand &MO = MI->getOperand(1);
1103 if (MO.isGlobal()) {
1104 const GlobalValue *GVal = MO.getGlobal();
1105 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1106 if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
1107 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1108 OS.EmitLabel(ORSym);
1110 MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1111 DIType *Ty = dyn_cast<DIType>(MDN);
1112 generateOffsetReloc(MI, ORSym, Ty, GVar->getName());
1113 } else if (GVar && !GVar->hasInitializer() && GVar->hasExternalLinkage() &&
1114 GVar->getSection() == BPFCoreSharedInfo::PatchableExtSecName) {
1115 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1116 OS.EmitLabel(ORSym);
1118 BTFExternReloc ExternReloc;
1119 ExternReloc.Label = ORSym;
1120 ExternReloc.ExternNameOff = addString(GVar->getName());
1121 ExternRelocTable[SecNameOff].push_back(ExternReloc);
1126 void BTFDebug::beginInstruction(const MachineInstr *MI) {
1127 DebugHandlerBase::beginInstruction(MI);
1129 if (SkipInstruction || MI->isMetaInstruction() ||
1130 MI->getFlag(MachineInstr::FrameSetup))
1133 if (MI->isInlineAsm()) {
1134 // Count the number of register definitions to find the asm string.
1135 unsigned NumDefs = 0;
1136 for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
1140 // Skip this inline asm instruction if the asmstr is empty.
1141 const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
1146 if (MI->getOpcode() == BPF::LD_imm64)
1149 // Skip this instruction if no DebugLoc or the DebugLoc
1150 // is the same as the previous instruction.
1151 const DebugLoc &DL = MI->getDebugLoc();
1152 if (!DL || PrevInstLoc == DL) {
1153 // This instruction will be skipped, no LineInfo has
1154 // been generated, construct one based on function signature.
1155 if (LineInfoGenerated == false) {
1156 auto *S = MI->getMF()->getFunction().getSubprogram();
1157 MCSymbol *FuncLabel = Asm->getFunctionBegin();
1158 constructLineInfo(S, FuncLabel, S->getLine(), 0);
1159 LineInfoGenerated = true;
1165 // Create a temporary label to remember the insn for lineinfo.
1166 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1167 OS.EmitLabel(LineSym);
1169 // Construct the lineinfo.
1170 auto SP = DL.get()->getScope()->getSubprogram();
1171 constructLineInfo(SP, LineSym, DL.getLine(), DL.getCol());
1173 LineInfoGenerated = true;
1177 void BTFDebug::processGlobals(bool ProcessingMapDef) {
1178 // Collect all types referenced by globals.
1179 const Module *M = MMI->getModule();
1180 for (const GlobalVariable &Global : M->globals()) {
1181 // Ignore external globals for now.
1182 if (!Global.hasInitializer() && Global.hasExternalLinkage())
1185 // Decide the section name.
1187 if (Global.hasSection()) {
1188 SecName = Global.getSection();
1190 // data, bss, or readonly sections
1191 if (Global.isConstant())
1192 SecName = ".rodata";
1194 SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data";
1197 if (ProcessingMapDef != SecName.startswith(".maps"))
1200 SmallVector<DIGlobalVariableExpression *, 1> GVs;
1201 Global.getDebugInfo(GVs);
1202 uint32_t GVTypeId = 0;
1203 for (auto *GVE : GVs) {
1204 if (SecName.startswith(".maps"))
1205 visitMapDefType(GVE->getVariable()->getType(), GVTypeId);
1207 visitTypeEntry(GVE->getVariable()->getType(), GVTypeId, false, false);
1211 // Only support the following globals:
1212 // . static variables
1213 // . non-static global variables with section attributes
1214 // Essentially means:
1215 // . .bcc/.data/.rodata DataSec entities only contain static data
1216 // . Other DataSec entities contain static or initialized global data.
1217 // Initialized global data are mostly used for finding map key/value type
1218 // id's. Whether DataSec is readonly or not can be found from
1219 // corresponding ELF section flags.
1220 auto Linkage = Global.getLinkage();
1221 if (Linkage != GlobalValue::InternalLinkage &&
1222 (Linkage != GlobalValue::ExternalLinkage || !Global.hasSection()))
1225 uint32_t GVarInfo = Linkage == GlobalValue::ExternalLinkage
1226 ? BTF::VAR_GLOBAL_ALLOCATED
1229 llvm::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
1230 uint32_t VarId = addType(std::move(VarEntry));
1232 // Find or create a DataSec
1233 if (DataSecEntries.find(SecName) == DataSecEntries.end()) {
1234 DataSecEntries[SecName] = llvm::make_unique<BTFKindDataSec>(Asm, SecName);
1237 // Calculate symbol size
1238 const DataLayout &DL = Global.getParent()->getDataLayout();
1239 uint32_t Size = DL.getTypeAllocSize(Global.getType()->getElementType());
1241 DataSecEntries[SecName]->addVar(VarId, Asm->getSymbol(&Global), Size);
1245 /// Emit proper patchable instructions.
1246 bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
1247 if (MI->getOpcode() == BPF::LD_imm64) {
1248 const MachineOperand &MO = MI->getOperand(1);
1249 if (MO.isGlobal()) {
1250 const GlobalValue *GVal = MO.getGlobal();
1251 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1252 if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
1253 MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1254 DIType *Ty = dyn_cast<DIType>(MDN);
1255 std::string TypeName = Ty->getName();
1256 int64_t Imm = AccessOffsets[GVar->getName().str()];
1258 // Emit "mov ri, <imm>" for abstract member accesses.
1259 OutMI.setOpcode(BPF::MOV_ri);
1260 OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1261 OutMI.addOperand(MCOperand::createImm(Imm));
1263 } else if (GVar && !GVar->hasInitializer() &&
1264 GVar->hasExternalLinkage() &&
1265 GVar->getSection() == BPFCoreSharedInfo::PatchableExtSecName) {
1266 const IntegerType *IntTy = dyn_cast<IntegerType>(GVar->getValueType());
1268 // For patchable externals, emit "LD_imm64, ri, 0" if the external
1269 // variable is 64bit width, emit "mov ri, 0" otherwise.
1270 if (IntTy->getBitWidth() == 64)
1271 OutMI.setOpcode(BPF::LD_imm64);
1273 OutMI.setOpcode(BPF::MOV_ri);
1274 OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1275 OutMI.addOperand(MCOperand::createImm(0));
1283 void BTFDebug::endModule() {
1284 // Collect MapDef globals if not collected yet.
1285 if (MapDefNotCollected) {
1286 processGlobals(true);
1287 MapDefNotCollected = false;
1290 // Collect global types/variables except MapDef globals.
1291 processGlobals(false);
1292 for (auto &DataSec : DataSecEntries)
1293 addType(std::move(DataSec.second));
1296 for (auto &Fixup : FixupDerivedTypes) {
1297 StringRef TypeName = Fixup.first;
1298 bool IsUnion = Fixup.second.first;
1300 // Search through struct types
1301 uint32_t StructTypeId = 0;
1302 for (const auto &StructType : StructTypes) {
1303 if (StructType->getName() == TypeName) {
1304 StructTypeId = StructType->getId();
1309 if (StructTypeId == 0) {
1310 auto FwdTypeEntry = llvm::make_unique<BTFTypeFwd>(TypeName, IsUnion);
1311 StructTypeId = addType(std::move(FwdTypeEntry));
1314 for (auto &DType : Fixup.second.second) {
1315 DType->setPointeeType(StructTypeId);
1319 // Complete BTF type cross refereences.
1320 for (const auto &TypeEntry : TypeEntries)
1321 TypeEntry->completeType(*this);
1323 // Emit BTF sections.
1325 emitBTFExtSection();