Skip to content

Commit 0f9a407

Browse files
committed
Complete struct field assignment
1 parent 36c2c0b commit 0f9a407

File tree

3 files changed

+72
-11
lines changed

3 files changed

+72
-11
lines changed

examples/c-form/ex6.bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
struct data_t {
1010
__u32 pid;
1111
__u64 ts;
12-
char comm[TASK_COMM_LEN];
12+
// char comm[TASK_COMM_LEN];
1313
};
1414

1515
// Define a perf event output map
@@ -31,7 +31,7 @@ int hello(struct pt_regs *ctx)
3131
data.ts = bpf_ktime_get_ns();
3232

3333
// Get current process name
34-
bpf_get_current_comm(&data.comm, sizeof(data.comm));
34+
// bpf_get_current_comm(&data.comm, sizeof(data.comm));
3535

3636
// Submit data to userspace via perf event
3737
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,

examples/execve5.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@ class data_t:
1111
pid: c_uint64
1212
ts: c_uint64
1313

14+
1415
@bpf
1516
@map
1617
def events() -> PerfEventArray:
1718
return PerfEventArray(key_size=c_int32, value_size=c_int32)
1819

20+
1921
@bpf
2022
@section("tracepoint/syscalls/sys_enter_clone")
2123
def hello(ctx: c_void_p) -> c_int32:
2224
dataobj = data_t()
2325
ts = ktime()
2426
process_id = pid()
27+
dataobj.pid = process_id
28+
dataobj.ts = ts
2529
print(f"clone called at {ts} by pid {process_id}")
2630
return c_int32(0)
2731

pythonbpf/functions_pass.py

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def get_probe_string(func_node):
2727
return "helper"
2828

2929

30-
def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
30+
def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab, structs_sym_tab):
3131
"""Handle assignment statements in the function body."""
3232
if len(stmt.targets) != 1:
3333
print("Unsupported multiassignment")
@@ -36,12 +36,35 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
3636
num_types = ("c_int32", "c_int64", "c_uint32", "c_uint64")
3737

3838
target = stmt.targets[0]
39-
if not isinstance(target, ast.Name):
39+
print(f"Handling assignment to {ast.dump(target)}")
40+
if not isinstance(target, ast.Name) and not isinstance(target, ast.Attribute):
4041
print("Unsupported assignment target")
4142
return
42-
var_name = target.id
43+
var_name = target.id if isinstance(target, ast.Name) else target.value.id
4344
rval = stmt.value
44-
if isinstance(rval, ast.Constant):
45+
if isinstance(target, ast.Attribute):
46+
# struct field assignment
47+
field_name = target.attr
48+
if var_name in local_sym_tab and var_name in local_var_metadata:
49+
struct_type = local_var_metadata[var_name]
50+
struct_info = structs_sym_tab[struct_type]
51+
52+
if field_name in struct_info["fields"]:
53+
field_idx = struct_info["fields"][field_name]
54+
struct_ptr = local_sym_tab[var_name]
55+
field_ptr = builder.gep(
56+
struct_ptr, [ir.Constant(ir.IntType(32), 0),
57+
ir.Constant(ir.IntType(32), field_idx)],
58+
inbounds=True)
59+
val = eval_expr(func, module, builder, rval,
60+
local_sym_tab, map_sym_tab)
61+
if val is None:
62+
print("Failed to evaluate struct field assignment")
63+
return
64+
builder.store(val, field_ptr)
65+
print(f"Assigned to struct field {var_name}.{field_name}")
66+
return
67+
elif isinstance(rval, ast.Constant):
4568
if isinstance(rval.value, bool):
4669
if rval.value:
4770
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):
92115
builder.store(val, local_sym_tab[var_name])
93116
# local_sym_tab[var_name] = var
94117
print(f"Dereferenced and assigned to {var_name}")
118+
elif call_type in structs_sym_tab and len(rval.args) == 0:
119+
struct_info = structs_sym_tab[call_type]
120+
ir_type = struct_info["type"]
121+
# var = builder.alloca(ir_type, name=var_name)
122+
# Null init
123+
builder.store(ir.Constant(ir_type, None),
124+
local_sym_tab[var_name])
125+
local_var_metadata[var_name] = call_type
126+
print(f"Assigned struct {call_type} to {var_name}")
127+
# local_sym_tab[var_name] = var
95128
else:
96129
print(f"Unsupported assignment call type: {call_type}")
97130
elif isinstance(rval.func, ast.Attribute):
98-
if isinstance(rval.func.value, ast.Call) and isinstance(rval.func.value.func, ast.Name):
131+
print(f"Assignment call attribute: {ast.dump(rval.func)}")
132+
if isinstance(rval.func.value, ast.Name):
133+
# probably a struct access
134+
var_name = rval.func.value.id
135+
field_name = rval.func.attr
136+
137+
print(f"Handling struct field assignment"
138+
f"{var_name}.{field_name}")
139+
140+
if var_name in local_sym_tab and var_name in local_var_metadata:
141+
struct_type = local_var_metadata[var_name]
142+
struct_info = structs_sym_tab[struct_type]
143+
144+
if field_name in struct_info["fields"]:
145+
field_idx = struct_info["fields"][field_name]
146+
struct_ptr = local_sym_tab[var_name]
147+
field_ptr = builder.gep(
148+
struct_ptr, [ir.Constant(ir.IntType(32), 0),
149+
ir.Constant(ir.IntType(32), field_idx)],
150+
inbounds=True)
151+
val = eval_expr(func, module, builder, rval,
152+
local_sym_tab, map_sym_tab)
153+
if val is None:
154+
print("Failed to evaluate struct field assignment")
155+
return
156+
builder.store(val, field_ptr)
157+
elif isinstance(rval.func.value, ast.Call) and isinstance(rval.func.value.func, ast.Name):
99158
map_name = rval.func.value.func.id
100159
method_name = rval.func.attr
101160
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
226285
if isinstance(stmt, ast.Expr):
227286
handle_expr(func, module, builder, stmt, local_sym_tab, map_sym_tab)
228287
elif isinstance(stmt, ast.Assign):
229-
handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab)
288+
handle_assign(func, module, builder, stmt, map_sym_tab,
289+
local_sym_tab, structs_sym_tab)
230290
elif isinstance(stmt, ast.AugAssign):
231291
raise SyntaxError("Augmented assignment not supported")
232292
elif isinstance(stmt, ast.If):
@@ -304,9 +364,6 @@ def allocate_mem(module, builder, body, func, ret_type, map_sym_tab, local_sym_t
304364
struct_info = structs_sym_tab[call_type]
305365
ir_type = struct_info["type"]
306366
var = builder.alloca(ir_type, name=var_name)
307-
308-
# Null init
309-
builder.store(ir.Constant(ir_type, None), var)
310367
local_var_metadata[var_name] = call_type
311368
print(
312369
f"Pre-allocated variable {var_name} for struct {call_type}")

0 commit comments

Comments
 (0)