1212 get_base_type_and_depth ,
1313 deref_to_depth ,
1414)
15- from pythonbpf .vmlinux_parser .assignment_info import Field
1615from .vmlinux_registry import VmlinuxHandlerRegistry
16+ from ..vmlinux_parser .dependency_node import Field
1717
1818logger : Logger = logging .getLogger (__name__ )
1919
@@ -173,8 +173,16 @@ def _handle_attribute_expr(
173173 return vmlinux_result
174174 else :
175175 raise RuntimeError ("Vmlinux struct did not process successfully" )
176- metadata = structs_sym_tab [var_metadata ]
177- if attr_name in metadata .fields :
176+
177+ elif isinstance (var_metadata , Field ):
178+ logger .error (
179+ f"Cannot access field '{ attr_name } ' on already-loaded field value '{ var_name } '"
180+ )
181+ return None
182+
183+ # Regular user-defined struct
184+ metadata = structs_sym_tab .get (var_metadata )
185+ if metadata and attr_name in metadata .fields :
178186 gep = metadata .gep (builder , var_ptr , attr_name )
179187 val = builder .load (gep )
180188 field_type = metadata .field_type (attr_name )
@@ -609,6 +617,66 @@ def _handle_boolean_op(
609617 return None
610618
611619
620+ # ============================================================================
621+ # VMLinux casting
622+ # ============================================================================
623+
624+
625+ def _handle_vmlinux_cast (
626+ func ,
627+ module ,
628+ builder ,
629+ expr ,
630+ local_sym_tab ,
631+ map_sym_tab ,
632+ structs_sym_tab = None ,
633+ ):
634+ # handle expressions such as struct_request(ctx.di) where struct_request is a vmlinux
635+ # struct and ctx.di is a pointer to a struct but is actually represented as a c_uint64
636+ # which needs to be cast to a pointer. This is also a field of another vmlinux struct
637+ """Handle vmlinux struct cast expressions like struct_request(ctx.di)."""
638+ if len (expr .args ) != 1 :
639+ logger .info ("vmlinux struct cast takes exactly one argument" )
640+ return None
641+
642+ # Get the struct name
643+ struct_name = expr .func .id
644+
645+ # Evaluate the argument (e.g., ctx.di which is a c_uint64)
646+ arg_result = eval_expr (
647+ func ,
648+ module ,
649+ builder ,
650+ expr .args [0 ],
651+ local_sym_tab ,
652+ map_sym_tab ,
653+ structs_sym_tab ,
654+ )
655+
656+ if arg_result is None :
657+ logger .info ("Failed to evaluate argument to vmlinux struct cast" )
658+ return None
659+
660+ arg_val , arg_type = arg_result
661+ # Get the vmlinux struct type
662+ vmlinux_struct_type = VmlinuxHandlerRegistry .get_struct_type (struct_name )
663+ if vmlinux_struct_type is None :
664+ logger .error (f"Failed to get vmlinux struct type for { struct_name } " )
665+ return None
666+ # Cast the integer/value to a pointer to the struct
667+ # If arg_val is an integer type, we need to inttoptr it
668+ ptr_type = ir .PointerType ()
669+ # TODO: add a integer check here later
670+ if ctypes_to_ir (arg_type .type .__name__ ):
671+ # Cast integer to pointer
672+ casted_ptr = builder .inttoptr (arg_val , ptr_type )
673+ else :
674+ logger .error (f"Unsupported type for vmlinux cast: { arg_type } " )
675+ return None
676+
677+ return casted_ptr , vmlinux_struct_type
678+
679+
612680# ============================================================================
613681# Expression Dispatcher
614682# ============================================================================
@@ -629,6 +697,18 @@ def eval_expr(
629697 elif isinstance (expr , ast .Constant ):
630698 return _handle_constant_expr (module , builder , expr )
631699 elif isinstance (expr , ast .Call ):
700+ if isinstance (expr .func , ast .Name ) and VmlinuxHandlerRegistry .is_vmlinux_struct (
701+ expr .func .id
702+ ):
703+ return _handle_vmlinux_cast (
704+ func ,
705+ module ,
706+ builder ,
707+ expr ,
708+ local_sym_tab ,
709+ map_sym_tab ,
710+ structs_sym_tab ,
711+ )
632712 if isinstance (expr .func , ast .Name ) and expr .func .id == "deref" :
633713 return _handle_deref_call (expr , local_sym_tab , builder )
634714
0 commit comments