...

Source file src/github.com/cilium/ebpf/btf/types.go

Documentation: github.com/cilium/ebpf/btf

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

View as plain text