Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_MAP_H #define __PERF_MAP_H #include <linux/refcount.h> #include <linux/compiler.h> #include <linux/list.h> #include <linux/rbtree.h> #include <stdio.h> #include <string.h> #include <stdbool.h> #include <linux/types.h> #include <internal/rc_check.h> struct dso; struct maps; struct machine; enum mapping_type { /* map__map_ip/map__unmap_ip are given as offsets in the DSO. */ MAPPING_TYPE__DSO, /* map__map_ip/map__unmap_ip are just the given ip value. */ MAPPING_TYPE__IDENTITY, }; DECLARE_RC_STRUCT(map) { u64 start; u64 end; u64 pgoff; u64 reloc; struct dso *dso; refcount_t refcnt; u32 prot; u32 flags; enum mapping_type mapping_type:8; bool erange_warned; bool priv; }; struct kmap; struct kmap *__map__kmap(struct map *map); struct kmap *map__kmap(struct map *map); struct maps *map__kmaps(struct map *map); static inline struct dso *map__dso(const struct map *map) { return RC_CHK_ACCESS(map)->dso; } static inline u64 map__start(const struct map *map) { return RC_CHK_ACCESS(map)->start; } static inline u64 map__end(const struct map *map) { return RC_CHK_ACCESS(map)->end; } static inline u64 map__pgoff(const struct map *map) { return RC_CHK_ACCESS(map)->pgoff; } static inline u64 map__reloc(const struct map *map) { return RC_CHK_ACCESS(map)->reloc; } static inline u32 map__flags(const struct map *map) { return RC_CHK_ACCESS(map)->flags; } static inline u32 map__prot(const struct map *map) { return RC_CHK_ACCESS(map)->prot; } static inline bool map__priv(const struct map *map) { return RC_CHK_ACCESS(map)->priv; } static inline refcount_t *map__refcnt(struct map *map) { return &RC_CHK_ACCESS(map)->refcnt; } static inline bool map__erange_warned(struct map *map) { return RC_CHK_ACCESS(map)->erange_warned; } static inline size_t map__size(const struct map *map) { return map__end(map) - map__start(map); } /* ip -> dso rip */ static inline u64 map__dso_map_ip(const struct map *map, u64 ip) { return ip - map__start(map) + map__pgoff(map); } /* dso rip -> ip */ static inline u64 map__dso_unmap_ip(const struct map *map, u64 rip) { return rip + map__start(map) - map__pgoff(map); } static inline u64 map__map_ip(const struct map *map, u64 ip_or_rip) { if ((RC_CHK_ACCESS(map)->mapping_type) == MAPPING_TYPE__DSO) return map__dso_map_ip(map, ip_or_rip); else return ip_or_rip; } static inline u64 map__unmap_ip(const struct map *map, u64 ip_or_rip) { if ((RC_CHK_ACCESS(map)->mapping_type) == MAPPING_TYPE__DSO) return map__dso_unmap_ip(map, ip_or_rip); else return ip_or_rip; } /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ u64 map__rip_2objdump(struct map *map, u64 rip); /* objdump address -> memory address */ u64 map__objdump_2mem(struct map *map, u64 ip); struct symbol; struct thread; /* map__for_each_symbol - iterate over the symbols in the given map * * @map: the 'struct map *' in which symbols are iterated * @pos: the 'struct symbol *' to use as a loop cursor * @n: the 'struct rb_node *' to use as a temporary storage * Note: caller must ensure map->dso is not NULL (map is loaded). */ #define map__for_each_symbol(map, pos, n) \ dso__for_each_symbol(map__dso(map), pos, n) /* map__for_each_symbol_with_name - iterate over the symbols in the given map * that have the given name * * @map: the 'struct map *' in which symbols are iterated * @sym_name: the symbol name * @pos: the 'struct symbol *' to use as a loop cursor * @idx: the cursor index in the symbol names array */ #define __map__for_each_symbol_by_name(map, sym_name, pos, idx) \ for (pos = map__find_symbol_by_name_idx(map, sym_name, &idx); \ pos && \ !symbol__match_symbol_name(pos->name, sym_name, \ SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); \ pos = dso__next_symbol_by_name(map__dso(map), &idx)) #define map__for_each_symbol_by_name(map, sym_name, pos, idx) \ __map__for_each_symbol_by_name(map, sym_name, (pos), idx) void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso); struct dso_id; struct build_id; struct map *map__new(struct machine *machine, u64 start, u64 len, u64 pgoff, struct dso_id *id, u32 prot, u32 flags, struct build_id *bid, char *filename, struct thread *thread); struct map *map__new2(u64 start, struct dso *dso); void map__delete(struct map *map); struct map *map__clone(struct map *map); static inline struct map *map__get(struct map *map) { struct map *result; if (RC_CHK_GET(result, map)) refcount_inc(map__refcnt(map)); return result; } void map__put(struct map *map); static inline void __map__zput(struct map **map) { map__put(*map); *map = NULL; } #define map__zput(map) __map__zput(&map) size_t map__fprintf(struct map *map, FILE *fp); size_t map__fprintf_dsoname(struct map *map, FILE *fp); size_t map__fprintf_dsoname_dsoff(struct map *map, bool print_off, u64 addr, FILE *fp); char *map__srcline(struct map *map, u64 addr, struct symbol *sym); int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, FILE *fp); int map__load(struct map *map); struct symbol *map__find_symbol(struct map *map, u64 addr); struct symbol *map__find_symbol_by_name(struct map *map, const char *name); struct symbol *map__find_symbol_by_name_idx(struct map *map, const char *name, size_t *idx); void map__fixup_start(struct map *map); void map__fixup_end(struct map *map); int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr); bool __map__is_kernel(const struct map *map); bool __map__is_extra_kernel_map(const struct map *map); bool __map__is_bpf_prog(const struct map *map); bool __map__is_bpf_image(const struct map *map); bool __map__is_ool(const struct map *map); static inline bool __map__is_kmodule(const struct map *map) { return !__map__is_kernel(map) && !__map__is_extra_kernel_map(map) && !__map__is_bpf_prog(map) && !__map__is_ool(map) && !__map__is_bpf_image(map); } bool map__has_symbols(const struct map *map); bool map__contains_symbol(const struct map *map, const struct symbol *sym); #define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline" static inline bool is_entry_trampoline(const char *name) { return !strcmp(name, ENTRY_TRAMPOLINE_NAME); } static inline bool is_bpf_image(const char *name) { return strncmp(name, "bpf_trampoline_", sizeof("bpf_trampoline_") - 1) == 0 || strncmp(name, "bpf_dispatcher_", sizeof("bpf_dispatcher_") - 1) == 0; } static inline int is_anon_memory(const char *filename) { return !strcmp(filename, "//anon") || !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) || !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1); } static inline int is_no_dso_memory(const char *filename) { return !strncmp(filename, "[stack", 6) || !strncmp(filename, "/SYSV", 5) || !strcmp(filename, "[heap]"); } static inline void map__set_start(struct map *map, u64 start) { RC_CHK_ACCESS(map)->start = start; } static inline void map__set_end(struct map *map, u64 end) { RC_CHK_ACCESS(map)->end = end; } static inline void map__set_pgoff(struct map *map, u64 pgoff) { RC_CHK_ACCESS(map)->pgoff = pgoff; } static inline void map__add_pgoff(struct map *map, u64 inc) { RC_CHK_ACCESS(map)->pgoff += inc; } static inline void map__set_reloc(struct map *map, u64 reloc) { RC_CHK_ACCESS(map)->reloc = reloc; } static inline void map__set_priv(struct map *map, int priv) { RC_CHK_ACCESS(map)->priv = priv; } static inline void map__set_erange_warned(struct map *map, bool erange_warned) { RC_CHK_ACCESS(map)->erange_warned = erange_warned; } static inline void map__set_dso(struct map *map, struct dso *dso) { RC_CHK_ACCESS(map)->dso = dso; } static inline void map__set_mapping_type(struct map *map, enum mapping_type type) { RC_CHK_ACCESS(map)->mapping_type = type; } static inline enum mapping_type map__mapping_type(struct map *map) { return RC_CHK_ACCESS(map)->mapping_type; } #endif /* __PERF_MAP_H */ |