LLVM 22.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 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(SizeInBits);
180 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
181}
182
184 if (IsCompleted)
185 return;
186 IsCompleted = true;
187
188 BTFType.NameOff = BDebug.addString(Name);
189}
190
193 OS.AddComment("0x" + Twine::utohexstr(IntVal));
194 OS.emitInt32(IntVal);
195}
196
198 bool IsSigned) : ETy(ETy) {
199 Kind = BTF::BTF_KIND_ENUM;
200 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
201 BTFType.Size = roundupToBytes(ETy->getSizeInBits());
202}
203
205 if (IsCompleted)
206 return;
207 IsCompleted = true;
208
209 BTFType.NameOff = BDebug.addString(ETy->getName());
210
211 DINodeArray Elements = ETy->getElements();
212 for (const auto Element : Elements) {
213 const auto *Enum = cast<DIEnumerator>(Element);
214
215 struct BTF::BTFEnum BTFEnum;
216 BTFEnum.NameOff = BDebug.addString(Enum->getName());
217 // BTF enum value is 32bit, enforce it.
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(BTFEnum);
225 }
226}
227
230 for (const auto &Enum : EnumValues) {
231 OS.emitInt32(Enum.NameOff);
232 OS.emitInt32(Enum.Val);
233 }
234}
235
237 bool IsSigned) : ETy(ETy) {
238 Kind = BTF::BTF_KIND_ENUM64;
239 BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
240 BTFType.Size = roundupToBytes(ETy->getSizeInBits());
241}
242
244 if (IsCompleted)
245 return;
246 IsCompleted = true;
247
248 BTFType.NameOff = BDebug.addString(ETy->getName());
249
250 DINodeArray Elements = ETy->getElements();
251 for (const auto Element : Elements) {
252 const auto *Enum = cast<DIEnumerator>(Element);
253
254 struct BTF::BTFEnum64 BTFEnum;
255 BTFEnum.NameOff = BDebug.addString(Enum->getName());
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(BTFEnum);
264 }
265}
266
269 for (const auto &Enum : EnumValues) {
270 OS.emitInt32(Enum.NameOff);
271 OS.AddComment("0x" + Twine::utohexstr(Enum.Val_Lo32));
272 OS.emitInt32(Enum.Val_Lo32);
273 OS.AddComment("0x" + Twine::utohexstr(Enum.Val_Hi32));
274 OS.emitInt32(Enum.Val_Hi32);
275 }
276}
277
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.
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
303 OS.emitInt32(ArrayInfo.ElemType);
304 OS.emitInt32(ArrayInfo.IndexType);
305 OS.emitInt32(ArrayInfo.Nelems);
306}
307
308/// Represent either a struct or a union.
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(STy->getSizeInBits());
314 BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
315}
316
318 if (IsCompleted)
319 return;
320 IsCompleted = true;
321
322 BTFType.NameOff = BDebug.addString(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(DTy->getName());
338 Discriminator.Offset = DTy->getOffsetInBits();
339 const auto *BaseTy = DTy->getBaseType();
340 Discriminator.Type = BDebug.getTypeId(BaseTy);
341
342 Members.push_back(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>(Element);
354
355 BTFMember.NameOff = BDebug.addString(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(DDTy->getBaseType());
363 BTFMember.Type = BDebug.getTypeId(BaseTy);
364 break;
365 }
366 case dwarf::DW_TAG_variant_part: {
367 const auto *DCTy = dyn_cast<DICompositeType>(Element);
368
369 BTFMember.NameOff = BDebug.addString(DCTy->getName());
370 BTFMember.Offset = DCTy->getOffsetInBits();
371 BTFMember.Type = BDebug.getTypeId(DCTy);
372 break;
373 }
374 default:
375 llvm_unreachable("Unexpected DI tag of a struct/union element");
376 }
377 Members.push_back(BTFMember);
378 }
379}
380
383 for (const auto &Member : Members) {
384 OS.emitInt32(Member.NameOff);
385 OS.emitInt32(Member.Type);
386 OS.AddComment("0x" + Twine::utohexstr(Member.Offset));
387 OS.emitInt32(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.
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
407 if (IsCompleted)
408 return;
409 IsCompleted = true;
410
411 DITypeRefArray Elements = STy->getTypeArray();
412 auto RetType = tryRemoveAtomicType(Elements[0]);
413 BTFType.Type = RetType ? BDebug.getTypeId(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(Elements[I]);
421 if (Element) {
422 Param.NameOff = BDebug.addString(FuncArgNames[I]);
423 Param.Type = BDebug.getTypeId(Element);
424 } else {
425 Param.NameOff = 0;
426 Param.Type = 0;
427 }
428 Parameters.push_back(Param);
429 }
430}
431
434 for (const auto &Param : Parameters) {
435 OS.emitInt32(Param.NameOff);
436 OS.emitInt32(Param.Type);
437 }
438}
439
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
449 if (IsCompleted)
450 return;
451 IsCompleted = true;
452
453 BTFType.NameOff = BDebug.addString(Name);
454}
455
457
459 : Name(VarName) {
460 Kind = BTF::BTF_KIND_VAR;
461 BTFType.Info = Kind << 24;
462 BTFType.Type = TypeId;
463 Info = VarInfo;
464}
465
467 BTFType.NameOff = BDebug.addString(Name);
468}
469
472 OS.emitInt32(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
483 BTFType.NameOff = BDebug.addString(Name);
484 BTFType.Info |= Vars.size();
485}
486
489
490 for (const auto &V : Vars) {
491 OS.emitInt32(std::get<0>(V));
492 Asm->emitLabelReference(std::get<1>(V), 4);
493 OS.emitInt32(std::get<2>(V));
494 }
495}
496
498 : Name(TypeName) {
499 Kind = BTF::BTF_KIND_FLOAT;
500 BTFType.Info = Kind << 24;
501 BTFType.Size = roundupToBytes(SizeInBits);
502}
503
505 if (IsCompleted)
506 return;
507 IsCompleted = true;
508
509 BTFType.NameOff = BDebug.addString(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
522 if (IsCompleted)
523 return;
524 IsCompleted = true;
525
526 BTFType.NameOff = BDebug.addString(Tag);
527}
528
533
535 : DTy(nullptr), Tag(Tag) {
536 Kind = BTF::BTF_KIND_TYPE_TAG;
537 BTFType.Info = Kind << 24;
538 BTFType.Type = NextTypeId;
539}
540
542 : DTy(DTy), Tag(Tag) {
543 Kind = BTF::BTF_KIND_TYPE_TAG;
544 BTFType.Info = Kind << 24;
545}
546
548 if (IsCompleted)
549 return;
550 IsCompleted = true;
551 BTFType.NameOff = BDebug.addString(Tag);
552 if (DTy) {
553 const DIType *ResolvedType = tryRemoveAtomicType(DTy->getBaseType());
554 if (!ResolvedType)
555 BTFType.Type = 0;
556 else
557 BTFType.Type = BDebug.getTypeId(ResolvedType);
558 }
559}
560
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(std::string(S));
571 Size += S.size() + 1;
572 return Offset;
573}
574
576 : DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false),
577 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
578 MapDefNotCollected(true) {
579 addString("\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(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(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 Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
612 break;
613 case dwarf::DW_ATE_float:
614 TypeEntry =
615 std::make_unique<BTFTypeFloat>(BTy->getSizeInBits(), BTy->getName());
616 break;
617 default:
618 return;
619 }
620
621 TypeId = addType(std::move(TypeEntry), 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 DITypeRefArray 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>(STy, VLen, FuncArgNames);
639 if (ForSubprog)
640 TypeId = addType(std::move(TypeEntry)); // For subprogram
641 else
642 TypeId = addType(std::move(TypeEntry), STy); // For func ptr
643
644 // Visit return type and func arg types.
645 for (const auto Element : Elements) {
646 visitTypeEntry(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>(Annotation);
658 const MDString *Name = cast<MDString>(MD->getOperand(0));
659 if (Name->getString() != "btf_decl_tag")
660 continue;
661
662 const MDString *Value = cast<MDString>(MD->getOperand(1));
663 auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
664 Value->getString());
665 addType(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>(SP->getName(), ProtoTypeId, Scope);
673 uint32_t FuncId = addType(std::move(FuncTypeEntry));
674
675 // Process argument annotations.
676 for (const DINode *DN : SP->getRetainedNodes()) {
677 if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
678 uint32_t Arg = DV->getArg();
679 if (Arg)
680 processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
681 }
682 }
683 processDeclAnnotations(SP->getAnnotations(), FuncId, -1);
684
685 return FuncId;
686}
687
688/// Generate btf_type_tag chains.
689int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) {
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>(Annotations);
697 const MDString *Name = cast<MDString>(MD->getOperand(0));
698 if (Name->getString() != "btf_type_tag")
699 continue;
700 MDStrs.push_back(cast<MDString>(MD->getOperand(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>(BaseTypeId, MDStrs[0]->getString());
716 else
717 TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
718 TmpTypeId = addType(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>(TmpTypeId, Value->getString());
723 TmpTypeId = addType(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(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>(Element);
751 if (E->isBitField()) {
752 HasBitField = true;
753 break;
754 }
755 }
756 }
757
758 auto TypeEntry =
759 std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
760 StructTypes.push_back(TypeEntry.get());
761 TypeId = addType(std::move(TypeEntry), CTy);
762
763 // Check struct/union annotations
764 processDeclAnnotations(CTy->getAnnotations(), TypeId, -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>(Element);
772 visitTypeEntry(Elem);
773 processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
774 break;
775 }
776 case dwarf::DW_TAG_variant_part: {
777 const auto Elem = cast<DICompositeType>(Element);
778 visitTypeEntry(Elem);
779 processDeclAnnotations(Elem->getAnnotations(), TypeId, 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(ElemType, ElemTypeId, false, 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>(Elements[I]))
799 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
800 const DISubrange *SR = cast<DISubrange>(Element);
801 auto *CI = dyn_cast<ConstantInt *>(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>(ElemTypeId,
808 Count >= 0 ? Count : 0);
809 if (I == 0)
810 ElemTypeId = addType(std::move(TypeEntry), CTy);
811 else
812 ElemTypeId = addType(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>(dwarf::DW_ATE_unsigned, 32,
823 0, "__ARRAY_SIZE_TYPE__");
824 ArrayIndexTypeId = addType(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>(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>(CTy, VLen, IsSigned);
847 TypeId = addType(std::move(TypeEntry), CTy);
848 } else {
849 assert(NumBits == 64);
850 auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
851 TypeId = addType(std::move(TypeEntry), 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>(CTy->getName(), IsUnion);
860 TypeId = addType(std::move(TypeEntry), 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, Tag == dwarf::DW_TAG_union_type, TypeId);
874 else
875 visitStructType(CTy, 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>(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(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>(DTy, Tag, true);
922 auto &Fixup = FixupDerivedTypes[cast<DICompositeType>(Base)];
923 Fixup.push_back(std::make_pair(DTy, TypeEntry.get()));
924 TypeId = addType(std::move(TypeEntry), DTy);
925 return;
926 }
927 }
928 }
929
930 if (Tag == dwarf::DW_TAG_pointer_type) {
931 int TmpTypeId = genBTFTypeTags(DTy, -1);
932 if (TmpTypeId >= 0) {
933 auto TypeDEntry =
934 std::make_unique<BTFTypeDerived>(TmpTypeId, Tag, DTy->getName());
935 TypeId = addType(std::move(TypeDEntry), DTy);
936 } else {
937 auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
938 TypeId = addType(std::move(TypeEntry), 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>(DTy, Tag, false);
944 TypeId = addType(std::move(TypeEntry), DTy);
945 if (Tag == dwarf::DW_TAG_typedef)
946 processDeclAnnotations(DTy->getAnnotations(), TypeId, -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(DTy->getBaseType(), TempTypeId, true, false);
956 else
957 visitTypeEntry(DTy->getBaseType(), 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(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>(Ty)) {
1003 while (DTy) {
1004 const DIType *BaseTy = DTy->getBaseType();
1005 if (!BaseTy)
1006 break;
1007
1008 if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
1009 DTy = dyn_cast<DIDerivedType>(BaseTy);
1010 } else {
1011 if (CheckPointer && DTy->getTag() == dwarf::DW_TAG_pointer_type &&
1012 !DTy->getAnnotations()) {
1013 SeenPointer = true;
1014 if (IsForwardDeclCandidate(BaseTy))
1015 break;
1016 }
1017 uint32_t TmpTypeId;
1018 visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
1019 break;
1020 }
1021 }
1022 }
1023 }
1024
1025 return;
1026 }
1027
1028 if (const auto *BTy = dyn_cast<DIBasicType>(Ty))
1029 visitBasicType(BTy, TypeId);
1030 else if (const auto *STy = dyn_cast<DISubroutineType>(Ty))
1031 visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),
1032 TypeId);
1033 else if (const auto *CTy = dyn_cast<DICompositeType>(Ty))
1034 visitCompositeType(CTy, TypeId);
1035 else if (const auto *DTy = dyn_cast<DIDerivedType>(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, false, false);
1044}
1045
1046void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
1047 if (!Ty || DIToIdMap.find(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(dyn_cast<DIDerivedType>(Ty)->getBaseType(), TmpId);
1060 break;
1061 case dwarf::DW_TAG_array_type:
1062 // Visit nested map array and jump to the element type
1063 visitMapDefType(dyn_cast<DICompositeType>(Ty)->getBaseType(), 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>(Ty);
1068 const DINodeArray Elements = CTy->getElements();
1069 for (const auto *Element : Elements) {
1070 const auto *MemberType = cast<DIDerivedType>(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>(MemberBaseType);
1079 if (MemberCTy) {
1080 visitMapDefType(MemberBaseType, TmpId);
1081 } else {
1082 visitTypeEntry(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, false, 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("/") && 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(FileName))
1106 return FileName;
1107
1108 std::vector<std::string> Content;
1109 std::string Line;
1110 Content.push_back(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);
1116 };
1117
1118 std::unique_ptr<MemoryBuffer> Buf;
1119 auto Source = File->getSource();
1120 if (Source)
1121 Buf = MemoryBuffer::getMemBufferCopy(*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(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(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(Content[Line]);
1143 else
1144 LineInfo.LineOff = 0;
1145 LineInfo.LineNum = Line;
1146 LineInfo.ColumnNum = Column;
1147 LineInfoTable[SecNameOff].push_back(LineInfo);
1148}
1149
1150void BTFDebug::emitCommonHeader() {
1151 OS.AddComment("0x" + Twine::utohexstr(BTF::MAGIC));
1152 OS.emitIntValue(BTF::MAGIC, 2);
1153 OS.emitInt8(BTF::VERSION);
1154 OS.emitInt8(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(".BTF", ELF::SHT_PROGBITS, 0);
1164 Sec->setAlignment(Align(4));
1165 OS.switchSection(Sec);
1166
1167 // Emit header.
1168 emitCommonHeader();
1169 OS.emitInt32(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(0);
1177 OS.emitInt32(TypeLen);
1178 OS.emitInt32(TypeLen);
1179 OS.emitInt32(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("string offset=" + std::to_string(StringOffset));
1189 OS.emitBytes(S);
1190 OS.emitBytes(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(".BTF.ext", ELF::SHT_PROGBITS, 0);
1204 Sec->setAlignment(Align(4));
1205 OS.switchSection(Sec);
1206
1207 // Emit header.
1208 emitCommonHeader();
1209 OS.emitInt32(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(0);
1232 OS.emitInt32(FuncLen);
1233 OS.emitInt32(FuncLen);
1234 OS.emitInt32(LineLen);
1235 OS.emitInt32(FuncLen + LineLen);
1236 OS.emitInt32(FieldRelocLen);
1237
1238 // Emit func_info table.
1239 OS.AddComment("FuncInfo");
1240 OS.emitInt32(BTF::BPFFuncInfoSize);
1241 for (const auto &FuncSec : FuncInfoTable) {
1242 OS.AddComment("FuncInfo section string offset=" +
1243 std::to_string(FuncSec.first));
1244 OS.emitInt32(FuncSec.first);
1245 OS.emitInt32(FuncSec.second.size());
1246 for (const auto &FuncInfo : FuncSec.second) {
1247 Asm->emitLabelReference(FuncInfo.Label, 4);
1248 OS.emitInt32(FuncInfo.TypeId);
1249 }
1250 }
1251
1252 // Emit line_info table.
1253 OS.AddComment("LineInfo");
1254 OS.emitInt32(BTF::BPFLineInfoSize);
1255 for (const auto &LineSec : LineInfoTable) {
1256 OS.AddComment("LineInfo section string offset=" +
1257 std::to_string(LineSec.first));
1258 OS.emitInt32(LineSec.first);
1259 OS.emitInt32(LineSec.second.size());
1260 for (const auto &LineInfo : LineSec.second) {
1261 Asm->emitLabelReference(LineInfo.Label, 4);
1262 OS.emitInt32(LineInfo.FileNameOff);
1263 OS.emitInt32(LineInfo.LineOff);
1264 OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +
1265 std::to_string(LineInfo.ColumnNum));
1266 OS.emitInt32(LineInfo.LineNum << 10 | LineInfo.ColumnNum);
1267 }
1268 }
1269
1270 // Emit field reloc table.
1271 if (FieldRelocLen) {
1272 OS.AddComment("FieldReloc");
1273 OS.emitInt32(BTF::BPFFieldRelocSize);
1274 for (const auto &FieldRelocSec : FieldRelocTable) {
1275 OS.AddComment("Field reloc section string offset=" +
1276 std::to_string(FieldRelocSec.first));
1277 OS.emitInt32(FieldRelocSec.first);
1278 OS.emitInt32(FieldRelocSec.second.size());
1279 for (const auto &FieldRelocInfo : FieldRelocSec.second) {
1280 Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1281 OS.emitInt32(FieldRelocInfo.TypeID);
1282 OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1283 OS.emitInt32(FieldRelocInfo.RelocKind);
1284 }
1285 }
1286 }
1287}
1288
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(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>(DN)) {
1329 // Collect function arguments for subprogram func type.
1330 uint32_t Arg = DV->getArg();
1331 if (Arg) {
1332 visitTypeEntry(DV->getType());
1333 FuncArgNames[Arg] = DV->getName();
1334 }
1335 }
1336 }
1337
1338 // Construct subprogram func proto type.
1339 uint32_t ProtoTypeId;
1340 visitSubroutineType(SP->getType(), true, FuncArgNames, 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(*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(Sec.getName());
1357 } else {
1358 SecNameOff = addString(".text");
1359 }
1360 FuncInfoTable[SecNameOff].push_back(FuncInfo);
1361}
1362
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, Id, false, false);
1374 for (const auto &TypeEntry : TypeEntries)
1375 TypeEntry->completeType(*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('$');
1388 if (IsAma) {
1389 size_t FirstColon = AccessPattern.find_first_of(':');
1390 size_t SecondColon = AccessPattern.find_first_of(':', FirstColon + 1);
1391 StringRef IndexPattern = AccessPattern.substr(FirstDollar + 1);
1392 StringRef RelocKindStr = AccessPattern.substr(FirstColon + 1,
1393 SecondColon - FirstColon);
1394 StringRef PatchImmStr = AccessPattern.substr(SecondColon + 1,
1395 FirstDollar - SecondColon);
1396
1397 FieldReloc.OffsetNameOff = addString(IndexPattern);
1398 FieldReloc.RelocKind = std::stoull(std::string(RelocKindStr));
1399 PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1400 FieldReloc.RelocKind);
1401 } else {
1402 StringRef RelocStr = AccessPattern.substr(FirstDollar + 1);
1403 FieldReloc.OffsetNameOff = addString("0");
1404 FieldReloc.RelocKind = std::stoull(std::string(RelocStr));
1405 PatchImms[GVar] = std::make_pair(RootId, FieldReloc.RelocKind);
1406 }
1407 FieldRelocTable[SecNameOff].push_back(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>(GVal);
1415 if (!GVar) {
1416 // Not a global variable. Maybe an extern function reference.
1417 processFuncPrototypes(dyn_cast<Function>(GVal));
1418 return;
1419 }
1420
1423 return;
1424
1425 MCSymbol *ORSym = OS.getContext().createTempSymbol();
1426 OS.emitLabel(ORSym);
1427
1428 MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1429 uint32_t RootId = populateType(dyn_cast<DIType>(MDN));
1430 generatePatchImmReloc(ORSym, RootId, GVar,
1432 }
1433}
1434
1437
1438 if (SkipInstruction || MI->isMetaInstruction() ||
1439 MI->getFlag(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(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(MI->getOperand(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(MI->getOperand(3));
1481 } else if (MI->getOpcode() == BPF::JAL) {
1482 // check extern function references
1483 const MachineOperand &MO = MI->getOperand(0);
1484 if (MO.isGlobal()) {
1485 processFuncPrototypes(dyn_cast<Function>(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(FuncLabel, S->getFile(), S->getLine(), 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(LineSym);
1513
1514 // Construct the lineinfo.
1515 constructLineInfo(LineSym, DL->getFile(), DL.getLine(), 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())
1531
1532 if (Global.isDeclarationForLinker())
1533 SecName = Global.hasSection() ? Global.getSection() : "";
1534 else if (GVKind->isCommon())
1535 SecName = ".bss";
1536 else {
1538 MCSection *Sec = TLOF->SectionForGlobal(&Global, Asm->TM);
1539 SecName = Sec->getName();
1540 }
1541
1542 if (ProcessingMapDef != SecName.starts_with(".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(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>(Asm, std::string(SecName));
1554 }
1555 }
1556
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(".maps"))
1569 visitMapDefType(DIGlobal->getType(), GVTypeId);
1570 else {
1571 const DIType *Ty = tryRemoveAtomicType(DIGlobal->getType());
1572 visitTypeEntry(Ty, GVTypeId, false, 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();
1590 continue;
1591
1592 uint32_t GVarInfo;
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>(Global.getName(), GVTypeId, GVarInfo);
1603 uint32_t VarId = addType(std::move(VarEntry));
1604
1605 processDeclAnnotations(DIGlobal->getAnnotations(), VarId, -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(std::string(SecName));
1613 if (Inserted)
1614 It->second = std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
1615
1616 // Calculate symbol size
1617 const DataLayout &DL = Global.getDataLayout();
1618 uint32_t Size = DL.getTypeAllocSize(Global.getValueType());
1619
1620 It->second->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size);
1621
1622 if (Global.hasInitializer())
1623 processGlobalInitializer(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>(C))
1640 processFuncPrototypes(Fn);
1641 if (auto *CA = dyn_cast<ConstantAggregate>(C)) {
1642 for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I)
1643 processGlobalInitializer(CA->getOperand(I));
1644 }
1645}
1646
1647/// Emit proper patchable instructions.
1649 if (MI->getOpcode() == BPF::LD_imm64) {
1650 const MachineOperand &MO = MI->getOperand(1);
1651 if (MO.isGlobal()) {
1652 const GlobalValue *GVal = MO.getGlobal();
1653 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1654 if (GVar) {
1657 return false;
1658
1659 // Emit "mov ri, <imm>"
1660 auto [Imm, Reloc] = PatchImms[GVar];
1663 OutMI.setOpcode(BPF::LD_imm64);
1664 else
1665 OutMI.setOpcode(BPF::MOV_ri);
1666 OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1667 OutMI.addOperand(MCOperand::createImm(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(3);
1676 if (MO.isGlobal()) {
1677 const GlobalValue *GVal = MO.getGlobal();
1678 auto *GVar = dyn_cast<GlobalVariable>(GVal);
1679 if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
1680 uint32_t Imm = PatchImms[GVar].first;
1681 OutMI.setOpcode(MI->getOperand(1).getImm());
1682 if (MI->getOperand(0).isImm())
1683 OutMI.addOperand(MCOperand::createImm(MI->getOperand(0).getImm()));
1684 else
1685 OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1686 OutMI.addOperand(MCOperand::createReg(MI->getOperand(2).getReg()));
1687 OutMI.addOperand(MCOperand::createImm(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(F).second)
1705 return;
1706
1707 uint32_t ProtoTypeId;
1708 const std::unordered_map<uint32_t, StringRef> FuncArgNames;
1709 visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);
1710 uint32_t FuncId = processDISubprogram(SP, ProtoTypeId, BTF::FUNC_EXTERN);
1711
1712 if (F->hasSection()) {
1713 StringRef SecName = F->getSection();
1714
1715 auto [It, Inserted] = DataSecEntries.try_emplace(std::string(SecName));
1716 if (Inserted)
1717 It->second = std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
1718
1719 // We really don't know func size, set it to 0.
1720 It->second->addDataSecEntry(FuncId, Asm->getSymbol(F), 0);
1721 }
1722}
1723
1725 // Collect MapDef globals if not collected yet.
1726 if (MapDefNotCollected) {
1727 processGlobals(true);
1728 MapDefNotCollected = false;
1729 }
1730
1731 // Collect global types/variables except MapDef globals.
1732 processGlobals(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);
1739 }
1740
1741 for (auto &DataSec : DataSecEntries)
1742 addType(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>(TypeName, IsUnion);
1761 StructTypeId = addType(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, 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(*this);
1779
1780 // Emit BTF sections.
1781 emitBTFSection();
1782 emitBTFExtSection();
1783}
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:575
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:487
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:482
BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
Definition BTFDebug.cpp:475
BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
Definition BTFDebug.cpp:458
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:470
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:466
uint32_t addString(StringRef S)
Add a string to the string table and returns its offset in the table.
Definition BTFDebug.cpp:561
BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems)
Definition BTFDebug.cpp:278
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:301
void completeType(BTFDebug &BDebug) override
Represent a BTF array.
Definition BTFDebug.cpp:289
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:521
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:529
BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag)
Definition BTFDebug.cpp:512
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:243
BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)
Definition BTFDebug.cpp:236
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:267
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:204
BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned)
Definition BTFDebug.cpp:197
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:228
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:504
BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
Definition BTFDebug.cpp:497
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:398
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:406
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:432
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:456
BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope)
Definition BTFDebug.cpp:440
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:448
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:191
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:183
void emitType(MCStreamer &OS) override
Emit types for this BTF type entry.
Definition BTFDebug.cpp:381
BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, uint32_t NumMembers)
Represent either a struct or a union.
Definition BTFDebug.cpp:309
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:317
std::string getName()
Definition BTFDebug.cpp:391
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:547
BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)
Definition BTFDebug.cpp:534
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.
DITypeRefArray 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 current metadata attachments for the given kind, if any.
Definition Value.h:576
@ 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:553
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:517
void setAlignment(Align Value)
Definition MCSection.h:601
StringRef getName() const
Definition MCSection.h:586
Streaming machine code generation interface.
Definition MCStreamer.h:220
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:387
void emitInt32(uint64_t Value)
Definition MCStreamer.h:750
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:1442
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:573
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:261
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:143
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:146
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:376
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:696
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:322
#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:1147
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