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