aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/bpf.txt
blob: 3cbff517979965ab8897425a0265c816cfe01a98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
# Copyright 2015 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

# Note these sysctls have radical effect on code paths inside of kernel:
# net.core.bpf_jit_enable  = { 0, 1, 2 }
# net.core.bpf_jit_harden  = { 0, 1, 2 }

include <uapi/linux/bpf.h>
include <uapi/linux/btf.h>

resource fd_bpf_map[fd]: BPF_PSEUDO_MAP_FD
resource fd_bpf_prog[fd]
resource fd_rawtp[fd_perf_base]
resource fd_btf[fd]
resource bpf_prog_id[int32]: 0, -1
resource bpf_map_id[int32]: 0, -1
resource bpf_btf_id[int32]: 0, -1

# NEED: this is a random index in btf_header:types. We can't express this, so we just use a small index.
type btf_type_id int32[1:5]
# NEED: opt modified on typedefs, this could be btf_type_id[opt]
type btf_opt_type_id int32[0:5]

# NEED: offset in bpf_btf_program:strings. We can't express this, so we just use a small index.
type btf_name_off int32[1:16]
type btf_opt_name_off int32[0:16]

bpf$MAP_CREATE(cmd const[BPF_MAP_CREATE], arg ptr[in, bpf_map_create_arg], size len[arg]) fd_bpf_map
bpf$MAP_LOOKUP_ELEM(cmd const[BPF_MAP_LOOKUP_ELEM], arg ptr[in, bpf_map_lookup_arg], size len[arg])
bpf$MAP_UPDATE_ELEM(cmd const[BPF_MAP_UPDATE_ELEM], arg ptr[in, bpf_map_update_arg], size len[arg])
bpf$MAP_DELETE_ELEM(cmd const[BPF_MAP_DELETE_ELEM], arg ptr[in, bpf_map_delete_arg], size len[arg])
bpf$MAP_GET_NEXT_KEY(cmd const[BPF_MAP_GET_NEXT_KEY], arg ptr[in, bpf_map_get_next_arg], size len[arg])
bpf$PROG_LOAD(cmd const[BPF_PROG_LOAD], arg ptr[in, bpf_prog], size len[arg]) fd_bpf_prog
bpf$OBJ_PIN_MAP(cmd const[BPF_OBJ_PIN], arg ptr[in, bpf_obj_pin_map], size len[arg])
bpf$OBJ_PIN_PROG(cmd const[BPF_OBJ_PIN], arg ptr[in, bpf_obj_pin_prog], size len[arg])
bpf$OBJ_GET_MAP(cmd const[BPF_OBJ_GET], arg ptr[in, bpf_obj_get], size len[arg]) fd_bpf_map
bpf$OBJ_GET_PROG(cmd const[BPF_OBJ_GET], arg ptr[in, bpf_obj_get], size len[arg]) fd_bpf_prog
bpf$BPF_PROG_ATTACH(cmd const[BPF_PROG_ATTACH], arg ptr[in, bpf_attach_arg], size len[arg])
bpf$BPF_PROG_DETACH(cmd const[BPF_PROG_DETACH], arg ptr[in, bpf_detach_arg], size len[arg])
bpf$BPF_PROG_TEST_RUN(cmd const[BPF_PROG_TEST_RUN], arg ptr[in, bpf_test_prog_arg], size len[arg])
bpf$BPF_PROG_GET_NEXT_ID(cmd const[BPF_PROG_GET_NEXT_ID], arg ptr[in, int32], size len[arg])
bpf$BPF_MAP_GET_NEXT_ID(cmd const[BPF_MAP_GET_NEXT_ID], arg ptr[in, int32], size len[arg])
bpf$BPF_PROG_GET_FD_BY_ID(cmd const[BPF_PROG_GET_FD_BY_ID], arg ptr[in, bpf_prog_id], size len[arg]) fd_bpf_prog
bpf$BPF_MAP_GET_FD_BY_ID(cmd const[BPF_MAP_GET_FD_BY_ID], arg ptr[in, bpf_map_get_fd_by_id_arg], size len[arg]) fd_bpf_map
bpf$BPF_GET_PROG_INFO(cmd const[BPF_OBJ_GET_INFO_BY_FD], arg ptr[in, bpf_get_prog_info_arg], size len[arg])
bpf$BPF_GET_MAP_INFO(cmd const[BPF_OBJ_GET_INFO_BY_FD], arg ptr[in, bpf_get_map_info_arg], size len[arg])
bpf$BPF_GET_BTF_INFO(cmd const[BPF_OBJ_GET_INFO_BY_FD], arg ptr[in, bpf_get_btf_info_arg], size len[arg])
bpf$BPF_PROG_QUERY(cmd const[BPF_PROG_QUERY], arg ptr[in, bpf_prog_query], size len[arg])
bpf$BPF_RAW_TRACEPOINT_OPEN(cmd const[BPF_RAW_TRACEPOINT_OPEN], arg ptr[in, bpf_raw_tracepoint], size len[arg]) fd_rawtp
bpf$BPF_BTF_LOAD(cmd const[BPF_BTF_LOAD], arg ptr[in, bpf_btf_load], size len[arg]) fd_btf
bpf$BPF_BTF_GET_FD_BY_ID(cmd const[BPF_BTF_GET_FD_BY_ID], arg ptr[in, bpf_btf_id], size len[arg]) fd_btf
bpf$BPF_TASK_FD_QUERY(cmd const[BPF_TASK_FD_QUERY], arg ptr[inout, bpf_task_fd_query], size len[arg])
bpf$BPF_MAP_LOOKUP_AND_DELETE_ELEM(cmd const[BPF_MAP_LOOKUP_AND_DELETE_ELEM], arg ptr[in, bpf_map_lookup_arg], size len[arg])
bpf$BPF_MAP_FREEZE(cmd const[BPF_MAP_FREEZE], arg ptr[in, fd_bpf_map], size len[arg])

