mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
libbpf: Allow specification of "kprobe/function+offset"
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. Signed-off-by: Alan Maguire <alan.maguire@oracle.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20210714094400.396467-8-jolsa@kernel.org
This commit is contained in:
parent
ac0ed48829
commit
a2488b5f48
1 changed files with 22 additions and 2 deletions
|
@ -10348,6 +10348,7 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
|
||||||
|
|
||||||
struct bpf_program_attach_kprobe_opts {
|
struct bpf_program_attach_kprobe_opts {
|
||||||
bool retprobe;
|
bool retprobe;
|
||||||
|
unsigned long offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bpf_link*
|
static struct bpf_link*
|
||||||
|
@ -10360,7 +10361,7 @@ bpf_program__attach_kprobe_opts(struct bpf_program *prog,
|
||||||
int pfd, err;
|
int pfd, err;
|
||||||
|
|
||||||
pfd = perf_event_open_probe(false /* uprobe */, opts->retprobe, func_name,
|
pfd = perf_event_open_probe(false /* uprobe */, opts->retprobe, func_name,
|
||||||
0 /* offset */, -1 /* pid */);
|
opts->offset, -1 /* pid */);
|
||||||
if (pfd < 0) {
|
if (pfd < 0) {
|
||||||
pr_warn("prog '%s': failed to create %s '%s' perf event: %s\n",
|
pr_warn("prog '%s': failed to create %s '%s' perf event: %s\n",
|
||||||
prog->name, opts->retprobe ? "kretprobe" : "kprobe", func_name,
|
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 *prog)
|
||||||
{
|
{
|
||||||
struct bpf_program_attach_kprobe_opts opts;
|
struct bpf_program_attach_kprobe_opts opts;
|
||||||
|
unsigned long offset = 0;
|
||||||
|
struct bpf_link *link;
|
||||||
const char *func_name;
|
const char *func_name;
|
||||||
|
char *func;
|
||||||
|
int n, err;
|
||||||
|
|
||||||
func_name = prog->sec_name + sec->len;
|
func_name = prog->sec_name + sec->len;
|
||||||
opts.retprobe = strcmp(sec->sec, "kretprobe/") == 0;
|
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);
|
||||||
|
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;
|
||||||
|
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,
|
struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue