...

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

Documentation: github.com/cilium/ebpf/btf

     1  package btf
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"io"
     7  )
     8  
     9  //go:generate stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage
    10  
    11  // btfKind describes a Type.
    12  type btfKind uint8
    13  
    14  // Equivalents of the BTF_KIND_* constants.
    15  const (
    16  	kindUnknown btfKind = iota
    17  	kindInt
    18  	kindPointer
    19  	kindArray
    20  	kindStruct
    21  	kindUnion
    22  	kindEnum
    23  	kindForward
    24  	kindTypedef
    25  	kindVolatile
    26  	kindConst
    27  	kindRestrict
    28  	// Added ~4.20
    29  	kindFunc
    30  	kindFuncProto
    31  	// Added ~5.1
    32  	kindVar
    33  	kindDatasec
    34  	// Added ~5.13
    35  	kindFloat
    36  )
    37  
    38  // FuncLinkage describes BTF function linkage metadata.
    39  type FuncLinkage int
    40  
    41  // Equivalent of enum btf_func_linkage.
    42  const (
    43  	StaticFunc FuncLinkage = iota // static
    44  	GlobalFunc                    // global
    45  	ExternFunc                    // extern
    46  )
    47  
    48  // VarLinkage describes BTF variable linkage metadata.
    49  type VarLinkage int
    50  
    51  const (
    52  	StaticVar VarLinkage = iota // static
    53  	GlobalVar                   // global
    54  	ExternVar                   // extern
    55  )
    56  
    57  const (
    58  	btfTypeKindShift     = 24
    59  	btfTypeKindLen       = 5
    60  	btfTypeVlenShift     = 0
    61  	btfTypeVlenMask      = 16
    62  	btfTypeKindFlagShift = 31
    63  	btfTypeKindFlagMask  = 1
    64  )
    65  
    66  // btfType is equivalent to struct btf_type in Documentation/bpf/btf.rst.
    67  type btfType struct {
    68  	NameOff uint32
    69  	/* "info" bits arrangement
    70  	 * bits  0-15: vlen (e.g. # of struct's members), linkage
    71  	 * bits 16-23: unused
    72  	 * bits 24-28: kind (e.g. int, ptr, array...etc)
    73  	 * bits 29-30: unused
    74  	 * bit     31: kind_flag, currently used by
    75  	 *             struct, union and fwd
    76  	 */
    77  	Info uint32
    78  	/* "size" is used by INT, ENUM, STRUCT and UNION.
    79  	 * "size" tells the size of the type it is describing.
    80  	 *
    81  	 * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
    82  	 * FUNC and FUNC_PROTO.
    83  	 * "type" is a type_id referring to another type.
    84  	 */
    85  	SizeType uint32
    86  }
    87  
    88  func (k btfKind) String() string {
    89  	switch k {
    90  	case kindUnknown:
    91  		return "Unknown"
    92  	case kindInt:
    93  		return "Integer"
    94  	case kindPointer:
    95  		return "Pointer"
    96  	case kindArray:
    97  		return "Array"
    98  	case kindStruct:
    99  		return "Struct"
   100  	case kindUnion:
   101  		return "Union"
   102  	case kindEnum:
   103  		return "Enumeration"
   104  	case kindForward:
   105  		return "Forward"
   106  	case kindTypedef:
   107  		return "Typedef"
   108  	case kindVolatile:
   109  		return "Volatile"
   110  	case kindConst:
   111  		return "Const"
   112  	case kindRestrict:
   113  		return "Restrict"
   114  	case kindFunc:
   115  		return "Function"
   116  	case kindFuncProto:
   117  		return "Function Proto"
   118  	case kindVar:
   119  		return "Variable"
   120  	case kindDatasec:
   121  		return "Section"
   122  	case kindFloat:
   123  		return "Float"
   124  	default:
   125  		return fmt.Sprintf("Unknown (%d)", k)
   126  	}
   127  }
   128  
   129  func mask(len uint32) uint32 {
   130  	return (1 << len) - 1
   131  }
   132  
   133  func readBits(value, len, shift uint32) uint32 {
   134  	return (value >> shift) & mask(len)
   135  }
   136  
   137  func writeBits(value, len, shift, new uint32) uint32 {
   138  	value &^= mask(len) << shift
   139  	value |= (new & mask(len)) << shift
   140  	return value
   141  }
   142  
   143  func (bt *btfType) info(len, shift uint32) uint32 {
   144  	return readBits(bt.Info, len, shift)
   145  }
   146  
   147  func (bt *btfType) setInfo(value, len, shift uint32) {
   148  	bt.Info = writeBits(bt.Info, len, shift, value)
   149  }
   150  
   151  func (bt *btfType) Kind() btfKind {
   152  	return btfKind(bt.info(btfTypeKindLen, btfTypeKindShift))
   153  }
   154  
   155  func (bt *btfType) SetKind(kind btfKind) {
   156  	bt.setInfo(uint32(kind), btfTypeKindLen, btfTypeKindShift)
   157  }
   158  
   159  func (bt *btfType) Vlen() int {
   160  	return int(bt.info(btfTypeVlenMask, btfTypeVlenShift))
   161  }
   162  
   163  func (bt *btfType) SetVlen(vlen int) {
   164  	bt.setInfo(uint32(vlen), btfTypeVlenMask, btfTypeVlenShift)
   165  }
   166  
   167  func (bt *btfType) KindFlag() bool {
   168  	return bt.info(btfTypeKindFlagMask, btfTypeKindFlagShift) == 1
   169  }
   170  
   171  func (bt *btfType) Linkage() FuncLinkage {
   172  	return FuncLinkage(bt.info(btfTypeVlenMask, btfTypeVlenShift))
   173  }
   174  
   175  func (bt *btfType) SetLinkage(linkage FuncLinkage) {
   176  	bt.setInfo(uint32(linkage), btfTypeVlenMask, btfTypeVlenShift)
   177  }
   178  
   179  func (bt *btfType) Type() TypeID {
   180  	// TODO: Panic here if wrong kind?
   181  	return TypeID(bt.SizeType)
   182  }
   183  
   184  func (bt *btfType) Size() uint32 {
   185  	// TODO: Panic here if wrong kind?
   186  	return bt.SizeType
   187  }
   188  
   189  func (bt *btfType) SetSize(size uint32) {
   190  	bt.SizeType = size
   191  }
   192  
   193  type rawType struct {
   194  	btfType
   195  	data interface{}
   196  }
   197  
   198  func (rt *rawType) Marshal(w io.Writer, bo binary.ByteOrder) error {
   199  	if err := binary.Write(w, bo, &rt.btfType); err != nil {
   200  		return err
   201  	}
   202  
   203  	if rt.data == nil {
   204  		return nil
   205  	}
   206  
   207  	return binary.Write(w, bo, rt.data)
   208  }
   209  
   210  // btfInt encodes additional data for integers.
   211  //
   212  //    ? ? ? ? e e e e o o o o o o o o ? ? ? ? ? ? ? ? b b b b b b b b
   213  //    ? = undefined
   214  //    e = encoding
   215  //    o = offset (bitfields?)
   216  //    b = bits (bitfields)
   217  type btfInt struct {
   218  	Raw uint32
   219  }
   220  
   221  const (
   222  	btfIntEncodingLen   = 4
   223  	btfIntEncodingShift = 24
   224  	btfIntOffsetLen     = 8
   225  	btfIntOffsetShift   = 16
   226  	btfIntBitsLen       = 8
   227  	btfIntBitsShift     = 0
   228  )
   229  
   230  func (bi btfInt) Encoding() IntEncoding {
   231  	return IntEncoding(readBits(bi.Raw, btfIntEncodingLen, btfIntEncodingShift))
   232  }
   233  
   234  func (bi *btfInt) SetEncoding(e IntEncoding) {
   235  	bi.Raw = writeBits(uint32(bi.Raw), btfIntEncodingLen, btfIntEncodingShift, uint32(e))
   236  }
   237  
   238  func (bi btfInt) Offset() Bits {
   239  	return Bits(readBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift))
   240  }
   241  
   242  func (bi *btfInt) SetOffset(offset uint32) {
   243  	bi.Raw = writeBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift, offset)
   244  }
   245  
   246  func (bi btfInt) Bits() Bits {
   247  	return Bits(readBits(bi.Raw, btfIntBitsLen, btfIntBitsShift))
   248  }
   249  
   250  func (bi *btfInt) SetBits(bits byte) {
   251  	bi.Raw = writeBits(bi.Raw, btfIntBitsLen, btfIntBitsShift, uint32(bits))
   252  }
   253  
   254  type btfArray struct {
   255  	Type      TypeID
   256  	IndexType TypeID
   257  	Nelems    uint32
   258  }
   259  
   260  type btfMember struct {
   261  	NameOff uint32
   262  	Type    TypeID
   263  	Offset  uint32
   264  }
   265  
   266  type btfVarSecinfo struct {
   267  	Type   TypeID
   268  	Offset uint32
   269  	Size   uint32
   270  }
   271  
   272  type btfVariable struct {
   273  	Linkage uint32
   274  }
   275  
   276  type btfEnum struct {
   277  	NameOff uint32
   278  	Val     int32
   279  }
   280  
   281  type btfParam struct {
   282  	NameOff uint32
   283  	Type    TypeID
   284  }
   285  
   286  func readTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32) ([]rawType, error) {
   287  	var header btfType
   288  	// because of the interleaving between types and struct members it is difficult to
   289  	// precompute the numbers of raw types this will parse
   290  	// this "guess" is a good first estimation
   291  	sizeOfbtfType := uintptr(binary.Size(btfType{}))
   292  	tyMaxCount := uintptr(typeLen) / sizeOfbtfType / 2
   293  	types := make([]rawType, 0, tyMaxCount)
   294  
   295  	for id := TypeID(1); ; id++ {
   296  		if err := binary.Read(r, bo, &header); err == io.EOF {
   297  			return types, nil
   298  		} else if err != nil {
   299  			return nil, fmt.Errorf("can't read type info for id %v: %v", id, err)
   300  		}
   301  
   302  		var data interface{}
   303  		switch header.Kind() {
   304  		case kindInt:
   305  			data = new(btfInt)
   306  		case kindPointer:
   307  		case kindArray:
   308  			data = new(btfArray)
   309  		case kindStruct:
   310  			fallthrough
   311  		case kindUnion:
   312  			data = make([]btfMember, header.Vlen())
   313  		case kindEnum:
   314  			data = make([]btfEnum, header.Vlen())
   315  		case kindForward:
   316  		case kindTypedef:
   317  		case kindVolatile:
   318  		case kindConst:
   319  		case kindRestrict:
   320  		case kindFunc:
   321  		case kindFuncProto:
   322  			data = make([]btfParam, header.Vlen())
   323  		case kindVar:
   324  			data = new(btfVariable)
   325  		case kindDatasec:
   326  			data = make([]btfVarSecinfo, header.Vlen())
   327  		case kindFloat:
   328  		default:
   329  			return nil, fmt.Errorf("type id %v: unknown kind: %v", id, header.Kind())
   330  		}
   331  
   332  		if data == nil {
   333  			types = append(types, rawType{header, nil})
   334  			continue
   335  		}
   336  
   337  		if err := binary.Read(r, bo, data); err != nil {
   338  			return nil, fmt.Errorf("type id %d: kind %v: can't read %T: %v", id, header.Kind(), data, err)
   339  		}
   340  
   341  		types = append(types, rawType{header, data})
   342  	}
   343  }
   344  

View as plain text