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