aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2018-06-28 17:41:38 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-06-30 19:01:50 -0400
commit9a94f277c4fb84815f450418d37bfc568d57b5cc (patch)
tree967999fb046e005b1026f0280f8be0b7f6190f6a /tools
parent9aba36139a5f9ee1d11a60d0a3a90944b8d56385 (diff)
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 48cca7e44f9f ("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: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/bpf/libbpf.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 7bc02d93e277..e2401b95f08d 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -234,6 +234,7 @@ struct bpf_object {
234 size_t nr_maps; 234 size_t nr_maps;
235 235
236 bool loaded; 236 bool loaded;
237 bool has_pseudo_calls;
237 238
238 /* 239 /*
239 * Information when doing elf related work. Only valid if fd 240 * Information when doing elf related work. Only valid if fd
@@ -400,10 +401,6 @@ bpf_object__init_prog_names(struct bpf_object *obj)
400 const char *name = NULL; 401 const char *name = NULL;
401 402
402 prog = &obj->programs[pi]; 403 prog = &obj->programs[pi];
403 if (prog->idx == obj->efile.text_shndx) {
404 name = ".text";
405 goto skip_search;
406 }
407 404
408 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; 405 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name;
409 si++) { 406 si++) {
@@ -426,12 +423,15 @@ bpf_object__init_prog_names(struct bpf_object *obj)
426 } 423 }
427 } 424 }
428 425
426 if (!name && prog->idx == obj->efile.text_shndx)
427 name = ".text";
428
429 if (!name) { 429 if (!name) {
430 pr_warning("failed to find sym for prog %s\n", 430 pr_warning("failed to find sym for prog %s\n",
431 prog->section_name); 431 prog->section_name);
432 return -EINVAL; 432 return -EINVAL;
433 } 433 }
434skip_search: 434
435 prog->name = strdup(name); 435 prog->name = strdup(name);
436 if (!prog->name) { 436 if (!prog->name) {
437 pr_warning("failed to allocate memory for prog sym %s\n", 437 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 prog->reloc_desc[i].type = RELO_CALL; 981 prog->reloc_desc[i].type = RELO_CALL;
982 prog->reloc_desc[i].insn_idx = insn_idx; 982 prog->reloc_desc[i].insn_idx = insn_idx;
983 prog->reloc_desc[i].text_off = sym.st_value; 983 prog->reloc_desc[i].text_off = sym.st_value;
984 obj->has_pseudo_calls = true;
984 continue; 985 continue;
985 } 986 }
986 987
@@ -1426,6 +1427,12 @@ out:
1426 return err; 1427 return err;
1427} 1428}
1428 1429
1430static bool bpf_program__is_function_storage(struct bpf_program *prog,
1431 struct bpf_object *obj)
1432{
1433 return prog->idx == obj->efile.text_shndx && obj->has_pseudo_calls;
1434}
1435
1429static int 1436static int
1430bpf_object__load_progs(struct bpf_object *obj) 1437bpf_object__load_progs(struct bpf_object *obj)
1431{ 1438{
@@ -1433,7 +1440,7 @@ bpf_object__load_progs(struct bpf_object *obj)
1433 int err; 1440 int err;
1434 1441
1435 for (i = 0; i < obj->nr_programs; i++) { 1442 for (i = 0; i < obj->nr_programs; i++) {
1436 if (obj->programs[i].idx == obj->efile.text_shndx) 1443 if (bpf_program__is_function_storage(&obj->programs[i], obj))
1437 continue; 1444 continue;
1438 err = bpf_program__load(&obj->programs[i], 1445 err = bpf_program__load(&obj->programs[i],
1439 obj->license, 1446 obj->license,
@@ -2247,7 +2254,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
2247 bpf_program__set_expected_attach_type(prog, 2254 bpf_program__set_expected_attach_type(prog,
2248 expected_attach_type); 2255 expected_attach_type);
2249 2256
2250 if (prog->idx != obj->efile.text_shndx && !first_prog) 2257 if (!bpf_program__is_function_storage(prog, obj) && !first_prog)
2251 first_prog = prog; 2258 first_prog = prog;
2252 } 2259 }
2253 2260