diff --git a/pythonbpf/helper/bpf_helper_handler.py b/pythonbpf/helper/bpf_helper_handler.py index aa7bf80..9002187 100644 --- a/pythonbpf/helper/bpf_helper_handler.py +++ b/pythonbpf/helper/bpf_helper_handler.py @@ -20,6 +20,7 @@ class BPFHelperID(Enum): BPF_GET_CURRENT_PID_TGID = 14 BPF_PERF_EVENT_OUTPUT = 25 BPF_RINGBUF_RESERVE = 131 + BPF_RINGBUF_SUBMIT = 132 @HelperHandlerRegistry.register("ktime") @@ -181,6 +182,54 @@ def bpf_map_update_elem_emitter( return result, None +@HelperHandlerRegistry.register("submit") +def bpf_ringbuf_submit_emitter( + call, + map_ptr, + module, + builder, + func, + local_sym_tab=None, + struct_sym_tab=None, + local_var_metadata=None, +): + """ + Emit LLVM IR for bpf_ringbuf_submit helper function call. + Expected call signature: ringbuf.submit(data, flags=0) + """ + if not call.args or len(call.args) < 1 or len(call.args) > 2: + raise ValueError( + "Ringbuf submit expects 1 or 2 args (data, flags), " + f"got {len(call.args)}" + ) + + data_arg = call.args[0] + data_ptr = get_or_create_ptr_from_arg(data_arg, builder, local_sym_tab) + + # Get flags argument (default to 0) + flags_arg = call.args[1] if len(call.args) > 1 else None + flags_val = get_flags_val(flags_arg, builder, local_sym_tab) + + # Returns: void + # Args: (void* data, u64 flags) + fn_type = ir.FunctionType( + ir.VoidType(), + [ir.PointerType(), ir.IntType(64)], + var_arg=False, + ) + fn_ptr_type = ir.PointerType(fn_type) + + fn_addr = ir.Constant(ir.IntType(64), BPFHelperID.BPF_RINGBUF_SUBMIT.value) + fn_ptr = builder.inttoptr(fn_addr, fn_ptr_type) + + if isinstance(flags_val, int): + flags_const = ir.Constant(ir.IntType(64), flags_val) + else: + flags_const = flags_val + + builder.call(fn_ptr, [data_ptr, flags_const], tail=True) + + return None @HelperHandlerRegistry.register("reserve") def bpf_ringbuf_reserve_emitter( diff --git a/tests/c-form/ringbuf.bpf.c b/tests/c-form/ringbuf.bpf.c index 88319f3..1a91ecb 100644 --- a/tests/c-form/ringbuf.bpf.c +++ b/tests/c-form/ringbuf.bpf.c @@ -22,14 +22,14 @@ struct { SEC("tracepoint/syscalls/sys_enter_execve") int trace_execve(void *ctx) { - struct event *e; - __u64 pid_tgid; - __u64 uid_gid; - +// struct event *e; +// __u64 pid_tgid; +// __u64 uid_gid; + __u32 *e; // Reserve space in the ringbuffer e = bpf_ringbuf_reserve(&events, sizeof(*e), 0); -// if (!e) -// return 0; + if (!e) + return 0; // // // Fill the struct with data // pid_tgid = bpf_get_current_pid_tgid(); @@ -39,11 +39,13 @@ int trace_execve(void *ctx) // e->uid = uid_gid & 0xFFFFFFFF; // // e->timestamp = bpf_ktime_get_ns(); -// + // bpf_get_current_comm(&e->comm, sizeof(e->comm)); // // // Submit the event to ringbuffer -// bpf_ringbuf_submit(e, 0); + __u32 temp = 32; + e = &temp; + bpf_ringbuf_submit(e, 0); return 0; } diff --git a/tests/passing_tests/ringbuf.py b/tests/passing_tests/ringbuf.py index 8d335fe..f4b71ff 100644 --- a/tests/passing_tests/ringbuf.py +++ b/tests/passing_tests/ringbuf.py @@ -1,4 +1,4 @@ -from pythonbpf import bpf, map, bpfglobal, section, compile, compile_to_ir +from pythonbpf import bpf, map, bpfglobal, section, compile, compile_to_ir, BPF from pythonbpf.maps import RingBuf from ctypes import c_int32, c_void_p @@ -13,7 +13,9 @@ def mymap() -> RingBuf: @section("tracepoint/syscalls/sys_enter_clone") def random_section(ctx: c_void_p) -> c_int32: print("Hello") - e = mymap().reserve(16) + e = mymap().reserve(6) + if e: + mymap().submit(e) return c_int32(0) @@ -25,3 +27,7 @@ def LICENSE() -> str: compile_to_ir("ringbuf.py", "ringbuf.ll") compile() +b = BPF() +b.load_and_attach() +while True: + print("running") \ No newline at end of file