aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c80
1 files changed, 14 insertions, 66 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6b13a1ecf1e7..18ac5eaefc36 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -24,6 +24,7 @@
24#include "util/thread.h" 24#include "util/thread.h"
25#include "util/sort.h" 25#include "util/sort.h"
26#include "util/hist.h" 26#include "util/hist.h"
27#include "util/process_events.h"
27 28
28static char const *input_name = "perf.data"; 29static char const *input_name = "perf.data";
29 30
@@ -33,11 +34,9 @@ static int input;
33static int full_paths; 34static int full_paths;
34 35
35static int print_line; 36static int print_line;
36static bool use_modules;
37 37
38static unsigned long page_size; 38static unsigned long page_size;
39static unsigned long mmap_window = 32; 39static unsigned long mmap_window = 32;
40const char *vmlinux_name;
41 40
42struct sym_hist { 41struct sym_hist {
43 u64 sum; 42 u64 sum;
@@ -55,6 +54,11 @@ struct sym_priv {
55 struct sym_ext *ext; 54 struct sym_ext *ext;
56}; 55};
57 56
57static struct symbol_conf symbol_conf = {
58 .priv_size = sizeof(struct sym_priv),
59 .try_vmlinux_path = true,
60};
61
58static const char *sym_hist_filter; 62static const char *sym_hist_filter;
59 63
60static int symbol_filter(struct map *map __used, struct symbol *sym) 64static int symbol_filter(struct map *map __used, struct symbol *sym)
@@ -158,7 +162,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
158 162
159 if (event->header.misc & PERF_RECORD_MISC_KERNEL) { 163 if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
160 level = 'k'; 164 level = 'k';
161 sym = kernel_maps__find_symbol(ip, &map, symbol_filter); 165 sym = kernel_maps__find_function(ip, &map, symbol_filter);
162 dump_printf(" ...... dso: %s\n", 166 dump_printf(" ...... dso: %s\n",
163 map ? map->dso->long_name : "<not found>"); 167 map ? map->dso->long_name : "<not found>");
164 } else if (event->header.misc & PERF_RECORD_MISC_USER) { 168 } else if (event->header.misc & PERF_RECORD_MISC_USER) {
@@ -167,7 +171,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
167 if (map != NULL) { 171 if (map != NULL) {
168got_map: 172got_map:
169 ip = map->map_ip(map, ip); 173 ip = map->map_ip(map, ip);
170 sym = map__find_symbol(map, ip, symbol_filter); 174 sym = map__find_function(map, ip, symbol_filter);
171 } else { 175 } else {
172 /* 176 /*
173 * If this is outside of all known maps, 177 * If this is outside of all known maps,
@@ -202,32 +206,6 @@ got_map:
202} 206}
203 207
204static int 208static int
205process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
206{
207 struct map *map = map__new(&event->mmap, NULL, 0);
208 struct thread *thread = threads__findnew(event->mmap.pid);
209
210 dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n",
211 (void *)(offset + head),
212 (void *)(long)(event->header.size),
213 event->mmap.pid,
214 (void *)(long)event->mmap.start,
215 (void *)(long)event->mmap.len,
216 (void *)(long)event->mmap.pgoff,
217 event->mmap.filename);
218
219 if (thread == NULL || map == NULL) {
220 dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
221 return 0;
222 }
223
224 thread__insert_map(thread, map);
225 total_mmap++;
226
227 return 0;
228}
229
230static int
231process_comm_event(event_t *event, unsigned long offset, unsigned long head) 209process_comm_event(event_t *event, unsigned long offset, unsigned long head)
232{ 210{
233 struct thread *thread = threads__findnew(event->comm.pid); 211 struct thread *thread = threads__findnew(event->comm.pid);
@@ -248,33 +226,6 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
248} 226}
249 227
250static int 228static int
251process_fork_event(event_t *event, unsigned long offset, unsigned long head)
252{
253 struct thread *thread = threads__findnew(event->fork.pid);
254 struct thread *parent = threads__findnew(event->fork.ppid);
255
256 dump_printf("%p [%p]: PERF_RECORD_FORK: %d:%d\n",
257 (void *)(offset + head),
258 (void *)(long)(event->header.size),
259 event->fork.pid, event->fork.ppid);
260
261 /*
262 * A thread clone will have the same PID for both
263 * parent and child.
264 */
265 if (thread == parent)
266 return 0;
267
268 if (!thread || !parent || thread__fork(thread, parent)) {
269 dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
270 return -1;
271 }
272 total_fork++;
273
274 return 0;
275}
276
277static int
278process_event(event_t *event, unsigned long offset, unsigned long head) 229process_event(event_t *event, unsigned long offset, unsigned long head)
279{ 230{
280 switch (event->header.type) { 231 switch (event->header.type) {
@@ -288,7 +239,7 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
288 return process_comm_event(event, offset, head); 239 return process_comm_event(event, offset, head);
289 240
290 case PERF_RECORD_FORK: 241 case PERF_RECORD_FORK:
291 return process_fork_event(event, offset, head); 242 return process_task_event(event, offset, head);
292 /* 243 /*
293 * We dont process them right now but they are fine: 244 * We dont process them right now but they are fine:
294 */ 245 */
@@ -638,11 +589,6 @@ static int __cmd_annotate(void)
638 exit(0); 589 exit(0);
639 } 590 }
640 591
641 if (kernel_maps__init(vmlinux_name, true, use_modules) < 0) {
642 pr_err("failed to create kernel maps for symbol resolution\b");
643 return -1;
644 }
645
646remap: 592remap:
647 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, 593 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
648 MAP_SHARED, input, offset); 594 MAP_SHARED, input, offset);
@@ -743,8 +689,9 @@ static const struct option options[] = {
743 "be more verbose (show symbol address, etc)"), 689 "be more verbose (show symbol address, etc)"),
744 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 690 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
745 "dump raw trace in ASCII"), 691 "dump raw trace in ASCII"),
746 OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"), 692 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
747 OPT_BOOLEAN('m', "modules", &use_modules, 693 "file", "vmlinux pathname"),
694 OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
748 "load module symbols - WARNING: use only with -k and LIVE kernel"), 695 "load module symbols - WARNING: use only with -k and LIVE kernel"),
749 OPT_BOOLEAN('l', "print-line", &print_line, 696 OPT_BOOLEAN('l', "print-line", &print_line,
750 "print matching source lines (may be slow)"), 697 "print matching source lines (may be slow)"),
@@ -770,7 +717,8 @@ static void setup_sorting(void)
770 717
771int cmd_annotate(int argc, const char **argv, const char *prefix __used) 718int cmd_annotate(int argc, const char **argv, const char *prefix __used)
772{ 719{
773 symbol__init(sizeof(struct sym_priv)); 720 if (symbol__init(&symbol_conf) < 0)
721 return -1;
774 722
775 page_size = getpagesize(); 723 page_size = getpagesize();
776 724