@@ -2042,7 +2042,19 @@ let generate_ringbuf_operation ctx ringbuf_val op =
20422042 match op with
20432043 | RingbufReserve result_val ->
20442044 (* Generate bpf_ringbuf_reserve_dynptr call - modern dynptr API *)
2045- let ringbuf_str = generate_c_value ctx ringbuf_val in
2045+ (* Handle pinned ring buffers specially to avoid address-of-rvalue issues *)
2046+ let ringbuf_str = match ringbuf_val.value_desc with
2047+ | IRVariable name when List. mem name ctx.pinned_globals ->
2048+ (* For pinned ring buffers, create a temporary pointer variable *)
2049+ let temp_var = fresh_var ctx " pinned_ringbuf" in
2050+ emit_line ctx (sprintf " void *%s;" temp_var);
2051+ emit_line ctx (sprintf " { struct __pinned_globals *__pg = get_pinned_globals();" );
2052+ emit_line ctx (sprintf " %s = __pg ? __pg->%s : NULL; }" temp_var name);
2053+ temp_var
2054+ | _ ->
2055+ (* Regular ring buffer - use address-of *)
2056+ " &" ^ (generate_c_value ctx ringbuf_val)
2057+ in
20462058 let result_str = generate_c_value ctx result_val in
20472059
20482060 (* Calculate proper size based on the result type *)
@@ -2064,27 +2076,20 @@ let generate_ringbuf_operation ctx ringbuf_val op =
20642076 | _ -> " unknown type" ))
20652077 in
20662078
2067- (* Declare dynptr for the reservation - track it for later submit/discard *)
2068- let base_name = match result_val.value_desc with
2069- | IRRegister reg -> sprintf " ptr_%d " reg
2079+ (* Get consistent variable name for the result register *)
2080+ let result_var_name = match result_val.value_desc with
2081+ | IRRegister reg -> get_meaningful_var_name ctx reg result_val.val_type
20702082 | IRVariable name -> name
20712083 | _ -> " dynptr_data"
20722084 in
2073- let dynptr_var = base_name ^ " _dynptr" in
2085+
2086+ (* Declare dynptr for the reservation - track it for later submit/discard *)
2087+ let dynptr_var = result_var_name ^ " _dynptr" in
20742088 emit_line ctx (sprintf " struct bpf_dynptr %s;" dynptr_var);
20752089
2076- (* Ensure the data pointer variable is declared before the if block *)
2077- (match result_val.value_desc with
2078- | IRRegister reg ->
2079- let c_type = ebpf_type_from_ir_type result_val.val_type in
2080- let var_name = get_meaningful_var_name ctx reg result_val.val_type in
2081- if not (Hashtbl. mem ctx.declared_registers reg) then (
2082- emit_line ctx (sprintf " %s %s;" c_type var_name);
2083- Hashtbl. add ctx.declared_registers reg ()
2084- )
2085- | _ -> () );
2090+ (* The data pointer variable will be declared by the function's register collection phase *)
20862091
2087- emit_line ctx (sprintf " if (bpf_ringbuf_reserve_dynptr(& %s, %s, 0, &%s) == 0) {"
2092+ emit_line ctx (sprintf " if (bpf_ringbuf_reserve_dynptr(%s, %s, 0, &%s) == 0) {"
20882093 ringbuf_str size dynptr_var);
20892094
20902095 (* Get data pointer from dynptr *)
@@ -2337,11 +2342,16 @@ let rec generate_c_instruction ctx ir_instr =
23372342
23382343 | IRDeclareVariable (dest_val , typ , init_expr_opt ) ->
23392344 (* Variable declaration with optional initialization *)
2340- let var_name = get_meaningful_var_name ctx
2341- (match dest_val.value_desc with
2342- | IRRegister reg -> reg
2343- | _ -> failwith " IRDeclareVariable target must be a register" )
2344- typ in
2345+ let var_name = match dest_val.value_desc with
2346+ | IRRegister reg ->
2347+ let name = get_meaningful_var_name ctx reg typ in
2348+ (* Store the declared name for this register to ensure consistency *)
2349+ Hashtbl. replace ctx.register_name_hints reg (String. split_on_char '_' name |> List. hd);
2350+ (* Mark this register as declared *)
2351+ Hashtbl. add ctx.declared_registers reg () ;
2352+ name
2353+ | _ -> failwith " IRDeclareVariable target must be a register"
2354+ in
23452355
23462356 (* Special handling for different types in variable declarations *)
23472357 (match typ with
@@ -3296,8 +3306,14 @@ let collect_registers_in_function ir_func =
32963306 collect_in_value dest_val; collect_in_value flag_val
32973307 | IRObjectDelete ptr_val ->
32983308 collect_in_value ptr_val
3299- | IRRingbufOp (ringbuf_val , _ ) ->
3300- collect_in_value ringbuf_val
3309+ | IRRingbufOp (ringbuf_val , op ) ->
3310+ collect_in_value ringbuf_val;
3311+ (* Also collect registers from ring buffer operation arguments *)
3312+ (match op with
3313+ | RingbufReserve result_val -> collect_in_value result_val
3314+ | RingbufSubmit data_val -> collect_in_value data_val
3315+ | RingbufDiscard data_val -> collect_in_value data_val
3316+ | RingbufOnEvent _ -> () )
33013317 in
33023318 List. iter (fun block ->
33033319 List. iter collect_in_instr block.instructions
@@ -3392,21 +3408,17 @@ let generate_c_function ctx ir_func =
33923408 (match dest_val.value_desc with
33933409 | IRRegister reg -> declared_registers := reg :: ! declared_registers
33943410 | _ -> () )
3395- | IRRingbufOp (_ , op ) ->
3396- (* Collect registers that will be declared by ringbuf operations *)
3397- (match op with
3398- | RingbufReserve result_val ->
3399- (match result_val.value_desc with
3400- | IRRegister reg -> declared_registers := reg :: ! declared_registers
3401- | _ -> () )
3402- | _ -> () )
3411+ (* IRRingbufOp registers are now handled by the regular collection process *)
34033412 | _ -> ()
34043413 ) block.instructions
34053414 ) ir_func.basic_blocks;
34063415
34073416 (* Declare temporary variables for all registers *)
34083417 let register_variable_map = collect_register_variable_mapping ir_func in
34093418
3419+ (* Add all pre-declared registers to the context's declared_registers hashtable *)
3420+ List. iter (fun reg -> Hashtbl. add ctx.declared_registers reg () ) ! declared_registers;
3421+
34103422 (* Generate proper variable declarations for all registers *)
34113423 let register_declarations = ref [] in
34123424 List. iter (fun (reg , reg_type ) ->
@@ -3434,14 +3446,16 @@ let generate_c_function ctx ir_func =
34343446 let var_name = get_meaningful_var_name ctx reg reg_type in
34353447 let decl = generate_ebpf_c_declaration reg_type var_name in
34363448 register_declarations := (decl ^ " ;" ) :: ! register_declarations;
3449+ Hashtbl. add ctx.declared_registers reg () ;
34373450 " " (* Skip the simple type processing below *)
34383451 )
34393452 in
34403453 (* Handle simple types that use alias names *)
34413454 if effective_type <> " " then (
34423455 let var_name = get_meaningful_var_name ctx reg reg_type in
34433456 let simple_decl = sprintf " %s %s;" effective_type var_name in
3444- register_declarations := simple_decl :: ! register_declarations
3457+ register_declarations := simple_decl :: ! register_declarations;
3458+ Hashtbl. add ctx.declared_registers reg ()
34453459 )
34463460 )
34473461 ) all_registers;
@@ -3766,9 +3780,9 @@ let compile_multi_to_c_with_tail_calls
37663780
37673781 (* First pass: collect all callbacks *)
37683782 let temp_ctx = create_c_context () in
3769- List. iter (fun ir_prog ->
3770- generate_c_function temp_ctx ir_prog.entry_function
3771- ) ir_multi_prog.programs;
3783+ List. iter (fun ir_prog ->
3784+ generate_c_function temp_ctx ir_prog.entry_function
3785+ ) ir_multi_prog.programs;
37723786
37733787 (* Emit collected callbacks BEFORE the actual functions *)
37743788 if temp_ctx.pending_callbacks <> [] then (
0 commit comments