162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __PERF_MAP_H 362306a36Sopenharmony_ci#define __PERF_MAP_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/refcount.h> 662306a36Sopenharmony_ci#include <linux/compiler.h> 762306a36Sopenharmony_ci#include <linux/list.h> 862306a36Sopenharmony_ci#include <linux/rbtree.h> 962306a36Sopenharmony_ci#include <stdio.h> 1062306a36Sopenharmony_ci#include <string.h> 1162306a36Sopenharmony_ci#include <stdbool.h> 1262306a36Sopenharmony_ci#include <linux/types.h> 1362306a36Sopenharmony_ci#include <internal/rc_check.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct dso; 1662306a36Sopenharmony_cistruct maps; 1762306a36Sopenharmony_cistruct machine; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciDECLARE_RC_STRUCT(map) { 2062306a36Sopenharmony_ci u64 start; 2162306a36Sopenharmony_ci u64 end; 2262306a36Sopenharmony_ci bool erange_warned:1; 2362306a36Sopenharmony_ci bool priv:1; 2462306a36Sopenharmony_ci u32 prot; 2562306a36Sopenharmony_ci u64 pgoff; 2662306a36Sopenharmony_ci u64 reloc; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* ip -> dso rip */ 2962306a36Sopenharmony_ci u64 (*map_ip)(const struct map *, u64); 3062306a36Sopenharmony_ci /* dso rip -> ip */ 3162306a36Sopenharmony_ci u64 (*unmap_ip)(const struct map *, u64); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci struct dso *dso; 3462306a36Sopenharmony_ci refcount_t refcnt; 3562306a36Sopenharmony_ci u32 flags; 3662306a36Sopenharmony_ci}; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistruct kmap; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistruct kmap *__map__kmap(struct map *map); 4162306a36Sopenharmony_cistruct kmap *map__kmap(struct map *map); 4262306a36Sopenharmony_cistruct maps *map__kmaps(struct map *map); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* ip -> dso rip */ 4562306a36Sopenharmony_ciu64 map__dso_map_ip(const struct map *map, u64 ip); 4662306a36Sopenharmony_ci/* dso rip -> ip */ 4762306a36Sopenharmony_ciu64 map__dso_unmap_ip(const struct map *map, u64 ip); 4862306a36Sopenharmony_ci/* Returns ip */ 4962306a36Sopenharmony_ciu64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic inline struct dso *map__dso(const struct map *map) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->dso; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic inline u64 map__map_ip(const struct map *map, u64 ip) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->map_ip(map, ip); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic inline u64 map__unmap_ip(const struct map *map, u64 ip) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->unmap_ip(map, ip); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic inline void *map__map_ip_ptr(struct map *map) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->map_ip; 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic inline void* map__unmap_ip_ptr(struct map *map) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->unmap_ip; 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic inline u64 map__start(const struct map *map) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->start; 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic inline u64 map__end(const struct map *map) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->end; 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic inline u64 map__pgoff(const struct map *map) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->pgoff; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic inline u64 map__reloc(const struct map *map) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->reloc; 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic inline u32 map__flags(const struct map *map) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->flags; 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic inline u32 map__prot(const struct map *map) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->prot; 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic inline bool map__priv(const struct map *map) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->priv; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic inline refcount_t *map__refcnt(struct map *map) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci return &RC_CHK_ACCESS(map)->refcnt; 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic inline bool map__erange_warned(struct map *map) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci return RC_CHK_ACCESS(map)->erange_warned; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic inline size_t map__size(const struct map *map) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci return map__end(map) - map__start(map); 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ 12762306a36Sopenharmony_ciu64 map__rip_2objdump(struct map *map, u64 rip); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/* objdump address -> memory address */ 13062306a36Sopenharmony_ciu64 map__objdump_2mem(struct map *map, u64 ip); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistruct symbol; 13362306a36Sopenharmony_cistruct thread; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci/* map__for_each_symbol - iterate over the symbols in the given map 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * @map: the 'struct map *' in which symbols are iterated 13862306a36Sopenharmony_ci * @pos: the 'struct symbol *' to use as a loop cursor 13962306a36Sopenharmony_ci * @n: the 'struct rb_node *' to use as a temporary storage 14062306a36Sopenharmony_ci * Note: caller must ensure map->dso is not NULL (map is loaded). 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_ci#define map__for_each_symbol(map, pos, n) \ 14362306a36Sopenharmony_ci dso__for_each_symbol(map__dso(map), pos, n) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/* map__for_each_symbol_with_name - iterate over the symbols in the given map 14662306a36Sopenharmony_ci * that have the given name 14762306a36Sopenharmony_ci * 14862306a36Sopenharmony_ci * @map: the 'struct map *' in which symbols are iterated 14962306a36Sopenharmony_ci * @sym_name: the symbol name 15062306a36Sopenharmony_ci * @pos: the 'struct symbol *' to use as a loop cursor 15162306a36Sopenharmony_ci * @idx: the cursor index in the symbol names array 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_ci#define __map__for_each_symbol_by_name(map, sym_name, pos, idx) \ 15462306a36Sopenharmony_ci for (pos = map__find_symbol_by_name_idx(map, sym_name, &idx); \ 15562306a36Sopenharmony_ci pos && \ 15662306a36Sopenharmony_ci !symbol__match_symbol_name(pos->name, sym_name, \ 15762306a36Sopenharmony_ci SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); \ 15862306a36Sopenharmony_ci pos = dso__next_symbol_by_name(map__dso(map), &idx)) 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci#define map__for_each_symbol_by_name(map, sym_name, pos, idx) \ 16162306a36Sopenharmony_ci __map__for_each_symbol_by_name(map, sym_name, (pos), idx) 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_civoid map__init(struct map *map, 16462306a36Sopenharmony_ci u64 start, u64 end, u64 pgoff, struct dso *dso); 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistruct dso_id; 16762306a36Sopenharmony_cistruct build_id; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistruct map *map__new(struct machine *machine, u64 start, u64 len, 17062306a36Sopenharmony_ci u64 pgoff, struct dso_id *id, u32 prot, u32 flags, 17162306a36Sopenharmony_ci struct build_id *bid, char *filename, struct thread *thread); 17262306a36Sopenharmony_cistruct map *map__new2(u64 start, struct dso *dso); 17362306a36Sopenharmony_civoid map__delete(struct map *map); 17462306a36Sopenharmony_cistruct map *map__clone(struct map *map); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic inline struct map *map__get(struct map *map) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci struct map *result; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci if (RC_CHK_GET(result, map)) 18162306a36Sopenharmony_ci refcount_inc(map__refcnt(map)); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci return result; 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_civoid map__put(struct map *map); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistatic inline void __map__zput(struct map **map) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci map__put(*map); 19162306a36Sopenharmony_ci *map = NULL; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#define map__zput(map) __map__zput(&map) 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cisize_t map__fprintf(struct map *map, FILE *fp); 19762306a36Sopenharmony_cisize_t map__fprintf_dsoname(struct map *map, FILE *fp); 19862306a36Sopenharmony_cisize_t map__fprintf_dsoname_dsoff(struct map *map, bool print_off, u64 addr, FILE *fp); 19962306a36Sopenharmony_cichar *map__srcline(struct map *map, u64 addr, struct symbol *sym); 20062306a36Sopenharmony_ciint map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, 20162306a36Sopenharmony_ci FILE *fp); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ciint map__load(struct map *map); 20462306a36Sopenharmony_cistruct symbol *map__find_symbol(struct map *map, u64 addr); 20562306a36Sopenharmony_cistruct symbol *map__find_symbol_by_name(struct map *map, const char *name); 20662306a36Sopenharmony_cistruct symbol *map__find_symbol_by_name_idx(struct map *map, const char *name, size_t *idx); 20762306a36Sopenharmony_civoid map__fixup_start(struct map *map); 20862306a36Sopenharmony_civoid map__fixup_end(struct map *map); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciint map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, 21162306a36Sopenharmony_ci u64 addr); 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cibool __map__is_kernel(const struct map *map); 21462306a36Sopenharmony_cibool __map__is_extra_kernel_map(const struct map *map); 21562306a36Sopenharmony_cibool __map__is_bpf_prog(const struct map *map); 21662306a36Sopenharmony_cibool __map__is_bpf_image(const struct map *map); 21762306a36Sopenharmony_cibool __map__is_ool(const struct map *map); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic inline bool __map__is_kmodule(const struct map *map) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci return !__map__is_kernel(map) && !__map__is_extra_kernel_map(map) && 22262306a36Sopenharmony_ci !__map__is_bpf_prog(map) && !__map__is_ool(map) && 22362306a36Sopenharmony_ci !__map__is_bpf_image(map); 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cibool map__has_symbols(const struct map *map); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cibool map__contains_symbol(const struct map *map, const struct symbol *sym); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci#define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline" 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cistatic inline bool is_entry_trampoline(const char *name) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci return !strcmp(name, ENTRY_TRAMPOLINE_NAME); 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic inline bool is_bpf_image(const char *name) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci return strncmp(name, "bpf_trampoline_", sizeof("bpf_trampoline_") - 1) == 0 || 24062306a36Sopenharmony_ci strncmp(name, "bpf_dispatcher_", sizeof("bpf_dispatcher_") - 1) == 0; 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic inline int is_anon_memory(const char *filename) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci return !strcmp(filename, "//anon") || 24662306a36Sopenharmony_ci !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) || 24762306a36Sopenharmony_ci !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1); 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline int is_no_dso_memory(const char *filename) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci return !strncmp(filename, "[stack", 6) || 25362306a36Sopenharmony_ci !strncmp(filename, "/SYSV", 5) || 25462306a36Sopenharmony_ci !strcmp(filename, "[heap]"); 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistatic inline void map__set_start(struct map *map, u64 start) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci RC_CHK_ACCESS(map)->start = start; 26062306a36Sopenharmony_ci} 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_cistatic inline void map__set_end(struct map *map, u64 end) 26362306a36Sopenharmony_ci{ 26462306a36Sopenharmony_ci RC_CHK_ACCESS(map)->end = end; 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_cistatic inline void map__set_pgoff(struct map *map, u64 pgoff) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci RC_CHK_ACCESS(map)->pgoff = pgoff; 27062306a36Sopenharmony_ci} 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_cistatic inline void map__add_pgoff(struct map *map, u64 inc) 27362306a36Sopenharmony_ci{ 27462306a36Sopenharmony_ci RC_CHK_ACCESS(map)->pgoff += inc; 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic inline void map__set_reloc(struct map *map, u64 reloc) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci RC_CHK_ACCESS(map)->reloc = reloc; 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistatic inline void map__set_priv(struct map *map, int priv) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci RC_CHK_ACCESS(map)->priv = priv; 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic inline void map__set_erange_warned(struct map *map, bool erange_warned) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci RC_CHK_ACCESS(map)->erange_warned = erange_warned; 29062306a36Sopenharmony_ci} 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cistatic inline void map__set_dso(struct map *map, struct dso *dso) 29362306a36Sopenharmony_ci{ 29462306a36Sopenharmony_ci RC_CHK_ACCESS(map)->dso = dso; 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic inline void map__set_map_ip(struct map *map, u64 (*map_ip)(const struct map *map, u64 ip)) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci RC_CHK_ACCESS(map)->map_ip = map_ip; 30062306a36Sopenharmony_ci} 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistatic inline void map__set_unmap_ip(struct map *map, u64 (*unmap_ip)(const struct map *map, u64 rip)) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci RC_CHK_ACCESS(map)->unmap_ip = unmap_ip; 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci#endif /* __PERF_MAP_H */ 307