aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-06-30 10:43:17 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-30 11:09:30 -0400
commitf5812a7a336fb952d819e4427b9a2dce02368e82 (patch)
tree584b8581f68325c8e98a32df51c5155234e0e362
parent57e7986ed142417498155ebcd5eaf617ac37136d (diff)
perf_counter tools: Adjust only prelinked symbol's addresses
I.e. we can't handle these two kinds of files in the same way: 1) prelinked system library: [acme@doppio pahole]$ readelf -s /usr/lib64/libdw-0.141.so | egrep 'FUNC.+GLOBAL.+dwfl_report_elf' 278: 00000030450105a0 261 FUNC GLOBAL DEFAULT 12 dwfl_report_elf@@ELFUTILS_0.122 2) not prelinked library with debug information from a -debuginfo package: [acme@doppio pahole]$ readelf -s /usr/lib/debug/usr/lib64/libdw-0.141.so.debug | egrep 'FUNC.+GLOBAL.+dwfl_report_elf' 629: 00000000000105a0 261 FUNC GLOBAL DEFAULT 12 dwfl_report_elf [acme@doppio pahole]$ Now the numbers I got for a pahole perf run are in line with the numbers I get from oprofile. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <20090630144317.GB12663@ghostprotocols.net> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/util/symbol.c16
-rw-r--r--tools/perf/util/symbol.h3
2 files changed, 13 insertions, 6 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 9c659ef6aec2..78c2efde01b7 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -520,7 +520,9 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
520 nr_syms = shdr.sh_size / shdr.sh_entsize; 520 nr_syms = shdr.sh_size / shdr.sh_entsize;
521 521
522 memset(&sym, 0, sizeof(sym)); 522 memset(&sym, 0, sizeof(sym));
523 523 self->prelinked = elf_section_by_name(elf, &ehdr, &shdr,
524 ".gnu.prelink_undo",
525 NULL) != NULL;
524 elf_symtab__for_each_symbol(syms, nr_syms, index, sym) { 526 elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
525 struct symbol *f; 527 struct symbol *f;
526 u64 obj_start; 528 u64 obj_start;
@@ -535,11 +537,13 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
535 gelf_getshdr(sec, &shdr); 537 gelf_getshdr(sec, &shdr);
536 obj_start = sym.st_value; 538 obj_start = sym.st_value;
537 539
538 if (verbose >= 2) 540 if (self->prelinked) {
539 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", 541 if (verbose >= 2)
540 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); 542 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
543 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
541 544
542 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 545 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
546 }
543 547
544 f = symbol__new(sym.st_value, sym.st_size, 548 f = symbol__new(sym.st_value, sym.st_size,
545 elf_sym__name(&sym, symstrs), 549 elf_sym__name(&sym, symstrs),
@@ -573,6 +577,8 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
573 if (!name) 577 if (!name)
574 return -1; 578 return -1;
575 579
580 self->prelinked = 0;
581
576 if (strncmp(self->name, "/tmp/perf-", 10) == 0) 582 if (strncmp(self->name, "/tmp/perf-", 10) == 0)
577 return dso__load_perf_map(self, filter, verbose); 583 return dso__load_perf_map(self, filter, verbose);
578 584
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 940b432db16e..2c48ace8203b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -20,8 +20,9 @@ struct symbol {
20struct dso { 20struct dso {
21 struct list_head node; 21 struct list_head node;
22 struct rb_root syms; 22 struct rb_root syms;
23 unsigned int sym_priv_size;
24 struct symbol *(*find_symbol)(struct dso *, u64 ip); 23 struct symbol *(*find_symbol)(struct dso *, u64 ip);
24 unsigned int sym_priv_size;
25 unsigned char prelinked;
25 char name[0]; 26 char name[0];
26}; 27};
27 28