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