@@ -94,20 +94,21 @@ def handle_vmlinux_struct_field(
9494 f"Attempting to access field { field_name } of possible vmlinux struct { struct_var_name } "
9595 )
9696 python_type : type = var_info .metadata
97+ struct_name = python_type .__name__
9798 globvar_ir , field_data = self .get_field_type (
98- python_type . __name__ , field_name
99+ struct_name , field_name
99100 )
100101 builder .function .args [0 ].type = ir .PointerType (ir .IntType (8 ))
101102 field_ptr = self .load_ctx_field (
102- builder , builder .function .args [0 ], globvar_ir , field_data
103+ builder , builder .function .args [0 ], globvar_ir , field_data , struct_name
103104 )
104105 # Return pointer to field and field type
105106 return field_ptr , field_data
106107 else :
107108 raise RuntimeError ("Variable accessed not found in symbol table" )
108109
109110 @staticmethod
110- def load_ctx_field (builder , ctx_arg , offset_global , field_data ):
111+ def load_ctx_field (builder , ctx_arg , offset_global , field_data , struct_name = None ):
111112 """
112113 Generate LLVM IR to load a field from BPF context using offset.
113114
@@ -116,8 +117,9 @@ def load_ctx_field(builder, ctx_arg, offset_global, field_data):
116117 ctx_arg: The context pointer argument (ptr/i8*)
117118 offset_global: Global variable containing the field offset (i64)
118119 field_data: contains data about the field
120+ struct_name: Name of the struct being accessed (optional)
119121 Returns:
120- The loaded value (i64 register)
122+ The loaded value (i64 register or appropriately sized )
121123 """
122124
123125 # Load the offset value
@@ -164,6 +166,7 @@ def load_ctx_field(builder, ctx_arg, offset_global, field_data):
164166
165167 # Determine the appropriate IR type based on field information
166168 int_width = 64 # Default to 64-bit
169+ needs_zext = False # Track if we need zero-extension for xdp_md
167170
168171 if field_data is not None :
169172 # Try to determine the size from field metadata
@@ -175,6 +178,12 @@ def load_ctx_field(builder, ctx_arg, offset_global, field_data):
175178 if field_size_bits in [8 , 16 , 32 , 64 ]:
176179 int_width = field_size_bits
177180 logger .info (f"Determined field size: { int_width } bits" )
181+
182+ # Special handling for struct_xdp_md i32 fields
183+ # Load as i32 but extend to i64 before storing
184+ if struct_name == "struct_xdp_md" and int_width == 32 :
185+ needs_zext = True
186+ logger .info (f"struct_xdp_md i32 field detected, will zero-extend to i64" )
178187 else :
179188 logger .warning (
180189 f"Unusual field size { field_size_bits } bits, using default 64"
@@ -203,6 +212,11 @@ def load_ctx_field(builder, ctx_arg, offset_global, field_data):
203212 # Load and return the value
204213 value = builder .load (typed_ptr )
205214
215+ # Zero-extend i32 to i64 for struct_xdp_md fields
216+ if needs_zext :
217+ value = builder .zext (value , ir .IntType (64 ))
218+ logger .info ("Zero-extended i32 value to i64 for struct_xdp_md field" )
219+
206220 return value
207221
208222 def has_field (self , struct_name , field_name ):
0 commit comments