1 package btf
2
3 import (
4 "encoding/binary"
5 "fmt"
6 "io"
7 )
8
9
10
11
12 type btfKind uint8
13
14
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
29 kindFunc
30 kindFuncProto
31
32 kindVar
33 kindDatasec
34
35 kindFloat
36 )
37
38
39 type FuncLinkage int
40
41
42 const (
43 StaticFunc FuncLinkage = iota
44 GlobalFunc
45 ExternFunc
46 )
47
48
49 type VarLinkage int
50
51 const (
52 StaticVar VarLinkage = iota
53 GlobalVar
54 ExternVar
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
67 type btfType struct {
68 NameOff uint32
69
77 Info uint32
78
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
181 return TypeID(bt.SizeType)
182 }
183
184 func (bt *btfType) Size() uint32 {
185
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
211
212
213
214
215
216
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
289
290
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