bpf_map_create_arg {
	type			flags[bpf_map_type, int32]
	ksize			int32
	vsize			int32
	max			int32
	flags			flags[map_flags, int32]
	inner			fd_bpf_map[opt]
	node			int32
	map_name		array[const[0, int8], BPF_OBJ_NAME_LEN]
	map_ifindex		ifindex[opt]
	btf_fd			fd_btf[opt]
	btf_key_type_id		btf_opt_type_id
	btf_value_type_id	btf_opt_type_id
}

bpf_map_get_fd_by_id_arg {
	map_id		bpf_map_id
	next_id		int32
	open_flags	flags[bpf_open_flags, int32]
}

bpf_map_lookup_arg {
	map	fd_bpf_map
	key	ptr64[in, array[int8]]
	val	ptr64[out, array[int8]]
}

bpf_map_update_arg {
	map	fd_bpf_map
	key	ptr64[in, array[int8]]
	val	ptr64[in, array[int8]]
	flags	flags[bpf_map_flags, int64]
}

bpf_map_delete_arg {
	map	fd_bpf_map
	key	ptr64[in, array[int8]]
}

bpf_map_get_next_arg {
	map	fd_bpf_map
	key	ptr64[in, array[int8]]
	next	ptr64[out, array[int8]]
}

define BPF_LINE_INFO_SIZE	sizeof(struct bpf_line_info)
define BPF_FUNC_INFO_SIZE	sizeof(struct bpf_func_info)

bpf_prog {
	type			flags[bpf_prog_type, int32]
	ninsn			bytesize8[insns, int32]
	insns			ptr64[in, bpf_instructions]
	license			ptr64[in, string[bpf_licenses]]
	loglev			int32
	logsize			len[log, int32]
	log			ptr64[out, array[int8], opt]
	kern_version		flags[bpf_kern_version, int32]
	flags			flags[bpf_prog_load_flags, int32]
	prog_name		array[const[0, int8], BPF_OBJ_NAME_LEN]
	prog_ifindex		ifindex[opt]
	expected_attach_type	flags[bpf_attach_type, int32]
	btf_fd			fd_btf[opt]
	func_info_rec_size	const[BPF_FUNC_INFO_SIZE, int32]
	func_info		ptr64[in, bpf_func_info]
	func_info_cnt		len[func_info, int32]
	line_info_rec_size	const[BPF_LINE_INFO_SIZE, int32]
	line_info		ptr64[in, bpf_line_info]
	line_info_cnt		len[line_info, int32]
}

