Skip to content

Commit a137169

Browse files
committed
overhaul handle_helper_calls
1 parent 3c976b8 commit a137169

3 files changed

Lines changed: 65 additions & 17 deletions

File tree

pythonbpf/bpf_helper_handler.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def bpf_ktime_get_ns_emitter(call, map_ptr, module, builder, func, local_sym_tab
1616
return result
1717

1818

19-
def bpf_map_lookup_elem_emitter(call, map_ptr, module, builder, local_sym_tab=None, struct_sym_tab=None):
19+
def bpf_map_lookup_elem_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None):
2020
"""
2121
Emit LLVM IR for bpf_map_lookup_elem helper function call.
2222
"""
@@ -172,7 +172,7 @@ def bpf_printk_emitter(call, map_ptr, module, builder, func, local_sym_tab=None)
172172
ir.IntType(32), len(fmt_str))], tail=True)
173173

174174

175-
def bpf_map_update_elem_emitter(call, map_ptr, module, builder, local_sym_tab=None, struct_sym_tab=None):
175+
def bpf_map_update_elem_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None):
176176
"""
177177
Emit LLVM IR for bpf_map_update_elem helper function call.
178178
Expected call signature: map.update(key, value, flags=0)
@@ -268,7 +268,7 @@ def bpf_map_update_elem_emitter(call, map_ptr, module, builder, local_sym_tab=No
268268
return result
269269

270270

271-
def bpf_map_delete_elem_emitter(call, map_ptr, module, builder, local_sym_tab=None, struct_sym_tab=None):
271+
def bpf_map_delete_elem_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None):
272272
"""
273273
Emit LLVM IR for bpf_map_delete_elem helper function call.
274274
Expected call signature: map.delete(key)
@@ -340,8 +340,31 @@ def bpf_get_current_pid_tgid_emitter(call, map_ptr, module, builder, func, local
340340
return pid
341341

342342

343-
def bpf_perf_event_output_handler(call, map_ptr, module, builder, local_sym_tab=None, struct_sym_tab=None):
344-
pass
343+
def bpf_perf_event_output_handler(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None, local_var_metadata=None):
344+
if len(call.args) != 1:
345+
raise ValueError("Perf event output expects exactly one argument (data), got "
346+
f"{len(call.args)}")
347+
data_arg = call.args[0]
348+
ctx_ptr = func.args[0] # First argument to the function is ctx
349+
350+
if isinstance(data_arg, ast.Name):
351+
data_name = data_arg.id
352+
if local_sym_tab and data_name in local_sym_tab:
353+
data_ptr = local_sym_tab[data_name]
354+
else:
355+
raise ValueError(
356+
f"Data variable {data_name} not found in local symbol table.")
357+
# Check is data_name is a struct
358+
if local_var_metadata and data_name in local_var_metadata:
359+
data_type = local_var_metadata[data_name]
360+
if data_type in struct_sym_tab:
361+
struct_info = struct_sym_tab[data_type]
362+
data_size = 0
363+
for field_type in struct_info["type"].elements:
364+
if isinstance(field_type, ir.IntType):
365+
data_size += field_type.width // 8
366+
elif isinstance(field_type, ir.PointerType):
367+
data_size += 8
345368

346369

347370
helper_func_list = {
@@ -355,7 +378,7 @@ def bpf_perf_event_output_handler(call, map_ptr, module, builder, local_sym_tab=
355378
}
356379

357380

358-
def handle_helper_call(call, module, builder, func, local_sym_tab=None, map_sym_tab=None, struct_sym_tab=None):
381+
def handle_helper_call(call, module, builder, func, local_sym_tab=None, map_sym_tab=None, struct_sym_tab=None, local_var_metadata=None):
359382
if isinstance(call.func, ast.Name):
360383
func_name = call.func.id
361384
if func_name in helper_func_list:
@@ -372,14 +395,29 @@ def handle_helper_call(call, module, builder, func, local_sym_tab=None, map_sym_
372395
if map_sym_tab and map_name in map_sym_tab:
373396
map_ptr = map_sym_tab[map_name]
374397
if method_name in helper_func_list:
398+
print(local_var_metadata)
375399
return helper_func_list[method_name](
376-
call, map_ptr, module, builder, local_sym_tab, struct_sym_tab)
400+
call, map_ptr, module, builder, func, local_sym_tab, struct_sym_tab, local_var_metadata)
377401
else:
378402
raise NotImplementedError(
379403
f"Map method {method_name} is not implemented as a helper function.")
380404
else:
381405
raise ValueError(
382406
f"Map variable {map_name} not found in symbol tables.")
407+
elif isinstance(call.func.value, ast.Name):
408+
obj_name = call.func.value.id
409+
method_name = call.func.attr
410+
if map_sym_tab and obj_name in map_sym_tab:
411+
map_ptr = map_sym_tab[obj_name]
412+
if method_name in helper_func_list:
413+
return helper_func_list[method_name](
414+
call, map_ptr, module, builder, func, local_sym_tab, struct_sym_tab, local_var_metadata)
415+
else:
416+
raise NotImplementedError(
417+
f"Map method {method_name} is not implemented as a helper function.")
418+
else:
419+
raise ValueError(
420+
f"Map variable {obj_name} not found in symbol tables.")
383421
else:
384422
raise NotImplementedError(
385423
"Attribute not supported for map method calls.")

pythonbpf/expr_pass.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from llvmlite import ir
33

44

5-
def eval_expr(func, module, builder, expr, local_sym_tab, map_sym_tab):
5+
def eval_expr(func, module, builder, expr, local_sym_tab, map_sym_tab, structs_sym_tab=None, local_var_metadata=None):
66
print(f"Evaluating expression: {expr}")
77
if isinstance(expr, ast.Name):
88
if expr.id in local_sym_tab:
@@ -50,22 +50,31 @@ def eval_expr(func, module, builder, expr, local_sym_tab, map_sym_tab):
5050
# check for helpers
5151
if expr.func.id in helper_func_list:
5252
return handle_helper_call(
53-
expr, module, builder, func, local_sym_tab, map_sym_tab)
53+
expr, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata)
5454
elif isinstance(expr.func, ast.Attribute):
55+
print(f"Handling method call: {ast.dump(expr.func)}")
5556
if isinstance(expr.func.value, ast.Call) and isinstance(expr.func.value.func, ast.Name):
5657
method_name = expr.func.attr
5758
if method_name in helper_func_list:
5859
return handle_helper_call(
59-
expr, module, builder, func, local_sym_tab, map_sym_tab)
60+
expr, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata)
61+
elif isinstance(expr.func.value, ast.Name):
62+
obj_name = expr.func.value.id
63+
method_name = expr.func.attr
64+
if obj_name in map_sym_tab:
65+
if method_name in helper_func_list:
66+
return handle_helper_call(
67+
expr, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata)
6068
print("Unsupported expression evaluation")
6169
return None
6270

