|
12 | 12 | get_base_type_and_depth, |
13 | 13 | deref_to_depth, |
14 | 14 | ) |
| 15 | +from pythonbpf.vmlinux_parser.assignment_info import Field |
15 | 16 | from .vmlinux_registry import VmlinuxHandlerRegistry |
16 | 17 |
|
17 | 18 | logger: Logger = logging.getLogger(__name__) |
@@ -279,16 +280,45 @@ def _handle_ctypes_call( |
279 | 280 | call_type = expr.func.id |
280 | 281 | expected_type = ctypes_to_ir(call_type) |
281 | 282 |
|
282 | | - if val[1] != expected_type: |
| 283 | + # Extract the actual IR value and type |
| 284 | + # val could be (value, ir_type) or (value, Field) |
| 285 | + value, val_type = val |
| 286 | + |
| 287 | + # If val_type is a Field object (from vmlinux struct), get the actual IR type of the value |
| 288 | + if isinstance(val_type, Field): |
| 289 | + # The value is already the correct IR value (potentially zero-extended) |
| 290 | + # Get the IR type from the value itself |
| 291 | + actual_ir_type = value.type |
| 292 | + logger.info( |
| 293 | + f"Converting vmlinux field {val_type.name} (IR type: {actual_ir_type}) to {call_type}" |
| 294 | + ) |
| 295 | + else: |
| 296 | + actual_ir_type = val_type |
| 297 | + |
| 298 | + if actual_ir_type != expected_type: |
283 | 299 | # NOTE: We are only considering casting to and from int types for now |
284 | | - if isinstance(val[1], ir.IntType) and isinstance(expected_type, ir.IntType): |
285 | | - if val[1].width < expected_type.width: |
286 | | - val = (builder.sext(val[0], expected_type), expected_type) |
| 300 | + if isinstance(actual_ir_type, ir.IntType) and isinstance( |
| 301 | + expected_type, ir.IntType |
| 302 | + ): |
| 303 | + if actual_ir_type.width < expected_type.width: |
| 304 | + value = builder.sext(value, expected_type) |
| 305 | + logger.info( |
| 306 | + f"Sign-extended from i{actual_ir_type.width} to i{expected_type.width}" |
| 307 | + ) |
| 308 | + elif actual_ir_type.width > expected_type.width: |
| 309 | + value = builder.trunc(value, expected_type) |
| 310 | + logger.info( |
| 311 | + f"Truncated from i{actual_ir_type.width} to i{expected_type.width}" |
| 312 | + ) |
287 | 313 | else: |
288 | | - val = (builder.trunc(val[0], expected_type), expected_type) |
| 314 | + # Same width, just use as-is (e.g., both i64) |
| 315 | + pass |
289 | 316 | else: |
290 | | - raise ValueError(f"Type mismatch: expected {expected_type}, got {val[1]}") |
291 | | - return val |
| 317 | + raise ValueError( |
| 318 | + f"Type mismatch: expected {expected_type}, got {actual_ir_type} (original type: {val_type})" |
| 319 | + ) |
| 320 | + |
| 321 | + return value, expected_type |
292 | 322 |
|
293 | 323 |
|
294 | 324 | def _handle_compare( |
|
0 commit comments