mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2025-12-31 21:06:25 +00:00
Allow access from struct fields
This commit is contained in:
@ -26,10 +26,10 @@ def hello(ctx: c_void_p) -> c_int32:
|
||||
ts = ktime()
|
||||
process_id = pid()
|
||||
strobj = "hellohellohello"
|
||||
dataobj.pid = process_id
|
||||
dataobj.ts = ts
|
||||
dataobj.pid = pid()
|
||||
dataobj.ts = ktime()
|
||||
# dataobj.comm = strobj
|
||||
print(f"clone called at {ts} by pid {process_id}, comm {strobj}")
|
||||
print(f"clone called at {dataobj.ts} by pid {dataobj.pid}, comm {strobj}")
|
||||
events.output(dataobj)
|
||||
return c_int32(0)
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ from llvmlite import ir
|
||||
from .expr_pass import eval_expr
|
||||
|
||||
|
||||
def bpf_ktime_get_ns_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, local_var_metadata=None):
|
||||
def bpf_ktime_get_ns_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None, local_var_metadata=None):
|
||||
"""
|
||||
Emit LLVM IR for bpf_ktime_get_ns helper function call.
|
||||
"""
|
||||
@ -63,7 +63,7 @@ def bpf_map_lookup_elem_emitter(call, map_ptr, module, builder, func, local_sym_
|
||||
return result, ir.PointerType()
|
||||
|
||||
|
||||
def bpf_printk_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, local_var_metadata=None):
|
||||
def bpf_printk_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None, local_var_metadata=None):
|
||||
if not hasattr(func, "_fmt_counter"):
|
||||
func._fmt_counter = 0
|
||||
|
||||
@ -101,10 +101,42 @@ def bpf_printk_emitter(call, map_ptr, module, builder, func, local_sym_tab=None,
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
"Only integer and pointer types are supported in formatted values.")
|
||||
print("Formatted value variable:", var_ptr, var_type)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Variable {value.value.id} not found in local symbol table.")
|
||||
elif isinstance(value.value, ast.Attribute):
|
||||
# object field access from struct
|
||||
if isinstance(value.value.value, ast.Name) and local_sym_tab and value.value.value.id in local_sym_tab:
|
||||
var_name = value.value.value.id
|
||||
field_name = value.value.attr
|
||||
if local_var_metadata and var_name in local_var_metadata:
|
||||
var_type = local_var_metadata[var_name]
|
||||
if var_type in struct_sym_tab:
|
||||
struct_info = struct_sym_tab[var_type]
|
||||
if field_name in struct_info["fields"]:
|
||||
field_index = struct_info["fields"][field_name]
|
||||
field_type = struct_info["field_types"][field_index]
|
||||
if isinstance(field_type, ir.IntType):
|
||||
fmt_parts.append("%lld")
|
||||
exprs.append(value.value)
|
||||
elif field_type == ir.PointerType(ir.IntType(8)):
|
||||
fmt_parts.append("%s")
|
||||
exprs.append(value.value)
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
"Only integer and pointer types are supported in formatted values.")
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Field {field_name} not found in struct {var_type}.")
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Struct type {var_type} for variable {var_name} not found in struct symbol table.")
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Metadata for variable {var_name} not found in local variable metadata.")
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Variable {value.value.value.id} not found in local symbol table.")
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
"Only simple variable names are supported in formatted values.")
|
||||
@ -136,8 +168,9 @@ def bpf_printk_emitter(call, map_ptr, module, builder, func, local_sym_tab=None,
|
||||
"Warning: bpf_printk supports up to 3 arguments, extra arguments will be ignored.")
|
||||
|
||||
for expr in exprs[:3]:
|
||||
print(f"{ast.dump(expr)}")
|
||||
val, _ = eval_expr(func, module, builder,
|
||||
expr, local_sym_tab, None)
|
||||
expr, local_sym_tab, None, struct_sym_tab, local_var_metadata)
|
||||
if val:
|
||||
if isinstance(val.type, ir.PointerType):
|
||||
val = builder.ptrtoint(val, ir.IntType(64))
|
||||
@ -339,7 +372,7 @@ def bpf_map_delete_elem_emitter(call, map_ptr, module, builder, func, local_sym_
|
||||
return result, None
|
||||
|
||||
|
||||
def bpf_get_current_pid_tgid_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, local_var_metadata=None):
|
||||
def bpf_get_current_pid_tgid_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None, local_var_metadata=None):
|
||||
"""
|
||||
Emit LLVM IR for bpf_get_current_pid_tgid helper function call.
|
||||
"""
|
||||
@ -420,11 +453,12 @@ helper_func_list = {
|
||||
|
||||
|
||||
def handle_helper_call(call, module, builder, func, local_sym_tab=None, map_sym_tab=None, struct_sym_tab=None, local_var_metadata=None):
|
||||
print(local_var_metadata)
|
||||
if isinstance(call.func, ast.Name):
|
||||
func_name = call.func.id
|
||||
if func_name in helper_func_list:
|
||||
# it is not a map method call
|
||||
return helper_func_list[func_name](call, None, module, builder, func, local_sym_tab)
|
||||
return helper_func_list[func_name](call, None, module, builder, func, local_sym_tab, struct_sym_tab, local_var_metadata)
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
f"Function {func_name} is not implemented as a helper function.")
|
||||
|
||||
@ -4,6 +4,7 @@ from llvmlite import ir
|
||||
|
||||
def eval_expr(func, module, builder, expr, local_sym_tab, map_sym_tab, structs_sym_tab=None, local_var_metadata=None):
|
||||
print(f"Evaluating expression: {ast.dump(expr)}")
|
||||
print(local_var_metadata)
|
||||
if isinstance(expr, ast.Name):
|
||||
if expr.id in local_sym_tab:
|
||||
var = local_sym_tab[expr.id][0]
|
||||
@ -66,6 +67,25 @@ def eval_expr(func, module, builder, expr, local_sym_tab, map_sym_tab, structs_s
|
||||
if method_name in helper_func_list:
|
||||
return handle_helper_call(
|
||||
expr, module, builder, func, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata)
|
||||
elif isinstance(expr, ast.Attribute):
|
||||
if isinstance(expr.value, ast.Name):
|
||||
var_name = expr.value.id
|
||||
attr_name = expr.attr
|
||||
if var_name in local_sym_tab:
|
||||
var_ptr, var_type = local_sym_tab[var_name]
|
||||
print(f"Loading attribute "
|
||||
f"{attr_name} from variable {var_name}")
|
||||
print(f"Variable type: {var_type}, Variable ptr: {var_ptr}")
|
||||
print(local_var_metadata)
|
||||
if local_var_metadata and var_name in local_var_metadata:
|
||||
metadata = structs_sym_tab[local_var_metadata[var_name]]
|
||||
if attr_name in metadata["fields"]:
|
||||
field_idx = metadata["fields"][attr_name]
|
||||
gep = builder.gep(var_ptr, [ir.Constant(ir.IntType(32), 0),
|
||||
ir.Constant(ir.IntType(32), field_idx)])
|
||||
val = builder.load(gep)
|
||||
field_type = metadata["field_types"][field_idx]
|
||||
return val, field_type
|
||||
print("Unsupported expression evaluation")
|
||||
return None
|
||||
|
||||
@ -73,6 +93,7 @@ def eval_expr(func, module, builder, expr, local_sym_tab, map_sym_tab, structs_s
|
||||
def handle_expr(func, module, builder, expr, local_sym_tab, map_sym_tab, structs_sym_tab, local_var_metadata):
|
||||
"""Handle expression statements in the function body."""
|
||||
print(f"Handling expression: {ast.dump(expr)}")
|
||||
print(local_var_metadata)
|
||||
call = expr.value
|
||||
if isinstance(call, ast.Call):
|
||||
eval_expr(func, module, builder, call, local_sym_tab,
|
||||
|
||||
@ -282,6 +282,7 @@ def handle_if(func, module, builder, stmt, map_sym_tab, local_sym_tab, structs_s
|
||||
def process_stmt(func, module, builder, stmt, local_sym_tab, map_sym_tab, structs_sym_tab, did_return, ret_type=ir.IntType(64)):
|
||||
print(f"Processing statement: {ast.dump(stmt)}")
|
||||
if isinstance(stmt, ast.Expr):
|
||||
print(local_var_metadata)
|
||||
handle_expr(func, module, builder, stmt, local_sym_tab,
|
||||
map_sym_tab, structs_sym_tab, local_var_metadata)
|
||||
elif isinstance(stmt, ast.Assign):
|
||||
|
||||
Reference in New Issue
Block a user