6371

64-
def handle_expr(func, module, builder, expr, local_sym_tab, map_sym_tab):
72+
def handle_expr(func, module, builder, expr, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata):
6573
"""Handle expression statements in the function body."""
6674
print(f"Handling expression: {ast.dump(expr)}")
6775
call = expr.value
6876
if isinstance(call, ast.Call):
69-
eval_expr(func, module, builder, call, local_sym_tab, map_sym_tab)
77+
eval_expr(func, module, builder, call, local_sym_tab,
78+
map_sym_tab, structs_sym_tab, local_var_metadata)
7079
else:
7180
print("Unsupported expression type")

pythonbpf/functions_pass.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab, struc
5757
ir.Constant(ir.IntType(32), field_idx)],
5858
inbounds=True)
5959
val = eval_expr(func, module, builder, rval,
60-
local_sym_tab, map_sym_tab)
60+
local_sym_tab, map_sym_tab, structs_sym_tab)
6161
if val is None:
6262
print("Failed to evaluate struct field assignment")
6363
return
@@ -100,14 +100,14 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab, struc
100100
# var = builder.alloca(ir.IntType(64), name=var_name)
101101
# var.align = 8
102102
val = handle_helper_call(
103-
rval, module, builder, None, local_sym_tab, map_sym_tab, structs_sym_tab)
103+
rval, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata)
104104
builder.store(val, local_sym_tab[var_name])
105105
# local_sym_tab[var_name] = var
106106
print(f"Assigned constant {rval.func.id} to {var_name}")
107107
elif call_type == "deref" and len(rval.args) == 1:
108108
print(f"Handling deref assignment {ast.dump(rval)}")
109109
val = eval_expr(func, module, builder, rval,
110-
local_sym_tab, map_sym_tab)
110+
local_sym_tab, map_sym_tab, structs_sym_tab)
111111
if val is None:
112112
print("Failed to evaluate deref argument")
113113
return
@@ -139,7 +139,7 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab, struc
139139
map_ptr = map_sym_tab[map_name]
140140
if method_name in helper_func_list:
141141
val = handle_helper_call(
142-
rval, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab)
142+
rval, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata)
143143
# var = builder.alloca(ir.IntType(64), name=var_name)
144144
# var.align = 8
145145
builder.store(val, local_sym_tab[var_name])
@@ -261,7 +261,8 @@ def handle_if(func, module, builder, stmt, map_sym_tab, local_sym_tab):
261261
def process_stmt(func, module, builder, stmt, local_sym_tab, map_sym_tab, structs_sym_tab, did_return, ret_type=ir.IntType(64)):
262262
print(f"Processing statement: {ast.dump(stmt)}")
263263
if isinstance(stmt, ast.Expr):
264-
handle_expr(func, module, builder, stmt, local_sym_tab, map_sym_tab)
264+
handle_expr(func, module, builder, stmt, local_sym_tab,
265+
map_sym_tab, structs_sym_tab, local_var_metadata)
265266
elif isinstance(stmt, ast.Assign):
266267
handle_assign(func, module, builder, stmt, map_sym_tab,
267268
local_sym_tab, structs_sym_tab)

0 commit comments

Comments
 (0)