Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }