Skip to content

Commit 0f365be

Browse files
committed
Add some support for strings in structs
1 parent 4ebf048 commit 0f365be

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

examples/execve5.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def hello(ctx: c_void_p) -> c_int32:
2828
strobj = "hellohellohello"
2929
dataobj.pid = process_id
3030
dataobj.ts = ts
31+
# dataobj.comm = strobj
3132
print(f"clone called at {ts} by pid {process_id}, comm {strobj}")
3233
events.output(dataobj)
3334
return c_int32(0)

pythonbpf/functions_pass.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,17 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab, struc
5858
inbounds=True)
5959
val = eval_expr(func, module, builder, rval,
6060
local_sym_tab, map_sym_tab, structs_sym_tab)
61+
if isinstance(struct_info["field_types"][field_idx], ir.ArrayType) and val[1] == ir.PointerType(ir.IntType(8)):
62+
# TODO: Figure it out, not a priority rn
63+
# Special case for string assignment to char array
64+
#str_len = struct_info["field_types"][field_idx].count
65+
#assign_string_to_array(builder, field_ptr, val[0], str_len)
66+
#print(f"Assigned to struct field {var_name}.{field_name}")
67+
pass
6168
if val is None:
6269
print("Failed to evaluate struct field assignment")
6370
return
71+
print(field_ptr)
6472
builder.store(val[0], field_ptr)
6573
print(f"Assigned to struct field {var_name}.{field_name}")
6674
return
@@ -537,3 +545,46 @@ def _expr_type(e):
537545
raise ValueError("Conflicting return types:"
538546
f"{found_type} vs {t}")
539547
return found_type or "None"
548+
549+
# For string assignment to fixed-size arrays
550+
def assign_string_to_array(builder, target_array_ptr, source_string_ptr, array_length):
551+
"""
552+
Copy a string (i8*) to a fixed-size array ([N x i8]*)
553+
"""
554+
# Create a loop to copy characters one by one
555+
entry_block = builder.block
556+
copy_block = builder.append_basic_block("copy_char")
557+
end_block = builder.append_basic_block("copy_end")
558+
559+
# Create loop counter
560+
i = builder.alloca(ir.IntType(32))
561+
builder.store(ir.Constant(ir.IntType(32), 0), i)
562+
563+
# Start the loop
564+
builder.branch(copy_block)
565+
566+
# Copy loop
567+
builder.position_at_end(copy_block)
568+
idx = builder.load(i)
569+
in_bounds = builder.icmp_unsigned('<', idx, ir.Constant(ir.IntType(32), array_length))
570+
builder.cbranch(in_bounds, copy_block, end_block)
571+
572+
with builder.if_then(in_bounds):
573+
# Load character from source
574+
src_ptr = builder.gep(source_string_ptr, [idx])
575+
char = builder.load(src_ptr)
576+
577+
# Store character in target
578+
dst_ptr = builder.gep(target_array_ptr, [ir.Constant(ir.IntType(32), 0), idx])
579+
builder.store(char, dst_ptr)
580+
581+
# Increment counter
582+
next_idx = builder.add(idx, ir.Constant(ir.IntType(32), 1))
583+
builder.store(next_idx, i)
584+
585+
builder.position_at_end(end_block)
586+
587+
# Ensure null termination
588+
last_idx = ir.Constant(ir.IntType(32), array_length - 1)
589+
null_ptr = builder.gep(target_array_ptr, [ir.Constant(ir.IntType(32), 0), last_idx])
590+
builder.store(ir.Constant(ir.IntType(8), 0), null_ptr)

pythonbpf/structs_pass.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def process_bpf_struct(cls_node, module):
6363
structs_sym_tab[struct_name] = {
6464
"type": struct_type,
6565
"fields": {name: idx for idx, name in enumerate(field_names)},
66-
"size": total_size
66+
"size": total_size,
67+
"field_types": field_types,
6768
}
6869
print(f"Created struct {struct_name} with fields {field_names}")

0 commit comments

Comments
 (0)