Commit 9a94f277 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Daniel Borkmann

tools: libbpf: restore the ability to load programs from .text section

libbpf used to be able to load programs from the default section
called '.text'.  It's not very common to leave sections unnamed,
but if it happens libbpf will fail to load the programs reporting
-EINVAL from the kernel.  The -EINVAL comes from bpf_obj_name_cpy()
because since 48cca7e4 ("libbpf: add support for bpf_call")
libbpf does not resolve program names for programs in '.text',
defaulting to '.text'.  '.text', however, does not pass the
(isalnum(*src) || *src == '_') check in bpf_obj_name_cpy().

With few extra lines of code we can limit the pseudo call
assumptions only to objects which actually contain code relocations.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 9aba3613
...@@ -234,6 +234,7 @@ struct bpf_object { ...@@ -234,6 +234,7 @@ struct bpf_object {
size_t nr_maps; size_t nr_maps;
bool loaded; bool loaded;
bool has_pseudo_calls;
/* /*
* Information when doing elf related work. Only valid if fd * Information when doing elf related work. Only valid if fd
...@@ -400,10 +401,6 @@ bpf_object__init_prog_names(struct bpf_object *obj) ...@@ -400,10 +401,6 @@ bpf_object__init_prog_names(struct bpf_object *obj)
const char *name = NULL; const char *name = NULL;
prog = &obj->programs[pi]; prog = &obj->programs[pi];
if (prog->idx == obj->efile.text_shndx) {
name = ".text";
goto skip_search;
}
for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name;
si++) { si++) {
...@@ -426,12 +423,15 @@ bpf_object__init_prog_names(struct bpf_object *obj) ...@@ -426,12 +423,15 @@ bpf_object__init_prog_names(struct bpf_object *obj)
} }
} }
if (!name && prog->idx == obj->efile.text_shndx)
name = ".text";
if (!name) { if (!name) {
pr_warning("failed to find sym for prog %s\n", pr_warning("failed to find sym for prog %s\n",
prog->section_name); prog->section_name);
return -EINVAL; return -EINVAL;
} }
skip_search:
prog->name = strdup(name); prog->name = strdup(name);
if (!prog->name) { if (!prog->name) {
pr_warning("failed to allocate memory for prog sym %s\n", pr_warning("failed to allocate memory for prog sym %s\n",
...@@ -981,6 +981,7 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, ...@@ -981,6 +981,7 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
prog->reloc_desc[i].type = RELO_CALL; prog->reloc_desc[i].type = RELO_CALL;
prog->reloc_desc[i].insn_idx = insn_idx; prog->reloc_desc[i].insn_idx = insn_idx;
prog->reloc_desc[i].text_off = sym.st_value; prog->reloc_desc[i].text_off = sym.st_value;
obj->has_pseudo_calls = true;
continue; continue;
} }
...@@ -1426,6 +1427,12 @@ bpf_program__load(struct bpf_program *prog, ...@@ -1426,6 +1427,12 @@ bpf_program__load(struct bpf_program *prog,
return err; return err;
} }
static bool bpf_program__is_function_storage(struct bpf_program *prog,
struct bpf_object *obj)
{
return prog->idx == obj->efile.text_shndx && obj->has_pseudo_calls;
}
static int static int
bpf_object__load_progs(struct bpf_object *obj) bpf_object__load_progs(struct bpf_object *obj)
{ {
...@@ -1433,7 +1440,7 @@ bpf_object__load_progs(struct bpf_object *obj) ...@@ -1433,7 +1440,7 @@ bpf_object__load_progs(struct bpf_object *obj)
int err; int err;
for (i = 0; i < obj->nr_programs; i++) { for (i = 0; i < obj->nr_programs; i++) {
if (obj->programs[i].idx == obj->efile.text_shndx) if (bpf_program__is_function_storage(&obj->programs[i], obj))
continue; continue;
err = bpf_program__load(&obj->programs[i], err = bpf_program__load(&obj->programs[i],
obj->license, obj->license,
...@@ -2247,7 +2254,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, ...@@ -2247,7 +2254,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
bpf_program__set_expected_attach_type(prog, bpf_program__set_expected_attach_type(prog,
expected_attach_type); expected_attach_type);
if (prog->idx != obj->efile.text_shndx && !first_prog) if (!bpf_program__is_function_storage(prog, obj) && !first_prog)
first_prog = prog; first_prog = 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