From: Masami Hiramatsu Date: Sat, 3 Jul 2021 15:35:27 +0000 (+0900) Subject: perf symbol-elf: Decode dynsym even if symtab exists X-Git-Tag: v5.15~734^2~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87704345cc602a845be713abdc679d65dc600431;p=platform%2Fkernel%2Flinux-starfive.git perf symbol-elf: Decode dynsym even if symtab exists In Fedora34, libc-2.33.so has both .dynsym and .symtab sections and most of (not all) symbols moved to .dynsym. In this case, perf only decode the symbols in .symtab, and perf probe can not list up the functions in the library. To fix this issue, decode both .symtab and .dynsym sections. Without this fix, ----- $ ./perf probe -x /usr/lib64/libc-2.33.so -F @plt @plt calloc@plt free@plt malloc@plt memalign@plt realloc@plt ----- With this fix. ----- $ ./perf probe -x /usr/lib64/libc-2.33.so -F @plt @plt a64l abort abs accept accept4 access acct addmntent ----- Reported-by: Thomas Richter Signed-off-by: Masami Hiramatsu Acked-by: Thomas Richter Cc: Heiko Carstens Cc: Stefan Liebler Cc: Sven Schnelle Link: http://lore.kernel.org/lkml/162532652681.393143.10163733179955267999.stgit@devnote2 Signed-off-by: Arnaldo Carvalho de Melo --- diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index a733457..eb10b4e 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1074,8 +1074,9 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, return 0; } -int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, - struct symsrc *runtime_ss, int kmodule) +static int +dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, + struct symsrc *runtime_ss, int kmodule, int dynsym) { struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL; struct maps *kmaps = kmap ? map__kmaps(map) : NULL; @@ -1098,34 +1099,15 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, if (kmap && !kmaps) return -1; - dso->symtab_type = syms_ss->type; - dso->is_64_bit = syms_ss->is_64_bit; - dso->rel = syms_ss->ehdr.e_type == ET_REL; - - /* - * Modules may already have symbols from kallsyms, but those symbols - * have the wrong values for the dso maps, so remove them. - */ - if (kmodule && syms_ss->symtab) - symbols__delete(&dso->symbols); - - if (!syms_ss->symtab) { - /* - * If the vmlinux is stripped, fail so we will fall back - * to using kallsyms. The vmlinux runtime symbols aren't - * of much use. - */ - if (dso->kernel) - goto out_elf_end; - - syms_ss->symtab = syms_ss->dynsym; - syms_ss->symshdr = syms_ss->dynshdr; - } - elf = syms_ss->elf; ehdr = syms_ss->ehdr; - sec = syms_ss->symtab; - shdr = syms_ss->symshdr; + if (dynsym) { + sec = syms_ss->dynsym; + shdr = syms_ss->dynshdr; + } else { + sec = syms_ss->symtab; + shdr = syms_ss->symshdr; + } if (elf_section_by_name(runtime_ss->elf, &runtime_ss->ehdr, &tshdr, ".text", NULL)) @@ -1312,6 +1294,50 @@ out_elf_end: return err; } +int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, + struct symsrc *runtime_ss, int kmodule) +{ + int nr = 0; + int err = -1; + + dso->symtab_type = syms_ss->type; + dso->is_64_bit = syms_ss->is_64_bit; + dso->rel = syms_ss->ehdr.e_type == ET_REL; + + /* + * Modules may already have symbols from kallsyms, but those symbols + * have the wrong values for the dso maps, so remove them. + */ + if (kmodule && syms_ss->symtab) + symbols__delete(&dso->symbols); + + if (!syms_ss->symtab) { + /* + * If the vmlinux is stripped, fail so we will fall back + * to using kallsyms. The vmlinux runtime symbols aren't + * of much use. + */ + if (dso->kernel) + return err; + } else { + err = dso__load_sym_internal(dso, map, syms_ss, runtime_ss, + kmodule, 0); + if (err < 0) + return err; + nr = err; + } + + if (syms_ss->dynsym) { + err = dso__load_sym_internal(dso, map, syms_ss, runtime_ss, + kmodule, 1); + if (err < 0) + return err; + err += nr; + } + + return err; +} + static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data) { GElf_Phdr phdr;