diff options
-rw-r--r-- | tools/perf/util/map.c | 84 | ||||
-rw-r--r-- | tools/perf/util/map.h | 47 | ||||
-rw-r--r-- | tools/perf/util/session.c | 29 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 53 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 48 |
5 files changed, 131 insertions, 130 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index a9b42273675d..9f2963f9ee9a 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -1,8 +1,9 @@ | |||
1 | #include "symbol.h" | 1 | #include "symbol.h" |
2 | #include <limits.h> | ||
2 | #include <stdlib.h> | 3 | #include <stdlib.h> |
3 | #include <string.h> | 4 | #include <string.h> |
4 | #include <stdio.h> | 5 | #include <stdio.h> |
5 | #include "debug.h" | 6 | #include "map.h" |
6 | 7 | ||
7 | const char *map_type__name[MAP__NR_TYPES] = { | 8 | const char *map_type__name[MAP__NR_TYPES] = { |
8 | [MAP__FUNCTION] = "Functions", | 9 | [MAP__FUNCTION] = "Functions", |
@@ -232,3 +233,84 @@ u64 map__objdump_2ip(struct map *map, u64 addr) | |||
232 | map->unmap_ip(map, addr); /* RIP -> IP */ | 233 | map->unmap_ip(map, addr); /* RIP -> IP */ |
233 | return ip; | 234 | return ip; |
234 | } | 235 | } |
236 | |||
237 | struct symbol *map_groups__find_symbol(struct map_groups *self, | ||
238 | enum map_type type, u64 addr, | ||
239 | symbol_filter_t filter) | ||
240 | { | ||
241 | struct map *map = map_groups__find(self, type, addr); | ||
242 | |||
243 | if (map != NULL) | ||
244 | return map__find_symbol(map, map->map_ip(map, addr), filter); | ||
245 | |||
246 | return NULL; | ||
247 | } | ||
248 | |||
249 | static u64 map__reloc_map_ip(struct map *map, u64 ip) | ||
250 | { | ||
251 | return ip + (s64)map->pgoff; | ||
252 | } | ||
253 | |||
254 | static u64 map__reloc_unmap_ip(struct map *map, u64 ip) | ||
255 | { | ||
256 | return ip - (s64)map->pgoff; | ||
257 | } | ||
258 | |||
259 | void map__reloc_vmlinux(struct map *self) | ||
260 | { | ||
261 | struct kmap *kmap = map__kmap(self); | ||
262 | s64 reloc; | ||
263 | |||
264 | if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr) | ||
265 | return; | ||
266 | |||
267 | reloc = (kmap->ref_reloc_sym->unrelocated_addr - | ||
268 | kmap->ref_reloc_sym->addr); | ||
269 | |||
270 | if (!reloc) | ||
271 | return; | ||
272 | |||
273 | self->map_ip = map__reloc_map_ip; | ||
274 | self->unmap_ip = map__reloc_unmap_ip; | ||
275 | self->pgoff = reloc; | ||
276 | } | ||
277 | |||
278 | void maps__insert(struct rb_root *maps, struct map *map) | ||
279 | { | ||
280 | struct rb_node **p = &maps->rb_node; | ||
281 | struct rb_node *parent = NULL; | ||
282 | const u64 ip = map->start; | ||
283 | struct map *m; | ||
284 | |||
285 | while (*p != NULL) { | ||
286 | parent = *p; | ||
287 | m = rb_entry(parent, struct map, rb_node); | ||
288 | if (ip < m->start) | ||
289 | p = &(*p)->rb_left; | ||
290 | else | ||
291 | p = &(*p)->rb_right; | ||
292 | } | ||
293 | |||
294 | rb_link_node(&map->rb_node, parent, p); | ||
295 | rb_insert_color(&map->rb_node, maps); | ||
296 | } | ||
297 | |||
298 | struct map *maps__find(struct rb_root *maps, u64 ip) | ||
299 | { | ||
300 | struct rb_node **p = &maps->rb_node; | ||
301 | struct rb_node *parent = NULL; | ||
302 | struct map *m; | ||
303 | |||
304 | while (*p != NULL) { | ||
305 | parent = *p; | ||
306 | m = rb_entry(parent, struct map, rb_node); | ||
307 | if (ip < m->start) | ||
308 | p = &(*p)->rb_left; | ||
309 | else if (ip > m->end) | ||
310 | p = &(*p)->rb_right; | ||
311 | else | ||
312 | return m; | ||
313 | } | ||
314 | |||
315 | return NULL; | ||
316 | } | ||
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index a4a5bc4fca6d..6a703fa74707 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -4,7 +4,8 @@ | |||
4 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/rbtree.h> | 6 | #include <linux/rbtree.h> |
7 | #include <linux/types.h> | 7 | #include <stdio.h> |
8 | #include "types.h" | ||
8 | 9 | ||
9 | enum map_type { | 10 | enum map_type { |
10 | MAP__FUNCTION = 0, | 11 | MAP__FUNCTION = 0, |
@@ -90,4 +91,48 @@ void map__fixup_end(struct map *self); | |||
90 | 91 | ||
91 | void map__reloc_vmlinux(struct map *self); | 92 | void map__reloc_vmlinux(struct map *self); |
92 | 93 | ||
94 | struct map_groups { | ||
95 | struct rb_root maps[MAP__NR_TYPES]; | ||
96 | struct list_head removed_maps[MAP__NR_TYPES]; | ||
97 | }; | ||
98 | |||
99 | size_t __map_groups__fprintf_maps(struct map_groups *self, | ||
100 | enum map_type type, FILE *fp); | ||
101 | void maps__insert(struct rb_root *maps, struct map *map); | ||
102 | struct map *maps__find(struct rb_root *maps, u64 addr); | ||
103 | void map_groups__init(struct map_groups *self); | ||
104 | size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); | ||
105 | |||
106 | static inline void map_groups__insert(struct map_groups *self, struct map *map) | ||
107 | { | ||
108 | maps__insert(&self->maps[map->type], map); | ||
109 | } | ||
110 | |||
111 | static inline struct map *map_groups__find(struct map_groups *self, | ||
112 | enum map_type type, u64 addr) | ||
113 | { | ||
114 | return maps__find(&self->maps[type], addr); | ||
115 | } | ||
116 | |||
117 | struct symbol *map_groups__find_symbol(struct map_groups *self, | ||
118 | enum map_type type, u64 addr, | ||
119 | symbol_filter_t filter); | ||
120 | |||
121 | static inline struct symbol *map_groups__find_function(struct map_groups *self, | ||
122 | u64 addr, | ||
123 | symbol_filter_t filter) | ||
124 | { | ||
125 | return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter); | ||
126 | } | ||
127 | |||
128 | struct map *map_groups__find_by_name(struct map_groups *self, | ||
129 | enum map_type type, const char *name); | ||
130 | int __map_groups__create_kernel_maps(struct map_groups *self, | ||
131 | struct map *vmlinux_maps[MAP__NR_TYPES], | ||
132 | struct dso *kernel); | ||
133 | int map_groups__create_kernel_maps(struct map_groups *self, | ||
134 | struct map *vmlinux_maps[MAP__NR_TYPES]); | ||
135 | struct map *map_groups__new_module(struct map_groups *self, u64 start, | ||
136 | const char *filename); | ||
137 | |||
93 | #endif /* __PERF_MAP_H */ | 138 | #endif /* __PERF_MAP_H */ |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2cef3730cd99..76b4ac689df9 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -544,32 +544,3 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self, | |||
544 | 544 | ||
545 | return 0; | 545 | return 0; |
546 | } | 546 | } |
547 | |||
548 | static u64 map__reloc_map_ip(struct map *map, u64 ip) | ||
549 | { | ||
550 | return ip + (s64)map->pgoff; | ||
551 | } | ||
552 | |||
553 | static u64 map__reloc_unmap_ip(struct map *map, u64 ip) | ||
554 | { | ||
555 | return ip - (s64)map->pgoff; | ||
556 | } | ||
557 | |||
558 | void map__reloc_vmlinux(struct map *self) | ||
559 | { | ||
560 | struct kmap *kmap = map__kmap(self); | ||
561 | s64 reloc; | ||
562 | |||
563 | if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr) | ||
564 | return; | ||
565 | |||
566 | reloc = (kmap->ref_reloc_sym->unrelocated_addr - | ||
567 | kmap->ref_reloc_sym->addr); | ||
568 | |||
569 | if (!reloc) | ||
570 | return; | ||
571 | |||
572 | self->map_ip = map__reloc_map_ip; | ||
573 | self->unmap_ip = map__reloc_unmap_ip; | ||
574 | self->pgoff = reloc; | ||
575 | } | ||
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index ea6506234d57..9bbe27d75306 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -272,46 +272,6 @@ static int map_groups__fixup_overlappings(struct map_groups *self, | |||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | void maps__insert(struct rb_root *maps, struct map *map) | ||
276 | { | ||
277 | struct rb_node **p = &maps->rb_node; | ||
278 | struct rb_node *parent = NULL; | ||
279 | const u64 ip = map->start; | ||
280 | struct map *m; | ||
281 | |||
282 | while (*p != NULL) { | ||
283 | parent = *p; | ||
284 | m = rb_entry(parent, struct map, rb_node); | ||
285 | if (ip < m->start) | ||
286 | p = &(*p)->rb_left; | ||
287 | else | ||
288 | p = &(*p)->rb_right; | ||
289 | } | ||
290 | |||
291 | rb_link_node(&map->rb_node, parent, p); | ||
292 | rb_insert_color(&map->rb_node, maps); | ||
293 | } | ||
294 | |||
295 | struct map *maps__find(struct rb_root *maps, u64 ip) | ||
296 | { | ||
297 | struct rb_node **p = &maps->rb_node; | ||
298 | struct rb_node *parent = NULL; | ||
299 | struct map *m; | ||
300 | |||
301 | while (*p != NULL) { | ||
302 | parent = *p; | ||
303 | m = rb_entry(parent, struct map, rb_node); | ||
304 | if (ip < m->start) | ||
305 | p = &(*p)->rb_left; | ||
306 | else if (ip > m->end) | ||
307 | p = &(*p)->rb_right; | ||
308 | else | ||
309 | return m; | ||
310 | } | ||
311 | |||
312 | return NULL; | ||
313 | } | ||
314 | |||
315 | void thread__insert_map(struct thread *self, struct map *map) | 275 | void thread__insert_map(struct thread *self, struct map *map) |
316 | { | 276 | { |
317 | map_groups__fixup_overlappings(&self->mg, map); | 277 | map_groups__fixup_overlappings(&self->mg, map); |
@@ -367,16 +327,3 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp) | |||
367 | 327 | ||
368 | return ret; | 328 | return ret; |
369 | } | 329 | } |
370 | |||
371 | struct symbol *map_groups__find_symbol(struct map_groups *self, | ||
372 | enum map_type type, u64 addr, | ||
373 | symbol_filter_t filter) | ||
374 | { | ||
375 | struct map *map = map_groups__find(self, type, addr); | ||
376 | |||
377 | if (map != NULL) | ||
378 | return map__find_symbol(map, map->map_ip(map, addr), filter); | ||
379 | |||
380 | return NULL; | ||
381 | } | ||
382 | |||
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index a81426a891bf..9c488fcadec9 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
@@ -5,14 +5,6 @@ | |||
5 | #include <unistd.h> | 5 | #include <unistd.h> |
6 | #include "symbol.h" | 6 | #include "symbol.h" |
7 | 7 | ||
8 | struct map_groups { | ||
9 | struct rb_root maps[MAP__NR_TYPES]; | ||
10 | struct list_head removed_maps[MAP__NR_TYPES]; | ||
11 | }; | ||
12 | |||
13 | size_t __map_groups__fprintf_maps(struct map_groups *self, | ||
14 | enum map_type type, FILE *fp); | ||
15 | |||
16 | struct thread { | 8 | struct thread { |
17 | struct rb_node rb_node; | 9 | struct rb_node rb_node; |
18 | struct map_groups mg; | 10 | struct map_groups mg; |
@@ -23,30 +15,16 @@ struct thread { | |||
23 | int comm_len; | 15 | int comm_len; |
24 | }; | 16 | }; |
25 | 17 | ||
18 | struct perf_session; | ||
19 | |||
26 | int find_all_tid(int pid, pid_t ** all_tid); | 20 | int find_all_tid(int pid, pid_t ** all_tid); |
27 | void map_groups__init(struct map_groups *self); | ||
28 | int thread__set_comm(struct thread *self, const char *comm); | 21 | int thread__set_comm(struct thread *self, const char *comm); |
29 | int thread__comm_len(struct thread *self); | 22 | int thread__comm_len(struct thread *self); |
30 | struct thread *perf_session__findnew(struct perf_session *self, pid_t pid); | 23 | struct thread *perf_session__findnew(struct perf_session *self, pid_t pid); |
31 | void thread__insert_map(struct thread *self, struct map *map); | 24 | void thread__insert_map(struct thread *self, struct map *map); |
32 | int thread__fork(struct thread *self, struct thread *parent); | 25 | int thread__fork(struct thread *self, struct thread *parent); |
33 | size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); | ||
34 | size_t perf_session__fprintf(struct perf_session *self, FILE *fp); | 26 | size_t perf_session__fprintf(struct perf_session *self, FILE *fp); |
35 | 27 | ||
36 | void maps__insert(struct rb_root *maps, struct map *map); | ||
37 | struct map *maps__find(struct rb_root *maps, u64 addr); | ||
38 | |||
39 | static inline void map_groups__insert(struct map_groups *self, struct map *map) | ||
40 | { | ||
41 | maps__insert(&self->maps[map->type], map); | ||
42 | } | ||
43 | |||
44 | static inline struct map *map_groups__find(struct map_groups *self, | ||
45 | enum map_type type, u64 addr) | ||
46 | { | ||
47 | return maps__find(&self->maps[type], addr); | ||
48 | } | ||
49 | |||
50 | static inline struct map *thread__find_map(struct thread *self, | 28 | static inline struct map *thread__find_map(struct thread *self, |
51 | enum map_type type, u64 addr) | 29 | enum map_type type, u64 addr) |
52 | { | 30 | { |
@@ -63,26 +41,4 @@ void thread__find_addr_location(struct thread *self, | |||
63 | enum map_type type, u64 addr, | 41 | enum map_type type, u64 addr, |
64 | struct addr_location *al, | 42 | struct addr_location *al, |
65 | symbol_filter_t filter); | 43 | symbol_filter_t filter); |
66 | struct symbol *map_groups__find_symbol(struct map_groups *self, | ||
67 | enum map_type type, u64 addr, | ||
68 | symbol_filter_t filter); | ||
69 | |||
70 | static inline struct symbol *map_groups__find_function(struct map_groups *self, | ||
71 | u64 addr, | ||
72 | symbol_filter_t filter) | ||
73 | { | ||
74 | return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter); | ||
75 | } | ||
76 | |||
77 | struct map *map_groups__find_by_name(struct map_groups *self, | ||
78 | enum map_type type, const char *name); | ||
79 | |||
80 | int __map_groups__create_kernel_maps(struct map_groups *self, | ||
81 | struct map *vmlinux_maps[MAP__NR_TYPES], | ||
82 | struct dso *kernel); | ||
83 | int map_groups__create_kernel_maps(struct map_groups *self, | ||
84 | struct map *vmlinux_maps[MAP__NR_TYPES]); | ||
85 | |||
86 | struct map *map_groups__new_module(struct map_groups *self, u64 start, | ||
87 | const char *filename); | ||
88 | #endif /* __PERF_THREAD_H */ | 44 | #endif /* __PERF_THREAD_H */ |