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