1//===- BTFDebug.cpp - BTF Generator ---------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains support for writing BTF debug info.
10//
11//===----------------------------------------------------------------------===//
12
13#include "BTFDebug.h"
14#include "BPF.h"
15#include "BPFCORE.h"
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/CodeGen/MachineOperand.h"
21#include "llvm/IR/Module.h"
22#include "llvm/MC/MCContext.h"
23#include "llvm/MC/MCObjectFileInfo.h"
24#include "llvm/MC/MCSectionELF.h"
25#include "llvm/MC/MCStreamer.h"
26#include "llvm/Support/LineIterator.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include "llvm/Target/TargetLoweringObjectFile.h"
29#include <optional>
30
31using namespace llvm;
32
33static const char *BTFKindStr[] = {
34#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
35#include "llvm/DebugInfo/BTF/BTF.def"
36};
37
38static const DIType *tryRemoveAtomicType(const DIType *Ty) {
39 if (!Ty)
40 return Ty;
41 auto DerivedTy = dyn_cast<DIDerivedType>(Val: Ty);
42 if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
43 return DerivedTy->getBaseType();
44 return Ty;
45}
46
47/// Emit a BTF common type.
48void BTFTypeBase::emitType(MCStreamer &OS) {
49 OS.AddComment(T: std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(val: Id) +
50 ")");
51 OS.emitInt32(Value: BTFType.NameOff);
52 OS.AddComment(T: "0x" + Twine::utohexstr(Val: BTFType.Info));
53 OS.emitInt32(Value: BTFType.Info);
54 OS.emitInt32(Value: BTFType.Size);
55}
56
57BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag,
58 bool NeedsFixup)
59 : DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->getName()) {
60 switch (Tag) {
61 case dwarf::DW_TAG_pointer_type:
62 Kind = BTF::BTF_KIND_PTR;
63 break;
64 case dwarf::DW_TAG_const_type:
65 Kind = BTF::BTF_KIND_CONST;
66 break;
67 case dwarf::DW_TAG_volatile_type:
68 Kind = BTF::BTF_KIND_VOLATILE;
69 break;
70 case dwarf::DW_TAG_typedef:
71 Kind = BTF::BTF_KIND_TYPEDEF;
72 break;
73 case dwarf::DW_TAG_restrict_type:
74 Kind = BTF::BTF_KIND_RESTRICT;
75 break;
76 default:
77 llvm_unreachable("Unknown DIDerivedType Tag");
78 }
79 BTFType.Info = Kind << 24;
80}
81
82/// Used by DW_TAG_pointer_type only.
83BTFTypeDerived::BTFTypeDerived(unsigned NextTypeId, unsigned Tag,
84 StringRef Name)
85 : DTy(nullptr), NeedsFixup(false), Name(Name) {
86 Kind = BTF::BTF_KIND_PTR;
87 BTFType.Info = Kind << 24;
88 BTFType.Type = NextTypeId;
89}
90
91void BTFTypeDerived::completeType(BTFDebug &BDebug) {
92 if (IsCompleted)
93 return;
94 IsCompleted = true;
95
96 BTFType.NameOff = BDebug.addString(S: Name);
97
98 if (NeedsFixup || !DTy)
99 return;
100
101 // The base type for PTR/CONST/VOLATILE could be void.
102 const DIType *ResolvedType = tryRemoveAtomicType(Ty: DTy->getBaseType());
103 if (!ResolvedType) {
104 assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
105 Kind == BTF::BTF_KIND_VOLATILE) &&
106 "Invalid null basetype");
107 BTFType.Type = 0;
108 } else {
109 BTFType.Type = BDebug.getTypeId(Ty: ResolvedType);
110 }
111}
112
113void BTFTypeDerived::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
114
115void BTFTypeDerived::setPointeeType(uint32_t PointeeType) {
116 BTFType.Type = PointeeType;
117}
118
119/// Represent a struct/union forward declaration.
120BTFTypeFwd::BTFTypeFwd(StringRef Name, bool IsUnion) : Name(Name) {
121 Kind = BTF::BTF_KIND_FWD;
122 BTFType.Info = IsUnion << 31 | Kind << 24;
123 BTFType.Type = 0;
124}
125
126void BTFTypeFwd::completeType(BTFDebug &BDebug) {
127 if (IsCompleted)
128 return;
129 IsCompleted = true;
130
131 BTFType.NameOff = BDebug.addString(S: Name);
132}
133
134void BTFTypeFwd::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
135
136BTFTypeInt::BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits,
137 uint32_t OffsetInBits, StringRef TypeName)
138 : Name(TypeName) {
139 // Translate IR int encoding to BTF int encoding.
140 uint8_t BTFEncoding;
141 switch (Encoding) {
142 case dwarf::DW_ATE_boolean:
143 BTFEncoding = BTF::INT_BOOL;
144 break;
145 case dwarf::DW_ATE_signed:
146 case dwarf::DW_ATE_signed_char:
147 BTFEncoding = BTF::INT_SIGNED;
148 break;
149 case dwarf::DW_ATE_unsigned:
150 case dwarf::DW_ATE_unsigned_char:
151 BTFEncoding = 0;
152 break;
153 default:
154 llvm_unreachable("Unknown BTFTypeInt Encoding");
155 }
156
157 Kind = BTF::BTF_KIND_INT;
158 BTFType.Info = Kind << 24;
159 BTFType.Size = roundupToBytes(NumBits: SizeInBits);
160 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
161}
162
163void BTFTypeInt::completeType(BTFDebug &BDebug) {
164 if (IsCompleted)
165 return;
166 IsCompleted = true;
167
168 BTFType.NameOff = BDebug.addString(S: Name);
169}
170
171void BTFTypeInt::emitType(MCStreamer &OS) {
172 BTFTypeBase::emitType(OS);
173 OS.AddComment(T: "0x" + Twine::utohexstr(Val: IntVal));
174 OS.emitInt32(Value: IntVal);
175}
176
177BTFTypeEnum::BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen,
178 bool IsSigned) : ETy(ETy) {
179 Kind = BTF::BTF_KIND_ENUM;
180 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
181 BTFType.Size = roundupToBytes(NumBits: ETy->getSizeInBits());
182}
183
184void BTFTypeEnum::completeType(BTFDebug &BDebug) {
185 if (IsCompleted)
186 return;
187 IsCompleted = true;
188
189 BTFType.NameOff = BDebug.addString(S: ETy->getName());
190
191 DINodeArray Elements = ETy->getElements();
192 for (const auto Element : Elements) {
193 const auto *Enum = cast<DIEnumerator>(Val: Element);
194
195 struct BTF::BTFEnum BTFEnum;
196 BTFEnum.NameOff = BDebug.addString(S: Enum->getName());
197 // BTF enum value is 32bit, enforce it.
198 uint32_t Value;
199 if (Enum->isUnsigned())
200 Value = static_cast<uint32_t>(Enum->getValue().getZExtValue());
201 else
202 Value = static_cast<uint32_t>(Enum->getValue().getSExtValue());
203 BTFEnum.Val = Value;
204 EnumValues.push_back(x: BTFEnum);
205 }
206}
207
208void BTFTypeEnum::emitType(MCStreamer &OS) {
209 BTFTypeBase::emitType(OS);
210 for (const auto &Enum : EnumValues) {
211 OS.emitInt32(Value: Enum.NameOff);
212 OS.emitInt32(Value: Enum.Val);
213 }
214}
215
216BTFTypeEnum64::BTFTypeEnum64(const DICompositeType *ETy, uint32_t VLen,
217 bool IsSigned) : ETy(ETy) {
218 Kind = BTF::BTF_KIND_ENUM64;
219 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
220 BTFType.Size = roundupToBytes(NumBits: ETy->getSizeInBits());
221}
222
223void BTFTypeEnum64::completeType(BTFDebug &BDebug) {
224 if (IsCompleted)
225 return;
226 IsCompleted = true;
227
228 BTFType.NameOff = BDebug.addString(S: ETy->getName());
229
230 DINodeArray Elements = ETy->getElements();
231 for (const auto Element : Elements) {
232 const auto *Enum = cast<DIEnumerator>(Val: Element);
233
234 struct BTF::BTFEnum64 BTFEnum;
235 BTFEnum.NameOff = BDebug.addString(S: Enum->getName());
236 uint64_t Value;
237 if (Enum->isUnsigned())
238 Value = static_cast<uint64_t>(Enum->getValue().getZExtValue());
239 else
240 Value = static_cast<uint64_t>(Enum->getValue().getSExtValue());
241 BTFEnum.Val_Lo32 = Value;
242 BTFEnum.Val_Hi32 = Value >> 32;
243 EnumValues.push_back(x: BTFEnum);
244 }
245}
246
247void BTFTypeEnum64::emitType(MCStreamer &OS) {
248 BTFTypeBase::emitType(OS);
249 for (const auto &Enum : EnumValues) {
250 OS.emitInt32(Value: Enum.NameOff);
251 OS.AddComment(T: "0x" + Twine::utohexstr(Val: Enum.Val_Lo32));
252 OS.emitInt32(Value: Enum.Val_Lo32);
253 OS.AddComment(T: "0x" + Twine::utohexstr(Val: Enum.Val_Hi32));
254 OS.emitInt32(Value: Enum.Val_Hi32);
255 }
256}
257
258BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems) {
259 Kind = BTF::BTF_KIND_ARRAY;
260 BTFType.NameOff = 0;
261 BTFType.Info = Kind << 24;
262 BTFType.Size = 0;
263
264 ArrayInfo.ElemType = ElemTypeId;
265 ArrayInfo.Nelems = NumElems;
266}
267
268/// Represent a BTF array.
269void BTFTypeArray::completeType(BTFDebug &BDebug) {
270 if (IsCompleted)
271 return;
272 IsCompleted = true;
273
274 // The IR does not really have a type for the index.
275 // A special type for array index should have been
276 // created during initial type traversal. Just
277 // retrieve that type id.
278 ArrayInfo.IndexType = BDebug.getArrayIndexTypeId();
279}
280
281void BTFTypeArray::emitType(MCStreamer &OS) {
282 BTFTypeBase::emitType(OS);
283 OS.emitInt32(Value: ArrayInfo.ElemType);
284 OS.emitInt32(Value: ArrayInfo.IndexType);
285 OS.emitInt32(Value: ArrayInfo.Nelems);
286}
287
288/// Represent either a struct or a union.
289BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct,
290 bool HasBitField, uint32_t Vlen)
291 : STy(STy), HasBitField(HasBitField) {
292 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
293 BTFType.Size = roundupToBytes(NumBits: STy->getSizeInBits());
294 BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
295}
296
297void BTFTypeStruct::completeType(BTFDebug &BDebug) {
298 if (IsCompleted)
299 return;
300 IsCompleted = true;
301
302 BTFType.NameOff = BDebug.addString(S: STy->getName());
303
304 // Add struct/union members.
305 const DINodeArray Elements = STy->getElements();
306 for (const auto *Element : Elements) {
307 struct BTF::BTFMember BTFMember;
308 const auto *DDTy = cast<DIDerivedType>(Val: Element);
309
310 BTFMember.NameOff = BDebug.addString(S: DDTy->getName());
311 if (HasBitField) {
312 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
313 BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
314 } else {
315 BTFMember.Offset = DDTy->getOffsetInBits();
316 }
317 const auto *BaseTy = tryRemoveAtomicType(Ty: DDTy->getBaseType());
318 BTFMember.Type = BDebug.getTypeId(Ty: BaseTy);
319 Members.push_back(x: BTFMember);
320 }
321}
322
323void BTFTypeStruct::emitType(MCStreamer &OS) {
324 BTFTypeBase::emitType(OS);
325 for (const auto &Member : Members) {
326 OS.emitInt32(Value: Member.NameOff);
327 OS.emitInt32(Value: Member.Type);
328 OS.AddComment(T: "0x" + Twine::utohexstr(Val: Member.Offset));
329 OS.emitInt32(Value: Member.Offset);
330 }
331}
332
333std::string BTFTypeStruct::getName() { return std::string(STy->getName()); }
334
335/// The Func kind represents both subprogram and pointee of function
336/// pointers. If the FuncName is empty, it represents a pointee of function
337/// pointer. Otherwise, it represents a subprogram. The func arg names
338/// are empty for pointee of function pointer case, and are valid names
339/// for subprogram.
340BTFTypeFuncProto::BTFTypeFuncProto(
341 const DISubroutineType *STy, uint32_t VLen,
342 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
343 : STy(STy), FuncArgNames(FuncArgNames) {
344 Kind = BTF::BTF_KIND_FUNC_PROTO;
345 BTFType.Info = (Kind << 24) | VLen;
346}
347
348void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
349 if (IsCompleted)
350 return;
351 IsCompleted = true;
352
353 DITypeRefArray Elements = STy->getTypeArray();
354 auto RetType = tryRemoveAtomicType(Ty: Elements[0]);
355 BTFType.Type = RetType ? BDebug.getTypeId(Ty: RetType) : 0;
356 BTFType.NameOff = 0;
357
358 // For null parameter which is typically the last one
359 // to represent the vararg, encode the NameOff/Type to be 0.
360 for (unsigned I = 1, N = Elements.size(); I < N; ++I) {
361 struct BTF::BTFParam Param;
362 auto Element = tryRemoveAtomicType(Ty: Elements[I]);
363 if (Element) {
364 Param.NameOff = BDebug.addString(S: FuncArgNames[I]);
365 Param.Type = BDebug.getTypeId(Ty: Element);
366 } else {
367 Param.NameOff = 0;
368 Param.Type = 0;
369 }
370 Parameters.push_back(x: Param);
371 }
372}
373
374void BTFTypeFuncProto::emitType(MCStreamer &OS) {
375 BTFTypeBase::emitType(OS);
376 for (const auto &Param : Parameters) {
377 OS.emitInt32(Value: Param.NameOff);
378 OS.emitInt32(Value: Param.Type);
379 }
380}
381
382BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId,
383 uint32_t Scope)
384 : Name(FuncName) {
385 Kind = BTF::BTF_KIND_FUNC;
386 BTFType.Info = (Kind << 24) | Scope;
387 BTFType.Type = ProtoTypeId;
388}
389
390void BTFTypeFunc::completeType(BTFDebug &BDebug) {
391 if (IsCompleted)
392 return;
393 IsCompleted = true;
394
395 BTFType.NameOff = BDebug.addString(S: Name);
396}
397
398void BTFTypeFunc::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
399
400BTFKindVar::BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
401 : Name(VarName) {
402 Kind = BTF::BTF_KIND_VAR;
403 BTFType.Info = Kind << 24;
404 BTFType.Type = TypeId;
405 Info = VarInfo;
406}
407
408void BTFKindVar::completeType(BTFDebug &BDebug) {
409 BTFType.NameOff = BDebug.addString(S: Name);
410}
411
412void BTFKindVar::emitType(MCStreamer &OS) {
413 BTFTypeBase::emitType(OS);
414 OS.emitInt32(Value: Info);
415}
416
417BTFKindDataSec::BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
418 : Asm(AsmPrt), Name(SecName) {
419 Kind = BTF::BTF_KIND_DATASEC;
420 BTFType.Info = Kind << 24;
421 BTFType.Size = 0;
422}
423
424void BTFKindDataSec::completeType(BTFDebug &BDebug) {
425 BTFType.NameOff = BDebug.addString(S: Name);
426 BTFType.Info |= Vars.size();
427}
428
429void BTFKindDataSec::emitType(MCStreamer &OS) {
430 BTFTypeBase::emitType(OS);
431
432 for (const auto &V : Vars) {
433 OS.emitInt32(Value: std::get<0>(t: V));
434 Asm->emitLabelReference(Label: std::get<1>(t: V), Size: 4);
435 OS.emitInt32(Value: std::get<2>(t: V));
436 }
437}
438
439BTFTypeFloat::BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
440 : Name(TypeName) {
441 Kind = BTF::BTF_KIND_FLOAT;
442 BTFType.Info = Kind << 24;
443 BTFType.Size = roundupToBytes(NumBits: SizeInBits);
444}
445
446void BTFTypeFloat::completeType(BTFDebug &BDebug) {
447 if (IsCompleted)
448 return;
449 IsCompleted = true;
450
451 BTFType.NameOff = BDebug.addString(S: Name);
452}
453
454BTFTypeDeclTag::BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentIdx,
455 StringRef Tag)
456 : Tag(Tag) {
457 Kind = BTF::BTF_KIND_DECL_TAG;
458 BTFType.Info = Kind << 24;
459 BTFType.Type = BaseTypeId;
460 Info = ComponentIdx;
461}
462
463void BTFTypeDeclTag::completeType(BTFDebug &BDebug) {
464 if (IsCompleted)
465 return;
466 IsCompleted = true;
467
468 BTFType.NameOff = BDebug.addString(S: Tag);
469}
470
471void BTFTypeDeclTag::emitType(MCStreamer &OS) {
472 BTFTypeBase::emitType(OS);
473 OS.emitInt32(Value: Info);
474}
475
476BTFTypeTypeTag::BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)
477 : DTy(nullptr), Tag(Tag) {
478 Kind = BTF::BTF_KIND_TYPE_TAG;
479 BTFType.Info = Kind << 24;
480 BTFType.Type = NextTypeId;
481}
482
483BTFTypeTypeTag::BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag)
484 : DTy(DTy), Tag(Tag) {
485 Kind = BTF::BTF_KIND_TYPE_TAG;
486 BTFType.Info = Kind << 24;
487}
488
489void BTFTypeTypeTag::completeType(BTFDebug &BDebug) {
490 if (IsCompleted)
491 return;
492 IsCompleted = true;
493 BTFType.NameOff = BDebug.addString(S: Tag);
494 if (DTy) {
495 const DIType *ResolvedType = tryRemoveAtomicType(Ty: DTy->getBaseType());
496 if (!ResolvedType)
497 BTFType.Type = 0;
498 else
499 BTFType.Type = BDebug.getTypeId(Ty: ResolvedType);
500 }
501}
502
503uint32_t BTFStringTable::addString(StringRef S) {
504 // Check whether the string already exists.
505 for (auto &OffsetM : OffsetToIdMap) {
506 if (Table[OffsetM.second] == S)
507 return OffsetM.first;
508 }
509 // Not find, add to the string table.
510 uint32_t Offset = Size;
511 OffsetToIdMap[Offset] = Table.size();
512 Table.push_back(x: std::string(S));
513 Size += S.size() + 1;
514 return Offset;
515}
516
517BTFDebug::BTFDebug(AsmPrinter *AP)
518 : DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false),
519 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
520 MapDefNotCollected(true) {
521 addString(S: "\0");
522}
523
524uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
525 const DIType *Ty) {
526 TypeEntry->setId(TypeEntries.size() + 1);
527 uint32_t Id = TypeEntry->getId();
528 DIToIdMap[Ty] = Id;
529 TypeEntries.push_back(x: std::move(TypeEntry));
530 return Id;
531}
532
533uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
534 TypeEntry->setId(TypeEntries.size() + 1);
535 uint32_t Id = TypeEntry->getId();
536 TypeEntries.push_back(x: std::move(TypeEntry));
537 return Id;
538}
539
540void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
541 // Only int and binary floating point types are supported in BTF.
542 uint32_t Encoding = BTy->getEncoding();
543 std::unique_ptr<BTFTypeBase> TypeEntry;
544 switch (Encoding) {
545 case dwarf::DW_ATE_boolean:
546 case dwarf::DW_ATE_signed:
547 case dwarf::DW_ATE_signed_char:
548 case dwarf::DW_ATE_unsigned:
549 case dwarf::DW_ATE_unsigned_char:
550 // Create a BTF type instance for this DIBasicType and put it into
551 // DIToIdMap for cross-type reference check.
552 TypeEntry = std::make_unique<BTFTypeInt>(
553 args&: Encoding, args: BTy->getSizeInBits(), args: BTy->getOffsetInBits(), args: BTy->getName());
554 break;
555 case dwarf::DW_ATE_float:
556 TypeEntry =
557 std::make_unique<BTFTypeFloat>(args: BTy->getSizeInBits(), args: BTy->getName());
558 break;
559 default:
560 return;
561 }
562
563 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: BTy);
564}
565
566/// Handle subprogram or subroutine types.
567void BTFDebug::visitSubroutineType(
568 const DISubroutineType *STy, bool ForSubprog,
569 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
570 uint32_t &TypeId) {
571 DITypeRefArray Elements = STy->getTypeArray();
572 uint32_t VLen = Elements.size() - 1;
573 if (VLen > BTF::MAX_VLEN)
574 return;
575
576 // Subprogram has a valid non-zero-length name, and the pointee of
577 // a function pointer has an empty name. The subprogram type will
578 // not be added to DIToIdMap as it should not be referenced by
579 // any other types.
580 auto TypeEntry = std::make_unique<BTFTypeFuncProto>(args&: STy, args&: VLen, args: FuncArgNames);
581 if (ForSubprog)
582 TypeId = addType(TypeEntry: std::move(TypeEntry)); // For subprogram
583 else
584 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: STy); // For func ptr
585
586 // Visit return type and func arg types.
587 for (const auto Element : Elements) {
588 visitTypeEntry(Ty: Element);
589 }
590}
591
592void BTFDebug::processDeclAnnotations(DINodeArray Annotations,
593 uint32_t BaseTypeId,
594 int ComponentIdx) {
595 if (!Annotations)
596 return;
597
598 for (const Metadata *Annotation : Annotations->operands()) {
599 const MDNode *MD = cast<MDNode>(Val: Annotation);
600 const MDString *Name = cast<MDString>(Val: MD->getOperand(I: 0));
601 if (Name->getString() != "btf_decl_tag")
602 continue;
603
604 const MDString *Value = cast<MDString>(Val: MD->getOperand(I: 1));
605 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(args&: BaseTypeId, args&: ComponentIdx,
606 args: Value->getString());
607 addType(TypeEntry: std::move(TypeEntry));
608 }
609}
610
611uint32_t BTFDebug::processDISubprogram(const DISubprogram *SP,
612 uint32_t ProtoTypeId, uint8_t Scope) {
613 auto FuncTypeEntry =
614 std::make_unique<BTFTypeFunc>(args: SP->getName(), args&: ProtoTypeId, args&: Scope);
615 uint32_t FuncId = addType(TypeEntry: std::move(FuncTypeEntry));
616
617 // Process argument annotations.
618 for (const DINode *DN : SP->getRetainedNodes()) {
619 if (const auto *DV = dyn_cast<DILocalVariable>(Val: DN)) {
620 uint32_t Arg = DV->getArg();
621 if (Arg)
622 processDeclAnnotations(Annotations: DV->getAnnotations(), BaseTypeId: FuncId, ComponentIdx: Arg - 1);
623 }
624 }
625 processDeclAnnotations(Annotations: SP->getAnnotations(), BaseTypeId: FuncId, ComponentIdx: -1);
626
627 return FuncId;
628}
629
630/// Generate btf_type_tag chains.
631int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) {
632 SmallVector<const MDString *, 4> MDStrs;
633 DINodeArray Annots = DTy->getAnnotations();
634 if (Annots) {
635 // For type with "int __tag1 __tag2 *p", the MDStrs will have
636 // content: [__tag1, __tag2].
637 for (const Metadata *Annotations : Annots->operands()) {
638 const MDNode *MD = cast<MDNode>(Val: Annotations);
639 const MDString *Name = cast<MDString>(Val: MD->getOperand(I: 0));
640 if (Name->getString() != "btf_type_tag")
641 continue;
642 MDStrs.push_back(Elt: cast<MDString>(Val: MD->getOperand(I: 1)));
643 }
644 }
645
646 if (MDStrs.size() == 0)
647 return -1;
648
649 // With MDStrs [__tag1, __tag2], the output type chain looks like
650 // PTR -> __tag2 -> __tag1 -> BaseType
651 // In the below, we construct BTF types with the order of __tag1, __tag2
652 // and PTR.
653 unsigned TmpTypeId;
654 std::unique_ptr<BTFTypeTypeTag> TypeEntry;
655 if (BaseTypeId >= 0)
656 TypeEntry =
657 std::make_unique<BTFTypeTypeTag>(args&: BaseTypeId, args: MDStrs[0]->getString());
658 else
659 TypeEntry = std::make_unique<BTFTypeTypeTag>(args&: DTy, args: MDStrs[0]->getString());
660 TmpTypeId = addType(TypeEntry: std::move(TypeEntry));
661
662 for (unsigned I = 1; I < MDStrs.size(); I++) {
663 const MDString *Value = MDStrs[I];
664 TypeEntry = std::make_unique<BTFTypeTypeTag>(args&: TmpTypeId, args: Value->getString());
665 TmpTypeId = addType(TypeEntry: std::move(TypeEntry));
666 }
667 return TmpTypeId;
668}
669
670/// Handle structure/union types.
671void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
672 uint32_t &TypeId) {
673 const DINodeArray Elements = CTy->getElements();
674 uint32_t VLen = Elements.size();
675 if (VLen > BTF::MAX_VLEN)
676 return;
677
678 // Check whether we have any bitfield members or not
679 bool HasBitField = false;
680 for (const auto *Element : Elements) {
681 auto E = cast<DIDerivedType>(Val: Element);
682 if (E->isBitField()) {
683 HasBitField = true;
684 break;
685 }
686 }
687
688 auto TypeEntry =
689 std::make_unique<BTFTypeStruct>(args&: CTy, args&: IsStruct, args&: HasBitField, args&: VLen);
690 StructTypes.push_back(x: TypeEntry.get());
691 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: CTy);
692
693 // Check struct/union annotations
694 processDeclAnnotations(Annotations: CTy->getAnnotations(), BaseTypeId: TypeId, ComponentIdx: -1);
695
696 // Visit all struct members.
697 int FieldNo = 0;
698 for (const auto *Element : Elements) {
699 const auto Elem = cast<DIDerivedType>(Val: Element);
700 visitTypeEntry(Ty: Elem);
701 processDeclAnnotations(Annotations: Elem->getAnnotations(), BaseTypeId: TypeId, ComponentIdx: FieldNo);
702 FieldNo++;
703 }
704}
705
706void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
707 // Visit array element type.
708 uint32_t ElemTypeId;
709 const DIType *ElemType = CTy->getBaseType();
710 visitTypeEntry(Ty: ElemType, TypeId&: ElemTypeId, CheckPointer: false, SeenPointer: false);
711
712 // Visit array dimensions.
713 DINodeArray Elements = CTy->getElements();
714 for (int I = Elements.size() - 1; I >= 0; --I) {
715 if (auto *Element = dyn_cast_or_null<DINode>(Val: Elements[I]))
716 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
717 const DISubrange *SR = cast<DISubrange>(Val: Element);
718 auto *CI = dyn_cast<ConstantInt *>(Val: SR->getCount());
719 int64_t Count = CI->getSExtValue();
720
721 // For struct s { int b; char c[]; }, the c[] will be represented
722 // as an array with Count = -1.
723 auto TypeEntry =
724 std::make_unique<BTFTypeArray>(args&: ElemTypeId,
725 args: Count >= 0 ? Count : 0);
726 if (I == 0)
727 ElemTypeId = addType(TypeEntry: std::move(TypeEntry), Ty: CTy);
728 else
729 ElemTypeId = addType(TypeEntry: std::move(TypeEntry));
730 }
731 }
732
733 // The array TypeId is the type id of the outermost dimension.
734 TypeId = ElemTypeId;
735
736 // The IR does not have a type for array index while BTF wants one.
737 // So create an array index type if there is none.
738 if (!ArrayIndexTypeId) {
739 auto TypeEntry = std::make_unique<BTFTypeInt>(args: dwarf::DW_ATE_unsigned, args: 32,
740 args: 0, args: "__ARRAY_SIZE_TYPE__");
741 ArrayIndexTypeId = addType(TypeEntry: std::move(TypeEntry));
742 }
743}
744
745void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {
746 DINodeArray Elements = CTy->getElements();
747 uint32_t VLen = Elements.size();
748 if (VLen > BTF::MAX_VLEN)
749 return;
750
751 bool IsSigned = false;
752 unsigned NumBits = 32;
753 // No BaseType implies forward declaration in which case a
754 // BTFTypeEnum with Vlen = 0 is emitted.
755 if (CTy->getBaseType() != nullptr) {
756 const auto *BTy = cast<DIBasicType>(Val: CTy->getBaseType());
757 IsSigned = BTy->getEncoding() == dwarf::DW_ATE_signed ||
758 BTy->getEncoding() == dwarf::DW_ATE_signed_char;
759 NumBits = BTy->getSizeInBits();
760 }
761
762 if (NumBits <= 32) {
763 auto TypeEntry = std::make_unique<BTFTypeEnum>(args&: CTy, args&: VLen, args&: IsSigned);
764 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: CTy);
765 } else {
766 assert(NumBits == 64);
767 auto TypeEntry = std::make_unique<BTFTypeEnum64>(args&: CTy, args&: VLen, args&: IsSigned);
768 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: CTy);
769 }
770 // No need to visit base type as BTF does not encode it.
771}
772
773/// Handle structure/union forward declarations.
774void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
775 uint32_t &TypeId) {
776 auto TypeEntry = std::make_unique<BTFTypeFwd>(args: CTy->getName(), args&: IsUnion);
777 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: CTy);
778}
779
780/// Handle structure, union, array and enumeration types.
781void BTFDebug::visitCompositeType(const DICompositeType *CTy,
782 uint32_t &TypeId) {
783 auto Tag = CTy->getTag();
784 if (Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
785 // Handle forward declaration differently as it does not have members.
786 if (CTy->isForwardDecl())
787 visitFwdDeclType(CTy, IsUnion: Tag == dwarf::DW_TAG_union_type, TypeId);
788 else
789 visitStructType(CTy, IsStruct: Tag == dwarf::DW_TAG_structure_type, TypeId);
790 } else if (Tag == dwarf::DW_TAG_array_type)
791 visitArrayType(CTy, TypeId);
792 else if (Tag == dwarf::DW_TAG_enumeration_type)
793 visitEnumType(CTy, TypeId);
794}
795
796bool BTFDebug::IsForwardDeclCandidate(const DIType *Base) {
797 if (const auto *CTy = dyn_cast<DICompositeType>(Val: Base)) {
798 auto CTag = CTy->getTag();
799 if ((CTag == dwarf::DW_TAG_structure_type ||
800 CTag == dwarf::DW_TAG_union_type) &&
801 !CTy->getName().empty() && !CTy->isForwardDecl())
802 return true;
803 }
804 return false;
805}
806
807/// Handle pointer, typedef, const, volatile, restrict and member types.
808void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
809 bool CheckPointer, bool SeenPointer) {
810 unsigned Tag = DTy->getTag();
811
812 if (Tag == dwarf::DW_TAG_atomic_type)
813 return visitTypeEntry(Ty: DTy->getBaseType(), TypeId, CheckPointer,
814 SeenPointer);
815
816 /// Try to avoid chasing pointees, esp. structure pointees which may
817 /// unnecessary bring in a lot of types.
818 if (CheckPointer && !SeenPointer) {
819 SeenPointer = Tag == dwarf::DW_TAG_pointer_type && !DTy->getAnnotations();
820 }
821
822 if (CheckPointer && SeenPointer) {
823 const DIType *Base = DTy->getBaseType();
824 if (Base) {
825 if (IsForwardDeclCandidate(Base)) {
826 /// Find a candidate, generate a fixup. Later on the struct/union
827 /// pointee type will be replaced with either a real type or
828 /// a forward declaration.
829 auto TypeEntry = std::make_unique<BTFTypeDerived>(args&: DTy, args&: Tag, args: true);
830 auto &Fixup = FixupDerivedTypes[cast<DICompositeType>(Val: Base)];
831 Fixup.push_back(x: std::make_pair(x&: DTy, y: TypeEntry.get()));
832 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: DTy);
833 return;
834 }
835 }
836 }
837
838 if (Tag == dwarf::DW_TAG_pointer_type) {
839 int TmpTypeId = genBTFTypeTags(DTy, BaseTypeId: -1);
840 if (TmpTypeId >= 0) {
841 auto TypeDEntry =
842 std::make_unique<BTFTypeDerived>(args&: TmpTypeId, args&: Tag, args: DTy->getName());
843 TypeId = addType(TypeEntry: std::move(TypeDEntry), Ty: DTy);
844 } else {
845 auto TypeEntry = std::make_unique<BTFTypeDerived>(args&: DTy, args&: Tag, args: false);
846 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: DTy);
847 }
848 } else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type ||
849 Tag == dwarf::DW_TAG_volatile_type ||
850 Tag == dwarf::DW_TAG_restrict_type) {
851 auto TypeEntry = std::make_unique<BTFTypeDerived>(args&: DTy, args&: Tag, args: false);
852 TypeId = addType(TypeEntry: std::move(TypeEntry), Ty: DTy);
853 if (Tag == dwarf::DW_TAG_typedef)
854 processDeclAnnotations(Annotations: DTy->getAnnotations(), BaseTypeId: TypeId, ComponentIdx: -1);
855 } else if (Tag != dwarf::DW_TAG_member) {
856 return;
857 }
858
859 // Visit base type of pointer, typedef, const, volatile, restrict or
860 // struct/union member.
861 uint32_t TempTypeId = 0;
862 if (Tag == dwarf::DW_TAG_member)
863 visitTypeEntry(Ty: DTy->getBaseType(), TypeId&: TempTypeId, CheckPointer: true, SeenPointer: false);
864 else
865 visitTypeEntry(Ty: DTy->getBaseType(), TypeId&: TempTypeId, CheckPointer, SeenPointer);
866}
867
868/// Visit a type entry. CheckPointer is true if the type has
869/// one of its predecessors as one struct/union member. SeenPointer
870/// is true if CheckPointer is true and one of its predecessors
871/// is a pointer. The goal of CheckPointer and SeenPointer is to
872/// do pruning for struct/union types so some of these types
873/// will not be emitted in BTF and rather forward declarations
874/// will be generated.
875void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId,
876 bool CheckPointer, bool SeenPointer) {
877 if (!Ty || DIToIdMap.find(x: Ty) != DIToIdMap.end()) {
878 TypeId = DIToIdMap[Ty];
879
880 // To handle the case like the following:
881 // struct t;
882 // typedef struct t _t;
883 // struct s1 { _t *c; };
884 // int test1(struct s1 *arg) { ... }
885 //
886 // struct t { int a; int b; };
887 // struct s2 { _t c; }
888 // int test2(struct s2 *arg) { ... }
889 //
890 // During traversing test1() argument, "_t" is recorded
891 // in DIToIdMap and a forward declaration fixup is created
892 // for "struct t" to avoid pointee type traversal.
893 //
894 // During traversing test2() argument, even if we see "_t" is
895 // already defined, we should keep moving to eventually
896 // bring in types for "struct t". Otherwise, the "struct s2"
897 // definition won't be correct.
898 //
899 // In the above, we have following debuginfo:
900 // {ptr, struct_member} -> typedef -> struct
901 // and BTF type for 'typedef' is generated while 'struct' may
902 // be in FixUp. But let us generalize the above to handle
903 // {different types} -> [various derived types]+ -> another type.
904 // For example,
905 // {func_param, struct_member} -> const -> ptr -> volatile -> struct
906 // We will traverse const/ptr/volatile which already have corresponding
907 // BTF types and generate type for 'struct' which might be in Fixup
908 // state.
909 if (Ty && (!CheckPointer || !SeenPointer)) {
910 if (const auto *DTy = dyn_cast<DIDerivedType>(Val: Ty)) {
911 while (DTy) {
912 const DIType *BaseTy = DTy->getBaseType();
913 if (!BaseTy)
914 break;
915
916 if (DIToIdMap.find(x: BaseTy) != DIToIdMap.end()) {
917 DTy = dyn_cast<DIDerivedType>(Val: BaseTy);
918 } else {
919 if (CheckPointer && DTy->getTag() == dwarf::DW_TAG_pointer_type &&
920 !DTy->getAnnotations()) {
921 SeenPointer = true;
922 if (IsForwardDeclCandidate(Base: BaseTy))
923 break;
924 }
925 uint32_t TmpTypeId;
926 visitTypeEntry(Ty: BaseTy, TypeId&: TmpTypeId, CheckPointer, SeenPointer);
927 break;
928 }
929 }
930 }
931 }
932
933 return;
934 }
935
936 if (const auto *BTy = dyn_cast<DIBasicType>(Val: Ty))
937 visitBasicType(BTy, TypeId);
938 else if (const auto *STy = dyn_cast<DISubroutineType>(Val: Ty))
939 visitSubroutineType(STy, ForSubprog: false, FuncArgNames: std::unordered_map<uint32_t, StringRef>(),
940 TypeId);
941 else if (const auto *CTy = dyn_cast<DICompositeType>(Val: Ty))
942 visitCompositeType(CTy, TypeId);
943 else if (const auto *DTy = dyn_cast<DIDerivedType>(Val: Ty))
944 visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
945 else
946 llvm_unreachable("Unknown DIType");
947}
948
949void BTFDebug::visitTypeEntry(const DIType *Ty) {
950 uint32_t TypeId;
951 visitTypeEntry(Ty, TypeId, CheckPointer: false, SeenPointer: false);
952}
953
954void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
955 if (!Ty || DIToIdMap.find(x: Ty) != DIToIdMap.end()) {
956 TypeId = DIToIdMap[Ty];
957 return;
958 }
959
960 // MapDef type may be a struct type or a non-pointer derived type
961 const DIType *OrigTy = Ty;
962 while (auto *DTy = dyn_cast<DIDerivedType>(Val: Ty)) {
963 auto Tag = DTy->getTag();
964 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
965 Tag != dwarf::DW_TAG_volatile_type &&
966 Tag != dwarf::DW_TAG_restrict_type)
967 break;
968 Ty = DTy->getBaseType();
969 }
970
971 const auto *CTy = dyn_cast<DICompositeType>(Val: Ty);
972 if (!CTy)
973 return;
974
975 auto Tag = CTy->getTag();
976 if (Tag != dwarf::DW_TAG_structure_type || CTy->isForwardDecl())
977 return;
978
979 // Visit all struct members to ensure their types are visited.
980 const DINodeArray Elements = CTy->getElements();
981 for (const auto *Element : Elements) {
982 const auto *MemberType = cast<DIDerivedType>(Val: Element);
983 const DIType *MemberBaseType = MemberType->getBaseType();
984
985 // If the member is a composite type, that may indicate the currently
986 // visited composite type is a wrapper, and the member represents the
987 // actual map definition.
988 // In that case, visit the member with `visitMapDefType` instead of
989 // `visitTypeEntry`, treating it specifically as a map definition rather
990 // than as a regular composite type.
991 const auto *MemberCTy = dyn_cast<DICompositeType>(Val: MemberBaseType);
992 if (MemberCTy) {
993 visitMapDefType(Ty: MemberBaseType, TypeId);
994 } else {
995 visitTypeEntry(Ty: MemberBaseType);
996 }
997 }
998
999 // Visit this type, struct or a const/typedef/volatile/restrict type
1000 visitTypeEntry(Ty: OrigTy, TypeId, CheckPointer: false, SeenPointer: false);
1001}
1002
1003/// Read file contents from the actual file or from the source
1004std::string BTFDebug::populateFileContent(const DIFile *File) {
1005 std::string FileName;
1006
1007 if (!File->getFilename().starts_with(Prefix: "/") && File->getDirectory().size())
1008 FileName = File->getDirectory().str() + "/" + File->getFilename().str();
1009 else
1010 FileName = std::string(File->getFilename());
1011
1012 // No need to populate the contends if it has been populated!
1013 if (FileContent.contains(Key: FileName))
1014 return FileName;
1015
1016 std::vector<std::string> Content;
1017 std::string Line;
1018 Content.push_back(x: Line); // Line 0 for empty string
1019
1020 std::unique_ptr<MemoryBuffer> Buf;
1021 auto Source = File->getSource();
1022 if (Source)
1023 Buf = MemoryBuffer::getMemBufferCopy(InputData: *Source);
1024 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
1025 MemoryBuffer::getFile(Filename: FileName))
1026 Buf = std::move(*BufOrErr);
1027 if (Buf)
1028 for (line_iterator I(*Buf, false), E; I != E; ++I)
1029 Content.push_back(x: std::string(*I));
1030
1031 FileContent[FileName] = Content;
1032 return FileName;
1033}
1034
1035void BTFDebug::constructLineInfo(MCSymbol *Label, const DIFile *File,
1036 uint32_t Line, uint32_t Column) {
1037 std::string FileName = populateFileContent(File);
1038 BTFLineInfo LineInfo;
1039
1040 LineInfo.Label = Label;
1041 LineInfo.FileNameOff = addString(S: FileName);
1042 // If file content is not available, let LineOff = 0.
1043 const auto &Content = FileContent[FileName];
1044 if (Line < Content.size())
1045 LineInfo.LineOff = addString(S: Content[Line]);
1046 else
1047 LineInfo.LineOff = 0;
1048 LineInfo.LineNum = Line;
1049 LineInfo.ColumnNum = Column;
1050 LineInfoTable[SecNameOff].push_back(x: LineInfo);
1051}
1052
1053void BTFDebug::emitCommonHeader() {
1054 OS.AddComment(T: "0x" + Twine::utohexstr(Val: BTF::MAGIC));
1055 OS.emitIntValue(Value: BTF::MAGIC, Size: 2);
1056 OS.emitInt8(Value: BTF::VERSION);
1057 OS.emitInt8(Value: 0);
1058}
1059
1060void BTFDebug::emitBTFSection() {
1061 // Do not emit section if no types and only "" string.
1062 if (!TypeEntries.size() && StringTable.getSize() == 1)
1063 return;
1064
1065 MCContext &Ctx = OS.getContext();
1066 MCSectionELF *Sec = Ctx.getELFSection(Section: ".BTF", Type: ELF::SHT_PROGBITS, Flags: 0);
1067 Sec->setAlignment(Align(4));
1068 OS.switchSection(Section: Sec);
1069
1070 // Emit header.
1071 emitCommonHeader();
1072 OS.emitInt32(Value: BTF::HeaderSize);
1073
1074 uint32_t TypeLen = 0, StrLen;
1075 for (const auto &TypeEntry : TypeEntries)
1076 TypeLen += TypeEntry->getSize();
1077 StrLen = StringTable.getSize();
1078
1079 OS.emitInt32(Value: 0);
1080 OS.emitInt32(Value: TypeLen);
1081 OS.emitInt32(Value: TypeLen);
1082 OS.emitInt32(Value: StrLen);
1083
1084 // Emit type table.
1085 for (const auto &TypeEntry : TypeEntries)
1086 TypeEntry->emitType(OS);
1087
1088 // Emit string table.
1089 uint32_t StringOffset = 0;
1090 for (const auto &S : StringTable.getTable()) {
1091 OS.AddComment(T: "string offset=" + std::to_string(val: StringOffset));
1092 OS.emitBytes(Data: S);
1093 OS.emitBytes(Data: StringRef("\0", 1));
1094 StringOffset += S.size() + 1;
1095 }
1096}
1097
1098void BTFDebug::emitBTFExtSection() {
1099 // Do not emit section if empty FuncInfoTable and LineInfoTable
1100 // and FieldRelocTable.
1101 if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1102 !FieldRelocTable.size())
1103 return;
1104
1105 MCContext &Ctx = OS.getContext();
1106 MCSectionELF *Sec = Ctx.getELFSection(Section: ".BTF.ext", Type: ELF::SHT_PROGBITS, Flags: 0);
1107 Sec->setAlignment(Align(4));
1108 OS.switchSection(Section: Sec);
1109
1110 // Emit header.
1111 emitCommonHeader();
1112 OS.emitInt32(Value: BTF::ExtHeaderSize);
1113
1114 // Account for FuncInfo/LineInfo record size as well.
1115 uint32_t FuncLen = 4, LineLen = 4;
1116 // Do not account for optional FieldReloc.
1117 uint32_t FieldRelocLen = 0;
1118 for (const auto &FuncSec : FuncInfoTable) {
1119 FuncLen += BTF::SecFuncInfoSize;
1120 FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize;
1121 }
1122 for (const auto &LineSec : LineInfoTable) {
1123 LineLen += BTF::SecLineInfoSize;
1124 LineLen += LineSec.second.size() * BTF::BPFLineInfoSize;
1125 }
1126 for (const auto &FieldRelocSec : FieldRelocTable) {
1127 FieldRelocLen += BTF::SecFieldRelocSize;
1128 FieldRelocLen += FieldRelocSec.second.size() * BTF::BPFFieldRelocSize;
1129 }
1130
1131 if (FieldRelocLen)
1132 FieldRelocLen += 4;
1133
1134 OS.emitInt32(Value: 0);
1135 OS.emitInt32(Value: FuncLen);
1136 OS.emitInt32(Value: FuncLen);
1137 OS.emitInt32(Value: LineLen);
1138 OS.emitInt32(Value: FuncLen + LineLen);
1139 OS.emitInt32(Value: FieldRelocLen);
1140
1141 // Emit func_info table.
1142 OS.AddComment(T: "FuncInfo");
1143 OS.emitInt32(Value: BTF::BPFFuncInfoSize);
1144 for (const auto &FuncSec : FuncInfoTable) {
1145 OS.AddComment(T: "FuncInfo section string offset=" +
1146 std::to_string(val: FuncSec.first));
1147 OS.emitInt32(Value: FuncSec.first);
1148 OS.emitInt32(Value: FuncSec.second.size());
1149 for (const auto &FuncInfo : FuncSec.second) {
1150 Asm->emitLabelReference(Label: FuncInfo.Label, Size: 4);
1151 OS.emitInt32(Value: FuncInfo.TypeId);
1152 }
1153 }
1154
1155 // Emit line_info table.
1156 OS.AddComment(T: "LineInfo");
1157 OS.emitInt32(Value: BTF::BPFLineInfoSize);
1158 for (const auto &LineSec : LineInfoTable) {
1159 OS.AddComment(T: "LineInfo section string offset=" +
1160 std::to_string(val: LineSec.first));
1161 OS.emitInt32(Value: LineSec.first);
1162 OS.emitInt32(Value: LineSec.second.size());
1163 for (const auto &LineInfo : LineSec.second) {
1164 Asm->emitLabelReference(Label: LineInfo.Label, Size: 4);
1165 OS.emitInt32(Value: LineInfo.FileNameOff);
1166 OS.emitInt32(Value: LineInfo.LineOff);
1167 OS.AddComment(T: "Line " + std::to_string(val: LineInfo.LineNum) + " Col " +
1168 std::to_string(val: LineInfo.ColumnNum));
1169 OS.emitInt32(Value: LineInfo.LineNum << 10 | LineInfo.ColumnNum);
1170 }
1171 }
1172
1173 // Emit field reloc table.
1174 if (FieldRelocLen) {
1175 OS.AddComment(T: "FieldReloc");
1176 OS.emitInt32(Value: BTF::BPFFieldRelocSize);
1177 for (const auto &FieldRelocSec : FieldRelocTable) {
1178 OS.AddComment(T: "Field reloc section string offset=" +
1179 std::to_string(val: FieldRelocSec.first));
1180 OS.emitInt32(Value: FieldRelocSec.first);
1181 OS.emitInt32(Value: FieldRelocSec.second.size());
1182 for (const auto &FieldRelocInfo : FieldRelocSec.second) {
1183 Asm->emitLabelReference(Label: FieldRelocInfo.Label, Size: 4);
1184 OS.emitInt32(Value: FieldRelocInfo.TypeID);
1185 OS.emitInt32(Value: FieldRelocInfo.OffsetNameOff);
1186 OS.emitInt32(Value: FieldRelocInfo.RelocKind);
1187 }
1188 }
1189 }
1190}
1191
1192void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
1193 auto *SP = MF->getFunction().getSubprogram();
1194 auto *Unit = SP->getUnit();
1195
1196 if (Unit->getEmissionKind() == DICompileUnit::NoDebug) {
1197 SkipInstruction = true;
1198 return;
1199 }
1200 SkipInstruction = false;
1201
1202 // Collect MapDef types. Map definition needs to collect
1203 // pointee types. Do it first. Otherwise, for the following
1204 // case:
1205 // struct m { ...};
1206 // struct t {
1207 // struct m *key;
1208 // };
1209 // foo(struct t *arg);
1210 //
1211 // struct mapdef {
1212 // ...
1213 // struct m *key;
1214 // ...
1215 // } __attribute__((section(".maps"))) hash_map;
1216 //
1217 // If subroutine foo is traversed first, a type chain
1218 // "ptr->struct m(fwd)" will be created and later on
1219 // when traversing mapdef, since "ptr->struct m" exists,
1220 // the traversal of "struct m" will be omitted.
1221 if (MapDefNotCollected) {
1222 processGlobals(ProcessingMapDef: true);
1223 MapDefNotCollected = false;
1224 }
1225
1226 // Collect all types locally referenced in this function.
1227 // Use RetainedNodes so we can collect all argument names
1228 // even if the argument is not used.
1229 std::unordered_map<uint32_t, StringRef> FuncArgNames;
1230 for (const DINode *DN : SP->getRetainedNodes()) {
1231 if (const auto *DV = dyn_cast<DILocalVariable>(Val: DN)) {
1232 // Collect function arguments for subprogram func type.
1233 uint32_t Arg = DV->getArg();
1234 if (Arg) {
1235 visitTypeEntry(Ty: DV->getType());
1236 FuncArgNames[Arg] = DV->getName();
1237 }
1238 }
1239 }
1240
1241 // Construct subprogram func proto type.
1242 uint32_t ProtoTypeId;
1243 visitSubroutineType(STy: SP->getType(), ForSubprog: true, FuncArgNames, TypeId&: ProtoTypeId);
1244
1245 // Construct subprogram func type
1246 uint8_t Scope = SP->isLocalToUnit() ? BTF::FUNC_STATIC : BTF::FUNC_GLOBAL;
1247 uint32_t FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1248
1249 for (const auto &TypeEntry : TypeEntries)
1250 TypeEntry->completeType(BDebug&: *this);
1251
1252 // Construct funcinfo and the first lineinfo for the function.
1253 MCSymbol *FuncLabel = Asm->getFunctionBegin();
1254 BTFFuncInfo FuncInfo;
1255 FuncInfo.Label = FuncLabel;
1256 FuncInfo.TypeId = FuncTypeId;
1257 if (FuncLabel->isInSection()) {
1258 MCSection &Section = FuncLabel->getSection();
1259 const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(Val: &Section);
1260 assert(SectionELF && "Null section for Function Label");
1261 SecNameOff = addString(S: SectionELF->getName());
1262 } else {
1263 SecNameOff = addString(S: ".text");
1264 }
1265 FuncInfoTable[SecNameOff].push_back(x: FuncInfo);
1266}
1267
1268void BTFDebug::endFunctionImpl(const MachineFunction *MF) {
1269 SkipInstruction = false;
1270 LineInfoGenerated = false;
1271 SecNameOff = 0;
1272}
1273
1274/// On-demand populate types as requested from abstract member
1275/// accessing or preserve debuginfo type.
1276unsigned BTFDebug::populateType(const DIType *Ty) {
1277 unsigned Id;
1278 visitTypeEntry(Ty, TypeId&: Id, CheckPointer: false, SeenPointer: false);
1279 for (const auto &TypeEntry : TypeEntries)
1280 TypeEntry->completeType(BDebug&: *this);
1281 return Id;
1282}
1283
1284/// Generate a struct member field relocation.
1285void BTFDebug::generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
1286 const GlobalVariable *GVar, bool IsAma) {
1287 BTFFieldReloc FieldReloc;
1288 FieldReloc.Label = ORSym;
1289 FieldReloc.TypeID = RootId;
1290
1291 StringRef AccessPattern = GVar->getName();
1292 size_t FirstDollar = AccessPattern.find_first_of(C: '$');
1293 if (IsAma) {
1294 size_t FirstColon = AccessPattern.find_first_of(C: ':');
1295 size_t SecondColon = AccessPattern.find_first_of(C: ':', From: FirstColon + 1);
1296 StringRef IndexPattern = AccessPattern.substr(Start: FirstDollar + 1);
1297 StringRef RelocKindStr = AccessPattern.substr(Start: FirstColon + 1,
1298 N: SecondColon - FirstColon);
1299 StringRef PatchImmStr = AccessPattern.substr(Start: SecondColon + 1,
1300 N: FirstDollar - SecondColon);
1301
1302 FieldReloc.OffsetNameOff = addString(S: IndexPattern);
1303 FieldReloc.RelocKind = std::stoull(str: std::string(RelocKindStr));
1304 PatchImms[GVar] = std::make_pair(x: std::stoll(str: std::string(PatchImmStr)),
1305 y&: FieldReloc.RelocKind);
1306 } else {
1307 StringRef RelocStr = AccessPattern.substr(Start: FirstDollar + 1);
1308 FieldReloc.OffsetNameOff = addString(S: "0");
1309 FieldReloc.RelocKind = std::stoull(str: std::string(RelocStr));
1310 PatchImms[GVar] = std::make_pair(x&: RootId, y&: FieldReloc.RelocKind);
1311 }
1312 FieldRelocTable[SecNameOff].push_back(x: FieldReloc);
1313}
1314
1315void BTFDebug::processGlobalValue(const MachineOperand &MO) {
1316 // check whether this is a candidate or not
1317 if (MO.isGlobal()) {
1318 const GlobalValue *GVal = MO.getGlobal();
1319 auto *GVar = dyn_cast<GlobalVariable>(Val: GVal);
1320 if (!GVar) {
1321 // Not a global variable. Maybe an extern function reference.
1322 processFuncPrototypes(dyn_cast<Function>(Val: GVal));
1323 return;
1324 }
1325
1326 if (!GVar->hasAttribute(Kind: BPFCoreSharedInfo::AmaAttr) &&
1327 !GVar->hasAttribute(Kind: BPFCoreSharedInfo::TypeIdAttr))
1328 return;
1329
1330 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1331 OS.emitLabel(Symbol: ORSym);
1332
1333 MDNode *MDN = GVar->getMetadata(KindID: LLVMContext::MD_preserve_access_index);
1334 uint32_t RootId = populateType(Ty: dyn_cast<DIType>(Val: MDN));
1335 generatePatchImmReloc(ORSym, RootId, GVar,
1336 IsAma: GVar->hasAttribute(Kind: BPFCoreSharedInfo::AmaAttr));
1337 }
1338}
1339
1340void BTFDebug::beginInstruction(const MachineInstr *MI) {
1341 DebugHandlerBase::beginInstruction(MI);
1342
1343 if (SkipInstruction || MI->isMetaInstruction() ||
1344 MI->getFlag(Flag: MachineInstr::FrameSetup))
1345 return;
1346
1347 if (MI->isInlineAsm()) {
1348 // Count the number of register definitions to find the asm string.
1349 unsigned NumDefs = 0;
1350 while (true) {
1351 const MachineOperand &MO = MI->getOperand(i: NumDefs);
1352 if (MO.isReg() && MO.isDef()) {
1353 ++NumDefs;
1354 continue;
1355 }
1356 // Skip this inline asm instruction if the asmstr is empty.
1357 const char *AsmStr = MO.getSymbolName();
1358 if (AsmStr[0] == 0)
1359 return;
1360 break;
1361 }
1362 }
1363
1364 if (MI->getOpcode() == BPF::LD_imm64) {
1365 // If the insn is "r2 = LD_imm64 @<an AmaAttr global>",
1366 // add this insn into the .BTF.ext FieldReloc subsection.
1367 // Relocation looks like:
1368 // . SecName:
1369 // . InstOffset
1370 // . TypeID
1371 // . OffSetNameOff
1372 // . RelocType
1373 // Later, the insn is replaced with "r2 = <offset>"
1374 // where "<offset>" equals to the offset based on current
1375 // type definitions.
1376 //
1377 // If the insn is "r2 = LD_imm64 @<an TypeIdAttr global>",
1378 // The LD_imm64 result will be replaced with a btf type id.
1379 processGlobalValue(MO: MI->getOperand(i: 1));
1380 } else if (MI->getOpcode() == BPF::CORE_LD64 ||
1381 MI->getOpcode() == BPF::CORE_LD32 ||
1382 MI->getOpcode() == BPF::CORE_ST ||
1383 MI->getOpcode() == BPF::CORE_SHIFT) {
1384 // relocation insn is a load, store or shift insn.
1385 processGlobalValue(MO: MI->getOperand(i: 3));
1386 } else if (MI->getOpcode() == BPF::JAL) {
1387 // check extern function references
1388 const MachineOperand &MO = MI->getOperand(i: 0);
1389 if (MO.isGlobal()) {
1390 processFuncPrototypes(dyn_cast<Function>(Val: MO.getGlobal()));
1391 }
1392 }
1393
1394 if (!CurMI) // no debug info
1395 return;
1396
1397 // Skip this instruction if no DebugLoc, the DebugLoc
1398 // is the same as the previous instruction or Line is 0.
1399 const DebugLoc &DL = MI->getDebugLoc();
1400 if (!DL || PrevInstLoc == DL || DL.getLine() == 0) {
1401 // This instruction will be skipped, no LineInfo has
1402 // been generated, construct one based on function signature.
1403 if (LineInfoGenerated == false) {
1404 auto *S = MI->getMF()->getFunction().getSubprogram();
1405 if (!S)
1406 return;
1407 MCSymbol *FuncLabel = Asm->getFunctionBegin();
1408 constructLineInfo(Label: FuncLabel, File: S->getFile(), Line: S->getLine(), Column: 0);
1409 LineInfoGenerated = true;
1410 }
1411
1412 return;
1413 }
1414
1415 // Create a temporary label to remember the insn for lineinfo.
1416 MCSymbol *LineSym = OS.getContext().createTempSymbol();
1417 OS.emitLabel(Symbol: LineSym);
1418
1419 // Construct the lineinfo.
1420 constructLineInfo(Label: LineSym, File: DL->getFile(), Line: DL.getLine(), Column: DL.getCol());
1421
1422 LineInfoGenerated = true;
1423 PrevInstLoc = DL;
1424}
1425
1426void BTFDebug::processGlobals(bool ProcessingMapDef) {
1427 // Collect all types referenced by globals.
1428 const Module *M = MMI->getModule();
1429 for (const GlobalVariable &Global : M->globals()) {
1430 // Decide the section name.
1431 StringRef SecName;
1432 std::optional<SectionKind> GVKind;
1433
1434 if (!Global.isDeclarationForLinker())
1435 GVKind = TargetLoweringObjectFile::getKindForGlobal(GO: &Global, TM: Asm->TM);
1436
1437 if (Global.isDeclarationForLinker())
1438 SecName = Global.hasSection() ? Global.getSection() : "";
1439 else if (GVKind->isCommon())
1440 SecName = ".bss";
1441 else {
1442 TargetLoweringObjectFile *TLOF = Asm->TM.getObjFileLowering();
1443 MCSection *Sec = TLOF->SectionForGlobal(GO: &Global, TM: Asm->TM);
1444 SecName = Sec->getName();
1445 }
1446
1447 if (ProcessingMapDef != SecName.starts_with(Prefix: ".maps"))
1448 continue;
1449
1450 // Create a .rodata datasec if the global variable is an initialized
1451 // constant with private linkage and if it won't be in .rodata.str<#>
1452 // and .rodata.cst<#> sections.
1453 if (SecName == ".rodata" && Global.hasPrivateLinkage() &&
1454 DataSecEntries.find(x: SecName) == DataSecEntries.end()) {
1455 // skip .rodata.str<#> and .rodata.cst<#> sections
1456 if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1457 DataSecEntries[std::string(SecName)] =
1458 std::make_unique<BTFKindDataSec>(args&: Asm, args: std::string(SecName));
1459 }
1460 }
1461
1462 SmallVector<DIGlobalVariableExpression *, 1> GVs;
1463 Global.getDebugInfo(GVs);
1464
1465 // No type information, mostly internal, skip it.
1466 if (GVs.size() == 0)
1467 continue;
1468
1469 uint32_t GVTypeId = 0;
1470 DIGlobalVariable *DIGlobal = nullptr;
1471 for (auto *GVE : GVs) {
1472 DIGlobal = GVE->getVariable();
1473 if (SecName.starts_with(Prefix: ".maps"))
1474 visitMapDefType(Ty: DIGlobal->getType(), TypeId&: GVTypeId);
1475 else {
1476 const DIType *Ty = tryRemoveAtomicType(Ty: DIGlobal->getType());
1477 visitTypeEntry(Ty, TypeId&: GVTypeId, CheckPointer: false, SeenPointer: false);
1478 }
1479 break;
1480 }
1481
1482 // Only support the following globals:
1483 // . static variables
1484 // . non-static weak or non-weak global variables
1485 // . weak or non-weak extern global variables
1486 // Whether DataSec is readonly or not can be found from corresponding ELF
1487 // section flags. Whether a BTF_KIND_VAR is a weak symbol or not
1488 // can be found from the corresponding ELF symbol table.
1489 auto Linkage = Global.getLinkage();
1490 if (Linkage != GlobalValue::InternalLinkage &&
1491 Linkage != GlobalValue::ExternalLinkage &&
1492 Linkage != GlobalValue::WeakAnyLinkage &&
1493 Linkage != GlobalValue::WeakODRLinkage &&
1494 Linkage != GlobalValue::ExternalWeakLinkage)
1495 continue;
1496
1497 uint32_t GVarInfo;
1498 if (Linkage == GlobalValue::InternalLinkage) {
1499 GVarInfo = BTF::VAR_STATIC;
1500 } else if (Global.hasInitializer()) {
1501 GVarInfo = BTF::VAR_GLOBAL_ALLOCATED;
1502 } else {
1503 GVarInfo = BTF::VAR_GLOBAL_EXTERNAL;
1504 }
1505
1506 auto VarEntry =
1507 std::make_unique<BTFKindVar>(args: Global.getName(), args&: GVTypeId, args&: GVarInfo);
1508 uint32_t VarId = addType(TypeEntry: std::move(VarEntry));
1509
1510 processDeclAnnotations(Annotations: DIGlobal->getAnnotations(), BaseTypeId: VarId, ComponentIdx: -1);
1511
1512 // An empty SecName means an extern variable without section attribute.
1513 if (SecName.empty())
1514 continue;
1515
1516 // Find or create a DataSec
1517 auto [It, Inserted] = DataSecEntries.try_emplace(k: std::string(SecName));
1518 if (Inserted)
1519 It->second = std::make_unique<BTFKindDataSec>(args&: Asm, args: std::string(SecName));
1520
1521 // Calculate symbol size
1522 const DataLayout &DL = Global.getDataLayout();
1523 uint32_t Size = DL.getTypeAllocSize(Ty: Global.getValueType());
1524
1525 It->second->addDataSecEntry(Id: VarId, Sym: Asm->getSymbol(GV: &Global), Size);
1526
1527 if (Global.hasInitializer())
1528 processGlobalInitializer(C: Global.getInitializer());
1529 }
1530}
1531
1532/// Process global variable initializer in pursuit for function
1533/// pointers. Add discovered (extern) functions to BTF. Some (extern)
1534/// functions might have been missed otherwise. Every symbol needs BTF
1535/// info when linking with bpftool. Primary use case: "static"
1536/// initialization of BPF maps.
1537///
1538/// struct {
1539/// __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
1540/// ...
1541/// } prog_map SEC(".maps") = { .values = { extern_func } };
1542///
1543void BTFDebug::processGlobalInitializer(const Constant *C) {
1544 if (auto *Fn = dyn_cast<Function>(Val: C))
1545 processFuncPrototypes(Fn);
1546 if (auto *CA = dyn_cast<ConstantAggregate>(Val: C)) {
1547 for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I)
1548 processGlobalInitializer(C: CA->getOperand(i_nocapture: I));
1549 }
1550}
1551
1552/// Emit proper patchable instructions.
1553bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
1554 if (MI->getOpcode() == BPF::LD_imm64) {
1555 const MachineOperand &MO = MI->getOperand(i: 1);
1556 if (MO.isGlobal()) {
1557 const GlobalValue *GVal = MO.getGlobal();
1558 auto *GVar = dyn_cast<GlobalVariable>(Val: GVal);
1559 if (GVar) {
1560 if (!GVar->hasAttribute(Kind: BPFCoreSharedInfo::AmaAttr) &&
1561 !GVar->hasAttribute(Kind: BPFCoreSharedInfo::TypeIdAttr))
1562 return false;
1563
1564 // Emit "mov ri, <imm>"
1565 auto [Imm, Reloc] = PatchImms[GVar];
1566 if (Reloc == BTF::ENUM_VALUE_EXISTENCE || Reloc == BTF::ENUM_VALUE ||
1567 Reloc == BTF::BTF_TYPE_ID_LOCAL || Reloc == BTF::BTF_TYPE_ID_REMOTE)
1568 OutMI.setOpcode(BPF::LD_imm64);
1569 else
1570 OutMI.setOpcode(BPF::MOV_ri);
1571 OutMI.addOperand(Op: MCOperand::createReg(Reg: MI->getOperand(i: 0).getReg()));
1572 OutMI.addOperand(Op: MCOperand::createImm(Val: Imm));
1573 return true;
1574 }
1575 }
1576 } else if (MI->getOpcode() == BPF::CORE_LD64 ||
1577 MI->getOpcode() == BPF::CORE_LD32 ||
1578 MI->getOpcode() == BPF::CORE_ST ||
1579 MI->getOpcode() == BPF::CORE_SHIFT) {
1580 const MachineOperand &MO = MI->getOperand(i: 3);
1581 if (MO.isGlobal()) {
1582 const GlobalValue *GVal = MO.getGlobal();
1583 auto *GVar = dyn_cast<GlobalVariable>(Val: GVal);
1584 if (GVar && GVar->hasAttribute(Kind: BPFCoreSharedInfo::AmaAttr)) {
1585 uint32_t Imm = PatchImms[GVar].first;
1586 OutMI.setOpcode(MI->getOperand(i: 1).getImm());
1587 if (MI->getOperand(i: 0).isImm())
1588 OutMI.addOperand(Op: MCOperand::createImm(Val: MI->getOperand(i: 0).getImm()));
1589 else
1590 OutMI.addOperand(Op: MCOperand::createReg(Reg: MI->getOperand(i: 0).getReg()));
1591 OutMI.addOperand(Op: MCOperand::createReg(Reg: MI->getOperand(i: 2).getReg()));
1592 OutMI.addOperand(Op: MCOperand::createImm(Val: Imm));
1593 return true;
1594 }
1595 }
1596 }
1597 return false;
1598}
1599
1600void BTFDebug::processFuncPrototypes(const Function *F) {
1601 if (!F)
1602 return;
1603
1604 const DISubprogram *SP = F->getSubprogram();
1605 if (!SP || SP->isDefinition())
1606 return;
1607
1608 // Do not emit again if already emitted.
1609 if (!ProtoFunctions.insert(x: F).second)
1610 return;
1611
1612 uint32_t ProtoTypeId;
1613 const std::unordered_map<uint32_t, StringRef> FuncArgNames;
1614 visitSubroutineType(STy: SP->getType(), ForSubprog: false, FuncArgNames, TypeId&: ProtoTypeId);
1615 uint32_t FuncId = processDISubprogram(SP, ProtoTypeId, Scope: BTF::FUNC_EXTERN);
1616
1617 if (F->hasSection()) {
1618 StringRef SecName = F->getSection();
1619
1620 auto [It, Inserted] = DataSecEntries.try_emplace(k: std::string(SecName));
1621 if (Inserted)
1622 It->second = std::make_unique<BTFKindDataSec>(args&: Asm, args: std::string(SecName));
1623
1624 // We really don't know func size, set it to 0.
1625 It->second->addDataSecEntry(Id: FuncId, Sym: Asm->getSymbol(GV: F), Size: 0);
1626 }
1627}
1628
1629void BTFDebug::endModule() {
1630 // Collect MapDef globals if not collected yet.
1631 if (MapDefNotCollected) {
1632 processGlobals(ProcessingMapDef: true);
1633 MapDefNotCollected = false;
1634 }
1635
1636 // Collect global types/variables except MapDef globals.
1637 processGlobals(ProcessingMapDef: false);
1638
1639 // In case that BPF_TRAP usage is removed during machine-level optimization,
1640 // generate btf for BPF_TRAP function here.
1641 for (const Function &F : *MMI->getModule()) {
1642 if (F.getName() == BPF_TRAP)
1643 processFuncPrototypes(F: &F);
1644 }
1645
1646 for (auto &DataSec : DataSecEntries)
1647 addType(TypeEntry: std::move(DataSec.second));
1648
1649 // Fixups
1650 for (auto &Fixup : FixupDerivedTypes) {
1651 const DICompositeType *CTy = Fixup.first;
1652 StringRef TypeName = CTy->getName();
1653 bool IsUnion = CTy->getTag() == dwarf::DW_TAG_union_type;
1654
1655 // Search through struct types
1656 uint32_t StructTypeId = 0;
1657 for (const auto &StructType : StructTypes) {
1658 if (StructType->getName() == TypeName) {
1659 StructTypeId = StructType->getId();
1660 break;
1661 }
1662 }
1663
1664 if (StructTypeId == 0) {
1665 auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(args&: TypeName, args&: IsUnion);
1666 StructTypeId = addType(TypeEntry: std::move(FwdTypeEntry));
1667 }
1668
1669 for (auto &TypeInfo : Fixup.second) {
1670 const DIDerivedType *DTy = TypeInfo.first;
1671 BTFTypeDerived *BDType = TypeInfo.second;
1672
1673 int TmpTypeId = genBTFTypeTags(DTy, BaseTypeId: StructTypeId);
1674 if (TmpTypeId >= 0)
1675 BDType->setPointeeType(TmpTypeId);
1676 else
1677 BDType->setPointeeType(StructTypeId);
1678 }
1679 }
1680
1681 // Complete BTF type cross refereences.
1682 for (const auto &TypeEntry : TypeEntries)
1683 TypeEntry->completeType(BDebug&: *this);
1684
1685 // Emit BTF sections.
1686 emitBTFSection();
1687 emitBTFExtSection();
1688}
1689