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>
This commit is contained in:
parent
57e7986ed1
commit
f5812a7a33
|
@ -520,7 +520,9 @@ 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;
|
||||
elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
|
||||
struct symbol *f;
|
||||
u64 obj_start;
|
||||
|
@ -535,11 +537,13 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
|
|||
gelf_getshdr(sec, &shdr);
|
||||
obj_start = sym.st_value;
|
||||
|
||||
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);
|
||||
if (self->prelinked) {
|
||||
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);
|
||||
|
||||
sym.st_value -= shdr.sh_addr - shdr.sh_offset;
|
||||
sym.st_value -= shdr.sh_addr - shdr.sh_offset;
|
||||
}
|
||||
|
||||
f = symbol__new(sym.st_value, sym.st_size,
|
||||
elf_sym__name(&sym, symstrs),
|
||||
|
@ -573,6 +577,8 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
|
|||
if (!name)
|
||||
return -1;
|
||||
|
||||
self->prelinked = 0;
|
||||
|
||||
if (strncmp(self->name, "/tmp/perf-", 10) == 0)
|
||||
return dso__load_perf_map(self, filter, verbose);
|
||||
|
||||
|
|
|
@ -20,8 +20,9 @@ struct symbol {
|
|||
struct dso {
|
||||
struct list_head node;
|
||||
struct rb_root syms;
|
||||
unsigned int sym_priv_size;
|
||||
struct symbol *(*find_symbol)(struct dso *, u64 ip);
|
||||
unsigned int sym_priv_size;
|
||||
unsigned char prelinked;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue