@@ -618,7 +618,7 @@ def _handle_boolean_op(
618618
619619
620620# ============================================================================
621- # VMLinux casting
621+ # Struct casting (including vmlinux struct casting)
622622# ============================================================================
623623
624624
@@ -667,7 +667,7 @@ def _handle_vmlinux_cast(
667667 # If arg_val is an integer type, we need to inttoptr it
668668 ptr_type = ir .PointerType ()
669669 # TODO: add a field value type check here
670- print (arg_type )
670+ # print(arg_type)
671671 if isinstance (arg_type , Field ):
672672 if ctypes_to_ir (arg_type .type .__name__ ):
673673 # Cast integer to pointer
@@ -681,6 +681,69 @@ def _handle_vmlinux_cast(
681681 return casted_ptr , vmlinux_struct_type
682682
683683
684+ def _handle_user_defined_struct_cast (
685+ func ,
686+ module ,
687+ builder ,
688+ expr ,
689+ local_sym_tab ,
690+ map_sym_tab ,
691+ structs_sym_tab ,
692+ ):
693+ """Handle user-defined struct cast expressions like iphdr(nh).
694+
695+ This casts a pointer/integer value to a pointer to the user-defined struct,
696+ similar to how vmlinux struct casts work but for user-defined @struct types.
697+ """
698+ if len (expr .args ) != 1 :
699+ logger .info ("User-defined struct cast takes exactly one argument" )
700+ return None
701+
702+ # Get the struct name
703+ struct_name = expr .func .id
704+
705+ if struct_name not in structs_sym_tab :
706+ logger .error (f"Struct { struct_name } not found in structs_sym_tab" )
707+ return None
708+
709+ struct_info = structs_sym_tab [struct_name ]
710+
711+ # Evaluate the argument (e.g.,
712+ # an address/pointer value)
713+ arg_result = eval_expr (
714+ func ,
715+ module ,
716+ builder ,
717+ expr .args [0 ],
718+ local_sym_tab ,
719+ map_sym_tab ,
720+ structs_sym_tab ,
721+ )
722+
723+ if arg_result is None :
724+ logger .info ("Failed to evaluate argument to user-defined struct cast" )
725+ return None
726+
727+ arg_val , arg_type = arg_result
728+
729+ # Cast the integer/pointer value to a pointer to the struct type
730+ # The struct pointer type is a pointer to the struct's IR type
731+ struct_ptr_type = ir .PointerType (struct_info .ir_type )
732+
733+ # If arg_val is an integer type (like i64), convert to pointer using inttoptr
734+ if isinstance (arg_val .type , ir .IntType ):
735+ casted_ptr = builder .inttoptr (arg_val , struct_ptr_type )
736+ logger .info (f"Cast integer to pointer for struct { struct_name } " )
737+ elif isinstance (arg_val .type , ir .PointerType ):
738+ # If already a pointer, bitcast to the struct pointer type
739+ casted_ptr = builder .bitcast (arg_val , struct_ptr_type )
740+ logger .info (f"Bitcast pointer to struct pointer for { struct_name } " )
741+ else :
742+ logger .error (f"Unsupported type for user-defined struct cast: { arg_val .type } " )
743+ return None
744+
745+ return casted_ptr , struct_name
746+
684747# ============================================================================
685748# Expression Dispatcher
686749# ============================================================================
@@ -726,6 +789,16 @@ def eval_expr(
726789 map_sym_tab ,
727790 structs_sym_tab ,
728791 )
792+ if isinstance (expr .func , ast .Name ) and (expr .func .id in structs_sym_tab ):
793+ return _handle_user_defined_struct_cast (
794+ func ,
795+ module ,
796+ builder ,
797+ expr ,
798+ local_sym_tab ,
799+ map_sym_tab ,
800+ structs_sym_tab ,
801+ )
729802
730803 result = CallHandlerRegistry .handle_call (
731804 expr , module , builder , func , local_sym_tab , map_sym_tab , structs_sym_tab
0 commit comments