From: Menglong Dong <imagedong@xxxxxxxxxxx> The function name in kernel may be changed by the compiler. For example, the function 'ip_rcv_core' can be compiled to 'ip_rcv_core.isra.0'. This kind optimization can happen in any kernel function. Therefor, we should conside this case. If we failed to attach kprobe with a '-ENOENT', then we can lookup the kallsyms and check if there is a similar function end with '.xxx', and retry. Signed-off-by: Menglong Dong <imagedong@xxxxxxxxxxx> --- tools/lib/bpf/libbpf.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a5c67a3c93c5..fdfb1ca34ced 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -10375,12 +10375,30 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, return libbpf_err_ptr(err); } +struct kprobe_resolve { + char pattern[128]; + char name[128]; +}; + +static int kprobe_kallsyms_cb(unsigned long long sym_addr, char sym_type, + const char *sym_name, void *ctx) +{ + struct kprobe_resolve *res = ctx; + + if (!glob_match(sym_name, res->pattern)) + return 0; + strcpy(res->name, sym_name); + return 1; +} + static int attach_kprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link) { DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts); + struct kprobe_resolve res = {}; unsigned long offset = 0; const char *func_name; char *func; + int err; int n; *link = NULL; @@ -10408,8 +10426,25 @@ static int attach_kprobe(const struct bpf_program *prog, long cookie, struct bpf opts.offset = offset; *link = bpf_program__attach_kprobe_opts(prog, func, &opts); + err = libbpf_get_error(*link); + + if (!err || err != -ENOENT) + goto out; + + sprintf(res.pattern, "%s.*", func); + if (!libbpf_kallsyms_parse(kprobe_kallsyms_cb, &res)) + goto out; + + pr_warn("prog '%s': trying to create %s '%s+0x%zx' perf event instead\n", + prog->name, opts.retprobe ? "kretprobe" : "kprobe", + res.name, offset); + + *link = bpf_program__attach_kprobe_opts(prog, res.name, &opts); + err = libbpf_get_error(*link); + +out: free(func); - return libbpf_get_error(*link); + return err; } static int attach_ksyscall(const struct bpf_program *prog, long cookie, struct bpf_link **link) -- 2.39.0