github.com/cilium/ebpf@v0.10.0/btf/types.go (about)

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