add ringbuf reserve function

This commit is contained in:
2025-10-02 06:07:17 +05:30
parent 1a66887f48
commit 2a93a325ce
5 changed files with 82 additions and 33 deletions

View File

@ -41,14 +41,14 @@ repos:
- id: ruff
args: ["--fix", "--show-fixes"]
- id: ruff-format
exclude: ^(docs)|^(tests)|^(examples)
exclude: ^(tests/|examples/|docs/)
# Checking static types
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.10.0"
hooks:
- id: mypy
exclude: ^(tests)|^(examples)
exclude: ^(tests/|examples/)
additional_dependencies: [types-setuptools]
# Changes tabs to spaces

View File

@ -22,9 +22,5 @@ def LICENSE() -> str:
b = BPF()
b.load_and_attach()
if b.is_loaded() and b.is_attached():
print("Successfully loaded and attached")
else:
print("Could not load successfully")
# Now cat /sys/kernel/debug/tracing/trace_pipe to see results of the execve syscall.

View File

@ -19,6 +19,7 @@ class BPFHelperID(Enum):
BPF_PRINTK = 6
BPF_GET_CURRENT_PID_TGID = 14
BPF_PERF_EVENT_OUTPUT = 25
BPF_RINGBUF_RESERVE = 131
@HelperHandlerRegistry.register("ktime")
@ -181,6 +182,66 @@ def bpf_map_update_elem_emitter(
return result, None
@HelperHandlerRegistry.register("reserve")
def bpf_ringbuf_reserve_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_reserve helper function call.
Expected call signature: ringbuf.reserve(size, flags=0)
"""
if not call.args or len(call.args) < 1 or len(call.args) > 2:
raise ValueError(
"Ringbuf reserve expects 1 or 2 args (size, flags), "
f"got {len(call.args)}"
)
# TODO: here, getting length of stuff does not actually work. need to fix this.
size_arg = call.args[0]
if isinstance(size_arg, ast.Constant):
size_val = ir.Constant(ir.IntType(64), size_arg.value)
elif isinstance(size_arg, ast.Name):
if size_arg.id not in local_sym_tab:
raise ValueError(
f"Variable '{size_arg.id}' not found in local symbol table"
)
size_val = builder.load(local_sym_tab[size_arg.id])
else:
raise NotImplementedError(f"Unsupported size argument type: {type(size_arg)}")
flags_arg = call.args[1] if len(call.args) > 1 else None
flags_val = get_flags_val(flags_arg, builder, local_sym_tab)
map_void_ptr = builder.bitcast(map_ptr, ir.PointerType())
# Args: (void* ringbuf, u64 size, u64 flags)
fn_type = ir.FunctionType(
ir.PointerType(),
[ir.PointerType(), ir.IntType(64), ir.IntType(64)],
var_arg=False,
)
fn_ptr_type = ir.PointerType(fn_type)
fn_addr = ir.Constant(ir.IntType(64), BPFHelperID.BPF_RINGBUF_RESERVE.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
result = builder.call(fn_ptr, [map_void_ptr, size_val, flags_const], tail=True)
return result, ir.PointerType()
@HelperHandlerRegistry.register("delete")
def bpf_map_delete_elem_emitter(
call,

View File

@ -28,22 +28,22 @@ int trace_execve(void *ctx)
// Reserve space in the ringbuffer
e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
if (!e)
return 0;
// Fill the struct with data
pid_tgid = bpf_get_current_pid_tgid();
e->pid = pid_tgid >> 32;
uid_gid = bpf_get_current_uid_gid();
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);
// if (!e)
// return 0;
//
// // Fill the struct with data
// pid_tgid = bpf_get_current_pid_tgid();
// e->pid = pid_tgid >> 32;
//
// uid_gid = bpf_get_current_uid_gid();
// 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);
return 0;
}

View File

@ -1,5 +1,5 @@
from pythonbpf import bpf, BPF, map, bpfglobal, section, compile, compile_to_ir
from pythonbpf.maps import RingBuf, HashMap
from pythonbpf import bpf, map, bpfglobal, section, compile, compile_to_ir
from pythonbpf.maps import RingBuf
from ctypes import c_int32, c_void_p
@ -9,17 +9,11 @@ from ctypes import c_int32, c_void_p
def mymap() -> RingBuf:
return RingBuf(max_entries=(1024))
@bpf
@map
def mymap2() -> HashMap:
return HashMap(key=c_int32, value=c_int32, max_entries=1024)
@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def random_section(ctx: c_void_p) -> c_int32:
print("Hello")
e = mymap().reserve(16)
return c_int32(0)
@ -31,5 +25,3 @@ def LICENSE() -> str:
compile_to_ir("ringbuf.py", "ringbuf.ll")
compile()
b = BPF()
b.load_and_attach()