@@ -311,13 +311,24 @@ static char* resolve_type_to_string(struct btf *btf, int type_id) {
311311}
312312
313313/* Helper function to format function prototype */
314- static char * format_function_prototype (struct btf * btf , const struct btf_type * func_proto ) {
314+ static char * format_function_prototype (struct btf * btf , const struct btf_type * func_proto , int force_i32_return ) {
315315 char result [1024 ];
316316 int ret_type_id = func_proto -> type ;
317317 int param_count = btf_vlen (func_proto );
318318
319319 /* Get return type */
320- char * ret_type = resolve_type_to_string (btf , ret_type_id );
320+ char * original_ret_type = resolve_type_to_string (btf , ret_type_id );
321+
322+ /* Use original return type unless forced to i32 for eBPF probe/kfunc functions */
323+ const char * ret_type ;
324+ if (force_i32_return ) {
325+ /* eBPF probe/kfunc functions must return i32 due to BPF_PROG() constraint,
326+ * regardless of the kernel function's actual return type */
327+ ret_type = "i32" ;
328+ } else {
329+ /* Preserve original return type for struct_ops and other contexts */
330+ ret_type = original_ret_type ;
331+ }
321332
322333 /* Start building the function signature */
323334 snprintf (result , sizeof (result ), "fn(" );
@@ -353,7 +364,7 @@ static char* format_function_prototype(struct btf *btf, const struct btf_type *f
353364 snprintf (closing , sizeof (closing ), ") -> %s" , ret_type );
354365 strncat (result , closing , sizeof (result ) - strlen (result ) - 1 );
355366
356- free (ret_type );
367+ free (original_ret_type );
357368 return strdup (result );
358369}
359370
@@ -384,7 +395,7 @@ value btf_resolve_type_stub(value btf_handle, value type_id) {
384395 /* Check if this points to a function prototype */
385396 const struct btf_type * target = btf__type_by_id (btf , t -> type );
386397 if (target && btf_kind (target ) == BTF_KIND_FUNC_PROTO ) {
387- char * func_sig = format_function_prototype (btf , target );
398+ char * func_sig = format_function_prototype (btf , target , 0 ); /* Don't force i32 for general BTF resolution */
388399 value result = caml_copy_string (func_sig );
389400 free (func_sig );
390401 CAMLreturn (result );
@@ -474,7 +485,7 @@ value btf_resolve_type_stub(value btf_handle, value type_id) {
474485 CAMLreturn (caml_copy_string ("fwd" ));
475486 }
476487 case BTF_KIND_FUNC_PROTO : {
477- char * func_sig = format_function_prototype (btf , t );
488+ char * func_sig = format_function_prototype (btf , t , 0 ); /* Don't force i32 for general BTF resolution */
478489 value result = caml_copy_string (func_sig );
479490 free (func_sig );
480491 CAMLreturn (result );
@@ -573,8 +584,8 @@ value btf_extract_function_signatures_stub(value btf_handle, value function_name
573584 /* Get the function prototype */
574585 const struct btf_type * func_proto = btf__type_by_id (btf , t -> type );
575586 if (func_proto && btf_kind (func_proto ) == BTF_KIND_FUNC_PROTO ) {
576- /* Extract function signature */
577- char * signature = format_function_prototype (btf , func_proto );
587+ /* Extract function signature - force i32 return for probe functions */
588+ char * signature = format_function_prototype (btf , func_proto , 1 );
578589
579590 /* Create tuple (function_name, signature) */
580591 tuple = caml_alloc_tuple (2 );
@@ -665,8 +676,7 @@ value btf_extract_kfuncs_stub(value btf_handle) {
665676 /* Get the function prototype */
666677 const struct btf_type * func_proto = btf__type_by_id (btf , target_func -> type );
667678 if (func_proto && btf_kind (func_proto ) == BTF_KIND_FUNC_PROTO ) {
668- /* Extract function signature */
669- char * signature = format_function_prototype (btf , func_proto );
679+ char * signature = format_function_prototype (btf , func_proto , 0 );
670680
671681 /* Create tuple (function_name, signature) */
672682 tuple = caml_alloc_tuple (2 );
0 commit comments