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, &params[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  }