bpf_licenses = "GPL", "syzkaller"
bpf_kern_version = 0x40f00, 0x41000, 0x41100

bpf_func_info {
# This is instruction index, so should not be too large.
	insn_off	int32[0:10]
	type_id		btf_type_id
}

bpf_line_info {
# This is instruction index, so should not be too large.
	insn_off	int32[0:5]
	file_name_off	btf_opt_name_off
	line_off	int32
	line_col	int32
}

bpf_instructions [
	raw	array[bpf_insn]
	framed	bpf_framed_program
] [varlen]

bpf_framed_program {
	initr0	bpf_insn_init_r0
	body	array[bpf_insn]
	exit	bpf_insn_exit
} [packed]

bpf_insn [
	generic	bpf_insn_generic
	ldst	bpf_insn_ldst
	alu	bpf_insn_alu
	jmp	bpf_insn_jmp
	call	bpf_insn_call
	exit	bpf_insn_exit
	initr0	bpf_insn_init_r0
	map	bpf_insn_map
] [varlen]

bpf_insn_generic {
	code	int8
	dst	int8:4
	src	int8:4
	off	int16
	imm	int32
}

bpf_insn_ldst {
	code_class	flags[bpf_ldst_insn, int8:3]
	code_size	flags[bpf_ldst_size, int8:2]
	code_mode	flags[bpf_ldst_mode, int8:3]
	dst		flags[bpf_reg, int8:4]
	src		flags[bpf_reg, int8:4]
	off		flags[bpf_insn_offsets, int16]
	imm		flags[bpf_insn_immediates, int32]
}

bpf_ldst_insn = BPF_LD, BPF_LDX, BPF_ST, BPF_STX
bpf_ldst_size = BPF_W0, BPF_H0, BPF_B0, BPF_DW0
bpf_ldst_mode = BPF_IMM0, BPF_ABS0, BPF_IND0, BPF_MEM0, BPF_XADD0

define BPF_W0	BPF_W >> 3
define BPF_H0	BPF_H >> 3
define BPF_B0	BPF_B >> 3
define BPF_DW0	BPF_DW >> 3

define BPF_IMM0	BPF_IMM >> 5
define BPF_ABS0	BPF_ABS >> 5
define BPF_IND0	BPF_IND >> 5
define BPF_MEM0	BPF_MEM >> 5
define BPF_XADD0	BPF_XADD >> 5

bpf_insn_alu {
	code_class	flags[bpf_alu_insn, int8:3]
	code_s		int8:1
	code_op		flags[bpf_alu_op, int8:4]
	dst		flags[bpf_reg, int8:4]
	src		flags[bpf_reg, int8:4]
	off		flags[bpf_insn_offsets, int16]
	imm		flags[bpf_insn_immediates, int32]
}

bpf_alu_insn = BPF_ALU, BPF_ALU64
bpf_alu_op = BPF_ADD0, BPF_SUB0, BPF_MUL0, BPF_DIV0, BPF_OR0, BPF_AND0, BPF_LSH0, BPF_RSH0, BPF_NEG0, BPF_MOD0, BPF_XOR0, BPF_MOV0, BPF_ARSH0, BPF_END0

define BPF_ADD0	BPF_ADD >> 4
define BPF_SUB0	BPF_SUB >> 4
define BPF_MUL0	BPF_MUL >> 4
define BPF_DIV0	BPF_DIV >> 4
define BPF_OR0	BPF_OR >> 4
define BPF_AND0	BPF_AND >> 4
define BPF_LSH0	BPF_LSH >> 4
define BPF_RSH0	BPF_RSH >> 4
define BPF_NEG0	BPF_NEG >> 4
define BPF_MOD0	BPF_MOD >> 4
define BPF_XOR0	BPF_XOR >> 4
define BPF_MOV0	BPF_MOV >> 4
define BPF_ARSH0	BPF_ARSH >> 4
define BPF_END0	BPF_END >> 4

