github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/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 cpy, ok := copies[typ] 686 if ok { 687 // This has been copied previously, no need to continue. 688 return cpy 689 } 690 691 cpy = typ.copy() 692 copies[typ] = cpy 693 694 if id, ok := ids[typ]; ok { 695 copiedIDs[cpy] = id 696 } 697 698 children(cpy, func(child *Type) bool { 699 *child = copyType(*child, ids, copies, copiedIDs) 700 return true 701 }) 702 703 return cpy 704 } 705 706 type typeDeque = internal.Deque[*Type] 707 708 // readAndInflateTypes reads the raw btf type info and turns it into a graph 709 // of Types connected via pointers. 710 // 711 // If base is provided, then the types are considered to be of a split BTF 712 // (e.g., a kernel module). 713 // 714 // Returns a slice of types indexed by TypeID. Since BTF ignores compilation 715 // units, multiple types may share the same name. A Type may form a cyclic graph 716 // by pointing at itself. 717 func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawStrings *stringTable, base *Spec) ([]Type, error) { 718 // because of the interleaving between types and struct members it is difficult to 719 // precompute the numbers of raw types this will parse 720 // this "guess" is a good first estimation 721 sizeOfbtfType := uintptr(btfTypeLen) 722 tyMaxCount := uintptr(typeLen) / sizeOfbtfType / 2 723 types := make([]Type, 0, tyMaxCount) 724 725 // Void is defined to always be type ID 0, and is thus omitted from BTF. 726 types = append(types, (*Void)(nil)) 727 728 firstTypeID := TypeID(0) 729 if base != nil { 730 var err error 731 firstTypeID, err = base.nextTypeID() 732 if err != nil { 733 return nil, err 734 } 735 736 // Split BTF doesn't contain Void. 737 types = types[:0] 738 } 739 740 type fixupDef struct { 741 id TypeID 742 typ *Type 743 } 744 745 var fixups []fixupDef 746 fixup := func(id TypeID, typ *Type) { 747 if id < firstTypeID { 748 if baseType, err := base.TypeByID(id); err == nil { 749 *typ = baseType 750 return 751 } 752 } 753 754 idx := int(id - firstTypeID) 755 if idx < len(types) { 756 // We've already inflated this type, fix it up immediately. 757 *typ = types[idx] 758 return 759 } 760 761 fixups = append(fixups, fixupDef{id, typ}) 762 } 763 764 type bitfieldFixupDef struct { 765 id TypeID 766 m *Member 767 } 768 769 var ( 770 legacyBitfields = make(map[TypeID][2]Bits) // offset, size 771 bitfieldFixups []bitfieldFixupDef 772 ) 773 convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) { 774 // NB: The fixup below relies on pre-allocating this array to 775 // work, since otherwise append might re-allocate members. 776 members := make([]Member, 0, len(raw)) 777 for i, btfMember := range raw { 778 name, err := rawStrings.Lookup(btfMember.NameOff) 779 if err != nil { 780 return nil, fmt.Errorf("can't get name for member %d: %w", i, err) 781 } 782 783 members = append(members, Member{ 784 Name: name, 785 Offset: Bits(btfMember.Offset), 786 }) 787 788 m := &members[i] 789 fixup(raw[i].Type, &m.Type) 790 791 if kindFlag { 792 m.BitfieldSize = Bits(btfMember.Offset >> 24) 793 m.Offset &= 0xffffff 794 // We ignore legacy bitfield definitions if the current composite 795 // is a new-style bitfield. This is kind of safe since offset and 796 // size on the type of the member must be zero if kindFlat is set 797 // according to spec. 798 continue 799 } 800 801 // This may be a legacy bitfield, try to fix it up. 802 data, ok := legacyBitfields[raw[i].Type] 803 if ok { 804 // Bingo! 805 m.Offset += data[0] 806 m.BitfieldSize = data[1] 807 continue 808 } 809 810 if m.Type != nil { 811 // We couldn't find a legacy bitfield, but we know that the member's 812 // type has already been inflated. Hence we know that it can't be 813 // a legacy bitfield and there is nothing left to do. 814 continue 815 } 816 817 // We don't have fixup data, and the type we're pointing 818 // at hasn't been inflated yet. No choice but to defer 819 // the fixup. 820 bitfieldFixups = append(bitfieldFixups, bitfieldFixupDef{ 821 raw[i].Type, 822 m, 823 }) 824 } 825 return members, nil 826 } 827 828 var ( 829 buf = make([]byte, 1024) 830 header btfType 831 bInt btfInt 832 bArr btfArray 833 bMembers []btfMember 834 bEnums []btfEnum 835 bParams []btfParam 836 bVariable btfVariable 837 bSecInfos []btfVarSecinfo 838 bDeclTag btfDeclTag 839 bEnums64 []btfEnum64 840 ) 841 842 var declTags []*declTag 843 for { 844 var ( 845 id = firstTypeID + TypeID(len(types)) 846 typ Type 847 ) 848 849 if _, err := io.ReadFull(r, buf[:btfTypeLen]); err == io.EOF { 850 break 851 } else if err != nil { 852 return nil, fmt.Errorf("can't read type info for id %v: %v", id, err) 853 } 854 855 if _, err := unmarshalBtfType(&header, buf[:btfTypeLen], bo); err != nil { 856 return nil, fmt.Errorf("can't unmarshal type info for id %v: %v", id, err) 857 } 858 859 if id < firstTypeID { 860 return nil, fmt.Errorf("no more type IDs") 861 } 862 863 name, err := rawStrings.Lookup(header.NameOff) 864 if err != nil { 865 return nil, fmt.Errorf("get name for type id %d: %w", id, err) 866 } 867 868 switch header.Kind() { 869 case kindInt: 870 size := header.Size() 871 buf = buf[:btfIntLen] 872 if _, err := io.ReadFull(r, buf); err != nil { 873 return nil, fmt.Errorf("can't read btfInt, id: %d: %w", id, err) 874 } 875 if _, err := unmarshalBtfInt(&bInt, buf, bo); err != nil { 876 return nil, fmt.Errorf("can't unmarshal btfInt, id: %d: %w", id, err) 877 } 878 if bInt.Offset() > 0 || bInt.Bits().Bytes() != size { 879 legacyBitfields[id] = [2]Bits{bInt.Offset(), bInt.Bits()} 880 } 881 typ = &Int{name, header.Size(), bInt.Encoding()} 882 883 case kindPointer: 884 ptr := &Pointer{nil} 885 fixup(header.Type(), &ptr.Target) 886 typ = ptr 887 888 case kindArray: 889 buf = buf[:btfArrayLen] 890 if _, err := io.ReadFull(r, buf); err != nil { 891 return nil, fmt.Errorf("can't read btfArray, id: %d: %w", id, err) 892 } 893 if _, err := unmarshalBtfArray(&bArr, buf, bo); err != nil { 894 return nil, fmt.Errorf("can't unmarshal btfArray, id: %d: %w", id, err) 895 } 896 897 arr := &Array{nil, nil, bArr.Nelems} 898 fixup(bArr.IndexType, &arr.Index) 899 fixup(bArr.Type, &arr.Type) 900 typ = arr 901 902 case kindStruct: 903 vlen := header.Vlen() 904 bMembers = slices.Grow(bMembers[:0], vlen)[:vlen] 905 buf = slices.Grow(buf[:0], vlen*btfMemberLen)[:vlen*btfMemberLen] 906 if _, err := io.ReadFull(r, buf); err != nil { 907 return nil, fmt.Errorf("can't read btfMembers, id: %d: %w", id, err) 908 } 909 if _, err := unmarshalBtfMembers(bMembers, buf, bo); err != nil { 910 return nil, fmt.Errorf("can't unmarshal btfMembers, id: %d: %w", id, err) 911 } 912 913 members, err := convertMembers(bMembers, header.Bitfield()) 914 if err != nil { 915 return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) 916 } 917 typ = &Struct{name, header.Size(), members} 918 919 case kindUnion: 920 vlen := header.Vlen() 921 bMembers = slices.Grow(bMembers[:0], vlen)[:vlen] 922 buf = slices.Grow(buf[:0], vlen*btfMemberLen)[:vlen*btfMemberLen] 923 if _, err := io.ReadFull(r, buf); err != nil { 924 return nil, fmt.Errorf("can't read btfMembers, id: %d: %w", id, err) 925 } 926 if _, err := unmarshalBtfMembers(bMembers, buf, bo); err != nil { 927 return nil, fmt.Errorf("can't unmarshal btfMembers, id: %d: %w", id, err) 928 } 929 930 members, err := convertMembers(bMembers, header.Bitfield()) 931 if err != nil { 932 return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) 933 } 934 typ = &Union{name, header.Size(), members} 935 936 case kindEnum: 937 vlen := header.Vlen() 938 bEnums = slices.Grow(bEnums[:0], vlen)[:vlen] 939 buf = slices.Grow(buf[:0], vlen*btfEnumLen)[:vlen*btfEnumLen] 940 if _, err := io.ReadFull(r, buf); err != nil { 941 return nil, fmt.Errorf("can't read btfEnums, id: %d: %w", id, err) 942 } 943 if _, err := unmarshalBtfEnums(bEnums, buf, bo); err != nil { 944 return nil, fmt.Errorf("can't unmarshal btfEnums, id: %d: %w", id, err) 945 } 946 947 vals := make([]EnumValue, 0, vlen) 948 signed := header.Signed() 949 for i, btfVal := range bEnums { 950 name, err := rawStrings.Lookup(btfVal.NameOff) 951 if err != nil { 952 return nil, fmt.Errorf("get name for enum value %d: %s", i, err) 953 } 954 value := uint64(btfVal.Val) 955 if signed { 956 // Sign extend values to 64 bit. 957 value = uint64(int32(btfVal.Val)) 958 } 959 vals = append(vals, EnumValue{name, value}) 960 } 961 typ = &Enum{name, header.Size(), signed, vals} 962 963 case kindForward: 964 typ = &Fwd{name, header.FwdKind()} 965 966 case kindTypedef: 967 typedef := &Typedef{name, nil} 968 fixup(header.Type(), &typedef.Type) 969 typ = typedef 970 971 case kindVolatile: 972 volatile := &Volatile{nil} 973 fixup(header.Type(), &volatile.Type) 974 typ = volatile 975 976 case kindConst: 977 cnst := &Const{nil} 978 fixup(header.Type(), &cnst.Type) 979 typ = cnst 980 981 case kindRestrict: 982 restrict := &Restrict{nil} 983 fixup(header.Type(), &restrict.Type) 984 typ = restrict 985 986 case kindFunc: 987 fn := &Func{name, nil, header.Linkage()} 988 fixup(header.Type(), &fn.Type) 989 typ = fn 990 991 case kindFuncProto: 992 vlen := header.Vlen() 993 bParams = slices.Grow(bParams[:0], vlen)[:vlen] 994 buf = slices.Grow(buf[:0], vlen*btfParamLen)[:vlen*btfParamLen] 995 if _, err := io.ReadFull(r, buf); err != nil { 996 return nil, fmt.Errorf("can't read btfParams, id: %d: %w", id, err) 997 } 998 if _, err := unmarshalBtfParams(bParams, buf, bo); err != nil { 999 return nil, fmt.Errorf("can't unmarshal btfParams, id: %d: %w", id, err) 1000 } 1001 1002 params := make([]FuncParam, 0, vlen) 1003 for i, param := range bParams { 1004 name, err := rawStrings.Lookup(param.NameOff) 1005 if err != nil { 1006 return nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err) 1007 } 1008 params = append(params, FuncParam{ 1009 Name: name, 1010 }) 1011 } 1012 for i := range params { 1013 fixup(bParams[i].Type, ¶ms[i].Type) 1014 } 1015 1016 fp := &FuncProto{nil, params} 1017 fixup(header.Type(), &fp.Return) 1018 typ = fp 1019 1020 case kindVar: 1021 buf = buf[:btfVariableLen] 1022 if _, err := io.ReadFull(r, buf); err != nil { 1023 return nil, fmt.Errorf("can't read btfVariable, id: %d: %w", id, err) 1024 } 1025 if _, err := unmarshalBtfVariable(&bVariable, buf, bo); err != nil { 1026 return nil, fmt.Errorf("can't read btfVariable, id: %d: %w", id, err) 1027 } 1028 1029 v := &Var{name, nil, VarLinkage(bVariable.Linkage)} 1030 fixup(header.Type(), &v.Type) 1031 typ = v 1032 1033 case kindDatasec: 1034 vlen := header.Vlen() 1035 bSecInfos = slices.Grow(bSecInfos[:0], vlen)[:vlen] 1036 buf = slices.Grow(buf[:0], vlen*btfVarSecinfoLen)[:vlen*btfVarSecinfoLen] 1037 if _, err := io.ReadFull(r, buf); err != nil { 1038 return nil, fmt.Errorf("can't read btfVarSecInfos, id: %d: %w", id, err) 1039 } 1040 if _, err := unmarshalBtfVarSecInfos(bSecInfos, buf, bo); err != nil { 1041 return nil, fmt.Errorf("can't unmarshal btfVarSecInfos, id: %d: %w", id, err) 1042 } 1043 1044 vars := make([]VarSecinfo, 0, vlen) 1045 for _, btfVar := range bSecInfos { 1046 vars = append(vars, VarSecinfo{ 1047 Offset: btfVar.Offset, 1048 Size: btfVar.Size, 1049 }) 1050 } 1051 for i := range vars { 1052 fixup(bSecInfos[i].Type, &vars[i].Type) 1053 } 1054 typ = &Datasec{name, header.Size(), vars} 1055 1056 case kindFloat: 1057 typ = &Float{name, header.Size()} 1058 1059 case kindDeclTag: 1060 buf = buf[:btfDeclTagLen] 1061 if _, err := io.ReadFull(r, buf); err != nil { 1062 return nil, fmt.Errorf("can't read btfDeclTag, id: %d: %w", id, err) 1063 } 1064 if _, err := unmarshalBtfDeclTag(&bDeclTag, buf, bo); err != nil { 1065 return nil, fmt.Errorf("can't read btfDeclTag, id: %d: %w", id, err) 1066 } 1067 1068 btfIndex := bDeclTag.ComponentIdx 1069 if uint64(btfIndex) > math.MaxInt { 1070 return nil, fmt.Errorf("type id %d: index exceeds int", id) 1071 } 1072 1073 dt := &declTag{nil, name, int(int32(btfIndex))} 1074 fixup(header.Type(), &dt.Type) 1075 typ = dt 1076 1077 declTags = append(declTags, dt) 1078 1079 case kindTypeTag: 1080 tt := &typeTag{nil, name} 1081 fixup(header.Type(), &tt.Type) 1082 typ = tt 1083 1084 case kindEnum64: 1085 vlen := header.Vlen() 1086 bEnums64 = slices.Grow(bEnums64[:0], vlen)[:vlen] 1087 buf = slices.Grow(buf[:0], vlen*btfEnum64Len)[:vlen*btfEnum64Len] 1088 if _, err := io.ReadFull(r, buf); err != nil { 1089 return nil, fmt.Errorf("can't read btfEnum64s, id: %d: %w", id, err) 1090 } 1091 if _, err := unmarshalBtfEnums64(bEnums64, buf, bo); err != nil { 1092 return nil, fmt.Errorf("can't unmarshal btfEnum64s, id: %d: %w", id, err) 1093 } 1094 1095 vals := make([]EnumValue, 0, vlen) 1096 for i, btfVal := range bEnums64 { 1097 name, err := rawStrings.Lookup(btfVal.NameOff) 1098 if err != nil { 1099 return nil, fmt.Errorf("get name for enum64 value %d: %s", i, err) 1100 } 1101 value := (uint64(btfVal.ValHi32) << 32) | uint64(btfVal.ValLo32) 1102 vals = append(vals, EnumValue{name, value}) 1103 } 1104 typ = &Enum{name, header.Size(), header.Signed(), vals} 1105 1106 default: 1107 return nil, fmt.Errorf("type id %d: unknown kind: %v", id, header.Kind()) 1108 } 1109 1110 types = append(types, typ) 1111 } 1112 1113 for _, fixup := range fixups { 1114 if fixup.id < firstTypeID { 1115 return nil, fmt.Errorf("fixup for base type id %d is not expected", fixup.id) 1116 } 1117 1118 idx := int(fixup.id - firstTypeID) 1119 if idx >= len(types) { 1120 return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) 1121 } 1122 1123 *fixup.typ = types[idx] 1124 } 1125 1126 for _, bitfieldFixup := range bitfieldFixups { 1127 if bitfieldFixup.id < firstTypeID { 1128 return nil, fmt.Errorf("bitfield fixup from split to base types is not expected") 1129 } 1130 1131 data, ok := legacyBitfields[bitfieldFixup.id] 1132 if ok { 1133 // This is indeed a legacy bitfield, fix it up. 1134 bitfieldFixup.m.Offset += data[0] 1135 bitfieldFixup.m.BitfieldSize = data[1] 1136 } 1137 } 1138 1139 for _, dt := range declTags { 1140 switch t := dt.Type.(type) { 1141 case *Var, *Typedef: 1142 if dt.Index != -1 { 1143 return nil, fmt.Errorf("type %s: index %d is not -1", dt, dt.Index) 1144 } 1145 1146 case composite: 1147 if dt.Index >= len(t.members()) { 1148 return nil, fmt.Errorf("type %s: index %d exceeds members of %s", dt, dt.Index, t) 1149 } 1150 1151 case *Func: 1152 fp, ok := t.Type.(*FuncProto) 1153 if !ok { 1154 return nil, fmt.Errorf("type %s: %s is not a FuncProto", dt, t.Type) 1155 } 1156 1157 if dt.Index >= len(fp.Params) { 1158 return nil, fmt.Errorf("type %s: index %d exceeds params of %s", dt, dt.Index, t) 1159 } 1160 1161 default: 1162 return nil, fmt.Errorf("type %s: decl tag for type %s is not supported", dt, t) 1163 } 1164 } 1165 1166 return types, nil 1167 } 1168 1169 // essentialName represents the name of a BTF type stripped of any flavor 1170 // suffixes after a ___ delimiter. 1171 type essentialName string 1172 1173 // newEssentialName returns name without a ___ suffix. 1174 // 1175 // CO-RE has the concept of 'struct flavors', which are used to deal with 1176 // changes in kernel data structures. Anything after three underscores 1177 // in a type name is ignored for the purpose of finding a candidate type 1178 // in the kernel's BTF. 1179 func newEssentialName(name string) essentialName { 1180 if name == "" { 1181 return "" 1182 } 1183 lastIdx := strings.LastIndex(name, "___") 1184 if lastIdx > 0 { 1185 return essentialName(name[:lastIdx]) 1186 } 1187 return essentialName(name) 1188 } 1189 1190 // UnderlyingType skips qualifiers and Typedefs. 1191 func UnderlyingType(typ Type) Type { 1192 result := typ 1193 for depth := 0; depth <= maxResolveDepth; depth++ { 1194 switch v := (result).(type) { 1195 case qualifier: 1196 result = v.qualify() 1197 case *Typedef: 1198 result = v.Type 1199 default: 1200 return result 1201 } 1202 } 1203 return &cycle{typ} 1204 } 1205 1206 // As returns typ if is of type T. Otherwise it peels qualifiers and Typedefs 1207 // until it finds a T. 1208 // 1209 // Returns the zero value and false if there is no T or if the type is nested 1210 // too deeply. 1211 func As[T Type](typ Type) (T, bool) { 1212 // NB: We can't make this function return (*T) since then 1213 // we can't assert that a type matches an interface which 1214 // embeds Type: as[composite](T). 1215 for depth := 0; depth <= maxResolveDepth; depth++ { 1216 switch v := (typ).(type) { 1217 case T: 1218 return v, true 1219 case qualifier: 1220 typ = v.qualify() 1221 case *Typedef: 1222 typ = v.Type 1223 default: 1224 goto notFound 1225 } 1226 } 1227 notFound: 1228 var zero T 1229 return zero, false 1230 } 1231 1232 type formatState struct { 1233 fmt.State 1234 depth int 1235 } 1236 1237 // formattableType is a subset of Type, to ease unit testing of formatType. 1238 type formattableType interface { 1239 fmt.Formatter 1240 TypeName() string 1241 } 1242 1243 // formatType formats a type in a canonical form. 1244 // 1245 // Handles cyclical types by only printing cycles up to a certain depth. Elements 1246 // in extra are separated by spaces unless the preceding element is a string 1247 // ending in '='. 1248 func formatType(f fmt.State, verb rune, t formattableType, extra ...interface{}) { 1249 if verb != 'v' && verb != 's' { 1250 fmt.Fprintf(f, "{UNRECOGNIZED: %c}", verb) 1251 return 1252 } 1253 1254 _, _ = io.WriteString(f, internal.GoTypeName(t)) 1255 1256 if name := t.TypeName(); name != "" { 1257 // Output BTF type name if present. 1258 fmt.Fprintf(f, ":%q", name) 1259 } 1260 1261 if f.Flag('+') { 1262 // Output address if requested. 1263 fmt.Fprintf(f, ":%#p", t) 1264 } 1265 1266 if verb == 's' { 1267 // %s omits details. 1268 return 1269 } 1270 1271 var depth int 1272 if ps, ok := f.(*formatState); ok { 1273 depth = ps.depth 1274 f = ps.State 1275 } 1276 1277 maxDepth, ok := f.Width() 1278 if !ok { 1279 maxDepth = 0 1280 } 1281 1282 if depth > maxDepth { 1283 // We've reached the maximum depth. This avoids infinite recursion even 1284 // for cyclical types. 1285 return 1286 } 1287 1288 if len(extra) == 0 { 1289 return 1290 } 1291 1292 wantSpace := false 1293 _, _ = io.WriteString(f, "[") 1294 for _, arg := range extra { 1295 if wantSpace { 1296 _, _ = io.WriteString(f, " ") 1297 } 1298 1299 switch v := arg.(type) { 1300 case string: 1301 _, _ = io.WriteString(f, v) 1302 wantSpace = len(v) > 0 && v[len(v)-1] != '=' 1303 continue 1304 1305 case formattableType: 1306 v.Format(&formatState{f, depth + 1}, verb) 1307 1308 default: 1309 fmt.Fprint(f, arg) 1310 } 1311 1312 wantSpace = true 1313 } 1314 _, _ = io.WriteString(f, "]") 1315 }