aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-07-02 20:24:14 -0400
committerIngo Molnar <mingo@elte.hu>2009-07-03 02:24:13 -0400
commit30d7a77dd5a9720430af72f6f62f5156fe073e55 (patch)
tree1b09e7b1a1d560b1604e124832bcabf6693cd4fa /tools
parent24b57c6988c5791628c89a8838910991abc9cc1e (diff)
perf_counter tools: Adjust symbols in ET_EXEC files too
Ingo Molnar wrote: > i just bisected a 'perf report' bug that would cause us to not > resolve all user-space symbols in a 'git gc' run to: > > f5812a7a336fb952d819e4427b9a2dce02368e82 is first bad commit > commit f5812a7a336fb952d819e4427b9a2dce02368e82 > Author: Arnaldo Carvalho de Melo <acme@redhat.com> > Date: Tue Jun 30 11:43:17 2009 -0300 > > perf_counter tools: Adjust only prelinked symbol's addresses Rename ->prelinked to ->adjust_symbols and making what was done only for prelinked libraries also to ET_EXEC binaries, such as /usr/bin/git: [acme@doppio pahole]$ readelf -h /usr/bin/git | grep Type Type: EXEC (Executable file) [acme@doppio pahole]$ And after installing the 'git-debuginfo' package, I get correct results: [acme@doppio linux-2.6-tip]$ perf report --sort comm,dso,symbol -d /usr/bin/git | head -20 # # (1139614 samples) # # Overhead Command Shared Object Symbol # ........ ................ ......................... ...... # 34.98% git /usr/bin/git [.] send_sideband 33.39% git /usr/bin/git [.] enter_repo 6.81% git /usr/bin/git [.] diff_opt_parse 4.95% git /usr/bin/git [.] is_repository_shallow 3.24% git /usr/bin/git [.] odb_mkstemp 1.39% git /usr/bin/git [.] output 1.34% git /usr/bin/git [.] xmmap 1.25% git /usr/bin/git [.] receive_pack_config 1.16% git /usr/bin/git [.] git_pathdup 0.90% git /usr/bin/git [.] read_object_with_reference 0.86% git /usr/bin/git [.] show_patch_diff 0.85% git /usr/bin/git 0x00000000095e2e 0.69% git /usr/bin/git [.] display [acme@doppio linux-2.6-tip]$ I'll check what are the last cases where we can't resolve symbols, like this 0x00000000095e2e later. And I guess this will fix the problems Mike were seeing too: [acme@doppio linux-2.6-tip]$ readelf -h ../build/perf/vmlinux | grep Type Type: EXEC (Executable file) [acme@doppio linux-2.6-tip]$ Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/symbol.c11
-rw-r--r--tools/perf/util/symbol.h2
2 files changed, 7 insertions, 6 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 98a13114de70..4683b67b5ee4 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -555,9 +555,10 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
555 nr_syms = shdr.sh_size / shdr.sh_entsize; 555 nr_syms = shdr.sh_size / shdr.sh_entsize;
556 556
557 memset(&sym, 0, sizeof(sym)); 557 memset(&sym, 0, sizeof(sym));
558 self->prelinked = elf_section_by_name(elf, &ehdr, &shdr, 558 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
559 ".gnu.prelink_undo", 559 elf_section_by_name(elf, &ehdr, &shdr,
560 NULL) != NULL; 560 ".gnu.prelink_undo",
561 NULL) != NULL);
561 elf_symtab__for_each_symbol(syms, nr_syms, index, sym) { 562 elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
562 struct symbol *f; 563 struct symbol *f;
563 u64 obj_start; 564 u64 obj_start;
@@ -580,7 +581,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
580 section_name = elf_sec__name(&shdr, secstrs); 581 section_name = elf_sec__name(&shdr, secstrs);
581 obj_start = sym.st_value; 582 obj_start = sym.st_value;
582 583
583 if (self->prelinked) { 584 if (self->adjust_symbols) {
584 if (verbose >= 2) 585 if (verbose >= 2)
585 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", 586 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
586 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); 587 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
@@ -632,7 +633,7 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
632 if (!name) 633 if (!name)
633 return -1; 634 return -1;
634 635
635 self->prelinked = 0; 636 self->adjust_symbols = 0;
636 637
637 if (strncmp(self->name, "/tmp/perf-", 10) == 0) 638 if (strncmp(self->name, "/tmp/perf-", 10) == 0)
638 return dso__load_perf_map(self, filter, verbose); 639 return dso__load_perf_map(self, filter, verbose);
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4e141a30911e..7918cffb23cd 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -24,7 +24,7 @@ struct dso {
24 struct rb_root syms; 24 struct rb_root syms;
25 struct symbol *(*find_symbol)(struct dso *, u64 ip); 25 struct symbol *(*find_symbol)(struct dso *, u64 ip);
26 unsigned int sym_priv_size; 26 unsigned int sym_priv_size;
27 unsigned char prelinked; 27 unsigned char adjust_symbols;
28 char name[0]; 28 char name[0];
29}; 29};
30 30