diff options
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r-- | tools/lib/bpf/libbpf.c | 21 |
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 | } |
434 | skip_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 | ||
1430 | static 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 | |||
1429 | static int | 1436 | static int |
1430 | bpf_object__load_progs(struct bpf_object *obj) | 1437 | bpf_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 | ||