From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752530AbcAFI0s (ORCPT ); Wed, 6 Jan 2016 03:26:48 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:7288 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752170AbcAFI0q (ORCPT ); Wed, 6 Jan 2016 03:26:46 -0500 From: He Kuang To: , , , , , , , , CC: Subject: [PATCH] perf symbols: Fix wrong symbol offset according to p_addr Date: Wed, 6 Jan 2016 08:26:14 +0000 Message-ID: <1452068774-19491-1-git-send-email-hekuang@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <20160105111351.GA10705@arm.com> References: <20160105111351.GA10705@arm.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.250] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090202.568CCFB8.0095,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 2b145719be9d479a1550b8df1922e6e4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Perf missed the 'VirtAddr' value in elf program_headers when adjusting symbol address for dynamic libraries. This patch considers the p_addr value and gets the right symbol offset. Before this patch, some symbols can not be right parsed on android phone: init 369 [002] 339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8) ... 230ac [unknown] (/system/lib64/libsurfaceflinger.so) 11a0 main (/system/bin/surfaceflinger) 1c3fc __libc_init (/system/lib64/libc.so) fd0 _start (/system/bin/surfaceflinger) 29ec __dl__start (/system/bin/linker64) After this patch: init 369 [002] 339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8) ... 3a0ac _ZN7android14SurfaceFlinger3runEv (/system/lib64/libsurfaceflinger.so) 11a0 main (/system/bin/surfaceflinger) 1c3fc __libc_init (/system/lib64/libc.so) fd0 _start (/system/bin/surfaceflinger) 29ec __dl__start (/system/bin/linker64) Signed-off-by: He Kuang --- tools/perf/util/dso.c | 6 ++++++ tools/perf/util/dso.h | 1 + tools/perf/util/event.c | 6 +++++- tools/perf/util/map.h | 7 +++++-- tools/perf/util/symbol-elf.c | 20 ++++++++++++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e8e9a9d..93bf13a 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1063,6 +1063,7 @@ struct dso *dso__new(const char *name) dso->needs_swap = DSO_SWAP__UNSET; RB_CLEAR_NODE(&dso->rb_node); dso->root = NULL; + dso->vaddr = 0; INIT_LIST_HEAD(&dso->node); INIT_LIST_HEAD(&dso->data.open_entry); pthread_mutex_init(&dso->lock, NULL); @@ -1367,3 +1368,8 @@ int dso__strerror_load(struct dso *dso, char *buf, size_t buflen) scnprintf(buf, buflen, "%s", dso_load__error_str[idx]); return 0; } + +u64 dso__get_vaddr(struct dso *dso) +{ + return dso->vaddr; +} diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 45ec4d0..b6c894f 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -166,6 +166,7 @@ struct dso { const char *long_name; u16 long_name_len; u16 short_name_len; + u64 vaddr; void *dwfl; /* DWARF debug info */ struct auxtrace_cache *auxtrace_cache; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index cd61bb1..ef964c0 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1273,8 +1273,12 @@ try_again: * Kernel maps might be changed when loading symbols so loading * must be done prior to using kernel maps. */ + map__load(al->map, machine->symbol_filter); + + /* exclude kernel kallsyms */ if (load_map) - map__load(al->map, machine->symbol_filter); + al->map->dso->vaddr = 0; + al->addr = al->map->map_ip(al->map, al->addr); } } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 7309d64..68ab703 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -86,14 +86,17 @@ void map_groups__put(struct map_groups *mg); struct kmap *map__kmap(struct map *map); struct map_groups *map__kmaps(struct map *map); +u64 dso__get_vaddr(struct dso *dso); static inline u64 map__map_ip(struct map *map, u64 ip) { - return ip - map->start + map->pgoff; + return ip - map->start + map->pgoff + + dso__get_vaddr(map->dso); } static inline u64 map__unmap_ip(struct map *map, u64 ip) { - return ip + map->start - map->pgoff; + return ip + map->start - map->pgoff - + dso__get_vaddr(map->dso); } static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 562b8eb..de0129f 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -15,6 +15,8 @@ #define EM_AARCH64 183 /* ARM 64 bit */ #endif +static int elf_read_maps_ex(Elf * elf, bool exe, mapfn_t mapfn, void *data, + struct map *map); #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT extern char *cplus_demangle(const char *, int); @@ -831,6 +833,10 @@ int dso__load_sym(struct dso *dso, struct map *map, sec = syms_ss->symtab; shdr = syms_ss->symshdr; + err = elf_read_maps_ex(elf, ehdr.e_type == ET_EXEC || + ehdr.e_type == ET_REL, + NULL, NULL, map); + if (runtime_ss->opdsec) opddata = elf_rawdata(runtime_ss->opdsec, NULL); @@ -1116,6 +1122,13 @@ out_elf_end: static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data) { + + return elf_read_maps_ex(elf, exe, mapfn, data, NULL); +} + +static int elf_read_maps_ex(Elf *elf, bool exe, mapfn_t mapfn, void *data, + struct map *map) +{ GElf_Phdr phdr; size_t i, phdrnum; int err; @@ -1135,10 +1148,17 @@ static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data) } else { if (!(phdr.p_flags & PF_R)) continue; + if (map && (phdr.p_flags & PF_X)) + map->dso->vaddr = phdr.p_vaddr; } + sz = min(phdr.p_memsz, phdr.p_filesz); if (!sz) continue; + + if (!mapfn) + continue; + err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data); if (err) return err; -- 1.8.5.2