^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <assert.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "map_symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "vdso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "srcline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "unwind.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "srccode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "ui/ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static void __maps__insert(struct maps *maps, struct map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static inline int is_android_lib(const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return strstarts(filename, "/data/app-lib/") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) strstarts(filename, "/system/lib/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static inline bool replace_android_lib(const char *filename, char *newfilename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) const char *libname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) char *app_abi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) size_t app_abi_length, new_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) size_t lib_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) libname = strrchr(filename, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (libname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) lib_length = strlen(libname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) app_abi = getenv("APP_ABI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (!app_abi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) app_abi_length = strlen(app_abi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (strstarts(filename, "/data/app-lib/")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) char *apk_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (!app_abi_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) new_length = 7 + app_abi_length + lib_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) apk_path = getenv("APK_PATH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (apk_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) new_length += strlen(apk_path) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (new_length > PATH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) snprintf(newfilename, new_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "%s/libs/%s/%s", apk_path, app_abi, libname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (new_length > PATH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) snprintf(newfilename, new_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) "libs/%s/%s", app_abi, libname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (strstarts(filename, "/system/lib/")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) char *ndk, *app;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) const char *arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int ndk_length, app_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ndk = getenv("NDK_ROOT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) app = getenv("APP_PLATFORM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!(ndk && app))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ndk_length = strlen(ndk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) app_length = strlen(app);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!(ndk_length && app_length && app_abi_length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) arch = !strncmp(app_abi, "arm", 3) ? "arm" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) !strncmp(app_abi, "mips", 4) ? "mips" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) !strncmp(app_abi, "x86", 3) ? "x86" : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!arch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) new_length = 27 + ndk_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) app_length + lib_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) + strlen(arch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (new_length > PATH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) snprintf(newfilename, new_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "%.*s/platforms/%.*s/arch-%s/usr/lib/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ndk_length, ndk, app_length, app, arch, libname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) map->start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) map->end = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) map->pgoff = pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) map->reloc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) map->dso = dso__get(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) map->map_ip = map__map_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) map->unmap_ip = map__unmap_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) RB_CLEAR_NODE(&map->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) map->erange_warned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) refcount_set(&map->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct map *map__new(struct machine *machine, u64 start, u64 len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u64 pgoff, struct dso_id *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u32 prot, u32 flags, char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct map *map = malloc(sizeof(*map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct nsinfo *nsi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct nsinfo *nnsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (map != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) char newfilename[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct dso *dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int anon, no_dso, vdso, android;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) android = is_android_lib(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) anon = is_anon_memory(filename) || flags & MAP_HUGETLB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) vdso = is_vdso_map(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) no_dso = is_no_dso_memory(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) map->prot = prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) map->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) nsi = nsinfo__get(thread->nsinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if ((anon || no_dso) && nsi && (prot & PROT_EXEC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) snprintf(newfilename, sizeof(newfilename),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) "/tmp/perf-%d.map", nsi->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) filename = newfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (android) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (replace_android_lib(filename, newfilename))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) filename = newfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (vdso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* The vdso maps are always on the host and not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * container. Ensure that we don't use setns to look
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * them up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) nnsi = nsinfo__copy(nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (nnsi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) nsinfo__put(nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) nnsi->need_setns = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) nsi = nnsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pgoff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dso = machine__findnew_vdso(machine, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dso = machine__findnew_dso_id(machine, filename, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (dso == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) map__init(map, start, start + len, pgoff, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (anon || no_dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) map->map_ip = map->unmap_ip = identity__map_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * Set memory without DSO as loaded. All map__find_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * functions still return NULL, and we avoid the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * unnecessary map__load warning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!(prot & PROT_EXEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dso__set_loaded(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dso->nsinfo = nsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) dso__put(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) out_delete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) nsinfo__put(nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) free(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * Constructor variant for modules (where we know from /proc/modules where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * they are loaded) and for vmlinux, where only after we load all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * symbols we'll know where it starts and ends.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct map *map__new2(u64 start, struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct map *map = calloc(1, (sizeof(*map) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) (dso->kernel ? sizeof(struct kmap) : 0)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (map != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * ->end will be filled after we load all the symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) map__init(map, start, 0, 0, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) bool __map__is_kernel(const struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!map->dso->kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return machine__kernel_map(map__kmaps((struct map *)map)->machine) == map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) bool __map__is_extra_kernel_map(const struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct kmap *kmap = __map__kmap((struct map *)map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return kmap && kmap->name[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bool __map__is_bpf_prog(const struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * If PERF_RECORD_BPF_EVENT is not included, the dso will not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * guess the type based on name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) name = map->dso->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return name && (strstr(name, "bpf_prog_") == name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) bool __map__is_bpf_image(const struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * If PERF_RECORD_KSYMBOL is not included, the dso will not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * guess the type based on name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) name = map->dso->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return name && is_bpf_image(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) bool __map__is_ool(const struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return map->dso && map->dso->binary_type == DSO_BINARY_TYPE__OOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bool map__has_symbols(const struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return dso__has_symbols(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void map__exit(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) BUG_ON(refcount_read(&map->refcnt) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dso__zput(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) void map__delete(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) map__exit(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) free(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) void map__put(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (map && refcount_dec_and_test(&map->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) map__delete(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) void map__fixup_start(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct rb_root_cached *symbols = &map->dso->symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct rb_node *nd = rb_first_cached(symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (nd != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) map->start = sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) void map__fixup_end(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct rb_root_cached *symbols = &map->dso->symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct rb_node *nd = rb_last(&symbols->rb_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (nd != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) map->end = sym->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define DSO__DELETED "(deleted)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int map__load(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) const char *name = map->dso->long_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (dso__loaded(map->dso))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) nr = dso__load(map->dso, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (nr < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (map->dso->has_build_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) char sbuild_id[SBUILD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) build_id__sprintf(&map->dso->bid, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) pr_debug("%s with build id %s not found", name, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) pr_debug("Failed to open %s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pr_debug(", continuing without symbols\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) } else if (nr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #ifdef HAVE_LIBELF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) const size_t len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const size_t real_len = len - sizeof(DSO__DELETED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (len > sizeof(DSO__DELETED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) strcmp(name + real_len + 1, DSO__DELETED) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pr_debug("%.*s was updated (is prelink enabled?). "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) "Restart the long running apps that use it!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) (int)real_len, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) pr_debug("no symbols found in %s, maybe install a debug package?\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct symbol *map__find_symbol(struct map *map, u64 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (map__load(map) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return dso__find_symbol(map->dso, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (map__load(map) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!dso__sorted_by_name(map->dso))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dso__sort_by_name(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return dso__find_symbol_by_name(map->dso, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct map *map__clone(struct map *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) size_t size = sizeof(struct map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (from->dso && from->dso->kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) size += sizeof(struct kmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) map = memdup(from, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (map != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) refcount_set(&map->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) RB_CLEAR_NODE(&map->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dso__get(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) size_t map__fprintf(struct map *map, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) map->start, map->end, map->pgoff, map->dso->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) size_t map__fprintf_dsoname(struct map *map, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) char buf[symbol_conf.pad_output_len_dso + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) const char *dsoname = "[unknown]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (map && map->dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (symbol_conf.show_kernel_path && map->dso->long_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dsoname = map->dso->long_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) dsoname = map->dso->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (symbol_conf.pad_output_len_dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) scnprintf_pad(buf, symbol_conf.pad_output_len_dso, "%s", dsoname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dsoname = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return fprintf(fp, "%s", dsoname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) char *map__srcline(struct map *map, u64 addr, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (map == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return SRCLINE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, true, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (map && map->dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) char *srcline = map__srcline(map, addr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = fprintf(fp, "%s%s", prefix, srcline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) free_srcline(srcline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) void srccode_state_free(struct srccode_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) zfree(&state->srcfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) state->line = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * map__rip_2objdump - convert symbol start address to objdump address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @map: memory map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * @rip: symbol start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * relative to section start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Return: Address suitable for passing to "objdump --start-address="
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) u64 map__rip_2objdump(struct map *map, u64 rip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct kmap *kmap = __map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * vmlinux does not have program headers for PTI entry trampolines and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * kcore may not either. However the trampoline object code is on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * main kernel map, so just use that instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps && kmap->kmaps->machine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct map *kernel_map = machine__kernel_map(kmap->kmaps->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (kernel_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) map = kernel_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!map->dso->adjust_symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return rip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (map->dso->rel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return rip - map->pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * kernel modules also have DSO_TYPE_USER in dso->kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * but all kernel modules are ET_REL, so won't get here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (map->dso->kernel == DSO_SPACE__USER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return rip + map->dso->text_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return map->unmap_ip(map, rip) - map->reloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * map__objdump_2mem - convert objdump address to a memory address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * @map: memory map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * @ip: objdump address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Closely related to map__rip_2objdump(), this function takes an address from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * objdump and converts it to a memory address. Note this assumes that @map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * contains the address. To be sure the result is valid, check it forwards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * Return: Memory address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) u64 map__objdump_2mem(struct map *map, u64 ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (!map->dso->adjust_symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return map->unmap_ip(map, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (map->dso->rel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return map->unmap_ip(map, ip + map->pgoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * kernel modules also have DSO_TYPE_USER in dso->kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * but all kernel modules are ET_REL, so won't get here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (map->dso->kernel == DSO_SPACE__USER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return map->unmap_ip(map, ip - map->dso->text_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return ip + map->reloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) void maps__init(struct maps *maps, struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) maps->entries = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) init_rwsem(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) maps->machine = machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) maps->last_search_by_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) maps->nr_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) maps->maps_by_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) refcount_set(&maps->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static void __maps__free_maps_by_name(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * Free everything to try to do it from the rbtree in the next search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) zfree(&maps->maps_by_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) maps->nr_maps_allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) void maps__insert(struct maps *maps, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) down_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) __maps__insert(maps, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ++maps->nr_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (map->dso && map->dso->kernel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct kmap *kmap = map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (kmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kmap->kmaps = maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pr_err("Internal error: kernel dso with non kernel map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * If we already performed some search by name, then we need to add the just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * inserted map and resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (maps->maps_by_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (maps->nr_maps > maps->nr_maps_allocated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int nr_allocate = maps->nr_maps * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct map **maps_by_name = realloc(maps->maps_by_name, nr_allocate * sizeof(map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (maps_by_name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) __maps__free_maps_by_name(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) up_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) maps->maps_by_name = maps_by_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) maps->nr_maps_allocated = nr_allocate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) maps->maps_by_name[maps->nr_maps - 1] = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) __maps__sort_by_name(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) up_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static void __maps__remove(struct maps *maps, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) rb_erase_init(&map->rb_node, &maps->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) void maps__remove(struct maps *maps, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) down_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (maps->last_search_by_name == map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) maps->last_search_by_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) __maps__remove(maps, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) --maps->nr_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (maps->maps_by_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) __maps__free_maps_by_name(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) up_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static void __maps__purge(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct map *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) maps__for_each_entry_safe(maps, pos, next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) rb_erase_init(&pos->rb_node, &maps->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) map__put(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) void maps__exit(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) down_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) __maps__purge(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) up_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) bool maps__empty(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return !maps__first(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct maps *maps__new(struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct maps *maps = zalloc(sizeof(*maps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (maps != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) maps__init(maps, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) void maps__delete(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) maps__exit(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) unwind__finish_access(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) free(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) void maps__put(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (maps && refcount_dec_and_test(&maps->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) maps__delete(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct map *map = maps__find(maps, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* Ensure map is loaded before using map->map_ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (map != NULL && map__load(map) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (mapp != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *mapp = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return map__find_symbol(map, map->map_ip(map, addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static bool map__contains_symbol(struct map *map, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u64 ip = map->unmap_ip(map, sym->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return ip >= map->start && ip < map->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct map *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) down_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) maps__for_each_entry(maps, pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) sym = map__find_symbol_by_name(pos, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (sym == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (!map__contains_symbol(pos, sym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (mapp != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) *mapp = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) up_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ams->addr < ams->ms.map->start || ams->addr >= ams->ms.map->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (maps == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) ams->ms.map = maps__find(maps, ams->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (ams->ms.map == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return ams->ms.sym ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) size_t maps__fprintf(struct maps *maps, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) size_t printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct map *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) down_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) maps__for_each_entry(maps, pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) printed += fprintf(fp, "Map:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) printed += map__fprintf(pos, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (verbose > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) printed += dso__fprintf(pos->dso, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) printed += fprintf(fp, "--\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) up_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct rb_root *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct rb_node *next, *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) down_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) root = &maps->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * Find first map where end > map->start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * Same as find_vma() in kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) next = root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) first = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct map *pos = rb_entry(next, struct map, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (pos->end > map->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) first = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (pos->start <= map->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) next = next->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) next = next->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) next = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct map *pos = rb_entry(next, struct map, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) next = rb_next(&pos->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * Stop if current map starts after map->end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * Maps are ordered by start: next will not overlap for sure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (pos->start >= map->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (verbose >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (use_browser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pr_debug("overlapping maps in %s (disable tui for more info)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) map->dso->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) fputs("overlapping maps:\n", fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) map__fprintf(map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) map__fprintf(pos, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) rb_erase_init(&pos->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * Now check if we need to create new maps for areas not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * overlapped by the new map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (map->start > pos->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct map *before = map__clone(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (before == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto put_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) before->end = map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) __maps__insert(maps, before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (verbose >= 2 && !use_browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) map__fprintf(before, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) map__put(before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (map->end < pos->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct map *after = map__clone(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (after == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) goto put_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) after->start = map->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) after->pgoff += map->end - pos->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) __maps__insert(maps, after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (verbose >= 2 && !use_browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) map__fprintf(after, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) map__put(after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) put_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) map__put(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) up_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * XXX This should not really _copy_ te maps, but refcount them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int maps__clone(struct thread *thread, struct maps *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct maps *maps = thread->maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) down_read(&parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) maps__for_each_entry(parent, map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct map *new = map__clone(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (new == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) err = unwind__prepare_access(maps, new, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) maps__insert(maps, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) map__put(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) up_read(&parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static void __maps__insert(struct maps *maps, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct rb_node **p = &maps->entries.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) const u64 ip = map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct map *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) m = rb_entry(parent, struct map, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (ip < m->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) rb_link_node(&map->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) rb_insert_color(&map->rb_node, &maps->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) map__get(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct map *maps__find(struct maps *maps, u64 ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct map *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) down_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) p = maps->entries.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) while (p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) m = rb_entry(p, struct map, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (ip < m->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) p = p->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) else if (ip >= m->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) p = p->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) up_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct map *maps__first(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct rb_node *first = rb_first(&maps->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return rb_entry(first, struct map, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static struct map *__map__next(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct rb_node *next = rb_next(&map->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return rb_entry(next, struct map, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct map *map__next(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return map ? __map__next(map) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct kmap *__map__kmap(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!map->dso || !map->dso->kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return (struct kmap *)(map + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct kmap *map__kmap(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct kmap *kmap = __map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!kmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pr_err("Internal error: map__kmap with a non-kernel map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return kmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) struct maps *map__kmaps(struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct kmap *kmap = map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (!kmap || !kmap->kmaps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) pr_err("Internal error: map__kmaps with a non-kernel map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return kmap->kmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }