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