On Fri, Jul 16, 2021 at 06:42:05PM -0700, Andrii Nakryiko wrote: > 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 ok > > > + 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 ugh.. thanks jirka > > > > + 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 > > >