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