bpf_insn_jmp {
	code_class	const[BPF_JMP, int8:3]
	code_s		int8:1
	code_op		flags[bpf_jmp_op, int8:4]
	dst		flags[bpf_reg, int8:4]
	src		flags[bpf_reg, int8:4]
	off		flags[bpf_insn_offsets, int16]
	imm		flags[bpf_insn_immediates, int32]
}

bpf_jmp_op = BPF_JA0, BPF_JEQ0, BPF_JGT0, BPF_JGE0, BPF_JSET0, BPF_JNE0, BPF_JSGT0, BPF_JSGE0, BPF_CALL0, BPF_EXIT0, BPF_JLT0, BPF_JLE0, BPF_JSLT0, BPF_JSLE0

define BPF_JA0	BPF_JA >> 4
define BPF_JEQ0	BPF_JEQ >> 4
define BPF_JGT0	BPF_JGT >> 4
define BPF_JGE0	BPF_JGE >> 4
define BPF_JSET0	BPF_JSET >> 4
define BPF_JNE0	BPF_JNE >> 4
define BPF_JSGT0	BPF_JSGT >> 4
define BPF_JSGE0	BPF_JSGE >> 4
define BPF_CALL0	BPF_CALL >> 4
define BPF_EXIT0	BPF_EXIT >> 4
define BPF_JLT0	BPF_JLT >> 4
define BPF_JLE0	BPF_JLE >> 4
define BPF_JSLT0	BPF_JSLT >> 4
define BPF_JSLE0	BPF_JSLE >> 4

bpf_insn_call {
	code	const[bpf_call_code, int8]
	regs	const[0, int8]
	off	const[0, int16]
	func	int32[0:__BPF_FUNC_MAX_ID]
}

define bpf_call_code	BPF_JMP | BPF_CALL

bpf_insn_exit {
	code	const[bpf_exit_code, int8]
	regs	const[0, int8]
	off	const[0, int16]
	imm	const[0, int32]
}

define bpf_exit_code	BPF_JMP | BPF_EXIT

bpf_insn_init_r0 {
	code	const[bpf_insn_load_imm_dw, int8]
	dst	const[BPF_REG_0, int8:4]
	src	const[0, int8:4]
	off	const[0, int16]
	imm	int32
	code2	const[0, int8]
	regs2	const[0, int8]
	off2	const[0, int16]
	imm2	int32
}

bpf_insn_map {
	code	const[bpf_insn_load_imm_dw, int8]
	dst	flags[bpf_reg, int8:4]
	src	const[BPF_PSEUDO_MAP_FD, int8:4]
	off	const[0, int16]
	imm	fd_bpf_map
	code2	const[0, int8]
	regs2	const[0, int8]
	off2	const[0, int16]
	imm2	const[0, int32]
}

define bpf_insn_load_imm_dw	BPF_LD | BPF_DW | BPF_IMM

# Slightly prune state space, these values frequently must be 0.
bpf_insn_offsets = 0, 1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 80, 128, 256, -1, -2, -4, -8, -12, -16, -32, -64
bpf_insn_immediates = 0, 1, 4, 8, 16, -1, -4, -16
bpf_reg = BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5, BPF_REG_6, BPF_REG_7, BPF_REG_8, BPF_REG_9, BPF_REG_10, __MAX_BPF_REG

define MAX_BPF_REG	__MAX_BPF_REG

# NEED: these filenames must be on bpf filesystem, can we do it somehow?
bpf_obj_pin_map {
	path	ptr64[in, filename]
	fd	fd_bpf_map
}

bpf_obj_pin_prog {
	path	ptr64[in, filename]
	fd	fd_bpf_prog
}

bpf_obj_get {
	path		ptr64[in, filename]
	fd		const[0, int32]
	file_flags	flags[bpf_open_flags, int32]
}

bpf_attach_arg {
	target_fd	fd_cgroup
	attach_bpf_fd	fd_bpf_prog
	type		flags[bpf_attach_type, int32]
	flags		flags[bpf_attach_flags, int32]
}

bpf_detach_arg {
	target	const[0, int32]
	prog	fd_bpf_prog
	type	flags[bpf_attach_type, int32]
	flags	flags[bpf_attach_flags, int32]
	prog2	const[0, int32]
}

bpf_test_prog_arg {
	prog	fd_bpf_prog
	retval	const[0, int32]
	insize	len[indata, int32]
	outsize	len[outdata, int32]
	indata	ptr64[in, array[int8]]
	outdata	ptr64[out, array[int8]]
	repeat	int32
	dur	const[0, int32]
}

bpf_get_prog_info_arg {
	prog	fd_bpf_prog
	len	len[info, int32]
	info	ptr64[out, bpf_prog_info]
}

bpf_prog_info {
	type				int32
	id				bpf_prog_id
	tag				int64
	jited_prog_len			int32
	xlated_prog_len			int32
	jited_prog_insns		int64
	xlated_prog_insns		int64
	load_time			int64
	created_by_uid			int32
	nr_map_ids			int32
	map_ids				int64
	name				array[int8, BPF_OBJ_NAME_LEN]
	ifindex				int32
	gpl_compatible			int32:1
	netns_dev			int64
	netns_ino			int64
	nr_jited_ksyms			int32
	nr_jited_func_lens		int32
	jited_ksyms			ptr64[in, int64]
	jited_func_lens			int64
	btf_id				bpf_btf_id
	func_info_rec_size		int32
	func_info			ptr64[in, bpf_func_info]
	nr_func_info			int32
	nr_line_info			int32
	line_info			ptr64[in, bpf_line_info]
	jited_line_info			ptr64[in, int64]
	nr_jited_line_info		int32
	line_info_rec_size		int32
	jited_line_info_rec_size	int32
	nr_prog_tags			int32
	prog_tags			ptr64[in, int64]
} [align_8]

bpf_get_map_info_arg {
	prog	fd_bpf_map
	len	len[info, int32]
	info	ptr64[out, bpf_map_info]
}

bpf_map_info {
	type		int32
	id		bpf_map_id
	key_size	int32
	value_size	int32
	max_entries	int32
	map_flags	int32
	name		array[int8, BPF_OBJ_NAME_LEN]
} [align_8]

bpf_get_btf_info_arg {
	btf	fd_btf
	len	len[info, int32]
	info	ptr64[inout, bpf_btf_info]
}

bpf_btf_info {
	btf		ptr64[out, array[int8]]
	btf_size	bytesize[btf, int32]
	id		bpf_btf_id[opt]
} [align_8]

bpf_prog_query {
	target_fd	fd_cgroup
	attach_type	flags[bpf_prog_query_attach_type, int32]
	query_flags	flags[bpf_prog_query_flags, int32]
	attach_flags	int32
	prog_ids	ptr64[out, array[int32]]
	prog_cnt	len[prog_ids, int32]
} [align_8]

bpf_raw_tracepoint {
	name	ptr64[in, string]
	prog_fd	fd_bpf_prog
} [align_8]

bpf_btf_load {
	btf		ptr64[in, bpf_btf_program]
	btf_log_buf	ptr64[out, array[int8]]
	btf_size	bytesize[btf, int32]
	btf_log_size	bytesize[btf_log_buf, int32]
	btf_log_level	bool32
} [align_8]

bpf_btf_program {
	header	btf_header
	strings	bpf_btf_strings
} [packed]

btf_header {
	magic		const[BTF_MAGIC, int16]
	version		const[BTF_VERSION, int8]
	flags		const[0, int8]
	hdr_len		const[0x18, int32]
	type_off	const[0, int32]
	type_len	bytesize[types, int32]
	str_off		bytesize[types, int32]
	str_len		bytesize[bpf_btf_program:strings, int32]
	types		array[btf_type]
} [align_4]

btf_type [
	int		btf_type_int
	ptr		btf_type_ref_t[BTF_KIND_PTR]
	array		btf_type_array
	struct		btf_type_struct_t[BTF_KIND_STRUCT]
	union		btf_type_struct_t[BTF_KIND_UNION]
	enum		btf_type_enum
	fwd		btf_type_fwd
	typedef		btf_type_ref_t[BTF_KIND_TYPEDEF]
	volatile	btf_type_ref_t[BTF_KIND_VOLATILE]
	const		btf_type_ref_t[BTF_KIND_CONST]
	restrict	btf_type_ref_t[BTF_KIND_RESTRICT]
	func		btf_type_func
	func_proto	btf_type_func_proto
	var		btf_type_var
	datasec		btf_type_datasec
] [varlen]

btf_type_int {
# Note: this is an offset in bpf_btf_program:strings
	name_off	btf_opt_name_off
	info_vlen	const[0, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_INT, int8]
	size		const[0, int32]
	bits		int8[0:128]
	pad		const[0, int8]
	offset		int8[0:128]
	encoding	flags[btf_type_int_encoding, int8]
}

btf_type_int_encoding = 0, BTF_INT_SIGNED, BTF_INT_CHAR, BTF_INT_BOOL

type btf_type_ref_t[TYP] {
	name_off	btf_opt_name_off
	info_vlen	const[0, int16]
	info_pad	const[0, int8]
	info_typ	const[TYP, int8]
	type		btf_opt_type_id
}

btf_type_array {
	name_off	const[0, int32]
	info_vlen	const[0, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_ARRAY, int8]
	size		const[0, int32]
	data		btf_array
}

btf_array {
	type		btf_type_id
	index_type	btf_type_id
	nelems		int32
}

type btf_type_struct_t[TYP] {
	name_off	btf_opt_name_off
	info_vlen	len[fields, int16]
	info_pad	const[0, int8]
	info_typ	const[TYP, int8:7]
	info_kflag	int8:1
	size		int32
	fields		array[btf_member]
}

btf_member {
	name_off	btf_opt_name_off
	type		btf_opt_type_id
	offset		int32
}

btf_type_enum {
	name_off	btf_opt_name_off
	info_vlen	len[values, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_ENUM, int8]
	size		const[4, int32]
	values		array[btf_enum]
}

btf_enum {
	name_off	btf_opt_name_off
	val		int32
}

btf_type_fwd {
	name_off	btf_name_off
	info_vlen	const[0, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_FWD, int8]
	size		const[0, int32]
}

btf_type_func {
	name_off	btf_name_off
	info_vlen	const[0, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_FUNC, int8]
	type		btf_type_id
}

btf_type_func_proto {
	name_off	const[0, int32]
	info_vlen	len[params, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_FUNC_PROTO, int8]
	size		const[0, int32]
	params		array[btf_param]
}

btf_param {
	name_off	btf_opt_name_off
	type		btf_opt_type_id
}

btf_type_var {
	name_off	btf_name_off
	info_vlen	const[0, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_VAR, int8]
	type		btf_type_id
	linkage		bool32
}

btf_type_datasec {
	name_off	btf_name_off
	info_vlen	len[secinfo, int16]
	info_pad	const[0, int8]
	info_typ	const[BTF_KIND_DATASEC, int8]
	size		bytesize[data, int32]
	secinfo		array[btf_var_secinfo]
	data		array[int8, 1:3]
} [packed]

btf_var_secinfo {
	type	btf_type_id
# NEED: offset/size are for btf_type_datasec:data and must be increasing and within bounds (see btf_datasec_check_meta)
	offset	int32
	size	int32
}

bpf_btf_strings {
	z0	const[0, int8]
	data	array[flags[bpf_btf_strings_elem, int8]]
	z1	const[0, int8]
} [packed]

bpf_btf_strings_elem = 'a', '0', '_', '.', 0

bpf_task_fd_query {
# NEED: part of fields are input here and part are output. We can't express this yet (#245).
	pid		pid
	fd		fd_perf_base
	flags		const[0, int32]
	buf_len		bytesize[buf, int32]
	buf		ptr64[in, string]
# These are output fields:
	prog_id		bpf_prog_id[opt]
	fd_type		const[0, int32]
	probe_offset	const[0, int64]
	probe_addr	const[0, int64]
}

