diff --git a/pythonbpf/allocation_pass.py b/pythonbpf/allocation_pass.py index 44d74fc..777d385 100644 --- a/pythonbpf/allocation_pass.py +++ b/pythonbpf/allocation_pass.py @@ -245,13 +245,17 @@ def _allocate_for_attribute(builder, var_name, rval, local_sym_tab, structs_sym_ # loaded_value = builder.load(field_ir, align=8) # #TODO: fatal flaw that this always assumes first argument of function to be the context of what this gets. - # base_ptr = builder.function.args[0] + base_ptr = builder.function.args[0] + local_sym_tab[ + struct_var + ].var = base_ptr # This is repurposing of var to store the pointer of the base type + local_sym_tab[struct_var].ir_type = field_ir # gep_result = builder.gep( # base_ptr, # [loaded_value], # inbounds=False, # Not using inbounds GEP # ) - # print("DEBB", loaded_value, base_ptr, gep_result) + # print("DEBUG", loaded_value, base_ptr, gep_result) # Use i64 for allocation since that's what the global variable contains actual_ir_type = ir.IntType(64) diff --git a/pythonbpf/vmlinux_parser/vmlinux_exports_handler.py b/pythonbpf/vmlinux_parser/vmlinux_exports_handler.py index 46dfbed..d36c31e 100644 --- a/pythonbpf/vmlinux_parser/vmlinux_exports_handler.py +++ b/pythonbpf/vmlinux_parser/vmlinux_exports_handler.py @@ -97,7 +97,16 @@ class VmlinuxHandler: globvar_ir, field_data = self.get_field_type( python_type.__name__, field_name ) - + # field_index = self.get_field_index(python_type.__name__, field_name) + offset = builder.load(globvar_ir) + i8_ptr_type = ir.IntType(8).as_pointer() + byte_ptr = builder.bitcast(var_info.var, i8_ptr_type) + print(byte_ptr) + # Step 3: GEP with the offset to get field pointer + field_ptr_i8 = builder.gep( + byte_ptr, [ir.Constant(ir.IntType(32), 0), offset], inbounds=False + ) + print(field_ptr_i8) # Return pointer to field and field type return None else: @@ -122,3 +131,18 @@ class VmlinuxHandler: ) else: raise ValueError(f"{vmlinux_struct_name} is not a vmlinux struct") + + def get_field_index(self, vmlinux_struct_name, field_name): + """Get the type of a field in a vmlinux struct""" + if self.is_vmlinux_struct(vmlinux_struct_name): + python_type = self.vmlinux_symtab[vmlinux_struct_name]["python_type"] + if hasattr(python_type, field_name): + return list( + self.vmlinux_symtab[vmlinux_struct_name]["members"].keys() + ).index(field_name) + else: + raise ValueError( + f"Field {field_name} not found in vmlinux struct {vmlinux_struct_name}" + ) + else: + raise ValueError(f"{vmlinux_struct_name} is not a vmlinux struct") diff --git a/tests/c-form/struct_field_tests.bpf.c b/tests/c-form/struct_field_tests.bpf.c index bb85d84..6f447e0 100644 --- a/tests/c-form/struct_field_tests.bpf.c +++ b/tests/c-form/struct_field_tests.bpf.c @@ -21,7 +21,21 @@ int handle_setuid_entry(struct trace_event_raw_sys_enter *ctx) { // Access each argument separately with clear variable assignments long int arg0 = ctx->id; bpf_printk("args[0]: %d", arg0); - + /* + * the IR to aim for is + * %2 = alloca ptr, align 8 + * store ptr %0, ptr %2, align 8 + * Above, %0 is the arg pointer + * %5 = load ptr, ptr %2, align 8 + * %6 = getelementptr inbounds %struct.trace_event_raw_sys_enter, ptr %5, i32 0, i32 2 + * %7 = load i64, ptr @"llvm.trace_event_raw_sys_enter:0:16$0:2:0", align 8 + * %8 = bitcast ptr %5 to ptr + * %9 = getelementptr i8, ptr %8, i64 %7 + * %10 = bitcast ptr %9 to ptr + * %11 = call ptr @llvm.bpf.passthrough.p0.p0(i32 0, ptr %10) + * %12 = load i64, ptr %11, align 8, !dbg !101 + * + */ return 0; }