From ee11b90b12eb1ec25e1044bac861e90bfd19ec9e Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 7 Feb 2010 11:46:15 -0200 Subject: perf top: Fix annotate for userspace First, for programs and prelinked libraries, annotate code was fooled by objdump output IPs (src->eip in the code) being wrongly converted to absolute IPs. In such case there were no conversion needed, but in src->eip = strtoull(src->line, NULL, 16); src->eip = map->unmap_ip(map, src->eip); // = eip + map->start - map->pgoff we were reading absolute address from objdump (e.g. 8048604) and then almost doubling it, because eip & map->start are approximately close for small programs. Needless to say, that later, in record_precise_ip() there was no matching with real runtime IPs. And second, like with `perf annotate` the problem with non-prelinked *.so was that we were doing rip -> objdump address conversion wrong. Also, because unlike `perf annotate`, `perf top` code does annotation based on absolute IPs for performance reasons(*), new helper for mapping objdump addresse to IP is introduced. (*) we get samples info in absolute IPs, and since we do lots of hit-testing on absolute IPs at runtime in record_precise_ip(), it's better to convert objdump addresses to IPs once and do no conversion at runtime. I also had to fix how objdump output is parsed (with hardcoded 8/16 characters format, which was inappropriate for ET_DYN dsos with small addresses like '4ac') Also note, that not all objdump output lines has associtated IPs, e.g. look at source lines here: 000004ac : extern "C" int my_strlen(const char *s) 4ac: 55 push %ebp 4ad: 89 e5 mov %esp,%ebp 4af: 83 ec 10 sub $0x10,%esp { int len = 0; 4b2: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) 4b9: eb 08 jmp 4c3 while (*s) { ++len; 4bb: 83 45 fc 01 addl $0x1,-0x4(%ebp) ++s; 4bf: 83 45 08 01 addl $0x1,0x8(%ebp) So we mark them with eip=0, and ignore such lines in annotate lookup code. Signed-off-by: Kirill Smelkov [ Note: one hunk of this patch was applied by Mike in 57d8188 ] Signed-off-by: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1265550376-12665-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/util/map.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 9cee9c788db..86f77cb1d06 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -61,9 +61,9 @@ static inline u64 identity__map_ip(struct map *map __used, u64 ip) } -/* rip -> addr suitable for passing to `objdump --start-address=` */ +/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ u64 map__rip_2objdump(struct map *map, u64 rip); - +u64 map__objdump_2ip(struct map *map, u64 addr); struct symbol; struct mmap_event; -- cgit v1.2.3