perf symbols: Split kernel symbol processing from dso__load_sym()
tip-bot for Arnaldo Carvalho de Melo
merge botCommit-ID: 4e0d1e8bcb96821ea16c8c025f36a112804e829f Gitweb: https://git.kernel.org/tip/4e0d1e8bcb96821ea16c8c025f36a112804e829f Author: Arnaldo Carvalho de Melo <[email protected]> AuthorDate: Fri, 27 Apr 2018 15:15:24 -0300 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Fri, 27 Apr 2018 15:15:24 -0300
perf symbols: Split kernel symbol processing from dso__load_sym()
More should be done to split this function, removing stuff map relocation steps from the actual symbol table loading.
Arch specific stuff also should go elsewhere, to tools/arch/ and we should have it keyed by data from the perf_env either in the perf.data header or from the running environment.
Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Wang Nan <[email protected]>
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>
--- tools/perf/util/symbol-elf.c | 205 +++++++++++++++++++++++-------------------- 1 file changed, 108 insertions(+), 97 deletions(-)
tools/perf/util/symbol-elf.c +108 -97
@@ -797,6 +797,110 @@ static u64 ref_reloc(struct kmap *kmap)void __weak arch__sym_update (struct symbol *s__maybe_unused ,GElf_Sym *sym__maybe_unused ) { } +static int dso__process_kernel_symbol (struct dso *dso,struct map *map, +GElf_Sym *sym,GElf_Shdr *shdr, +struct map_groups *kmaps,struct kmap *kmap, +struct dso **curr_dsop,struct map **curr_mapp, +const char *section_name, +bool adjust_kernel_syms,bool kmodule,bool *remap_kernel) +{ +struct dso *curr_dso = *curr_dsop; +struct map *curr_map; +char dso_name[PATH_MAX ]; + +/* Adjust symbol to map to file offset */ +if (adjust_kernel_syms) + sym->st_value -= shdr->sh_addr - shdr->sh_offset; + +if (strcmp (section_name, (curr_dso->short_name + dso->short_name_len)) ==0 ) +return 0 ; + +if (strcmp (section_name,".text" ) ==0 ) { +/* +* The initial kernel mapping is based on +* kallsyms and identity maps. Overwrite it to +* map to the kernel dso. +*/ +if (*remap_kernel && dso->kernel) { + *remap_kernel = false; + map->start = shdr->sh_addr +ref_reloc (kmap); + map->end = map->start + shdr->sh_size; + map->pgoff = shdr->sh_offset; + map->map_ip = map__map_ip; + map->unmap_ip = map__unmap_ip; +/* Ensure maps are correctly ordered */ +if (kmaps) { +map__get (map); +map_groups__remove (kmaps, map); +map_groups__insert (kmaps, map); +map__put (map); + } + } + +/* +* The initial module mapping is based on +* /proc/modules mapped to offset zero. +* Overwrite it to map to the module dso. +*/ +if (*remap_kernel && kmodule) { + *remap_kernel = false; + map->pgoff = shdr->sh_offset; + } + + *curr_mapp = map; + *curr_dsop = dso; +return 0 ; + } + +if (!kmap) +return 0 ; + +snprintf (dso_name,sizeof (dso_name),"%s%s" , dso->short_name, section_name); + + curr_map =map_groups__find_by_name (kmaps, dso_name); +if (curr_map ==NULL ) { +u64 start = sym->st_value; + +if (kmodule) + start += map->start + shdr->sh_offset; + + curr_dso =dso__new (dso_name); +if (curr_dso ==NULL ) +return -1 ; + curr_dso->kernel = dso->kernel; + curr_dso->long_name = dso->long_name; + curr_dso->long_name_len = dso->long_name_len; + curr_map =map__new2 (start, curr_dso); +dso__put (curr_dso); +if (curr_map ==NULL ) +return -1 ; + +if (adjust_kernel_syms) { + curr_map->start = shdr->sh_addr +ref_reloc (kmap); + curr_map->end = curr_map->start + shdr->sh_size; + curr_map->pgoff = shdr->sh_offset; + }else { + curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; + } + curr_dso->symtab_type = dso->symtab_type; +map_groups__insert (kmaps, curr_map); +/* +* Add it before we drop the referece to curr_map, i.e. while +* we still are sure to have a reference to this DSO via +* *curr_map->dso. +*/ +dsos__add (&map->groups->machine->dsos, curr_dso); +/* kmaps already got it */ +map__put (curr_map); +dso__set_loaded (curr_dso); + *curr_mapp = curr_map; + *curr_dsop = curr_dso; + }else + *curr_dsop = curr_map->dso; + +return 0 ; +} +int dso__load_sym (struct dso *dso,struct map *map,struct symsrc *syms_ss,struct symsrc *runtime_ss,int kmodule) {
@@ -973,102 +1077,9 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, --sym.st_value;if (dso->kernel || kmodule) { -char dso_name[PATH_MAX ]; - -/* Adjust symbol to map to file offset */ -if (adjust_kernel_syms) - sym.st_value -= shdr.sh_addr - shdr.sh_offset; - -if (strcmp (section_name, - (curr_dso->short_name + - dso->short_name_len)) ==0 ) - goto new_symbol; - -if (strcmp (section_name,".text" ) ==0 ) { -/* -* The initial kernel mapping is based on -* kallsyms and identity maps. Overwrite it to -* map to the kernel dso. -*/ -if (remap_kernel && dso->kernel) { - remap_kernel = false; - map->start = shdr.sh_addr + -ref_reloc (kmap); - map->end = map->start + shdr.sh_size; - map->pgoff = shdr.sh_offset; - map->map_ip = map__map_ip; - map->unmap_ip = map__unmap_ip; -/* Ensure maps are correctly ordered */ -if (kmaps) { -map__get (map); -map_groups__remove (kmaps, map); -map_groups__insert (kmaps, map); -map__put (map); - } - } - -/* -* The initial module mapping is based on -* /proc/modules mapped to offset zero. -* Overwrite it to map to the module dso. -*/ -if (remap_kernel && kmodule) { - remap_kernel = false; - map->pgoff = shdr.sh_offset; - } - - curr_map = map; - curr_dso = dso; - goto new_symbol; - } - -if (!kmap) - goto new_symbol; - -snprintf (dso_name,sizeof (dso_name), -"%s%s" , dso->short_name, section_name); - - curr_map =map_groups__find_by_name (kmaps, dso_name); -if (curr_map ==NULL ) { -u64 start = sym.st_value; - -if (kmodule) - start += map->start + shdr.sh_offset; - - curr_dso =dso__new (dso_name); -if (curr_dso ==NULL ) - goto out_elf_end; - curr_dso->kernel = dso->kernel; - curr_dso->long_name = dso->long_name; - curr_dso->long_name_len = dso->long_name_len; - curr_map =map__new2 (start, curr_dso); -dso__put (curr_dso); -if (curr_map ==NULL ) { - goto out_elf_end; - } -if (adjust_kernel_syms) { - curr_map->start = shdr.sh_addr + -ref_reloc (kmap); - curr_map->end = curr_map->start + - shdr.sh_size; - curr_map->pgoff = shdr.sh_offset; - }else { - curr_map->map_ip = identity__map_ip; - curr_map->unmap_ip = identity__map_ip; - } - curr_dso->symtab_type = dso->symtab_type; -map_groups__insert (kmaps, curr_map); -/* -* Add it before we drop the referece to curr_map, -* i.e. while we still are sure to have a reference -* to this DSO via curr_map->dso. -*/ -dsos__add (&map->groups->machine->dsos, curr_dso); -/* kmaps already got it */ -map__put (curr_map); -dso__set_loaded (curr_dso); - }else - curr_dso = curr_map->dso; +if (dso__process_kernel_symbol (dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map, + section_name, adjust_kernel_syms, kmodule, &remap_kernel)) + goto out_elf_end; }else if ((used_opd && runtime_ss->adjust_symbols) || (!used_opd && syms_ss->adjust_symbols)) { pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
@@ -1077,7 +1088,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, (u64)shdr.sh_offset); sym.st_value -= shdr.sh_addr - shdr.sh_offset; } -new_symbol: + demangled =demangle_sym (dso, kmodule, elf_name);if (demangled !=NULL ) elf_name = demangled;