aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux
diff options
context:
space:
mode:
authorPaul Chaignon <paul.chaignon@gmail.com>2023-11-27 22:53:43 +0100
committerAleksandr Nogikh <nogikh@google.com>2023-11-28 12:12:09 +0000
commitbaec5b18b692c2a40f471841cc7bf288e9bd6600 (patch)
tree8717fa3582feec50921073f51e32d1b843b92276 /sys/linux
parent37241f00429afb88d5c6a0b1fe00277505f34064 (diff)
sys/linux: move description of BPF programs to own file
The bpf.txt file is becoming huge as it contains the descriptions for all the bpf(2) commands. The most complex command to describe is currently BPF_PROG_LOAD has it contains the whole BPF program description. Those descriptions are also likely to grow significantly as we add more BPF helper descriptions. This commit therefore moves the descriptions pertaining to BPF programs (attributes for BPF_PROG_LOAD, eBPF instructions, and BPF helpers) to their own file, bpf_prog.txt. Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Diffstat (limited to 'sys/linux')
-rw-r--r--sys/linux/bpf.txt507
-rw-r--r--sys/linux/bpf_prog.txt510
2 files changed, 510 insertions, 507 deletions
diff --git a/sys/linux/bpf.txt b/sys/linux/bpf.txt
index 3cd25716b..b6aa67152 100644
--- a/sys/linux/bpf.txt
+++ b/sys/linux/bpf.txt
@@ -324,512 +324,6 @@ bpf_iter_create_arg {
bpf_batch_flags = BPF_F_LOCK
-define BPF_LINE_INFO_SIZE sizeof(struct bpf_line_info)
-define BPF_FUNC_INFO_SIZE sizeof(struct bpf_func_info)
-define BPF_CORE_RELO_SIZE sizeof(struct bpf_core_relo)
-
-type bpf_prog_t[TYPE, ATTACH_TYPE, BTF_ID, PROG_FD] {
- type TYPE
- 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 ATTACH_TYPE
- btf_fd fd_btf[opt]
- func_info_rec_size const[BPF_FUNC_INFO_SIZE, int32]
- func_info ptr64[in, bpf_func_info, opt]
- func_info_cnt len[func_info, int32]
- line_info_rec_size const[BPF_LINE_INFO_SIZE, int32]
- line_info ptr64[in, bpf_line_info, opt]
- line_info_cnt len[line_info, int32]
- attach_btf_id BTF_ID
- attach_prog_fd PROG_FD
- core_relo_cnt len[core_relos, int32]
- fd_array ptr64[in, array[fd_bpf_map], opt]
- core_relos ptr64[in, array[bpf_core_relo], opt]
- core_relo_rec_size const[BPF_CORE_RELO_SIZE, int32]
- log_true_size int32
-}
-
-type bpf_prog bpf_prog_t[flags[bpf_prog_type, int32], flags[bpf_attach_type, int32], bpf_btf_id[opt], fd_bpf_prog[opt]]
-
-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_core_relo {
-# This is instruction index, so should not be too large.
- insn_off int32[0:5]
- type_id btf_type_id
- access_str_off btf_opt_name_off
- kind flags[bpf_core_relo_kind, int32]
-}
-
-bpf_instructions [
- raw array[bpf_insn]
- framed bpf_framed_program
- ringbuf bpf_program_ringbuf
-] [varlen]
-
-bpf_framed_program {
- initr0 bpf_insn_init_r0
- body array[bpf_insn]
- exit bpf_insn_exit
-} [packed]
-
-bpf_program_ringbuf {
- initr0 bpf_insn_init_r0
- reserve bpf_insn_ringbuf_reserve
- null_check bpf_insn_null_check[BPF_REG_9]
- body array[bpf_insn]
- free bpf_insn_ringbuf_free
- 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_helper
- func bpf_insn_call_func
- kfunc bpf_insn_call_kfunc
- exit bpf_insn_exit
- initr0 bpf_insn_init_r0
- map_fd bpf_insn_map_fd
- map_idx bpf_insn_map_idx
- map_val bpf_insn_map_value
- map_idx_val bpf_insn_map_idx_value
- btf_id bpf_insn_btf_id
- cb_func bpf_insn_cb_func
- printk bpf_insn_trace_printk
- snprintf bpf_insn_snprintf
- tail_call bpf_insn_tail_call
- ringbuf_query bpf_insn_ringbuf_query
- ringbuf_output bpf_insn_ringbuf_output
-] [varlen]
-
-bpf_insn_generic {
- code int8
- dst int8:4
- src int8:4
- off int16
- imm int32
-}
-
-type bpf_insn_ldst_t[CLASS, SZ, MODE, DST, SRC, OFF, IMM] {
- code_class int8:3[CLASS]
- code_size int8:2[SZ]
- code_mode int8:3[MODE]
- dst DST
- src SRC
- off OFF
- imm IMM
-}
-
-type bpf_insn_ldst bpf_insn_ldst_t[bpf_ldst_insn, bpf_ldst_size, bpf_ldst_mode, flags[bpf_reg, int8:4], flags[bpf_reg, int8:4], flags[bpf_insn_offsets, int16], flags[bpf_insn_immediates, int32]]
-type bpf_insn_st64_reg[SRC, DST, OFF] bpf_insn_ldst_t[BPF_STX, BPF_DW0, BPF_MEM0, const[DST, int8:4], const[SRC, int8:4], const[OFF, int16], const[0, 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, BPF_MEMSX0
-
-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
-define BPF_MEMSX0 BPF_MEMSX >> 5
-
-type bpf_insn_alu_t[CLASS, SOURCE, OP, DST, SRC, OFF, IMM] {
- code_class int8:3[CLASS]
- code_s int8:1[SOURCE]
- code_op int8:4[OP]
- dst DST
- src SRC
- off OFF
- imm IMM
-}
-
-type bpf_insn_alu bpf_insn_alu_t[bpf_alu_insn, bpf_alu_source, bpf_alu_op, flags[bpf_reg, int8:4], flags[bpf_reg, int8:4], flags[bpf_insn_offsets, int16], flags[bpf_insn_immediates, int32]]
-type bpf_insn_mov_imm[DST, IMM] bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_MOV0, const[DST, int8:4], const[0, int8:4], const[0, int16], const[IMM, int32]]
-type bpf_insn_mov_imm_any[DST] bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_MOV0, const[DST, int8:4], const[0, int8:4], const[0, int16], int32]
-type bpf_insn_mov_imm_flag[DST, FLAG] bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_MOV0, const[DST, int8:4], const[0, int8:4], const[0, int16], flags[FLAG, int32]]
-type bpf_insn_mov_reg[SRC, DST] bpf_insn_alu_t[BPF_ALU64, BPF_X0, BPF_MOV0, const[DST, int8:4], const[SRC, int8:4], const[0, int16], const[0, int32]]
-type bpf_insn_op_imm[DST, OP, IMM] bpf_insn_alu_t[BPF_ALU64, BPF_K0, OP, const[DST, int8:4], const[0, int8:4], const[0, int16], const[IMM, int32]]
-
-bpf_alu_source = BPF_K0, BPF_X0
-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
-
-define BPF_K0 BPF_K >> 3
-define BPF_X0 BPF_X >> 3
-
-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]
-}
-
-# Equivalent to: if reg != 0 goto +1;
-type bpf_insn_not_null_jmp[REG] {
- code_class const[BPF_JMP, int8:3]
- code_s const[BPF_K0, int8:1]
- code_op const[BPF_JNE0, int8:4]
- dst const[REG, int8:4]
- src const[0, int8:4]
- off const[1, int16]
- imm const[0, 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
-
-type bpf_insn_call_helper_t[FUNC] {
- code const[bpf_call_code, int8]
- regs const[0, int8]
- off const[0, int16]
- func FUNC
-}
-
-type bpf_insn_call_helper bpf_insn_call_helper_t[int32[0:__BPF_FUNC_MAX_ID]]
-
-bpf_insn_call_func {
- code const[bpf_call_code, int8]
- dst const[0, int8:4]
- src const[BPF_PSEUDO_CALL, int8:4]
- off const[0, int16]
-# NEED: to limit the call offset to the program size, we'd need support for path expressions inside ranges of values.
- func int32[-8:8]
-}
-
-bpf_insn_call_kfunc {
- code const[bpf_call_code, int8]
- dst const[0, int8:4]
- src const[BPF_PSEUDO_KFUNC_CALL, int8:4]
- off const[0, int16]
- kfunc btf_type_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
-}
-
-type bpf_insn_mov_imm64[DST, IMM1, IMM2] {
- code const[bpf_insn_load_imm_dw, int8]
- dst const[DST, int8:4]
- src const[0, int8:4]
- off const[0, int16]
- imm const[IMM1, int32]
- code2 const[0, int8]
- regs2 const[0, int8]
- off2 const[0, int16]
- imm2 const[IMM2, int32]
-}
-
-type bpf_insn_map_fd_t[DST, MAP_FD] {
- code const[bpf_insn_load_imm_dw, int8]
- dst DST
- src const[BPF_PSEUDO_MAP_FD, int8:4]
- off const[0, int16]
- imm MAP_FD
- code2 const[0, int8]
- regs2 const[0, int8]
- off2 const[0, int16]
- imm2 const[0, int32]
-}
-
-type bpf_insn_map_fd bpf_insn_map_fd_t[flags[bpf_reg, int8:4], fd_bpf_map]
-type bpf_insn_tail_call_map_fd[DST] bpf_insn_map_fd_t[const[DST, int8:4], tail_call_map]
-type bpf_insn_ringbuf_fd[DST] bpf_insn_map_fd_t[const[DST, int8:4], ringbuf_map_fd]
-
-bpf_insn_map_idx {
- code const[bpf_insn_load_imm_dw, int8]
- dst flags[bpf_reg, int8:4]
- src const[BPF_PSEUDO_MAP_IDX, int8:4]
- off const[0, int16]
- imm map_fd_id
- code2 const[0, int8]
- regs2 const[0, int8]
- off2 const[0, int16]
- imm2 const[0, int32]
-}
-
-type bpf_insn_map_value_t[DST, MAP_FD, VALUE_OFFSET] {
- code const[bpf_insn_load_imm_dw, int8]
- dst DST
- src const[BPF_PSEUDO_MAP_VALUE, int8:4]
- off const[0, int16]
- imm MAP_FD
- code2 const[0, int8]
- regs2 const[0, int8]
- off2 const[0, int16]
- imm2 VALUE_OFFSET
-}
-
-type bpf_insn_map_value bpf_insn_map_value_t[flags[bpf_reg, int8:4], fd_bpf_map, int32]
-type bpf_insn_const_str[DST] bpf_insn_map_value_t[const[DST, int8:4], bpf_frozen_const_str, const[0, int32]]
-
-bpf_insn_map_idx_value {
- code const[bpf_insn_load_imm_dw, int8]
- dst flags[bpf_reg, int8:4]
- src const[BPF_PSEUDO_MAP_IDX_VALUE, int8:4]
- off const[0, int16]
- imm map_fd_id
- code2 const[0, int8]
- regs2 const[0, int8]
- off2 const[0, int16]
- imm2 int32
-}
-
-bpf_insn_cb_func {
- code const[bpf_insn_load_imm_dw, int8]
- dst flags[bpf_reg, int8:4]
- src const[BPF_PSEUDO_FUNC, int8:4]
- off const[0, int16]
-# NEED: to limit the call offset to the program size, we'd need support for path expressions inside ranges of values.
- imm int32[-8:8]
- code2 const[0, int8]
- regs2 const[0, int8]
- off2 const[0, int16]
- imm2 const[0, int32]
-}
-
-bpf_insn_btf_id {
- code const[bpf_insn_load_imm_dw, int8]
- dst flags[bpf_reg, int8:4]
- src const[BPF_PSEUDO_BTF_ID, int8:4]
- off const[0, int16]
- imm btf_type_id
- 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
-
-# Equivalent to:
-# if reg != 0 goto +1;
-# exit;
-# This is useful to check null pointers. We exit if the pointer is null and
-# continue the normal flow otherwise.
-type bpf_insn_null_check[REG] {
- cond_jump bpf_insn_not_null_jmp[REG]
- exit bpf_insn_exit
-}
-
-# Format specifiers for bpf_trace_printk, encoded as a zero-terminated string
-# of 7 characters. For example, field 'p' corresponds to "%p ".
-type bpf_insn_mov_printk_str_hex[DST] [
- p bpf_insn_mov_imm64[DST, 0x25702020, 0x20202000]
- d bpf_insn_mov_imm64[DST, 0x25642020, 0x20202000]
- i bpf_insn_mov_imm64[DST, 0x25692020, 0x20202000]
- u bpf_insn_mov_imm64[DST, 0x25752020, 0x20202000]
- x bpf_insn_mov_imm64[DST, 0x25782020, 0x20202000]
- ld bpf_insn_mov_imm64[DST, 0x256c6420, 0x20202000]
- li bpf_insn_mov_imm64[DST, 0x256c6920, 0x20202000]
- lu bpf_insn_mov_imm64[DST, 0x256c7520, 0x20202000]
- lx bpf_insn_mov_imm64[DST, 0x256c7820, 0x20202000]
- lld bpf_insn_mov_imm64[DST, 0x256c6c64, 0x20202000]
- lli bpf_insn_mov_imm64[DST, 0x256c6c69, 0x20202000]
- llu bpf_insn_mov_imm64[DST, 0x256c6c75, 0x20202000]
- llx bpf_insn_mov_imm64[DST, 0x256c6c78, 0x20202000]
- s bpf_insn_mov_imm64[DST, 0x25732020, 0x20202000]
-]
-
-# (18) r1 = "%d "
-# (7b) *(u64 *)(r10 -8) = r1
-# (bf) r1 = r10
-# (07) r1 += -8
-# (b7) r2 = 8
-# (b7) r3 = X
-# (85) call bpf_trace_printk#-108352
-bpf_insn_trace_printk {
- insn1 bpf_insn_mov_printk_str_hex[BPF_REG_1]
- insn2 bpf_insn_st64_reg[BPF_REG_1, BPF_REG_10, -8]
- insn3 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_1]
- insn4 bpf_insn_op_imm[BPF_REG_1, BPF_ADD0, -8]
- insn5 bpf_insn_mov_imm[BPF_REG_2, 8]
- insn6 bpf_insn_mov_imm_any[BPF_REG_3]
- insn7 bpf_insn_call_helper_t[const[BPF_FUNC_trace_printk, int32]]
-}
-
-# (b7) r8 = 0
-# (7b) *(u64 *)(r10 -8) = r8
-# (b7) r8 = X
-# (7b) *(u64 *)(r10 -16) = r8
-# (bf) r1 = r10
-# (07) r1 += -8
-# (bf) r4 = r10
-# (07) r4 += -16
-# (b7) r2 = 8
-# (18) r3 = map[id:31][0]+0
-# (b7) r5 = 8
-# (85) call bpf_snprintf#168880
-bpf_insn_snprintf {
- insn1 bpf_insn_mov_imm[BPF_REG_8, 0]
- insn2 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -8]
- insn3 bpf_insn_mov_imm_any[BPF_REG_8]
- insn4 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -16]
- insn5 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_1]
- insn6 bpf_insn_op_imm[BPF_REG_1, BPF_ADD0, -8]
- insn7 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_4]
- insn8 bpf_insn_op_imm[BPF_REG_4, BPF_ADD0, -16]
- insn9 bpf_insn_mov_imm[BPF_REG_2, 8]
- insn10 bpf_insn_const_str[BPF_REG_3]
- insn11 bpf_insn_mov_imm[BPF_REG_5, 8]
- insn12 bpf_insn_call_helper_t[const[BPF_FUNC_snprintf, int32]]
-}
-
-# (18) r2 = map[id:10]
-# (b7) r3 = 2
-# (85) call bpf_tail_call#12
-# (b7) r0 = 0
-bpf_insn_tail_call {
- insn1 bpf_insn_tail_call_map_fd[BPF_REG_2]
- insn2 bpf_insn_mov_imm[BPF_REG_3, 0]
- insn3 bpf_insn_call_helper_t[const[BPF_FUNC_tail_call, int32]]
- insn4 bpf_insn_mov_imm[BPF_REG_0, 0]
-}
-
-# (18) r1 = map[id:16]
-# (b7) r2 = 8
-# (b7) r3 = 0
-# (85) call bpf_ringbuf_reserve#320112
-# (bf) r9 = r0
-bpf_insn_ringbuf_reserve {
- insn1 bpf_insn_ringbuf_fd[BPF_REG_1]
- insn2 bpf_insn_mov_imm[BPF_REG_2, 20]
- insn3 bpf_insn_mov_imm[BPF_REG_3, 0]
- insn4 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_reserve, int32]]
- insn5 bpf_insn_mov_reg[BPF_REG_0, BPF_REG_9]
-}
-
-# (bf) r1 = r9
-# (b7) r2 = BPF_RB_X
-# (85) call bpf_ringbuf_{submit,discard}#322192
-# (bf) r0 = 0
-bpf_insn_ringbuf_free {
- insn1 bpf_insn_mov_reg[BPF_REG_9, BPF_REG_1]
- insn2 bpf_insn_mov_imm_flag[BPF_REG_2, bpf_ringbuf_wakeup_flags]
- insn3 bpf_insn_call_helper_t[flags[bpf_helpers_ringbuf_free, int32]]
- insn4 bpf_insn_mov_imm[BPF_REG_0, 0]
-}
-
-bpf_helpers_ringbuf_free = BPF_FUNC_ringbuf_submit, BPF_FUNC_ringbuf_discard
-
-# (18) r1 = map[id:16]
-# (b7) r2 = 0
-# (85) call bpf_ringbuf_query#322192
-bpf_insn_ringbuf_query {
- insn1 bpf_insn_tail_call_map_fd[BPF_REG_1]
- insn2 bpf_insn_mov_imm[BPF_REG_2, 0]
- insn3 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_query, int32]]
-}
-
-# (18) r1 = map[id:16]
-# (b7) r8 = X
-# (7b) *(u64 *)(r10 -8) = r8
-# (bf) r2 = r10
-# (07) r2 += -8
-# (b7) r3 = 8
-# (b7) r4 = BPF_RB_X
-# (85) call bpf_ringbuf_output#322192
-bpf_insn_ringbuf_output {
- insn1 bpf_insn_tail_call_map_fd[BPF_REG_1]
- insn2 bpf_insn_mov_imm_any[BPF_REG_8]
- insn3 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -8]
- insn4 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_2]
- insn5 bpf_insn_op_imm[BPF_REG_2, BPF_ADD0, -8]
- insn6 bpf_insn_mov_imm[BPF_REG_3, 8]
- insn7 bpf_insn_mov_imm_flag[BPF_REG_4, bpf_ringbuf_wakeup_flags]
- insn8 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_output, int32]]
-}
-
-define MAX_BPF_REG __MAX_BPF_REG
-
bpf_obj_pin_map [
generic bpf_obj_pin_map_generic
o_path bpf_obj_pin_map_o_path
@@ -1298,4 +792,3 @@ bpf_link_create_kprobe_multi_flags = BPF_F_KPROBE_MULTI_RETURN
nf_dev_hooks = NF_NETDEV_INGRESS, NF_NETDEV_EGRESS
bpf_link_create_netfilter_flags = BPF_F_NETFILTER_IP_DEFRAG
bpf_link_create_uprobe_multi_flags = BPF_F_UPROBE_MULTI_RETURN
-bpf_ringbuf_wakeup_flags = 0, BPF_RB_NO_WAKEUP, BPF_RB_FORCE_WAKEUP
diff --git a/sys/linux/bpf_prog.txt b/sys/linux/bpf_prog.txt
new file mode 100644
index 000000000..e9ceb7aba
--- /dev/null
+++ b/sys/linux/bpf_prog.txt
@@ -0,0 +1,510 @@
+# Copyright 2023 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.
+
+define BPF_LINE_INFO_SIZE sizeof(struct bpf_line_info)
+define BPF_FUNC_INFO_SIZE sizeof(struct bpf_func_info)
+define BPF_CORE_RELO_SIZE sizeof(struct bpf_core_relo)
+
+type bpf_prog_t[TYPE, ATTACH_TYPE, BTF_ID, PROG_FD] {
+ type TYPE
+ 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 ATTACH_TYPE
+ btf_fd fd_btf[opt]
+ func_info_rec_size const[BPF_FUNC_INFO_SIZE, int32]
+ func_info ptr64[in, bpf_func_info, opt]
+ func_info_cnt len[func_info, int32]
+ line_info_rec_size const[BPF_LINE_INFO_SIZE, int32]
+ line_info ptr64[in, bpf_line_info, opt]
+ line_info_cnt len[line_info, int32]
+ attach_btf_id BTF_ID
+ attach_prog_fd PROG_FD
+ core_relo_cnt len[core_relos, int32]
+ fd_array ptr64[in, array[fd_bpf_map], opt]
+ core_relos ptr64[in, array[bpf_core_relo], opt]
+ core_relo_rec_size const[BPF_CORE_RELO_SIZE, int32]
+ log_true_size int32
+}
+
+type bpf_prog bpf_prog_t[flags[bpf_prog_type, int32], flags[bpf_attach_type, int32], bpf_btf_id[opt], fd_bpf_prog[opt]]
+
+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_core_relo {
+# This is instruction index, so should not be too large.
+ insn_off int32[0:5]
+ type_id btf_type_id
+ access_str_off btf_opt_name_off
+ kind flags[bpf_core_relo_kind, int32]
+}
+
+bpf_instructions [
+ raw array[bpf_insn]
+ framed bpf_framed_program
+ ringbuf bpf_program_ringbuf
+] [varlen]
+
+bpf_framed_program {
+ initr0 bpf_insn_init_r0
+ body array[bpf_insn]
+ exit bpf_insn_exit
+} [packed]
+
+bpf_program_ringbuf {
+ initr0 bpf_insn_init_r0
+ reserve bpf_insn_ringbuf_reserve
+ null_check bpf_insn_null_check[BPF_REG_9]
+ body array[bpf_insn]
+ free bpf_insn_ringbuf_free
+ 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_helper
+ func bpf_insn_call_func
+ kfunc bpf_insn_call_kfunc
+ exit bpf_insn_exit
+ initr0 bpf_insn_init_r0
+ map_fd bpf_insn_map_fd
+ map_idx bpf_insn_map_idx
+ map_val bpf_insn_map_value
+ map_idx_val bpf_insn_map_idx_value
+ btf_id bpf_insn_btf_id
+ cb_func bpf_insn_cb_func
+ printk bpf_insn_trace_printk
+ snprintf bpf_insn_snprintf
+ tail_call bpf_insn_tail_call
+ ringbuf_query bpf_insn_ringbuf_query
+ ringbuf_output bpf_insn_ringbuf_output
+] [varlen]
+
+bpf_insn_generic {
+ code int8
+ dst int8:4
+ src int8:4
+ off int16
+ imm int32
+}
+
+type bpf_insn_ldst_t[CLASS, SZ, MODE, DST, SRC, OFF, IMM] {
+ code_class int8:3[CLASS]
+ code_size int8:2[SZ]
+ code_mode int8:3[MODE]
+ dst DST
+ src SRC
+ off OFF
+ imm IMM
+}
+
+type bpf_insn_ldst bpf_insn_ldst_t[bpf_ldst_insn, bpf_ldst_size, bpf_ldst_mode, flags[bpf_reg, int8:4], flags[bpf_reg, int8:4], flags[bpf_insn_offsets, int16], flags[bpf_insn_immediates, int32]]
+type bpf_insn_st64_reg[SRC, DST, OFF] bpf_insn_ldst_t[BPF_STX, BPF_DW0, BPF_MEM0, const[DST, int8:4], const[SRC, int8:4], const[OFF, int16], const[0, 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, BPF_MEMSX0
+
+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
+define BPF_MEMSX0 BPF_MEMSX >> 5
+
+type bpf_insn_alu_t[CLASS, SOURCE, OP, DST, SRC, OFF, IMM] {
+ code_class int8:3[CLASS]
+ code_s int8:1[SOURCE]
+ code_op int8:4[OP]
+ dst DST
+ src SRC
+ off OFF
+ imm IMM
+}
+
+type bpf_insn_alu bpf_insn_alu_t[bpf_alu_insn, bpf_alu_source, bpf_alu_op, flags[bpf_reg, int8:4], flags[bpf_reg, int8:4], flags[bpf_insn_offsets, int16], flags[bpf_insn_immediates, int32]]
+type bpf_insn_mov_imm[DST, IMM] bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_MOV0, const[DST, int8:4], const[0, int8:4], const[0, int16], const[IMM, int32]]
+type bpf_insn_mov_imm_any[DST] bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_MOV0, const[DST, int8:4], const[0, int8:4], const[0, int16], int32]
+type bpf_insn_mov_imm_flag[DST, FLAG] bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_MOV0, const[DST, int8:4], const[0, int8:4], const[0, int16], flags[FLAG, int32]]
+type bpf_insn_mov_reg[SRC, DST] bpf_insn_alu_t[BPF_ALU64, BPF_X0, BPF_MOV0, const[DST, int8:4], const[SRC, int8:4], const[0, int16], const[0, int32]]
+type bpf_insn_op_imm[DST, OP, IMM] bpf_insn_alu_t[BPF_ALU64, BPF_K0, OP, const[DST, int8:4], const[0, int8:4], const[0, int16], const[IMM, int32]]
+
+bpf_alu_source = BPF_K0, BPF_X0
+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
+
+define BPF_K0 BPF_K >> 3
+define BPF_X0 BPF_X >> 3
+
+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]
+}
+
+# Equivalent to: if reg != 0 goto +1;
+type bpf_insn_not_null_jmp[REG] {
+ code_class const[BPF_JMP, int8:3]
+ code_s const[BPF_K0, int8:1]
+ code_op const[BPF_JNE0, int8:4]
+ dst const[REG, int8:4]
+ src const[0, int8:4]
+ off const[1, int16]
+ imm const[0, 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
+
+type bpf_insn_call_helper_t[FUNC] {
+ code const[bpf_call_code, int8]
+ regs const[0, int8]
+ off const[0, int16]
+ func FUNC
+}
+
+type bpf_insn_call_helper bpf_insn_call_helper_t[int32[0:__BPF_FUNC_MAX_ID]]
+
+bpf_insn_call_func {
+ code const[bpf_call_code, int8]
+ dst const[0, int8:4]
+ src const[BPF_PSEUDO_CALL, int8:4]
+ off const[0, int16]
+# NEED: to limit the call offset to the program size, we'd need support for path expressions inside ranges of values.
+ func int32[-8:8]
+}
+
+bpf_insn_call_kfunc {
+ code const[bpf_call_code, int8]
+ dst const[0, int8:4]
+ src const[BPF_PSEUDO_KFUNC_CALL, int8:4]
+ off const[0, int16]
+ kfunc btf_type_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
+}
+
+type bpf_insn_mov_imm64[DST, IMM1, IMM2] {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst const[DST, int8:4]
+ src const[0, int8:4]
+ off const[0, int16]
+ imm const[IMM1, int32]
+ code2 const[0, int8]
+ regs2 const[0, int8]
+ off2 const[0, int16]
+ imm2 const[IMM2, int32]
+}
+
+type bpf_insn_map_fd_t[DST, MAP_FD] {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst DST
+ src const[BPF_PSEUDO_MAP_FD, int8:4]
+ off const[0, int16]
+ imm MAP_FD
+ code2 const[0, int8]
+ regs2 const[0, int8]
+ off2 const[0, int16]
+ imm2 const[0, int32]
+}
+
+type bpf_insn_map_fd bpf_insn_map_fd_t[flags[bpf_reg, int8:4], fd_bpf_map]
+type bpf_insn_tail_call_map_fd[DST] bpf_insn_map_fd_t[const[DST, int8:4], tail_call_map]
+type bpf_insn_ringbuf_fd[DST] bpf_insn_map_fd_t[const[DST, int8:4], ringbuf_map_fd]
+
+bpf_insn_map_idx {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst flags[bpf_reg, int8:4]
+ src const[BPF_PSEUDO_MAP_IDX, int8:4]
+ off const[0, int16]
+ imm map_fd_id
+ code2 const[0, int8]
+ regs2 const[0, int8]
+ off2 const[0, int16]
+ imm2 const[0, int32]
+}
+
+type bpf_insn_map_value_t[DST, MAP_FD, VALUE_OFFSET] {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst DST
+ src const[BPF_PSEUDO_MAP_VALUE, int8:4]
+ off const[0, int16]
+ imm MAP_FD
+ code2 const[0, int8]
+ regs2 const[0, int8]
+ off2 const[0, int16]
+ imm2 VALUE_OFFSET
+}
+
+type bpf_insn_map_value bpf_insn_map_value_t[flags[bpf_reg, int8:4], fd_bpf_map, int32]
+type bpf_insn_const_str[DST] bpf_insn_map_value_t[const[DST, int8:4], bpf_frozen_const_str, const[0, int32]]
+
+bpf_insn_map_idx_value {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst flags[bpf_reg, int8:4]
+ src const[BPF_PSEUDO_MAP_IDX_VALUE, int8:4]
+ off const[0, int16]
+ imm map_fd_id
+ code2 const[0, int8]
+ regs2 const[0, int8]
+ off2 const[0, int16]
+ imm2 int32
+}
+
+bpf_insn_cb_func {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst flags[bpf_reg, int8:4]
+ src const[BPF_PSEUDO_FUNC, int8:4]
+ off const[0, int16]
+# NEED: to limit the call offset to the program size, we'd need support for path expressions inside ranges of values.
+ imm int32[-8:8]
+ code2 const[0, int8]
+ regs2 const[0, int8]
+ off2 const[0, int16]
+ imm2 const[0, int32]
+}
+
+bpf_insn_btf_id {
+ code const[bpf_insn_load_imm_dw, int8]
+ dst flags[bpf_reg, int8:4]
+ src const[BPF_PSEUDO_BTF_ID, int8:4]
+ off const[0, int16]
+ imm btf_type_id
+ 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
+
+# Equivalent to:
+# if reg != 0 goto +1;
+# exit;
+# This is useful to check null pointers. We exit if the pointer is null and
+# continue the normal flow otherwise.
+type bpf_insn_null_check[REG] {
+ cond_jump bpf_insn_not_null_jmp[REG]
+ exit bpf_insn_exit
+}
+
+# Format specifiers for bpf_trace_printk, encoded as a zero-terminated string
+# of 7 characters. For example, field 'p' corresponds to "%p ".
+type bpf_insn_mov_printk_str_hex[DST] [
+ p bpf_insn_mov_imm64[DST, 0x25702020, 0x20202000]
+ d bpf_insn_mov_imm64[DST, 0x25642020, 0x20202000]
+ i bpf_insn_mov_imm64[DST, 0x25692020, 0x20202000]
+ u bpf_insn_mov_imm64[DST, 0x25752020, 0x20202000]
+ x bpf_insn_mov_imm64[DST, 0x25782020, 0x20202000]
+ ld bpf_insn_mov_imm64[DST, 0x256c6420, 0x20202000]
+ li bpf_insn_mov_imm64[DST, 0x256c6920, 0x20202000]
+ lu bpf_insn_mov_imm64[DST, 0x256c7520, 0x20202000]
+ lx bpf_insn_mov_imm64[DST, 0x256c7820, 0x20202000]
+ lld bpf_insn_mov_imm64[DST, 0x256c6c64, 0x20202000]
+ lli bpf_insn_mov_imm64[DST, 0x256c6c69, 0x20202000]
+ llu bpf_insn_mov_imm64[DST, 0x256c6c75, 0x20202000]
+ llx bpf_insn_mov_imm64[DST, 0x256c6c78, 0x20202000]
+ s bpf_insn_mov_imm64[DST, 0x25732020, 0x20202000]
+]
+
+# (18) r1 = "%d "
+# (7b) *(u64 *)(r10 -8) = r1
+# (bf) r1 = r10
+# (07) r1 += -8
+# (b7) r2 = 8
+# (b7) r3 = X
+# (85) call bpf_trace_printk#-108352
+bpf_insn_trace_printk {
+ insn1 bpf_insn_mov_printk_str_hex[BPF_REG_1]
+ insn2 bpf_insn_st64_reg[BPF_REG_1, BPF_REG_10, -8]
+ insn3 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_1]
+ insn4 bpf_insn_op_imm[BPF_REG_1, BPF_ADD0, -8]
+ insn5 bpf_insn_mov_imm[BPF_REG_2, 8]
+ insn6 bpf_insn_mov_imm_any[BPF_REG_3]
+ insn7 bpf_insn_call_helper_t[const[BPF_FUNC_trace_printk, int32]]
+}
+
+# (b7) r8 = 0
+# (7b) *(u64 *)(r10 -8) = r8
+# (b7) r8 = X
+# (7b) *(u64 *)(r10 -16) = r8
+# (bf) r1 = r10
+# (07) r1 += -8
+# (bf) r4 = r10
+# (07) r4 += -16
+# (b7) r2 = 8
+# (18) r3 = map[id:31][0]+0
+# (b7) r5 = 8
+# (85) call bpf_snprintf#168880
+bpf_insn_snprintf {
+ insn1 bpf_insn_mov_imm[BPF_REG_8, 0]
+ insn2 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -8]
+ insn3 bpf_insn_mov_imm_any[BPF_REG_8]
+ insn4 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -16]
+ insn5 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_1]
+ insn6 bpf_insn_op_imm[BPF_REG_1, BPF_ADD0, -8]
+ insn7 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_4]
+ insn8 bpf_insn_op_imm[BPF_REG_4, BPF_ADD0, -16]
+ insn9 bpf_insn_mov_imm[BPF_REG_2, 8]
+ insn10 bpf_insn_const_str[BPF_REG_3]
+ insn11 bpf_insn_mov_imm[BPF_REG_5, 8]
+ insn12 bpf_insn_call_helper_t[const[BPF_FUNC_snprintf, int32]]
+}
+
+# (18) r2 = map[id:10]
+# (b7) r3 = 2
+# (85) call bpf_tail_call#12
+# (b7) r0 = 0
+bpf_insn_tail_call {
+ insn1 bpf_insn_tail_call_map_fd[BPF_REG_2]
+ insn2 bpf_insn_mov_imm[BPF_REG_3, 0]
+ insn3 bpf_insn_call_helper_t[const[BPF_FUNC_tail_call, int32]]
+ insn4 bpf_insn_mov_imm[BPF_REG_0, 0]
+}
+
+# (18) r1 = map[id:16]
+# (b7) r2 = 8
+# (b7) r3 = 0
+# (85) call bpf_ringbuf_reserve#320112
+# (bf) r9 = r0
+bpf_insn_ringbuf_reserve {
+ insn1 bpf_insn_ringbuf_fd[BPF_REG_1]
+ insn2 bpf_insn_mov_imm[BPF_REG_2, 20]
+ insn3 bpf_insn_mov_imm[BPF_REG_3, 0]
+ insn4 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_reserve, int32]]
+ insn5 bpf_insn_mov_reg[BPF_REG_0, BPF_REG_9]
+}
+
+# (bf) r1 = r9
+# (b7) r2 = BPF_RB_X
+# (85) call bpf_ringbuf_{submit,discard}#322192
+# (bf) r0 = 0
+bpf_insn_ringbuf_free {
+ insn1 bpf_insn_mov_reg[BPF_REG_9, BPF_REG_1]
+ insn2 bpf_insn_mov_imm_flag[BPF_REG_2, bpf_ringbuf_wakeup_flags]
+ insn3 bpf_insn_call_helper_t[flags[bpf_helpers_ringbuf_free, int32]]
+ insn4 bpf_insn_mov_imm[BPF_REG_0, 0]
+}
+
+bpf_helpers_ringbuf_free = BPF_FUNC_ringbuf_submit, BPF_FUNC_ringbuf_discard
+
+# (18) r1 = map[id:16]
+# (b7) r2 = 0
+# (85) call bpf_ringbuf_query#322192
+bpf_insn_ringbuf_query {
+ insn1 bpf_insn_tail_call_map_fd[BPF_REG_1]
+ insn2 bpf_insn_mov_imm[BPF_REG_2, 0]
+ insn3 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_query, int32]]
+}
+
+# (18) r1 = map[id:16]
+# (b7) r8 = X
+# (7b) *(u64 *)(r10 -8) = r8
+# (bf) r2 = r10
+# (07) r2 += -8
+# (b7) r3 = 8
+# (b7) r4 = BPF_RB_X
+# (85) call bpf_ringbuf_output#322192
+bpf_insn_ringbuf_output {
+ insn1 bpf_insn_tail_call_map_fd[BPF_REG_1]
+ insn2 bpf_insn_mov_imm_any[BPF_REG_8]
+ insn3 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -8]
+ insn4 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_2]
+ insn5 bpf_insn_op_imm[BPF_REG_2, BPF_ADD0, -8]
+ insn6 bpf_insn_mov_imm[BPF_REG_3, 8]
+ insn7 bpf_insn_mov_imm_flag[BPF_REG_4, bpf_ringbuf_wakeup_flags]
+ insn8 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_output, int32]]
+}
+
+define MAX_BPF_REG __MAX_BPF_REG
+
+bpf_ringbuf_wakeup_flags = 0, BPF_RB_NO_WAKEUP, BPF_RB_FORCE_WAKEUP