|
12 | 12 | get_int_value_from_arg, |
13 | 13 | ) |
14 | 14 | from .printk_formatter import simple_string_print, handle_fstring_print |
| 15 | +from pythonbpf.maps import BPFMapType |
15 | 16 | import logging |
16 | 17 |
|
17 | 18 | logger = logging.getLogger(__name__) |
@@ -360,11 +361,6 @@ def bpf_get_current_pid_tgid_emitter( |
360 | 361 | return pid, ir.IntType(64) |
361 | 362 |
|
362 | 363 |
|
363 | | -@HelperHandlerRegistry.register( |
364 | | - "output", |
365 | | - param_types=[ir.PointerType(ir.IntType(8))], |
366 | | - return_type=ir.IntType(64), |
367 | | -) |
368 | 364 | def bpf_perf_event_output_handler( |
369 | 365 | call, |
370 | 366 | map_ptr, |
@@ -416,6 +412,98 @@ def bpf_perf_event_output_handler( |
416 | 412 | return result, None |
417 | 413 |
|
418 | 414 |
|
| 415 | +def bpf_ringbuf_output_emitter( |
| 416 | + call, |
| 417 | + map_ptr, |
| 418 | + module, |
| 419 | + builder, |
| 420 | + func, |
| 421 | + local_sym_tab=None, |
| 422 | + struct_sym_tab=None, |
| 423 | + map_sym_tab=None, |
| 424 | +): |
| 425 | + """ |
| 426 | + Emit LLVM IR for bpf_ringbuf_output helper function call. |
| 427 | + """ |
| 428 | + |
| 429 | + if len(call.args) != 1: |
| 430 | + raise ValueError( |
| 431 | + f"Ringbuf output expects exactly one argument, got {len(call.args)}" |
| 432 | + ) |
| 433 | + data_arg = call.args[0] |
| 434 | + data_ptr, size_val = get_data_ptr_and_size(data_arg, local_sym_tab, struct_sym_tab) |
| 435 | + flags_val = ir.Constant(ir.IntType(64), 0) |
| 436 | + |
| 437 | + map_void_ptr = builder.bitcast(map_ptr, ir.PointerType()) |
| 438 | + data_void_ptr = builder.bitcast(data_ptr, ir.PointerType()) |
| 439 | + fn_type = ir.FunctionType( |
| 440 | + ir.IntType(64), |
| 441 | + [ |
| 442 | + ir.PointerType(), |
| 443 | + ir.PointerType(), |
| 444 | + ir.IntType(64), |
| 445 | + ir.IntType(64), |
| 446 | + ], |
| 447 | + var_arg=False, |
| 448 | + ) |
| 449 | + fn_ptr_type = ir.PointerType(fn_type) |
| 450 | + |
| 451 | + # helper id |
| 452 | + fn_addr = ir.Constant(ir.IntType(64), BPFHelperID.BPF_RINGBUF_OUTPUT.value) |
| 453 | + fn_ptr = builder.inttoptr(fn_addr, fn_ptr_type) |
| 454 | + |
| 455 | + result = builder.call( |
| 456 | + fn_ptr, [map_void_ptr, data_void_ptr, size_val, flags_val], tail=False |
| 457 | + ) |
| 458 | + return result, None |
| 459 | + |
| 460 | + |
| 461 | +@HelperHandlerRegistry.register( |
| 462 | + "output", |
| 463 | + param_types=[ir.PointerType(ir.IntType(8))], |
| 464 | + return_type=ir.IntType(64), |
| 465 | +) |
| 466 | +def handle_output_helper( |
| 467 | + call, |
| 468 | + map_ptr, |
| 469 | + module, |
| 470 | + builder, |
| 471 | + func, |
| 472 | + local_sym_tab=None, |
| 473 | + struct_sym_tab=None, |
| 474 | + map_sym_tab=None, |
| 475 | +): |
| 476 | + """ |
| 477 | + Route output helper to the appropriate emitter based on map type. |
| 478 | + """ |
| 479 | + match map_sym_tab[map_ptr.name].type: |
| 480 | + case BPFMapType.PERF_EVENT_ARRAY: |
| 481 | + return bpf_perf_event_output_handler( |
| 482 | + call, |
| 483 | + map_ptr, |
| 484 | + module, |
| 485 | + builder, |
| 486 | + func, |
| 487 | + local_sym_tab, |
| 488 | + struct_sym_tab, |
| 489 | + map_sym_tab, |
| 490 | + ) |
| 491 | + case BPFMapType.RINGBUF: |
| 492 | + return bpf_ringbuf_output_emitter( |
| 493 | + call, |
| 494 | + map_ptr, |
| 495 | + module, |
| 496 | + builder, |
| 497 | + func, |
| 498 | + local_sym_tab, |
| 499 | + struct_sym_tab, |
| 500 | + map_sym_tab, |
| 501 | + ) |
| 502 | + case _: |
| 503 | + logger.error("Unsupported map type for output helper.") |
| 504 | + raise NotImplementedError("Output helper for this map type is not implemented.") |
| 505 | + |
| 506 | + |
419 | 507 | def emit_probe_read_kernel_str_call(builder, dst_ptr, dst_size, src_ptr): |
420 | 508 | """Emit LLVM IR call to bpf_probe_read_kernel_str""" |
421 | 509 |
|
|
0 commit comments