Commit 90db26e6 authored by Alan Maguire's avatar Alan Maguire Committed by Andrii Nakryiko

libbpf: Improve string parsing for uprobe auto-attach

For uprobe auto-attach, the parsing can be simplified for the SEC()
name to a single sscanf(); the return value of the sscanf can then
be used to distinguish between sections that simply specify
"u[ret]probe" (and thus cannot auto-attach), those that specify
"u[ret]probe/binary_path:function+offset" etc.
Suggested-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/1649245431-29956-3-git-send-email-alan.maguire@oracle.com
parent a1c9d61b
...@@ -10913,60 +10913,45 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid, ...@@ -10913,60 +10913,45 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link) static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link)
{ {
DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts); DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts);
char *func, *probe_name, *func_end; char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;
char *func_name, binary_path[512]; int n, ret = -EINVAL;
unsigned long long raw_offset; long offset = 0;
size_t offset = 0;
int n;
*link = NULL; *link = NULL;
opts.retprobe = str_has_pfx(prog->sec_name, "uretprobe"); n = sscanf(prog->sec_name, "%m[^/]/%m[^:]:%m[a-zA-Z0-9_.]+%li",
if (opts.retprobe) &probe_type, &binary_path, &func_name, &offset);
probe_name = prog->sec_name + sizeof("uretprobe") - 1; switch (n) {
else case 1:
probe_name = prog->sec_name + sizeof("uprobe") - 1;
if (probe_name[0] == '/')
probe_name++;
/* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */ /* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */
if (strlen(probe_name) == 0) ret = 0;
return 0; break;
case 2:
snprintf(binary_path, sizeof(binary_path), "%s", probe_name); pr_warn("prog '%s': section '%s' missing ':function[+offset]' specification\n",
/* ':' should be prior to function+offset */ prog->name, prog->sec_name);
func_name = strrchr(binary_path, ':'); break;
if (!func_name) { case 3:
pr_warn("section '%s' missing ':function[+offset]' specification\n", case 4:
prog->sec_name); opts.retprobe = strcmp(probe_type, "uretprobe") == 0;
return -EINVAL;
}
func_name[0] = '\0';
func_name++;
n = sscanf(func_name, "%m[a-zA-Z0-9_.]+%li", &func, &offset);
if (n < 1) {
pr_warn("uprobe name '%s' is invalid\n", func_name);
return -EINVAL;
}
if (opts.retprobe && offset != 0) { if (opts.retprobe && offset != 0) {
free(func); pr_warn("prog '%s': uretprobes do not support offset specification\n",
pr_warn("uretprobes do not support offset specification\n"); prog->name);
return -EINVAL; break;
} }
opts.func_name = func_name;
/* Is func a raw address? */ *link = bpf_program__attach_uprobe_opts(prog, -1, binary_path, offset, &opts);
errno = 0; ret = libbpf_get_error(*link);
raw_offset = strtoull(func, &func_end, 0); break;
if (!errno && !*func_end) { default:
free(func); pr_warn("prog '%s': invalid format of section definition '%s'\n", prog->name,
func = NULL; prog->sec_name);
offset = (size_t)raw_offset; break;
} }
opts.func_name = func; free(probe_type);
free(binary_path);
free(func_name);
*link = bpf_program__attach_uprobe_opts(prog, -1, binary_path, offset, &opts); return ret;
free(func);
return libbpf_get_error(*link);
} }
struct bpf_link *bpf_program__attach_uprobe(const struct bpf_program *prog, struct bpf_link *bpf_program__attach_uprobe(const struct bpf_program *prog,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment