diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 1d8de2e4a40740bf38297ed5163ef1cc679f7c01..f012a98c726c536502584e1fc8bd096496e6d60b 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -206,7 +206,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al); + event->ip.ip, &al, NULL); if (al.map != NULL) { if (!al.map->dso->hit) { diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1cad370146738b85536efa2a2de9c979d87e4963..cd616ff5d2218c95b3d267af194cfd38bb8a3456 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -341,10 +341,10 @@ static void print_sample_addr(union perf_event *event, return; thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - sample->addr, &al); + sample->addr, &al, NULL); if (!al.map) thread__find_addr_map(thread, machine, cpumode, MAP__VARIABLE, - sample->addr, &al); + sample->addr, &al, NULL); al.cpu = sample->cpu; al.sym = NULL; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 28bee6285f5d3127801f5350308e9764c0557d2f..0c7b052cead281406f49e5bd8dfe246249729631 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -138,7 +138,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, addr, - &al); + &al, NULL); if (!al.map || !al.map->dso) { pr_debug("thread__find_addr_map failed\n"); return -1; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 5295625c0c009af43e980a1182e6748959df0734..3a0f5089379c5b9a7a7b78b607551f57b0e875f1 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -33,7 +33,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al); + event->ip.ip, &al, NULL); if (al.map != NULL) al.map->dso->hit = 1; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 95412705d0d2f84016ecb64bf09457200260f357..cc7c0c9c9ea67bbc52e0d6dca83176f30130fc1d 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -592,9 +592,10 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, void thread__find_addr_map(struct thread *self, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, - struct addr_location *al) + struct addr_location *al, symbol_filter_t filter) { struct map_groups *mg = &self->mg; + bool load_map = false; al->thread = self; al->addr = addr; @@ -609,11 +610,13 @@ void thread__find_addr_map(struct thread *self, 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 { /* * 'u' means guest os user space. @@ -654,8 +657,15 @@ void thread__find_addr_map(struct thread *self, mg = &machine->kmaps; goto try_again; } - } else + } 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, filter); al->addr = al->map->map_ip(al->map, al->addr); + } } void thread__find_addr_location(struct thread *thread, struct machine *machine, @@ -663,7 +673,7 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine, struct addr_location *al, symbol_filter_t filter) { - thread__find_addr_map(thread, machine, cpumode, type, addr, al); + thread__find_addr_map(thread, machine, cpumode, type, addr, al, filter); if (al->map != NULL) al->sym = map__find_symbol(al->map, al->addr, filter); else @@ -699,7 +709,7 @@ int perf_event__preprocess_sample(const union perf_event *event, machine__create_kernel_maps(machine); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, al); + event->ip.ip, al, filter); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : ""); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 0fe1f9c05865623e054430b50c7b79b7ec986429..f98d1d983547ef399fbe182e0d81fef4b76a45f8 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -41,7 +41,7 @@ static inline struct map *thread__find_map(struct thread *self, void thread__find_addr_map(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, - struct addr_location *al); + struct addr_location *al, symbol_filter_t filter); void thread__find_addr_location(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 958723ba3d2efaa3978a4870d6623f6e7feef601..5bbd4947c27d0dcc806fc6388a9b7e73702ab23a 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c @@ -272,7 +272,7 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui) struct addr_location al; thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER, - MAP__FUNCTION, ip, &al); + MAP__FUNCTION, ip, &al, NULL); return al.map; } @@ -349,7 +349,7 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, ssize_t size; thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER, - MAP__FUNCTION, addr, &al); + MAP__FUNCTION, addr, &al, NULL); if (!al.map) { pr_debug("unwind: no map for %lx\n", (unsigned long)addr); return -1;