I would like to define my own custom kfunc (in a loadable linux kernel module) that I can then use in a bpf program. I think I'm 99% there, but I'm stuck on loading the bpf program with bpftool. What I see is:
libbpf: failed to find BTF for extern 'foo_bar': -3
The foo_bar is my custom kfunc (see below). I do not understand where the symbol is looked for...
Reproduction
$ make
make -C /lib/modules/6.16.2-zen1-1-zen/build M=/home/xyz modules
make[1]: Entering directory '/usr/lib/modules/6.16.2-zen1-1-zen/build'
make[2]: Entering directory '/home/xyz'
CC [M] kfoo.o
MODPOST Module.symvers
CC [M] kfoo.mod.o
CC [M] .module-common.o
LD [M] kfoo.ko
BTF [M] kfoo.ko
make[2]: Leaving directory '/home/xyz'
make[1]: Leaving directory '/usr/lib/modules/6.16.2-zen1-1-zen/build'
$ sudo insmod kfoo.ko
$ strings /sys/kernel/btf/kfoo
foo_bar
bpf_kfunc
kfoo_exit
kfoo_init
regs
$ clang -Wall -Werror -O2 -target bpf -c foo_bpf.c -o foo_bpf.o
$ sudo bpftool prog load foo_bpf.o /sys/fs/bpf/foo_bpf autoattach
libbpf: failed to find BTF for extern 'foo_bar': -3
Error: failed to open object file
The sources I'm using are below.
foo_bpf.c
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <asm/ptrace.h>
extern int foo_bar(struct pt_regs *regs);
SEC("uretprobe//tmp/app:foo")
int foo_bar_call(struct pt_regs *ctx) {
foo_bar(ctx);
return 0;
}
char _license[] SEC("license") = "GPL";
kfoo.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/btf.h>
__bpf_kfunc int foo_bar(struct pt_regs *regs);
__bpf_kfunc_start_defs();
__bpf_kfunc int foo_bar(struct pt_regs *regs)
{
pr_err("foo_bar\n");
return 0;
}
__bpf_kfunc_end_defs();
BTF_KFUNCS_START(kfunc_foo_bar)
BTF_ID_FLAGS(func, foo_bar)
BTF_KFUNCS_END(kfunc_foo_bar)
static const struct btf_kfunc_id_set foo_bar_set = {
.owner = THIS_MODULE,
.set = &kfunc_foo_bar,
};
static int __init kfoo_init(void)
{
int ret;
ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_KPROBE, &foo_bar_set);
pr_err("%s: %d\n", __func__, ret);
return ret;
}
static void __exit kfoo_exit(void)
{
pr_err("%s: bye\n", __func__);
}
MODULE_LICENSE("GPL");
module_init(kfoo_init);
module_exit(kfoo_exit);
Makefile
obj-m += kfoo.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
-gto clang invocation gives now:libbpf: failed to find BTF for extern 'foo_bar' [7] section: -2which is as enigmatic as the previous error.