mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2025-12-31 21:06:25 +00:00
Complete struct field assignment
This commit is contained in:
@ -9,7 +9,7 @@
|
|||||||
struct data_t {
|
struct data_t {
|
||||||
__u32 pid;
|
__u32 pid;
|
||||||
__u64 ts;
|
__u64 ts;
|
||||||
char comm[TASK_COMM_LEN];
|
// char comm[TASK_COMM_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define a perf event output map
|
// Define a perf event output map
|
||||||
@ -31,7 +31,7 @@ int hello(struct pt_regs *ctx)
|
|||||||
data.ts = bpf_ktime_get_ns();
|
data.ts = bpf_ktime_get_ns();
|
||||||
|
|
||||||
// Get current process name
|
// Get current process name
|
||||||
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
// bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
||||||
|
|
||||||
// Submit data to userspace via perf event
|
// Submit data to userspace via perf event
|
||||||
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
|
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
|
||||||
|
|||||||
@ -11,17 +11,21 @@ class data_t:
|
|||||||
pid: c_uint64
|
pid: c_uint64
|
||||||
ts: c_uint64
|
ts: c_uint64
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@map
|
@map
|
||||||
def events() -> PerfEventArray:
|
def events() -> PerfEventArray:
|
||||||
return PerfEventArray(key_size=c_int32, value_size=c_int32)
|
return PerfEventArray(key_size=c_int32, value_size=c_int32)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@section("tracepoint/syscalls/sys_enter_clone")
|
@section("tracepoint/syscalls/sys_enter_clone")
|
||||||
def hello(ctx: c_void_p) -> c_int32:
|
def hello(ctx: c_void_p) -> c_int32:
|
||||||
dataobj = data_t()
|
dataobj = data_t()
|
||||||
ts = ktime()
|
ts = ktime()
|
||||||
process_id = pid()
|
process_id = pid()
|
||||||
|
dataobj.pid = process_id
|
||||||
|
dataobj.ts = ts
|
||||||
print(f"clone called at {ts} by pid {process_id}")
|
print(f"clone called at {ts} by pid {process_id}")
|
||||||
return c_int32(0)
|
return c_int32(0)
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ def get_probe_string(func_node):
|
|||||||
return "helper"
|
return "helper"
|
||||||
|
|
||||||
|
|
||||||
def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
|
def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab, structs_sym_tab):
|
||||||
"""Handle assignment statements in the function body."""
|
"""Handle assignment statements in the function body."""
|
||||||
if len(stmt.targets) != 1:
|
if len(stmt.targets) != 1:
|
||||||
print("Unsupported multiassignment")
|
print("Unsupported multiassignment")
|
||||||
@ -36,12 +36,35 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
|
|||||||
num_types = ("c_int32", "c_int64", "c_uint32", "c_uint64")
|
num_types = ("c_int32", "c_int64", "c_uint32", "c_uint64")
|
||||||
|
|
||||||
target = stmt.targets[0]
|
target = stmt.targets[0]
|
||||||
if not isinstance(target, ast.Name):
|
print(f"Handling assignment to {ast.dump(target)}")
|
||||||
|
if not isinstance(target, ast.Name) and not isinstance(target, ast.Attribute):
|
||||||
print("Unsupported assignment target")
|
print("Unsupported assignment target")
|
||||||
return
|
return
|
||||||
var_name = target.id
|
var_name = target.id if isinstance(target, ast.Name) else target.value.id
|
||||||
rval = stmt.value
|
rval = stmt.value
|
||||||
if isinstance(rval, ast.Constant):
|
if isinstance(target, ast.Attribute):
|
||||||
|
# struct field assignment
|
||||||
|
field_name = target.attr
|
||||||
|
if var_name in local_sym_tab and var_name in local_var_metadata:
|
||||||
|
struct_type = local_var_metadata[var_name]
|
||||||
|
struct_info = structs_sym_tab[struct_type]
|
||||||
|
|
||||||
|
if field_name in struct_info["fields"]:
|
||||||
|
field_idx = struct_info["fields"][field_name]
|
||||||
|
struct_ptr = local_sym_tab[var_name]
|
||||||
|
field_ptr = builder.gep(
|
||||||
|
struct_ptr, [ir.Constant(ir.IntType(32), 0),
|
||||||
|
ir.Constant(ir.IntType(32), field_idx)],
|
||||||
|
inbounds=True)
|
||||||
|
val = eval_expr(func, module, builder, rval,
|
||||||
|
local_sym_tab, map_sym_tab)
|
||||||
|
if val is None:
|
||||||
|
print("Failed to evaluate struct field assignment")
|
||||||
|
return
|
||||||
|
builder.store(val, field_ptr)
|
||||||
|
print(f"Assigned to struct field {var_name}.{field_name}")
|
||||||
|
return
|
||||||
|
elif isinstance(rval, ast.Constant):
|
||||||
if isinstance(rval.value, bool):
|
if isinstance(rval.value, bool):
|
||||||
if rval.value:
|
if rval.value:
|
||||||
builder.store(ir.Constant(ir.IntType(1), 1),
|
builder.store(ir.Constant(ir.IntType(1), 1),
|
||||||
@ -92,10 +115,46 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
|
|||||||
builder.store(val, local_sym_tab[var_name])
|
builder.store(val, local_sym_tab[var_name])
|
||||||
# local_sym_tab[var_name] = var
|
# local_sym_tab[var_name] = var
|
||||||
print(f"Dereferenced and assigned to {var_name}")
|
print(f"Dereferenced and assigned to {var_name}")
|
||||||
|
elif call_type in structs_sym_tab and len(rval.args) == 0:
|
||||||
|
struct_info = structs_sym_tab[call_type]
|
||||||
|
ir_type = struct_info["type"]
|
||||||
|
# var = builder.alloca(ir_type, name=var_name)
|
||||||
|
# Null init
|
||||||
|
builder.store(ir.Constant(ir_type, None),
|
||||||
|
local_sym_tab[var_name])
|
||||||
|
local_var_metadata[var_name] = call_type
|
||||||
|
print(f"Assigned struct {call_type} to {var_name}")
|
||||||
|
# local_sym_tab[var_name] = var
|
||||||
else:
|
else:
|
||||||
print(f"Unsupported assignment call type: {call_type}")
|
print(f"Unsupported assignment call type: {call_type}")
|
||||||
elif isinstance(rval.func, ast.Attribute):
|
elif isinstance(rval.func, ast.Attribute):
|
||||||
if isinstance(rval.func.value, ast.Call) and isinstance(rval.func.value.func, ast.Name):
|
print(f"Assignment call attribute: {ast.dump(rval.func)}")
|
||||||
|
if isinstance(rval.func.value, ast.Name):
|
||||||
|
# probably a struct access
|
||||||
|
var_name = rval.func.value.id
|
||||||
|
field_name = rval.func.attr
|
||||||
|
|
||||||
|
print(f"Handling struct field assignment"
|
||||||
|
f"{var_name}.{field_name}")
|
||||||
|
|
||||||
|
if var_name in local_sym_tab and var_name in local_var_metadata:
|
||||||
|
struct_type = local_var_metadata[var_name]
|
||||||
|
struct_info = structs_sym_tab[struct_type]
|
||||||
|
|
||||||
|
if field_name in struct_info["fields"]:
|
||||||
|
field_idx = struct_info["fields"][field_name]
|
||||||
|
struct_ptr = local_sym_tab[var_name]
|
||||||
|
field_ptr = builder.gep(
|
||||||
|
struct_ptr, [ir.Constant(ir.IntType(32), 0),
|
||||||
|
ir.Constant(ir.IntType(32), field_idx)],
|
||||||
|
inbounds=True)
|
||||||
|
val = eval_expr(func, module, builder, rval,
|
||||||
|
local_sym_tab, map_sym_tab)
|
||||||
|
if val is None:
|
||||||
|
print("Failed to evaluate struct field assignment")
|
||||||
|
return
|
||||||
|
builder.store(val, field_ptr)
|
||||||
|
elif isinstance(rval.func.value, ast.Call) and isinstance(rval.func.value.func, ast.Name):
|
||||||
map_name = rval.func.value.func.id
|
map_name = rval.func.value.func.id
|
||||||
method_name = rval.func.attr
|
method_name = rval.func.attr
|
||||||
if map_name in map_sym_tab:
|
if map_name in map_sym_tab:
|
||||||
@ -226,7 +285,8 @@ def process_stmt(func, module, builder, stmt, local_sym_tab, map_sym_tab, struct
|
|||||||
if isinstance(stmt, ast.Expr):
|
if isinstance(stmt, ast.Expr):
|
||||||
handle_expr(func, module, builder, stmt, local_sym_tab, map_sym_tab)
|
handle_expr(func, module, builder, stmt, local_sym_tab, map_sym_tab)
|
||||||
elif isinstance(stmt, ast.Assign):
|
elif isinstance(stmt, ast.Assign):
|
||||||
handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab)
|
handle_assign(func, module, builder, stmt, map_sym_tab,
|
||||||
|
local_sym_tab, structs_sym_tab)
|
||||||
elif isinstance(stmt, ast.AugAssign):
|
elif isinstance(stmt, ast.AugAssign):
|
||||||
raise SyntaxError("Augmented assignment not supported")
|
raise SyntaxError("Augmented assignment not supported")
|
||||||
elif isinstance(stmt, ast.If):
|
elif isinstance(stmt, ast.If):
|
||||||
@ -304,9 +364,6 @@ def allocate_mem(module, builder, body, func, ret_type, map_sym_tab, local_sym_t
|
|||||||
struct_info = structs_sym_tab[call_type]
|
struct_info = structs_sym_tab[call_type]
|
||||||
ir_type = struct_info["type"]
|
ir_type = struct_info["type"]
|
||||||
var = builder.alloca(ir_type, name=var_name)
|
var = builder.alloca(ir_type, name=var_name)
|
||||||
|
|
||||||
# Null init
|
|
||||||
builder.store(ir.Constant(ir_type, None), var)
|
|
||||||
local_var_metadata[var_name] = call_type
|
local_var_metadata[var_name] = call_type
|
||||||
print(
|
print(
|
||||||
f"Pre-allocated variable {var_name} for struct {call_type}")
|
f"Pre-allocated variable {var_name} for struct {call_type}")
|
||||||
|
|||||||
Reference in New Issue
Block a user