@@ -3048,11 +3048,14 @@ let generate_declarations_in_source_order_unified ctx ir_multi_prog ~_btf_path _
30483048 emit_blank_line ctx
30493049
30503050 | Ir. IRDeclKfuncDecl kfunc_decl ->
3051- (* Emit a function-signature declaration so eBPF programs can call the kfunc.
3052- Kernel-provided kfuncs need `extern ... __ksym;`; locally-defined @kfunc
3053- functions just need a forward prototype. Standard BPF helpers are skipped
3054- entirely - libbpf's bpf_helpers.h already declares them, and a __ksym
3055- extern would clash with that declaration. *)
3051+ (* Emit `extern ... __ksym;` so libbpf resolves the symbol against the
3052+ kernel's BTF at load time. Both kinds of kfunc are external to the
3053+ eBPF object: kernel-provided ones live in vmlinux, and locally-defined
3054+ @kfunc bodies live in the sibling kernel module compiled alongside the
3055+ eBPF program. Without __ksym, bpftool's skeleton generator looks for
3056+ BTF inside the .o and fails. Standard BPF helpers are skipped entirely
3057+ - libbpf's bpf_helpers.h already declares them, and a __ksym extern
3058+ would clash with that declaration. *)
30563059 let name = kfunc_decl.Ir. ikfunc_name in
30573060 if kfunc_decl.Ir. ikfunc_is_extern && Bpf_helpers. is_bpf_helper name then
30583061 ()
@@ -3064,13 +3067,8 @@ let generate_declarations_in_source_order_unified ctx ir_multi_prog ~_btf_path _
30643067 ) params)
30653068 in
30663069 let return_type_str = kfunc_signature_type_to_c kfunc_decl.Ir. ikfunc_return_type in
3067- if kfunc_decl.Ir. ikfunc_is_extern then
3068- emit_line ctx (sprintf " extern %s %s(%s) __ksym;"
3069- return_type_str name params_str)
3070- else (
3071- emit_line ctx " /* kfunc declaration */" ;
3072- emit_line ctx (sprintf " %s %s(%s);" return_type_str name params_str)
3073- );
3070+ emit_line ctx (sprintf " extern %s %s(%s) __ksym;"
3071+ return_type_str name params_str);
30743072 emit_blank_line ctx
30753073 )
30763074 ) ir_multi_prog.Ir. source_declarations;
0 commit comments