perf_counter tools: Adjust symbols in ET_EXEC files too
authorArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 3 Jul 2009 00:24:14 +0000 (21:24 -0300)
committerIngo Molnar <mingo@elte.hu>
Fri, 3 Jul 2009 06:24:13 +0000 (08:24 +0200)
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>
tools/perf/util/symbol.c
tools/perf/util/symbol.h

index 98a13114de70e470788136a46b98ac43923e22a8..4683b67b5ee4316cfb9a7266da799194bb4ad957 100644 (file)
@@ -555,9 +555,10 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
        nr_syms = shdr.sh_size / shdr.sh_entsize;
 
        memset(&sym, 0, sizeof(sym));
-       self->prelinked = elf_section_by_name(elf, &ehdr, &shdr,
-                                             ".gnu.prelink_undo",
-                                             NULL) != NULL;
+       self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
+                               elf_section_by_name(elf, &ehdr, &shdr,
+                                                    ".gnu.prelink_undo",
+                                                    NULL) != NULL);
        elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
                struct symbol *f;
                u64 obj_start;
@@ -580,7 +581,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
                section_name = elf_sec__name(&shdr, secstrs);
                obj_start = sym.st_value;
 
-               if (self->prelinked) {
+               if (self->adjust_symbols) {
                        if (verbose >= 2)
                                printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
                                        (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)
        if (!name)
                return -1;
 
-       self->prelinked = 0;
+       self->adjust_symbols = 0;
 
        if (strncmp(self->name, "/tmp/perf-", 10) == 0)
                return dso__load_perf_map(self, filter, verbose);
index 4e141a30911e62f3f140dcd9a0e369eb772b10db..7918cffb23cd35726cad6eca22acce0fd74cf392 100644 (file)
@@ -24,7 +24,7 @@ struct dso {
        struct rb_root   syms;
        struct symbol    *(*find_symbol)(struct dso *, u64 ip);
        unsigned int     sym_priv_size;
-       unsigned char    prelinked;
+       unsigned char    adjust_symbols;
        char             name[0];
 };