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