Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf symbols: Demangle symbols for synthesized @plt entries.

The symbols in the synthesized @plt entries where not demangled before,
i.e. we could end up with entries such as:

$ perf report
Samples: 7K of event 'cycles:ppp', Event count (approx.): 6223833141
Children Self Command Shared Object Symbol
- 93.63% 28.89% lab_mandelbrot lab_mandelbrot [.] main
- 73.81% main
- 33.57% hypot
27.76% __hypot_finite
15.97% __muldc3
2.90% __muldc3@plt
2.40% _ZNK6QImage6heightEv@plt
+ 2.14% QColor::rgb
1.94% _ZNK6QImage5widthEv@plt
1.92% cabs@plt

This patch remedies this issue by also applying demangling to the
synthesized symbols. The output for the above is now:

$ perf report
Samples: 7K of event 'cycles:ppp', Event count (approx.): 6223833141
Children Self Command Shared Object Symbol
- 93.63% 28.89% lab_mandelbrot lab_mandelbrot [.] main
- 73.81% main
- 33.57% hypot
27.76% __hypot_finite
15.97% __muldc3
2.90% __muldc3@plt
2.40% QImage::height() const@plt
+ 2.14% QColor::rgb
1.94% QImage::width() const@plt
1.92% cabs@plt

Signed-off-by: Milian Wolff <milian.wolff@kdab.com>
LPU-Reference: 20160830114102.30863-1-milian.wolff@kdab.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Milian Wolff and committed by
Arnaldo Carvalho de Melo
2a8d41b4 fd227598

+52 -29
+52 -29
tools/perf/util/symbol-elf.c
··· 206 206 return NULL; 207 207 } 208 208 209 + static bool want_demangle(bool is_kernel_sym) 210 + { 211 + return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle; 212 + } 213 + 214 + static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) 215 + { 216 + int demangle_flags = verbose ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; 217 + char *demangled = NULL; 218 + 219 + /* 220 + * We need to figure out if the object was created from C++ sources 221 + * DWARF DW_compile_unit has this, but we don't always have access 222 + * to it... 223 + */ 224 + if (!want_demangle(dso->kernel || kmodule)) 225 + return demangled; 226 + 227 + demangled = bfd_demangle(NULL, elf_name, demangle_flags); 228 + if (demangled == NULL) 229 + demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET); 230 + else if (rust_is_mangled(demangled)) 231 + /* 232 + * Input to Rust demangling is the BFD-demangled 233 + * name which it Rust-demangles in place. 234 + */ 235 + rust_demangle_sym(demangled); 236 + 237 + return demangled; 238 + } 239 + 209 240 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \ 210 241 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \ 211 242 idx < nr_entries; \ ··· 332 301 333 302 elf_section__for_each_rela(reldata, pos, pos_mem, idx, 334 303 nr_rel_entries) { 304 + const char *elf_name = NULL; 305 + char *demangled = NULL; 335 306 symidx = GELF_R_SYM(pos->r_info); 336 307 plt_offset += shdr_plt.sh_entsize; 337 308 gelf_getsym(syms, symidx, &sym); 309 + 310 + elf_name = elf_sym__name(&sym, symstrs); 311 + demangled = demangle_sym(dso, 0, elf_name); 312 + if (demangled != NULL) 313 + elf_name = demangled; 338 314 snprintf(sympltname, sizeof(sympltname), 339 - "%s@plt", elf_sym__name(&sym, symstrs)); 315 + "%s@plt", elf_name); 316 + free(demangled); 340 317 341 318 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 342 319 STB_GLOBAL, sympltname); ··· 362 323 GElf_Rel pos_mem, *pos; 363 324 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 364 325 nr_rel_entries) { 326 + const char *elf_name = NULL; 327 + char *demangled = NULL; 365 328 symidx = GELF_R_SYM(pos->r_info); 366 329 plt_offset += shdr_plt.sh_entsize; 367 330 gelf_getsym(syms, symidx, &sym); 331 + 332 + elf_name = elf_sym__name(&sym, symstrs); 333 + demangled = demangle_sym(dso, 0, elf_name); 334 + if (demangled != NULL) 335 + elf_name = demangled; 368 336 snprintf(sympltname, sizeof(sympltname), 369 - "%s@plt", elf_sym__name(&sym, symstrs)); 337 + "%s@plt", elf_name); 338 + free(demangled); 370 339 371 340 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 372 341 STB_GLOBAL, sympltname); ··· 822 775 return 0; 823 776 } 824 777 825 - static bool want_demangle(bool is_kernel_sym) 826 - { 827 - return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle; 828 - } 829 - 830 778 void __weak arch__sym_update(struct symbol *s __maybe_unused, 831 779 GElf_Sym *sym __maybe_unused) { } 832 780 ··· 1112 1070 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 1113 1071 } 1114 1072 new_symbol: 1115 - /* 1116 - * We need to figure out if the object was created from C++ sources 1117 - * DWARF DW_compile_unit has this, but we don't always have access 1118 - * to it... 1119 - */ 1120 - if (want_demangle(dso->kernel || kmodule)) { 1121 - int demangle_flags = DMGL_NO_OPTS; 1122 - if (verbose) 1123 - demangle_flags = DMGL_PARAMS | DMGL_ANSI; 1073 + demangled = demangle_sym(dso, kmodule, elf_name); 1074 + if (demangled != NULL) 1075 + elf_name = demangled; 1124 1076 1125 - demangled = bfd_demangle(NULL, elf_name, demangle_flags); 1126 - if (demangled == NULL) 1127 - demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET); 1128 - else if (rust_is_mangled(demangled)) 1129 - /* 1130 - * Input to Rust demangling is the BFD-demangled 1131 - * name which it Rust-demangles in place. 1132 - */ 1133 - rust_demangle_sym(demangled); 1134 - 1135 - if (demangled != NULL) 1136 - elf_name = demangled; 1137 - } 1138 1077 f = symbol__new(sym.st_value, sym.st_size, 1139 1078 GELF_ST_BIND(sym.st_info), elf_name); 1140 1079 free(demangled);