LLVM: lib/DebugInfo/BTF/BTFParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
18
19#define DEBUG_TYPE "debug-info-btf-parser"
20
21using namespace llvm;
25
28
29
30
31
32
33
34
35
36
37
38
39namespace {
40class Err {
41 std::string Buffer;
43
44public:
45 Err(const char *InitialMsg) : Buffer(InitialMsg), Stream(Buffer) {}
47 : Buffer(), Stream(Buffer) {
48 *this << "error while reading " << SectionName
49 << " section: " << C.takeError();
50 };
51
52 template Err &operator<<(T Val) {
53 Stream << Val;
54 return *this;
55 }
56
57 Err &write_hex(unsigned long long Val) {
59 return *this;
60 }
61
65 return *this;
66 }
67
68 operator Error() const {
70 }
71};
72}
73
74
75
76
80
82
83public:
86
89 if (!Contents)
92 Obj.getBytesInAddress());
93 }
94
96 auto It = Sections.find(Name);
98 return It->second;
99 return std::nullopt;
100 }
101};
102
105 if (!MaybeExtractor)
106 return MaybeExtractor.takeError();
107
110 uint16_t Magic = Extractor.getU16(C);
111 if ()
112 return Err(".BTF", C);
114 return Err("invalid .BTF magic: ").write_hex(Magic);
116 if ()
117 return Err(".BTF", C);
119 return Err("unsupported .BTF version: ") << (unsigned)Version;
120 (void)Extractor.getU8(C);
121 uint32_t HdrLen = Extractor.getU32(C);
122 if ()
123 return Err(".BTF", C);
124 if (HdrLen < 8)
125 return Err("unexpected .BTF header length: ") << HdrLen;
126 uint32_t TypeOff = Extractor.getU32(C);
127 uint32_t TypeLen = Extractor.getU32(C);
128 uint32_t StrOff = Extractor.getU32(C);
129 uint32_t StrLen = Extractor.getU32(C);
130 uint32_t StrStart = HdrLen + StrOff;
131 uint32_t StrEnd = StrStart + StrLen;
132 uint32_t TypesInfoStart = HdrLen + TypeOff;
133 uint32_t TypesInfoEnd = TypesInfoStart + TypeLen;
134 uint32_t BytesExpected = std::max(StrEnd, TypesInfoEnd);
135 if ()
136 return Err(".BTF", C);
137 if (Extractor.getData().size() < BytesExpected)
138 return Err("invalid .BTF section size, expecting at-least ")
139 << BytesExpected << " bytes";
140
141 StringsTable = Extractor.getData().slice(StrStart, StrEnd);
142
143 if (TypeLen > 0 && Ctx.Opts.LoadTypes) {
144 StringRef RawData = Extractor.getData().slice(TypesInfoStart, TypesInfoEnd);
145 if (Error E = parseTypesInfo(Ctx, TypesInfoStart, RawData))
146 return E;
147 }
148
150}
151
152
153
156 switch (Type->getKind()) {
157 case BTF::BTF_KIND_INT:
159 break;
160 case BTF::BTF_KIND_ARRAY:
162 break;
163 case BTF::BTF_KIND_VAR:
165 break;
166 case BTF::BTF_KIND_DECL_TAG:
168 break;
169 case BTF::BTF_KIND_STRUCT:
170 case BTF::BTF_KIND_UNION:
172 break;
173 case BTF::BTF_KIND_ENUM:
175 break;
176 case BTF::BTF_KIND_ENUM64:
178 break;
179 case BTF::BTF_KIND_FUNC_PROTO:
181 break;
182 case BTF::BTF_KIND_DATASEC:
184 break;
185 }
187}
188
189
190
192
193
194
195
196
197
198
199
200
201
202
203
204
205Error BTFParser::parseTypesInfo(ParseContext &Ctx, uint64_t TypesInfoStart,
208
210
213 uint32_t *TypesBuffer32 = (uint32_t *)TypesBuffer.data();
214 for (uint64_t I = 0; I < TypesBuffer.size() / 4; ++I)
215 TypesBuffer32[I] = byte_swap(TypesBuffer32[I], Endianness);
216
217
219
220 uint64_t Pos = 0;
221 while (Pos < RawData.size()) {
222 uint64_t BytesLeft = RawData.size() - Pos;
223 uint64_t Offset = TypesInfoStart + Pos;
224 BTF::CommonType *Type = (BTF::CommonType *)&TypesBuffer[Pos];
225 if (BytesLeft < sizeof(*Type))
226 return Err("incomplete type definition in .BTF section:")
227 << " offset " << Offset << ", index " << Types.size();
228
230 if (BytesLeft < Size)
231 return Err("incomplete type definition in .BTF section:")
232 << " offset=" << Offset << ", index=" << Types.size()
233 << ", vlen=" << Type->getVlen();
234
237 << " Id = " << Types.size() << "\n"
238 << " Kind = " << Type->getKind() << "\n"
240 << " Record Size = " << Size << "\n";
241 });
242 Types.push_back(Type);
244 }
245
247}
248
249Error BTFParser::parseBTFExt(ParseContext &Ctx, SectionRef BTFExt) {
250 Expected MaybeExtractor = Ctx.makeExtractor(BTFExt);
251 if (!MaybeExtractor)
252 return MaybeExtractor.takeError();
253
254 DataExtractor &Extractor = MaybeExtractor.get();
255 DataExtractor::Cursor C = DataExtractor::Cursor(0);
257 if ()
258 return Err(".BTF.ext", C);
260 return Err("invalid .BTF.ext magic: ").write_hex(Magic);
262 if ()
263 return Err(".BTF", C);
265 return Err("unsupported .BTF.ext version: ") << (unsigned)Version;
267 uint32_t HdrLen = Extractor.getU32(C);
268 if ()
269 return Err(".BTF.ext", C);
270 if (HdrLen < 8)
271 return Err("unexpected .BTF.ext header length: ") << HdrLen;
272 (void)Extractor.getU32(C);
273 (void)Extractor.getU32(C);
274 uint32_t LineInfoOff = Extractor.getU32(C);
275 uint32_t LineInfoLen = Extractor.getU32(C);
276 uint32_t RelocInfoOff = Extractor.getU32(C);
277 uint32_t RelocInfoLen = Extractor.getU32(C);
278 if ()
279 return Err(".BTF.ext", C);
280
281 if (LineInfoLen > 0 && Ctx.Opts.LoadLines) {
282 uint32_t LineInfoStart = HdrLen + LineInfoOff;
283 uint32_t LineInfoEnd = LineInfoStart + LineInfoLen;
284 if (Error E = parseLineInfo(Ctx, Extractor, LineInfoStart, LineInfoEnd))
285 return E;
286 }
287
288 if (RelocInfoLen > 0 && Ctx.Opts.LoadRelocs) {
289 uint32_t RelocInfoStart = HdrLen + RelocInfoOff;
290 uint32_t RelocInfoEnd = RelocInfoStart + RelocInfoLen;
291 if (Error E = parseRelocInfo(Ctx, Extractor, RelocInfoStart, RelocInfoEnd))
292 return E;
293 }
294
296}
297
298Error BTFParser::parseLineInfo(ParseContext &Ctx, DataExtractor &Extractor,
299 uint64_t LineInfoStart, uint64_t LineInfoEnd) {
300 DataExtractor::Cursor C = DataExtractor::Cursor(LineInfoStart);
301 uint32_t RecSize = Extractor.getU32(C);
302 if ()
303 return Err(".BTF.ext", C);
304 if (RecSize < 16)
305 return Err("unexpected .BTF.ext line info record length: ") << RecSize;
306
307 while (C && C.tell() < LineInfoEnd) {
308 uint32_t SecNameOff = Extractor.getU32(C);
309 uint32_t NumInfo = Extractor.getU32(C);
310 StringRef SecName = findString(SecNameOff);
311 std::optional Sec = Ctx.findSection(SecName);
312 if ()
313 return Err(".BTF.ext", C);
314 if (!Sec)
315 return Err("") << "can't find section '" << SecName
316 << "' while parsing .BTF.ext line info";
317 BTFLinesVector &Lines = SectionLines[Sec->getIndex()];
318 for (uint32_t I = 0; C && I < NumInfo; ++I) {
319 uint64_t RecStart = C.tell();
320 uint32_t InsnOff = Extractor.getU32(C);
321 uint32_t FileNameOff = Extractor.getU32(C);
322 uint32_t LineOff = Extractor.getU32(C);
323 uint32_t LineCol = Extractor.getU32(C);
324 if ()
325 return Err(".BTF.ext", C);
326 Lines.push_back({InsnOff, FileNameOff, LineOff, LineCol});
327 C.seek(RecStart + RecSize);
328 }
330 [](const BTF::BPFLineInfo &L, const BTF::BPFLineInfo &R) {
331 return L.InsnOffset < R.InsnOffset;
332 });
333 }
334 if ()
335 return Err(".BTF.ext", C);
336
338}
339
340Error BTFParser::parseRelocInfo(ParseContext &Ctx, DataExtractor &Extractor,
341 uint64_t RelocInfoStart,
342 uint64_t RelocInfoEnd) {
343 DataExtractor::Cursor C = DataExtractor::Cursor(RelocInfoStart);
344 uint32_t RecSize = Extractor.getU32(C);
345 if ()
346 return Err(".BTF.ext", C);
347 if (RecSize < 16)
348 return Err("unexpected .BTF.ext field reloc info record length: ")
349 << RecSize;
350 while (C && C.tell() < RelocInfoEnd) {
351 uint32_t SecNameOff = Extractor.getU32(C);
352 uint32_t NumInfo = Extractor.getU32(C);
353 StringRef SecName = findString(SecNameOff);
354 std::optional Sec = Ctx.findSection(SecName);
355 BTFRelocVector &Relocs = SectionRelocs[Sec->getIndex()];
356 for (uint32_t I = 0; C && I < NumInfo; ++I) {
357 uint64_t RecStart = C.tell();
358 uint32_t InsnOff = Extractor.getU32(C);
360 uint32_t OffsetNameOff = Extractor.getU32(C);
361 uint32_t RelocKind = Extractor.getU32(C);
362 if ()
363 return Err(".BTF.ext", C);
364 Relocs.push_back({InsnOff, TypeID, OffsetNameOff, RelocKind});
365 C.seek(RecStart + RecSize);
366 }
368 Relocs, [](const BTF::BPFFieldReloc &L, const BTF::BPFFieldReloc &R) {
369 return L.InsnOffset < R.InsnOffset;
370 });
371 }
372 if ()
373 return Err(".BTF.ext", C);
374
376}
377
380 SectionLines.clear();
381 SectionRelocs.clear();
382 Types.clear();
384
386 std::optional BTF;
387 std::optional BTFExt;
388 for (SectionRef Sec : Obj.sections()) {
390 if (!MaybeName)
391 return Err("error while reading section name: ") << MaybeName.takeError();
392 Ctx.Sections[*MaybeName] = Sec;
394 BTF = Sec;
396 BTFExt = Sec;
397 }
398 if ()
399 return Err("can't find .BTF section");
400 if (!BTFExt)
401 return Err("can't find .BTF.ext section");
402 if (Error E = parseBTF(Ctx, *BTF))
403 return E;
404 if (Error E = parseBTFExt(Ctx, *BTFExt))
405 return E;
406
408}
409
411 bool HasBTF = false;
412 bool HasBTFExt = false;
413 for (SectionRef Sec : Obj.sections()) {
415 if (Error E = Name.takeError()) {
417 continue;
418 }
421 if (HasBTF && HasBTFExt)
422 return true;
423 }
424 return false;
425}
426
430
431template
434 auto MaybeSecInfo = SecMap.find(Address.SectionIndex);
435 if (MaybeSecInfo == SecMap.end())
436 return nullptr;
437
439 const uint64_t TargetOffset = Address.Address;
441 SecInfo, [=](const T &Entry) { return Entry.InsnOffset < TargetOffset; });
442 if (MaybeInfo == SecInfo.end() || MaybeInfo->InsnOffset != Address.Address)
443 return nullptr;
444
445 return &*MaybeInfo;
446}
447
452
457
459 if (Id < Types.size())
460 return Types[Id];
461 return nullptr;
462}
463
470
472 switch (Reloc->RelocKind) {
489 default:
491 }
492}
493
495 switch (Type->getKind()) {
496 case BTF::BTF_KIND_VOLATILE:
497 case BTF::BTF_KIND_CONST:
498 case BTF::BTF_KIND_RESTRICT:
499 case BTF::BTF_KIND_TYPE_TAG:
500 return true;
501 default:
502 return false;
503 }
504}
505
508 switch (Type->getKind()) {
509 case BTF::BTF_KIND_CONST:
510 Stream << " const";
511 break;
512 case BTF::BTF_KIND_VOLATILE:
513 Stream << " volatile";
514 break;
515 case BTF::BTF_KIND_RESTRICT:
516 Stream << " restrict";
517 break;
518 case BTF::BTF_KIND_TYPE_TAG:
519 Stream << " type_tag(\"" << BTF.findString(Type->NameOff) << "\")";
520 break;
521 default:
522 return false;
523 }
524 return true;
525}
526
529 while (isMod(Type) || Type->getKind() == BTF::BTF_KIND_TYPEDEF) {
532 break;
534 }
536}
537
538namespace {
539struct StrOrAnon {
540 const BTFParser &BTF;
542 uint32_t Idx;
543};
544
547 if (Str.empty())
548 Stream << "<anon " << S.Idx << ">";
549 else
550 Stream << Str;
551 return Stream;
552}
553}
554
556 Out << "<";
557 switch (X) {
558 default:
559 Out << "reloc kind #" << X;
560 break;
562 Out << "byte_off";
563 break;
565 Out << "byte_sz";
566 break;
568 Out << "field_exists";
569 break;
571 Out << "signed";
572 break;
574 Out << "lshift_u64";
575 break;
577 Out << "rshift_u64";
578 break;
580 Out << "local_type_id";
581 break;
583 Out << "target_type_id";
584 break;
586 Out << "type_exists";
587 break;
589 Out << "type_matches";
590 break;
592 Out << "type_size";
593 break;
595 Out << "enumval_exists";
596 break;
598 Out << "enumval_value";
599 break;
600 }
601 Out << ">";
602}
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
662
663 auto Fail = [&](auto Msg) {
664 Result.resize(0);
666 Stream << " [" << Reloc->TypeID << "] '" << FullSpecStr << "'"
667 << " <" << Msg << ">";
668 };
669
670
671
672
674 while (SpecStr.size()) {
675 unsigned long long Val;
677 return Fail("spec string is not a number");
679 if (SpecStr.empty())
680 break;
681 if (SpecStr[0] != ':')
682 return Fail(format("unexpected spec string delimiter: '%c'", SpecStr[0]));
683 SpecStr = SpecStr.substr(1);
684 }
685
686
688
692 return Fail(format("unknown type id: %d", CurId));
693
694 Stream << " [" << CurId << "]";
695
696
697
698
700 if (ChainLen >= 32)
701 return Fail("modifiers chain is too long");
702
705 if (!NextType)
706 return Fail(format("unknown type id: %d in modifiers chain", CurId));
707 Type = NextType;
708 }
709
710 if (CurId == 0) {
711 Stream << " void";
712 } else {
713 switch (Type->getKind()) {
714 case BTF::BTF_KIND_TYPEDEF:
715 Stream << " typedef";
716 break;
717 case BTF::BTF_KIND_STRUCT:
718 Stream << " struct";
719 break;
720 case BTF::BTF_KIND_UNION:
721 Stream << " union";
722 break;
723 case BTF::BTF_KIND_ENUM:
724 Stream << " enum";
725 break;
726 case BTF::BTF_KIND_ENUM64:
727 Stream << " enum";
728 break;
729 case BTF::BTF_KIND_FWD:
731 Stream << " fwd union";
732 else
733 Stream << " fwd struct";
734 break;
735 default:
736 break;
737 }
738 Stream << " " << StrOrAnon({*this, Type->NameOff, CurId});
739 }
740
742
743
745 if (RawSpec.size() != 1 || RawSpec[0] != 0)
746 return Fail("unexpected type-based relocation spec: should be '0'");
747 return;
748 }
749
750 Stream << "::";
751
752
753
754
755
756
757
758
761
762 if (RawSpec.size() != 1)
763 return Fail("unexpected enumval relocation spec size");
764
769 if (T->values().size() <= Idx)
770 return Fail(format("bad value index: %d", Idx));
772 NameOff = E.NameOff;
773 Val = E.Val;
775 if (T->values().size() <= Idx)
776 return Fail(format("bad value index: %d", Idx));
778 NameOff = E.NameOff;
779 Val = (uint64_t)E.Val_Hi32 << 32u | E.Val_Lo32;
780 } else {
781 return Fail(format("unexpected type kind for enum relocation: %d",
782 Type->getKind()));
783 }
784
785 Stream << StrOrAnon({*this, NameOff, Idx});
787 Stream << " = " << (int64_t)Val;
788 else
789 Stream << " = " << (uint64_t)Val;
790 return;
791 }
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
816 if (RawSpec.size() < 1)
817 return Fail("field spec too short");
818
819 if (RawSpec[0] != 0)
820 Stream << "[" << RawSpec[0] << "]";
821 for (uint32_t I = 1; I < RawSpec.size(); ++I) {
824
826 if (T->getVlen() <= Idx)
828 format("member index %d for spec sub-string %d is out of range",
829 Idx, I));
830
832 if (I != 1 || RawSpec[0] != 0)
833 Stream << ".";
834 Stream << StrOrAnon({*this, Member.NameOff, Idx});
837 return Fail(format("unknown member type id %d for spec sub-string %d",
838 Member.Type, I));
840 Stream << "[" << Idx << "]";
844 format("unknown element type id %d for spec sub-string %d",
845 T->getArray().ElemType, I));
846 } else {
847 return Fail(format("unexpected type kind %d for spec sub-string %d",
849 }
850 }
851
852 Stream << " (" << FullSpecStr << ")";
853 return;
854 }
855
856 return Fail(format("unknown relocation kind: %d", Reloc->RelocKind));
857}
static RelocKindGroup relocKindGroup(const BTF::BPFFieldReloc *Reloc)
Definition BTFParser.cpp:471
static size_t byteSize(BTF::CommonType *Type)
Definition BTFParser.cpp:154
static bool printMod(const BTFParser &BTF, const BTF::CommonType *Type, raw_ostream &Stream)
Definition BTFParser.cpp:506
const BTF::CommonType VoidTypeInst
Definition BTFParser.cpp:191
static bool isMod(const BTF::CommonType *Type)
Definition BTFParser.cpp:494
const char BTFSectionName[]
Definition BTFParser.cpp:26
const char BTFExtSectionName[]
Definition BTFParser.cpp:27
static void relocKindName(uint32_t X, raw_ostream &Out)
Definition BTFParser.cpp:555
static const T * findInfo(const DenseMap< uint64_t, SmallVector< T, 0 > > &SecMap, SectionedAddress Address)
Definition BTFParser.cpp:432
static const BTF::CommonType * skipModsAndTypedefs(const BTFParser &BTF, const BTF::CommonType *Type)
Definition BTFParser.cpp:527
RelocKindGroup
Definition BTFParser.cpp:464
@ RKG_UNKNOWN
Definition BTFParser.cpp:468
@ RKG_ENUMVAL
Definition BTFParser.cpp:467
@ RKG_FIELD
Definition BTFParser.cpp:465
@ RKG_TYPE
Definition BTFParser.cpp:466
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LLVM_ABI StringRef findString(uint32_t Offset) const
Definition BTFParser.cpp:427
LLVM_ABI Error parse(const ObjectFile &Obj, const ParseOptions &Opts)
Definition BTFParser.cpp:378
LLVM_ABI const BTF::BPFLineInfo * findLineInfo(SectionedAddress Address) const
Definition BTFParser.cpp:449
LLVM_ABI void symbolize(const BTF::BPFFieldReloc *Reloc, SmallVectorImpl< char > &Result) const
Definition BTFParser.cpp:657
LLVM_ABI const BTF::CommonType * findType(uint32_t Id) const
Definition BTFParser.cpp:458
static LLVM_ABI bool hasBTFSections(const ObjectFile &Obj)
Definition BTFParser.cpp:410
LLVM_ABI const BTF::BPFFieldReloc * findFieldReloc(SectionedAddress Address) const
Definition BTFParser.cpp:454
Base class for error info classes.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
This is a MutableArrayRef that owns its array.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
The instances of the Type class are immutable: once they are created, they are never changed.
Type(LLVMContext &C, TypeID tid)
This class is the base class for all object file types.
This is a value type class that represents a single section in the list of sections in the object fil...
Expected< StringRef > getContents() const
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
constexpr uint32_t ENUM_SIGNED_FLAG
constexpr uint32_t FWD_UNION_FLAG
@ C
The default llvm calling convention, compatible with C.
constexpr llvm::endianness Endianness
The endianness of all multi-byte encoded values in MessagePack.
value_type byte_swap(value_type value, endianness endian)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
void stable_sort(R &&Range)
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
LLVM_ABI bool consumeUnsignedInteger(StringRef &Str, unsigned Radix, unsigned long long &Result)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition BTFParser.cpp:77
std::optional< SectionRef > findSection(StringRef Name) const
Definition BTFParser.cpp:95
Expected< DataExtractor > makeExtractor(SectionRef Sec)
Definition BTFParser.cpp:87
ParseContext(const ObjectFile &Obj, const ParseOptions &Opts)
Definition BTFParser.cpp:84
const ObjectFile & Obj
Definition BTFParser.cpp:78
DenseMap< StringRef, SectionRef > Sections
Definition BTFParser.cpp:81
const ParseOptions & Opts
Definition BTFParser.cpp:79
Specifying one offset relocation.
Specifying one line info.
BTF_KIND_ARRAY is followed by one "struct BTFArray".
BTF_KIND_DATASEC are followed by multiple "struct BTFDataSecVar".
BTF_KIND_ENUM64 is followed by multiple "struct BTFEnum64".
BTF_KIND_ENUM is followed by multiple "struct BTFEnum".
BTF_KIND_STRUCT and BTF_KIND_UNION are followed by multiple "struct BTFMember".
BTF_KIND_FUNC_PROTO are followed by multiple "struct BTFParam".
The BTF common type definition.