From 83720209961f5cfed17214bc78978a02e3414a41 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 20 Mar 2023 14:22:32 -0700 Subject: perf map: Move map list node into symbol Using a perf map as a list node is only done in symbol. Move the list_node struct into symbol as a single pointer to the map. This makes reference count behavior more obvious and easy to check. Committer notes: Some changes to reduce the number of lines touched by keeping, for instance, the 'new_map' variable and setting it to new_node->map, so that we keep more of the project history in place and keep as much as possible the value of the 'git blame' tool. Also use map__zput() when putting a struct members, so that when we free the container struct we can get use-after-free errors as NULL pointer derefs sometimes. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230320212248.1175731-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 3dcfe06db6b3..2879cae05ee0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,10 +16,7 @@ struct maps; struct machine; struct map { - union { - struct rb_node rb_node; - struct list_head node; - }; + struct rb_node rb_node; u64 start; u64 end; bool erange_warned:1; -- cgit v1.2.3 From ff583dc43dc8b62c9ec639604adae641ba38a91d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 20 Mar 2023 14:22:33 -0700 Subject: perf maps: Remove rb_node from struct map struct map is reference counted, having it also be a node in an red-black tree complicates the reference counting. Switch to having a map_rb_node which is a red-block tree node but points at the reference counted struct map. This reference is responsible for a single reference count. Committer notes: Fixed up tools/perf/util/unwind-libunwind-local.c to use map_rb_node as well. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230320212248.1175731-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/event.c | 13 +-- tools/perf/builtin-report.c | 6 +- tools/perf/tests/maps.c | 8 +- tools/perf/tests/vmlinux-kallsyms.c | 17 +-- tools/perf/util/bpf_lock_contention.c | 2 +- tools/perf/util/machine.c | 68 +++++++----- tools/perf/util/map.c | 16 --- tools/perf/util/map.h | 1 - tools/perf/util/maps.c | 180 ++++++++++++++++++++----------- tools/perf/util/maps.h | 17 ++- tools/perf/util/probe-event.c | 18 ++-- tools/perf/util/symbol-elf.c | 9 +- tools/perf/util/symbol.c | 77 ++++++++----- tools/perf/util/synthetic-events.c | 26 ++--- tools/perf/util/thread.c | 10 +- tools/perf/util/unwind-libunwind-local.c | 6 +- tools/perf/util/vdso.c | 7 +- 17 files changed, 295 insertions(+), 186 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index e4288d09f3a0..17bf60babfbd 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -19,7 +19,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, struct machine *machine) { int rc = 0; - struct map *pos; + struct map_rb_node *pos; struct maps *kmaps = machine__kernel_maps(machine); union perf_event *event = zalloc(sizeof(event->mmap) + machine->id_hdr_size); @@ -33,11 +33,12 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, maps__for_each_entry(kmaps, pos) { struct kmap *kmap; size_t size; + struct map *map = pos->map; - if (!__map__is_extra_kernel_map(pos)) + if (!__map__is_extra_kernel_map(map)) continue; - kmap = map__kmap(pos); + kmap = map__kmap(map); size = sizeof(event->mmap) - sizeof(event->mmap.filename) + PERF_ALIGN(strlen(kmap->name) + 1, sizeof(u64)) + @@ -58,9 +59,9 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, event->mmap.header.size = size; - event->mmap.start = pos->start; - event->mmap.len = pos->end - pos->start; - event->mmap.pgoff = pos->pgoff; + event->mmap.start = map->start; + event->mmap.len = map->end - map->start; + event->mmap.pgoff = map->pgoff; event->mmap.pid = machine->pid; strlcpy(event->mmap.filename, kmap->name, PATH_MAX); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 4011abc03d0d..c7e3863e8f44 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -844,9 +844,11 @@ static struct task *tasks_list(struct task *task, struct machine *machine) static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) { size_t printed = 0; - struct map *map; + struct map_rb_node *rb_node; + + maps__for_each_entry(maps, rb_node) { + struct map *map = rb_node->map; - maps__for_each_entry(maps, map) { printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n", indent, "", map->start, map->end, map->prot & PROT_READ ? 'r' : '-', diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index a69988a89d26..8246d37e4b7a 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -15,10 +15,12 @@ struct map_def { static int check_maps(struct map_def *merged, unsigned int size, struct maps *maps) { - struct map *map; + struct map_rb_node *rb_node; unsigned int i = 0; - maps__for_each_entry(maps, map) { + maps__for_each_entry(maps, rb_node) { + struct map *map = rb_node->map; + if (i > 0) TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i == size)); @@ -74,7 +76,7 @@ static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest map->start = bpf_progs[i].start; map->end = bpf_progs[i].end; - maps__insert(maps, map); + TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) == 0); map__put(map); } diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 8ab035b55875..c8abb3ca8347 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -118,7 +118,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused int err = TEST_FAIL; struct rb_node *nd; struct symbol *sym; - struct map *kallsyms_map, *vmlinux_map, *map; + struct map *kallsyms_map, *vmlinux_map; + struct map_rb_node *rb_node; struct machine kallsyms, vmlinux; struct maps *maps; u64 mem_start, mem_end; @@ -290,15 +291,15 @@ next_pair: header_printed = false; - maps__for_each_entry(maps, map) { - struct map * + maps__for_each_entry(maps, rb_node) { + struct map *map = rb_node->map; /* * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while * the kernel will have the path for the vmlinux file being used, * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - pair = maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ? + struct map *pair = maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ? map->dso->short_name : map->dso->name)); if (pair) { @@ -314,8 +315,8 @@ next_pair: header_printed = false; - maps__for_each_entry(maps, map) { - struct map *pair; + maps__for_each_entry(maps, rb_node) { + struct map *pair, *map = rb_node->map; mem_start = vmlinux_map->unmap_ip(vmlinux_map, map->start); mem_end = vmlinux_map->unmap_ip(vmlinux_map, map->end); @@ -344,7 +345,9 @@ next_pair: maps = machine__kernel_maps(&kallsyms); - maps__for_each_entry(maps, map) { + maps__for_each_entry(maps, rb_node) { + struct map *map = rb_node->map; + if (!map->priv) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index b3e8aa9cd011..8a5d0eb44189 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -284,7 +284,7 @@ int lock_contention_read(struct lock_contention *con) } /* make sure it loads the kernel map */ - map__load(maps__first(machine->kmaps)); + map__load(maps__first(machine->kmaps)->map); prev_key = NULL; while (!bpf_map_get_next_key(fd, prev_key, &key)) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 3182815c73c6..2058623726d2 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -883,6 +883,7 @@ static int machine__process_ksymbol_register(struct machine *machine, if (!map) { struct dso *dso = dso__new(event->ksymbol.name); + int err; if (dso) { dso->kernel = DSO_SPACE__KERNEL; @@ -902,8 +903,11 @@ static int machine__process_ksymbol_register(struct machine *machine, map->start = event->ksymbol.addr; map->end = map->start + event->ksymbol.len; - maps__insert(machine__kernel_maps(machine), map); + err = maps__insert(machine__kernel_maps(machine), map); map__put(map); + if (err) + return err; + dso__set_loaded(dso); if (is_bpf_image(event->ksymbol.name)) { @@ -1003,6 +1007,7 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start struct map *map = NULL; struct kmod_path m; struct dso *dso; + int err; if (kmod_path__parse_name(&m, filename)) return NULL; @@ -1015,10 +1020,14 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start if (map == NULL) goto out; - maps__insert(machine__kernel_maps(machine), map); + err = maps__insert(machine__kernel_maps(machine), map); /* Put the map here because maps__insert already got it */ map__put(map); + + /* If maps__insert failed, return NULL. */ + if (err) + map = NULL; out: /* put the dso here, corresponding to machine__findnew_module_dso */ dso__put(dso); @@ -1185,10 +1194,11 @@ int machine__create_extra_kernel_map(struct machine *machine, { struct kmap *kmap; struct map *map; + int err; map = map__new2(xm->start, kernel); if (!map) - return -1; + return -ENOMEM; map->end = xm->end; map->pgoff = xm->pgoff; @@ -1197,14 +1207,16 @@ int machine__create_extra_kernel_map(struct machine *machine, strlcpy(kmap->name, xm->name, KMAP_NAME_LEN); - maps__insert(machine__kernel_maps(machine), map); + err = maps__insert(machine__kernel_maps(machine), map); - pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", - kmap->name, map->start, map->end); + if (!err) { + pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", + kmap->name, map->start, map->end); + } map__put(map); - return 0; + return err; } static u64 find_entry_trampoline(struct dso *dso) @@ -1245,16 +1257,16 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine, struct maps *kmaps = machine__kernel_maps(machine); int nr_cpus_avail, cpu; bool found = false; - struct map *map; + struct map_rb_node *rb_node; u64 pgoff; /* * In the vmlinux case, pgoff is a virtual address which must now be * mapped to a vmlinux offset. */ - maps__for_each_entry(kmaps, map) { + maps__for_each_entry(kmaps, rb_node) { + struct map *dest_map, *map = rb_node->map; struct kmap *kmap = __map__kmap(map); - struct map *dest_map; if (!kmap || !is_entry_trampoline(kmap->name)) continue; @@ -1309,11 +1321,10 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) machine->vmlinux_map = map__new2(0, kernel); if (machine->vmlinux_map == NULL) - return -1; + return -ENOMEM; machine->vmlinux_map->map_ip = machine->vmlinux_map->unmap_ip = identity__map_ip; - maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); - return 0; + return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } void machine__destroy_kernel_maps(struct machine *machine) @@ -1635,25 +1646,26 @@ static void machine__set_kernel_mmap(struct machine *machine, machine->vmlinux_map->end = ~0ULL; } -static void machine__update_kernel_mmap(struct machine *machine, +static int machine__update_kernel_mmap(struct machine *machine, u64 start, u64 end) { struct map *map = machine__kernel_map(machine); + int err; map__get(map); maps__remove(machine__kernel_maps(machine), map); machine__set_kernel_mmap(machine, start, end); - maps__insert(machine__kernel_maps(machine), map); + err = maps__insert(machine__kernel_maps(machine), map); map__put(map); + return err; } int machine__create_kernel_maps(struct machine *machine) { struct dso *kernel = machine__get_kernel(machine); const char *name = NULL; - struct map *map; u64 start = 0, end = ~0ULL; int ret; @@ -1685,7 +1697,9 @@ int machine__create_kernel_maps(struct machine *machine) * we have a real start address now, so re-order the kmaps * assume it's the last in the kmaps */ - machine__update_kernel_mmap(machine, start, end); + ret = machine__update_kernel_mmap(machine, start, end); + if (ret < 0) + goto out_put; } if (machine__create_extra_kernel_maps(machine, kernel)) @@ -1693,9 +1707,12 @@ int machine__create_kernel_maps(struct machine *machine) if (end == ~0ULL) { /* update end address of the kernel map using adjacent module address */ - map = map__next(machine__kernel_map(machine)); - if (map) - machine__set_kernel_mmap(machine, start, map->start); + struct map_rb_node *rb_node = maps__find_node(machine__kernel_maps(machine), + machine__kernel_map(machine)); + struct map_rb_node *next = map_rb_node__next(rb_node); + + if (next) + machine__set_kernel_mmap(machine, start, next->map->start); } out_put: @@ -1828,7 +1845,10 @@ static int machine__process_kernel_mmap_event(struct machine *machine, if (strstr(kernel->long_name, "vmlinux")) dso__set_short_name(kernel, "[kernel.vmlinux]", false); - machine__update_kernel_mmap(machine, xm->start, xm->end); + if (machine__update_kernel_mmap(machine, xm->start, xm->end) < 0) { + dso__put(kernel); + goto out_problem; + } if (build_id__is_defined(bid)) dso__set_build_id(kernel, bid); @@ -3330,11 +3350,11 @@ int machine__for_each_dso(struct machine *machine, machine__dso_t fn, void *priv int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, void *priv) { struct maps *maps = machine__kernel_maps(machine); - struct map *map; + struct map_rb_node *pos; int err = 0; - for (map = maps__first(maps); map != NULL; map = map__next(map)) { - err = fn(map, priv); + maps__for_each_entry(maps, pos) { + err = fn(pos->map, priv); if (err != 0) { break; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index f3a3d9b3a40d..7620cfa114d4 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -111,7 +111,6 @@ void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso) map->dso = dso__get(dso); map->map_ip = map__map_ip; map->unmap_ip = map__unmap_ip; - RB_CLEAR_NODE(&map->rb_node); map->erange_warned = false; refcount_set(&map->refcnt, 1); } @@ -397,7 +396,6 @@ struct map *map__clone(struct map *from) map = memdup(from, size); if (map != NULL) { refcount_set(&map->refcnt, 1); - RB_CLEAR_NODE(&map->rb_node); dso__get(map->dso); } @@ -537,20 +535,6 @@ bool map__contains_symbol(const struct map *map, const struct symbol *sym) return ip >= map->start && ip < map->end; } -static struct map *__map__next(struct map *map) -{ - struct rb_node *next = rb_next(&map->rb_node); - - if (next) - return rb_entry(next, struct map, rb_node); - return NULL; -} - -struct map *map__next(struct map *map) -{ - return map ? __map__next(map) : NULL; -} - struct kmap *__map__kmap(struct map *map) { if (!map->dso || !map->dso->kernel) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 2879cae05ee0..d1a6f85fd31d 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,7 +16,6 @@ struct maps; struct machine; struct map { - struct rb_node rb_node; u64 start; u64 end; bool erange_warned:1; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 37bd5b40000d..83ec126bcbe5 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -10,8 +10,6 @@ #include "ui/ui.h" #include "unwind.h" -static void __maps__insert(struct maps *maps, struct map *map); - static void maps__init(struct maps *maps, struct machine *machine) { maps->entries = RB_ROOT; @@ -32,10 +30,44 @@ static void __maps__free_maps_by_name(struct maps *maps) maps->nr_maps_allocated = 0; } -void maps__insert(struct maps *maps, struct map *map) +static int __maps__insert(struct maps *maps, struct map *map) { + struct rb_node **p = &maps->entries.rb_node; + struct rb_node *parent = NULL; + const u64 ip = map->start; + struct map_rb_node *m, *new_rb_node; + + new_rb_node = malloc(sizeof(*new_rb_node)); + if (!new_rb_node) + return -ENOMEM; + + RB_CLEAR_NODE(&new_rb_node->rb_node); + new_rb_node->map = map; + + while (*p != NULL) { + parent = *p; + m = rb_entry(parent, struct map_rb_node, rb_node); + if (ip < m->map->start) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + rb_link_node(&new_rb_node->rb_node, parent, p); + rb_insert_color(&new_rb_node->rb_node, &maps->entries); + map__get(map); + return 0; +} + +int maps__insert(struct maps *maps, struct map *map) +{ + int err; + down_write(&maps->lock); - __maps__insert(maps, map); + err = __maps__insert(maps, map); + if (err) + goto out; + ++maps->nr_maps; if (map->dso && map->dso->kernel) { @@ -59,32 +91,39 @@ void maps__insert(struct maps *maps, struct map *map) if (maps_by_name == NULL) { __maps__free_maps_by_name(maps); - up_write(&maps->lock); - return; + err = -ENOMEM; + goto out; } maps->maps_by_name = maps_by_name; maps->nr_maps_allocated = nr_allocate; - } +} maps->maps_by_name[maps->nr_maps - 1] = map; __maps__sort_by_name(maps); } + out: up_write(&maps->lock); + return err; } -static void __maps__remove(struct maps *maps, struct map *map) +static void __maps__remove(struct maps *maps, struct map_rb_node *rb_node) { - rb_erase_init(&map->rb_node, &maps->entries); - map__put(map); + rb_erase_init(&rb_node->rb_node, &maps->entries); + map__put(rb_node->map); + free(rb_node); } void maps__remove(struct maps *maps, struct map *map) { + struct map_rb_node *rb_node; + down_write(&maps->lock); if (maps->last_search_by_name == map) maps->last_search_by_name = NULL; - __maps__remove(maps, map); + rb_node = maps__find_node(maps, map); + assert(rb_node->map == map); + __maps__remove(maps, rb_node); --maps->nr_maps; if (maps->maps_by_name) __maps__free_maps_by_name(maps); @@ -93,11 +132,12 @@ void maps__remove(struct maps *maps, struct map *map) static void __maps__purge(struct maps *maps) { - struct map *pos, *next; + struct map_rb_node *pos, *next; maps__for_each_entry_safe(maps, pos, next) { rb_erase_init(&pos->rb_node, &maps->entries); - map__put(pos); + map__put(pos->map); + free(pos); } } @@ -153,21 +193,21 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp) { struct symbol *sym; - struct map *pos; + struct map_rb_node *pos; down_read(&maps->lock); maps__for_each_entry(maps, pos) { - sym = map__find_symbol_by_name(pos, name); + sym = map__find_symbol_by_name(pos->map, name); if (sym == NULL) continue; - if (!map__contains_symbol(pos, sym)) { + if (!map__contains_symbol(pos->map, sym)) { sym = NULL; continue; } if (mapp != NULL) - *mapp = pos; + *mapp = pos->map; goto out; } @@ -196,15 +236,15 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) size_t maps__fprintf(struct maps *maps, FILE *fp) { size_t printed = 0; - struct map *pos; + struct map_rb_node *pos; down_read(&maps->lock); maps__for_each_entry(maps, pos) { printed += fprintf(fp, "Map:"); - printed += map__fprintf(pos, fp); + printed += map__fprintf(pos->map, fp); if (verbose > 2) { - printed += dso__fprintf(pos->dso, fp); + printed += dso__fprintf(pos->map->dso, fp); printed += fprintf(fp, "--\n"); } } @@ -231,11 +271,11 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) next = root->rb_node; first = NULL; while (next) { - struct map *pos = rb_entry(next, struct map, rb_node); + struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node); - if (pos->end > map->start) { + if (pos->map->end > map->start) { first = next; - if (pos->start <= map->start) + if (pos->map->start <= map->start) break; next = next->rb_left; } else @@ -244,14 +284,14 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) next = first; while (next) { - struct map *pos = rb_entry(next, struct map, rb_node); + struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node); next = rb_next(&pos->rb_node); /* * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (pos->start >= map->end) + if (pos->map->start >= map->end) break; if (verbose >= 2) { @@ -262,7 +302,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) } else { fputs("overlapping maps:\n", fp); map__fprintf(map, fp); - map__fprintf(pos, fp); + map__fprintf(pos->map, fp); } } @@ -271,8 +311,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map->start > pos->start) { - struct map *before = map__clone(pos); + if (map->start > pos->map->start) { + struct map *before = map__clone(pos->map); if (before == NULL) { err = -ENOMEM; @@ -280,14 +320,17 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) } before->end = map->start; - __maps__insert(maps, before); + err = __maps__insert(maps, before); + if (err) + goto put_map; + if (verbose >= 2 && !use_browser) map__fprintf(before, fp); map__put(before); } - if (map->end < pos->end) { - struct map *after = map__clone(pos); + if (map->end < pos->map->end) { + struct map *after = map__clone(pos->map); if (after == NULL) { err = -ENOMEM; @@ -295,15 +338,19 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) } after->start = map->end; - after->pgoff += map->end - pos->start; - assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end)); - __maps__insert(maps, after); + after->pgoff += map->end - pos->map->start; + assert(pos->map->map_ip(pos->map, map->end) == + after->map_ip(after, map->end)); + err = __maps__insert(maps, after); + if (err) + goto put_map; + if (verbose >= 2 && !use_browser) map__fprintf(after, fp); map__put(after); } put_map: - map__put(pos); + map__put(pos->map); if (err) goto out; @@ -322,12 +369,12 @@ int maps__clone(struct thread *thread, struct maps *parent) { struct maps *maps = thread->maps; int err; - struct map *map; + struct map_rb_node *rb_node; down_read(&parent->lock); - maps__for_each_entry(parent, map) { - struct map *new = map__clone(map); + maps__for_each_entry(parent, rb_node) { + struct map *new = map__clone(rb_node->map); if (new == NULL) { err = -ENOMEM; @@ -338,7 +385,10 @@ int maps__clone(struct thread *thread, struct maps *parent) if (err) goto out_unlock; - maps__insert(maps, new); + err = maps__insert(maps, new); + if (err) + goto out_unlock; + map__put(new); } @@ -348,40 +398,31 @@ out_unlock: return err; } -static void __maps__insert(struct maps *maps, struct map *map) +struct map_rb_node *maps__find_node(struct maps *maps, struct map *map) { - struct rb_node **p = &maps->entries.rb_node; - struct rb_node *parent = NULL; - const u64 ip = map->start; - struct map *m; + struct map_rb_node *rb_node; - while (*p != NULL) { - parent = *p; - m = rb_entry(parent, struct map, rb_node); - if (ip < m->start) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; + maps__for_each_entry(maps, rb_node) { + if (rb_node->map == map) + return rb_node; } - - rb_link_node(&map->rb_node, parent, p); - rb_insert_color(&map->rb_node, &maps->entries); - map__get(map); + return NULL; } struct map *maps__find(struct maps *maps, u64 ip) { struct rb_node *p; - struct map *m; + struct map_rb_node *m; + down_read(&maps->lock); p = maps->entries.rb_node; while (p != NULL) { - m = rb_entry(p, struct map, rb_node); - if (ip < m->start) + m = rb_entry(p, struct map_rb_node, rb_node); + if (ip < m->map->start) p = p->rb_left; - else if (ip >= m->end) + else if (ip >= m->map->end) p = p->rb_right; else goto out; @@ -390,14 +431,29 @@ struct map *maps__find(struct maps *maps, u64 ip) m = NULL; out: up_read(&maps->lock); - return m; + return m ? m->map : NULL; } -struct map *maps__first(struct maps *maps) +struct map_rb_node *maps__first(struct maps *maps) { struct rb_node *first = rb_first(&maps->entries); if (first) - return rb_entry(first, struct map, rb_node); + return rb_entry(first, struct map_rb_node, rb_node); return NULL; } + +struct map_rb_node *map_rb_node__next(struct map_rb_node *node) +{ + struct rb_node *next; + + if (!node) + return NULL; + + next = rb_next(&node->rb_node); + + if (!next) + return NULL; + + return rb_entry(next, struct map_rb_node, rb_node); +} diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 7e729ff42749..512746ec0f9a 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -15,15 +15,22 @@ struct map; struct maps; struct thread; +struct map_rb_node { + struct rb_node rb_node; + struct map *map; +}; + +struct map_rb_node *maps__first(struct maps *maps); +struct map_rb_node *map_rb_node__next(struct map_rb_node *node); +struct map_rb_node *maps__find_node(struct maps *maps, struct map *map); struct map *maps__find(struct maps *maps, u64 addr); -struct map *maps__first(struct maps *maps); -struct map *map__next(struct map *map); #define maps__for_each_entry(maps, map) \ - for (map = maps__first(maps); map; map = map__next(map)) + for (map = maps__first(maps); map; map = map_rb_node__next(map)) #define maps__for_each_entry_safe(maps, map, next) \ - for (map = maps__first(maps), next = map__next(map); map; map = next, next = map__next(map)) + for (map = maps__first(maps), next = map_rb_node__next(map); map; \ + map = next, next = map_rb_node__next(map)) struct maps { struct rb_root entries; @@ -63,7 +70,7 @@ void maps__put(struct maps *maps); int maps__clone(struct thread *thread, struct maps *parent); size_t maps__fprintf(struct maps *maps, FILE *fp); -void maps__insert(struct maps *maps, struct map *map); +int maps__insert(struct maps *maps, struct map *map); void maps__remove(struct maps *maps, struct map *map); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 881d94f65a6b..cdf5d655d84c 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -151,23 +151,27 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr, static struct map *kernel_get_module_map(const char *module) { struct maps *maps = machine__kernel_maps(host_machine); - struct map *pos; + struct map_rb_node *pos; /* A file path -- this is an offline module */ if (module && strchr(module, '/')) return dso__new_map(module); if (!module) { - pos = machine__kernel_map(host_machine); - return map__get(pos); + struct map *map = machine__kernel_map(host_machine); + + return map__get(map); } maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ - if (strncmp(pos->dso->short_name + 1, module, - pos->dso->short_name_len - 2) == 0 && - module[pos->dso->short_name_len - 2] == '\0') { - return map__get(pos); + const char *short_name = pos->map->dso->short_name; + u16 short_name_len = pos->map->dso->short_name_len; + + if (strncmp(short_name + 1, module, + short_name_len - 2) == 0 && + module[short_name_len - 2] == '\0') { + return map__get(pos->map); } } return NULL; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index ae810d4cf3cd..33e1f587baa9 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1361,10 +1361,14 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, map->unmap_ip = map__unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { + int err; + map__get(map); maps__remove(kmaps, map); - maps__insert(kmaps, map); + err = maps__insert(kmaps, map); map__put(map); + if (err) + return err; } } @@ -1417,7 +1421,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; } curr_dso->symtab_type = dso->symtab_type; - maps__insert(kmaps, curr_map); + if (maps__insert(kmaps, curr_map)) + return -1; /* * Add it before we drop the reference to curr_map, i.e. while * we still are sure to have a reference to this DSO via diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 8719074b7f21..e7a8ae290c57 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -273,13 +273,13 @@ void symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms) void maps__fixup_end(struct maps *maps) { - struct map *prev = NULL, *curr; + struct map_rb_node *prev = NULL, *curr; down_write(&maps->lock); maps__for_each_entry(maps, curr) { - if (prev != NULL && !prev->end) - prev->end = curr->start; + if (prev != NULL && !prev->map->end) + prev->map->end = curr->map->start; prev = curr; } @@ -288,8 +288,8 @@ void maps__fixup_end(struct maps *maps) * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !curr->end) - curr->end = ~0ULL; + if (curr && !curr->map->end) + curr->map->end = ~0ULL; up_write(&maps->lock); } @@ -942,7 +942,10 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, } curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; - maps__insert(kmaps, curr_map); + if (maps__insert(kmaps, curr_map)) { + dso__put(ndso); + return -1; + } ++kernel_range; } else if (delta) { /* Kernel was relocated at boot time */ @@ -1130,14 +1133,15 @@ out_delete_from: static int do_validate_kcore_modules(const char *filename, struct maps *kmaps) { struct rb_root modules = RB_ROOT; - struct map *old_map; + struct map_rb_node *old_node; int err; err = read_proc_modules(filename, &modules); if (err) return err; - maps__for_each_entry(kmaps, old_map) { + maps__for_each_entry(kmaps, old_node) { + struct map *old_map = old_node->map; struct module_info *mi; if (!__map__is_kmodule(old_map)) { @@ -1254,10 +1258,13 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) */ int maps__merge_in(struct maps *kmaps, struct map *new_map) { - struct map *old_map; + struct map_rb_node *rb_node; LIST_HEAD(merged); + int err = 0; + + maps__for_each_entry(kmaps, rb_node) { + struct map *old_map = rb_node->map; - maps__for_each_entry(kmaps, old_map) { /* no overload with this one */ if (new_map->end < old_map->start || new_map->start >= old_map->end) @@ -1281,13 +1288,16 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) */ struct map_list_node *m = map_list_node__new(); - if (!m) - return -ENOMEM; + if (!m) { + err = -ENOMEM; + goto out; + } m->map = map__clone(new_map); if (!m->map) { free(m); - return -ENOMEM; + err = -ENOMEM; + goto out; } m->map->end = old_map->start; @@ -1319,21 +1329,24 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) } } +out: while (!list_empty(&merged)) { struct map_list_node *old_node; old_node = list_entry(merged.next, struct map_list_node, node); list_del_init(&old_node->node); - maps__insert(kmaps, old_node->map); + if (!err) + err = maps__insert(kmaps, old_node->map); map__put(old_node->map); free(old_node); } if (new_map) { - maps__insert(kmaps, new_map); + if (!err) + err = maps__insert(kmaps, new_map); map__put(new_map); } - return 0; + return err; } static int dso__load_kcore(struct dso *dso, struct map *map, @@ -1341,7 +1354,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map, { struct maps *kmaps = map__kmaps(map); struct kcore_mapfn_data md; - struct map *old_map, *replacement_map = NULL, *next; + struct map *replacement_map = NULL; + struct map_rb_node *old_node, *next; struct machine *machine; bool is_64_bit; int err, fd; @@ -1388,7 +1402,9 @@ static int dso__load_kcore(struct dso *dso, struct map *map, } /* Remove old maps */ - maps__for_each_entry_safe(kmaps, old_map, next) { + maps__for_each_entry_safe(kmaps, old_node, next) { + struct map *old_map = old_node->map; + /* * We need to preserve eBPF maps even if they are * covered by kcore, because we need to access @@ -1443,17 +1459,21 @@ static int dso__load_kcore(struct dso *dso, struct map *map, /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); - maps__insert(kmaps, map); + err = maps__insert(kmaps, map); map__put(map); map__put(new_map); + if (err) + goto out_err; } else { /* * Merge kcore map into existing maps, * and ensure that current maps (eBPF) * stay intact. */ - if (maps__merge_in(kmaps, new_map)) + if (maps__merge_in(kmaps, new_map)) { + err = -EINVAL; goto out_err; + } } free(new_node); } @@ -1500,7 +1520,7 @@ out_err: free(list_node); } close(fd); - return -EINVAL; + return err; } /* @@ -2044,8 +2064,9 @@ void __maps__sort_by_name(struct maps *maps) static int map__groups__sort_by_name_from_rbtree(struct maps *maps) { - struct map *map; - struct map **maps_by_name = realloc(maps->maps_by_name, maps->nr_maps * sizeof(map)); + struct map_rb_node *rb_node; + struct map **maps_by_name = realloc(maps->maps_by_name, + maps->nr_maps * sizeof(struct map *)); int i = 0; if (maps_by_name == NULL) @@ -2057,8 +2078,8 @@ static int map__groups__sort_by_name_from_rbtree(struct maps *maps) maps->maps_by_name = maps_by_name; maps->nr_maps_allocated = maps->nr_maps; - maps__for_each_entry(maps, map) - maps_by_name[i++] = map; + maps__for_each_entry(maps, rb_node) + maps_by_name[i++] = rb_node->map; __maps__sort_by_name(maps); @@ -2084,6 +2105,7 @@ static struct map *__maps__find_by_name(struct maps *maps, const char *name) struct map *maps__find_by_name(struct maps *maps, const char *name) { + struct map_rb_node *rb_node; struct map *map; down_read(&maps->lock); @@ -2102,12 +2124,13 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) goto out_unlock; /* Fallback to traversing the rbtree... */ - maps__for_each_entry(maps, map) + maps__for_each_entry(maps, rb_node) { + map = rb_node->map; if (strcmp(map->dso->short_name, name) == 0) { maps->last_search_by_name = map; goto out_unlock; } - + } map = NULL; out_unlock: diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 6def01036eb5..57b95c1d7e39 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -669,7 +669,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t struct machine *machine) { int rc = 0; - struct map *pos; + struct map_rb_node *pos; struct maps *maps = machine__kernel_maps(machine); union perf_event *event; size_t size = symbol_conf.buildid_mmap2 ? @@ -692,37 +692,39 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; maps__for_each_entry(maps, pos) { - if (!__map__is_kmodule(pos)) + struct map *map = pos->map; + + if (!__map__is_kmodule(map)) continue; if (symbol_conf.buildid_mmap2) { - size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + size = PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); event->mmap2.header.type = PERF_RECORD_MMAP2; event->mmap2.header.size = (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); memset(event->mmap2.filename + size, 0, machine->id_hdr_size); event->mmap2.header.size += machine->id_hdr_size; - event->mmap2.start = pos->start; - event->mmap2.len = pos->end - pos->start; + event->mmap2.start = map->start; + event->mmap2.len = map->end - map->start; event->mmap2.pid = machine->pid; - memcpy(event->mmap2.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); + memcpy(event->mmap2.filename, map->dso->long_name, + map->dso->long_name_len + 1); perf_record_mmap2__read_build_id(&event->mmap2, machine, false); } else { - size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + size = PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); event->mmap.header.type = PERF_RECORD_MMAP; event->mmap.header.size = (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); memset(event->mmap.filename + size, 0, machine->id_hdr_size); event->mmap.header.size += machine->id_hdr_size; - event->mmap.start = pos->start; - event->mmap.len = pos->end - pos->start; + event->mmap.start = map->start; + event->mmap.len = map->end - map->start; event->mmap.pid = machine->pid; - memcpy(event->mmap.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); + memcpy(event->mmap.filename, map->dso->long_name, + map->dso->long_name_len + 1); } if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index a2490a20eb56..24e53bd55f7d 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -352,9 +352,7 @@ int thread__insert_map(struct thread *thread, struct map *map) return ret; maps__fixup_overlappings(thread->maps, map, stderr); - maps__insert(thread->maps, map); - - return 0; + return maps__insert(thread->maps, map); } static int __thread__prepare_access(struct thread *thread) @@ -362,12 +360,12 @@ static int __thread__prepare_access(struct thread *thread) bool initialized = false; int err = 0; struct maps *maps = thread->maps; - struct map *map; + struct map_rb_node *rb_node; down_read(&maps->lock); - maps__for_each_entry(maps, map) { - err = unwind__prepare_access(thread->maps, map, &initialized); + maps__for_each_entry(maps, rb_node) { + err = unwind__prepare_access(thread->maps, rb_node->map, &initialized); if (err || initialized) break; } diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 81b6bd6e1536..dea70a477b91 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -306,7 +306,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui, u64 *table_data, u64 *segbase, u64 *fde_count) { - struct map *map; + struct map_rb_node *map_node; u64 base_addr = UINT64_MAX; int ret, fd; @@ -325,7 +325,9 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui, return -EINVAL; } - maps__for_each_entry(ui->thread->maps, map) { + maps__for_each_entry(ui->thread->maps, map_node) { + struct map *map = map_node->map; + if (map->dso == dso && map->start < base_addr) base_addr = map->start; } diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 43beb169631d..835c39efb80d 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -144,10 +144,11 @@ static enum dso_type machine__thread_dso_type(struct machine *machine, struct thread *thread) { enum dso_type dso_type = DSO__TYPE_UNKNOWN; - struct map *map; + struct map_rb_node *rb_node; + + maps__for_each_entry(thread->maps, rb_node) { + struct dso *dso = rb_node->map->dso; - maps__for_each_entry(thread->maps, map) { - struct dso *dso = map->dso; if (!dso || dso->long_name[0] != '/') continue; dso_type = dso__type(dso, machine); -- cgit v1.2.3 From 63df0e4bc368adbd12ed70ed4789d8d52d65661d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 20 Mar 2023 14:22:35 -0700 Subject: perf map: Add accessor for dso Later changes will add reference count checking for struct map, with dso being the most frequently accessed variable. Add an accessor so that the reference count check is only necessary in one place. Additional changes: - add a dso variable to avoid repeated map__dso calls. - in builtin-mem.c dump_raw_samples, code only partially tested for dso == NULL. Make the possibility of NULL consistent. - in thread.c thread__memcpy fix use of spaces and use tabs. Committer notes: Did missing conversions on these files: tools/perf/arch/powerpc/util/skip-callchain-idx.c tools/perf/arch/powerpc/util/sym-handling.c tools/perf/ui/browsers/hists.c tools/perf/ui/gtk/annotate.c tools/perf/util/cs-etm.c tools/perf/util/thread.c tools/perf/util/unwind-libunwind-local.c tools/perf/util/unwind-libunwind.c Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230320212248.1175731-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/skip-callchain-idx.c | 2 +- tools/perf/arch/powerpc/util/sym-handling.c | 2 +- tools/perf/builtin-annotate.c | 11 +-- tools/perf/builtin-buildid-list.c | 2 +- tools/perf/builtin-inject.c | 8 +- tools/perf/builtin-kallsyms.c | 4 +- tools/perf/builtin-mem.c | 10 ++- tools/perf/builtin-report.c | 7 +- tools/perf/builtin-script.c | 19 +++-- tools/perf/builtin-top.c | 11 ++- tools/perf/builtin-trace.c | 2 +- .../perf/scripts/python/Perf-Trace-Util/Context.c | 6 +- tools/perf/tests/code-reading.c | 28 ++++--- tools/perf/tests/hists_common.c | 8 +- tools/perf/tests/hists_cumulate.c | 4 +- tools/perf/tests/hists_filter.c | 4 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/maps.c | 2 +- tools/perf/tests/symbols.c | 6 +- tools/perf/tests/vmlinux-kallsyms.c | 13 +-- tools/perf/ui/browsers/annotate.c | 9 +- tools/perf/ui/browsers/hists.c | 17 ++-- tools/perf/ui/browsers/map.c | 4 +- tools/perf/ui/gtk/annotate.c | 5 +- tools/perf/util/annotate.c | 16 ++-- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/block-info.c | 4 +- tools/perf/util/bpf-event.c | 10 ++- tools/perf/util/build-id.c | 2 +- tools/perf/util/callchain.c | 6 +- tools/perf/util/cs-etm.c | 17 ++-- tools/perf/util/data-convert-json.c | 10 ++- tools/perf/util/db-export.c | 4 +- tools/perf/util/dlfilter.c | 10 ++- tools/perf/util/event.c | 9 +- tools/perf/util/evsel_fprintf.c | 2 +- tools/perf/util/hist.c | 10 +-- tools/perf/util/intel-pt.c | 45 +++++----- tools/perf/util/machine.c | 70 +++++++++------- tools/perf/util/map.c | 96 ++++++++++++++-------- tools/perf/util/map.h | 7 +- tools/perf/util/maps.c | 7 +- tools/perf/util/probe-event.c | 30 ++++--- .../perf/util/scripting-engines/trace-event-perl.c | 10 ++- .../util/scripting-engines/trace-event-python.c | 16 ++-- tools/perf/util/sort.c | 49 +++++------ tools/perf/util/symbol-elf.c | 2 +- tools/perf/util/symbol.c | 55 ++++++++----- tools/perf/util/synthetic-events.c | 12 +-- tools/perf/util/thread.c | 30 ++++--- tools/perf/util/unwind-libdw.c | 10 +-- tools/perf/util/unwind-libunwind-local.c | 31 ++++--- tools/perf/util/unwind-libunwind.c | 6 +- tools/perf/util/vdso.c | 2 +- 54 files changed, 447 insertions(+), 319 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index 20cd6244863b..fe0e4530673c 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c @@ -255,7 +255,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); if (al.map) - dso = al.map->dso; + dso = map__dso(al.map); if (!dso) { pr_debug("%" PRIx64 " dso is NULL\n", ip); diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index 0856b32f9e08..9f99fc88dbff 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -104,7 +104,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev, lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym); - if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) + if (map__dso(map)->symtab_type == DSO_BINARY_TYPE__KALLSYMS) tev->point.offset += PPC64LE_LEP_OFFSET; else if (lep_offset) { if (pev->uprobes) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 655987afef58..63fd2080b803 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -205,7 +205,7 @@ static int process_branch_callback(struct evsel *evsel, return 0; if (a.map != NULL) - a.map->dso->hit = 1; + map__dso(a.map)->hit = 1; hist__account_cycles(sample->branch_stack, al, sample, false, NULL); @@ -235,10 +235,11 @@ static int evsel__add_sample(struct evsel *evsel, struct perf_sample *sample, * the DSO? */ if (al->sym != NULL) { - rb_erase_cached(&al->sym->rb_node, - &al->map->dso->symbols); + struct dso *dso = map__dso(al->map); + + rb_erase_cached(&al->sym->rb_node, &dso->symbols); symbol__delete(al->sym); - dso__reset_find_symbol_cache(al->map->dso); + dso__reset_find_symbol_cache(dso); } return 0; } @@ -320,7 +321,7 @@ static void hists__find_annotations(struct hists *hists, struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct annotation *notes; - if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned) + if (he->ms.sym == NULL || map__dso(he->ms.map)->annotate_warned) goto find_next; if (ann->sym_hist_filter && diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 00bfe89f0b5d..cad9ed44ce7c 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -24,7 +24,7 @@ static int buildid__map_cb(struct map *map, void *arg __maybe_unused) { - const struct dso *dso = map->dso; + const struct dso *dso = map__dso(map); char bid_buf[SBUILD_ID_SIZE]; memset(bid_buf, 0, sizeof(bid_buf)); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 10bb1d494258..8f6909dd8a54 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -753,9 +753,11 @@ int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, } if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { - if (!al.map->dso->hit) { - al.map->dso->hit = 1; - dso__inject_build_id(al.map->dso, tool, machine, + struct dso *dso = map__dso(al.map); + + if (!dso->hit) { + dso->hit = 1; + dso__inject_build_id(dso, tool, machine, sample->cpumode, al.map->flags); } } diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index c08ee81529e8..5638ca4dbd8e 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -28,6 +28,7 @@ static int __cmd_kallsyms(int argc, const char **argv) for (i = 0; i < argc; ++i) { struct map *map; + const struct dso *dso; struct symbol *symbol = machine__find_kernel_symbol_by_name(machine, argv[i], &map); if (symbol == NULL) { @@ -35,8 +36,9 @@ static int __cmd_kallsyms(int argc, const char **argv) continue; } + dso = map__dso(map); printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n", - symbol->name, map->dso->short_name, map->dso->long_name, + symbol->name, dso->short_name, dso->long_name, map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end), symbol->start, symbol->end); } diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index dedd612eae5e..1e27188b0de1 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -200,6 +200,7 @@ dump_raw_samples(struct perf_tool *tool, struct addr_location al; const char *fmt, *field_sep; char str[PAGE_SIZE_NAME_LEN]; + struct dso *dso = NULL; if (machine__resolve(machine, &al, sample) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", @@ -210,8 +211,11 @@ dump_raw_samples(struct perf_tool *tool, if (al.filtered || (mem->hide_unresolved && al.sym == NULL)) goto out_put; - if (al.map != NULL) - al.map->dso->hit = 1; + if (al.map != NULL) { + dso = map__dso(al.map); + if (dso) + dso->hit = 1; + } field_sep = symbol_conf.field_sep; if (field_sep) { @@ -252,7 +256,7 @@ dump_raw_samples(struct perf_tool *tool, symbol_conf.field_sep, sample->data_src, symbol_conf.field_sep, - al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + dso ? dso->long_name : "???", al.sym ? al.sym->name : "???"); out_put: addr_location__put(&al); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c7e3863e8f44..ff239b89e4d0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -319,7 +319,7 @@ static int process_sample_event(struct perf_tool *tool, } if (al.map != NULL) - al.map->dso->hit = 1; + map__dso(al.map)->hit = 1; if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) { hist__account_cycles(sample->branch_stack, &al, sample, @@ -608,7 +608,7 @@ static void report__warn_kptr_restrict(const struct report *rep) return; if (kernel_map == NULL || - (kernel_map->dso->hit && + (map__dso(kernel_map)->hit && (kernel_kmap->ref_reloc_sym == NULL || kernel_kmap->ref_reloc_sym->addr == 0))) { const char *desc = @@ -848,6 +848,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) maps__for_each_entry(maps, rb_node) { struct map *map = rb_node->map; + const struct dso *dso = map__dso(map); printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n", indent, "", map->start, map->end, @@ -856,7 +857,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) map->prot & PROT_EXEC ? 'x' : '-', map->flags & MAP_SHARED ? 's' : 'p', map->pgoff, - map->dso->id.ino, map->dso->name); + dso->id.ino, dso->name); } return printed; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c9296d8b33c0..27fd9c203600 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1011,11 +1011,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample, to = entries[i].to; if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && - !alf.map->dso->adjust_symbols) + !map__dso(alf.map)->adjust_symbols) from = map__map_ip(alf.map, from); if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && - !alt.map->dso->adjust_symbols) + !map__dso(alt.map)->adjust_symbols) to = map__map_ip(alt.map, to); printed += fprintf(fp, " 0x%"PRIx64, from); @@ -1044,6 +1044,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, long offset, len; struct addr_location al; bool kernel; + struct dso *dso; if (!start || !end) return 0; @@ -1074,11 +1075,12 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, return 0; } - if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) { + dso = map__dso(al.map); + if (!thread__find_map(thread, *cpumode, start, &al) || !dso) { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); return 0; } - if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) { + if (dso->data.status == DSO_DATA_STATUS_ERROR) { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); return 0; } @@ -1087,10 +1089,10 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, map__load(al.map); offset = al.map->map_ip(al.map, start); - len = dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer, + len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer, end - start + MAXINSN); - *is64bit = al.map->dso->is_64_bit; + *is64bit = dso->is_64_bit; if (len <= 0) pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", start, end); @@ -1104,10 +1106,11 @@ static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srcc unsigned line; int len; char *srccode; + struct dso *dso = map__dso(map); - if (!map || !map->dso) + if (!map || !dso) return 0; - srcfile = get_srcline_split(map->dso, + srcfile = get_srcline_split(dso, map__rip_2objdump(map, addr), &line); if (!srcfile) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 2c985cfea517..babfc163efe2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -114,6 +114,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) struct symbol *sym; struct annotation *notes; struct map *map; + struct dso *dso; int err = -1; if (!he || !he->ms.sym) @@ -123,12 +124,12 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) sym = he->ms.sym; map = he->ms.map; + dso = map__dso(map); /* * We can't annotate with just /proc/kallsyms */ - if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && - !dso__is_kcore(map->dso)) { + if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { pr_err("Can't annotate %s: No vmlinux file was found in the " "path\n", sym->name); sleep(1); @@ -169,6 +170,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) { struct utsname uts; int err = uname(&uts); + struct dso *dso = map__dso(map); ui__warning("Out of bounds address found:\n\n" "Addr: %" PRIx64 "\n" @@ -180,7 +182,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) "Tools: %s\n\n" "Not all samples will be on the annotation output.\n\n" "Please report to linux-kernel@vger.kernel.org\n", - ip, map->dso->long_name, dso__symtab_origin(map->dso), + ip, dso->long_name, dso__symtab_origin(dso), map->start, map->end, sym->start, sym->end, sym->binding == STB_GLOBAL ? 'g' : sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, @@ -810,7 +812,8 @@ static void perf_event__process_sample(struct perf_tool *tool, __map__is_kernel(al.map) && map__has_symbols(al.map)) { if (symbol_conf.vmlinux_name) { char serr[256]; - dso__strerror_load(al.map->dso, serr, sizeof(serr)); + + dso__strerror_load(map__dso(al.map), serr, sizeof(serr)); ui__warning("The %s file can't be used: %s\n%s", symbol_conf.vmlinux_name, serr, msg); } else { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b363c609818b..72ef0bebb06b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2863,7 +2863,7 @@ static void print_location(FILE *f, struct perf_sample *sample, { if ((verbose > 0 || print_dso) && al->map) - fprintf(f, "%s@", al->map->dso->long_name); + fprintf(f, "%s@", map__dso(al->map)->long_name); if ((verbose > 0 || print_sym) && al->sym) fprintf(f, "%s+0x%" PRIx64, al->sym->name, diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c index feedd02b3b3d..53b1587db403 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -145,6 +145,7 @@ static PyObject *perf_sample_src(PyObject *obj, PyObject *args, bool get_srccode char *srccode = NULL; PyObject *result; struct map *map; + struct dso *dso; int len = 0; u64 addr; @@ -153,9 +154,10 @@ static PyObject *perf_sample_src(PyObject *obj, PyObject *args, bool get_srccode map = c->al->map; addr = c->al->addr; + dso = map ? map__dso(map) : NULL; - if (map && map->dso) - srcfile = get_srcline_split(map->dso, map__rip_2objdump(map, addr), &line); + if (dso) + srcfile = get_srcline_split(dso, map__rip_2objdump(map, addr), &line); if (get_srccode) { if (srcfile) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 8d2036f2f944..936c61546e64 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -237,10 +237,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, char decomp_name[KMOD_DECOMP_LEN]; bool decomp = false; int ret, err = 0; + struct dso *dso; pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); - if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) { + if (!thread__find_map(thread, cpumode, addr, &al) || !map__dso(al.map)) { if (cpumode == PERF_RECORD_MISC_HYPERVISOR) { pr_debug("Hypervisor address can not be resolved - skipping\n"); goto out; @@ -250,11 +251,10 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, err = -1; goto out; } + dso = map__dso(al.map); + pr_debug("File is: %s\n", dso->long_name); - pr_debug("File is: %s\n", al.map->dso->long_name); - - if (al.map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && - !dso__is_kcore(al.map->dso)) { + if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { pr_debug("Unexpected kernel address - skipping\n"); goto out; } @@ -269,7 +269,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, len = al.map->end - addr; /* Read the object code using perf */ - ret_len = dso__data_read_offset(al.map->dso, maps__machine(thread->maps), + ret_len = dso__data_read_offset(dso, maps__machine(thread->maps), al.addr, buf1, len); if (ret_len != len) { pr_debug("dso__data_read_offset failed\n"); @@ -287,7 +287,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, } /* objdump struggles with kcore - try each map only once */ - if (dso__is_kcore(al.map->dso)) { + if (dso__is_kcore(dso)) { size_t d; for (d = 0; d < state->done_cnt; d++) { @@ -304,9 +304,9 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, state->done[state->done_cnt++] = al.map->start; } - objdump_name = al.map->dso->long_name; - if (dso__needs_decompress(al.map->dso)) { - if (dso__decompress_kmodule_path(al.map->dso, objdump_name, + objdump_name = dso->long_name; + if (dso__needs_decompress(dso)) { + if (dso__decompress_kmodule_path(dso, objdump_name, decomp_name, sizeof(decomp_name)) < 0) { pr_debug("decompression failed\n"); @@ -335,7 +335,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, len -= ret; if (len) { pr_debug("Reducing len to %zu\n", len); - } else if (dso__is_kcore(al.map->dso)) { + } else if (dso__is_kcore(dso)) { /* * objdump cannot handle very large segments * that may be found in kcore. @@ -572,6 +572,7 @@ static int do_test_code_reading(bool try_kcore) pid_t pid; struct map *map; bool have_vmlinux, have_kcore, excl_kernel = false; + struct dso *dso; pid = getpid(); @@ -595,8 +596,9 @@ static int do_test_code_reading(bool try_kcore) pr_debug("map__load failed\n"); goto out_err; } - have_vmlinux = dso__is_vmlinux(map->dso); - have_kcore = dso__is_kcore(map->dso); + dso = map__dso(map); + have_vmlinux = dso__is_vmlinux(dso); + have_kcore = dso__is_kcore(dso); /* 2nd time through we just try kcore */ if (try_kcore && !have_kcore) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 6f34d08b84e5..745ab18d17db 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -179,9 +179,11 @@ void print_hists_in(struct hists *hists) he = rb_entry(node, struct hist_entry, rb_node_in); if (!he->filtered) { + struct dso *dso = map__dso(he->ms.map); + pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n", i, thread__comm_str(he->thread), - he->ms.map->dso->short_name, + dso->short_name, he->ms.sym->name, he->stat.period); } @@ -206,9 +208,11 @@ void print_hists_out(struct hists *hists) he = rb_entry(node, struct hist_entry, rb_node); if (!he->filtered) { + struct dso *dso = map__dso(he->ms.map); + pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n", i, thread__comm_str(he->thread), he->thread->tid, - he->ms.map->dso->short_name, + dso->short_name, he->ms.sym->name, he->stat.period, he->stat_acc ? he->stat_acc->period : 0); } diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index b42d37ff2399..f00ec9abdbcd 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -150,12 +150,12 @@ static void del_hist_entries(struct hists *hists) typedef int (*test_fn_t)(struct evsel *, struct machine *); #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (he->ms.map->dso->short_name) +#define DSO(he) (map__dso(he->ms.map)->short_name) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (he->thread->tid) #define DEPTH(he) (he->callchain->max_depth) -#define CDSO(cl) (cl->ms.map->dso->short_name) +#define CDSO(cl) (map__dso(cl->ms.map)->short_name) #define CSYM(cl) (cl->ms.sym->name) struct result { diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 8e1ceeb9b7b6..7c552549f4a4 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -194,7 +194,7 @@ static int test__hists_filter(struct test_suite *test __maybe_unused, int subtes hists__filter_by_thread(hists); /* now applying dso filter for 'kernel' */ - hists->dso_filter = fake_samples[0].map->dso; + hists->dso_filter = map__dso(fake_samples[0].map); hists__filter_by_dso(hists); if (verbose > 2) { @@ -288,7 +288,7 @@ static int test__hists_filter(struct test_suite *test __maybe_unused, int subtes /* now applying all filters at once. */ hists->thread_filter = fake_samples[1].thread; - hists->dso_filter = fake_samples[1].map->dso; + hists->dso_filter = map__dso(fake_samples[1].map); hists__filter_by_thread(hists); hists__filter_by_dso(hists); diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 62b0093253e3..428d11a938f2 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -116,7 +116,7 @@ static void del_hist_entries(struct hists *hists) typedef int (*test_fn_t)(struct evsel *, struct machine *); #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (he->ms.map->dso->short_name) +#define DSO(he) (map__dso(he->ms.map)->short_name) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (he->thread->tid) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 8246d37e4b7a..ae7028fbf79e 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -26,7 +26,7 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma TEST_ASSERT_VAL("wrong map start", map->start == merged[i].start); TEST_ASSERT_VAL("wrong map end", map->end == merged[i].end); - TEST_ASSERT_VAL("wrong map name", !strcmp(map->dso->name, merged[i].name)); + TEST_ASSERT_VAL("wrong map name", !strcmp(map__dso(map)->name, merged[i].name)); TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) == 1); i++; diff --git a/tools/perf/tests/symbols.c b/tools/perf/tests/symbols.c index 0793f8f419e2..2d1aa42d36a9 100644 --- a/tools/perf/tests/symbols.c +++ b/tools/perf/tests/symbols.c @@ -102,6 +102,7 @@ static int test_file(struct test_info *ti, char *filename) { struct map *map = NULL; int ret, nr; + struct dso *dso; pr_debug("Testing %s\n", filename); @@ -109,7 +110,8 @@ static int test_file(struct test_info *ti, char *filename) if (ret != TEST_OK) return ret; - nr = dso__load(map->dso, map); + dso = map__dso(map); + nr = dso__load(dso, map); if (nr < 0) { pr_debug("dso__load() failed!\n"); ret = TEST_FAIL; @@ -122,7 +124,7 @@ static int test_file(struct test_info *ti, char *filename) goto out_put; } - ret = test_dso(map->dso); + ret = test_dso(dso); out_put: map__put(map); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index c8abb3ca8347..c614c2db7e89 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -293,15 +293,16 @@ next_pair: maps__for_each_entry(maps, rb_node) { struct map *map = rb_node->map; + struct dso *dso = map__dso(map); /* * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while * the kernel will have the path for the vmlinux file being used, * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - struct map *pair = maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ? - map->dso->short_name : - map->dso->name)); + struct map *pair = maps__find_by_name(kallsyms.kmaps, (dso->kernel ? + dso->short_name : + dso->name)); if (pair) { pair->priv = 1; } else { @@ -326,17 +327,19 @@ next_pair: continue; if (pair->start == mem_start) { + struct dso *dso = map__dso(map); + if (!header_printed) { pr_info("WARN: Maps in vmlinux with a different name in kallsyms:\n"); header_printed = true; } pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map->start, map->end, map->pgoff, map->dso->name); + map->start, map->end, map->pgoff, dso->name); if (mem_end != pair->end) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, pair->start, pair->end, pair->pgoff); - pr_info(" %s\n", pair->dso->name); + pr_info(" %s\n", dso->name); pair->priv = 1; } } diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index c03fa76c02ff..12c3ce530e42 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -441,7 +441,8 @@ static void ui_browser__init_asm_mode(struct ui_browser *browser) static int sym_title(struct symbol *sym, struct map *map, char *title, size_t sz, int percent_type) { - return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, map->dso->long_name, + return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, + map__dso(map)->long_name, percent_type_str(percent_type)); } @@ -964,20 +965,22 @@ int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, }, .opts = opts, }; + struct dso *dso; int ret = -1, err; int not_annotated = list_empty(¬es->src->source); if (sym == NULL) return -1; - if (ms->map->dso->annotate_warned) + dso = map__dso(ms->map); + if (dso->annotate_warned) return -1; if (not_annotated) { err = symbol__annotate2(ms, evsel, opts, &browser.arch); if (err) { char msg[BUFSIZ]; - ms->map->dso->annotate_warned = true; + dso->annotate_warned = true; symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); goto out_free_offsets; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 572ff38ceb0f..9f9f622325ae 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2487,7 +2487,7 @@ static struct symbol *symbol__new_unresolved(u64 addr, struct map *map) return NULL; } - dso__insert_symbol(map->dso, sym); + dso__insert_symbol(map__dso(map), sym); } return sym; @@ -2499,7 +2499,9 @@ add_annotate_opt(struct hist_browser *browser __maybe_unused, struct map_symbol *ms, u64 addr) { - if (!ms->map || !ms->map->dso || ms->map->dso->annotate_warned) + struct dso *dso = map__dso(ms->map); + + if (!ms->map || !dso || dso->annotate_warned) return 0; if (!ms->sym) @@ -2589,9 +2591,10 @@ static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map browser->hists->dso_filter = NULL; ui_helpline__pop(); } else { + struct dso *dso = map__dso(map); ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name); - browser->hists->dso_filter = map->dso; + __map__is_kernel(map) ? "the Kernel" : dso->short_name); + browser->hists->dso_filter = dso; perf_hpp__set_elide(HISTC_DSO, true); pstack__push(browser->pstack, &browser->hists->dso_filter); } @@ -2616,7 +2619,7 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act, if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)", browser->hists->dso_filter ? "out of" : "into", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0) + __map__is_kernel(map) ? "the Kernel" : map__dso(map)->short_name) < 0) return 0; act->ms.map = map; @@ -3091,8 +3094,8 @@ do_hotkey: // key came straight from options ui__popup_menu() if (!browser->selection || !browser->selection->map || - !browser->selection->map->dso || - browser->selection->map->dso->annotate_warned) { + !map__dso(browser->selection->map) || + map__dso(browser->selection->map)->annotate_warned) { continue; } diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 3d49b916c9e4..3d1b958d8832 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -76,7 +76,7 @@ static int map_browser__run(struct map_browser *browser) { int key; - if (ui_browser__show(&browser->b, browser->map->dso->long_name, + if (ui_browser__show(&browser->b, map__dso(browser->map)->long_name, "Press ESC to exit, %s / to search", verbose > 0 ? "" : "restart with -v to use") < 0) return -1; @@ -106,7 +106,7 @@ int map__browse(struct map *map) { struct map_browser mb = { .b = { - .entries = &map->dso->symbols, + .entries = &map__dso(map)->symbols, .refresh = ui_browser__rb_tree_refresh, .seek = ui_browser__rb_tree_seek, .write = map_browser__write, diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index a1c021a6d3c1..2effac77ca8c 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -165,6 +165,7 @@ static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *options, struct hist_browser_timer *hbt) { + struct dso *dso = map__dso(ms->map); struct symbol *sym = ms->sym; GtkWidget *window; GtkWidget *notebook; @@ -172,13 +173,13 @@ static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel, GtkWidget *tab_label; int err; - if (ms->map->dso->annotate_warned) + if (dso->annotate_warned) return -1; err = symbol__annotate(ms, evsel, options, NULL); if (err) { char msg[BUFSIZ]; - ms->map->dso->annotate_warned = true; + dso->annotate_warned = true; symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s: %s\n", sym->name, msg); return -1; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f47b5dde66bc..84100ca5f306 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1585,7 +1585,7 @@ static void delete_last_nop(struct symbol *sym) int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, size_t buflen) { - struct dso *dso = ms->map->dso; + struct dso *dso = map__dso(ms->map); BUG_ON(buflen == 0); @@ -1727,7 +1727,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, struct map *map = args->ms.map; struct perf_bpil *info_linear; struct disassemble_info info; - struct dso *dso = map->dso; + struct dso *dso = map__dso(map); int pc = 0, count, sub_id; struct btf *btf = NULL; char tpath[PATH_MAX]; @@ -1950,7 +1950,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) { struct annotation_options *opts = args->options; struct map *map = args->ms.map; - struct dso *dso = map->dso; + struct dso *dso = map__dso(map); char *command; FILE *file; char symfs_filename[PATH_MAX]; @@ -2395,7 +2395,7 @@ int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel, { struct map *map = ms->map; struct symbol *sym = ms->sym; - struct dso *dso = map->dso; + struct dso *dso = map__dso(map); char *filename; const char *d_filename; const char *evsel_name = evsel__name(evsel); @@ -2578,7 +2578,7 @@ int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel, } fprintf(fp, "%s() %s\nEvent: %s\n\n", - ms->sym->name, ms->map->dso->long_name, ev_name); + ms->sym->name, map__dso(ms->map)->long_name, ev_name); symbol__annotate_fprintf2(ms->sym, fp, opts); fclose(fp); @@ -2804,7 +2804,7 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map, if (percent_max <= 0.5) continue; - al->path = get_srcline(map->dso, notes->start + al->offset, NULL, + al->path = get_srcline(map__dso(map), notes->start + al->offset, NULL, false, true, notes->start + al->offset); insert_source_line(&tmp_root, al, opts); } @@ -2823,7 +2823,7 @@ static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root, int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { - struct dso *dso = ms->map->dso; + struct dso *dso = map__dso(ms->map); struct symbol *sym = ms->sym; struct rb_root source_line = RB_ROOT; struct hists *hists = evsel__hists(evsel); @@ -2859,7 +2859,7 @@ int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { - struct dso *dso = ms->map->dso; + struct dso *dso = map__dso(ms->map); struct symbol *sym = ms->sym; struct rb_root source_line = RB_ROOT; int err; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index b2a5e5397bad..a0368202a746 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2560,7 +2560,7 @@ static struct dso *load_dso(const char *name) if (map__load(map) < 0) pr_err("File '%s' not found or has no symbols.\n", name); - dso = dso__get(map->dso); + dso = dso__get(map__dso(map)); map__put(map); diff --git a/tools/perf/util/block-info.c b/tools/perf/util/block-info.c index 5ecd4f401f32..16a7b4adcf18 100644 --- a/tools/perf/util/block-info.c +++ b/tools/perf/util/block-info.c @@ -317,9 +317,9 @@ static int block_dso_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct block_fmt *block_fmt = container_of(fmt, struct block_fmt, fmt); struct map *map = he->ms.map; - if (map && map->dso) { + if (map && map__dso(map)) { return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, - map->dso->short_name); + map__dso(map)->short_name); } return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 025f331b3867..38fcf3ba5749 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -57,10 +57,12 @@ static int machine__process_bpf_event_load(struct machine *machine, struct map *map = maps__find(machine__kernel_maps(machine), addr); if (map) { - map->dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO; - map->dso->bpf_prog.id = id; - map->dso->bpf_prog.sub_id = i; - map->dso->bpf_prog.env = env; + struct dso *dso = map__dso(map); + + dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO; + dso->bpf_prog.id = id; + dso->bpf_prog.sub_id = i; + dso->bpf_prog.env = env; } } return 0; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index ea9c083ab1e3..06a8cd88cbef 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -59,7 +59,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, } if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) - al.map->dso->hit = 1; + map__dso(al.map)->hit = 1; thread__put(thread); return 0; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 0aa979f64565..9e9c39dd9d2b 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -701,8 +701,8 @@ static enum match_result match_chain_strings(const char *left, static enum match_result match_chain_dso_addresses(struct map *left_map, u64 left_ip, struct map *right_map, u64 right_ip) { - struct dso *left_dso = left_map ? left_map->dso : NULL; - struct dso *right_dso = right_map ? right_map->dso : NULL; + struct dso *left_dso = left_map ? map__dso(left_map) : NULL; + struct dso *right_dso = right_map ? map__dso(right_map) : NULL; if (left_dso != right_dso) return left_dso < right_dso ? MATCH_LT : MATCH_GT; @@ -1174,7 +1174,7 @@ char *callchain_list__sym_name(struct callchain_list *cl, if (show_dso) scnprintf(bf + printed, bfsize - printed, " %s", cl->ms.map ? - cl->ms.map->dso->short_name : + map__dso(cl->ms.map)->short_name : "unknown"); return bf; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 94e2d02009eb..528a7fb066cf 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -865,6 +865,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, struct thread *thread; struct machine *machine; struct addr_location al; + struct dso *dso; struct cs_etm_traceid_queue *tidq; if (!etmq) @@ -883,27 +884,29 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, thread = etmq->etm->unknown_thread; } - if (!thread__find_map(thread, cpumode, address, &al) || !al.map->dso) + dso = map__dso(al.map); + + if (!thread__find_map(thread, cpumode, address, &al) || !dso) return 0; - if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR && - dso__data_status_seen(al.map->dso, DSO_DATA_STATUS_SEEN_ITRACE)) + if (dso->data.status == DSO_DATA_STATUS_ERROR && + dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) return 0; offset = al.map->map_ip(al.map, address); map__load(al.map); - len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size); + len = dso__data_read_offset(dso, machine, offset, buffer, size); if (len <= 0) { ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n" " Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols.\n"); - if (!al.map->dso->auxtrace_warned) { + if (!dso->auxtrace_warned) { pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n", address, - al.map->dso->long_name ? al.map->dso->long_name : "Unknown"); - al.map->dso->auxtrace_warned = true; + dso->long_name ? dso->long_name : "Unknown"); + dso->auxtrace_warned = true; } return 0; } diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index ba9d93ce9463..653709ab867a 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -128,15 +128,17 @@ static void output_sample_callchain_entry(struct perf_tool *tool, output_json_key_format(out, false, 5, "ip", "\"0x%" PRIx64 "\"", ip); if (al && al->sym && al->sym->namelen) { + struct dso *dso = al->map ? map__dso(al->map) : NULL; + fputc(',', out); output_json_key_string(out, false, 5, "symbol", al->sym->name); - if (al->map && al->map->dso) { - const char *dso = al->map->dso->short_name; + if (dso) { + const char *dso_name = dso->short_name; - if (dso && strlen(dso) > 0) { + if (dso_name && strlen(dso_name) > 0) { fputc(',', out); - output_json_key_string(out, false, 5, "dso", dso); + output_json_key_string(out, false, 5, "dso", dso_name); } } } diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 1cfcfdd3cf52..84c970c11794 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -179,7 +179,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, int err; if (al->map) { - struct dso *dso = al->map->dso; + struct dso *dso = map__dso(al->map); err = db_export__dso(dbe, dso, maps__machine(al->maps)); if (err) @@ -255,7 +255,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe, al.addr = node->ip; if (al.map && !al.sym) - al.sym = dso__find_symbol(al.map->dso, al.addr); + al.sym = dso__find_symbol(map__dso(al.map), al.addr); db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset); diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index fe2a0752a0f6..8a7ffe0d805a 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -29,7 +29,7 @@ static void al_to_d_al(struct addr_location *al, struct perf_dlfilter_al *d_al) d_al->size = sizeof(*d_al); if (al->map) { - struct dso *dso = al->map->dso; + struct dso *dso = map__dso(al->map); if (symbol_conf.show_kernel_path && dso->long_name) d_al->dso = dso->long_name; @@ -220,6 +220,7 @@ static const char *dlfilter__srcline(void *ctx, __u32 *line_no) unsigned int line = 0; char *srcfile = NULL; struct map *map; + struct dso *dso; u64 addr; if (!d->ctx_valid || !line_no) @@ -231,9 +232,10 @@ static const char *dlfilter__srcline(void *ctx, __u32 *line_no) map = al->map; addr = al->addr; + dso = map ? map__dso(map) : NULL; - if (map && map->dso) - srcfile = get_srcline_split(map->dso, map__rip_2objdump(map, addr), &line); + if (dso) + srcfile = get_srcline_split(dso, map__rip_2objdump(map, addr), &line); *line_no = line; return srcfile; @@ -279,7 +281,7 @@ have_map: offset = map->map_ip(map, ip); if (ip + len >= map->end) len = map->end - ip; - return dso__data_read_offset(map->dso, d->machine, offset, buf, len); + return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); } static const struct perf_dlfilter_fns perf_dlfilter_fns = { diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f40cdd6ac126..2ddc75dee019 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -685,6 +685,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample) { struct thread *thread; + struct dso *dso; if (symbol_conf.guest_code && !machine__is_host(machine)) thread = machine__findnew_guest_code(machine, sample->pid); @@ -695,9 +696,11 @@ int machine__resolve(struct machine *machine, struct addr_location *al, dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); thread__find_map(thread, sample->cpumode, sample->ip, al); + dso = al->map ? map__dso(al->map) : NULL; dump_printf(" ...... dso: %s\n", - al->map ? al->map->dso->long_name : - al->level == 'H' ? "[hypervisor]" : ""); + dso + ? dso->long_name + : (al->level == 'H' ? "[hypervisor]" : "")); if (thread__is_filtered(thread)) al->filtered |= (1 << HIST_FILTER__THREAD); @@ -715,8 +718,6 @@ int machine__resolve(struct machine *machine, struct addr_location *al, } if (al->map) { - struct dso *dso = al->map->dso; - if (symbol_conf.dso_list && (!dso || !(strlist__has_entry(symbol_conf.dso_list, dso->short_name) || diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index bd22c4932d10..dff5d8c4b06d 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -155,7 +155,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, if (print_ip) { /* Show binary offset for userspace addr */ - if (map && !map->dso->kernel) + if (map && !map__dso(map)->kernel) printed += fprintf(fp, "%c%16" PRIx64, s, addr); else printed += fprintf(fp, "%c%16" PRIx64, s, node->ip); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 5f9f38ed5da1..e494425cad06 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -106,7 +106,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) hists__set_col_len(hists, HISTC_THREAD, len + 8); if (h->ms.map) { - len = dso__name_len(h->ms.map->dso); + len = dso__name_len(map__dso(h->ms.map)); hists__new_col_len(hists, HISTC_DSO, len); } @@ -120,7 +120,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) symlen += BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); - symlen = dso__name_len(h->branch_info->from.ms.map->dso); + symlen = dso__name_len(map__dso(h->branch_info->from.ms.map)); hists__new_col_len(hists, HISTC_DSO_FROM, symlen); } else { symlen = unresolved_col_width + 4 + 2; @@ -135,7 +135,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) symlen += BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); - symlen = dso__name_len(h->branch_info->to.ms.map->dso); + symlen = dso__name_len(map__dso(h->branch_info->to.ms.map)); hists__new_col_len(hists, HISTC_DSO_TO, symlen); } else { symlen = unresolved_col_width + 4 + 2; @@ -180,7 +180,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) } if (h->mem_info->daddr.ms.map) { - symlen = dso__name_len(h->mem_info->daddr.ms.map->dso); + symlen = dso__name_len(map__dso(h->mem_info->daddr.ms.map)); hists__new_col_len(hists, HISTC_MEM_DADDR_DSO, symlen); } else { @@ -2110,7 +2110,7 @@ static bool hists__filter_entry_by_dso(struct hists *hists, struct hist_entry *he) { if (hists->dso_filter != NULL && - (he->ms.map == NULL || he->ms.map->dso != hists->dso_filter)) { + (he->ms.map == NULL || map__dso(he->ms.map) != hists->dso_filter)) { he->filtered |= (1 << HIST_FILTER__DSO); return true; } diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 955c1b9dc6a4..8cec88e09792 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -801,17 +801,19 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, } while (1) { - if (!thread__find_map(thread, cpumode, *ip, &al) || !al.map->dso) { + struct dso *dso; + + if (!thread__find_map(thread, cpumode, *ip, &al) || !map__dso(al.map)) { if (al.map) intel_pt_log("ERROR: thread has no dso for %#" PRIx64 "\n", *ip); else intel_pt_log("ERROR: thread has no map for %#" PRIx64 "\n", *ip); return -EINVAL; } + dso = map__dso(al.map); - if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR && - dso__data_status_seen(al.map->dso, - DSO_DATA_STATUS_SEEN_ITRACE)) + if (dso->data.status == DSO_DATA_STATUS_ERROR && + dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) return -ENOENT; offset = al.map->map_ip(al.map, *ip); @@ -819,7 +821,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, if (!to_ip && one_map) { struct intel_pt_cache_entry *e; - e = intel_pt_cache_lookup(al.map->dso, machine, offset); + e = intel_pt_cache_lookup(dso, machine, offset); if (e && (!max_insn_cnt || e->insn_cnt <= max_insn_cnt)) { *insn_cnt_ptr = e->insn_cnt; @@ -829,8 +831,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, intel_pt_insn->emulated_ptwrite = e->emulated_ptwrite; intel_pt_insn->length = e->length; intel_pt_insn->rel = e->rel; - memcpy(intel_pt_insn->buf, e->insn, - INTEL_PT_INSN_BUF_SZ); + memcpy(intel_pt_insn->buf, e->insn, INTEL_PT_INSN_BUF_SZ); intel_pt_log_insn_no_data(intel_pt_insn, *ip); return 0; } @@ -842,17 +843,17 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); - x86_64 = al.map->dso->is_64_bit; + x86_64 = dso->is_64_bit; while (1) { - len = dso__data_read_offset(al.map->dso, machine, + len = dso__data_read_offset(dso, machine, offset, buf, INTEL_PT_INSN_BUF_SZ); if (len <= 0) { intel_pt_log("ERROR: failed to read at offset %#" PRIx64 " ", offset); if (intel_pt_enable_logging) - dso__fprintf(al.map->dso, intel_pt_log_fp()); + dso__fprintf(dso, intel_pt_log_fp()); return -EINVAL; } @@ -871,7 +872,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, goto out; /* Check for emulated ptwrite */ offs = offset + intel_pt_insn->length; - eptw = intel_pt_emulated_ptwrite(al.map->dso, machine, offs); + eptw = intel_pt_emulated_ptwrite(dso, machine, offs); intel_pt_insn->emulated_ptwrite = eptw; goto out; } @@ -906,13 +907,13 @@ out: if (to_ip) { struct intel_pt_cache_entry *e; - e = intel_pt_cache_lookup(al.map->dso, machine, start_offset); + e = intel_pt_cache_lookup(map__dso(al.map), machine, start_offset); if (e) return 0; } /* Ignore cache errors */ - intel_pt_cache_add(al.map->dso, machine, start_offset, insn_cnt, + intel_pt_cache_add(map__dso(al.map), machine, start_offset, insn_cnt, *ip - start_ip, intel_pt_insn); return 0; @@ -983,13 +984,12 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data) if (!thread) return -EINVAL; - if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso) + if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map)) return -EINVAL; offset = al.map->map_ip(al.map, ip); - return intel_pt_match_pgd_ip(ptq->pt, ip, offset, - al.map->dso->long_name); + return intel_pt_match_pgd_ip(ptq->pt, ip, offset, map__dso(al.map)->long_name); } static bool intel_pt_pgd_ip(uint64_t ip, void *data) @@ -2744,7 +2744,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip) if (map__load(map)) return 0; - start = dso__first_symbol(map->dso); + start = dso__first_symbol(map__dso(map)); for (sym = start; sym; sym = dso__next_symbol(sym)) { if (sym->binding == STB_GLOBAL && @@ -3381,18 +3381,21 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event) return 0; for (; cnt; cnt--, addr--) { + struct dso *dso; + if (intel_pt_find_map(thread, cpumode, addr, &al)) { if (addr < event->text_poke.addr) return 0; continue; } - if (!al.map->dso || !al.map->dso->auxtrace_cache) + dso = map__dso(al.map); + if (!dso || !dso->auxtrace_cache) continue; offset = al.map->map_ip(al.map, addr); - e = intel_pt_cache_lookup(al.map->dso, machine, offset); + e = intel_pt_cache_lookup(dso, machine, offset); if (!e) continue; @@ -3405,9 +3408,9 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event) if (e->branch != INTEL_PT_BR_NO_BRANCH) return 0; } else { - intel_pt_cache_invalidate(al.map->dso, machine, offset); + intel_pt_cache_invalidate(dso, machine, offset); intel_pt_log("Invalidated instruction cache for %s at %#"PRIx64"\n", - al.map->dso->long_name, addr); + dso->long_name, addr); } } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index d6da4b5e1333..8bae38c96788 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -48,7 +48,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms static struct dso *machine__kernel_dso(struct machine *machine) { - return machine->vmlinux_map->dso; + return map__dso(machine->vmlinux_map); } static void dsos__init(struct dsos *dsos) @@ -879,12 +879,13 @@ static int machine__process_ksymbol_register(struct machine *machine, struct perf_sample *sample __maybe_unused) { struct symbol *sym; + struct dso *dso; struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); if (!map) { - struct dso *dso = dso__new(event->ksymbol.name); int err; + dso = dso__new(event->ksymbol.name); if (dso) { dso->kernel = DSO_SPACE__KERNEL; map = map__new2(0, dso); @@ -896,9 +897,9 @@ static int machine__process_ksymbol_register(struct machine *machine, } if (event->ksymbol.ksym_type == PERF_RECORD_KSYMBOL_TYPE_OOL) { - map->dso->binary_type = DSO_BINARY_TYPE__OOL; - map->dso->data.file_size = event->ksymbol.len; - dso__set_loaded(map->dso); + dso->binary_type = DSO_BINARY_TYPE__OOL; + dso->data.file_size = event->ksymbol.len; + dso__set_loaded(dso); } map->start = event->ksymbol.addr; @@ -914,6 +915,8 @@ static int machine__process_ksymbol_register(struct machine *machine, dso->binary_type = DSO_BINARY_TYPE__BPF_IMAGE; dso__set_long_name(dso, "", false); } + } else { + dso = map__dso(map); } sym = symbol__new(map->map_ip(map, map->start), @@ -921,7 +924,7 @@ static int machine__process_ksymbol_register(struct machine *machine, 0, 0, event->ksymbol.name); if (!sym) return -ENOMEM; - dso__insert_symbol(map->dso, sym); + dso__insert_symbol(dso, sym); return 0; } @@ -939,9 +942,11 @@ static int machine__process_ksymbol_unregister(struct machine *machine, if (map != machine->vmlinux_map) maps__remove(machine__kernel_maps(machine), map); else { - sym = dso__find_symbol(map->dso, map->map_ip(map, map->start)); + struct dso *dso = map__dso(map); + + sym = dso__find_symbol(dso, map->map_ip(map, map->start)); if (sym) - dso__delete_symbol(map->dso, sym); + dso__delete_symbol(dso, sym); } return 0; @@ -965,6 +970,7 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event, { struct map *map = maps__find(machine__kernel_maps(machine), event->text_poke.addr); u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; + struct dso *dso = map ? map__dso(map) : NULL; if (dump_trace) perf_event__fprintf_text_poke(event, machine, stdout); @@ -977,7 +983,7 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event, return 0; } - if (map && map->dso) { + if (dso) { u8 *new_bytes = event->text_poke.bytes + event->text_poke.old_len; int ret; @@ -986,7 +992,7 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event, * must be done prior to using kernel maps. */ map__load(map); - ret = dso__data_write_cache_addr(map->dso, map, machine, + ret = dso__data_write_cache_addr(dso, map, machine, event->text_poke.addr, new_bytes, event->text_poke.new_len); @@ -1422,10 +1428,11 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid) int machine__load_kallsyms(struct machine *machine, const char *filename) { struct map *map = machine__kernel_map(machine); - int ret = __dso__load_kallsyms(map->dso, filename, map, true); + struct dso *dso = map__dso(map); + int ret = __dso__load_kallsyms(dso, filename, map, true); if (ret > 0) { - dso__set_loaded(map->dso); + dso__set_loaded(dso); /* * Since /proc/kallsyms will have multiple sessions for the * kernel, with modules between them, fixup the end of all @@ -1440,10 +1447,11 @@ int machine__load_kallsyms(struct machine *machine, const char *filename) int machine__load_vmlinux_path(struct machine *machine) { struct map *map = machine__kernel_map(machine); - int ret = dso__load_vmlinux_path(map->dso, map); + struct dso *dso = map__dso(map); + int ret = dso__load_vmlinux_path(dso, map); if (ret > 0) - dso__set_loaded(map->dso); + dso__set_loaded(dso); return ret; } @@ -1485,6 +1493,7 @@ static bool is_kmod_dso(struct dso *dso) static int maps__set_module_path(struct maps *maps, const char *path, struct kmod_path *m) { char *long_name; + struct dso *dso; struct map *map = maps__find_by_name(maps, m->name); if (map == NULL) @@ -1494,16 +1503,17 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo if (long_name == NULL) return -ENOMEM; - dso__set_long_name(map->dso, long_name, true); - dso__kernel_module_get_build_id(map->dso, ""); + dso = map__dso(map); + dso__set_long_name(dso, long_name, true); + dso__kernel_module_get_build_id(dso, ""); /* * Full name could reveal us kmod compression, so * we need to update the symtab_type if needed. */ - if (m->comp && is_kmod_dso(map->dso)) { - map->dso->symtab_type++; - map->dso->comp = m->comp; + if (m->comp && is_kmod_dso(dso)) { + dso->symtab_type++; + dso->comp = m->comp; } return 0; @@ -1602,7 +1612,7 @@ static int machine__create_module(void *arg, const char *name, u64 start, return -1; map->end = start + size; - dso__kernel_module_get_build_id(map->dso, machine->root_dir); + dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); return 0; } @@ -1788,7 +1798,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, map->end = map->start + xm->end - xm->start; if (build_id__is_defined(bid)) - dso__set_build_id(map->dso, bid); + dso__set_build_id(map__dso(map), bid); } else if (is_kernel_mmap) { const char *symbol_name = xm->name + strlen(mmap_name); @@ -2248,18 +2258,20 @@ static char *callchain_srcline(struct map_symbol *ms, u64 ip) { struct map *map = ms->map; char *srcline = NULL; + struct dso *dso; if (!map || callchain_param.key == CCKEY_FUNCTION) return srcline; - srcline = srcline__tree_find(&map->dso->srclines, ip); + dso = map__dso(map); + srcline = srcline__tree_find(&dso->srclines, ip); if (!srcline) { bool show_sym = false; bool show_addr = callchain_param.key == CCKEY_ADDRESS; - srcline = get_srcline(map->dso, map__rip_2objdump(map, ip), + srcline = get_srcline(dso, map__rip_2objdump(map, ip), ms->sym, show_sym, show_addr, ip); - srcline__tree_insert(&map->dso->srclines, ip, srcline); + srcline__tree_insert(&dso->srclines, ip, srcline); } return srcline; @@ -3039,6 +3051,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms struct map *map = ms->map; struct inline_node *inline_node; struct inline_list *ilist; + struct dso *dso; u64 addr; int ret = 1; @@ -3047,13 +3060,14 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms addr = map__map_ip(map, ip); addr = map__rip_2objdump(map, addr); + dso = map__dso(map); - inline_node = inlines__tree_find(&map->dso->inlined_nodes, addr); + inline_node = inlines__tree_find(&dso->inlined_nodes, addr); if (!inline_node) { - inline_node = dso__parse_addr_inlines(map->dso, addr, sym); + inline_node = dso__parse_addr_inlines(dso, addr, sym); if (!inline_node) return ret; - inlines__tree_insert(&map->dso->inlined_nodes, inline_node); + inlines__tree_insert(&dso->inlined_nodes, inline_node); } list_for_each_entry(ilist, &inline_node->val, list) { @@ -3330,7 +3344,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch if (sym == NULL) return NULL; - *modp = __map__is_kmodule(map) ? (char *)map->dso->short_name : NULL; + *modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL; *addrp = map->unmap_ip(map, sym->start); return sym->name; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index a99dbde656a2..90062af6675a 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -232,7 +232,7 @@ struct map *map__new2(u64 start, struct dso *dso) bool __map__is_kernel(const struct map *map) { - if (!map->dso->kernel) + if (!map__dso(map)->kernel) return false; return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) == map; } @@ -247,8 +247,9 @@ bool __map__is_extra_kernel_map(const struct map *map) bool __map__is_bpf_prog(const struct map *map) { const char *name; + struct dso *dso = map__dso(map); - if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) + if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) return true; /* @@ -256,15 +257,16 @@ bool __map__is_bpf_prog(const struct map *map) * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can * guess the type based on name. */ - name = map->dso->short_name; + name = dso->short_name; return name && (strstr(name, "bpf_prog_") == name); } bool __map__is_bpf_image(const struct map *map) { const char *name; + struct dso *dso = map__dso(map); - if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) + if (dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) return true; /* @@ -272,18 +274,20 @@ bool __map__is_bpf_image(const struct map *map) * type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can * guess the type based on name. */ - name = map->dso->short_name; + name = dso->short_name; return name && is_bpf_image(name); } bool __map__is_ool(const struct map *map) { - return map->dso && map->dso->binary_type == DSO_BINARY_TYPE__OOL; + const struct dso *dso = map__dso(map); + + return dso && dso->binary_type == DSO_BINARY_TYPE__OOL; } bool map__has_symbols(const struct map *map) { - return dso__has_symbols(map->dso); + return dso__has_symbols(map__dso(map)); } static void map__exit(struct map *map) @@ -306,18 +310,23 @@ void map__put(struct map *map) void map__fixup_start(struct map *map) { - struct rb_root_cached *symbols = &map->dso->symbols; + struct dso *dso = map__dso(map); + struct rb_root_cached *symbols = &dso->symbols; struct rb_node *nd = rb_first_cached(symbols); + if (nd != NULL) { struct symbol *sym = rb_entry(nd, struct symbol, rb_node); + map->start = sym->start; } } void map__fixup_end(struct map *map) { - struct rb_root_cached *symbols = &map->dso->symbols; + struct dso *dso = map__dso(map); + struct rb_root_cached *symbols = &dso->symbols; struct rb_node *nd = rb_last(&symbols->rb_root); + if (nd != NULL) { struct symbol *sym = rb_entry(nd, struct symbol, rb_node); map->end = sym->end; @@ -328,18 +337,19 @@ void map__fixup_end(struct map *map) int map__load(struct map *map) { - const char *name = map->dso->long_name; + struct dso *dso = map__dso(map); + const char *name = dso->long_name; int nr; - if (dso__loaded(map->dso)) + if (dso__loaded(dso)) return 0; - nr = dso__load(map->dso, map); + nr = dso__load(dso, map); if (nr < 0) { - if (map->dso->has_build_id) { + if (dso->has_build_id) { char sbuild_id[SBUILD_ID_SIZE]; - build_id__sprintf(&map->dso->bid, sbuild_id); + build_id__sprintf(&dso->bid, sbuild_id); pr_debug("%s with build id %s not found", name, sbuild_id); } else pr_debug("Failed to open %s", name); @@ -371,32 +381,36 @@ struct symbol *map__find_symbol(struct map *map, u64 addr) if (map__load(map) < 0) return NULL; - return dso__find_symbol(map->dso, addr); + return dso__find_symbol(map__dso(map), addr); } struct symbol *map__find_symbol_by_name(struct map *map, const char *name) { + struct dso *dso; + if (map__load(map) < 0) return NULL; - if (!dso__sorted_by_name(map->dso)) - dso__sort_by_name(map->dso); + dso = map__dso(map); + if (!dso__sorted_by_name(dso)) + dso__sort_by_name(dso); - return dso__find_symbol_by_name(map->dso, name); + return dso__find_symbol_by_name(dso, name); } struct map *map__clone(struct map *from) { size_t size = sizeof(struct map); struct map *map; + struct dso *dso = map__dso(from); - if (from->dso && from->dso->kernel) + if (dso && dso->kernel) size += sizeof(struct kmap); map = memdup(from, size); if (map != NULL) { refcount_set(&map->refcnt, 1); - dso__get(map->dso); + dso__get(dso); } return map; @@ -404,20 +418,23 @@ struct map *map__clone(struct map *from) size_t map__fprintf(struct map *map, FILE *fp) { + const struct dso *dso = map__dso(map); + return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map->start, map->end, map->pgoff, map->dso->name); + map->start, map->end, map->pgoff, dso->name); } size_t map__fprintf_dsoname(struct map *map, FILE *fp) { char buf[symbol_conf.pad_output_len_dso + 1]; const char *dsoname = "[unknown]"; + const struct dso *dso = map ? map__dso(map) : NULL; - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname = map->dso->long_name; + if (dso) { + if (symbol_conf.show_kernel_path && dso->long_name) + dsoname = dso->long_name; else - dsoname = map->dso->name; + dsoname = dso->name; } if (symbol_conf.pad_output_len_dso) { @@ -432,15 +449,17 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym) { if (map == NULL) return SRCLINE_UNKNOWN; - return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, true, addr); + + return get_srcline(map__dso(map), map__rip_2objdump(map, addr), sym, true, true, addr); } int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, FILE *fp) { + const struct dso *dso = map ? map__dso(map) : NULL; int ret = 0; - if (map && map->dso) { + if (dso) { char *srcline = map__srcline(map, addr, NULL); if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) ret = fprintf(fp, "%s%s", prefix, srcline); @@ -469,6 +488,7 @@ void srccode_state_free(struct srccode_state *state) u64 map__rip_2objdump(struct map *map, u64 rip) { struct kmap *kmap = __map__kmap(map); + const struct dso *dso = map__dso(map); /* * vmlinux does not have program headers for PTI entry trampolines and @@ -486,18 +506,18 @@ u64 map__rip_2objdump(struct map *map, u64 rip) } } - if (!map->dso->adjust_symbols) + if (!dso->adjust_symbols) return rip; - if (map->dso->rel) + if (dso->rel) return rip - map->pgoff; /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ - if (map->dso->kernel == DSO_SPACE__USER) - return rip + map->dso->text_offset; + if (dso->kernel == DSO_SPACE__USER) + return rip + dso->text_offset; return map->unmap_ip(map, rip) - map->reloc; } @@ -516,18 +536,20 @@ u64 map__rip_2objdump(struct map *map, u64 rip) */ u64 map__objdump_2mem(struct map *map, u64 ip) { - if (!map->dso->adjust_symbols) + const struct dso *dso = map__dso(map); + + if (!dso->adjust_symbols) return map->unmap_ip(map, ip); - if (map->dso->rel) + if (dso->rel) return map->unmap_ip(map, ip + map->pgoff); /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ - if (map->dso->kernel == DSO_SPACE__USER) - return map->unmap_ip(map, ip - map->dso->text_offset); + if (dso->kernel == DSO_SPACE__USER) + return map->unmap_ip(map, ip - dso->text_offset); return ip + map->reloc; } @@ -541,7 +563,9 @@ bool map__contains_symbol(const struct map *map, const struct symbol *sym) struct kmap *__map__kmap(struct map *map) { - if (!map->dso || !map->dso->kernel) + const struct dso *dso = map__dso(map); + + if (!dso || !dso->kernel) return NULL; return (struct kmap *)(map + 1); } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index d1a6f85fd31d..36c5add0144d 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -47,6 +47,11 @@ u64 map__unmap_ip(const struct map *map, u64 ip); /* Returns ip */ u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); +static inline struct dso *map__dso(const struct map *map) +{ + return map->dso; +} + static inline size_t map__size(const struct map *map) { return map->end - map->start; @@ -69,7 +74,7 @@ struct thread; * Note: caller must ensure map->dso is not NULL (map is loaded). */ #define map__for_each_symbol(map, pos, n) \ - dso__for_each_symbol(map->dso, pos, n) + dso__for_each_symbol(map__dso(map), pos, n) /* map__for_each_symbol_with_name - iterate over the symbols in the given map * that have the given name diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 91bb015caede..09ec6bbafcbc 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -62,6 +62,7 @@ static int __maps__insert(struct maps *maps, struct map *map) int maps__insert(struct maps *maps, struct map *map) { int err; + const struct dso *dso = map__dso(map); down_write(maps__lock(maps)); err = __maps__insert(maps, map); @@ -70,7 +71,7 @@ int maps__insert(struct maps *maps, struct map *map) ++maps->nr_maps; - if (map->dso && map->dso->kernel) { + if (dso && dso->kernel) { struct kmap *kmap = map__kmap(map); if (kmap) @@ -253,7 +254,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) printed += fprintf(fp, "Map:"); printed += map__fprintf(pos->map, fp); if (verbose > 2) { - printed += dso__fprintf(pos->map->dso, fp); + printed += dso__fprintf(map__dso(pos->map), fp); printed += fprintf(fp, "--\n"); } } @@ -307,7 +308,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) if (use_browser) { pr_debug("overlapping maps in %s (disable tui for more info)\n", - map->dso->name); + map__dso(map)->name); } else { fputs("overlapping maps:\n", fp); map__fprintf(map, fp); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index cdf5d655d84c..b26670a26005 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -165,8 +165,9 @@ static struct map *kernel_get_module_map(const char *module) maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ - const char *short_name = pos->map->dso->short_name; - u16 short_name_len = pos->map->dso->short_name_len; + struct dso *dso = map__dso(pos->map); + const char *short_name = dso->short_name; + u16 short_name_len = dso->short_name_len; if (strncmp(short_name + 1, module, short_name_len - 2) == 0 && @@ -182,13 +183,15 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user) /* Init maps of given executable or kernel */ if (user) { struct map *map; + struct dso *dso; map = dso__new_map(target); - if (map && map->dso) { - mutex_lock(&map->dso->lock); - nsinfo__put(map->dso->nsinfo); - map->dso->nsinfo = nsinfo__get(nsi); - mutex_unlock(&map->dso->lock); + dso = map ? map__dso(map) : NULL; + if (dso) { + mutex_lock(&dso->lock); + nsinfo__put(dso->nsinfo); + dso->nsinfo = nsinfo__get(nsi); + mutex_unlock(&dso->lock); } return map; } else { @@ -341,7 +344,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) snprintf(module_name, sizeof(module_name), "[%s]", module); map = maps__find_by_name(machine__kernel_maps(host_machine), module_name); if (map) { - dso = map->dso; + dso = map__dso(map); goto found; } pr_debug("Failed to find module %s.\n", module); @@ -349,7 +352,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) } map = machine__kernel_map(host_machine); - dso = map->dso; + dso = map__dso(map); if (!dso->has_build_id) dso__read_running_kernel_build_id(dso, host_machine); @@ -3737,6 +3740,7 @@ int show_available_funcs(const char *target, struct nsinfo *nsi, { struct rb_node *nd; struct map *map; + struct dso *dso; int ret; ret = init_probe_symbol_maps(user); @@ -3762,14 +3766,14 @@ int show_available_funcs(const char *target, struct nsinfo *nsi, (target) ? : "kernel"); goto end; } - if (!dso__sorted_by_name(map->dso)) - dso__sort_by_name(map->dso); + dso = map__dso(map); + if (!dso__sorted_by_name(dso)) + dso__sort_by_name(dso); /* Show all (filtered) symbols */ setup_pager(); - for (nd = rb_first_cached(&map->dso->symbol_names); nd; - nd = rb_next(nd)) { + for (nd = rb_first_cached(&dso->symbol_names); nd; nd = rb_next(nd)) { struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); if (strfilter__compare(_filter, pos->sym.name)) diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 83fd2fd0ba16..039d0365ad41 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -315,12 +315,14 @@ static SV *perl_process_callchain(struct perf_sample *sample, if (node->ms.map) { struct map *map = node->ms.map; + struct dso *dso = map ? map__dso(map) : NULL; const char *dsoname = "[unknown]"; - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname = map->dso->long_name; + + if (dso) { + if (symbol_conf.show_kernel_path && dso->long_name) + dsoname = dso->long_name; else - dsoname = map->dso->name; + dsoname = dso->name; } if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) { hv_undef(elem); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index e5cc18f6fcda..b8e5c6f61d80 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -390,12 +390,13 @@ static PyObject *get_field_numeric_entry(struct tep_event *event, static const char *get_dsoname(struct map *map) { const char *dsoname = "[unknown]"; + struct dso *dso = map ? map__dso(map) : NULL; - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname = map->dso->long_name; + if (dso) { + if (symbol_conf.show_kernel_path && dso->long_name) + dsoname = dso->long_name; else - dsoname = map->dso->name; + dsoname = dso->name; } return dsoname; @@ -780,9 +781,10 @@ static void set_sym_in_dict(PyObject *dict, struct addr_location *al, char sbuild_id[SBUILD_ID_SIZE]; if (al->map) { - pydict_set_item_string_decref(dict, dso_field, - _PyUnicode_FromString(al->map->dso->name)); - build_id__sprintf(&al->map->dso->bid, sbuild_id); + struct dso *dso = map__dso(al->map); + + pydict_set_item_string_decref(dict, dso_field, _PyUnicode_FromString(dso->name)); + build_id__sprintf(&dso->bid, sbuild_id); pydict_set_item_string_decref(dict, dso_bid_field, _PyUnicode_FromString(sbuild_id)); pydict_set_item_string_decref(dict, dso_map_start, diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 430f67e7cc82..f161589aefda 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -230,8 +230,8 @@ struct sort_entry sort_comm = { static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r) { - struct dso *dso_l = map_l ? map_l->dso : NULL; - struct dso *dso_r = map_r ? map_r->dso : NULL; + struct dso *dso_l = map_l ? map__dso(map_l) : NULL; + struct dso *dso_r = map_r ? map__dso(map_r) : NULL; const char *dso_name_l, *dso_name_r; if (!dso_l || !dso_r) @@ -257,13 +257,13 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) static int _hist_entry__dso_snprintf(struct map *map, char *bf, size_t size, unsigned int width) { - if (map && map->dso) { - const char *dso_name = verbose > 0 ? map->dso->long_name : - map->dso->short_name; - return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); - } + const struct dso *dso = map ? map__dso(map) : NULL; + const char *dso_name = "[unknown]"; + + if (dso) + dso_name = verbose > 0 ? dso->long_name : dso->short_name; - return repsep_snprintf(bf, size, "%-*.*s", width, width, "[unknown]"); + return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); } static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf, @@ -279,7 +279,7 @@ static int hist_entry__dso_filter(struct hist_entry *he, int type, const void *a if (type != HIST_FILTER__DSO) return -1; - return dso && (!he->ms.map || he->ms.map->dso != dso); + return dso && (!he->ms.map || map__dso(he->ms.map) != dso); } struct sort_entry sort_dso = { @@ -359,11 +359,11 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms, size_t ret = 0; if (verbose > 0) { - char o = map ? dso__symtab_origin(map->dso) : '!'; + struct dso *dso = map ? map__dso(map) : NULL; + char o = dso ? dso__symtab_origin(dso) : '!'; u64 rip = ip; - if (map && map->dso && map->dso->kernel - && map->dso->adjust_symbols) + if (dso && dso->kernel && dso->adjust_symbols) rip = map->unmap_ip(map, ip); ret += repsep_snprintf(bf, size, "%-#*llx %c ", @@ -641,7 +641,7 @@ static char *hist_entry__get_srcfile(struct hist_entry *e) if (!map) return no_srcfile; - sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip), + sf = __get_srcline(map__dso(map), map__rip_2objdump(map, e->ip), e->ms.sym, false, true, true, e->ip); if (!strcmp(sf, SRCLINE_UNKNOWN)) return no_srcfile; @@ -982,7 +982,7 @@ static int hist_entry__dso_from_filter(struct hist_entry *he, int type, return -1; return dso && (!he->branch_info || !he->branch_info->from.ms.map || - he->branch_info->from.ms.map->dso != dso); + map__dso(he->branch_info->from.ms.map) != dso); } static int64_t @@ -1014,7 +1014,7 @@ static int hist_entry__dso_to_filter(struct hist_entry *he, int type, return -1; return dso && (!he->branch_info || !he->branch_info->to.ms.map || - he->branch_info->to.ms.map->dso != dso); + map__dso(he->branch_info->to.ms.map) != dso); } static int64_t @@ -1506,6 +1506,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right) { u64 l, r; struct map *l_map, *r_map; + struct dso *l_dso, *r_dso; int rc; if (!left->mem_info) return -1; @@ -1525,7 +1526,9 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right) if (!l_map) return -1; if (!r_map) return 1; - rc = dso__cmp_id(l_map->dso, r_map->dso); + l_dso = map__dso(l_map); + r_dso = map__dso(r_map); + rc = dso__cmp_id(l_dso, r_dso); if (rc) return rc; /* @@ -1537,9 +1540,8 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right) */ if ((left->cpumode != PERF_RECORD_MISC_KERNEL) && - (!(l_map->flags & MAP_SHARED)) && - !l_map->dso->id.maj && !l_map->dso->id.min && - !l_map->dso->id.ino && !l_map->dso->id.ino_generation) { + (!(l_map->flags & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min && + !l_dso->id.ino && !l_dso->id.ino_generation) { /* userspace anonymous */ if (left->thread->pid_ > right->thread->pid_) return -1; @@ -1567,6 +1569,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf, if (he->mem_info) { struct map *map = he->mem_info->daddr.ms.map; + struct dso *dso = map__dso(map); addr = cl_address(he->mem_info->daddr.al_addr, chk_double_cl); ms = &he->mem_info->daddr.ms; @@ -1575,8 +1578,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf, if ((he->cpumode != PERF_RECORD_MISC_KERNEL) && map && !(map->prot & PROT_EXEC) && (map->flags & MAP_SHARED) && - (map->dso->id.maj || map->dso->id.min || - map->dso->id.ino || map->dso->id.ino_generation)) + (dso->id.maj || dso->id.min || dso->id.ino || dso->id.ino_generation)) level = 's'; else if (!map) level = 'X'; @@ -2072,9 +2074,8 @@ sort__dso_size_cmp(struct hist_entry *left, struct hist_entry *right) static int _hist_entry__dso_size_snprintf(struct map *map, char *bf, size_t bf_size, unsigned int width) { - if (map && map->dso) - return repsep_snprintf(bf, bf_size, "%*d", width, - map__size(map)); + if (map && map__dso(map)) + return repsep_snprintf(bf, bf_size, "%*d", width, map__size(map)); return repsep_snprintf(bf, bf_size, "%*s", width, "unknown"); } diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 3084e556d3eb..561372869792 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1435,7 +1435,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, *curr_mapp = curr_map; *curr_dsop = curr_dso; } else - *curr_dsop = curr_map->dso; + *curr_dsop = map__dso(curr_map); return 0; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 316b63fb5691..a1c85c22676f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -791,6 +791,7 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) *root = RB_ROOT_CACHED; while (next) { + struct dso *curr_map_dso; char *module; pos = rb_entry(next, struct symbol, rb_node); @@ -808,13 +809,13 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) symbol__delete(pos); continue; } - + curr_map_dso = map__dso(curr_map); pos->start -= curr_map->start - curr_map->pgoff; if (pos->end > curr_map->end) pos->end = curr_map->end; if (pos->end) pos->end -= curr_map->start - curr_map->pgoff; - symbols__insert(&curr_map->dso->symbols, pos); + symbols__insert(&curr_map_dso->symbols, pos); ++count; } @@ -856,12 +857,14 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, module = strchr(pos->name, '\t'); if (module) { + struct dso *curr_map_dso; + if (!symbol_conf.use_modules) goto discard_symbol; *module++ = '\0'; - - if (strcmp(curr_map->dso->short_name, module)) { + curr_map_dso = map__dso(curr_map); + if (strcmp(curr_map_dso->short_name, module)) { if (curr_map != initial_map && dso->kernel == DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { @@ -872,7 +875,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, * symbols are in its kmap. Mark it as * loaded. */ - dso__set_loaded(curr_map->dso); + dso__set_loaded(curr_map_dso); } curr_map = maps__find_by_name(kmaps, module); @@ -884,8 +887,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, curr_map = initial_map; goto discard_symbol; } - - if (curr_map->dso->loaded && + curr_map_dso = map__dso(curr_map); + if (curr_map_dso->loaded && !machine__is_default_guest(machine)) goto discard_symbol; } @@ -954,8 +957,10 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, } add_symbol: if (curr_map != initial_map) { + struct dso *curr_map_dso = map__dso(curr_map); + rb_erase_cached(&pos->rb_node, root); - symbols__insert(&curr_map->dso->symbols, pos); + symbols__insert(&curr_map_dso->symbols, pos); ++moved; } else ++count; @@ -969,7 +974,7 @@ discard_symbol: if (curr_map != initial_map && dso->kernel == DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(maps__machine(kmaps))) { - dso__set_loaded(curr_map->dso); + dso__set_loaded(map__dso(curr_map)); } return count + moved; @@ -1143,13 +1148,14 @@ static int do_validate_kcore_modules(const char *filename, struct maps *kmaps) maps__for_each_entry(kmaps, old_node) { struct map *old_map = old_node->map; struct module_info *mi; + struct dso *dso; if (!__map__is_kmodule(old_map)) { continue; } - + dso = map__dso(old_map); /* Module must be in memory at the same address */ - mi = find_module(old_map->dso->short_name, &modules); + mi = find_module(dso->short_name, &modules); if (!mi || mi->start != old_map->start) { err = -EINVAL; goto out; @@ -2047,14 +2053,17 @@ out: static int map__strcmp(const void *a, const void *b) { - const struct map *ma = *(const struct map **)a, *mb = *(const struct map **)b; - return strcmp(ma->dso->short_name, mb->dso->short_name); + const struct dso *dso_a = map__dso(*(const struct map **)a); + const struct dso *dso_b = map__dso(*(const struct map **)b); + + return strcmp(dso_a->short_name, dso_b->short_name); } static int map__strcmp_name(const void *name, const void *b) { - const struct map *map = *(const struct map **)b; - return strcmp(name, map->dso->short_name); + const struct dso *dso = map__dso(*(const struct map **)b); + + return strcmp(name, dso->short_name); } void __maps__sort_by_name(struct maps *maps) @@ -2111,10 +2120,13 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) down_read(maps__lock(maps)); - if (maps->last_search_by_name && - strcmp(maps->last_search_by_name->dso->short_name, name) == 0) { - map = maps->last_search_by_name; - goto out_unlock; + if (maps->last_search_by_name) { + const struct dso *dso = map__dso(maps->last_search_by_name); + + if (strcmp(dso->short_name, name) == 0) { + map = maps->last_search_by_name; + goto out_unlock; + } } /* * If we have maps->maps_by_name, then the name isn't in the rbtree, @@ -2127,8 +2139,11 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) /* Fallback to traversing the rbtree... */ maps__for_each_entry(maps, rb_node) { + struct dso *dso; + map = rb_node->map; - if (strcmp(map->dso->short_name, name) == 0) { + dso = map__dso(map); + if (strcmp(dso->short_name, name) == 0) { maps->last_search_by_name = map; goto out_unlock; } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 57b95c1d7e39..fbd1a882b013 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -693,12 +693,14 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t maps__for_each_entry(maps, pos) { struct map *map = pos->map; + struct dso *dso; if (!__map__is_kmodule(map)) continue; + dso = map__dso(map); if (symbol_conf.buildid_mmap2) { - size = PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); + size = PERF_ALIGN(dso->long_name_len + 1, sizeof(u64)); event->mmap2.header.type = PERF_RECORD_MMAP2; event->mmap2.header.size = (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); @@ -708,12 +710,11 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t event->mmap2.len = map->end - map->start; event->mmap2.pid = machine->pid; - memcpy(event->mmap2.filename, map->dso->long_name, - map->dso->long_name_len + 1); + memcpy(event->mmap2.filename, dso->long_name, dso->long_name_len + 1); perf_record_mmap2__read_build_id(&event->mmap2, machine, false); } else { - size = PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); + size = PERF_ALIGN(dso->long_name_len + 1, sizeof(u64)); event->mmap.header.type = PERF_RECORD_MMAP; event->mmap.header.size = (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); @@ -723,8 +724,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t event->mmap.len = map->end - map->start; event->mmap.pid = machine->pid; - memcpy(event->mmap.filename, map->dso->long_name, - map->dso->long_name_len + 1); + memcpy(event->mmap.filename, dso->long_name, dso->long_name_len + 1); } if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 292585a52281..bb7a2ce82d46 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -448,23 +448,27 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa int thread__memcpy(struct thread *thread, struct machine *machine, void *buf, u64 ip, int len, bool *is64bit) { - u8 cpumode = PERF_RECORD_MISC_USER; - struct addr_location al; - long offset; + u8 cpumode = PERF_RECORD_MISC_USER; + struct addr_location al; + struct dso *dso; + long offset; - if (machine__kernel_ip(machine, ip)) - cpumode = PERF_RECORD_MISC_KERNEL; + if (machine__kernel_ip(machine, ip)) + cpumode = PERF_RECORD_MISC_KERNEL; - if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso || - al.map->dso->data.status == DSO_DATA_STATUS_ERROR || - map__load(al.map) < 0) - return -1; + if (!thread__find_map(thread, cpumode, ip, &al)) + return -1; - offset = al.map->map_ip(al.map, ip); - if (is64bit) - *is64bit = al.map->dso->is_64_bit; + dso = map__dso(al.map); - return dso__data_read_offset(al.map->dso, machine, offset, buf, len); + if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0) + return -1; + + offset = al.map->map_ip(al.map, ip); + if (is64bit) + *is64bit = dso->is_64_bit; + + return dso__data_read_offset(dso, machine, offset, buf, len); } void thread__free_stitch_list(struct thread *thread) diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 94aa40f6e348..c8cba9d4bfd9 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -52,7 +52,7 @@ static int __report_module(struct addr_location *al, u64 ip, thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al); if (al->map) - dso = al->map->dso; + dso = map__dso(al->map); if (!dso) return 0; @@ -134,17 +134,17 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr, { struct addr_location al; ssize_t size; + struct dso *dso; if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) { pr_debug("unwind: no map for %lx\n", (unsigned long)addr); return -1; } - - if (!al.map->dso) + dso = map__dso(al.map); + if (!dso) return -1; - size = dso__data_read_addr(al.map->dso, al.map, ui->machine, - addr, (u8 *) data, sizeof(*data)); + size = dso__data_read_addr(dso, al.map, ui->machine, addr, (u8 *) data, sizeof(*data)); return !(size == sizeof(*data)); } diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index c487a249b33c..108f7b1697a7 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -328,7 +328,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui, maps__for_each_entry(ui->thread->maps, map_node) { struct map *map = map_node->map; - if (map->dso == dso && map->start < base_addr) + if (map__dso(map) == dso && map->start < base_addr) base_addr = map->start; } base_addr -= dso->data.elf_base_addr; @@ -424,19 +424,23 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, { struct unwind_info *ui = arg; struct map *map; + struct dso *dso; unw_dyn_info_t di; u64 table_data, segbase, fde_count; int ret = -EINVAL; map = find_map(ip, ui); - if (!map || !map->dso) + if (!map) return -EINVAL; - pr_debug("unwind: find_proc_info dso %s\n", map->dso->name); + dso = map__dso(map); + if (!dso) + return -EINVAL; + + pr_debug("unwind: find_proc_info dso %s\n", dso->name); /* Check the .eh_frame section for unwinding info */ - if (!read_unwind_spec_eh_frame(map->dso, ui, - &table_data, &segbase, &fde_count)) { + if (!read_unwind_spec_eh_frame(dso, ui, &table_data, &segbase, &fde_count)) { memset(&di, 0, sizeof(di)); di.format = UNW_INFO_FORMAT_REMOTE_TABLE; di.start_ip = map->start; @@ -452,16 +456,16 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, #ifndef NO_LIBUNWIND_DEBUG_FRAME /* Check the .debug_frame section for unwinding info */ if (ret < 0 && - !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { - int fd = dso__data_get_fd(map->dso, ui->machine); - int is_exec = elf_is_exec(fd, map->dso->name); + !read_unwind_spec_debug_frame(dso, ui->machine, &segbase)) { + int fd = dso__data_get_fd(dso, ui->machine); + int is_exec = elf_is_exec(fd, dso->name); unw_word_t base = is_exec ? 0 : map->start; const char *symfile; if (fd >= 0) - dso__data_put_fd(map->dso); + dso__data_put_fd(dso); - symfile = map->dso->symsrc_filename ?: map->dso->name; + symfile = dso->symsrc_filename ?: dso->name; memset(&di, 0, sizeof(di)); if (dwarf_find_debug_frame(0, &di, ip, base, symfile, @@ -513,6 +517,7 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, unw_word_t *data) { struct map *map; + struct dso *dso; ssize_t size; map = find_map(addr, ui); @@ -521,10 +526,12 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, return -1; } - if (!map->dso) + dso = map__dso(map); + + if (!dso) return -1; - size = dso__data_read_addr(map->dso, map, ui->machine, + size = dso__data_read_addr(dso, map, ui->machine, addr, (u8 *) data, sizeof(*data)); return !(size == sizeof(*data)); diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 42528ade513e..4378daaafcd3 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -22,6 +22,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized const char *arch; enum dso_type dso_type; struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops; + struct dso *dso = map__dso(map); struct machine *machine; int err; @@ -29,8 +30,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized return 0; if (maps__addr_space(maps)) { - pr_debug("unwind: thread map already set, dso=%s\n", - map->dso->name); + pr_debug("unwind: thread map already set, dso=%s\n", dso->name); if (initialized) *initialized = true; return 0; @@ -41,7 +41,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized if (!machine->env || !machine->env->arch) goto out_register; - dso_type = dso__type(map->dso, machine); + dso_type = dso__type(dso, machine); if (dso_type == DSO__TYPE_UNKNOWN) return 0; diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 835c39efb80d..ec777ee11493 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -147,7 +147,7 @@ static enum dso_type machine__thread_dso_type(struct machine *machine, struct map_rb_node *rb_node; maps__for_each_entry(thread->maps, rb_node) { - struct dso *dso = rb_node->map->dso; + struct dso *dso = map__dso(rb_node->map); if (!dso || dso->long_name[0] != '/') continue; -- cgit v1.2.3 From e5116f46d44b72ede59a6923829f68a8b8f84e76 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 20 Mar 2023 14:22:36 -0700 Subject: perf map: Add accessor for start and end Later changes will add reference count checking for struct map, start and end are frequently accessed variables. Add an accessor so that the reference count check is only necessary in one place. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230320212248.1175731-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/tests/dwarf-unwind.c | 2 +- tools/perf/arch/arm64/tests/dwarf-unwind.c | 2 +- tools/perf/arch/powerpc/tests/dwarf-unwind.c | 2 +- tools/perf/arch/powerpc/util/skip-callchain-idx.c | 2 +- tools/perf/arch/x86/tests/dwarf-unwind.c | 2 +- tools/perf/arch/x86/util/event.c | 4 +- tools/perf/builtin-buildid-list.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/tests/code-reading.c | 8 ++-- tools/perf/tests/maps.c | 4 +- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 14 +++---- tools/perf/util/annotate.c | 4 +- tools/perf/util/dlfilter.c | 8 ++-- tools/perf/util/intel-pt.c | 8 ++-- tools/perf/util/machine.c | 14 +++---- tools/perf/util/map.c | 8 ++-- tools/perf/util/map.h | 12 +++++- tools/perf/util/maps.c | 30 +++++++------- tools/perf/util/probe-event.c | 4 +- .../util/scripting-engines/trace-event-python.c | 6 +-- tools/perf/util/symbol-elf.c | 8 ++-- tools/perf/util/symbol.c | 48 +++++++++++----------- tools/perf/util/symbol_fprintf.c | 2 +- tools/perf/util/synthetic-events.c | 16 ++++---- tools/perf/util/unwind-libdw.c | 6 +-- tools/perf/util/unwind-libunwind-local.c | 15 +++---- 29 files changed, 125 insertions(+), 114 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c index ccfa87055c4a..566fb6c0eae7 100644 --- a/tools/perf/arch/arm/tests/dwarf-unwind.c +++ b/tools/perf/arch/arm/tests/dwarf-unwind.c @@ -33,7 +33,7 @@ static int sample_ustack(struct perf_sample *sample, return -1; } - stack_size = map->end - sp; + stack_size = map__end(map) - sp; stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/arch/arm64/tests/dwarf-unwind.c b/tools/perf/arch/arm64/tests/dwarf-unwind.c index 46147a483049..90a7ef293ce7 100644 --- a/tools/perf/arch/arm64/tests/dwarf-unwind.c +++ b/tools/perf/arch/arm64/tests/dwarf-unwind.c @@ -33,7 +33,7 @@ static int sample_ustack(struct perf_sample *sample, return -1; } - stack_size = map->end - sp; + stack_size = map__end(map) - sp; stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/arch/powerpc/tests/dwarf-unwind.c b/tools/perf/arch/powerpc/tests/dwarf-unwind.c index c9cb4b059392..32fffb593fbf 100644 --- a/tools/perf/arch/powerpc/tests/dwarf-unwind.c +++ b/tools/perf/arch/powerpc/tests/dwarf-unwind.c @@ -33,7 +33,7 @@ static int sample_ustack(struct perf_sample *sample, return -1; } - stack_size = map->end - sp; + stack_size = map__end(map) - sp; stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index fe0e4530673c..b7223feec770 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c @@ -262,7 +262,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) return skip_slot; } - rc = check_return_addr(dso, al.map->start, ip); + rc = check_return_addr(dso, map__start(al.map), ip); pr_debug("[DSO %s, sym %s, ip 0x%" PRIx64 "] rc %d\n", dso->long_name, al.sym->name, ip, rc); diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index a54dea7c112f..497593be80f2 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -33,7 +33,7 @@ static int sample_ustack(struct perf_sample *sample, return -1; } - stack_size = map->end - sp; + stack_size = map__end(map) - sp; stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index 17bf60babfbd..3b2475707756 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -59,8 +59,8 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, event->mmap.header.size = size; - event->mmap.start = map->start; - event->mmap.len = map->end - map->start; + event->mmap.start = map__start(map); + event->mmap.len = map__size(map); event->mmap.pgoff = map->pgoff; event->mmap.pid = machine->pid; diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index cad9ed44ce7c..eea28cbcc0b7 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -30,7 +30,7 @@ static int buildid__map_cb(struct map *map, void *arg __maybe_unused) memset(bid_buf, 0, sizeof(bid_buf)); if (dso->has_build_id) build_id__sprintf(&dso->bid, bid_buf); - printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map->start, map->end); + printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map__start(map), map__end(map)); if (dso->long_name != NULL) { printf(" %s", dso->long_name); } else if (dso->short_name != NULL) { diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ff239b89e4d0..2a6e2cee5e0d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -851,7 +851,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) const struct dso *dso = map__dso(map); printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n", - indent, "", map->start, map->end, + indent, "", map__start(map), map__end(map), map->prot & PROT_READ ? 'r' : '-', map->prot & PROT_WRITE ? 'w' : '-', map->prot & PROT_EXEC ? 'x' : '-', diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 27fd9c203600..1d078106abc4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1209,7 +1209,7 @@ static int ip__fprintf_sym(uint64_t addr, struct thread *thread, if (al.addr < al.sym->end) off = al.addr - al.sym->start; else - off = al.addr - al.map->start - al.sym->start; + off = al.addr - map__start(al.map) - al.sym->start; printed += fprintf(fp, "\t%s", al.sym->name); if (off) printed += fprintf(fp, "%+d", off); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index babfc163efe2..b803af4329d1 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -183,7 +183,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) "Not all samples will be on the annotation output.\n\n" "Please report to linux-kernel@vger.kernel.org\n", ip, dso->long_name, dso__symtab_origin(dso), - map->start, map->end, sym->start, sym->end, + map__start(map), map__end(map), sym->start, sym->end, sym->binding == STB_GLOBAL ? 'g' : sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, err ? "[unknown]" : uts.machine, diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 936c61546e64..1545fcaa95c6 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -265,8 +265,8 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, len = BUFSZ; /* Do not go off the map */ - if (addr + len > al.map->end) - len = al.map->end - addr; + if (addr + len > map__end(al.map)) + len = map__end(al.map) - addr; /* Read the object code using perf */ ret_len = dso__data_read_offset(dso, maps__machine(thread->maps), @@ -291,7 +291,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, size_t d; for (d = 0; d < state->done_cnt; d++) { - if (state->done[d] == al.map->start) { + if (state->done[d] == map__start(al.map)) { pr_debug("kcore map tested already"); pr_debug(" - skipping\n"); goto out; @@ -301,7 +301,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, pr_debug("Too many kcore maps - skipping\n"); goto out; } - state->done[state->done_cnt++] = al.map->start; + state->done[state->done_cnt++] = map__start(al.map); } objdump_name = dso->long_name; diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index ae7028fbf79e..fd0c464fcf95 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -24,8 +24,8 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma if (i > 0) TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i == size)); - TEST_ASSERT_VAL("wrong map start", map->start == merged[i].start); - TEST_ASSERT_VAL("wrong map end", map->end == merged[i].end); + TEST_ASSERT_VAL("wrong map start", map__start(map) == merged[i].start); + TEST_ASSERT_VAL("wrong map end", map__end(map) == merged[i].end); TEST_ASSERT_VAL("wrong map name", !strcmp(map__dso(map)->name, merged[i].name)); TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) == 1); diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index a4301fc7b770..5cc4644e353d 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -202,7 +202,7 @@ static int mmap_events(synth_cb synth) break; } - pr_debug("map %p, addr %" PRIx64 "\n", al.map, al.map->start); + pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map)); } machine__delete_threads(machine); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index c614c2db7e89..0a75623172c2 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -267,7 +267,7 @@ next_pair: continue; } - } else if (mem_start == kallsyms.vmlinux_map->end) { + } else if (mem_start == map__end(kallsyms.vmlinux_map)) { /* * Ignore aliases to _etext, i.e. to the end of the kernel text area, * such as __indirect_thunk_end. @@ -319,14 +319,14 @@ next_pair: maps__for_each_entry(maps, rb_node) { struct map *pair, *map = rb_node->map; - mem_start = vmlinux_map->unmap_ip(vmlinux_map, map->start); - mem_end = vmlinux_map->unmap_ip(vmlinux_map, map->end); + mem_start = vmlinux_map->unmap_ip(vmlinux_map, map__start(map)); + mem_end = vmlinux_map->unmap_ip(vmlinux_map, map__end(map)); pair = maps__find(kallsyms.kmaps, mem_start); if (pair == NULL || pair->priv) continue; - if (pair->start == mem_start) { + if (map__start(pair) == mem_start) { struct dso *dso = map__dso(map); if (!header_printed) { @@ -335,10 +335,10 @@ next_pair: } pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map->start, map->end, map->pgoff, dso->name); - if (mem_end != pair->end) + map__start(map), map__end(map), map->pgoff, dso->name); + if (mem_end != map__end(pair)) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, - pair->start, pair->end, pair->pgoff); + map__start(pair), map__end(pair), pair->pgoff); pr_info(" %s\n", dso->name); pair->priv = 1; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 84100ca5f306..b9cff782d7df 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1008,13 +1008,13 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, if (start && (start->ms.sym == ams->ms.sym || (ams->ms.sym && - start->addr == ams->ms.sym->start + ams->ms.map->start))) + start->addr == ams->ms.sym->start + map__start(ams->ms.map)))) saddr = start->al_addr; if (saddr == 0) pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n", ams->addr, start ? start->addr : 0, - ams->ms.sym ? ams->ms.sym->start + ams->ms.map->start : 0, + ams->ms.sym ? ams->ms.sym->start + map__start(ams->ms.map) : 0, saddr); err = symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles); if (err) diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index 8a7ffe0d805a..fe401fa4be02 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -51,7 +51,7 @@ static void al_to_d_al(struct addr_location *al, struct perf_dlfilter_al *d_al) if (al->addr < sym->end) d_al->symoff = al->addr - sym->start; else - d_al->symoff = al->addr - al->map->start - sym->start; + d_al->symoff = al->addr - map__start(al->map) - sym->start; d_al->sym_binding = sym->binding; } else { d_al->sym = NULL; @@ -268,7 +268,7 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len) map = al->map; - if (map && ip >= map->start && ip < map->end && + if (map && ip >= map__start(map) && ip < map__end(map) && machine__kernel_ip(d->machine, ip) == machine__kernel_ip(d->machine, d->sample->ip)) goto have_map; @@ -279,8 +279,8 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len) map = a.map; have_map: offset = map->map_ip(map, ip); - if (ip + len >= map->end) - len = map->end - ip; + if (ip + len >= map__end(map)) + len = map__end(map) - ip; return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); } diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 8cec88e09792..a2e62daa708e 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -887,7 +887,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, goto out_no_cache; } - if (*ip >= al.map->end) + if (*ip >= map__end(al.map)) break; offset += intel_pt_insn->length; @@ -2750,7 +2750,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip) if (sym->binding == STB_GLOBAL && !strcmp(sym->name, "__switch_to")) { ip = map->unmap_ip(map, sym->start); - if (ip >= map->start && ip < map->end) { + if (ip >= map__start(map) && ip < map__end(map)) { switch_ip = ip; break; } @@ -2768,7 +2768,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip) for (sym = start; sym; sym = dso__next_symbol(sym)) { if (!strcmp(sym->name, ptss)) { ip = map->unmap_ip(map, sym->start); - if (ip >= map->start && ip < map->end) { + if (ip >= map__start(map) && ip < map__end(map)) { *ptss_ip = ip; break; } @@ -3356,7 +3356,7 @@ static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt, static int intel_pt_find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al) { - if (!al->map || addr < al->map->start || addr >= al->map->end) { + if (!al->map || addr < map__start(al->map) || addr >= map__end(al->map)) { if (!thread__find_map(thread, cpumode, addr, al)) return -1; } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 8bae38c96788..7852b97da10a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -903,7 +903,7 @@ static int machine__process_ksymbol_register(struct machine *machine, } map->start = event->ksymbol.addr; - map->end = map->start + event->ksymbol.len; + map->end = map__start(map) + event->ksymbol.len; err = maps__insert(machine__kernel_maps(machine), map); map__put(map); if (err) @@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct machine *machine, dso = map__dso(map); } - sym = symbol__new(map->map_ip(map, map->start), + sym = symbol__new(map->map_ip(map, map__start(map)), event->ksymbol.len, 0, 0, event->ksymbol.name); if (!sym) @@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine, else { struct dso *dso = map__dso(map); - sym = dso__find_symbol(dso, map->map_ip(map, map->start)); + sym = dso__find_symbol(dso, map->map_ip(map, map__start(map))); if (sym) dso__delete_symbol(dso, sym); } @@ -1217,7 +1217,7 @@ int machine__create_extra_kernel_map(struct machine *machine, if (!err) { pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", - kmap->name, map->start, map->end); + kmap->name, map__start(map), map__end(map)); } map__put(map); @@ -1722,7 +1722,7 @@ int machine__create_kernel_maps(struct machine *machine) struct map_rb_node *next = map_rb_node__next(rb_node); if (next) - machine__set_kernel_mmap(machine, start, next->map->start); + machine__set_kernel_mmap(machine, start, map__start(next->map)); } out_put: @@ -1795,7 +1795,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, if (map == NULL) goto out_problem; - map->end = map->start + xm->end - xm->start; + map->end = map__start(map) + xm->end - xm->start; if (build_id__is_defined(bid)) dso__set_build_id(map__dso(map), bid); @@ -3293,7 +3293,7 @@ int machine__get_kernel_start(struct machine *machine) * kernel_start = 1ULL << 63 for x86_64. */ if (!err && !machine__is(machine, "x86_64")) - machine->kernel_start = map->start; + machine->kernel_start = map__start(map); } return err; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 90062af6675a..416fc449bde8 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -421,7 +421,7 @@ size_t map__fprintf(struct map *map, FILE *fp) const struct dso *dso = map__dso(map); return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map->start, map->end, map->pgoff, dso->name); + map__start(map), map__end(map), map->pgoff, dso->name); } size_t map__fprintf_dsoname(struct map *map, FILE *fp) @@ -558,7 +558,7 @@ bool map__contains_symbol(const struct map *map, const struct symbol *sym) { u64 ip = map->unmap_ip(map, sym->start); - return ip >= map->start && ip < map->end; + return ip >= map__start(map) && ip < map__end(map); } struct kmap *__map__kmap(struct map *map) @@ -592,12 +592,12 @@ struct maps *map__kmaps(struct map *map) u64 map__map_ip(const struct map *map, u64 ip) { - return ip - map->start + map->pgoff; + return ip - map__start(map) + map->pgoff; } u64 map__unmap_ip(const struct map *map, u64 ip) { - return ip + map->start - map->pgoff; + return ip + map__start(map) - map->pgoff; } u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 36c5add0144d..16646b94fa3a 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -52,9 +52,19 @@ static inline struct dso *map__dso(const struct map *map) return map->dso; } +static inline u64 map__start(const struct map *map) +{ + return map->start; +} + +static inline u64 map__end(const struct map *map) +{ + return map->end; +} + static inline size_t map__size(const struct map *map) { - return map->end - map->start; + return map__end(map) - map__start(map); } /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 09ec6bbafcbc..21010a2b8e16 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -34,7 +34,7 @@ static int __maps__insert(struct maps *maps, struct map *map) { struct rb_node **p = &maps__entries(maps)->rb_node; struct rb_node *parent = NULL; - const u64 ip = map->start; + const u64 ip = map__start(map); struct map_rb_node *m, *new_rb_node; new_rb_node = malloc(sizeof(*new_rb_node)); @@ -47,7 +47,7 @@ static int __maps__insert(struct maps *maps, struct map *map) while (*p != NULL) { parent = *p; m = rb_entry(parent, struct map_rb_node, rb_node); - if (ip < m->map->start) + if (ip < map__start(m->map)) p = &(*p)->rb_left; else p = &(*p)->rb_right; @@ -229,7 +229,7 @@ out: int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) { - if (ams->addr < ams->ms.map->start || ams->addr >= ams->ms.map->end) { + if (ams->addr < map__start(ams->ms.map) || ams->addr >= map__end(ams->ms.map)) { if (maps == NULL) return -1; ams->ms.map = maps__find(maps, ams->addr); @@ -283,9 +283,9 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) while (next) { struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node); - if (pos->map->end > map->start) { + if (map__end(pos->map) > map__start(map)) { first = next; - if (pos->map->start <= map->start) + if (map__start(pos->map) <= map__start(map)) break; next = next->rb_left; } else @@ -301,7 +301,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (pos->map->start >= map->end) + if (map__start(pos->map) >= map__end(map)) break; if (verbose >= 2) { @@ -321,7 +321,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map->start > pos->map->start) { + if (map__start(map) > map__start(pos->map)) { struct map *before = map__clone(pos->map); if (before == NULL) { @@ -329,7 +329,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) goto put_map; } - before->end = map->start; + before->end = map__start(map); err = __maps__insert(maps, before); if (err) goto put_map; @@ -339,7 +339,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) map__put(before); } - if (map->end < pos->map->end) { + if (map__end(map) < map__end(pos->map)) { struct map *after = map__clone(pos->map); if (after == NULL) { @@ -347,10 +347,10 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) goto put_map; } - after->start = map->end; - after->pgoff += map->end - pos->map->start; - assert(pos->map->map_ip(pos->map, map->end) == - after->map_ip(after, map->end)); + after->start = map__end(map); + after->pgoff += map__end(map) - map__start(pos->map); + assert(pos->map->map_ip(pos->map, map__end(map)) == + after->map_ip(after, map__end(map))); err = __maps__insert(maps, after); if (err) goto put_map; @@ -430,9 +430,9 @@ struct map *maps__find(struct maps *maps, u64 ip) p = maps__entries(maps)->rb_node; while (p != NULL) { m = rb_entry(p, struct map_rb_node, rb_node); - if (ip < m->map->start) + if (ip < map__start(m->map)) p = p->rb_left; - else if (ip >= m->map->end) + else if (ip >= map__end(m->map)) p = p->rb_right; else goto out; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b26670a26005..4d9dbeeb6014 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -143,7 +143,7 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr, return -ENOENT; *addr = map->unmap_ip(map, sym->start) - ((reloc) ? 0 : map->reloc) - - ((reladdr) ? map->start : 0); + ((reladdr) ? map__start(map) : 0); } return 0; } @@ -257,7 +257,7 @@ static bool kprobe_warn_out_range(const char *symbol, u64 address) map = kernel_get_module_map(NULL); if (map) { - ret = address <= map->start || map->end < address; + ret = address <= map__start(map) || map__end(map) < address; if (ret) pr_warning("%s is out of .text, skip it.\n", symbol); map__put(map); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index b8e5c6f61d80..cbf09eaf3734 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -409,7 +409,7 @@ static unsigned long get_offset(struct symbol *sym, struct addr_location *al) if (al->addr < sym->end) offset = al->addr - sym->start; else - offset = al->addr - al->map->start - sym->start; + offset = al->addr - map__start(al->map) - sym->start; return offset; } @@ -788,9 +788,9 @@ static void set_sym_in_dict(PyObject *dict, struct addr_location *al, pydict_set_item_string_decref(dict, dso_bid_field, _PyUnicode_FromString(sbuild_id)); pydict_set_item_string_decref(dict, dso_map_start, - PyLong_FromUnsignedLong(al->map->start)); + PyLong_FromUnsignedLong(map__start(al->map))); pydict_set_item_string_decref(dict, dso_map_end, - PyLong_FromUnsignedLong(al->map->end)); + PyLong_FromUnsignedLong(map__end(al->map))); } if (al->sym) { pydict_set_item_string_decref(dict, sym_field, diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 561372869792..e715869eab8a 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1355,7 +1355,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, if (*remap_kernel && dso->kernel && !kmodule) { *remap_kernel = false; map->start = shdr->sh_addr + ref_reloc(kmap); - map->end = map->start + shdr->sh_size; + map->end = map__start(map) + shdr->sh_size; map->pgoff = shdr->sh_offset; map->map_ip = map__map_ip; map->unmap_ip = map__unmap_ip; @@ -1397,7 +1397,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, u64 start = sym->st_value; if (kmodule) - start += map->start + shdr->sh_offset; + start += map__start(map) + shdr->sh_offset; curr_dso = dso__new(dso_name); if (curr_dso == NULL) @@ -1415,7 +1415,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, if (adjust_kernel_syms) { curr_map->start = shdr->sh_addr + ref_reloc(kmap); - curr_map->end = curr_map->start + shdr->sh_size; + curr_map->end = map__start(curr_map) + shdr->sh_size; curr_map->pgoff = shdr->sh_offset; } else { curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; @@ -1536,7 +1536,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, * attempted to prelink vdso to its virtual address. */ if (dso__is_vdso(dso)) - map->reloc = map->start - dso->text_offset; + map->reloc = map__start(map) - dso->text_offset; dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap); /* diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a1c85c22676f..b91deb177091 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -278,8 +278,8 @@ void maps__fixup_end(struct maps *maps) down_write(maps__lock(maps)); maps__for_each_entry(maps, curr) { - if (prev != NULL && !prev->map->end) - prev->map->end = curr->map->start; + if (prev != NULL && !map__end(prev->map)) + prev->map->end = map__start(curr->map); prev = curr; } @@ -288,7 +288,7 @@ void maps__fixup_end(struct maps *maps) * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !curr->map->end) + if (curr && !map__end(curr->map)) curr->map->end = ~0ULL; up_write(maps__lock(maps)); @@ -810,11 +810,11 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) continue; } curr_map_dso = map__dso(curr_map); - pos->start -= curr_map->start - curr_map->pgoff; - if (pos->end > curr_map->end) - pos->end = curr_map->end; + pos->start -= map__start(curr_map) - curr_map->pgoff; + if (pos->end > map__end(curr_map)) + pos->end = map__end(curr_map); if (pos->end) - pos->end -= curr_map->start - curr_map->pgoff; + pos->end -= map__start(curr_map) - curr_map->pgoff; symbols__insert(&curr_map_dso->symbols, pos); ++count; } @@ -1156,7 +1156,7 @@ static int do_validate_kcore_modules(const char *filename, struct maps *kmaps) dso = map__dso(old_map); /* Module must be in memory at the same address */ mi = find_module(dso->short_name, &modules); - if (!mi || mi->start != old_map->start) { + if (!mi || mi->start != map__start(old_map)) { err = -EINVAL; goto out; } @@ -1250,7 +1250,7 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) return -ENOMEM; } - list_node->map->end = list_node->map->start + len; + list_node->map->end = map__start(list_node->map) + len; list_node->map->pgoff = pgoff; list_add(&list_node->node, &md->maps); @@ -1272,21 +1272,21 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) struct map *old_map = rb_node->map; /* no overload with this one */ - if (new_map->end < old_map->start || - new_map->start >= old_map->end) + if (map__end(new_map) < map__start(old_map) || + map__start(new_map) >= map__end(old_map)) continue; - if (new_map->start < old_map->start) { + if (map__start(new_map) < map__start(old_map)) { /* * |new...... * |old.... */ - if (new_map->end < old_map->end) { + if (map__end(new_map) < map__end(old_map)) { /* * |new......| -> |new..| * |old....| -> |old....| */ - new_map->end = old_map->start; + new_map->end = map__start(old_map); } else { /* * |new.............| -> |new..| |new..| @@ -1306,17 +1306,17 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) goto out; } - m->map->end = old_map->start; + m->map->end = map__start(old_map); list_add_tail(&m->node, &merged); - new_map->pgoff += old_map->end - new_map->start; - new_map->start = old_map->end; + new_map->pgoff += map__end(old_map) - map__start(new_map); + new_map->start = map__end(old_map); } } else { /* * |new...... * |old.... */ - if (new_map->end < old_map->end) { + if (map__end(new_map) < map__end(old_map)) { /* * |new..| -> x * |old.........| -> |old.........| @@ -1329,8 +1329,8 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) * |new......| -> |new...| * |old....| -> |old....| */ - new_map->pgoff += old_map->end - new_map->start; - new_map->start = old_map->end; + new_map->pgoff += map__end(old_map) - map__start(new_map); + new_map->start = map__end(old_map); } } } @@ -1428,9 +1428,9 @@ static int dso__load_kcore(struct dso *dso, struct map *map, list_for_each_entry(new_node, &md.maps, node) { struct map *new_map = new_node->map; - u64 new_size = new_map->end - new_map->start; + u64 new_size = map__size(new_map); - if (!(stext >= new_map->start && stext < new_map->end)) + if (!(stext >= map__start(new_map) && stext < map__end(new_map))) continue; /* @@ -1457,8 +1457,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map, list_del_init(&new_node->node); if (new_map == replacement_map) { - map->start = new_map->start; - map->end = new_map->end; + map->start = map__start(new_map); + map->end = map__end(new_map); map->pgoff = new_map->pgoff; map->map_ip = new_map->map_ip; map->unmap_ip = new_map->unmap_ip; diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c index 2664fb65e47a..d9e5ad040b6a 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -30,7 +30,7 @@ size_t __symbol__fprintf_symname_offs(const struct symbol *sym, if (al->addr < sym->end) offset = al->addr - sym->start; else - offset = al->addr - al->map->start - sym->start; + offset = al->addr - map__start(al->map) - sym->start; length += fprintf(fp, "+0x%lx", offset); } return length; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index fbd1a882b013..b2e4afa5efa1 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -706,8 +706,8 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t (sizeof(event->mmap2.filename) - size)); memset(event->mmap2.filename + size, 0, machine->id_hdr_size); event->mmap2.header.size += machine->id_hdr_size; - event->mmap2.start = map->start; - event->mmap2.len = map->end - map->start; + event->mmap2.start = map__start(map); + event->mmap2.len = map__size(map); event->mmap2.pid = machine->pid; memcpy(event->mmap2.filename, dso->long_name, dso->long_name_len + 1); @@ -720,8 +720,8 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t (sizeof(event->mmap.filename) - size)); memset(event->mmap.filename + size, 0, machine->id_hdr_size); event->mmap.header.size += machine->id_hdr_size; - event->mmap.start = map->start; - event->mmap.len = map->end - map->start; + event->mmap.start = map__start(map); + event->mmap.len = map__size(map); event->mmap.pid = machine->pid; memcpy(event->mmap.filename, dso->long_name, dso->long_name_len + 1); @@ -1143,8 +1143,8 @@ static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, event->mmap2.header.size = (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size) + machine->id_hdr_size); event->mmap2.pgoff = kmap->ref_reloc_sym->addr; - event->mmap2.start = map->start; - event->mmap2.len = map->end - event->mmap.start; + event->mmap2.start = map__start(map); + event->mmap2.len = map__end(map) - event->mmap.start; event->mmap2.pid = machine->pid; perf_record_mmap2__read_build_id(&event->mmap2, machine, true); @@ -1156,8 +1156,8 @@ static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, event->mmap.header.size = (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); event->mmap.pgoff = kmap->ref_reloc_sym->addr; - event->mmap.start = map->start; - event->mmap.len = map->end - event->mmap.start; + event->mmap.start = map__start(map); + event->mmap.len = map__end(map) - event->mmap.start; event->mmap.pid = machine->pid; } diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index c8cba9d4bfd9..b79f57e5648f 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -62,19 +62,19 @@ static int __report_module(struct addr_location *al, u64 ip, Dwarf_Addr s; dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); - if (s != al->map->start - al->map->pgoff) + if (s != map__start(al->map) - al->map->pgoff) mod = 0; } if (!mod) mod = dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1, - al->map->start - al->map->pgoff, false); + map__start(al->map) - al->map->pgoff, false); if (!mod) { char filename[PATH_MAX]; if (dso__build_id_filename(dso, filename, sizeof(filename), false)) mod = dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1, - al->map->start - al->map->pgoff, false); + map__start(al->map) - al->map->pgoff, false); } if (mod) { diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 108f7b1697a7..1c13f43e7d22 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -327,9 +327,10 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui, maps__for_each_entry(ui->thread->maps, map_node) { struct map *map = map_node->map; + u64 start = map__start(map); - if (map__dso(map) == dso && map->start < base_addr) - base_addr = map->start; + if (map__dso(map) == dso && start < base_addr) + base_addr = start; } base_addr -= dso->data.elf_base_addr; /* Address of .eh_frame_hdr */ @@ -443,8 +444,8 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, if (!read_unwind_spec_eh_frame(dso, ui, &table_data, &segbase, &fde_count)) { memset(&di, 0, sizeof(di)); di.format = UNW_INFO_FORMAT_REMOTE_TABLE; - di.start_ip = map->start; - di.end_ip = map->end; + di.start_ip = map__start(map); + di.end_ip = map__end(map); di.u.rti.segbase = segbase; di.u.rti.table_data = table_data; di.u.rti.table_len = fde_count * sizeof(struct table_entry) @@ -459,7 +460,8 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, !read_unwind_spec_debug_frame(dso, ui->machine, &segbase)) { int fd = dso__data_get_fd(dso, ui->machine); int is_exec = elf_is_exec(fd, dso->name); - unw_word_t base = is_exec ? 0 : map->start; + u64 start = map__start(map); + unw_word_t base = is_exec ? 0 : start; const char *symfile; if (fd >= 0) @@ -468,8 +470,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, symfile = dso->symsrc_filename ?: dso->name; memset(&di, 0, sizeof(di)); - if (dwarf_find_debug_frame(0, &di, ip, base, symfile, - map->start, map->end)) + if (dwarf_find_debug_frame(0, &di, ip, base, symfile, start, map__end(map))) return dwarf_search_unwind_table(as, ip, &di, pi, need_unwind_info, arg); } -- cgit v1.2.3 From 0e6aa013bbc545f3ac04ba79c884466e47136d5d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 4 Apr 2023 13:59:43 -0700 Subject: perf map: Rename map_ip() and unmap_ip() Add dso to match comment. This avoids a naming conflict with later added accessor functions for variables in struct map. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230404205954.2245628-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/util/machine.c | 4 ++-- tools/perf/util/map.c | 8 ++++---- tools/perf/util/map.h | 4 ++-- tools/perf/util/symbol-elf.c | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index f3029742b800..4d4b770a401c 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -423,7 +423,7 @@ static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample) if (!caller) { /* found */ if (node->ms.map) - addr = map__unmap_ip(node->ms.map, node->ip); + addr = map__dso_unmap_ip(node->ms.map, node->ip); else addr = node->ip; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1d078106abc4..af0a69c7f41f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1012,11 +1012,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample, if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && !map__dso(alf.map)->adjust_symbols) - from = map__map_ip(alf.map, from); + from = map__dso_map_ip(alf.map, from); if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && !map__dso(alt.map)->adjust_symbols) - to = map__map_ip(alt.map, to); + to = map__dso_map_ip(alt.map, to); printed += fprintf(fp, " 0x%"PRIx64, from); if (PRINT_FIELD(DSO)) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7852b97da10a..9d24980a0a93 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -3058,7 +3058,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms if (!symbol_conf.inline_name || !map || !sym) return ret; - addr = map__map_ip(map, ip); + addr = map__dso_map_ip(map, ip); addr = map__rip_2objdump(map, addr); dso = map__dso(map); @@ -3103,7 +3103,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) * its corresponding binary. */ if (entry->ms.map) - addr = map__map_ip(entry->ms.map, entry->ip); + addr = map__dso_map_ip(entry->ms.map, entry->ip); srcline = callchain_srcline(&entry->ms, addr); return callchain_cursor_append(cursor, entry->ip, &entry->ms, diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 416fc449bde8..d97a6d20626f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -109,8 +109,8 @@ void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso) map->pgoff = pgoff; map->reloc = 0; map->dso = dso__get(dso); - map->map_ip = map__map_ip; - map->unmap_ip = map__unmap_ip; + map->map_ip = map__dso_map_ip; + map->unmap_ip = map__dso_unmap_ip; map->erange_warned = false; refcount_set(&map->refcnt, 1); } @@ -590,12 +590,12 @@ struct maps *map__kmaps(struct map *map) return kmap->kmaps; } -u64 map__map_ip(const struct map *map, u64 ip) +u64 map__dso_map_ip(const struct map *map, u64 ip) { return ip - map__start(map) + map->pgoff; } -u64 map__unmap_ip(const struct map *map, u64 ip) +u64 map__dso_unmap_ip(const struct map *map, u64 ip) { return ip + map__start(map) - map->pgoff; } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 16646b94fa3a..9b0a84e46e48 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -41,9 +41,9 @@ struct kmap *map__kmap(struct map *map); struct maps *map__kmaps(struct map *map); /* ip -> dso rip */ -u64 map__map_ip(const struct map *map, u64 ip); +u64 map__dso_map_ip(const struct map *map, u64 ip); /* dso rip -> ip */ -u64 map__unmap_ip(const struct map *map, u64 ip); +u64 map__dso_unmap_ip(const struct map *map, u64 ip); /* Returns ip */ u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index e715869eab8a..c55981116f68 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1357,8 +1357,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, map->start = shdr->sh_addr + ref_reloc(kmap); map->end = map__start(map) + shdr->sh_size; map->pgoff = shdr->sh_offset; - map->map_ip = map__map_ip; - map->unmap_ip = map__unmap_ip; + map->map_ip = map__dso_map_ip; + map->unmap_ip = map__dso_unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { int err; -- cgit v1.2.3 From 78a1f7cd9000d5d633268a2acb2d9b62d41a2f2c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 4 Apr 2023 13:59:44 -0700 Subject: perf map: Add helper for ->map_ip() and ->unmap_ip() Later changes will add reference count checking for struct map, add a helper function to invoke the map_ip and unmap_ip function pointers. The helper allows the reference count check to be in fewer places. Committer notes: Add missing conversions to: tools/perf/util/map.c tools/perf/util/cs-etm.c tools/perf/util/annotate.c tools/perf/arch/powerpc/util/sym-handling.c tools/perf/arch/s390/annotate/instructions.c Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230404205954.2245628-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/sym-handling.c | 2 +- tools/perf/arch/s390/annotate/instructions.c | 2 +- tools/perf/builtin-kallsyms.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-lock.c | 4 ++-- tools/perf/builtin-script.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 10 +++++----- tools/perf/util/annotate.c | 14 +++++++------- tools/perf/util/bpf_lock_contention.c | 4 ++-- tools/perf/util/cs-etm.c | 2 +- tools/perf/util/dlfilter.c | 2 +- tools/perf/util/dso.c | 6 ++++-- tools/perf/util/event.c | 8 ++++---- tools/perf/util/evsel_fprintf.c | 2 +- tools/perf/util/intel-pt.c | 10 +++++----- tools/perf/util/machine.c | 16 ++++++++-------- tools/perf/util/map.c | 12 ++++++------ tools/perf/util/map.h | 10 ++++++++++ tools/perf/util/maps.c | 8 ++++---- tools/perf/util/probe-event.c | 8 ++++---- tools/perf/util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/sort.c | 12 ++++++------ tools/perf/util/symbol.c | 4 ++-- tools/perf/util/thread.c | 2 +- tools/perf/util/unwind-libdw.c | 2 +- tools/perf/util/unwind-libunwind-local.c | 2 +- 26 files changed, 81 insertions(+), 69 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index 9f99fc88dbff..947bfad7aa59 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -131,7 +131,7 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev, for (i = 0; i < ntevs; i++) { tev = &pev->tevs[i]; map__for_each_symbol(map, sym, tmp) { - if (map->unmap_ip(map, sym->start) == tev->point.address) { + if (map__unmap_ip(map, sym->start) == tev->point.address) { arch__fix_tev_from_maps(pev, tev, map, sym); break; } diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c index 0e136630659e..de925b0e35ce 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -39,7 +39,7 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops, target.addr = map__objdump_2mem(map, ops->target.addr); if (maps__find_ams(ms->maps, &target) == 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) + map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; return 0; diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index 5638ca4dbd8e..3751df744577 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -39,7 +39,7 @@ static int __cmd_kallsyms(int argc, const char **argv) dso = map__dso(map); printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n", symbol->name, dso->short_name, dso->long_name, - map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end), + map__unmap_ip(map, symbol->start), map__unmap_ip(map, symbol->end), symbol->start, symbol->end); } diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 4d4b770a401c..fcd2ef3bd3f5 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -1024,7 +1024,7 @@ static void __print_slab_result(struct rb_root *root, if (sym != NULL) snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name, - addr - map->unmap_ip(map, sym->start)); + addr - map__unmap_ip(map, sym->start)); else snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr); printf(" %-34s |", buf); diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 4e24351b18bd..ecb1fac8ba3c 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -900,7 +900,7 @@ static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip, return 0; } - offset = map->map_ip(map, ip) - sym->start; + offset = map__map_ip(map, ip) - sym->start; if (offset) return scnprintf(buf, size, "%s+%#lx", sym->name, offset); @@ -1070,7 +1070,7 @@ static int report_lock_contention_begin_event(struct evsel *evsel, return -ENOMEM; } - addrs[filters.nr_addrs++] = kmap->unmap_ip(kmap, sym->start); + addrs[filters.nr_addrs++] = map__unmap_ip(kmap, sym->start); filters.addrs = addrs; } } diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index af0a69c7f41f..8fba247b798c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); - offset = al.map->map_ip(al.map, start); + offset = map__map_ip(al.map, start); len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer, end - start + MAXINSN); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 0a75623172c2..05a322ea3f9f 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -13,7 +13,7 @@ #include "debug.h" #include "machine.h" -#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x)) +#define UM(x) map__unmap_ip(kallsyms_map, (x)) static bool is_ignored_symbol(const char *name, char type) { @@ -221,8 +221,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused if (sym->start == sym->end) continue; - mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start); - mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end); + mem_start = map__unmap_ip(vmlinux_map, sym->start); + mem_end = map__unmap_ip(vmlinux_map, sym->end); first_pair = machine__find_kernel_symbol(&kallsyms, mem_start, NULL); pair = first_pair; @@ -319,8 +319,8 @@ next_pair: maps__for_each_entry(maps, rb_node) { struct map *pair, *map = rb_node->map; - mem_start = vmlinux_map->unmap_ip(vmlinux_map, map__start(map)); - mem_end = vmlinux_map->unmap_ip(vmlinux_map, map__end(map)); + mem_start = map__unmap_ip(vmlinux_map, map__start(map)); + mem_end = map__unmap_ip(vmlinux_map, map__end(map)); pair = maps__find(kallsyms.kmaps, mem_start); if (pair == NULL || pair->priv) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index b9cff782d7df..55f2e3a7577e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -272,7 +272,7 @@ find_target: target.addr = map__objdump_2mem(map, ops->target.addr); if (maps__find_ams(ms->maps, &target) == 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) + map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; return 0; @@ -376,8 +376,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s } target.addr = map__objdump_2mem(map, ops->target.addr); - start = map->unmap_ip(map, sym->start), - end = map->unmap_ip(map, sym->end); + start = map__unmap_ip(map, sym->start); + end = map__unmap_ip(map, sym->end); ops->target.outside = target.addr < start || target.addr > end; @@ -400,7 +400,7 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s * the symbol searching and disassembly should be done. */ if (maps__find_ams(ms->maps, &target) == 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) + map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; if (!ops->target.outside) { @@ -881,7 +881,7 @@ static int __symbol__inc_addr_samples(struct map_symbol *ms, unsigned offset; struct sym_hist *h; - pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr)); + pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr)); if ((addr < sym->start || addr >= sym->end) && (addr != sym->end || sym->start != sym->end)) { @@ -1977,8 +1977,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) return err; pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, - symfs_filename, sym->name, map->unmap_ip(map, sym->start), - map->unmap_ip(map, sym->end)); + symfs_filename, sym->name, map__unmap_ip(map, sym->start), + map__unmap_ip(map, sym->end)); pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso->long_name, sym, sym->name); diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 9e20fa8ade09..e7dddf0127bc 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -74,7 +74,7 @@ int lock_contention_prepare(struct lock_contention *con) continue; } - addrs[con->filters->nr_addrs++] = kmap->unmap_ip(kmap, sym->start); + addrs[con->filters->nr_addrs++] = map__unmap_ip(kmap, sym->start); con->filters->addrs = addrs; } naddrs = con->filters->nr_addrs; @@ -233,7 +233,7 @@ static const char *lock_contention_get_name(struct lock_contention *con, if (sym) { unsigned long offset; - offset = kmap->map_ip(kmap, addr) - sym->start; + offset = map__map_ip(kmap, addr) - sym->start; if (offset == 0) return sym->name; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 528a7fb066cf..944835e16430 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -893,7 +893,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) return 0; - offset = al.map->map_ip(al.map, address); + offset = map__map_ip(al.map, address); map__load(al.map); diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index fe401fa4be02..16238f823a5e 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -278,7 +278,7 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len) map = a.map; have_map: - offset = map->map_ip(map, ip); + offset = map__map_ip(map, ip); if (ip + len >= map__end(map)) len = map__end(map) - ip; return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index f1a14c0ad26d..e36b418df2c6 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1122,7 +1122,8 @@ ssize_t dso__data_read_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, u8 *data, ssize_t size) { - u64 offset = map->map_ip(map, addr); + u64 offset = map__map_ip(map, addr); + return dso__data_read_offset(dso, machine, offset, data, size); } @@ -1162,7 +1163,8 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, const u8 *data, ssize_t size) { - u64 offset = map->map_ip(map, addr); + u64 offset = map__map_ip(map, addr); + return dso__data_write_cache_offs(dso, machine, offset, data, size); } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2ddc75dee019..2712d1a8264e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -487,7 +487,7 @@ size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *ma al.map = maps__find(machine__kernel_maps(machine), tp->addr); if (al.map && map__load(al.map) >= 0) { - al.addr = al.map->map_ip(al.map, tp->addr); + al.addr = map__map_ip(al.map, tp->addr); al.sym = map__find_symbol(al.map, al.addr); if (al.sym) ret += symbol__fprintf_symname_offs(al.sym, &al, fp); @@ -622,7 +622,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, */ if (load_map) map__load(al->map); - al->addr = al->map->map_ip(al->map, al->addr); + al->addr = map__map_ip(al->map, al->addr); } return al->map; @@ -743,12 +743,12 @@ int machine__resolve(struct machine *machine, struct addr_location *al, } if (!ret && al->sym) { snprintf(al_addr_str, sz, "0x%"PRIx64, - al->map->unmap_ip(al->map, al->sym->start)); + map__unmap_ip(al->map, al->sym->start)); ret = strlist__has_entry(symbol_conf.sym_list, al_addr_str); } if (!ret && symbol_conf.addr_list && al->map) { - unsigned long addr = al->map->unmap_ip(al->map, al->addr); + unsigned long addr = map__unmap_ip(al->map, al->addr); ret = intlist__has_entry(symbol_conf.addr_list, addr); if (!ret && symbol_conf.addr_range) { diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index dff5d8c4b06d..a09ac00810b7 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -151,7 +151,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, printed += fprintf(fp, " <-"); if (map) - addr = map->map_ip(map, node->ip); + addr = map__map_ip(map, node->ip); if (print_ip) { /* Show binary offset for userspace addr */ diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index a2e62daa708e..fe893c9bab3f 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -816,7 +816,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) return -ENOENT; - offset = al.map->map_ip(al.map, *ip); + offset = map__map_ip(al.map, *ip); if (!to_ip && one_map) { struct intel_pt_cache_entry *e; @@ -987,7 +987,7 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data) if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map)) return -EINVAL; - offset = al.map->map_ip(al.map, ip); + offset = map__map_ip(al.map, ip); return intel_pt_match_pgd_ip(ptq->pt, ip, offset, map__dso(al.map)->long_name); } @@ -2749,7 +2749,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip) for (sym = start; sym; sym = dso__next_symbol(sym)) { if (sym->binding == STB_GLOBAL && !strcmp(sym->name, "__switch_to")) { - ip = map->unmap_ip(map, sym->start); + ip = map__unmap_ip(map, sym->start); if (ip >= map__start(map) && ip < map__end(map)) { switch_ip = ip; break; @@ -2767,7 +2767,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip) for (sym = start; sym; sym = dso__next_symbol(sym)) { if (!strcmp(sym->name, ptss)) { - ip = map->unmap_ip(map, sym->start); + ip = map__unmap_ip(map, sym->start); if (ip >= map__start(map) && ip < map__end(map)) { *ptss_ip = ip; break; @@ -3393,7 +3393,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event) if (!dso || !dso->auxtrace_cache) continue; - offset = al.map->map_ip(al.map, addr); + offset = map__map_ip(al.map, addr); e = intel_pt_cache_lookup(dso, machine, offset); if (!e) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9d24980a0a93..d29ec4a04488 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct machine *machine, dso = map__dso(map); } - sym = symbol__new(map->map_ip(map, map__start(map)), + sym = symbol__new(map__map_ip(map, map__start(map)), event->ksymbol.len, 0, 0, event->ksymbol.name); if (!sym) @@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine, else { struct dso *dso = map__dso(map); - sym = dso__find_symbol(dso, map->map_ip(map, map__start(map))); + sym = dso__find_symbol(dso, map__map_ip(map, map__start(map))); if (sym) dso__delete_symbol(dso, sym); } @@ -1279,7 +1279,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine, dest_map = maps__find(kmaps, map->pgoff); if (dest_map != map) - map->pgoff = dest_map->map_ip(dest_map, map->pgoff); + map->pgoff = map__map_ip(dest_map, map->pgoff); found = true; } if (found || machine->trampolines_mapped) @@ -3345,7 +3345,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch return NULL; *modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL; - *addrp = map->unmap_ip(map, sym->start); + *addrp = map__unmap_ip(map, sym->start); return sym->name; } @@ -3388,17 +3388,17 @@ bool machine__is_lock_function(struct machine *machine, u64 addr) return false; } - machine->sched.text_start = kmap->unmap_ip(kmap, sym->start); + machine->sched.text_start = map__unmap_ip(kmap, sym->start); /* should not fail from here */ sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap); - machine->sched.text_end = kmap->unmap_ip(kmap, sym->start); + machine->sched.text_end = map__unmap_ip(kmap, sym->start); sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap); - machine->lock.text_start = kmap->unmap_ip(kmap, sym->start); + machine->lock.text_start = map__unmap_ip(kmap, sym->start); sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap); - machine->lock.text_end = kmap->unmap_ip(kmap, sym->start); + machine->lock.text_end = map__unmap_ip(kmap, sym->start); } /* failed to get kernel symbols */ diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index d97a6d20626f..a55aef4b1310 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -519,7 +519,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) if (dso->kernel == DSO_SPACE__USER) return rip + dso->text_offset; - return map->unmap_ip(map, rip) - map->reloc; + return map__unmap_ip(map, rip) - map->reloc; } /** @@ -530,7 +530,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) * Closely related to map__rip_2objdump(), this function takes an address from * objdump and converts it to a memory address. Note this assumes that @map * contains the address. To be sure the result is valid, check it forwards - * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip + * e.g. map__rip_2objdump(map__map_ip(map, map__objdump_2mem(map, ip))) == ip * * Return: Memory address. */ @@ -539,24 +539,24 @@ u64 map__objdump_2mem(struct map *map, u64 ip) const struct dso *dso = map__dso(map); if (!dso->adjust_symbols) - return map->unmap_ip(map, ip); + return map__unmap_ip(map, ip); if (dso->rel) - return map->unmap_ip(map, ip + map->pgoff); + return map__unmap_ip(map, ip + map->pgoff); /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ if (dso->kernel == DSO_SPACE__USER) - return map->unmap_ip(map, ip - dso->text_offset); + return map__unmap_ip(map, ip - dso->text_offset); return ip + map->reloc; } bool map__contains_symbol(const struct map *map, const struct symbol *sym) { - u64 ip = map->unmap_ip(map, sym->start); + u64 ip = map__unmap_ip(map, sym->start); return ip >= map__start(map) && ip < map__end(map); } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 9b0a84e46e48..9118eba71032 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -52,6 +52,16 @@ static inline struct dso *map__dso(const struct map *map) return map->dso; } +static inline u64 map__map_ip(const struct map *map, u64 ip) +{ + return map->map_ip(map, ip); +} + +static inline u64 map__unmap_ip(const struct map *map, u64 ip) +{ + return map->unmap_ip(map, ip); +} + static inline u64 map__start(const struct map *map) { return map->start; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 21010a2b8e16..0eee27e24c33 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -194,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) if (map != NULL && map__load(map) >= 0) { if (mapp != NULL) *mapp = map; - return map__find_symbol(map, map->map_ip(map, addr)); + return map__find_symbol(map, map__map_ip(map, addr)); } return NULL; @@ -237,7 +237,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) return -1; } - ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr); + ams->al_addr = map__map_ip(ams->ms.map, ams->addr); ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr); return ams->ms.sym ? 0 : -1; @@ -349,8 +349,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) after->start = map__end(map); after->pgoff += map__end(map) - map__start(pos->map); - assert(pos->map->map_ip(pos->map, map__end(map)) == - after->map_ip(after, map__end(map))); + assert(map__map_ip(pos->map, map__end(map)) == + map__map_ip(after, map__end(map))); err = __maps__insert(maps, after); if (err) goto put_map; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 4d9dbeeb6014..bb44a3798df8 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -141,7 +141,7 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr, sym = machine__find_kernel_symbol_by_name(host_machine, name, &map); if (!sym) return -ENOENT; - *addr = map->unmap_ip(map, sym->start) - + *addr = map__unmap_ip(map, sym->start) - ((reloc) ? 0 : map->reloc) - ((reladdr) ? map__start(map) : 0); } @@ -400,7 +400,7 @@ static int find_alternative_probe_point(struct debuginfo *dinfo, "Consider identifying the final function used at run time and set the probe directly on that.\n", pp->function); } else - address = map->unmap_ip(map, sym->start) - map->reloc; + address = map__unmap_ip(map, sym->start) - map->reloc; break; } if (!address) { @@ -2249,7 +2249,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp, goto out; pp->retprobe = tp->retprobe; - pp->offset = addr - map->unmap_ip(map, sym->start); + pp->offset = addr - map__unmap_ip(map, sym->start); pp->function = strdup(sym->name); ret = pp->function ? 0 : -ENOMEM; @@ -3123,7 +3123,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, goto err_out; } /* Add one probe point */ - tp->address = map->unmap_ip(map, sym->start) + pp->offset; + tp->address = map__unmap_ip(map, sym->start) + pp->offset; /* Check the kprobe (not in module) is within .text */ if (!pev->uprobes && !pev->target && diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index cbf09eaf3734..41d4f9e6a8b7 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -471,7 +471,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample, struct addr_location node_al; unsigned long offset; - node_al.addr = map->map_ip(map, node->ip); + node_al.addr = map__map_ip(map, node->ip); node_al.map = map; offset = get_offset(node->ms.sym, &node_al); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index f161589aefda..87a3ba584af5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms, u64 rip = ip; if (dso && dso->kernel && dso->adjust_symbols) - rip = map->unmap_ip(map, ip); + rip = map__unmap_ip(map, ip); ret += repsep_snprintf(bf, size, "%-#*llx %c ", BITS_PER_LONG / 4 + 2, rip, o); @@ -375,7 +375,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms, if (sym->type == STT_OBJECT) { ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", - ip - map->unmap_ip(map, sym->start)); + ip - map__unmap_ip(map, sym->start)); } else { ret += repsep_snprintf(bf + ret, size - ret, "%.*s", width - ret, @@ -1147,7 +1147,7 @@ static int _hist_entry__addr_snprintf(struct map_symbol *ms, if (sym->type == STT_OBJECT) { ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", - ip - map->unmap_ip(map, sym->start)); + ip - map__unmap_ip(map, sym->start)); } else { ret += repsep_snprintf(bf + ret, size - ret, "%.*s", width - ret, @@ -2104,9 +2104,9 @@ sort__addr_cmp(struct hist_entry *left, struct hist_entry *right) struct map *right_map = right->ms.map; if (left_map) - left_ip = left_map->unmap_ip(left_map, left_ip); + left_ip = map__unmap_ip(left_map, left_ip); if (right_map) - right_ip = right_map->unmap_ip(right_map, right_ip); + right_ip = map__unmap_ip(right_map, right_ip); return _sort__addr_cmp(left_ip, right_ip); } @@ -2118,7 +2118,7 @@ static int hist_entry__addr_snprintf(struct hist_entry *he, char *bf, struct map *map = he->ms.map; if (map) - ip = map->unmap_ip(map, ip); + ip = map__unmap_ip(map, ip); return repsep_snprintf(bf, size, "%-#*llx", width, ip); } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b91deb177091..9ba49c1ef6ef 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -896,8 +896,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, * So that we look just like we get from .ko files, * i.e. not prelinked, relative to initial_map->start. */ - pos->start = curr_map->map_ip(curr_map, pos->start); - pos->end = curr_map->map_ip(curr_map, pos->end); + pos->start = map__map_ip(curr_map, pos->start); + pos->end = map__map_ip(curr_map, pos->end); } else if (x86_64 && is_entry_trampoline(pos->name)) { /* * These symbols are not needed anymore since the diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index bb7a2ce82d46..4b5bdc277baa 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -464,7 +464,7 @@ int thread__memcpy(struct thread *thread, struct machine *machine, if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0) return -1; - offset = al.map->map_ip(al.map, ip); + offset = map__map_ip(al.map, ip); if (is64bit) *is64bit = dso->is_64_bit; diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index b79f57e5648f..538320e4260c 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -115,7 +115,7 @@ static int entry(u64 ip, struct unwind_info *ui) pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", ip, - al.map ? al.map->map_ip(al.map, ip) : (u64) 0); + al.map ? map__map_ip(al.map, ip) : (u64) 0); return 0; } diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 1c13f43e7d22..f9a52af48de4 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -640,7 +640,7 @@ static int entry(u64 ip, struct thread *thread, pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", ip, - al.map ? al.map->map_ip(al.map, ip) : (u64) 0); + al.map ? map__map_ip(al.map, ip) : (u64) 0); return cb(&e, arg); } -- cgit v1.2.3 From ddee3f2bddc11f850f7f6fcfc04bc26ceeab23ce Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 4 Apr 2023 13:59:45 -0700 Subject: perf map: Add accessors for ->prot, ->priv and ->flags Later changes will add reference count checking for 'struct map'. Add an accessor so that the reference count check is only necessary in one place. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230404205954.2245628-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-report.c | 9 +++++---- tools/perf/tests/vmlinux-kallsyms.c | 4 ++-- tools/perf/util/map.h | 15 +++++++++++++++ tools/perf/util/sort.c | 6 +++--- tools/perf/util/symbol.c | 4 ++-- 6 files changed, 28 insertions(+), 12 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8f6909dd8a54..fd2b38458a5d 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -758,7 +758,7 @@ int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, if (!dso->hit) { dso->hit = 1; dso__inject_build_id(dso, tool, machine, - sample->cpumode, al.map->flags); + sample->cpumode, map__flags(al.map)); } } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2a6e2cee5e0d..c066452219c8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -849,13 +849,14 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) maps__for_each_entry(maps, rb_node) { struct map *map = rb_node->map; const struct dso *dso = map__dso(map); + u32 prot = map__prot(map); printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n", indent, "", map__start(map), map__end(map), - map->prot & PROT_READ ? 'r' : '-', - map->prot & PROT_WRITE ? 'w' : '-', - map->prot & PROT_EXEC ? 'x' : '-', - map->flags & MAP_SHARED ? 's' : 'p', + prot & PROT_READ ? 'r' : '-', + prot & PROT_WRITE ? 'w' : '-', + prot & PROT_EXEC ? 'x' : '-', + map__flags(map) ? 's' : 'p', map->pgoff, dso->id.ino, dso->name); } diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 05a322ea3f9f..7db102868bc2 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -323,7 +323,7 @@ next_pair: mem_end = map__unmap_ip(vmlinux_map, map__end(map)); pair = maps__find(kallsyms.kmaps, mem_start); - if (pair == NULL || pair->priv) + if (pair == NULL || map__priv(pair)) continue; if (map__start(pair) == mem_start) { @@ -351,7 +351,7 @@ next_pair: maps__for_each_entry(maps, rb_node) { struct map *map = rb_node->map; - if (!map->priv) { + if (!map__priv(map)) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); header_printed = true; diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 9118eba71032..fd440c9c279e 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -72,6 +72,21 @@ static inline u64 map__end(const struct map *map) return map->end; } +static inline u32 map__flags(const struct map *map) +{ + return map->flags; +} + +static inline u32 map__prot(const struct map *map) +{ + return map->prot; +} + +static inline bool map__priv(const struct map *map) +{ + return map->priv; +} + static inline size_t map__size(const struct map *map) { return map__end(map) - map__start(map); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 87a3ba584af5..80c9960c37e5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1540,7 +1540,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right) */ if ((left->cpumode != PERF_RECORD_MISC_KERNEL) && - (!(l_map->flags & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min && + (!(map__flags(l_map) & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min && !l_dso->id.ino && !l_dso->id.ino_generation) { /* userspace anonymous */ @@ -1576,8 +1576,8 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf, /* print [s] for shared data mmaps */ if ((he->cpumode != PERF_RECORD_MISC_KERNEL) && - map && !(map->prot & PROT_EXEC) && - (map->flags & MAP_SHARED) && + map && !(map__prot(map) & PROT_EXEC) && + (map__flags(map) & MAP_SHARED) && (dso->id.maj || dso->id.min || dso->id.ino || dso->id.ino_generation)) level = 's'; else if (!map) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 9ba49c1ef6ef..5c075d77a792 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1396,7 +1396,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, } /* Read new maps into temporary lists */ - err = file__read_maps(fd, map->prot & PROT_EXEC, kcore_mapfn, &md, + err = file__read_maps(fd, map__prot(map) & PROT_EXEC, kcore_mapfn, &md, &is_64_bit); if (err) goto out_err; @@ -1509,7 +1509,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, close(fd); - if (map->prot & PROT_EXEC) + if (map__prot(map) & PROT_EXEC) pr_debug("Using %s for kernel object code\n", kcore_filename); else pr_debug("Using %s for kernel data\n", kcore_filename); -- cgit v1.2.3 From 2a6e5e8a2ab68c9048f80d174d1698427fbd9c8c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 4 Apr 2023 13:59:46 -0700 Subject: perf map: Add accessors for ->pgoff and ->reloc Later changes will add reference count checking for 'struct map'. Add accessors so that the reference count check is only necessary in one place. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230404205954.2245628-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/event.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 4 ++-- tools/perf/util/machine.c | 4 ++-- tools/perf/util/map.c | 14 +++++++------- tools/perf/util/map.h | 10 ++++++++++ tools/perf/util/probe-event.c | 8 ++++---- tools/perf/util/symbol.c | 6 +++--- tools/perf/util/unwind-libdw.c | 6 +++--- 9 files changed, 33 insertions(+), 23 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index 3b2475707756..5741ffe47312 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -61,7 +61,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, event->mmap.start = map__start(map); event->mmap.len = map__size(map); - event->mmap.pgoff = map->pgoff; + event->mmap.pgoff = map__pgoff(map); event->mmap.pid = machine->pid; strlcpy(event->mmap.filename, kmap->name, PATH_MAX); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c066452219c8..92c6797e7cba 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -857,7 +857,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) prot & PROT_WRITE ? 'w' : '-', prot & PROT_EXEC ? 'x' : '-', map__flags(map) ? 's' : 'p', - map->pgoff, + map__pgoff(map), dso->id.ino, dso->name); } diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 7db102868bc2..af511233c764 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -335,10 +335,10 @@ next_pair: } pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map__start(map), map__end(map), map->pgoff, dso->name); + map__start(map), map__end(map), map__pgoff(map), dso->name); if (mem_end != map__end(pair)) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, - map__start(pair), map__end(pair), pair->pgoff); + map__start(pair), map__end(pair), map__pgoff(pair)); pr_info(" %s\n", dso->name); pair->priv = 1; } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index d29ec4a04488..1ea6f6c06bbb 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1277,9 +1277,9 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine, if (!kmap || !is_entry_trampoline(kmap->name)) continue; - dest_map = maps__find(kmaps, map->pgoff); + dest_map = maps__find(kmaps, map__pgoff(map)); if (dest_map != map) - map->pgoff = map__map_ip(dest_map, map->pgoff); + map->pgoff = map__map_ip(dest_map, map__pgoff(map)); found = true; } if (found || machine->trampolines_mapped) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index a55aef4b1310..6426af6882c2 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -421,7 +421,7 @@ size_t map__fprintf(struct map *map, FILE *fp) const struct dso *dso = map__dso(map); return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map__start(map), map__end(map), map->pgoff, dso->name); + map__start(map), map__end(map), map__pgoff(map), dso->name); } size_t map__fprintf_dsoname(struct map *map, FILE *fp) @@ -510,7 +510,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) return rip; if (dso->rel) - return rip - map->pgoff; + return rip - map__pgoff(map); /* * kernel modules also have DSO_TYPE_USER in dso->kernel, @@ -519,7 +519,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) if (dso->kernel == DSO_SPACE__USER) return rip + dso->text_offset; - return map__unmap_ip(map, rip) - map->reloc; + return map__unmap_ip(map, rip) - map__reloc(map); } /** @@ -542,7 +542,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return map__unmap_ip(map, ip); if (dso->rel) - return map__unmap_ip(map, ip + map->pgoff); + return map__unmap_ip(map, ip + map__pgoff(map)); /* * kernel modules also have DSO_TYPE_USER in dso->kernel, @@ -551,7 +551,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) if (dso->kernel == DSO_SPACE__USER) return map__unmap_ip(map, ip - dso->text_offset); - return ip + map->reloc; + return ip + map__reloc(map); } bool map__contains_symbol(const struct map *map, const struct symbol *sym) @@ -592,12 +592,12 @@ struct maps *map__kmaps(struct map *map) u64 map__dso_map_ip(const struct map *map, u64 ip) { - return ip - map__start(map) + map->pgoff; + return ip - map__start(map) + map__pgoff(map); } u64 map__dso_unmap_ip(const struct map *map, u64 ip) { - return ip + map__start(map) - map->pgoff; + return ip + map__start(map) - map__pgoff(map); } u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index fd440c9c279e..102485699aa8 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -72,6 +72,16 @@ static inline u64 map__end(const struct map *map) return map->end; } +static inline u64 map__pgoff(const struct map *map) +{ + return map->pgoff; +} + +static inline u64 map__reloc(const struct map *map) +{ + return map->reloc; +} + static inline u32 map__flags(const struct map *map) { return map->flags; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index bb44a3798df8..6e2110d605fb 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -135,14 +135,14 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr, /* ref_reloc_sym is just a label. Need a special fix*/ reloc_sym = kernel_get_ref_reloc_sym(&map); if (reloc_sym && strcmp(name, reloc_sym->name) == 0) - *addr = (!map->reloc || reloc) ? reloc_sym->addr : + *addr = (!map__reloc(map) || reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; else { sym = machine__find_kernel_symbol_by_name(host_machine, name, &map); if (!sym) return -ENOENT; *addr = map__unmap_ip(map, sym->start) - - ((reloc) ? 0 : map->reloc) - + ((reloc) ? 0 : map__reloc(map)) - ((reladdr) ? map__start(map) : 0); } return 0; @@ -400,7 +400,7 @@ static int find_alternative_probe_point(struct debuginfo *dinfo, "Consider identifying the final function used at run time and set the probe directly on that.\n", pp->function); } else - address = map__unmap_ip(map, sym->start) - map->reloc; + address = map__unmap_ip(map, sym->start) - map__reloc(map); break; } if (!address) { @@ -866,7 +866,7 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs, free(tevs[i].point.symbol); tevs[i].point.symbol = tmp; tevs[i].point.offset = tevs[i].point.address - - (map->reloc ? reloc_sym->unrelocated_addr : + (map__reloc(map) ? reloc_sym->unrelocated_addr : reloc_sym->addr); } return skipped; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 5c075d77a792..7282119c2990 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -810,11 +810,11 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) continue; } curr_map_dso = map__dso(curr_map); - pos->start -= map__start(curr_map) - curr_map->pgoff; + pos->start -= map__start(curr_map) - map__pgoff(curr_map); if (pos->end > map__end(curr_map)) pos->end = map__end(curr_map); if (pos->end) - pos->end -= map__start(curr_map) - curr_map->pgoff; + pos->end -= map__start(curr_map) - map__pgoff(curr_map); symbols__insert(&curr_map_dso->symbols, pos); ++count; } @@ -1459,7 +1459,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, if (new_map == replacement_map) { map->start = map__start(new_map); map->end = map__end(new_map); - map->pgoff = new_map->pgoff; + map->pgoff = map__pgoff(new_map); map->map_ip = new_map->map_ip; map->unmap_ip = new_map->unmap_ip; /* Ensure maps are correctly ordered */ diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 538320e4260c..9565f9906e5d 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -62,19 +62,19 @@ static int __report_module(struct addr_location *al, u64 ip, Dwarf_Addr s; dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); - if (s != map__start(al->map) - al->map->pgoff) + if (s != map__start(al->map) - map__pgoff(al->map)) mod = 0; } if (!mod) mod = dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1, - map__start(al->map) - al->map->pgoff, false); + map__start(al->map) - map__pgoff(al->map), false); if (!mod) { char filename[PATH_MAX]; if (dso__build_id_filename(dso, filename, sizeof(filename), false)) mod = dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1, - map__start(al->map) - al->map->pgoff, false); + map__start(al->map) - map__pgoff(al->map), false); } if (mod) { -- cgit v1.2.3 From 4e8db2d7520f780f86055465c680e20327008a34 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Apr 2023 12:36:58 -0300 Subject: perf map: Add map__refcnt() accessor to use in the maps test To remove one more direct access to 'struct map' so that we can intecept accesses to its instantiations and refcount check it to catch use after free, etc. Cc: Adrian Hunter Cc: Alexey Bayduraev Cc: Dmitriy Vyukov Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Cc: Riccardo Mancini Cc: Stephane Eranian Cc: Stephen Brennan Link: https://lore.kernel.org/lkml/ZDbRIJknafLnDwtO@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/maps.c | 4 ++-- tools/perf/util/map.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 1c7293476aca..a6278f9c8b71 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -30,7 +30,7 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma if (map__start(map) != merged[i].start || map__end(map) != merged[i].end || strcmp(map__dso(map)->name, merged[i].name) || - refcount_read(&map->refcnt) != 1) { + refcount_read(map__refcnt(map)) != 1) { failed = true; } i++; @@ -50,7 +50,7 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma map__start(map), map__end(map), map__dso(map)->name, - refcount_read(&map->refcnt)); + refcount_read(map__refcnt(map))); } } return failed ? TEST_FAIL : TEST_OK; diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 102485699aa8..f89ab7c2d327 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -97,6 +97,11 @@ static inline bool map__priv(const struct map *map) return map->priv; } +static inline refcount_t *map__refcnt(struct map *map) +{ + return &map->refcnt; +} + static inline size_t map__size(const struct map *map) { return map__end(map) - map__start(map); -- cgit v1.2.3 From e1805aae1e0f648351913e7f5a8a7530a90c8634 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 19 Apr 2023 10:57:57 -0300 Subject: perf map: Add missing conversions to map__refcnt() Some conversions weren't performed in 4e8db2d7520f780f ("perf map: Add map__refcnt() accessor to use in the maps test"), fix it. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 6 +++--- tools/perf/util/map.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index d81b6ca18ee9..b6a8935026eb 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -112,7 +112,7 @@ void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso) map->map_ip = map__dso_map_ip; map->unmap_ip = map__dso_unmap_ip; map->erange_warned = false; - refcount_set(&map->refcnt, 1); + refcount_set(map__refcnt(map), 1); } struct map *map__new(struct machine *machine, u64 start, u64 len, @@ -292,7 +292,7 @@ bool map__has_symbols(const struct map *map) static void map__exit(struct map *map) { - BUG_ON(refcount_read(&map->refcnt) != 0); + BUG_ON(refcount_read(map__refcnt(map)) != 0); dso__zput(map->dso); } @@ -304,7 +304,7 @@ void map__delete(struct map *map) void map__put(struct map *map) { - if (map && refcount_dec_and_test(&map->refcnt)) + if (map && refcount_dec_and_test(map__refcnt(map))) map__delete(map); } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index f89ab7c2d327..4f7d9505f7ff 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -159,7 +159,7 @@ struct map *map__clone(struct map *map); static inline struct map *map__get(struct map *map) { if (map) - refcount_inc(&map->refcnt); + refcount_inc(map__refcnt(map)); return map; } -- cgit v1.2.3 From e6a9efcee55f084a5450e4853ecbbaa0b086dcd0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 19 Apr 2023 12:24:12 -0300 Subject: perf map: Add set_ methods for map->{start,end,pgoff,pgoff,reloc,erange_warned,dso,map_ip,unmap_ip,priv} To have a way to intercept usage of the reference counted struct map. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 +-- tools/perf/tests/maps.c | 16 ++++----- tools/perf/tests/vmlinux-kallsyms.c | 4 +-- tools/perf/util/machine.c | 23 ++++++------- tools/perf/util/map.c | 20 ++++++------ tools/perf/util/map.h | 65 +++++++++++++++++++++++++++++++++++++ tools/perf/util/maps.c | 6 ++-- tools/perf/util/symbol-elf.c | 26 +++++++-------- tools/perf/util/symbol.c | 33 ++++++++++--------- 9 files changed, 132 insertions(+), 65 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5d448c36ed22..eb5740154bc0 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -191,7 +191,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) if (use_browser <= 0) sleep(5); - map->erange_warned = true; + map__set_erange_warned(map, true); } static void perf_top__record_precise_ip(struct perf_top *top, @@ -225,7 +225,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, */ mutex_unlock(&he->hists->lock); - if (err == -ERANGE && !he->ms.map->erange_warned) + if (err == -ERANGE && !map__erange_warned(he->ms.map)) ui__warn_map_erange(he->ms.map, sym, ip); else if (err == -ENOMEM) { pr_err("Not enough memory for annotating '%s' symbol!\n", diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index a6278f9c8b71..8c0eb5cf8bb5 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -95,8 +95,8 @@ static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest map = dso__new_map(bpf_progs[i].name); TEST_ASSERT_VAL("failed to create map", map); - map->start = bpf_progs[i].start; - map->end = bpf_progs[i].end; + map__set_start(map, bpf_progs[i].start); + map__set_end(map, bpf_progs[i].end); TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) == 0); map__put(map); } @@ -111,16 +111,16 @@ static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest TEST_ASSERT_VAL("failed to create map", map_kcore3); /* kcore1 map overlaps over all bpf maps */ - map_kcore1->start = 100; - map_kcore1->end = 1000; + map__set_start(map_kcore1, 100); + map__set_end(map_kcore1, 1000); /* kcore2 map hides behind bpf_prog_2 */ - map_kcore2->start = 550; - map_kcore2->end = 570; + map__set_start(map_kcore2, 550); + map__set_end(map_kcore2, 570); /* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */ - map_kcore3->start = 880; - map_kcore3->end = 1100; + map__set_start(map_kcore3, 880); + map__set_end(map_kcore3, 1100); ret = maps__merge_in(maps, map_kcore1); TEST_ASSERT_VAL("failed to merge map", !ret); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index af511233c764..1078a93b01aa 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -304,7 +304,7 @@ next_pair: dso->short_name : dso->name)); if (pair) { - pair->priv = 1; + map__set_priv(pair, 1); } else { if (!header_printed) { pr_info("WARN: Maps only in vmlinux:\n"); @@ -340,7 +340,7 @@ next_pair: pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, map__start(pair), map__end(pair), map__pgoff(pair)); pr_info(" %s\n", dso->name); - pair->priv = 1; + map__set_priv(pair, 1); } } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 85787672d335..8ccbe48e23bd 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -910,8 +910,8 @@ static int machine__process_ksymbol_register(struct machine *machine, dso__set_loaded(dso); } - map->start = event->ksymbol.addr; - map->end = map__start(map) + event->ksymbol.len; + map__set_start(map, event->ksymbol.addr); + map__set_end(map, map__start(map) + event->ksymbol.len); err = maps__insert(machine__kernel_maps(machine), map); if (err) { err = -ENOMEM; @@ -1218,8 +1218,8 @@ int machine__create_extra_kernel_map(struct machine *machine, if (!map) return -ENOMEM; - map->end = xm->end; - map->pgoff = xm->pgoff; + map__set_end(map, xm->end); + map__set_pgoff(map, xm->pgoff); kmap = map__kmap(map); @@ -1291,7 +1291,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine, dest_map = maps__find(kmaps, map__pgoff(map)); if (dest_map != map) - map->pgoff = map__map_ip(dest_map, map__pgoff(map)); + map__set_pgoff(map, map__map_ip(dest_map, map__pgoff(map))); found = true; } if (found || machine->trampolines_mapped) @@ -1342,7 +1342,8 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) if (machine->vmlinux_map == NULL) return -ENOMEM; - machine->vmlinux_map->map_ip = machine->vmlinux_map->unmap_ip = identity__map_ip; + map__set_map_ip(machine->vmlinux_map, identity__map_ip); + map__set_unmap_ip(machine->vmlinux_map, identity__map_ip); return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } @@ -1623,7 +1624,7 @@ static int machine__create_module(void *arg, const char *name, u64 start, map = machine__addnew_module_map(machine, start, name); if (map == NULL) return -1; - map->end = start + size; + map__set_end(map, start + size); dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); map__put(map); @@ -1659,14 +1660,14 @@ static int machine__create_modules(struct machine *machine) static void machine__set_kernel_mmap(struct machine *machine, u64 start, u64 end) { - machine->vmlinux_map->start = start; - machine->vmlinux_map->end = end; + map__set_start(machine->vmlinux_map, start); + map__set_end(machine->vmlinux_map, end); /* * Be a bit paranoid here, some perf.data file came with * a zero sized synthesized MMAP event for the kernel. */ if (start == 0 && end == 0) - machine->vmlinux_map->end = ~0ULL; + map__set_end(machine->vmlinux_map, ~0ULL); } static int machine__update_kernel_mmap(struct machine *machine, @@ -1810,7 +1811,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, if (map == NULL) goto out_problem; - map->end = map__start(map) + xm->end - xm->start; + map__set_end(map, map__start(map) + xm->end - xm->start); if (build_id__is_defined(bid)) dso__set_build_id(map__dso(map), bid); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index b6a8935026eb..bdd2742fa35b 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -104,14 +104,14 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso) { - map->start = start; - map->end = end; - map->pgoff = pgoff; - map->reloc = 0; - map->dso = dso__get(dso); - map->map_ip = map__dso_map_ip; - map->unmap_ip = map__dso_unmap_ip; - map->erange_warned = false; + map__set_start(map, start); + map__set_end(map, end); + map__set_pgoff(map, pgoff); + map__set_reloc(map, 0); + map__set_dso(map, dso__get(dso)); + map__set_map_ip(map, map__dso_map_ip); + map__set_unmap_ip(map, map__dso_unmap_ip); + map__set_erange_warned(map, false); refcount_set(map__refcnt(map), 1); } @@ -317,7 +317,7 @@ void map__fixup_start(struct map *map) if (nd != NULL) { struct symbol *sym = rb_entry(nd, struct symbol, rb_node); - map->start = sym->start; + map__set_start(map, sym->start); } } @@ -329,7 +329,7 @@ void map__fixup_end(struct map *map) if (nd != NULL) { struct symbol *sym = rb_entry(nd, struct symbol, rb_node); - map->end = sym->end; + map__set_end(map, sym->end); } } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 4f7d9505f7ff..0760c671314d 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -62,6 +62,16 @@ static inline u64 map__unmap_ip(const struct map *map, u64 ip) return map->unmap_ip(map, ip); } +static inline void *map__map_ip_ptr(struct map *map) +{ + return map->map_ip; +} + +static inline void* map__unmap_ip_ptr(struct map *map) +{ + return map->unmap_ip; +} + static inline u64 map__start(const struct map *map) { return map->start; @@ -102,6 +112,11 @@ static inline refcount_t *map__refcnt(struct map *map) return &map->refcnt; } +static inline bool map__erange_warned(struct map *map) +{ + return map->erange_warned; +} + static inline size_t map__size(const struct map *map) { return map__end(map) - map__start(map); @@ -231,4 +246,54 @@ static inline int is_no_dso_memory(const char *filename) !strncmp(filename, "/SYSV", 5) || !strcmp(filename, "[heap]"); } + +static inline void map__set_start(struct map *map, u64 start) +{ + map->start = start; +} + +static inline void map__set_end(struct map *map, u64 end) +{ + map->end = end; +} + +static inline void map__set_pgoff(struct map *map, u64 pgoff) +{ + map->pgoff = pgoff; +} + +static inline void map__add_pgoff(struct map *map, u64 inc) +{ + map->pgoff += inc; +} + +static inline void map__set_reloc(struct map *map, u64 reloc) +{ + map->reloc = reloc; +} + +static inline void map__set_priv(struct map *map, int priv) +{ + map->priv = priv; +} + +static inline void map__set_erange_warned(struct map *map, bool erange_warned) +{ + map->erange_warned = erange_warned; +} + +static inline void map__set_dso(struct map *map, struct dso *dso) +{ + map->dso = dso; +} + +static inline void map__set_map_ip(struct map *map, u64 (*map_ip)(const struct map *map, u64 ip)) +{ + map->map_ip = map_ip; +} + +static inline void map__set_unmap_ip(struct map *map, u64 (*unmap_ip)(const struct map *map, u64 rip)) +{ + map->unmap_ip = unmap_ip; +} #endif /* __PERF_MAP_H */ diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 8a13396acd1a..df2fc8221f3c 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -339,7 +339,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) goto put_map; } - before->end = map__start(map); + map__set_end(before, map__start(map)); err = __maps__insert(maps, before); if (err) { map__put(before); @@ -359,8 +359,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) goto put_map; } - after->start = map__end(map); - after->pgoff += map__end(map) - map__start(pos->map); + map__set_start(after, map__end(map)); + map__add_pgoff(after, map__end(map) - map__start(pos->map)); assert(map__map_ip(pos->map, map__end(map)) == map__map_ip(after, map__end(map))); err = __maps__insert(maps, after); diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 35724f6a84fa..2a165d83aac4 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1354,11 +1354,11 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, */ if (*remap_kernel && dso->kernel && !kmodule) { *remap_kernel = false; - map->start = shdr->sh_addr + ref_reloc(kmap); - map->end = map__start(map) + shdr->sh_size; - map->pgoff = shdr->sh_offset; - map->map_ip = map__dso_map_ip; - map->unmap_ip = map__dso_unmap_ip; + map__set_start(map, shdr->sh_addr + ref_reloc(kmap)); + map__set_end(map, map__start(map) + shdr->sh_size); + map__set_pgoff(map, shdr->sh_offset); + map__set_map_ip(map, map__dso_map_ip); + map__set_unmap_ip(map, map__dso_unmap_ip); /* Ensure maps are correctly ordered */ if (kmaps) { int err; @@ -1379,7 +1379,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, */ if (*remap_kernel && kmodule) { *remap_kernel = false; - map->pgoff = shdr->sh_offset; + map__set_pgoff(map, shdr->sh_offset); } *curr_mapp = map; @@ -1414,11 +1414,12 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, map__kmap(curr_map)->kmaps = kmaps; if (adjust_kernel_syms) { - curr_map->start = shdr->sh_addr + ref_reloc(kmap); - curr_map->end = map__start(curr_map) + shdr->sh_size; - curr_map->pgoff = shdr->sh_offset; + map__set_start(curr_map, shdr->sh_addr + ref_reloc(kmap)); + map__set_end(curr_map, map__start(curr_map) + shdr->sh_size); + map__set_pgoff(curr_map, shdr->sh_offset); } else { - curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; + map__set_map_ip(curr_map, identity__map_ip); + map__set_unmap_ip(curr_map, identity__map_ip); } curr_dso->symtab_type = dso->symtab_type; if (maps__insert(kmaps, curr_map)) @@ -1525,8 +1526,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, if (strcmp(elf_name, kmap->ref_reloc_sym->name)) continue; kmap->ref_reloc_sym->unrelocated_addr = sym.st_value; - map->reloc = kmap->ref_reloc_sym->addr - - kmap->ref_reloc_sym->unrelocated_addr; + map__set_reloc(map, kmap->ref_reloc_sym->addr - kmap->ref_reloc_sym->unrelocated_addr); break; } } @@ -1536,7 +1536,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, * attempted to prelink vdso to its virtual address. */ if (dso__is_vdso(dso)) - map->reloc = map__start(map) - dso->text_offset; + map__set_reloc(map, map__start(map) - dso->text_offset); dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap); /* diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 01fa5560a0bb..35d860f95b18 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -279,7 +279,7 @@ void maps__fixup_end(struct maps *maps) maps__for_each_entry(maps, curr) { if (prev != NULL && !map__end(prev->map)) - prev->map->end = map__start(curr->map); + map__set_end(prev->map, map__start(curr->map)); prev = curr; } @@ -289,7 +289,7 @@ void maps__fixup_end(struct maps *maps) * last map final address. */ if (curr && !map__end(curr->map)) - curr->map->end = ~0ULL; + map__set_end(curr->map, ~0ULL); up_write(maps__lock(maps)); } @@ -944,7 +944,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, return -1; } - curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; + map__set_map_ip(curr_map, identity__map_ip); + map__set_unmap_ip(curr_map, identity__map_ip); if (maps__insert(kmaps, curr_map)) { dso__put(ndso); return -1; @@ -1250,8 +1251,8 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) return -ENOMEM; } - list_node->map->end = map__start(list_node->map) + len; - list_node->map->pgoff = pgoff; + map__set_end(list_node->map, map__start(list_node->map) + len); + map__set_pgoff(list_node->map, pgoff); list_add(&list_node->node, &md->maps); @@ -1286,7 +1287,7 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) * |new......| -> |new..| * |old....| -> |old....| */ - new_map->end = map__start(old_map); + map__set_end(new_map, map__start(old_map)); } else { /* * |new.............| -> |new..| |new..| @@ -1306,10 +1307,10 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) goto out; } - m->map->end = map__start(old_map); + map__set_end(m->map, map__start(old_map)); list_add_tail(&m->node, &merged); - new_map->pgoff += map__end(old_map) - map__start(new_map); - new_map->start = map__end(old_map); + map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); + map__set_start(new_map, map__end(old_map)); } } else { /* @@ -1329,8 +1330,8 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) * |new......| -> |new...| * |old....| -> |old....| */ - new_map->pgoff += map__end(old_map) - map__start(new_map); - new_map->start = map__end(old_map); + map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); + map__set_start(new_map, map__end(old_map)); } } } @@ -1457,11 +1458,11 @@ static int dso__load_kcore(struct dso *dso, struct map *map, list_del_init(&new_node->node); if (new_map == replacement_map) { - map->start = map__start(new_map); - map->end = map__end(new_map); - map->pgoff = map__pgoff(new_map); - map->map_ip = new_map->map_ip; - map->unmap_ip = new_map->unmap_ip; + map__set_start(map, map__start(new_map)); + map__set_end(map, map__end(new_map)); + map__set_pgoff(map, map__pgoff(new_map)); + map__set_map_ip(map, map__map_ip_ptr(new_map)); + map__set_unmap_ip(map, map__unmap_ip_ptr(new_map)); /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); -- cgit v1.2.3 From 2832ef81d4c75d4f0e3945bd2cb0b7012313cbb3 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 19 Apr 2023 12:57:53 -0300 Subject: perf map: Add reference count checking There's no strict get/put policy with map that leads to leaks or use after free. Reference count checking identifies correct pairing of gets and puts. Committer notes: Extracted from a larger patch removing bits that were covered by the use of pre-existing map__ accessors (e.g. maps__nr_maps()) and new ones added (map__refcnt() and the maps__set_ ones) to reduce RC_CHK_ACCESS(maps)-> source code pollution. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexey Bayduraev Cc: Dmitriy Vyukov Cc: Jiri Olsa Cc: Namhyung Kim Cc: Riccardo Mancini Cc: Stephane Eranian Cc: Stephen Brennan Link: https://lore.kernel.org/lkml/20230407230405.2931830-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_link.c | 2 +- tools/perf/util/machine.c | 2 +- tools/perf/util/map.c | 43 ++++++++++++++++++-------------- tools/perf/util/map.h | 58 +++++++++++++++++++++++-------------------- tools/perf/util/maps.c | 4 +-- tools/perf/util/symbol.c | 4 +-- 6 files changed, 62 insertions(+), 51 deletions(-) (limited to 'tools/perf/util/map.h') diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 64ce8097889c..141e2972e34f 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -145,7 +145,7 @@ static int find_sample(struct sample *samples, size_t nr_samples, { while (nr_samples--) { if (samples->thread == t && - samples->map == m && + RC_CHK_ACCESS(samples->map) == RC_CHK_ACCESS(m) && samples->sym == s) return 1; samples++; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 8ccbe48e23bd..9e02e19c1b7a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -953,7 +953,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine, if (!map) return 0; - if (map != machine->vmlinux_map) + if (RC_CHK_ACCESS(map) != RC_CHK_ACCESS(machine->vmlinux_map)) maps__remove(machine__kernel_maps(machine), map); else { struct dso *dso = map__dso(map); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index bdd2742fa35b..b7f890950909 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -120,11 +120,13 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, u32 prot, u32 flags, struct build_id *bid, char *filename, struct thread *thread) { - struct map *map = malloc(sizeof(*map)); + struct map *result; + RC_STRUCT(map) *map; struct nsinfo *nsi = NULL; struct nsinfo *nnsi; - if (map != NULL) { + map = malloc(sizeof(*map)); + if (ADD_RC_CHK(result, map)) { char newfilename[PATH_MAX]; struct dso *dso, *header_bid_dso; int anon, no_dso, vdso, android; @@ -167,7 +169,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (dso == NULL) goto out_delete; - map__init(map, start, start + len, pgoff, dso); + map__init(result, start, start + len, pgoff, dso); if (anon || no_dso) { map->map_ip = map->unmap_ip = identity__map_ip; @@ -204,10 +206,10 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, } dso__put(dso); } - return map; + return result; out_delete: nsinfo__put(nsi); - free(map); + RC_CHK_FREE(result); return NULL; } @@ -218,16 +220,18 @@ out_delete: */ struct map *map__new2(u64 start, struct dso *dso) { - struct map *map = calloc(1, (sizeof(*map) + - (dso->kernel ? sizeof(struct kmap) : 0))); - if (map != NULL) { + struct map *result; + RC_STRUCT(map) *map; + + map = calloc(1, sizeof(*map) + (dso->kernel ? sizeof(struct kmap) : 0)); + if (ADD_RC_CHK(result, map)) { /* * ->end will be filled after we load all the symbols */ - map__init(map, start, 0, 0, dso); + map__init(result, start, 0, 0, dso); } - return map; + return result; } bool __map__is_kernel(const struct map *map) @@ -293,19 +297,21 @@ bool map__has_symbols(const struct map *map) static void map__exit(struct map *map) { BUG_ON(refcount_read(map__refcnt(map)) != 0); - dso__zput(map->dso); + dso__zput(RC_CHK_ACCESS(map)->dso); } void map__delete(struct map *map) { map__exit(map); - free(map); + RC_CHK_FREE(map); } void map__put(struct map *map) { if (map && refcount_dec_and_test(map__refcnt(map))) map__delete(map); + else + RC_CHK_PUT(map); } void map__fixup_start(struct map *map) @@ -400,20 +406,21 @@ struct symbol *map__find_symbol_by_name(struct map *map, const char *name) struct map *map__clone(struct map *from) { - size_t size = sizeof(struct map); - struct map *map; + struct map *result; + RC_STRUCT(map) *map; + size_t size = sizeof(RC_STRUCT(map)); struct dso *dso = map__dso(from); if (dso && dso->kernel) size += sizeof(struct kmap); - map = memdup(from, size); - if (map != NULL) { + map = memdup(RC_CHK_ACCESS(from), size); + if (ADD_RC_CHK(result, map)) { refcount_set(&map->refcnt, 1); map->dso = dso__get(dso); } - return map; + return result; } size_t map__fprintf(struct map *map, FILE *fp) @@ -567,7 +574,7 @@ struct kmap *__map__kmap(struct map *map) if (!dso || !dso->kernel) return NULL; - return (struct kmap *)(map + 1); + return (struct kmap *)(&RC_CHK_ACCESS(map)[1]); } struct kmap *map__kmap(struct map *map) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 0760c671314d..823ab7fc0acf 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -10,12 +10,13 @@ #include #include #include +#include struct dso; struct maps; struct machine; -struct map { +DECLARE_RC_STRUCT(map) { u64 start; u64 end; bool erange_warned:1; @@ -49,72 +50,72 @@ u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); static inline struct dso *map__dso(const struct map *map) { - return map->dso; + return RC_CHK_ACCESS(map)->dso; } static inline u64 map__map_ip(const struct map *map, u64 ip) { - return map->map_ip(map, ip); + return RC_CHK_ACCESS(map)->map_ip(map, ip); } static inline u64 map__unmap_ip(const struct map *map, u64 ip) { - return map->unmap_ip(map, ip); + return RC_CHK_ACCESS(map)->unmap_ip(map, ip); } static inline void *map__map_ip_ptr(struct map *map) { - return map->map_ip; + return RC_CHK_ACCESS(map)->map_ip; } static inline void* map__unmap_ip_ptr(struct map *map) { - return map->unmap_ip; + return RC_CHK_ACCESS(map)->unmap_ip; } static inline u64 map__start(const struct map *map) { - return map->start; + return RC_CHK_ACCESS(map)->start; } static inline u64 map__end(const struct map *map) { - return map->end; + return RC_CHK_ACCESS(map)->end; } static inline u64 map__pgoff(const struct map *map) { - return map->pgoff; + return RC_CHK_ACCESS(map)->pgoff; } static inline u64 map__reloc(const struct map *map) { - return map->reloc; + return RC_CHK_ACCESS(map)->reloc; } static inline u32 map__flags(const struct map *map) { - return map->flags; + return RC_CHK_ACCESS(map)->flags; } static inline u32 map__prot(const struct map *map) { - return map->prot; + return RC_CHK_ACCESS(map)->prot; } static inline bool map__priv(const struct map *map) { - return map->priv; + return RC_CHK_ACCESS(map)->priv; } static inline refcount_t *map__refcnt(struct map *map) { - return &map->refcnt; + return &RC_CHK_ACCESS(map)->refcnt; } static inline bool map__erange_warned(struct map *map) { - return map->erange_warned; + return RC_CHK_ACCESS(map)->erange_warned; } static inline size_t map__size(const struct map *map) @@ -173,9 +174,12 @@ struct map *map__clone(struct map *map); static inline struct map *map__get(struct map *map) { - if (map) + struct map *result; + + if (RC_CHK_GET(result, map)) refcount_inc(map__refcnt(map)); - return map; + + return result; } void map__put(struct map *map); @@ -249,51 +253,51 @@ static inline int is_no_dso_memory(const char *filename) static inline void map__set_start(struct map *map, u64 start) { - map->start = start; + RC_CHK_ACCESS(map)->start = start; } static inline void map__set_end(struct map *map, u64 end) { - map->end = end; + RC_CHK_ACCESS(map)->end = end; } static inline void map__set_pgoff(struct map *map, u64 pgoff) { - map->pgoff = pgoff; + RC_CHK_ACCESS(map)->pgoff = pgoff; } static inline void map__add_pgoff(struct map *map, u64 inc) { - map->pgoff += inc; + RC_CHK_ACCESS(map)->pgoff += inc; } static inline void map__set_reloc(struct map *map, u64 reloc) { - map->reloc = reloc; + RC_CHK_ACCESS(map)->reloc = reloc; } static inline void map__set_priv(struct map *map, int priv) { - map->priv = priv; + RC_CHK_ACCESS(map)->priv = priv; } static inline void map__set_erange_warned(struct map *map, bool erange_warned) { - map->erange_warned = erange_warned; + RC_CHK_ACCESS(map)->erange_warned = erange_warned; } static inline void map__set_dso(struct map *map, struct dso *dso) { - map->dso = dso; + RC_CHK_ACCESS(map)->dso = dso; } static inline void map__set_map_ip(struct map *map, u64 (*map_ip)(const struct map *map, u64 ip)) { - map->map_ip = map_ip; + RC_CHK_ACCESS(map)->map_ip = map_ip; } static inline void map__set_unmap_ip(struct map *map, u64 (*unmap_ip)(const struct map *map, u64 rip)) { - map->unmap_ip = unmap_ip; + RC_CHK_ACCESS(map)->unmap_ip = unmap_ip; } #endif /* __PERF_MAP_H */ diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index df2fc8221f3c..1aeb1db58fe5 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -126,7 +126,7 @@ void maps__remove(struct maps *maps, struct map *map) RC_CHK_ACCESS(maps)->last_search_by_name = NULL; rb_node = maps__find_node(maps, map); - assert(rb_node->map == map); + assert(rb_node->RC_CHK_ACCESS(map) == RC_CHK_ACCESS(map)); __maps__remove(maps, rb_node); if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); @@ -420,7 +420,7 @@ struct map_rb_node *maps__find_node(struct maps *maps, struct map *map) struct map_rb_node *rb_node; maps__for_each_entry(maps, rb_node) { - if (rb_node->map == map) + if (rb_node->RC_CHK_ACCESS(map) == RC_CHK_ACCESS(map)) return rb_node; } return NULL; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 35d860f95b18..6b9c55784b56 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -865,7 +865,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, *module++ = '\0'; curr_map_dso = map__dso(curr_map); if (strcmp(curr_map_dso->short_name, module)) { - if (curr_map != initial_map && + if (RC_CHK_ACCESS(curr_map) != RC_CHK_ACCESS(initial_map) && dso->kernel == DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { /* @@ -1457,7 +1457,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, list_del_init(&new_node->node); - if (new_map == replacement_map) { + if (RC_CHK_ACCESS(new_map) == RC_CHK_ACCESS(replacement_map)) { map__set_start(map, map__start(new_map)); map__set_end(map, map__end(new_map)); map__set_pgoff(map, map__pgoff(new_map)); -- cgit v1.2.3