bpf_map_type = BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_ARRAY, BPF_MAP_TYPE_PROG_ARRAY, BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_MAP_TYPE_STACK_TRACE, BPF_MAP_TYPE_CGROUP_ARRAY, BPF_MAP_TYPE_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_ARRAY, BPF_MAP_TYPE_LRU_HASH, BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_ARRAY_OF_MAPS, BPF_MAP_TYPE_HASH_OF_MAPS, BPF_MAP_TYPE_DEVMAP, BPF_MAP_TYPE_SOCKMAP, BPF_MAP_TYPE_CPUMAP, BPF_MAP_TYPE_XSKMAP, BPF_MAP_TYPE_SOCKHASH, BPF_MAP_TYPE_CGROUP_STORAGE, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, BPF_MAP_TYPE_QUEUE, BPF_MAP_TYPE_STACK, BPF_MAP_TYPE_SK_STORAGE
bpf_map_flags = BPF_ANY, BPF_NOEXIST, BPF_EXIST, BPF_F_LOCK
bpf_prog_type = BPF_PROG_TYPE_SOCKET_FILTER, BPF_PROG_TYPE_KPROBE, BPF_PROG_TYPE_SCHED_CLS, BPF_PROG_TYPE_SCHED_ACT, BPF_PROG_TYPE_TRACEPOINT, BPF_PROG_TYPE_XDP, BPF_PROG_TYPE_PERF_EVENT, BPF_PROG_TYPE_CGROUP_SKB, BPF_PROG_TYPE_CGROUP_SOCK, BPF_PROG_TYPE_LWT_IN, BPF_PROG_TYPE_LWT_OUT, BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, BPF_PROG_TYPE_SK_SKB, BPF_PROG_TYPE_CGROUP_DEVICE, BPF_PROG_TYPE_SK_MSG, BPF_PROG_TYPE_RAW_TRACEPOINT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_PROG_TYPE_LWT_SEG6LOCAL, BPF_PROG_TYPE_LIRC_MODE2, BPF_PROG_TYPE_SK_REUSEPORT, BPF_PROG_TYPE_FLOW_DISSECTOR, BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
map_flags = BPF_F_NO_PREALLOC, BPF_F_NO_COMMON_LRU, BPF_F_NUMA_NODE, BPF_F_RDONLY, BPF_F_WRONLY, BPF_F_STACK_BUILD_ID, BPF_F_ZERO_SEED, BPF_F_RDONLY_PROG, BPF_F_WRONLY_PROG
bpf_attach_type = BPF_CGROUP_INET_INGRESS, BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, BPF_SK_SKB_STREAM_PARSER, BPF_SK_SKB_STREAM_VERDICT, BPF_CGROUP_DEVICE, BPF_SK_MSG_VERDICT, BPF_CGROUP_INET4_BIND, BPF_CGROUP_INET6_BIND, BPF_CGROUP_INET4_CONNECT, BPF_CGROUP_INET6_CONNECT, BPF_CGROUP_INET4_POST_BIND, BPF_CGROUP_INET6_POST_BIND, BPF_CGROUP_UDP4_SENDMSG, BPF_CGROUP_UDP6_SENDMSG, BPF_LIRC_MODE2, BPF_FLOW_DISSECTOR, BPF_CGROUP_SYSCTL
bpf_prog_load_flags = BPF_F_STRICT_ALIGNMENT, BPF_F_ANY_ALIGNMENT
bpf_attach_flags = BPF_F_ALLOW_OVERRIDE, BPF_F_ALLOW_MULTI
bpf_prog_query_flags = BPF_F_QUERY_EFFECTIVE
bpf_prog_query_attach_type = BPF_CGROUP_INET_INGRESS, BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, BPF_CGROUP_DEVICE, BPF_CGROUP_INET4_BIND, BPF_CGROUP_INET4_CONNECT, BPF_CGROUP_INET4_POST_BIND, BPF_CGROUP_INET6_BIND, BPF_CGROUP_INET6_CONNECT, BPF_CGROUP_INET6_POST_BIND, BPF_CGROUP_UDP4_SENDMSG, BPF_CGROUP_UDP6_SENDMSG, BPF_LIRC_MODE2, BPF_CGROUP_SYSCTL, BPF_FLOW_DISSECTOR
bpf_open_flags = BPF_F_RDONLY, BPF_F_WRONLY