diff --git a/demo/pybpf.py b/demo/pybpf.py index f6a7ac7..329c3fa 100644 --- a/demo/pybpf.py +++ b/demo/pybpf.py @@ -1,9 +1,14 @@ from pythonbpf import bpf, map, section, bpfglobal, compile -from pythonbpf.helpers import ktime +from pythonbpf.helpers import ktime, deref from pythonbpf.maps import HashMap from ctypes import c_void_p, c_int64, c_uint64 +# Instructions to how to run this program +# 1. Install PythonBPF: pip install pythonbpf +# 2. Run the program: python demo/pybpf.py +# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf.o +# 4. Start a Python repl and `import os` and then keep entering `os.sync()` to see reponses. @bpf @map @@ -12,16 +17,20 @@ def last() -> HashMap: @bpf -@section("tracepoint/syscalls/sys_sync") +@section("tracepoint/syscalls/sys_enter_sync") def do_trace(ctx: c_void_p) -> c_int64: key = 0 tsp = last().lookup(key) if tsp: - delta = (ktime() - tsp) + kt = ktime() + delta = (kt - tsp) if delta < 1000000000: time_ms = (delta // 1000000) print(f"sync called within last second, last {time_ms} ms ago") last().delete(key) + else: + kt = ktime() + last().update(key, kt) return c_int64(0) diff --git a/examples/execve3.py b/examples/execve3.py index e0fe795..88ed105 100644 --- a/examples/execve3.py +++ b/examples/execve3.py @@ -35,9 +35,11 @@ def hello_again(ctx: c_void_p) -> c_int64: ts = ktime() last().update(key, ts) - keema = 8 - keeda = keema * keema - print(f"this is a variable {keeda}") + va = 8 + nm = 5 ^ va + al = 6 & 3 + ru = (nm + al) + al + print(f"this is a variable {ru}") # st = "st" # last().update(key, ts) diff --git a/pythonbpf/binary_ops.py b/pythonbpf/binary_ops.py index d8add0d..91e73bd 100644 --- a/pythonbpf/binary_ops.py +++ b/pythonbpf/binary_ops.py @@ -1,7 +1,21 @@ import ast from llvmlite import ir -def handle_binary_op(rval, module, builder, var_name, local_sym_tab, map_sym_tab): + +def recursive_dereferencer(var, builder): + """ dereference until primitive type comes out""" + if var.type == ir.PointerType(ir.PointerType(ir.IntType(64))): + a = builder.load(var) + return recursive_dereferencer(a, builder) + elif var.type == ir.PointerType(ir.IntType(64)): + a = builder.load(var) + return recursive_dereferencer(a, builder) + elif var.type == ir.IntType(64): + return var + else: + raise TypeError(f"Unsupported type for dereferencing: {var.type}") + +def handle_binary_op(rval, module, builder, var_name, local_sym_tab, map_sym_tab, func): print(module) left = rval.left right = rval.right @@ -10,7 +24,7 @@ def handle_binary_op(rval, module, builder, var_name, local_sym_tab, map_sym_tab # Handle left operand if isinstance(left, ast.Name): if left.id in local_sym_tab: - left = builder.load(local_sym_tab[left.id]) + left = recursive_dereferencer(local_sym_tab[left.id], builder) else: raise SyntaxError(f"Undefined variable: {left.id}") elif isinstance(left, ast.Constant): @@ -20,7 +34,7 @@ def handle_binary_op(rval, module, builder, var_name, local_sym_tab, map_sym_tab if isinstance(right, ast.Name): if right.id in local_sym_tab: - right = builder.load(local_sym_tab[right.id]) # Dereference the pre-assigned value + right = recursive_dereferencer(local_sym_tab[right.id], builder) else: raise SyntaxError(f"Undefined variable: {right.id}") elif isinstance(right, ast.Constant): @@ -60,5 +74,8 @@ def handle_binary_op(rval, module, builder, var_name, local_sym_tab, map_sym_tab elif isinstance(op, ast.BitAnd): builder.store(builder.and_(left, right), local_sym_tab[var_name]) + elif isinstance(op, ast.FloorDiv): + builder.store(builder.udiv(left, right), + local_sym_tab[var_name]) else: raise SyntaxError("Unsupported binary operation") diff --git a/pythonbpf/functions_pass.py b/pythonbpf/functions_pass.py index aa09f13..7b7c05e 100644 --- a/pythonbpf/functions_pass.py +++ b/pythonbpf/functions_pass.py @@ -111,7 +111,7 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab): print("Unsupported assignment call function type") elif isinstance(rval, ast.BinOp): handle_binary_op(rval, module, builder, var_name, - local_sym_tab, map_sym_tab) + local_sym_tab, map_sym_tab, func) else: print("Unsupported assignment value type") @@ -129,6 +129,15 @@ def handle_cond(func, module, builder, cond, local_sym_tab, map_sym_tab): if cond.id in local_sym_tab: var = local_sym_tab[cond.id] val = builder.load(var) + if val.type != ir.IntType(1): + # Convert nonzero values to true, zero to false + if isinstance(val.type, ir.PointerType): + # For pointer types, compare with null pointer + zero = ir.Constant(val.type, None) + else: + # For integer types, compare with zero + zero = ir.Constant(val.type, 0) + val = builder.icmp_signed("!=", val, zero) return val else: print(f"Undefined variable {cond.id} in condition")