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