|
1 | 1 | import ast |
| 2 | +import ctypes |
2 | 3 | import logging |
3 | 4 |
|
4 | 5 | from llvmlite import ir |
5 | 6 | from dataclasses import dataclass |
6 | 7 | from typing import Any |
7 | 8 | from pythonbpf.helper import HelperHandlerRegistry |
| 9 | +from pythonbpf.vmlinux_parser.dependency_node import Field |
8 | 10 | from .expr import VmlinuxHandlerRegistry |
9 | 11 | from pythonbpf.type_deducer import ctypes_to_ir |
10 | 12 |
|
@@ -60,21 +62,11 @@ def handle_assign_allocation(builder, stmt, local_sym_tab, structs_sym_tab): |
60 | 62 | continue |
61 | 63 |
|
62 | 64 | var_name = target.id |
63 | | - |
64 | 65 | # Skip if already allocated |
65 | 66 | if var_name in local_sym_tab: |
66 | 67 | logger.debug(f"Variable {var_name} already allocated, skipping") |
67 | 68 | continue |
68 | 69 |
|
69 | | - # When allocating a variable, check if it's a vmlinux struct type |
70 | | - if isinstance( |
71 | | - stmt.value, ast.Name |
72 | | - ) and VmlinuxHandlerRegistry.is_vmlinux_struct(stmt.value.id): |
73 | | - # Handle vmlinux struct allocation |
74 | | - # This requires more implementation |
75 | | - print(stmt.value) |
76 | | - pass |
77 | | - |
78 | 70 | # Determine type and allocate based on rval |
79 | 71 | if isinstance(rval, ast.Call): |
80 | 72 | _allocate_for_call(builder, var_name, rval, local_sym_tab, structs_sym_tab) |
@@ -248,9 +240,40 @@ def _allocate_for_attribute(builder, var_name, rval, local_sym_tab, structs_sym_ |
248 | 240 | logger.error(f"Struct variable '{struct_var}' not found") |
249 | 241 | return |
250 | 242 |
|
251 | | - struct_type = local_sym_tab[struct_var].metadata |
| 243 | + struct_type: type = local_sym_tab[struct_var].metadata |
252 | 244 | if not struct_type or struct_type not in structs_sym_tab: |
253 | | - logger.error(f"Struct type '{struct_type}' not found") |
| 245 | + if VmlinuxHandlerRegistry.is_vmlinux_struct(struct_type.__name__): |
| 246 | + # Handle vmlinux struct field access |
| 247 | + vmlinux_struct_name = struct_type.__name__ |
| 248 | + if not VmlinuxHandlerRegistry.has_field(vmlinux_struct_name, field_name): |
| 249 | + logger.error(f"Field '{field_name}' not found in vmlinux struct '{vmlinux_struct_name}'") |
| 250 | + return |
| 251 | + |
| 252 | + field_type: tuple[ir.GlobalVariable, Field] = VmlinuxHandlerRegistry.get_field_type(vmlinux_struct_name, field_name) |
| 253 | + field_ir, field = field_type |
| 254 | + #TODO: For now, we only support integer type allocations. |
| 255 | + |
| 256 | + # loaded_value = builder.load(field_ir, align=8) |
| 257 | + # #TODO: fatal flaw that this always assumes first argument of function to be the context of what this gets. |
| 258 | + # base_ptr = builder.function.args[0] |
| 259 | + # gep_result = builder.gep( |
| 260 | + # base_ptr, |
| 261 | + # [loaded_value], |
| 262 | + # inbounds=False, # Not using inbounds GEP |
| 263 | + # ) |
| 264 | + # print("DEBB", loaded_value, base_ptr, gep_result) |
| 265 | + # Use i64 for allocation since that's what the global variable contains |
| 266 | + |
| 267 | + actual_ir_type = ir.IntType(64) |
| 268 | + |
| 269 | + # Allocate with the actual IR type, not the GlobalVariable |
| 270 | + var = _allocate_with_type(builder, var_name, actual_ir_type) |
| 271 | + local_sym_tab[var_name] = LocalSymbol(var, actual_ir_type, field) |
| 272 | + |
| 273 | + logger.info(f"Pre-allocated {var_name} from vmlinux struct {vmlinux_struct_name}.{field_name}") |
| 274 | + return |
| 275 | + else: |
| 276 | + logger.error(f"Struct type '{struct_type}' not found") |
254 | 277 | return |
255 | 278 |
|
256 | 279 | struct_info = structs_sym_tab[struct_type] |
|
0 commit comments