0

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
1
  • Adding -g to clang invocation gives now: libbpf: failed to find BTF for extern 'foo_bar' [7] section: -2 which is as enigmatic as the previous error. Commented Aug 27 at 6:10

1 Answer 1

0

Seem like I was missing few things:

  1. The -g is needed for the bpf program (btf needs DWARF symbols?).

  2. The extern declaration in bpf program must also have __ksym: extern int foo_bar(struct pt_regs *regs) __ksym;

  3. I also needed to #include <asm/ptrace.h> in bpf program and in kernel module (struct pt_regs is defined there).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.