Skip to content

Commit a55efc6

Browse files
committed
Implement output helper for RingBuf maps, add a match-case based dispatch for output helper handlers for multiple map types
1 parent 64cd2d2 commit a55efc6

File tree

1 file changed

+93
-5
lines changed

1 file changed

+93
-5
lines changed

pythonbpf/helper/bpf_helper_handler.py

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
get_int_value_from_arg,
1313
)
1414
from .printk_formatter import simple_string_print, handle_fstring_print
15+
from pythonbpf.maps import BPFMapType
1516
import logging
1617

1718
logger = logging.getLogger(__name__)
@@ -360,11 +361,6 @@ def bpf_get_current_pid_tgid_emitter(
360361
return pid, ir.IntType(64)
361362

362363

363-
@HelperHandlerRegistry.register(
364-
"output",
365-
param_types=[ir.PointerType(ir.IntType(8))],
366-
return_type=ir.IntType(64),
367-
)
368364
def bpf_perf_event_output_handler(
369365
call,
370366
map_ptr,
@@ -416,6 +412,98 @@ def bpf_perf_event_output_handler(
416412
return result, None
417413

418414

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+
419507
def emit_probe_read_kernel_str_call(builder, dst_ptr, dst_size, src_ptr):
420508
"""Emit LLVM IR call to bpf_probe_read_kernel_str"""
421509

0 commit comments

Comments
 (0)