Add recursive dereferencing and get example working

This commit is contained in:
2025-09-13 00:12:04 +05:30
parent ca203a1fdd
commit 9f858bd159
4 changed files with 47 additions and 10 deletions

View File

@ -1,9 +1,14 @@
from pythonbpf import bpf, map, section, bpfglobal, compile 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 pythonbpf.maps import HashMap
from ctypes import c_void_p, c_int64, c_uint64 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 @bpf
@map @map
@ -12,16 +17,20 @@ def last() -> HashMap:
@bpf @bpf
@section("tracepoint/syscalls/sys_sync") @section("tracepoint/syscalls/sys_enter_sync")
def do_trace(ctx: c_void_p) -> c_int64: def do_trace(ctx: c_void_p) -> c_int64:
key = 0 key = 0
tsp = last().lookup(key) tsp = last().lookup(key)
if tsp: if tsp:
delta = (ktime() - tsp) kt = ktime()
delta = (kt - tsp)
if delta < 1000000000: if delta < 1000000000:
time_ms = (delta // 1000000) time_ms = (delta // 1000000)
print(f"sync called within last second, last {time_ms} ms ago") print(f"sync called within last second, last {time_ms} ms ago")
last().delete(key) last().delete(key)
else:
kt = ktime()
last().update(key, kt)
return c_int64(0) return c_int64(0)

View File

@ -35,9 +35,11 @@ def hello_again(ctx: c_void_p) -> c_int64:
ts = ktime() ts = ktime()
last().update(key, ts) last().update(key, ts)
keema = 8 va = 8
keeda = keema * keema nm = 5 ^ va
print(f"this is a variable {keeda}") al = 6 & 3
ru = (nm + al) + al
print(f"this is a variable {ru}")
# st = "st" # st = "st"
# last().update(key, ts) # last().update(key, ts)

View File

@ -1,7 +1,21 @@
import ast import ast
from llvmlite import ir 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) print(module)
left = rval.left left = rval.left
right = rval.right 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 # Handle left operand
if isinstance(left, ast.Name): if isinstance(left, ast.Name):
if left.id in local_sym_tab: 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: else:
raise SyntaxError(f"Undefined variable: {left.id}") raise SyntaxError(f"Undefined variable: {left.id}")
elif isinstance(left, ast.Constant): 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 isinstance(right, ast.Name):
if right.id in local_sym_tab: 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: else:
raise SyntaxError(f"Undefined variable: {right.id}") raise SyntaxError(f"Undefined variable: {right.id}")
elif isinstance(right, ast.Constant): 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): elif isinstance(op, ast.BitAnd):
builder.store(builder.and_(left, right), builder.store(builder.and_(left, right),
local_sym_tab[var_name]) local_sym_tab[var_name])
elif isinstance(op, ast.FloorDiv):
builder.store(builder.udiv(left, right),
local_sym_tab[var_name])
else: else:
raise SyntaxError("Unsupported binary operation") raise SyntaxError("Unsupported binary operation")

View File

@ -111,7 +111,7 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
print("Unsupported assignment call function type") print("Unsupported assignment call function type")
elif isinstance(rval, ast.BinOp): elif isinstance(rval, ast.BinOp):
handle_binary_op(rval, module, builder, var_name, handle_binary_op(rval, module, builder, var_name,
local_sym_tab, map_sym_tab) local_sym_tab, map_sym_tab, func)
else: else:
print("Unsupported assignment value type") 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: if cond.id in local_sym_tab:
var = local_sym_tab[cond.id] var = local_sym_tab[cond.id]
val = builder.load(var) 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 return val
else: else:
print(f"Undefined variable {cond.id} in condition") print(f"Undefined variable {cond.id} in condition")