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
| ||
|
Message-Id: <1443763159-29098-24-git-send-email-namhyung@kernel.org> Date: Fri, 2 Oct 2015 14:19:04 +0900 From: Namhyung Kim <namhyung@...nel.org> To: Arnaldo Carvalho de Melo <acme@...nel.org> Cc: Ingo Molnar <mingo@...nel.org>, Peter Zijlstra <a.p.zijlstra@...llo.nl>, Jiri Olsa <jolsa@...hat.com>, LKML <linux-kernel@...r.kernel.org>, Frederic Weisbecker <fweisbec@...il.com>, Stephane Eranian <eranian@...gle.com>, David Ahern <dsahern@...il.com>, Andi Kleen <andi@...stfloor.org> Subject: [RFC/PATCH 23/38] perf tools: Use map_groups__find_addr_by_time() Use timestamp to find a corresponding map so that it can find a match symbol eventually. Cc: Stephane Eranian <eranian@...gle.com> Signed-off-by: Namhyung Kim <namhyung@...nel.org> --- tools/perf/util/event.c | 81 ++++++++++++++++++++++++++++++++++++++++++------ tools/perf/util/thread.c | 8 +++-- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index c960cbcd30d4..d7997105ee7a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -895,12 +895,11 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, return machine__process_event(machine, event, sample); } -static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, - enum map_type type, u64 addr, - struct addr_location *al) +static bool map_groups__set_addr_location(struct map_groups *mg, + struct addr_location *al, + u8 cpumode, u64 addr) { struct machine *machine = mg->machine; - bool load_map = false; al->machine = machine; al->addr = addr; @@ -909,21 +908,17 @@ static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, if (machine == NULL) { al->map = NULL; - return; + return true; } BUG_ON(mg == NULL); if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { al->level = 'k'; - mg = &machine->kmaps; - load_map = true; } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { al->level = '.'; } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { al->level = 'g'; - mg = &machine->kmaps; - load_map = true; } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { al->level = 'u'; } else { @@ -939,8 +934,27 @@ static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, !perf_host) al->filtered |= (1 << HIST_FILTER__HOST); + return true; + } + return false; +} + +static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al) +{ + struct machine *machine = mg->machine; + bool load_map = false; + + if (map_groups__set_addr_location(mg, al, cpumode, addr)) return; + + if ((cpumode == PERF_RECORD_MISC_KERNEL && perf_host) || + (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)) { + mg = &machine->kmaps; + load_map = true; } + try_again: al->map = map_groups__find(mg, type, al->addr); if (al->map == NULL) { @@ -971,6 +985,53 @@ try_again: } } +static void map_groups__find_addr_map_by_time(struct map_groups *mg, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al, + u64 timestamp) +{ + struct machine *machine = mg->machine; + bool load_map = false; + + if (map_groups__set_addr_location(mg, al, cpumode, addr)) + return; + + if ((cpumode == PERF_RECORD_MISC_KERNEL && perf_host) || + (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)) { + mg = &machine->kmaps; + load_map = true; + } + +try_again: + al->map = map_groups__find_by_time(mg, type, al->addr, timestamp); + if (al->map == NULL) { + /* + * If this is outside of all known maps, and is a negative + * address, try to look it up in the kernel dso, as it might be + * a vsyscall or vdso (which executes in user-mode). + * + * XXX This is nasty, we should have a symbol list in the + * "[vdso]" dso, but for now lets use the old trick of looking + * in the whole kernel symbol list. + */ + if (cpumode == PERF_RECORD_MISC_USER && machine && + mg != &machine->kmaps && + machine__kernel_ip(machine, al->addr)) { + mg = &machine->kmaps; + load_map = true; + goto try_again; + } + } else { + /* + * Kernel maps might be changed when loading symbols so loading + * must be done prior to using kernel maps. + */ + if (load_map) + map__load(al->map, machine->symbol_filter); + al->addr = al->map->map_ip(al->map, al->addr); + } +} + void thread__find_addr_map(struct thread *thread, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al) @@ -991,7 +1052,7 @@ void thread__find_addr_map_by_time(struct thread *thread, u8 cpumode, mg = thread->mg; al->thread = thread; - map_groups__find_addr_map(mg, cpumode, type, addr, al); + map_groups__find_addr_map_by_time(mg, cpumode, type, addr, al, timestamp); } void thread__find_addr_location(struct thread *thread, diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index efd510d5d966..21de681415f4 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -337,8 +337,12 @@ size_t thread__fprintf(struct thread *thread, FILE *fp) void thread__insert_map(struct thread *thread, struct map *map) { - map_groups__fixup_overlappings(thread->mg, map, stderr); - map_groups__insert(thread->mg, map); + if (perf_has_index) { + map_groups__insert_by_time(thread->mg, map); + } else { + map_groups__fixup_overlappings(thread->mg, map, stderr); + map_groups__insert(thread->mg, map); + } } static int thread__clone_map_groups(struct thread *thread, -- 2.6.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists