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; /* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */
if (probe_name[0] == '/') ret = 0;
probe_name++; break;
case 2:
/* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */ pr_warn("prog '%s': section '%s' missing ':function[+offset]' specification\n",
if (strlen(probe_name) == 0) prog->name, prog->sec_name);
return 0; break;
case 3:
snprintf(binary_path, sizeof(binary_path), "%s", probe_name); case 4:
/* ':' should be prior to function+offset */ opts.retprobe = strcmp(probe_type, "uretprobe") == 0;
func_name = strrchr(binary_path, ':'); if (opts.retprobe && offset != 0) {
if (!func_name) { pr_warn("prog '%s': uretprobes do not support offset specification\n",
pr_warn("section '%s' missing ':function[+offset]' specification\n", prog->name);
break;
}
opts.func_name = func_name;
*link = bpf_program__attach_uprobe_opts(prog, -1, binary_path, offset, &opts);
ret = libbpf_get_error(*link);
break;
default:
pr_warn("prog '%s': invalid format of section definition '%s'\n", prog->name,
prog->sec_name); prog->sec_name);
return -EINVAL; break;
}
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) {
free(func);
pr_warn("uretprobes do not support offset specification\n");
return -EINVAL;
}
/* Is func a raw address? */
errno = 0;
raw_offset = strtoull(func, &func_end, 0);
if (!errno && !*func_end) {
free(func);
func = NULL;
offset = (size_t)raw_offset;
} }
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