github.com/cilium/ebpf@v0.16.0/btf/types.go (about) 1 package btf 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 "io" 8 "math" 9 "slices" 10 "strings" 11 12 "github.com/cilium/ebpf/asm" 13 "github.com/cilium/ebpf/internal" 14 "github.com/cilium/ebpf/internal/sys" 15 ) 16 17 // Mirrors MAX_RESOLVE_DEPTH in libbpf. 18 // https://github.com/libbpf/libbpf/blob/e26b84dc330c9644c07428c271ab491b0f01f4e1/src/btf.c#L761 19 const maxResolveDepth = 32 20 21 // TypeID identifies a type in a BTF section. 22 type TypeID = sys.TypeID 23 24 // Type represents a type described by BTF. 25 // 26 // Identity of Type follows the [Go specification]: two Types are considered 27 // equal if they have the same concrete type and the same dynamic value, aka 28 // they point at the same location in memory. This means that the following 29 // Types are considered distinct even though they have the same "shape". 30 // 31 // a := &Int{Size: 1} 32 // b := &Int{Size: 1} 33 // a != b 34 // 35 // [Go specification]: https://go.dev/ref/spec#Comparison_operators 36 type Type interface { 37 // Type can be formatted using the %s and %v verbs. %s outputs only the 38 // identity of the type, without any detail. %v outputs additional detail. 39 // 40 // Use the '+' flag to include the address of the type. 41 // 42 // Use the width to specify how many levels of detail to output, for example 43 // %1v will output detail for the root type and a short description of its 44 // children. %2v would output details of the root type and its children 45 // as well as a short description of the grandchildren. 46 fmt.Formatter 47 48 // Name of the type, empty for anonymous types and types that cannot 49 // carry a name, like Void and Pointer. 50 TypeName() string 51 52 // Make a copy of the type, without copying Type members. 53 copy() Type 54 55 // New implementations must update walkType. 56 } 57 58 var ( 59 _ Type = (*Int)(nil) 60 _ Type = (*Struct)(nil) 61 _ Type = (*Union)(nil) 62 _ Type = (*Enum)(nil) 63 _ Type = (*Fwd)(nil) 64 _ Type = (*Func)(nil) 65 _ Type = (*Typedef)(nil) 66 _ Type = (*Var)(nil) 67 _ Type = (*Datasec)(nil) 68 _ Type = (*Float)(nil) 69 _ Type = (*declTag)(nil) 70 _ Type = (*typeTag)(nil) 71 _ Type = (*cycle)(nil) 72 ) 73 74 // Void is the unit type of BTF. 75 type Void struct{} 76 77 func (v *Void) Format(fs fmt.State, verb rune) { formatType(fs, verb, v) } 78 func (v *Void) TypeName() string { return "" } 79 func (v *Void) size() uint32 { return 0 } 80 func (v *Void) copy() Type { return (*Void)(nil) } 81 82 type IntEncoding byte 83 84 // Valid IntEncodings. 85 // 86 // These may look like they are flags, but they aren't. 87 const ( 88 Unsigned IntEncoding = 0 89 Signed IntEncoding = 1 90 Char IntEncoding = 2 91 Bool IntEncoding = 4 92 ) 93 94 func (ie IntEncoding) String() string { 95 switch ie { 96 case Char: 97 // NB: There is no way to determine signedness for char. 98 return "char" 99 case Bool: 100 return "bool" 101 case Signed: 102 return "signed" 103 case Unsigned: 104 return "unsigned" 105 default: 106 return fmt.Sprintf("IntEncoding(%d)", byte(ie)) 107 } 108 } 109 110 // Int is an integer of a given length. 111 // 112 // See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int 113 type Int struct { 114 Name string 115 116 // The size of the integer in bytes. 117 Size uint32 118 Encoding IntEncoding 119 } 120 121 func (i *Int) Format(fs fmt.State, verb rune) { 122 formatType(fs, verb, i, i.Encoding, "size=", i.Size) 123 } 124 125 func (i *Int) TypeName() string { return i.Name } 126 func (i *Int) size() uint32 { return i.Size } 127 func (i *Int) copy() Type { 128 cpy := *i 129 return &cpy 130 } 131 132 // Pointer is a pointer to another type. 133 type Pointer struct { 134 Target Type 135 } 136 137 func (p *Pointer) Format(fs fmt.State, verb rune) { 138 formatType(fs, verb, p, "target=", p.Target) 139 } 140 141 func (p *Pointer) TypeName() string { return "" } 142 func (p *Pointer) size() uint32 { return 8 } 143 func (p *Pointer) copy() Type { 144 cpy := *p 145 return &cpy 146 } 147 148 // Array is an array with a fixed number of elements. 149 type Array struct { 150 Index Type 151 Type Type 152 Nelems uint32 153 } 154 155 func (arr *Array) Format(fs fmt.State, verb rune) { 156 formatType(fs, verb, arr, "index=", arr.Index, "type=", arr.Type, "n=", arr.Nelems) 157 } 158 159 func (arr *Array) TypeName() string { return "" } 160 161 func (arr *Array) copy() Type { 162 cpy := *arr 163 return &cpy 164 } 165 166 // Struct is a compound type of consecutive members. 167 type Struct struct { 168 Name string 169 // The size of the struct including padding, in bytes 170 Size uint32 171 Members []Member 172 } 173 174 func (s *Struct) Format(fs fmt.State, verb rune) { 175 formatType(fs, verb, s, "fields=", len(s.Members)) 176 } 177 178 func (s *Struct) TypeName() string { return s.Name } 179 180 func (s *Struct) size() uint32 { return s.Size } 181 182 func (s *Struct) copy() Type { 183 cpy := *s 184 cpy.Members = copyMembers(s.Members) 185 return &cpy 186 } 187 188 func (s *Struct) members() []Member { 189 return s.Members 190 } 191 192 // Union is a compound type where members occupy the same memory. 193 type Union struct { 194 Name string 195 // The size of the union including padding, in bytes. 196 Size uint32 197 Members []Member 198 } 199 200 func (u *Union) Format(fs fmt.State, verb rune) { 201 formatType(fs, verb, u, "fields=", len(u.Members)) 202 } 203 204 func (u *Union) TypeName() string { return u.Name } 205 206 func (u *Union) size() uint32 { return u.Size } 207 208 func (u *Union) copy() Type { 209 cpy := *u 210 cpy.Members = copyMembers(u.Members) 211 return &cpy 212 } 213 214 func (u *Union) members() []Member { 215 return u.Members 216 } 217 218 func copyMembers(orig []Member) []Member { 219 cpy := make([]Member, len(orig)) 220 copy(cpy, orig) 221 return cpy 222 } 223 224 type composite interface { 225 Type 226 members() []Member 227 } 228 229 var ( 230 _ composite = (*Struct)(nil) 231 _ composite = (*Union)(nil) 232 ) 233 234 // A value in bits. 235 type Bits uint32 236 237 // Bytes converts a bit value into bytes. 238 func (b Bits) Bytes() uint32 { 239 return uint32(b / 8) 240 } 241 242 // Member is part of a Struct or Union. 243 // 244 // It is not a valid Type. 245 type Member struct { 246 Name string 247 Type Type 248 Offset Bits 249 BitfieldSize Bits 250 } 251 252 // Enum lists possible values. 253 type Enum struct { 254 Name string 255 // Size of the enum value in bytes. 256 Size uint32 257 // True if the values should be interpreted as signed integers. 258 Signed bool 259 Values []EnumValue 260 } 261 262 func (e *Enum) Format(fs fmt.State, verb rune) { 263 formatType(fs, verb, e, "size=", e.Size, "values=", len(e.Values)) 264 } 265 266 func (e *Enum) TypeName() string { return e.Name } 267 268 // EnumValue is part of an Enum 269 // 270 // Is is not a valid Type 271 type EnumValue struct { 272 Name string 273 Value uint64 274 } 275 276 func (e *Enum) size() uint32 { return e.Size } 277 func (e *Enum) copy() Type { 278 cpy := *e 279 cpy.Values = make([]EnumValue, len(e.Values)) 280 copy(cpy.Values, e.Values) 281 return &cpy 282 } 283 284 // FwdKind is the type of forward declaration. 285 type FwdKind int 286 287 // Valid types of forward declaration. 288 const ( 289 FwdStruct FwdKind = iota 290 FwdUnion 291 ) 292 293 func (fk FwdKind) String() string { 294 switch fk { 295 case FwdStruct: 296 return "struct" 297 case FwdUnion: 298 return "union" 299 default: 300 return fmt.Sprintf("%T(%d)", fk, int(fk)) 301 } 302 } 303 304 // Fwd is a forward declaration of a Type. 305 type Fwd struct { 306 Name string 307 Kind FwdKind 308 } 309 310 func (f *Fwd) Format(fs fmt.State, verb rune) { 311 formatType(fs, verb, f, f.Kind) 312 } 313 314 func (f *Fwd) TypeName() string { return f.Name } 315 316 func (f *Fwd) copy() Type { 317 cpy := *f 318 return &cpy 319 } 320 321 func (f *Fwd) matches(typ Type) bool { 322 if _, ok := As[*Struct](typ); ok && f.Kind == FwdStruct { 323 return true 324 } 325 326 if _, ok := As[*Union](typ); ok && f.Kind == FwdUnion { 327 return true 328 } 329 330 return false 331 } 332 333 // Typedef is an alias of a Type. 334 type Typedef struct { 335 Name string 336 Type Type 337 } 338 339 func (td *Typedef) Format(fs fmt.State, verb rune) { 340 formatType(fs, verb, td, td.Type) 341 } 342 343 func (td *Typedef) TypeName() string { return td.Name } 344 345 func (td *Typedef) copy() Type { 346 cpy := *td 347 return &cpy 348 } 349 350 // Volatile is a qualifier. 351 type Volatile struct { 352 Type Type 353 } 354 355 func (v *Volatile) Format(fs fmt.State, verb rune) { 356 formatType(fs, verb, v, v.Type) 357 } 358 359 func (v *Volatile) TypeName() string { return "" } 360 361 func (v *Volatile) qualify() Type { return v.Type } 362 func (v *Volatile) copy() Type { 363 cpy := *v 364 return &cpy 365 } 366 367 // Const is a qualifier. 368 type Const struct { 369 Type Type 370 } 371 372 func (c *Const) Format(fs fmt.State, verb rune) { 373 formatType(fs, verb, c, c.Type) 374 } 375 376 func (c *Const) TypeName() string { return "" } 377 378 func (c *Const) qualify() Type { return c.Type } 379 func (c *Const) copy() Type { 380 cpy := *c 381 return &cpy 382 } 383 384 // Restrict is a qualifier. 385 type Restrict struct { 386 Type Type 387 } 388 389 func (r *Restrict) Format(fs fmt.State, verb rune) { 390 formatType(fs, verb, r, r.Type) 391 } 392 393 func (r *Restrict) TypeName() string { return "" } 394 395 func (r *Restrict) qualify() Type { return r.Type } 396 func (r *Restrict) copy() Type { 397 cpy := *r 398 return &cpy 399 } 400 401 // Func is a function definition. 402 type Func struct { 403 Name string 404 Type Type 405 Linkage FuncLinkage 406 } 407 408 func FuncMetadata(ins *asm.Instruction) *Func { 409 fn, _ := ins.Metadata.Get(funcInfoMeta{}).(*Func) 410 return fn 411 } 412 413 // WithFuncMetadata adds a btf.Func to the Metadata of asm.Instruction. 414 func WithFuncMetadata(ins asm.Instruction, fn *Func) asm.Instruction { 415 ins.Metadata.Set(funcInfoMeta{}, fn) 416 return ins 417 } 418 419 func (f *Func) Format(fs fmt.State, verb rune) { 420 formatType(fs, verb, f, f.Linkage, "proto=", f.Type) 421 } 422 423 func (f *Func) TypeName() string { return f.Name } 424 425 func (f *Func) copy() Type { 426 cpy := *f 427 return &cpy 428 } 429 430 // FuncProto is a function declaration. 431 type FuncProto struct { 432 Return Type 433 Params []FuncParam 434 } 435 436 func (fp *FuncProto) Format(fs fmt.State, verb rune) { 437 formatType(fs, verb, fp, "args=", len(fp.Params), "return=", fp.Return) 438 } 439 440 func (fp *FuncProto) TypeName() string { return "" } 441 442 func (fp *FuncProto) copy() Type { 443 cpy := *fp 444 cpy.Params = make([]FuncParam, len(fp.Params)) 445 copy(cpy.Params, fp.Params) 446 return &cpy 447 } 448 449 type FuncParam struct { 450 Name string 451 Type Type 452 } 453 454 // Var is a global variable. 455 type Var struct { 456 Name string 457 Type Type 458 Linkage VarLinkage 459 } 460 461 func (v *Var) Format(fs fmt.State, verb rune) { 462 formatType(fs, verb, v, v.Linkage) 463 } 464 465 func (v *Var) TypeName() string { return v.Name } 466 467 func (v *Var) copy() Type { 468 cpy := *v 469 return &cpy 470 } 471 472 // Datasec is a global program section containing data. 473 type Datasec struct { 474 Name string 475 Size uint32 476 Vars []VarSecinfo 477 } 478 479 func (ds *Datasec) Format(fs fmt.State, verb rune) { 480 formatType(fs, verb, ds) 481 } 482 483 func (ds *Datasec) TypeName() string { return ds.Name } 484 485 func (ds *Datasec) size() uint32 { return ds.Size } 486 487 func (ds *Datasec) copy() Type { 488 cpy := *ds 489 cpy.Vars = make([]VarSecinfo, len(ds.Vars)) 490 copy(cpy.Vars, ds.Vars) 491 return &cpy 492 } 493 494 // VarSecinfo describes variable in a Datasec. 495 // 496 // It is not a valid Type. 497 type VarSecinfo struct { 498 // Var or Func. 499 Type Type 500 Offset uint32 501 Size uint32 502 } 503 504 // Float is a float of a given length. 505 type Float struct { 506 Name string 507 508 // The size of the float in bytes. 509 Size uint32 510 } 511 512 func (f *Float) Format(fs fmt.State, verb rune) { 513 formatType(fs, verb, f, "size=", f.Size*8) 514 } 515 516 func (f *Float) TypeName() string { return f.Name } 517 func (f *Float) size() uint32 { return f.Size } 518 func (f *Float) copy() Type { 519 cpy := *f 520 return &cpy 521 } 522 523 // declTag associates metadata with a declaration. 524 type declTag struct { 525 Type Type 526 Value string 527 // The index this tag refers to in the target type. For composite types, 528 // a value of -1 indicates that the tag refers to the whole type. Otherwise 529 // it indicates which member or argument the tag applies to. 530 Index int 531 } 532 533 func (dt *declTag) Format(fs fmt.State, verb rune) { 534 formatType(fs, verb, dt, "type=", dt.Type, "value=", dt.Value, "index=", dt.Index) 535 } 536 537 func (dt *declTag) TypeName() string { return "" } 538 func (dt *declTag) copy() Type { 539 cpy := *dt 540 return &cpy 541 } 542 543 // typeTag associates metadata with a type. 544 type typeTag struct { 545 Type Type 546 Value string 547 } 548 549 func (tt *typeTag) Format(fs fmt.State, verb rune) { 550 formatType(fs, verb, tt, "type=", tt.Type, "value=", tt.Value) 551 } 552 553 func (tt *typeTag) TypeName() string { return "" } 554 func (tt *typeTag) qualify() Type { return tt.Type } 555 func (tt *typeTag) copy() Type { 556 cpy := *tt 557 return &cpy 558 } 559 560 // cycle is a type which had to be elided since it exceeded maxTypeDepth. 561 type cycle struct { 562 root Type 563 } 564 565 func (c *cycle) ID() TypeID { return math.MaxUint32 } 566 func (c *cycle) Format(fs fmt.State, verb rune) { formatType(fs, verb, c, "root=", c.root) } 567 func (c *cycle) TypeName() string { return "" } 568 func (c *cycle) copy() Type { 569 cpy := *c 570 return &cpy 571 } 572 573 type sizer interface { 574 size() uint32 575 } 576 577 var ( 578 _ sizer = (*Int)(nil) 579 _ sizer = (*Pointer)(nil) 580 _ sizer = (*Struct)(nil) 581 _ sizer = (*Union)(nil) 582 _ sizer = (*Enum)(nil) 583 _ sizer = (*Datasec)(nil) 584 ) 585 586 type qualifier interface { 587 qualify() Type 588 } 589 590 var ( 591 _ qualifier = (*Const)(nil) 592 _ qualifier = (*Restrict)(nil) 593 _ qualifier = (*Volatile)(nil) 594 _ qualifier = (*typeTag)(nil) 595 ) 596 597 var errUnsizedType = errors.New("type is unsized") 598 599 // Sizeof returns the size of a type in bytes. 600 // 601 // Returns an error if the size can't be computed. 602 func Sizeof(typ Type) (int, error) { 603 var ( 604 n = int64(1) 605 elem int64 606 ) 607 608 for i := 0; i < maxResolveDepth; i++ { 609 switch v := typ.(type) { 610 case *Array: 611 if n > 0 && int64(v.Nelems) > math.MaxInt64/n { 612 return 0, fmt.Errorf("type %s: overflow", typ) 613 } 614 615 // Arrays may be of zero length, which allows 616 // n to be zero as well. 617 n *= int64(v.Nelems) 618 typ = v.Type 619 continue 620 621 case sizer: 622 elem = int64(v.size()) 623 624 case *Typedef: 625 typ = v.Type 626 continue 627 628 case qualifier: 629 typ = v.qualify() 630 continue 631 632 default: 633 return 0, fmt.Errorf("type %T: %w", typ, errUnsizedType) 634 } 635 636 if n > 0 && elem > math.MaxInt64/n { 637 return 0, fmt.Errorf("type %s: overflow", typ) 638 } 639 640 size := n * elem 641 if int64(int(size)) != size { 642 return 0, fmt.Errorf("type %s: overflow", typ) 643 } 644 645 return int(size), nil 646 } 647 648 return 0, fmt.Errorf("type %s: exceeded type depth", typ) 649 } 650 651 // alignof returns the alignment of a type. 652 // 653 // Returns an error if the Type can't be aligned, like an integer with an uneven 654 // size. Currently only supports the subset of types necessary for bitfield 655 // relocations. 656 func alignof(typ Type) (int, error) { 657 var n int 658 659 switch t := UnderlyingType(typ).(type) { 660 case *Enum: 661 n = int(t.size()) 662 case *Int: 663 n = int(t.Size) 664 case *Array: 665 return alignof(t.Type) 666 default: 667 return 0, fmt.Errorf("can't calculate alignment of %T", t) 668 } 669 670 if !internal.IsPow(n) { 671 return 0, fmt.Errorf("alignment value %d is not a power of two", n) 672 } 673 674 return n, nil 675 } 676 677 // Copy a Type recursively. 678 // 679 // typ may form a cycle. 680 func Copy(typ Type) Type { 681 return copyType(typ, nil, make(map[Type]Type), nil) 682 } 683 684 func copyType(typ Type, ids map[Type]TypeID, copies map[Type]Type, copiedIDs map[Type]TypeID) Type { 685 if typ == nil { 686 return nil 687 } 688 689 cpy, ok := copies[typ] 690 if ok { 691 // This has been copied previously, no need to continue. 692 return cpy 693 } 694 695 cpy = typ.copy() 696 copies[typ] = cpy 697 698 if id, ok := ids[typ]; ok { 699 copiedIDs[cpy] = id 700 } 701 702 children(cpy, func(child *Type) bool { 703 *child = copyType(*child, ids, copies, copiedIDs) 704 return true 705 }) 706 707 return cpy 708 } 709 710 type typeDeque = internal.Deque[*Type] 711 712 // readAndInflateTypes reads the raw btf type info and turns it into a graph 713 // of Types connected via pointers. 714 // 715 // If base is provided, then the types are considered to be of a split BTF 716 // (e.g., a kernel module). 717 // 718 // Returns a slice of types indexed by TypeID. Since BTF ignores compilation 719 // units, multiple types may share the same name. A Type may form a cyclic graph 720 // by pointing at itself. 721 func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawStrings *stringTable, base *Spec) ([]Type, error) { 722 // because of the interleaving between types and struct members it is difficult to 723 // precompute the numbers of raw types this will parse 724 // this "guess" is a good first estimation 725 sizeOfbtfType := uintptr(btfTypeLen) 726 tyMaxCount := uintptr(typeLen) / sizeOfbtfType / 2 727 types := make([]Type, 0, tyMaxCount) 728 729 // Void is defined to always be type ID 0, and is thus omitted from BTF. 730 types = append(types, (*Void)(nil)) 731 732 firstTypeID := TypeID(0) 733 if base != nil { 734 var err error 735 firstTypeID, err = base.nextTypeID() 736 if err != nil { 737 return nil, err 738 } 739 740 // Split BTF doesn't contain Void. 741 types = types[:0] 742 } 743 744 type fixupDef struct { 745 id TypeID 746 typ *Type 747 } 748 749 var fixups []fixupDef 750 fixup := func(id TypeID, typ *Type) { 751 if id < firstTypeID { 752 if baseType, err := base.TypeByID(id); err == nil { 753 *typ = baseType 754 return 755 } 756 } 757 758 idx := int(id - firstTypeID) 759 if idx < len(types) { 760 // We've already inflated this type, fix it up immediately. 761 *typ = types[idx] 762 return 763 } 764 765 fixups = append(fixups, fixupDef{id, typ}) 766 } 767 768 type bitfieldFixupDef struct { 769 id TypeID 770 m *Member 771 } 772 773 var ( 774 legacyBitfields = make(map[TypeID][2]Bits) // offset, size 775 bitfieldFixups []bitfieldFixupDef 776 ) 777 convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) { 778 // NB: The fixup below relies on pre-allocating this array to 779 // work, since otherwise append might re-allocate members. 780 members := make([]Member, 0, len(raw)) 781 for i, btfMember := range raw { 782 name, err := rawStrings.Lookup(btfMember.NameOff) 783 if err != nil { 784 return nil, fmt.Errorf("can't get name for member %d: %w", i, err) 785 } 786 787 members = append(members, Member{ 788 Name: name, 789 Offset: Bits(btfMember.Offset), 790 }) 791 792 m := &members[i] 793 fixup(raw[i].Type, &m.Type) 794 795 if kindFlag { 796 m.BitfieldSize = Bits(btfMember.Offset >> 24) 797 m.Offset &= 0xffffff 798 // We ignore legacy bitfield definitions if the current composite 799 // is a new-style bitfield. This is kind of safe since offset and 800 // size on the type of the member must be zero if kindFlat is set 801 // according to spec. 802 continue 803 } 804 805 // This may be a legacy bitfield, try to fix it up. 806 data, ok := legacyBitfields[raw[i].Type] 807 if ok { 808 // Bingo! 809 m.Offset += data[0] 810 m.BitfieldSize = data[1] 811 continue 812 } 813 814 if m.Type != nil { 815 // We couldn't find a legacy bitfield, but we know that the member's 816 // type has already been inflated. Hence we know that it can't be 817 // a legacy bitfield and there is nothing left to do. 818 continue 819 } 820 821 // We don't have fixup data, and the type we're pointing 822 // at hasn't been inflated yet. No choice but to defer 823 // the fixup. 824 bitfieldFixups = append(bitfieldFixups, bitfieldFixupDef{ 825 raw[i].Type, 826 m, 827 }) 828 } 829 return members, nil 830 } 831 832 var ( 833 buf = make([]byte, 1024) 834 header btfType 835 bInt btfInt 836 bArr btfArray 837 bMembers []btfMember 838 bEnums []btfEnum 839 bParams []btfParam 840 bVariable btfVariable 841 bSecInfos []btfVarSecinfo 842 bDeclTag btfDeclTag 843 bEnums64 []btfEnum64 844 ) 845 846 var declTags []*declTag 847 for { 848 var ( 849 id = firstTypeID + TypeID(len(types)) 850 typ Type 851 ) 852 853 if _, err := io.ReadFull(r, buf[:btfTypeLen]); err == io.EOF { 854 break 855 } else if err != nil { 856 return nil, fmt.Errorf("can't read type info for id %v: %v", id, err) 857 } 858 859 if _, err := unmarshalBtfType(&header, buf[:btfTypeLen], bo); err != nil { 860 return nil, fmt.Errorf("can't unmarshal type info for id %v: %v", id, err) 861 } 862 863 if id < firstTypeID { 864 return nil, fmt.Errorf("no more type IDs") 865 } 866 867 name, err := rawStrings.Lookup(header.NameOff) 868 if err != nil { 869 return nil, fmt.Errorf("get name for type id %d: %w", id, err) 870 } 871 872 switch header.Kind() { 873 case kindInt: 874 size := header.Size() 875 buf = buf[:btfIntLen] 876 if _, err := io.ReadFull(r, buf); err != nil { 877 return nil, fmt.Errorf("can't read btfInt, id: %d: %w", id, err) 878 } 879 if _, err := unmarshalBtfInt(&bInt, buf, bo); err != nil { 880 return nil, fmt.Errorf("can't unmarshal btfInt, id: %d: %w", id, err) 881 } 882 if bInt.Offset() > 0 || bInt.Bits().Bytes() != size { 883 legacyBitfields[id] = [2]Bits{bInt.Offset(), bInt.Bits()} 884 } 885 typ = &Int{name, header.Size(), bInt.Encoding()} 886 887 case kindPointer: 888 ptr := &Pointer{nil} 889 fixup(header.Type(), &ptr.Target) 890 typ = ptr 891 892 case kindArray: 893 buf = buf[:btfArrayLen] 894 if _, err := io.ReadFull(r, buf); err != nil { 895 return nil, fmt.Errorf("can't read btfArray, id: %d: %w", id, err) 896 } 897 if _, err := unmarshalBtfArray(&bArr, buf, bo); err != nil { 898 return nil, fmt.Errorf("can't unmarshal btfArray, id: %d: %w", id, err) 899 } 900 901 arr := &Array{nil, nil, bArr.Nelems} 902 fixup(bArr.IndexType, &arr.Index) 903 fixup(bArr.Type, &arr.Type) 904 typ = arr 905 906 case kindStruct: 907 vlen := header.Vlen() 908 bMembers = slices.Grow(bMembers[:0], vlen)[:vlen] 909 buf = slices.Grow(buf[:0], vlen*btfMemberLen)[:vlen*btfMemberLen] 910 if _, err := io.ReadFull(r, buf); err != nil { 911 return nil, fmt.Errorf("can't read btfMembers, id: %d: %w", id, err) 912 } 913 if _, err := unmarshalBtfMembers(bMembers, buf, bo); err != nil { 914 return nil, fmt.Errorf("can't unmarshal btfMembers, id: %d: %w", id, err) 915 } 916 917 members, err := convertMembers(bMembers, header.Bitfield()) 918 if err != nil { 919 return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) 920 } 921 typ = &Struct{name, header.Size(), members} 922 923 case kindUnion: 924 vlen := header.Vlen() 925 bMembers = slices.Grow(bMembers[:0], vlen)[:vlen] 926 buf = slices.Grow(buf[:0], vlen*btfMemberLen)[:vlen*btfMemberLen] 927 if _, err := io.ReadFull(r, buf); err != nil { 928 return nil, fmt.Errorf("can't read btfMembers, id: %d: %w", id, err) 929 } 930 if _, err := unmarshalBtfMembers(bMembers, buf, bo); err != nil { 931 return nil, fmt.Errorf("can't unmarshal btfMembers, id: %d: %w", id, err) 932 } 933 934 members, err := convertMembers(bMembers, header.Bitfield()) 935 if err != nil { 936 return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) 937 } 938 typ = &Union{name, header.Size(), members} 939 940 case kindEnum: 941 vlen := header.Vlen() 942 bEnums = slices.Grow(bEnums[:0], vlen)[:vlen] 943 buf = slices.Grow(buf[:0], vlen*btfEnumLen)[:vlen*btfEnumLen] 944 if _, err := io.ReadFull(r, buf); err != nil { 945 return nil, fmt.Errorf("can't read btfEnums, id: %d: %w", id, err) 946 } 947 if _, err := unmarshalBtfEnums(bEnums, buf, bo); err != nil { 948 return nil, fmt.Errorf("can't unmarshal btfEnums, id: %d: %w", id, err) 949 } 950 951 vals := make([]EnumValue, 0, vlen) 952 signed := header.Signed() 953 for i, btfVal := range bEnums { 954 name, err := rawStrings.Lookup(btfVal.NameOff) 955 if err != nil { 956 return nil, fmt.Errorf("get name for enum value %d: %s", i, err) 957 } 958 value := uint64(btfVal.Val) 959 if signed { 960 // Sign extend values to 64 bit. 961 value = uint64(int32(btfVal.Val)) 962 } 963 vals = append(vals, EnumValue{name, value}) 964 } 965 typ = &Enum{name, header.Size(), signed, vals} 966 967 case kindForward: 968 typ = &Fwd{name, header.FwdKind()} 969 970 case kindTypedef: 971 typedef := &Typedef{name, nil} 972 fixup(header.Type(), &typedef.Type) 973 typ = typedef 974 975 case kindVolatile: 976 volatile := &Volatile{nil} 977 fixup(header.Type(), &volatile.Type) 978 typ = volatile 979 980 case kindConst: 981 cnst := &Const{nil} 982 fixup(header.Type(), &cnst.Type) 983 typ = cnst 984 985 case kindRestrict: 986 restrict := &Restrict{nil} 987 fixup(header.Type(), &restrict.Type) 988 typ = restrict 989 990 case kindFunc: 991 fn := &Func{name, nil, header.Linkage()} 992 fixup(header.Type(), &fn.Type) 993 typ = fn 994 995 case kindFuncProto: 996 vlen := header.Vlen() 997 bParams = slices.Grow(bParams[:0], vlen)[:vlen] 998 buf = slices.Grow(buf[:0], vlen*btfParamLen)[:vlen*btfParamLen] 999 if _, err := io.ReadFull(r, buf); err != nil { 1000 return nil, fmt.Errorf("can't read btfParams, id: %d: %w", id, err) 1001 } 1002 if _, err := unmarshalBtfParams(bParams, buf, bo); err != nil { 1003 return nil, fmt.Errorf("can't unmarshal btfParams, id: %d: %w", id, err) 1004 } 1005 1006 params := make([]FuncParam, 0, vlen) 1007 for i, param := range bParams { 1008 name, err := rawStrings.Lookup(param.NameOff) 1009 if err != nil { 1010 return nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err) 1011 } 1012 params = append(params, FuncParam{ 1013 Name: name, 1014 }) 1015 } 1016 for i := range params { 1017 fixup(bParams[i].Type, ¶ms[i].Type) 1018 } 1019 1020 fp := &FuncProto{nil, params} 1021 fixup(header.Type(), &fp.Return) 1022 typ = fp 1023 1024 case kindVar: 1025 buf = buf[:btfVariableLen] 1026 if _, err := io.ReadFull(r, buf); err != nil { 1027 return nil, fmt.Errorf("can't read btfVariable, id: %d: %w", id, err) 1028 } 1029 if _, err := unmarshalBtfVariable(&bVariable, buf, bo); err != nil { 1030 return nil, fmt.Errorf("can't read btfVariable, id: %d: %w", id, err) 1031 } 1032 1033 v := &Var{name, nil, VarLinkage(bVariable.Linkage)} 1034 fixup(header.Type(), &v.Type) 1035 typ = v 1036 1037 case kindDatasec: 1038 vlen := header.Vlen() 1039 bSecInfos = slices.Grow(bSecInfos[:0], vlen)[:vlen] 1040 buf = slices.Grow(buf[:0], vlen*btfVarSecinfoLen)[:vlen*btfVarSecinfoLen] 1041 if _, err := io.ReadFull(r, buf); err != nil { 1042 return nil, fmt.Errorf("can't read btfVarSecInfos, id: %d: %w", id, err) 1043 } 1044 if _, err := unmarshalBtfVarSecInfos(bSecInfos, buf, bo); err != nil { 1045 return nil, fmt.Errorf("can't unmarshal btfVarSecInfos, id: %d: %w", id, err) 1046 } 1047 1048 vars := make([]VarSecinfo, 0, vlen) 1049 for _, btfVar := range bSecInfos { 1050 vars = append(vars, VarSecinfo{ 1051 Offset: btfVar.Offset, 1052 Size: btfVar.Size, 1053 }) 1054 } 1055 for i := range vars { 1056 fixup(bSecInfos[i].Type, &vars[i].Type) 1057 } 1058 typ = &Datasec{name, header.Size(), vars} 1059 1060 case kindFloat: 1061 typ = &Float{name, header.Size()} 1062 1063 case kindDeclTag: 1064 buf = buf[:btfDeclTagLen] 1065 if _, err := io.ReadFull(r, buf); err != nil { 1066 return nil, fmt.Errorf("can't read btfDeclTag, id: %d: %w", id, err) 1067 } 1068 if _, err := unmarshalBtfDeclTag(&bDeclTag, buf, bo); err != nil { 1069 return nil, fmt.Errorf("can't read btfDeclTag, id: %d: %w", id, err) 1070 } 1071 1072 btfIndex := bDeclTag.ComponentIdx 1073 if uint64(btfIndex) > math.MaxInt { 1074 return nil, fmt.Errorf("type id %d: index exceeds int", id) 1075 } 1076 1077 dt := &declTag{nil, name, int(int32(btfIndex))} 1078 fixup(header.Type(), &dt.Type) 1079 typ = dt 1080 1081 declTags = append(declTags, dt) 1082 1083 case kindTypeTag: 1084 tt := &typeTag{nil, name} 1085 fixup(header.Type(), &tt.Type) 1086 typ = tt 1087 1088 case kindEnum64: 1089 vlen := header.Vlen() 1090 bEnums64 = slices.Grow(bEnums64[:0], vlen)[:vlen] 1091 buf = slices.Grow(buf[:0], vlen*btfEnum64Len)[:vlen*btfEnum64Len] 1092 if _, err := io.ReadFull(r, buf); err != nil { 1093 return nil, fmt.Errorf("can't read btfEnum64s, id: %d: %w", id, err) 1094 } 1095 if _, err := unmarshalBtfEnums64(bEnums64, buf, bo); err != nil { 1096 return nil, fmt.Errorf("can't unmarshal btfEnum64s, id: %d: %w", id, err) 1097 } 1098 1099 vals := make([]EnumValue, 0, vlen) 1100 for i, btfVal := range bEnums64 { 1101 name, err := rawStrings.Lookup(btfVal.NameOff) 1102 if err != nil { 1103 return nil, fmt.Errorf("get name for enum64 value %d: %s", i, err) 1104 } 1105 value := (uint64(btfVal.ValHi32) << 32) | uint64(btfVal.ValLo32) 1106 vals = append(vals, EnumValue{name, value}) 1107 } 1108 typ = &Enum{name, header.Size(), header.Signed(), vals} 1109 1110 default: 1111 return nil, fmt.Errorf("type id %d: unknown kind: %v", id, header.Kind()) 1112 } 1113 1114 types = append(types, typ) 1115 } 1116 1117 for _, fixup := range fixups { 1118 if fixup.id < firstTypeID { 1119 return nil, fmt.Errorf("fixup for base type id %d is not expected", fixup.id) 1120 } 1121 1122 idx := int(fixup.id - firstTypeID) 1123 if idx >= len(types) { 1124 return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) 1125 } 1126 1127 *fixup.typ = types[idx] 1128 } 1129 1130 for _, bitfieldFixup := range bitfieldFixups { 1131 if bitfieldFixup.id < firstTypeID { 1132 return nil, fmt.Errorf("bitfield fixup from split to base types is not expected") 1133 } 1134 1135 data, ok := legacyBitfields[bitfieldFixup.id] 1136 if ok { 1137 // This is indeed a legacy bitfield, fix it up. 1138 bitfieldFixup.m.Offset += data[0] 1139 bitfieldFixup.m.BitfieldSize = data[1] 1140 } 1141 } 1142 1143 for _, dt := range declTags { 1144 switch t := dt.Type.(type) { 1145 case *Var, *Typedef: 1146 if dt.Index != -1 { 1147 return nil, fmt.Errorf("type %s: index %d is not -1", dt, dt.Index) 1148 } 1149 1150 case composite: 1151 if dt.Index >= len(t.members()) { 1152 return nil, fmt.Errorf("type %s: index %d exceeds members of %s", dt, dt.Index, t) 1153 } 1154 1155 case *Func: 1156 fp, ok := t.Type.(*FuncProto) 1157 if !ok { 1158 return nil, fmt.Errorf("type %s: %s is not a FuncProto", dt, t.Type) 1159 } 1160 1161 if dt.Index >= len(fp.Params) { 1162 return nil, fmt.Errorf("type %s: index %d exceeds params of %s", dt, dt.Index, t) 1163 } 1164 1165 default: 1166 return nil, fmt.Errorf("type %s: decl tag for type %s is not supported", dt, t) 1167 } 1168 } 1169 1170 return types, nil 1171 } 1172 1173 // essentialName represents the name of a BTF type stripped of any flavor 1174 // suffixes after a ___ delimiter. 1175 type essentialName string 1176 1177 // newEssentialName returns name without a ___ suffix. 1178 // 1179 // CO-RE has the concept of 'struct flavors', which are used to deal with 1180 // changes in kernel data structures. Anything after three underscores 1181 // in a type name is ignored for the purpose of finding a candidate type 1182 // in the kernel's BTF. 1183 func newEssentialName(name string) essentialName { 1184 if name == "" { 1185 return "" 1186 } 1187 lastIdx := strings.LastIndex(name, "___") 1188 if lastIdx > 0 { 1189 return essentialName(name[:lastIdx]) 1190 } 1191 return essentialName(name) 1192 } 1193 1194 // UnderlyingType skips qualifiers and Typedefs. 1195 func UnderlyingType(typ Type) Type { 1196 result := typ 1197 for depth := 0; depth <= maxResolveDepth; depth++ { 1198 switch v := (result).(type) { 1199 case qualifier: 1200 result = v.qualify() 1201 case *Typedef: 1202 result = v.Type 1203 default: 1204 return result 1205 } 1206 } 1207 return &cycle{typ} 1208 } 1209 1210 // As returns typ if is of type T. Otherwise it peels qualifiers and Typedefs 1211 // until it finds a T. 1212 // 1213 // Returns the zero value and false if there is no T or if the type is nested 1214 // too deeply. 1215 func As[T Type](typ Type) (T, bool) { 1216 // NB: We can't make this function return (*T) since then 1217 // we can't assert that a type matches an interface which 1218 // embeds Type: as[composite](T). 1219 for depth := 0; depth <= maxResolveDepth; depth++ { 1220 switch v := (typ).(type) { 1221 case T: 1222 return v, true 1223 case qualifier: 1224 typ = v.qualify() 1225 case *Typedef: 1226 typ = v.Type 1227 default: 1228 goto notFound 1229 } 1230 } 1231 notFound: 1232 var zero T 1233 return zero, false 1234 } 1235 1236 type formatState struct { 1237 fmt.State 1238 depth int 1239 } 1240 1241 // formattableType is a subset of Type, to ease unit testing of formatType. 1242 type formattableType interface { 1243 fmt.Formatter 1244 TypeName() string 1245 } 1246 1247 // formatType formats a type in a canonical form. 1248 // 1249 // Handles cyclical types by only printing cycles up to a certain depth. Elements 1250 // in extra are separated by spaces unless the preceding element is a string 1251 // ending in '='. 1252 func formatType(f fmt.State, verb rune, t formattableType, extra ...interface{}) { 1253 if verb != 'v' && verb != 's' { 1254 fmt.Fprintf(f, "{UNRECOGNIZED: %c}", verb) 1255 return 1256 } 1257 1258 _, _ = io.WriteString(f, internal.GoTypeName(t)) 1259 1260 if name := t.TypeName(); name != "" { 1261 // Output BTF type name if present. 1262 fmt.Fprintf(f, ":%q", name) 1263 } 1264 1265 if f.Flag('+') { 1266 // Output address if requested. 1267 fmt.Fprintf(f, ":%#p", t) 1268 } 1269 1270 if verb == 's' { 1271 // %s omits details. 1272 return 1273 } 1274 1275 var depth int 1276 if ps, ok := f.(*formatState); ok { 1277 depth = ps.depth 1278 f = ps.State 1279 } 1280 1281 maxDepth, ok := f.Width() 1282 if !ok { 1283 maxDepth = 0 1284 } 1285 1286 if depth > maxDepth { 1287 // We've reached the maximum depth. This avoids infinite recursion even 1288 // for cyclical types. 1289 return 1290 } 1291 1292 if len(extra) == 0 { 1293 return 1294 } 1295 1296 wantSpace := false 1297 _, _ = io.WriteString(f, "[") 1298 for _, arg := range extra { 1299 if wantSpace { 1300 _, _ = io.WriteString(f, " ") 1301 } 1302 1303 switch v := arg.(type) { 1304 case string: 1305 _, _ = io.WriteString(f, v) 1306 wantSpace = len(v) > 0 && v[len(v)-1] != '=' 1307 continue 1308 1309 case formattableType: 1310 v.Format(&formatState{f, depth + 1}, verb) 1311 1312 default: 1313 fmt.Fprint(f, arg) 1314 } 1315 1316 wantSpace = true 1317 } 1318 _, _ = io.WriteString(f, "]") 1319 }