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,
static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link)
{
DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts);
char *func, *probe_name, *func_end;
char *func_name, binary_path[512];
unsigned long long raw_offset;
size_t offset = 0;
int n;
char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;
int n, ret = -EINVAL;
long offset = 0;
*link = NULL;
opts.retprobe = str_has_pfx(prog->sec_name, "uretprobe");
if (opts.retprobe)
probe_name = prog->sec_name + sizeof("uretprobe") - 1;
else
probe_name = prog->sec_name + sizeof("uprobe") - 1;
if (probe_name[0] == '/')
probe_name++;
n = sscanf(prog->sec_name, "%m[^/]/%m[^:]:%m[a-zA-Z0-9_.]+%li",
&probe_type, &binary_path, &func_name, &offset);
switch (n) {
case 1:
/* handle SEC("u[ret]probe") - format is valid, but auto-attach is impossible. */
if (strlen(probe_name) == 0)
return 0;
snprintf(binary_path, sizeof(binary_path), "%s", probe_name);
/* ':' should be prior to function+offset */
func_name = strrchr(binary_path, ':');
if (!func_name) {
pr_warn("section '%s' missing ':function[+offset]' specification\n",
prog->sec_name);
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;
}
ret = 0;
break;
case 2:
pr_warn("prog '%s': section '%s' missing ':function[+offset]' specification\n",
prog->name, prog->sec_name);
break;
case 3:
case 4:
opts.retprobe = strcmp(probe_type, "uretprobe") == 0;
if (opts.retprobe && offset != 0) {
free(func);
pr_warn("uretprobes do not support offset specification\n");
return -EINVAL;
pr_warn("prog '%s': uretprobes do not support offset specification\n",
prog->name);
break;
}
/* 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_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);
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);
free(func);
return libbpf_get_error(*link);
return ret;
}
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