On Wed, Jul 14, 2021 at 2:45 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > From: Alan Maguire <alan.maguire@xxxxxxxxxx> > > kprobes can be placed on most instructions in a function, not > just entry, and ftrace and bpftrace support the function+offset > notification for probe placement. Adding parsing of func_name > into func+offset to bpf_program__attach_kprobe() allows the > user to specify > > SEC("kprobe/bpf_fentry_test5+0x6") > > ...for example, and the offset can be passed to perf_event_open_probe() > to support kprobe attachment. > > [jolsa: changed original code to use bpf_program__attach_kprobe_opts > and use dynamic allocation in sscanf] > > Signed-off-by: Alan Maguire <alan.maguire@xxxxxxxxxx> > Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx> > --- > tools/lib/bpf/libbpf.c | 24 ++++++++++++++++++++++-- > 1 file changed, 22 insertions(+), 2 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index d93a6f9408d1..abe6d4842bb0 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -10348,6 +10348,7 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name, > > struct bpf_program_attach_kprobe_opts { > bool retprobe; > + unsigned long offset; > }; > > static struct bpf_link* > @@ -10360,7 +10361,7 @@ bpf_program__attach_kprobe_opts(struct bpf_program *prog, > int pfd, err; > > pfd = perf_event_open_probe(false /* uprobe */, opts->retprobe, func_name, > - 0 /* offset */, -1 /* pid */); > + opts->offset, -1 /* pid */); > if (pfd < 0) { > pr_warn("prog '%s': failed to create %s '%s' perf event: %s\n", > prog->name, opts->retprobe ? "kretprobe" : "kprobe", func_name, > @@ -10394,12 +10395,31 @@ static struct bpf_link *attach_kprobe(const struct bpf_sec_def *sec, > struct bpf_program *prog) > { > struct bpf_program_attach_kprobe_opts opts; > + unsigned long offset = 0; > + struct bpf_link *link; > const char *func_name; > + char *func; > + int n, err; > > func_name = prog->sec_name + sec->len; > opts.retprobe = strcmp(sec->sec, "kretprobe/") == 0; > > - return bpf_program__attach_kprobe_opts(prog, func_name, &opts); > + n = sscanf(func_name, "%m[a-zA-Z0-9_.]+%lx", &func, &offset); could have used %li here to support both +0xabc and +123 forms > + if (n < 1) { > + err = -EINVAL; > + pr_warn("kprobe name is invalid: %s\n", func_name); > + return libbpf_err_ptr(err); > + } > + if (opts.retprobe && offset != 0) { > + err = -EINVAL; leaking func here > + pr_warn("kretprobes do not support offset specification\n"); > + return libbpf_err_ptr(err); > + } > + > + opts.offset = offset; > + link = bpf_program__attach_kprobe_opts(prog, func, &opts); > + free(func); > + return link; > } > > struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog, > -- > 2.31.1 >