lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 12 Jan 2016 02:58:27 +0000 From: He Kuang <hekuang@...wei.com> To: <peterz@...radead.org>, <mingo@...hat.com>, <acme@...nel.org>, <jolsa@...hat.com>, <rabin.vincent@...s.com>, <namhyung@...nel.org>, <wangnan0@...wei.com>, <mark.rutland@....com>, <hekuang@...wei.com> CC: <linux-kernel@...r.kernel.org> Subject: [PATCH v2] perf symbols: Fix wrong symbol offset according to p_addr Perf missed the 'VirtAddr' value in elf program_headers when adjusting symbol address for dynamic libraries. This patch considers the p_addr value and calculates the right symbol offset. Before this patch, some symbols are not parsed correctly 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 <hekuang@...wei.com> --- Patch v1 to v2: - Modify commit message by following Ingo's suggestion. - Change ambiguous virable name 'vaddr' to 'load_virtaddr'. --- tools/perf/util/dso.c | 6 ++++++ tools/perf/util/dso.h | 3 ++- tools/perf/util/event.c | 6 +++++- tools/perf/util/map.h | 7 +++++-- tools/perf/util/symbol-elf.c | 20 ++++++++++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e8e9a9d..afc51ce 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->load_virtaddr = 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_load_virtaddr(struct dso *dso) +{ + return dso->load_virtaddr; +} diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 45ec4d0..2a03b87 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -166,7 +166,8 @@ struct dso { const char *long_name; u16 long_name_len; u16 short_name_len; - void *dwfl; /* DWARF debug info */ + u64 load_virtaddr; /* Load virtual address */ + void *dwfl; /* DWARF debug info */ struct auxtrace_cache *auxtrace_cache; /* dso data file */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index cd61bb1..7f1dbdf 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->load_virtaddr = 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..db284a4 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_load_virtaddr(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_load_virtaddr(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_load_virtaddr(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..9a02b3e 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->load_virtaddr = 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
Powered by blists - more mailing lists