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