xref: /openbmc/linux/tools/perf/util/map.h (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
24a58e611SArnaldo Carvalho de Melo #ifndef __PERF_MAP_H
34a58e611SArnaldo Carvalho de Melo #define __PERF_MAP_H
44a58e611SArnaldo Carvalho de Melo 
5e3a42cddSElena Reshetova #include <linux/refcount.h>
64a58e611SArnaldo Carvalho de Melo #include <linux/compiler.h>
74a58e611SArnaldo Carvalho de Melo #include <linux/list.h>
84a58e611SArnaldo Carvalho de Melo #include <linux/rbtree.h>
94b8cf846SArnaldo Carvalho de Melo #include <stdio.h>
104d004365SAdrian Hunter #include <string.h>
1123346f21SArnaldo Carvalho de Melo #include <stdbool.h>
12d944c4eeSBorislav Petkov #include <linux/types.h>
13*2832ef81SIan Rogers #include <internal/rc_check.h>
144a58e611SArnaldo Carvalho de Melo 
154a58e611SArnaldo Carvalho de Melo struct dso;
1679b6bb73SArnaldo Carvalho de Melo struct maps;
1723346f21SArnaldo Carvalho de Melo struct machine;
184a58e611SArnaldo Carvalho de Melo 
DECLARE_RC_STRUCT(map)19*2832ef81SIan Rogers DECLARE_RC_STRUCT(map) {
204a58e611SArnaldo Carvalho de Melo 	u64			start;
214a58e611SArnaldo Carvalho de Melo 	u64			end;
22dbc984c9SArnaldo Carvalho de Melo 	bool			erange_warned:1;
23dbc984c9SArnaldo Carvalho de Melo 	bool			priv:1;
247ef80703SDon Zickus 	u32			prot;
254a58e611SArnaldo Carvalho de Melo 	u64			pgoff;
269176753dSAdrian Hunter 	u64			reloc;
277a2b6209SKirill Smelkov 
287a2b6209SKirill Smelkov 	/* ip -> dso rip */
29b80675faSIan Rogers 	u64			(*map_ip)(const struct map *, u64);
307a2b6209SKirill Smelkov 	/* dso rip -> ip */
31b80675faSIan Rogers 	u64			(*unmap_ip)(const struct map *, u64);
327a2b6209SKirill Smelkov 
334a58e611SArnaldo Carvalho de Melo 	struct dso		*dso;
34e3a42cddSElena Reshetova 	refcount_t		refcnt;
357624e694SArnaldo Carvalho de Melo 	u32			flags;
364a58e611SArnaldo Carvalho de Melo };
374a58e611SArnaldo Carvalho de Melo 
3841f30914SArnaldo Carvalho de Melo struct kmap;
39a26ca671SArnaldo Carvalho de Melo 
405759a682SAdrian Hunter struct kmap *__map__kmap(struct map *map);
41ba92732eSWang Nan struct kmap *map__kmap(struct map *map);
4279b6bb73SArnaldo Carvalho de Melo struct maps *map__kmaps(struct map *map);
439de89fe7SArnaldo Carvalho de Melo 
44b80675faSIan Rogers /* ip -> dso rip */
450e6aa013SIan Rogers u64 map__dso_map_ip(const struct map *map, u64 ip);
46b80675faSIan Rogers /* dso rip -> ip */
470e6aa013SIan Rogers u64 map__dso_unmap_ip(const struct map *map, u64 ip);
48b80675faSIan Rogers /* Returns ip */
49b80675faSIan Rogers u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip);
504a58e611SArnaldo Carvalho de Melo 
map__dso(const struct map * map)5163df0e4bSIan Rogers static inline struct dso *map__dso(const struct map *map)
5263df0e4bSIan Rogers {
53*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->dso;
5463df0e4bSIan Rogers }
5563df0e4bSIan Rogers 
map__map_ip(const struct map * map,u64 ip)5678a1f7cdSIan Rogers static inline u64 map__map_ip(const struct map *map, u64 ip)
5778a1f7cdSIan Rogers {
58*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->map_ip(map, ip);
5978a1f7cdSIan Rogers }
6078a1f7cdSIan Rogers 
map__unmap_ip(const struct map * map,u64 ip)6178a1f7cdSIan Rogers static inline u64 map__unmap_ip(const struct map *map, u64 ip)
6278a1f7cdSIan Rogers {
63*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->unmap_ip(map, ip);
6478a1f7cdSIan Rogers }
6578a1f7cdSIan Rogers 
map__map_ip_ptr(struct map * map)66e6a9efceSArnaldo Carvalho de Melo static inline void *map__map_ip_ptr(struct map *map)
67e6a9efceSArnaldo Carvalho de Melo {
68*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->map_ip;
69e6a9efceSArnaldo Carvalho de Melo }
70e6a9efceSArnaldo Carvalho de Melo 
map__unmap_ip_ptr(struct map * map)71e6a9efceSArnaldo Carvalho de Melo static inline void* map__unmap_ip_ptr(struct map *map)
72e6a9efceSArnaldo Carvalho de Melo {
73*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->unmap_ip;
74e6a9efceSArnaldo Carvalho de Melo }
75e6a9efceSArnaldo Carvalho de Melo 
map__start(const struct map * map)76e5116f46SIan Rogers static inline u64 map__start(const struct map *map)
77e5116f46SIan Rogers {
78*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->start;
79e5116f46SIan Rogers }
80e5116f46SIan Rogers 
map__end(const struct map * map)81e5116f46SIan Rogers static inline u64 map__end(const struct map *map)
82e5116f46SIan Rogers {
83*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->end;
84e5116f46SIan Rogers }
85e5116f46SIan Rogers 
map__pgoff(const struct map * map)862a6e5e8aSIan Rogers static inline u64 map__pgoff(const struct map *map)
872a6e5e8aSIan Rogers {
88*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->pgoff;
892a6e5e8aSIan Rogers }
902a6e5e8aSIan Rogers 
map__reloc(const struct map * map)912a6e5e8aSIan Rogers static inline u64 map__reloc(const struct map *map)
922a6e5e8aSIan Rogers {
93*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->reloc;
942a6e5e8aSIan Rogers }
952a6e5e8aSIan Rogers 
map__flags(const struct map * map)96ddee3f2bSIan Rogers static inline u32 map__flags(const struct map *map)
97ddee3f2bSIan Rogers {
98*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->flags;
99ddee3f2bSIan Rogers }
100ddee3f2bSIan Rogers 
map__prot(const struct map * map)101ddee3f2bSIan Rogers static inline u32 map__prot(const struct map *map)
102ddee3f2bSIan Rogers {
103*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->prot;
104ddee3f2bSIan Rogers }
105ddee3f2bSIan Rogers 
map__priv(const struct map * map)106ddee3f2bSIan Rogers static inline bool map__priv(const struct map *map)
107ddee3f2bSIan Rogers {
108*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->priv;
109ddee3f2bSIan Rogers }
110ddee3f2bSIan Rogers 
map__refcnt(struct map * map)1114e8db2d7SArnaldo Carvalho de Melo static inline refcount_t *map__refcnt(struct map *map)
1124e8db2d7SArnaldo Carvalho de Melo {
113*2832ef81SIan Rogers 	return &RC_CHK_ACCESS(map)->refcnt;
1144e8db2d7SArnaldo Carvalho de Melo }
1154e8db2d7SArnaldo Carvalho de Melo 
map__erange_warned(struct map * map)116e6a9efceSArnaldo Carvalho de Melo static inline bool map__erange_warned(struct map *map)
117e6a9efceSArnaldo Carvalho de Melo {
118*2832ef81SIan Rogers 	return RC_CHK_ACCESS(map)->erange_warned;
119e6a9efceSArnaldo Carvalho de Melo }
120e6a9efceSArnaldo Carvalho de Melo 
map__size(const struct map * map)121b74d12d5SKim Phillips static inline size_t map__size(const struct map *map)
122b74d12d5SKim Phillips {
123e5116f46SIan Rogers 	return map__end(map) - map__start(map);
124b74d12d5SKim Phillips }
1257a2b6209SKirill Smelkov 
126ee11b90bSKirill Smelkov /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
1277a2b6209SKirill Smelkov u64 map__rip_2objdump(struct map *map, u64 rip);
1287a2b6209SKirill Smelkov 
1291d5077bdSAdrian Hunter /* objdump address -> memory address */
1301d5077bdSAdrian Hunter u64 map__objdump_2mem(struct map *map, u64 ip);
1311d5077bdSAdrian Hunter 
1324a58e611SArnaldo Carvalho de Melo struct symbol;
1335835eddaSAdrian Hunter struct thread;
1344a58e611SArnaldo Carvalho de Melo 
135eb948e50SMasami Hiramatsu /* map__for_each_symbol - iterate over the symbols in the given map
136eb948e50SMasami Hiramatsu  *
1374d39c89fSIngo Molnar  * @map: the 'struct map *' in which symbols are iterated
138eb948e50SMasami Hiramatsu  * @pos: the 'struct symbol *' to use as a loop cursor
139eb948e50SMasami Hiramatsu  * @n: the 'struct rb_node *' to use as a temporary storage
140eb948e50SMasami Hiramatsu  * Note: caller must ensure map->dso is not NULL (map is loaded).
141eb948e50SMasami Hiramatsu  */
142eb948e50SMasami Hiramatsu #define map__for_each_symbol(map, pos, n)	\
14363df0e4bSIan Rogers 	dso__for_each_symbol(map__dso(map), pos, n)
144eb948e50SMasami Hiramatsu 
1450a3873a8SArnaldo Carvalho de Melo /* map__for_each_symbol_with_name - iterate over the symbols in the given map
1460a3873a8SArnaldo Carvalho de Melo  *                                  that have the given name
1470a3873a8SArnaldo Carvalho de Melo  *
1484d39c89fSIngo Molnar  * @map: the 'struct map *' in which symbols are iterated
1490a3873a8SArnaldo Carvalho de Melo  * @sym_name: the symbol name
1500a3873a8SArnaldo Carvalho de Melo  * @pos: the 'struct symbol *' to use as a loop cursor
1510a3873a8SArnaldo Carvalho de Melo  * @idx: the cursor index in the symbol names array
152be39db9fSArnaldo Carvalho de Melo  */
153be39db9fSArnaldo Carvalho de Melo #define __map__for_each_symbol_by_name(map, sym_name, pos, idx)		\
154d8040645SPaul Clarke 	for (pos = map__find_symbol_by_name_idx(map, sym_name, &idx);	\
155d8040645SPaul Clarke 	     pos &&						\
156d8040645SPaul Clarke 	     !symbol__match_symbol_name(pos->name, sym_name,	\
1570a3873a8SArnaldo Carvalho de Melo 					SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); \
1580a3873a8SArnaldo Carvalho de Melo 	     pos = dso__next_symbol_by_name(map__dso(map), &idx))
1590a3873a8SArnaldo Carvalho de Melo 
160be39db9fSArnaldo Carvalho de Melo #define map__for_each_symbol_by_name(map, sym_name, pos, idx)	\
1614a58e611SArnaldo Carvalho de Melo 	__map__for_each_symbol_by_name(map, sym_name, (pos), idx)
1623183f8caSArnaldo Carvalho de Melo 
1634a58e611SArnaldo Carvalho de Melo void map__init(struct map *map,
1640e3149f8SArnaldo Carvalho de Melo 	       u64 start, u64 end, u64 pgoff, struct dso *dso);
1650e3149f8SArnaldo Carvalho de Melo 
1661ca6e802SJiri Olsa struct dso_id;
1670e3149f8SArnaldo Carvalho de Melo struct build_id;
1682a03068cSAdrian Hunter 
1694a7380a5SArnaldo Carvalho de Melo struct map *map__new(struct machine *machine, u64 start, u64 len,
1701ca6e802SJiri Olsa 		     u64 pgoff, struct dso_id *id, u32 prot, u32 flags,
1713183f8caSArnaldo Carvalho de Melo 		     struct build_id *bid, char *filename, struct thread *thread);
172237a7e04SArnaldo Carvalho de Melo struct map *map__new2(u64 start, struct dso *dso);
173237a7e04SArnaldo Carvalho de Melo void map__delete(struct map *map);
17484c2cafaSArnaldo Carvalho de Melo struct map *map__clone(struct map *map);
17584c2cafaSArnaldo Carvalho de Melo 
map__get(struct map * map)17684c2cafaSArnaldo Carvalho de Melo static inline struct map *map__get(struct map *map)
177*2832ef81SIan Rogers {
178*2832ef81SIan Rogers 	struct map *result;
179*2832ef81SIan Rogers 
180e1805aaeSArnaldo Carvalho de Melo 	if (RC_CHK_GET(result, map))
181*2832ef81SIan Rogers 		refcount_inc(map__refcnt(map));
182*2832ef81SIan Rogers 
18384c2cafaSArnaldo Carvalho de Melo 	return result;
18484c2cafaSArnaldo Carvalho de Melo }
18584c2cafaSArnaldo Carvalho de Melo 
18684c2cafaSArnaldo Carvalho de Melo void map__put(struct map *map);
1875c24b67aSArnaldo Carvalho de Melo 
__map__zput(struct map ** map)1885c24b67aSArnaldo Carvalho de Melo static inline void __map__zput(struct map **map)
1895c24b67aSArnaldo Carvalho de Melo {
1905c24b67aSArnaldo Carvalho de Melo 	map__put(*map);
1915c24b67aSArnaldo Carvalho de Melo 	*map = NULL;
1925c24b67aSArnaldo Carvalho de Melo }
1935c24b67aSArnaldo Carvalho de Melo 
1945c24b67aSArnaldo Carvalho de Melo #define map__zput(map) __map__zput(&map)
195237a7e04SArnaldo Carvalho de Melo 
196547a92e0SAkihiro Nagai size_t map__fprintf(struct map *map, FILE *fp);
197e2d88aaaSArnaldo Carvalho de Melo size_t map__fprintf_dsoname(struct map *map, FILE *fp);
198cc8fae1dSAdrian Hunter size_t map__fprintf_dsoname_dsoff(struct map *map, bool print_off, u64 addr, FILE *fp);
199cc8fae1dSAdrian Hunter char *map__srcline(struct map *map, u64 addr, struct symbol *sym);
2004a58e611SArnaldo Carvalho de Melo int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
201be39db9fSArnaldo Carvalho de Melo 			 FILE *fp);
202be39db9fSArnaldo Carvalho de Melo 
203be39db9fSArnaldo Carvalho de Melo int map__load(struct map *map);
204237a7e04SArnaldo Carvalho de Melo struct symbol *map__find_symbol(struct map *map, u64 addr);
205237a7e04SArnaldo Carvalho de Melo struct symbol *map__find_symbol_by_name(struct map *map, const char *name);
2064a58e611SArnaldo Carvalho de Melo struct symbol *map__find_symbol_by_name_idx(struct map *map, const char *name, size_t *idx);
2073183f8caSArnaldo Carvalho de Melo void map__fixup_start(struct map *map);
208743eb868SArnaldo Carvalho de Melo void map__fixup_end(struct map *map);
209743eb868SArnaldo Carvalho de Melo 
210e6ce7126SArnaldo Carvalho de Melo int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name,
2115759a682SAdrian Hunter 				    u64 addr);
212a93e0b23SSong Liu 
213830fadfdSJiri Olsa bool __map__is_kernel(const struct map *map);
214789e2419SAdrian Hunter bool __map__is_extra_kernel_map(const struct map *map);
215e6ce7126SArnaldo Carvalho de Melo bool __map__is_bpf_prog(const struct map *map);
216e6ce7126SArnaldo Carvalho de Melo bool __map__is_bpf_image(const struct map *map);
217e6ce7126SArnaldo Carvalho de Melo bool __map__is_ool(const struct map *map);
218a93e0b23SSong Liu 
__map__is_kmodule(const struct map * map)219830fadfdSJiri Olsa static inline bool __map__is_kmodule(const struct map *map)
220830fadfdSJiri Olsa {
221e6ce7126SArnaldo Carvalho de Melo 	return !__map__is_kernel(map) && !__map__is_extra_kernel_map(map) &&
222e6ce7126SArnaldo Carvalho de Melo 	       !__map__is_bpf_prog(map) && !__map__is_ool(map) &&
223e94b861aSArnaldo Carvalho de Melo 	       !__map__is_bpf_image(map);
224e94b861aSArnaldo Carvalho de Melo }
22559835f55SIan Rogers 
2269d31d18bSIan Rogers bool map__has_symbols(const struct map *map);
2274d004365SAdrian Hunter 
2284d004365SAdrian Hunter bool map__contains_symbol(const struct map *map, const struct symbol *sym);
2294d004365SAdrian Hunter 
2304d004365SAdrian Hunter #define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline"
2314d004365SAdrian Hunter 
is_entry_trampoline(const char * name)2324d004365SAdrian Hunter static inline bool is_entry_trampoline(const char *name)
2334d004365SAdrian Hunter {
234830fadfdSJiri Olsa 	return !strcmp(name, ENTRY_TRAMPOLINE_NAME);
235830fadfdSJiri Olsa }
236830fadfdSJiri Olsa 
is_bpf_image(const char * name)237830fadfdSJiri Olsa static inline bool is_bpf_image(const char *name)
238830fadfdSJiri Olsa {
239e7b60c5aSNamhyung Kim 	return strncmp(name, "bpf_trampoline_", sizeof("bpf_trampoline_") - 1) == 0 ||
240e7b60c5aSNamhyung Kim 	       strncmp(name, "bpf_dispatcher_", sizeof("bpf_dispatcher_") - 1) == 0;
241e7b60c5aSNamhyung Kim }
242e7b60c5aSNamhyung Kim 
is_anon_memory(const char * filename)243e7b60c5aSNamhyung Kim static inline int is_anon_memory(const char *filename)
244e7b60c5aSNamhyung Kim {
245e7b60c5aSNamhyung Kim 	return !strcmp(filename, "//anon") ||
246e7b60c5aSNamhyung Kim 	       !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) ||
247e7b60c5aSNamhyung Kim 	       !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1);
248e7b60c5aSNamhyung Kim }
249e7b60c5aSNamhyung Kim 
is_no_dso_memory(const char * filename)250e7b60c5aSNamhyung Kim static inline int is_no_dso_memory(const char *filename)
251e7b60c5aSNamhyung Kim {
252e7b60c5aSNamhyung Kim 	return !strncmp(filename, "[stack", 6) ||
253e6a9efceSArnaldo Carvalho de Melo 	       !strncmp(filename, "/SYSV", 5)  ||
254e6a9efceSArnaldo Carvalho de Melo 	       !strcmp(filename, "[heap]");
255e6a9efceSArnaldo Carvalho de Melo }
256*2832ef81SIan Rogers 
map__set_start(struct map * map,u64 start)257e6a9efceSArnaldo Carvalho de Melo static inline void map__set_start(struct map *map, u64 start)
258e6a9efceSArnaldo Carvalho de Melo {
259e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->start = start;
260e6a9efceSArnaldo Carvalho de Melo }
261*2832ef81SIan Rogers 
map__set_end(struct map * map,u64 end)262e6a9efceSArnaldo Carvalho de Melo static inline void map__set_end(struct map *map, u64 end)
263e6a9efceSArnaldo Carvalho de Melo {
264e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->end = end;
265e6a9efceSArnaldo Carvalho de Melo }
266*2832ef81SIan Rogers 
map__set_pgoff(struct map * map,u64 pgoff)267e6a9efceSArnaldo Carvalho de Melo static inline void map__set_pgoff(struct map *map, u64 pgoff)
268e6a9efceSArnaldo Carvalho de Melo {
269e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->pgoff = pgoff;
270e6a9efceSArnaldo Carvalho de Melo }
271*2832ef81SIan Rogers 
map__add_pgoff(struct map * map,u64 inc)272e6a9efceSArnaldo Carvalho de Melo static inline void map__add_pgoff(struct map *map, u64 inc)
273e6a9efceSArnaldo Carvalho de Melo {
274e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->pgoff += inc;
275e6a9efceSArnaldo Carvalho de Melo }
276*2832ef81SIan Rogers 
map__set_reloc(struct map * map,u64 reloc)277e6a9efceSArnaldo Carvalho de Melo static inline void map__set_reloc(struct map *map, u64 reloc)
278e6a9efceSArnaldo Carvalho de Melo {
279e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->reloc = reloc;
280e6a9efceSArnaldo Carvalho de Melo }
281*2832ef81SIan Rogers 
map__set_priv(struct map * map,int priv)282e6a9efceSArnaldo Carvalho de Melo static inline void map__set_priv(struct map *map, int priv)
283e6a9efceSArnaldo Carvalho de Melo {
284e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->priv = priv;
285e6a9efceSArnaldo Carvalho de Melo }
286*2832ef81SIan Rogers 
map__set_erange_warned(struct map * map,bool erange_warned)287e6a9efceSArnaldo Carvalho de Melo static inline void map__set_erange_warned(struct map *map, bool erange_warned)
288e6a9efceSArnaldo Carvalho de Melo {
289e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->erange_warned = erange_warned;
290e6a9efceSArnaldo Carvalho de Melo }
291*2832ef81SIan Rogers 
map__set_dso(struct map * map,struct dso * dso)292e6a9efceSArnaldo Carvalho de Melo static inline void map__set_dso(struct map *map, struct dso *dso)
293e6a9efceSArnaldo Carvalho de Melo {
294e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->dso = dso;
295e6a9efceSArnaldo Carvalho de Melo }
296*2832ef81SIan Rogers 
map__set_map_ip(struct map * map,u64 (* map_ip)(const struct map * map,u64 ip))297e6a9efceSArnaldo Carvalho de Melo static inline void map__set_map_ip(struct map *map, u64 (*map_ip)(const struct map *map, u64 ip))
298e6a9efceSArnaldo Carvalho de Melo {
299e6a9efceSArnaldo Carvalho de Melo 	RC_CHK_ACCESS(map)->map_ip = map_ip;
300e6a9efceSArnaldo Carvalho de Melo }
301*2832ef81SIan Rogers 
map__set_unmap_ip(struct map * map,u64 (* unmap_ip)(const struct map * map,u64 rip))302e6a9efceSArnaldo Carvalho de Melo static inline void map__set_unmap_ip(struct map *map, u64 (*unmap_ip)(const struct map *map, u64 rip))
3034a58e611SArnaldo Carvalho de Melo {
304 	RC_CHK_ACCESS(map)->unmap_ip = unmap_ip;
305 }
306 #endif /* __PERF_MAP_H */
307