diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-07-02 20:24:14 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-07-03 02:24:13 -0400 |
commit | 30d7a77dd5a9720430af72f6f62f5156fe073e55 (patch) | |
tree | 1b09e7b1a1d560b1604e124832bcabf6693cd4fa /tools/perf/util | |
parent | 24b57c6988c5791628c89a8838910991abc9cc1e (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/perf/util')
-rw-r--r-- | tools/perf/util/symbol.c | 11 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 2 |
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 | ||