Commit a2488b5f authored by Alan Maguire's avatar Alan Maguire Committed by Alexei Starovoitov
Browse files

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: default avatarAlan Maguire <alan.maguire@oracle.com>
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20210714094400.396467-8-jolsa@kernel.org
parent ac0ed488
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
@@ -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);
	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,