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 /// Emit a BTF common type.
34 void BTFTypeBase::emitType(MCStreamer
&OS
) {
35 OS
.AddComment(std::string(BTFKindStr
[Kind
]) + "(id = " + std::to_string(Id
) +
37 OS
.EmitIntValue(BTFType
.NameOff
, 4);
38 OS
.AddComment("0x" + Twine::utohexstr(BTFType
.Info
));
39 OS
.EmitIntValue(BTFType
.Info
, 4);
40 OS
.EmitIntValue(BTFType
.Size
, 4);
43 BTFTypeDerived::BTFTypeDerived(const DIDerivedType
*DTy
, unsigned Tag
,
45 : DTy(DTy
), NeedsFixup(NeedsFixup
) {
47 case dwarf::DW_TAG_pointer_type
:
48 Kind
= BTF::BTF_KIND_PTR
;
50 case dwarf::DW_TAG_const_type
:
51 Kind
= BTF::BTF_KIND_CONST
;
53 case dwarf::DW_TAG_volatile_type
:
54 Kind
= BTF::BTF_KIND_VOLATILE
;
56 case dwarf::DW_TAG_typedef
:
57 Kind
= BTF::BTF_KIND_TYPEDEF
;
59 case dwarf::DW_TAG_restrict_type
:
60 Kind
= BTF::BTF_KIND_RESTRICT
;
63 llvm_unreachable("Unknown DIDerivedType Tag");
65 BTFType
.Info
= Kind
<< 24;
68 void BTFTypeDerived::completeType(BTFDebug
&BDebug
) {
73 BTFType
.NameOff
= BDebug
.addString(DTy
->getName());
78 // The base type for PTR/CONST/VOLATILE could be void.
79 const DIType
*ResolvedType
= DTy
->getBaseType();
81 assert((Kind
== BTF::BTF_KIND_PTR
|| Kind
== BTF::BTF_KIND_CONST
||
82 Kind
== BTF::BTF_KIND_VOLATILE
) &&
83 "Invalid null basetype");
86 BTFType
.Type
= BDebug
.getTypeId(ResolvedType
);
90 void BTFTypeDerived::emitType(MCStreamer
&OS
) { BTFTypeBase::emitType(OS
); }
92 void BTFTypeDerived::setPointeeType(uint32_t PointeeType
) {
93 BTFType
.Type
= PointeeType
;
96 /// Represent a struct/union forward declaration.
97 BTFTypeFwd::BTFTypeFwd(StringRef Name
, bool IsUnion
) : Name(Name
) {
98 Kind
= BTF::BTF_KIND_FWD
;
99 BTFType
.Info
= IsUnion
<< 31 | Kind
<< 24;
103 void BTFTypeFwd::completeType(BTFDebug
&BDebug
) {
108 BTFType
.NameOff
= BDebug
.addString(Name
);
111 void BTFTypeFwd::emitType(MCStreamer
&OS
) { BTFTypeBase::emitType(OS
); }
113 BTFTypeInt::BTFTypeInt(uint32_t Encoding
, uint32_t SizeInBits
,
114 uint32_t OffsetInBits
, StringRef TypeName
)
116 // Translate IR int encoding to BTF int encoding.
119 case dwarf::DW_ATE_boolean
:
120 BTFEncoding
= BTF::INT_BOOL
;
122 case dwarf::DW_ATE_signed
:
123 case dwarf::DW_ATE_signed_char
:
124 BTFEncoding
= BTF::INT_SIGNED
;
126 case dwarf::DW_ATE_unsigned
:
127 case dwarf::DW_ATE_unsigned_char
:
131 llvm_unreachable("Unknown BTFTypeInt Encoding");
134 Kind
= BTF::BTF_KIND_INT
;
135 BTFType
.Info
= Kind
<< 24;
136 BTFType
.Size
= roundupToBytes(SizeInBits
);
137 IntVal
= (BTFEncoding
<< 24) | OffsetInBits
<< 16 | SizeInBits
;
140 void BTFTypeInt::completeType(BTFDebug
&BDebug
) {
145 BTFType
.NameOff
= BDebug
.addString(Name
);
148 void BTFTypeInt::emitType(MCStreamer
&OS
) {
149 BTFTypeBase::emitType(OS
);
150 OS
.AddComment("0x" + Twine::utohexstr(IntVal
));
151 OS
.EmitIntValue(IntVal
, 4);
154 BTFTypeEnum::BTFTypeEnum(const DICompositeType
*ETy
, uint32_t VLen
) : ETy(ETy
) {
155 Kind
= BTF::BTF_KIND_ENUM
;
156 BTFType
.Info
= Kind
<< 24 | VLen
;
157 BTFType
.Size
= roundupToBytes(ETy
->getSizeInBits());
160 void BTFTypeEnum::completeType(BTFDebug
&BDebug
) {
165 BTFType
.NameOff
= BDebug
.addString(ETy
->getName());
167 DINodeArray Elements
= ETy
->getElements();
168 for (const auto Element
: Elements
) {
169 const auto *Enum
= cast
<DIEnumerator
>(Element
);
171 struct BTF::BTFEnum BTFEnum
;
172 BTFEnum
.NameOff
= BDebug
.addString(Enum
->getName());
173 // BTF enum value is 32bit, enforce it.
174 BTFEnum
.Val
= static_cast<uint32_t>(Enum
->getValue());
175 EnumValues
.push_back(BTFEnum
);
179 void BTFTypeEnum::emitType(MCStreamer
&OS
) {
180 BTFTypeBase::emitType(OS
);
181 for (const auto &Enum
: EnumValues
) {
182 OS
.EmitIntValue(Enum
.NameOff
, 4);
183 OS
.EmitIntValue(Enum
.Val
, 4);
187 BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId
, uint32_t ElemSize
,
189 : ElemSize(ElemSize
) {
190 Kind
= BTF::BTF_KIND_ARRAY
;
192 BTFType
.Info
= Kind
<< 24;
195 ArrayInfo
.ElemType
= ElemTypeId
;
196 ArrayInfo
.Nelems
= NumElems
;
199 /// Represent a BTF array.
200 void BTFTypeArray::completeType(BTFDebug
&BDebug
) {
205 // The IR does not really have a type for the index.
206 // A special type for array index should have been
207 // created during initial type traversal. Just
208 // retrieve that type id.
209 ArrayInfo
.IndexType
= BDebug
.getArrayIndexTypeId();
212 void BTFTypeArray::emitType(MCStreamer
&OS
) {
213 BTFTypeBase::emitType(OS
);
214 OS
.EmitIntValue(ArrayInfo
.ElemType
, 4);
215 OS
.EmitIntValue(ArrayInfo
.IndexType
, 4);
216 OS
.EmitIntValue(ArrayInfo
.Nelems
, 4);
219 void BTFTypeArray::getLocInfo(uint32_t Loc
, uint32_t &LocOffset
,
220 uint32_t &ElementTypeId
) {
221 ElementTypeId
= ArrayInfo
.ElemType
;
222 LocOffset
= Loc
* ElemSize
;
225 /// Represent either a struct or a union.
226 BTFTypeStruct::BTFTypeStruct(const DICompositeType
*STy
, bool IsStruct
,
227 bool HasBitField
, uint32_t Vlen
)
228 : STy(STy
), HasBitField(HasBitField
) {
229 Kind
= IsStruct
? BTF::BTF_KIND_STRUCT
: BTF::BTF_KIND_UNION
;
230 BTFType
.Size
= roundupToBytes(STy
->getSizeInBits());
231 BTFType
.Info
= (HasBitField
<< 31) | (Kind
<< 24) | Vlen
;
234 void BTFTypeStruct::completeType(BTFDebug
&BDebug
) {
239 BTFType
.NameOff
= BDebug
.addString(STy
->getName());
241 // Add struct/union members.
242 const DINodeArray Elements
= STy
->getElements();
243 for (const auto *Element
: Elements
) {
244 struct BTF::BTFMember BTFMember
;
245 const auto *DDTy
= cast
<DIDerivedType
>(Element
);
247 BTFMember
.NameOff
= BDebug
.addString(DDTy
->getName());
249 uint8_t BitFieldSize
= DDTy
->isBitField() ? DDTy
->getSizeInBits() : 0;
250 BTFMember
.Offset
= BitFieldSize
<< 24 | DDTy
->getOffsetInBits();
252 BTFMember
.Offset
= DDTy
->getOffsetInBits();
254 BTFMember
.Type
= BDebug
.getTypeId(DDTy
->getBaseType());
255 Members
.push_back(BTFMember
);
259 void BTFTypeStruct::emitType(MCStreamer
&OS
) {
260 BTFTypeBase::emitType(OS
);
261 for (const auto &Member
: Members
) {
262 OS
.EmitIntValue(Member
.NameOff
, 4);
263 OS
.EmitIntValue(Member
.Type
, 4);
264 OS
.AddComment("0x" + Twine::utohexstr(Member
.Offset
));
265 OS
.EmitIntValue(Member
.Offset
, 4);
269 std::string
BTFTypeStruct::getName() { return STy
->getName(); }
271 void BTFTypeStruct::getMemberInfo(uint32_t Loc
, uint32_t &MemberOffset
,
272 uint32_t &MemberType
) {
273 MemberType
= Members
[Loc
].Type
;
275 HasBitField
? Members
[Loc
].Offset
& 0xffffff : Members
[Loc
].Offset
;
278 uint32_t BTFTypeStruct::getStructSize() { return STy
->getSizeInBits() >> 3; }
280 /// The Func kind represents both subprogram and pointee of function
281 /// pointers. If the FuncName is empty, it represents a pointee of function
282 /// pointer. Otherwise, it represents a subprogram. The func arg names
283 /// are empty for pointee of function pointer case, and are valid names
285 BTFTypeFuncProto::BTFTypeFuncProto(
286 const DISubroutineType
*STy
, uint32_t VLen
,
287 const std::unordered_map
<uint32_t, StringRef
> &FuncArgNames
)
288 : STy(STy
), FuncArgNames(FuncArgNames
) {
289 Kind
= BTF::BTF_KIND_FUNC_PROTO
;
290 BTFType
.Info
= (Kind
<< 24) | VLen
;
293 void BTFTypeFuncProto::completeType(BTFDebug
&BDebug
) {
298 DITypeRefArray Elements
= STy
->getTypeArray();
299 auto RetType
= Elements
[0];
300 BTFType
.Type
= RetType
? BDebug
.getTypeId(RetType
) : 0;
303 // For null parameter which is typically the last one
304 // to represent the vararg, encode the NameOff/Type to be 0.
305 for (unsigned I
= 1, N
= Elements
.size(); I
< N
; ++I
) {
306 struct BTF::BTFParam Param
;
307 auto Element
= Elements
[I
];
309 Param
.NameOff
= BDebug
.addString(FuncArgNames
[I
]);
310 Param
.Type
= BDebug
.getTypeId(Element
);
315 Parameters
.push_back(Param
);
319 void BTFTypeFuncProto::emitType(MCStreamer
&OS
) {
320 BTFTypeBase::emitType(OS
);
321 for (const auto &Param
: Parameters
) {
322 OS
.EmitIntValue(Param
.NameOff
, 4);
323 OS
.EmitIntValue(Param
.Type
, 4);
327 BTFTypeFunc::BTFTypeFunc(StringRef FuncName
, uint32_t ProtoTypeId
)
329 Kind
= BTF::BTF_KIND_FUNC
;
330 BTFType
.Info
= Kind
<< 24;
331 BTFType
.Type
= ProtoTypeId
;
334 void BTFTypeFunc::completeType(BTFDebug
&BDebug
) {
339 BTFType
.NameOff
= BDebug
.addString(Name
);
342 void BTFTypeFunc::emitType(MCStreamer
&OS
) { BTFTypeBase::emitType(OS
); }
344 BTFKindVar::BTFKindVar(StringRef VarName
, uint32_t TypeId
, uint32_t VarInfo
)
346 Kind
= BTF::BTF_KIND_VAR
;
347 BTFType
.Info
= Kind
<< 24;
348 BTFType
.Type
= TypeId
;
352 void BTFKindVar::completeType(BTFDebug
&BDebug
) {
353 BTFType
.NameOff
= BDebug
.addString(Name
);
356 void BTFKindVar::emitType(MCStreamer
&OS
) {
357 BTFTypeBase::emitType(OS
);
358 OS
.EmitIntValue(Info
, 4);
361 BTFKindDataSec::BTFKindDataSec(AsmPrinter
*AsmPrt
, std::string SecName
)
362 : Asm(AsmPrt
), Name(SecName
) {
363 Kind
= BTF::BTF_KIND_DATASEC
;
364 BTFType
.Info
= Kind
<< 24;
368 void BTFKindDataSec::completeType(BTFDebug
&BDebug
) {
369 BTFType
.NameOff
= BDebug
.addString(Name
);
370 BTFType
.Info
|= Vars
.size();
373 void BTFKindDataSec::emitType(MCStreamer
&OS
) {
374 BTFTypeBase::emitType(OS
);
376 for (const auto &V
: Vars
) {
377 OS
.EmitIntValue(std::get
<0>(V
), 4);
378 Asm
->EmitLabelReference(std::get
<1>(V
), 4);
379 OS
.EmitIntValue(std::get
<2>(V
), 4);
383 uint32_t BTFStringTable::addString(StringRef S
) {
384 // Check whether the string already exists.
385 for (auto &OffsetM
: OffsetToIdMap
) {
386 if (Table
[OffsetM
.second
] == S
)
387 return OffsetM
.first
;
389 // Not find, add to the string table.
390 uint32_t Offset
= Size
;
391 OffsetToIdMap
[Offset
] = Table
.size();
393 Size
+= S
.size() + 1;
397 BTFDebug::BTFDebug(AsmPrinter
*AP
)
398 : DebugHandlerBase(AP
), OS(*Asm
->OutStreamer
), SkipInstruction(false),
399 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
400 MapDefNotCollected(true) {
404 uint32_t BTFDebug::addType(std::unique_ptr
<BTFTypeBase
> TypeEntry
,
406 TypeEntry
->setId(TypeEntries
.size() + 1);
407 uint32_t Id
= TypeEntry
->getId();
409 TypeEntries
.push_back(std::move(TypeEntry
));
413 uint32_t BTFDebug::addType(std::unique_ptr
<BTFTypeBase
> TypeEntry
) {
414 TypeEntry
->setId(TypeEntries
.size() + 1);
415 uint32_t Id
= TypeEntry
->getId();
416 TypeEntries
.push_back(std::move(TypeEntry
));
420 void BTFDebug::visitBasicType(const DIBasicType
*BTy
, uint32_t &TypeId
) {
421 // Only int types are supported in BTF.
422 uint32_t Encoding
= BTy
->getEncoding();
423 if (Encoding
!= dwarf::DW_ATE_boolean
&& Encoding
!= dwarf::DW_ATE_signed
&&
424 Encoding
!= dwarf::DW_ATE_signed_char
&&
425 Encoding
!= dwarf::DW_ATE_unsigned
&&
426 Encoding
!= dwarf::DW_ATE_unsigned_char
)
429 // Create a BTF type instance for this DIBasicType and put it into
430 // DIToIdMap for cross-type reference check.
431 auto TypeEntry
= llvm::make_unique
<BTFTypeInt
>(
432 Encoding
, BTy
->getSizeInBits(), BTy
->getOffsetInBits(), BTy
->getName());
433 TypeId
= addType(std::move(TypeEntry
), BTy
);
436 /// Handle subprogram or subroutine types.
437 void BTFDebug::visitSubroutineType(
438 const DISubroutineType
*STy
, bool ForSubprog
,
439 const std::unordered_map
<uint32_t, StringRef
> &FuncArgNames
,
441 DITypeRefArray Elements
= STy
->getTypeArray();
442 uint32_t VLen
= Elements
.size() - 1;
443 if (VLen
> BTF::MAX_VLEN
)
446 // Subprogram has a valid non-zero-length name, and the pointee of
447 // a function pointer has an empty name. The subprogram type will
448 // not be added to DIToIdMap as it should not be referenced by
450 auto TypeEntry
= llvm::make_unique
<BTFTypeFuncProto
>(STy
, VLen
, FuncArgNames
);
452 TypeId
= addType(std::move(TypeEntry
)); // For subprogram
454 TypeId
= addType(std::move(TypeEntry
), STy
); // For func ptr
456 // Visit return type and func arg types.
457 for (const auto Element
: Elements
) {
458 visitTypeEntry(Element
);
462 /// Handle structure/union types.
463 void BTFDebug::visitStructType(const DICompositeType
*CTy
, bool IsStruct
,
465 const DINodeArray Elements
= CTy
->getElements();
466 uint32_t VLen
= Elements
.size();
467 if (VLen
> BTF::MAX_VLEN
)
470 // Check whether we have any bitfield members or not
471 bool HasBitField
= false;
472 for (const auto *Element
: Elements
) {
473 auto E
= cast
<DIDerivedType
>(Element
);
474 if (E
->isBitField()) {
481 llvm::make_unique
<BTFTypeStruct
>(CTy
, IsStruct
, HasBitField
, VLen
);
482 StructTypes
.push_back(TypeEntry
.get());
483 TypeId
= addType(std::move(TypeEntry
), CTy
);
485 // Visit all struct members.
486 for (const auto *Element
: Elements
)
487 visitTypeEntry(cast
<DIDerivedType
>(Element
));
490 void BTFDebug::visitArrayType(const DICompositeType
*CTy
, uint32_t &TypeId
) {
491 // Visit array element type.
492 uint32_t ElemTypeId
, ElemSize
;
493 const DIType
*ElemType
= CTy
->getBaseType();
494 visitTypeEntry(ElemType
, ElemTypeId
, false, false);
495 ElemSize
= ElemType
->getSizeInBits() >> 3;
497 if (!CTy
->getSizeInBits()) {
498 auto TypeEntry
= llvm::make_unique
<BTFTypeArray
>(ElemTypeId
, 0, 0);
499 ArrayTypes
.push_back(TypeEntry
.get());
500 ElemTypeId
= addType(std::move(TypeEntry
), CTy
);
502 // Visit array dimensions.
503 DINodeArray Elements
= CTy
->getElements();
504 for (int I
= Elements
.size() - 1; I
>= 0; --I
) {
505 if (auto *Element
= dyn_cast_or_null
<DINode
>(Elements
[I
]))
506 if (Element
->getTag() == dwarf::DW_TAG_subrange_type
) {
507 const DISubrange
*SR
= cast
<DISubrange
>(Element
);
508 auto *CI
= SR
->getCount().dyn_cast
<ConstantInt
*>();
509 int64_t Count
= CI
->getSExtValue();
512 llvm::make_unique
<BTFTypeArray
>(ElemTypeId
, ElemSize
, Count
);
513 ArrayTypes
.push_back(TypeEntry
.get());
515 ElemTypeId
= addType(std::move(TypeEntry
), CTy
);
517 ElemTypeId
= addType(std::move(TypeEntry
));
518 ElemSize
= ElemSize
* Count
;
523 // The array TypeId is the type id of the outermost dimension.
526 // The IR does not have a type for array index while BTF wants one.
527 // So create an array index type if there is none.
528 if (!ArrayIndexTypeId
) {
529 auto TypeEntry
= llvm::make_unique
<BTFTypeInt
>(dwarf::DW_ATE_unsigned
, 32,
530 0, "__ARRAY_SIZE_TYPE__");
531 ArrayIndexTypeId
= addType(std::move(TypeEntry
));
535 void BTFDebug::visitEnumType(const DICompositeType
*CTy
, uint32_t &TypeId
) {
536 DINodeArray Elements
= CTy
->getElements();
537 uint32_t VLen
= Elements
.size();
538 if (VLen
> BTF::MAX_VLEN
)
541 auto TypeEntry
= llvm::make_unique
<BTFTypeEnum
>(CTy
, VLen
);
542 TypeId
= addType(std::move(TypeEntry
), CTy
);
543 // No need to visit base type as BTF does not encode it.
546 /// Handle structure/union forward declarations.
547 void BTFDebug::visitFwdDeclType(const DICompositeType
*CTy
, bool IsUnion
,
549 auto TypeEntry
= llvm::make_unique
<BTFTypeFwd
>(CTy
->getName(), IsUnion
);
550 TypeId
= addType(std::move(TypeEntry
), CTy
);
553 /// Handle structure, union, array and enumeration types.
554 void BTFDebug::visitCompositeType(const DICompositeType
*CTy
,
556 auto Tag
= CTy
->getTag();
557 if (Tag
== dwarf::DW_TAG_structure_type
|| Tag
== dwarf::DW_TAG_union_type
) {
558 // Handle forward declaration differently as it does not have members.
559 if (CTy
->isForwardDecl())
560 visitFwdDeclType(CTy
, Tag
== dwarf::DW_TAG_union_type
, TypeId
);
562 visitStructType(CTy
, Tag
== dwarf::DW_TAG_structure_type
, TypeId
);
563 } else if (Tag
== dwarf::DW_TAG_array_type
)
564 visitArrayType(CTy
, TypeId
);
565 else if (Tag
== dwarf::DW_TAG_enumeration_type
)
566 visitEnumType(CTy
, TypeId
);
569 /// Handle pointer, typedef, const, volatile, restrict and member types.
570 void BTFDebug::visitDerivedType(const DIDerivedType
*DTy
, uint32_t &TypeId
,
571 bool CheckPointer
, bool SeenPointer
) {
572 unsigned Tag
= DTy
->getTag();
574 /// Try to avoid chasing pointees, esp. structure pointees which may
575 /// unnecessary bring in a lot of types.
576 if (CheckPointer
&& !SeenPointer
) {
577 SeenPointer
= Tag
== dwarf::DW_TAG_pointer_type
;
580 if (CheckPointer
&& SeenPointer
) {
581 const DIType
*Base
= DTy
->getBaseType();
583 if (const auto *CTy
= dyn_cast
<DICompositeType
>(Base
)) {
584 auto CTag
= CTy
->getTag();
585 if ((CTag
== dwarf::DW_TAG_structure_type
||
586 CTag
== dwarf::DW_TAG_union_type
) &&
587 !CTy
->isForwardDecl()) {
588 /// Find a candidate, generate a fixup. Later on the struct/union
589 /// pointee type will be replaced with either a real type or
590 /// a forward declaration.
591 auto TypeEntry
= llvm::make_unique
<BTFTypeDerived
>(DTy
, Tag
, true);
592 auto &Fixup
= FixupDerivedTypes
[CTy
->getName()];
593 Fixup
.first
= CTag
== dwarf::DW_TAG_union_type
;
594 Fixup
.second
.push_back(TypeEntry
.get());
595 TypeId
= addType(std::move(TypeEntry
), DTy
);
602 if (Tag
== dwarf::DW_TAG_pointer_type
|| Tag
== dwarf::DW_TAG_typedef
||
603 Tag
== dwarf::DW_TAG_const_type
|| Tag
== dwarf::DW_TAG_volatile_type
||
604 Tag
== dwarf::DW_TAG_restrict_type
) {
605 auto TypeEntry
= llvm::make_unique
<BTFTypeDerived
>(DTy
, Tag
, false);
606 TypeId
= addType(std::move(TypeEntry
), DTy
);
607 } else if (Tag
!= dwarf::DW_TAG_member
) {
611 // Visit base type of pointer, typedef, const, volatile, restrict or
612 // struct/union member.
613 uint32_t TempTypeId
= 0;
614 if (Tag
== dwarf::DW_TAG_member
)
615 visitTypeEntry(DTy
->getBaseType(), TempTypeId
, true, false);
617 visitTypeEntry(DTy
->getBaseType(), TempTypeId
, CheckPointer
, SeenPointer
);
620 void BTFDebug::visitTypeEntry(const DIType
*Ty
, uint32_t &TypeId
,
621 bool CheckPointer
, bool SeenPointer
) {
622 if (!Ty
|| DIToIdMap
.find(Ty
) != DIToIdMap
.end()) {
623 TypeId
= DIToIdMap
[Ty
];
627 if (const auto *BTy
= dyn_cast
<DIBasicType
>(Ty
))
628 visitBasicType(BTy
, TypeId
);
629 else if (const auto *STy
= dyn_cast
<DISubroutineType
>(Ty
))
630 visitSubroutineType(STy
, false, std::unordered_map
<uint32_t, StringRef
>(),
632 else if (const auto *CTy
= dyn_cast
<DICompositeType
>(Ty
))
633 visitCompositeType(CTy
, TypeId
);
634 else if (const auto *DTy
= dyn_cast
<DIDerivedType
>(Ty
))
635 visitDerivedType(DTy
, TypeId
, CheckPointer
, SeenPointer
);
637 llvm_unreachable("Unknown DIType");
640 void BTFDebug::visitTypeEntry(const DIType
*Ty
) {
642 visitTypeEntry(Ty
, TypeId
, false, false);
645 void BTFDebug::visitMapDefType(const DIType
*Ty
, uint32_t &TypeId
) {
646 if (!Ty
|| DIToIdMap
.find(Ty
) != DIToIdMap
.end()) {
647 TypeId
= DIToIdMap
[Ty
];
651 // MapDef type is a struct type
652 const auto *CTy
= dyn_cast
<DICompositeType
>(Ty
);
656 auto Tag
= CTy
->getTag();
657 if (Tag
!= dwarf::DW_TAG_structure_type
|| CTy
->isForwardDecl())
661 const DINodeArray Elements
= CTy
->getElements();
662 bool HasBitField
= false;
663 for (const auto *Element
: Elements
) {
664 auto E
= cast
<DIDerivedType
>(Element
);
665 if (E
->isBitField()) {
672 llvm::make_unique
<BTFTypeStruct
>(CTy
, true, HasBitField
, Elements
.size());
673 StructTypes
.push_back(TypeEntry
.get());
674 TypeId
= addType(std::move(TypeEntry
), CTy
);
676 // Visit all struct members
677 for (const auto *Element
: Elements
) {
678 const auto *MemberType
= cast
<DIDerivedType
>(Element
);
679 visitTypeEntry(MemberType
->getBaseType());
683 /// Read file contents from the actual file or from the source
684 std::string
BTFDebug::populateFileContent(const DISubprogram
*SP
) {
685 auto File
= SP
->getFile();
686 std::string FileName
;
688 if (!File
->getFilename().startswith("/") && File
->getDirectory().size())
689 FileName
= File
->getDirectory().str() + "/" + File
->getFilename().str();
691 FileName
= File
->getFilename();
693 // No need to populate the contends if it has been populated!
694 if (FileContent
.find(FileName
) != FileContent
.end())
697 std::vector
<std::string
> Content
;
699 Content
.push_back(Line
); // Line 0 for empty string
701 std::unique_ptr
<MemoryBuffer
> Buf
;
702 auto Source
= File
->getSource();
704 Buf
= MemoryBuffer::getMemBufferCopy(*Source
);
705 else if (ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufOrErr
=
706 MemoryBuffer::getFile(FileName
))
707 Buf
= std::move(*BufOrErr
);
709 for (line_iterator
I(*Buf
, false), E
; I
!= E
; ++I
)
710 Content
.push_back(*I
);
712 FileContent
[FileName
] = Content
;
716 void BTFDebug::constructLineInfo(const DISubprogram
*SP
, MCSymbol
*Label
,
717 uint32_t Line
, uint32_t Column
) {
718 std::string FileName
= populateFileContent(SP
);
719 BTFLineInfo LineInfo
;
721 LineInfo
.Label
= Label
;
722 LineInfo
.FileNameOff
= addString(FileName
);
723 // If file content is not available, let LineOff = 0.
724 if (Line
< FileContent
[FileName
].size())
725 LineInfo
.LineOff
= addString(FileContent
[FileName
][Line
]);
727 LineInfo
.LineOff
= 0;
728 LineInfo
.LineNum
= Line
;
729 LineInfo
.ColumnNum
= Column
;
730 LineInfoTable
[SecNameOff
].push_back(LineInfo
);
733 void BTFDebug::emitCommonHeader() {
734 OS
.AddComment("0x" + Twine::utohexstr(BTF::MAGIC
));
735 OS
.EmitIntValue(BTF::MAGIC
, 2);
736 OS
.EmitIntValue(BTF::VERSION
, 1);
737 OS
.EmitIntValue(0, 1);
740 void BTFDebug::emitBTFSection() {
741 // Do not emit section if no types and only "" string.
742 if (!TypeEntries
.size() && StringTable
.getSize() == 1)
745 MCContext
&Ctx
= OS
.getContext();
746 OS
.SwitchSection(Ctx
.getELFSection(".BTF", ELF::SHT_PROGBITS
, 0));
750 OS
.EmitIntValue(BTF::HeaderSize
, 4);
752 uint32_t TypeLen
= 0, StrLen
;
753 for (const auto &TypeEntry
: TypeEntries
)
754 TypeLen
+= TypeEntry
->getSize();
755 StrLen
= StringTable
.getSize();
757 OS
.EmitIntValue(0, 4);
758 OS
.EmitIntValue(TypeLen
, 4);
759 OS
.EmitIntValue(TypeLen
, 4);
760 OS
.EmitIntValue(StrLen
, 4);
763 for (const auto &TypeEntry
: TypeEntries
)
764 TypeEntry
->emitType(OS
);
766 // Emit string table.
767 uint32_t StringOffset
= 0;
768 for (const auto &S
: StringTable
.getTable()) {
769 OS
.AddComment("string offset=" + std::to_string(StringOffset
));
771 OS
.EmitBytes(StringRef("\0", 1));
772 StringOffset
+= S
.size() + 1;
776 void BTFDebug::emitBTFExtSection() {
777 // Do not emit section if empty FuncInfoTable and LineInfoTable.
778 if (!FuncInfoTable
.size() && !LineInfoTable
.size() &&
779 !OffsetRelocTable
.size() && !ExternRelocTable
.size())
782 MCContext
&Ctx
= OS
.getContext();
783 OS
.SwitchSection(Ctx
.getELFSection(".BTF.ext", ELF::SHT_PROGBITS
, 0));
787 OS
.EmitIntValue(BTF::ExtHeaderSize
, 4);
789 // Account for FuncInfo/LineInfo record size as well.
790 uint32_t FuncLen
= 4, LineLen
= 4;
791 // Do not account for optional OffsetReloc/ExternReloc.
792 uint32_t OffsetRelocLen
= 0, ExternRelocLen
= 0;
793 for (const auto &FuncSec
: FuncInfoTable
) {
794 FuncLen
+= BTF::SecFuncInfoSize
;
795 FuncLen
+= FuncSec
.second
.size() * BTF::BPFFuncInfoSize
;
797 for (const auto &LineSec
: LineInfoTable
) {
798 LineLen
+= BTF::SecLineInfoSize
;
799 LineLen
+= LineSec
.second
.size() * BTF::BPFLineInfoSize
;
801 for (const auto &OffsetRelocSec
: OffsetRelocTable
) {
802 OffsetRelocLen
+= BTF::SecOffsetRelocSize
;
803 OffsetRelocLen
+= OffsetRelocSec
.second
.size() * BTF::BPFOffsetRelocSize
;
805 for (const auto &ExternRelocSec
: ExternRelocTable
) {
806 ExternRelocLen
+= BTF::SecExternRelocSize
;
807 ExternRelocLen
+= ExternRelocSec
.second
.size() * BTF::BPFExternRelocSize
;
815 OS
.EmitIntValue(0, 4);
816 OS
.EmitIntValue(FuncLen
, 4);
817 OS
.EmitIntValue(FuncLen
, 4);
818 OS
.EmitIntValue(LineLen
, 4);
819 OS
.EmitIntValue(FuncLen
+ LineLen
, 4);
820 OS
.EmitIntValue(OffsetRelocLen
, 4);
821 OS
.EmitIntValue(FuncLen
+ LineLen
+ OffsetRelocLen
, 4);
822 OS
.EmitIntValue(ExternRelocLen
, 4);
824 // Emit func_info table.
825 OS
.AddComment("FuncInfo");
826 OS
.EmitIntValue(BTF::BPFFuncInfoSize
, 4);
827 for (const auto &FuncSec
: FuncInfoTable
) {
828 OS
.AddComment("FuncInfo section string offset=" +
829 std::to_string(FuncSec
.first
));
830 OS
.EmitIntValue(FuncSec
.first
, 4);
831 OS
.EmitIntValue(FuncSec
.second
.size(), 4);
832 for (const auto &FuncInfo
: FuncSec
.second
) {
833 Asm
->EmitLabelReference(FuncInfo
.Label
, 4);
834 OS
.EmitIntValue(FuncInfo
.TypeId
, 4);
838 // Emit line_info table.
839 OS
.AddComment("LineInfo");
840 OS
.EmitIntValue(BTF::BPFLineInfoSize
, 4);
841 for (const auto &LineSec
: LineInfoTable
) {
842 OS
.AddComment("LineInfo section string offset=" +
843 std::to_string(LineSec
.first
));
844 OS
.EmitIntValue(LineSec
.first
, 4);
845 OS
.EmitIntValue(LineSec
.second
.size(), 4);
846 for (const auto &LineInfo
: LineSec
.second
) {
847 Asm
->EmitLabelReference(LineInfo
.Label
, 4);
848 OS
.EmitIntValue(LineInfo
.FileNameOff
, 4);
849 OS
.EmitIntValue(LineInfo
.LineOff
, 4);
850 OS
.AddComment("Line " + std::to_string(LineInfo
.LineNum
) + " Col " +
851 std::to_string(LineInfo
.ColumnNum
));
852 OS
.EmitIntValue(LineInfo
.LineNum
<< 10 | LineInfo
.ColumnNum
, 4);
856 // Emit offset reloc table.
857 if (OffsetRelocLen
) {
858 OS
.AddComment("OffsetReloc");
859 OS
.EmitIntValue(BTF::BPFOffsetRelocSize
, 4);
860 for (const auto &OffsetRelocSec
: OffsetRelocTable
) {
861 OS
.AddComment("Offset reloc section string offset=" +
862 std::to_string(OffsetRelocSec
.first
));
863 OS
.EmitIntValue(OffsetRelocSec
.first
, 4);
864 OS
.EmitIntValue(OffsetRelocSec
.second
.size(), 4);
865 for (const auto &OffsetRelocInfo
: OffsetRelocSec
.second
) {
866 Asm
->EmitLabelReference(OffsetRelocInfo
.Label
, 4);
867 OS
.EmitIntValue(OffsetRelocInfo
.TypeID
, 4);
868 OS
.EmitIntValue(OffsetRelocInfo
.OffsetNameOff
, 4);
873 // Emit extern reloc table.
874 if (ExternRelocLen
) {
875 OS
.AddComment("ExternReloc");
876 OS
.EmitIntValue(BTF::BPFExternRelocSize
, 4);
877 for (const auto &ExternRelocSec
: ExternRelocTable
) {
878 OS
.AddComment("Extern reloc section string offset=" +
879 std::to_string(ExternRelocSec
.first
));
880 OS
.EmitIntValue(ExternRelocSec
.first
, 4);
881 OS
.EmitIntValue(ExternRelocSec
.second
.size(), 4);
882 for (const auto &ExternRelocInfo
: ExternRelocSec
.second
) {
883 Asm
->EmitLabelReference(ExternRelocInfo
.Label
, 4);
884 OS
.EmitIntValue(ExternRelocInfo
.ExternNameOff
, 4);
890 void BTFDebug::beginFunctionImpl(const MachineFunction
*MF
) {
891 auto *SP
= MF
->getFunction().getSubprogram();
892 auto *Unit
= SP
->getUnit();
894 if (Unit
->getEmissionKind() == DICompileUnit::NoDebug
) {
895 SkipInstruction
= true;
898 SkipInstruction
= false;
900 // Collect MapDef types. Map definition needs to collect
901 // pointee types. Do it first. Otherwise, for the following
907 // foo(struct t *arg);
913 // } __attribute__((section(".maps"))) hash_map;
915 // If subroutine foo is traversed first, a type chain
916 // "ptr->struct m(fwd)" will be created and later on
917 // when traversing mapdef, since "ptr->struct m" exists,
918 // the traversal of "struct m" will be omitted.
919 if (MapDefNotCollected
) {
920 processGlobals(true);
921 MapDefNotCollected
= false;
924 // Collect all types locally referenced in this function.
925 // Use RetainedNodes so we can collect all argument names
926 // even if the argument is not used.
927 std::unordered_map
<uint32_t, StringRef
> FuncArgNames
;
928 for (const DINode
*DN
: SP
->getRetainedNodes()) {
929 if (const auto *DV
= dyn_cast
<DILocalVariable
>(DN
)) {
930 // Collect function arguments for subprogram func type.
931 uint32_t Arg
= DV
->getArg();
933 visitTypeEntry(DV
->getType());
934 FuncArgNames
[Arg
] = DV
->getName();
939 // Construct subprogram func proto type.
940 uint32_t ProtoTypeId
;
941 visitSubroutineType(SP
->getType(), true, FuncArgNames
, ProtoTypeId
);
943 // Construct subprogram func type
945 llvm::make_unique
<BTFTypeFunc
>(SP
->getName(), ProtoTypeId
);
946 uint32_t FuncTypeId
= addType(std::move(FuncTypeEntry
));
948 for (const auto &TypeEntry
: TypeEntries
)
949 TypeEntry
->completeType(*this);
951 // Construct funcinfo and the first lineinfo for the function.
952 MCSymbol
*FuncLabel
= Asm
->getFunctionBegin();
953 BTFFuncInfo FuncInfo
;
954 FuncInfo
.Label
= FuncLabel
;
955 FuncInfo
.TypeId
= FuncTypeId
;
956 if (FuncLabel
->isInSection()) {
957 MCSection
&Section
= FuncLabel
->getSection();
958 const MCSectionELF
*SectionELF
= dyn_cast
<MCSectionELF
>(&Section
);
959 assert(SectionELF
&& "Null section for Function Label");
960 SecNameOff
= addString(SectionELF
->getSectionName());
962 SecNameOff
= addString(".text");
964 FuncInfoTable
[SecNameOff
].push_back(FuncInfo
);
967 void BTFDebug::endFunctionImpl(const MachineFunction
*MF
) {
968 SkipInstruction
= false;
969 LineInfoGenerated
= false;
973 /// On-demand populate struct types as requested from abstract member
975 unsigned BTFDebug::populateStructType(const DIType
*Ty
) {
977 visitTypeEntry(Ty
, Id
, false, false);
978 for (const auto &TypeEntry
: TypeEntries
)
979 TypeEntry
->completeType(*this);
983 // Find struct/array debuginfo types given a type id.
984 void BTFDebug::setTypeFromId(uint32_t TypeId
, BTFTypeStruct
**PrevStructType
,
985 BTFTypeArray
**PrevArrayType
) {
986 for (const auto &StructType
: StructTypes
) {
987 if (StructType
->getId() == TypeId
) {
988 *PrevStructType
= StructType
;
992 for (const auto &ArrayType
: ArrayTypes
) {
993 if (ArrayType
->getId() == TypeId
) {
994 *PrevArrayType
= ArrayType
;
1000 /// Generate a struct member offset relocation.
1001 void BTFDebug::generateOffsetReloc(const MachineInstr
*MI
,
1002 const MCSymbol
*ORSym
, DIType
*RootTy
,
1003 StringRef AccessPattern
) {
1004 BTFTypeStruct
*PrevStructType
= nullptr;
1005 BTFTypeArray
*PrevArrayType
= nullptr;
1006 unsigned RootId
= populateStructType(RootTy
);
1007 setTypeFromId(RootId
, &PrevStructType
, &PrevArrayType
);
1008 unsigned RootTySize
= PrevStructType
->getStructSize();
1010 BTFOffsetReloc OffsetReloc
;
1011 OffsetReloc
.Label
= ORSym
;
1012 OffsetReloc
.OffsetNameOff
= addString(AccessPattern
.drop_back());
1013 OffsetReloc
.TypeID
= RootId
;
1015 uint32_t Start
= 0, End
= 0, Offset
= 0;
1016 bool FirstAccess
= true;
1017 for (auto C
: AccessPattern
) {
1021 std::string SubStr
= AccessPattern
.substr(Start
, End
- Start
);
1022 int Loc
= std::stoi(SubStr
);
1025 Offset
= Loc
* RootTySize
;
1026 FirstAccess
= false;
1027 } else if (PrevStructType
) {
1028 uint32_t MemberOffset
, MemberTypeId
;
1029 PrevStructType
->getMemberInfo(Loc
, MemberOffset
, MemberTypeId
);
1031 Offset
+= MemberOffset
>> 3;
1032 PrevStructType
= nullptr;
1033 setTypeFromId(MemberTypeId
, &PrevStructType
, &PrevArrayType
);
1034 } else if (PrevArrayType
) {
1035 uint32_t LocOffset
, ElementTypeId
;
1036 PrevArrayType
->getLocInfo(Loc
, LocOffset
, ElementTypeId
);
1038 Offset
+= LocOffset
;
1039 PrevArrayType
= nullptr;
1040 setTypeFromId(ElementTypeId
, &PrevStructType
, &PrevArrayType
);
1046 AccessOffsets
[RootTy
->getName().str() + ":" + AccessPattern
.str()] = Offset
;
1047 OffsetRelocTable
[SecNameOff
].push_back(OffsetReloc
);
1050 void BTFDebug::processLDimm64(const MachineInstr
*MI
) {
1051 // If the insn is an LD_imm64, the following two cases
1052 // will generate an .BTF.ext record.
1054 // If the insn is "r2 = LD_imm64 @__BTF_...",
1055 // add this insn into the .BTF.ext OffsetReloc subsection.
1056 // Relocation looks like:
1061 // Later, the insn is replaced with "r2 = <offset>"
1062 // where "<offset>" equals to the offset based on current
1063 // type definitions.
1065 // If the insn is "r2 = LD_imm64 @VAR" and VAR is
1066 // a patchable external global, add this insn into the .BTF.ext
1067 // ExternReloc subsection.
1068 // Relocation looks like:
1072 // Later, the insn is replaced with "r2 = <value>" or
1073 // "LD_imm64 r2, <value>" where "<value>" = 0.
1075 // check whether this is a candidate or not
1076 const MachineOperand
&MO
= MI
->getOperand(1);
1077 if (MO
.isGlobal()) {
1078 const GlobalValue
*GVal
= MO
.getGlobal();
1079 auto *GVar
= dyn_cast
<GlobalVariable
>(GVal
);
1080 if (GVar
&& GVar
->hasAttribute(BPFCoreSharedInfo::AmaAttr
)) {
1081 MCSymbol
*ORSym
= OS
.getContext().createTempSymbol();
1082 OS
.EmitLabel(ORSym
);
1084 MDNode
*MDN
= GVar
->getMetadata(LLVMContext::MD_preserve_access_index
);
1085 DIType
*Ty
= dyn_cast
<DIType
>(MDN
);
1086 generateOffsetReloc(MI
, ORSym
, Ty
, GVar
->getName());
1087 } else if (GVar
&& !GVar
->hasInitializer() && GVar
->hasExternalLinkage() &&
1088 GVar
->getSection() == BPFCoreSharedInfo::PatchableExtSecName
) {
1089 MCSymbol
*ORSym
= OS
.getContext().createTempSymbol();
1090 OS
.EmitLabel(ORSym
);
1092 BTFExternReloc ExternReloc
;
1093 ExternReloc
.Label
= ORSym
;
1094 ExternReloc
.ExternNameOff
= addString(GVar
->getName());
1095 ExternRelocTable
[SecNameOff
].push_back(ExternReloc
);
1100 void BTFDebug::beginInstruction(const MachineInstr
*MI
) {
1101 DebugHandlerBase::beginInstruction(MI
);
1103 if (SkipInstruction
|| MI
->isMetaInstruction() ||
1104 MI
->getFlag(MachineInstr::FrameSetup
))
1107 if (MI
->isInlineAsm()) {
1108 // Count the number of register definitions to find the asm string.
1109 unsigned NumDefs
= 0;
1110 for (; MI
->getOperand(NumDefs
).isReg() && MI
->getOperand(NumDefs
).isDef();
1114 // Skip this inline asm instruction if the asmstr is empty.
1115 const char *AsmStr
= MI
->getOperand(NumDefs
).getSymbolName();
1120 if (MI
->getOpcode() == BPF::LD_imm64
)
1123 // Skip this instruction if no DebugLoc or the DebugLoc
1124 // is the same as the previous instruction.
1125 const DebugLoc
&DL
= MI
->getDebugLoc();
1126 if (!DL
|| PrevInstLoc
== DL
) {
1127 // This instruction will be skipped, no LineInfo has
1128 // been generated, construct one based on function signature.
1129 if (LineInfoGenerated
== false) {
1130 auto *S
= MI
->getMF()->getFunction().getSubprogram();
1131 MCSymbol
*FuncLabel
= Asm
->getFunctionBegin();
1132 constructLineInfo(S
, FuncLabel
, S
->getLine(), 0);
1133 LineInfoGenerated
= true;
1139 // Create a temporary label to remember the insn for lineinfo.
1140 MCSymbol
*LineSym
= OS
.getContext().createTempSymbol();
1141 OS
.EmitLabel(LineSym
);
1143 // Construct the lineinfo.
1144 auto SP
= DL
.get()->getScope()->getSubprogram();
1145 constructLineInfo(SP
, LineSym
, DL
.getLine(), DL
.getCol());
1147 LineInfoGenerated
= true;
1151 void BTFDebug::processGlobals(bool ProcessingMapDef
) {
1152 // Collect all types referenced by globals.
1153 const Module
*M
= MMI
->getModule();
1154 for (const GlobalVariable
&Global
: M
->globals()) {
1155 // Ignore external globals for now.
1156 if (!Global
.hasInitializer() && Global
.hasExternalLinkage())
1159 // Decide the section name.
1161 if (Global
.hasSection()) {
1162 SecName
= Global
.getSection();
1164 // data, bss, or readonly sections
1165 if (Global
.isConstant())
1166 SecName
= ".rodata";
1168 SecName
= Global
.getInitializer()->isZeroValue() ? ".bss" : ".data";
1171 if (ProcessingMapDef
!= SecName
.startswith(".maps"))
1174 SmallVector
<DIGlobalVariableExpression
*, 1> GVs
;
1175 Global
.getDebugInfo(GVs
);
1176 uint32_t GVTypeId
= 0;
1177 for (auto *GVE
: GVs
) {
1178 if (SecName
.startswith(".maps"))
1179 visitMapDefType(GVE
->getVariable()->getType(), GVTypeId
);
1181 visitTypeEntry(GVE
->getVariable()->getType(), GVTypeId
, false, false);
1185 // Only support the following globals:
1186 // . static variables
1187 // . non-static global variables with section attributes
1188 // Essentially means:
1189 // . .bcc/.data/.rodata DataSec entities only contain static data
1190 // . Other DataSec entities contain static or initialized global data.
1191 // Initialized global data are mostly used for finding map key/value type
1192 // id's. Whether DataSec is readonly or not can be found from
1193 // corresponding ELF section flags.
1194 auto Linkage
= Global
.getLinkage();
1195 if (Linkage
!= GlobalValue::InternalLinkage
&&
1196 (Linkage
!= GlobalValue::ExternalLinkage
|| !Global
.hasSection()))
1199 uint32_t GVarInfo
= Linkage
== GlobalValue::ExternalLinkage
1200 ? BTF::VAR_GLOBAL_ALLOCATED
1203 llvm::make_unique
<BTFKindVar
>(Global
.getName(), GVTypeId
, GVarInfo
);
1204 uint32_t VarId
= addType(std::move(VarEntry
));
1206 // Find or create a DataSec
1207 if (DataSecEntries
.find(SecName
) == DataSecEntries
.end()) {
1208 DataSecEntries
[SecName
] = llvm::make_unique
<BTFKindDataSec
>(Asm
, SecName
);
1211 // Calculate symbol size
1212 const DataLayout
&DL
= Global
.getParent()->getDataLayout();
1213 uint32_t Size
= DL
.getTypeAllocSize(Global
.getType()->getElementType());
1215 DataSecEntries
[SecName
]->addVar(VarId
, Asm
->getSymbol(&Global
), Size
);
1219 /// Emit proper patchable instructions.
1220 bool BTFDebug::InstLower(const MachineInstr
*MI
, MCInst
&OutMI
) {
1221 if (MI
->getOpcode() == BPF::LD_imm64
) {
1222 const MachineOperand
&MO
= MI
->getOperand(1);
1223 if (MO
.isGlobal()) {
1224 const GlobalValue
*GVal
= MO
.getGlobal();
1225 auto *GVar
= dyn_cast
<GlobalVariable
>(GVal
);
1226 if (GVar
&& GVar
->hasAttribute(BPFCoreSharedInfo::AmaAttr
)) {
1227 MDNode
*MDN
= GVar
->getMetadata(LLVMContext::MD_preserve_access_index
);
1228 DIType
*Ty
= dyn_cast
<DIType
>(MDN
);
1229 std::string TypeName
= Ty
->getName();
1230 int64_t Imm
= AccessOffsets
[TypeName
+ ":" + GVar
->getName().str()];
1232 // Emit "mov ri, <imm>" for abstract member accesses.
1233 OutMI
.setOpcode(BPF::MOV_ri
);
1234 OutMI
.addOperand(MCOperand::createReg(MI
->getOperand(0).getReg()));
1235 OutMI
.addOperand(MCOperand::createImm(Imm
));
1237 } else if (GVar
&& !GVar
->hasInitializer() &&
1238 GVar
->hasExternalLinkage() &&
1239 GVar
->getSection() == BPFCoreSharedInfo::PatchableExtSecName
) {
1240 const IntegerType
*IntTy
= dyn_cast
<IntegerType
>(GVar
->getValueType());
1242 // For patchable externals, emit "LD_imm64, ri, 0" if the external
1243 // variable is 64bit width, emit "mov ri, 0" otherwise.
1244 if (IntTy
->getBitWidth() == 64)
1245 OutMI
.setOpcode(BPF::LD_imm64
);
1247 OutMI
.setOpcode(BPF::MOV_ri
);
1248 OutMI
.addOperand(MCOperand::createReg(MI
->getOperand(0).getReg()));
1249 OutMI
.addOperand(MCOperand::createImm(0));
1257 void BTFDebug::endModule() {
1258 // Collect MapDef globals if not collected yet.
1259 if (MapDefNotCollected
) {
1260 processGlobals(true);
1261 MapDefNotCollected
= false;
1264 // Collect global types/variables except MapDef globals.
1265 processGlobals(false);
1266 for (auto &DataSec
: DataSecEntries
)
1267 addType(std::move(DataSec
.second
));
1270 for (auto &Fixup
: FixupDerivedTypes
) {
1271 StringRef TypeName
= Fixup
.first
;
1272 bool IsUnion
= Fixup
.second
.first
;
1274 // Search through struct types
1275 uint32_t StructTypeId
= 0;
1276 for (const auto &StructType
: StructTypes
) {
1277 if (StructType
->getName() == TypeName
) {
1278 StructTypeId
= StructType
->getId();
1283 if (StructTypeId
== 0) {
1284 auto FwdTypeEntry
= llvm::make_unique
<BTFTypeFwd
>(TypeName
, IsUnion
);
1285 StructTypeId
= addType(std::move(FwdTypeEntry
));
1288 for (auto &DType
: Fixup
.second
.second
) {
1289 DType
->setPointeeType(StructTypeId
);
1293 // Complete BTF type cross refereences.
1294 for (const auto &TypeEntry
: TypeEntries
)
1295 TypeEntry
->completeType(*this);
1297 // Emit BTF sections.
1299 emitBTFExtSection();