perf tools: Factorize high level dso helpers
[safe/jmp/linux-2.6] / tools / perf / builtin-annotate.c
1 /*
2  * builtin-annotate.c
3  *
4  * Builtin annotate command: Analyze the perf.data input file,
5  * look up and read DSOs and symbol information and display
6  * a histogram of results, along various sorting keys.
7  */
8 #include "builtin.h"
9
10 #include "util/util.h"
11
12 #include "util/color.h"
13 #include <linux/list.h>
14 #include "util/cache.h"
15 #include <linux/rbtree.h>
16 #include "util/symbol.h"
17 #include "util/string.h"
18
19 #include "perf.h"
20
21 #include "util/parse-options.h"
22 #include "util/parse-events.h"
23
24 #define SHOW_KERNEL     1
25 #define SHOW_USER       2
26 #define SHOW_HV         4
27
28 static char             const *input_name = "perf.data";
29
30 static char             default_sort_order[] = "comm,symbol";
31 static char             *sort_order = default_sort_order;
32
33 static int              input;
34 static int              show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
35
36 static int              dump_trace = 0;
37 #define dprintf(x...)   do { if (dump_trace) printf(x); } while (0)
38
39
40 static int              full_paths;
41
42 static int              print_line;
43
44 static unsigned long    page_size;
45 static unsigned long    mmap_window = 32;
46
47 struct ip_event {
48         struct perf_event_header header;
49         u64 ip;
50         u32 pid, tid;
51 };
52
53 struct mmap_event {
54         struct perf_event_header header;
55         u32 pid, tid;
56         u64 start;
57         u64 len;
58         u64 pgoff;
59         char filename[PATH_MAX];
60 };
61
62 struct comm_event {
63         struct perf_event_header header;
64         u32 pid, tid;
65         char comm[16];
66 };
67
68 struct fork_event {
69         struct perf_event_header header;
70         u32 pid, ppid;
71 };
72
73 typedef union event_union {
74         struct perf_event_header        header;
75         struct ip_event                 ip;
76         struct mmap_event               mmap;
77         struct comm_event               comm;
78         struct fork_event               fork;
79 } event_t;
80
81
82 struct sym_ext {
83         struct rb_node  node;
84         double          percent;
85         char            *path;
86 };
87
88 struct map {
89         struct list_head node;
90         u64      start;
91         u64      end;
92         u64      pgoff;
93         u64      (*map_ip)(struct map *, u64);
94         struct dso       *dso;
95 };
96
97 static u64 map__map_ip(struct map *map, u64 ip)
98 {
99         return ip - map->start + map->pgoff;
100 }
101
102 static u64 vdso__map_ip(struct map *map __used, u64 ip)
103 {
104         return ip;
105 }
106
107 static struct map *map__new(struct mmap_event *event)
108 {
109         struct map *self = malloc(sizeof(*self));
110
111         if (self != NULL) {
112                 const char *filename = event->filename;
113
114                 self->start = event->start;
115                 self->end   = event->start + event->len;
116                 self->pgoff = event->pgoff;
117
118                 self->dso = dsos__findnew(filename);
119                 if (self->dso == NULL)
120                         goto out_delete;
121
122                 if (self->dso == vdso)
123                         self->map_ip = vdso__map_ip;
124                 else
125                         self->map_ip = map__map_ip;
126         }
127         return self;
128 out_delete:
129         free(self);
130         return NULL;
131 }
132
133 static struct map *map__clone(struct map *self)
134 {
135         struct map *map = malloc(sizeof(*self));
136
137         if (!map)
138                 return NULL;
139
140         memcpy(map, self, sizeof(*self));
141
142         return map;
143 }
144
145 static int map__overlap(struct map *l, struct map *r)
146 {
147         if (l->start > r->start) {
148                 struct map *t = l;
149                 l = r;
150                 r = t;
151         }
152
153         if (l->end > r->start)
154                 return 1;
155
156         return 0;
157 }
158
159 static size_t map__fprintf(struct map *self, FILE *fp)
160 {
161         return fprintf(fp, " %Lx-%Lx %Lx %s\n",
162                        self->start, self->end, self->pgoff, self->dso->name);
163 }
164
165
166 struct thread {
167         struct rb_node   rb_node;
168         struct list_head maps;
169         pid_t            pid;
170         char             *comm;
171 };
172
173 static struct thread *thread__new(pid_t pid)
174 {
175         struct thread *self = malloc(sizeof(*self));
176
177         if (self != NULL) {
178                 self->pid = pid;
179                 self->comm = malloc(32);
180                 if (self->comm)
181                         snprintf(self->comm, 32, ":%d", self->pid);
182                 INIT_LIST_HEAD(&self->maps);
183         }
184
185         return self;
186 }
187
188 static int thread__set_comm(struct thread *self, const char *comm)
189 {
190         if (self->comm)
191                 free(self->comm);
192         self->comm = strdup(comm);
193         return self->comm ? 0 : -ENOMEM;
194 }
195
196 static size_t thread__fprintf(struct thread *self, FILE *fp)
197 {
198         struct map *pos;
199         size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
200
201         list_for_each_entry(pos, &self->maps, node)
202                 ret += map__fprintf(pos, fp);
203
204         return ret;
205 }
206
207
208 static struct rb_root threads;
209 static struct thread *last_match;
210
211 static struct thread *threads__findnew(pid_t pid)
212 {
213         struct rb_node **p = &threads.rb_node;
214         struct rb_node *parent = NULL;
215         struct thread *th;
216
217         /*
218          * Font-end cache - PID lookups come in blocks,
219          * so most of the time we dont have to look up
220          * the full rbtree:
221          */
222         if (last_match && last_match->pid == pid)
223                 return last_match;
224
225         while (*p != NULL) {
226                 parent = *p;
227                 th = rb_entry(parent, struct thread, rb_node);
228
229                 if (th->pid == pid) {
230                         last_match = th;
231                         return th;
232                 }
233
234                 if (pid < th->pid)
235                         p = &(*p)->rb_left;
236                 else
237                         p = &(*p)->rb_right;
238         }
239
240         th = thread__new(pid);
241         if (th != NULL) {
242                 rb_link_node(&th->rb_node, parent, p);
243                 rb_insert_color(&th->rb_node, &threads);
244                 last_match = th;
245         }
246
247         return th;
248 }
249
250 static void thread__insert_map(struct thread *self, struct map *map)
251 {
252         struct map *pos, *tmp;
253
254         list_for_each_entry_safe(pos, tmp, &self->maps, node) {
255                 if (map__overlap(pos, map)) {
256                         list_del_init(&pos->node);
257                         /* XXX leaks dsos */
258                         free(pos);
259                 }
260         }
261
262         list_add_tail(&map->node, &self->maps);
263 }
264
265 static int thread__fork(struct thread *self, struct thread *parent)
266 {
267         struct map *map;
268
269         if (self->comm)
270                 free(self->comm);
271         self->comm = strdup(parent->comm);
272         if (!self->comm)
273                 return -ENOMEM;
274
275         list_for_each_entry(map, &parent->maps, node) {
276                 struct map *new = map__clone(map);
277                 if (!new)
278                         return -ENOMEM;
279                 thread__insert_map(self, new);
280         }
281
282         return 0;
283 }
284
285 static struct map *thread__find_map(struct thread *self, u64 ip)
286 {
287         struct map *pos;
288
289         if (self == NULL)
290                 return NULL;
291
292         list_for_each_entry(pos, &self->maps, node)
293                 if (ip >= pos->start && ip <= pos->end)
294                         return pos;
295
296         return NULL;
297 }
298
299 static size_t threads__fprintf(FILE *fp)
300 {
301         size_t ret = 0;
302         struct rb_node *nd;
303
304         for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
305                 struct thread *pos = rb_entry(nd, struct thread, rb_node);
306
307                 ret += thread__fprintf(pos, fp);
308         }
309
310         return ret;
311 }
312
313 /*
314  * histogram, sorted on item, collects counts
315  */
316
317 static struct rb_root hist;
318
319 struct hist_entry {
320         struct rb_node   rb_node;
321
322         struct thread    *thread;
323         struct map       *map;
324         struct dso       *dso;
325         struct symbol    *sym;
326         u64      ip;
327         char             level;
328
329         uint32_t         count;
330 };
331
332 /*
333  * configurable sorting bits
334  */
335
336 struct sort_entry {
337         struct list_head list;
338
339         char *header;
340
341         int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
342         int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
343         size_t  (*print)(FILE *fp, struct hist_entry *);
344 };
345
346 /* --sort pid */
347
348 static int64_t
349 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
350 {
351         return right->thread->pid - left->thread->pid;
352 }
353
354 static size_t
355 sort__thread_print(FILE *fp, struct hist_entry *self)
356 {
357         return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
358 }
359
360 static struct sort_entry sort_thread = {
361         .header = "         Command:  Pid",
362         .cmp    = sort__thread_cmp,
363         .print  = sort__thread_print,
364 };
365
366 /* --sort comm */
367
368 static int64_t
369 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
370 {
371         return right->thread->pid - left->thread->pid;
372 }
373
374 static int64_t
375 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
376 {
377         char *comm_l = left->thread->comm;
378         char *comm_r = right->thread->comm;
379
380         if (!comm_l || !comm_r) {
381                 if (!comm_l && !comm_r)
382                         return 0;
383                 else if (!comm_l)
384                         return -1;
385                 else
386                         return 1;
387         }
388
389         return strcmp(comm_l, comm_r);
390 }
391
392 static size_t
393 sort__comm_print(FILE *fp, struct hist_entry *self)
394 {
395         return fprintf(fp, "%16s", self->thread->comm);
396 }
397
398 static struct sort_entry sort_comm = {
399         .header         = "         Command",
400         .cmp            = sort__comm_cmp,
401         .collapse       = sort__comm_collapse,
402         .print          = sort__comm_print,
403 };
404
405 /* --sort dso */
406
407 static int64_t
408 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
409 {
410         struct dso *dso_l = left->dso;
411         struct dso *dso_r = right->dso;
412
413         if (!dso_l || !dso_r) {
414                 if (!dso_l && !dso_r)
415                         return 0;
416                 else if (!dso_l)
417                         return -1;
418                 else
419                         return 1;
420         }
421
422         return strcmp(dso_l->name, dso_r->name);
423 }
424
425 static size_t
426 sort__dso_print(FILE *fp, struct hist_entry *self)
427 {
428         if (self->dso)
429                 return fprintf(fp, "%-25s", self->dso->name);
430
431         return fprintf(fp, "%016llx         ", (u64)self->ip);
432 }
433
434 static struct sort_entry sort_dso = {
435         .header = "Shared Object            ",
436         .cmp    = sort__dso_cmp,
437         .print  = sort__dso_print,
438 };
439
440 /* --sort symbol */
441
442 static int64_t
443 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
444 {
445         u64 ip_l, ip_r;
446
447         if (left->sym == right->sym)
448                 return 0;
449
450         ip_l = left->sym ? left->sym->start : left->ip;
451         ip_r = right->sym ? right->sym->start : right->ip;
452
453         return (int64_t)(ip_r - ip_l);
454 }
455
456 static size_t
457 sort__sym_print(FILE *fp, struct hist_entry *self)
458 {
459         size_t ret = 0;
460
461         if (verbose)
462                 ret += fprintf(fp, "%#018llx  ", (u64)self->ip);
463
464         if (self->sym) {
465                 ret += fprintf(fp, "[%c] %s",
466                         self->dso == kernel_dso ? 'k' : '.', self->sym->name);
467         } else {
468                 ret += fprintf(fp, "%#016llx", (u64)self->ip);
469         }
470
471         return ret;
472 }
473
474 static struct sort_entry sort_sym = {
475         .header = "Symbol",
476         .cmp    = sort__sym_cmp,
477         .print  = sort__sym_print,
478 };
479
480 static int sort__need_collapse = 0;
481
482 struct sort_dimension {
483         char                    *name;
484         struct sort_entry       *entry;
485         int                     taken;
486 };
487
488 static struct sort_dimension sort_dimensions[] = {
489         { .name = "pid",        .entry = &sort_thread,  },
490         { .name = "comm",       .entry = &sort_comm,    },
491         { .name = "dso",        .entry = &sort_dso,     },
492         { .name = "symbol",     .entry = &sort_sym,     },
493 };
494
495 static LIST_HEAD(hist_entry__sort_list);
496
497 static int sort_dimension__add(char *tok)
498 {
499         unsigned int i;
500
501         for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
502                 struct sort_dimension *sd = &sort_dimensions[i];
503
504                 if (sd->taken)
505                         continue;
506
507                 if (strncasecmp(tok, sd->name, strlen(tok)))
508                         continue;
509
510                 if (sd->entry->collapse)
511                         sort__need_collapse = 1;
512
513                 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
514                 sd->taken = 1;
515
516                 return 0;
517         }
518
519         return -ESRCH;
520 }
521
522 static int64_t
523 hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
524 {
525         struct sort_entry *se;
526         int64_t cmp = 0;
527
528         list_for_each_entry(se, &hist_entry__sort_list, list) {
529                 cmp = se->cmp(left, right);
530                 if (cmp)
531                         break;
532         }
533
534         return cmp;
535 }
536
537 static int64_t
538 hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
539 {
540         struct sort_entry *se;
541         int64_t cmp = 0;
542
543         list_for_each_entry(se, &hist_entry__sort_list, list) {
544                 int64_t (*f)(struct hist_entry *, struct hist_entry *);
545
546                 f = se->collapse ?: se->cmp;
547
548                 cmp = f(left, right);
549                 if (cmp)
550                         break;
551         }
552
553         return cmp;
554 }
555
556 /*
557  * collect histogram counts
558  */
559 static void hist_hit(struct hist_entry *he, u64 ip)
560 {
561         unsigned int sym_size, offset;
562         struct symbol *sym = he->sym;
563
564         he->count++;
565
566         if (!sym || !sym->hist)
567                 return;
568
569         sym_size = sym->end - sym->start;
570         offset = ip - sym->start;
571
572         if (offset >= sym_size)
573                 return;
574
575         sym->hist_sum++;
576         sym->hist[offset]++;
577
578         if (verbose >= 3)
579                 printf("%p %s: count++ [ip: %p, %08Lx] => %Ld\n",
580                         (void *)(unsigned long)he->sym->start,
581                         he->sym->name,
582                         (void *)(unsigned long)ip, ip - he->sym->start,
583                         sym->hist[offset]);
584 }
585
586 static int
587 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
588                 struct symbol *sym, u64 ip, char level)
589 {
590         struct rb_node **p = &hist.rb_node;
591         struct rb_node *parent = NULL;
592         struct hist_entry *he;
593         struct hist_entry entry = {
594                 .thread = thread,
595                 .map    = map,
596                 .dso    = dso,
597                 .sym    = sym,
598                 .ip     = ip,
599                 .level  = level,
600                 .count  = 1,
601         };
602         int cmp;
603
604         while (*p != NULL) {
605                 parent = *p;
606                 he = rb_entry(parent, struct hist_entry, rb_node);
607
608                 cmp = hist_entry__cmp(&entry, he);
609
610                 if (!cmp) {
611                         hist_hit(he, ip);
612
613                         return 0;
614                 }
615
616                 if (cmp < 0)
617                         p = &(*p)->rb_left;
618                 else
619                         p = &(*p)->rb_right;
620         }
621
622         he = malloc(sizeof(*he));
623         if (!he)
624                 return -ENOMEM;
625         *he = entry;
626         rb_link_node(&he->rb_node, parent, p);
627         rb_insert_color(&he->rb_node, &hist);
628
629         return 0;
630 }
631
632 static void hist_entry__free(struct hist_entry *he)
633 {
634         free(he);
635 }
636
637 /*
638  * collapse the histogram
639  */
640
641 static struct rb_root collapse_hists;
642
643 static void collapse__insert_entry(struct hist_entry *he)
644 {
645         struct rb_node **p = &collapse_hists.rb_node;
646         struct rb_node *parent = NULL;
647         struct hist_entry *iter;
648         int64_t cmp;
649
650         while (*p != NULL) {
651                 parent = *p;
652                 iter = rb_entry(parent, struct hist_entry, rb_node);
653
654                 cmp = hist_entry__collapse(iter, he);
655
656                 if (!cmp) {
657                         iter->count += he->count;
658                         hist_entry__free(he);
659                         return;
660                 }
661
662                 if (cmp < 0)
663                         p = &(*p)->rb_left;
664                 else
665                         p = &(*p)->rb_right;
666         }
667
668         rb_link_node(&he->rb_node, parent, p);
669         rb_insert_color(&he->rb_node, &collapse_hists);
670 }
671
672 static void collapse__resort(void)
673 {
674         struct rb_node *next;
675         struct hist_entry *n;
676
677         if (!sort__need_collapse)
678                 return;
679
680         next = rb_first(&hist);
681         while (next) {
682                 n = rb_entry(next, struct hist_entry, rb_node);
683                 next = rb_next(&n->rb_node);
684
685                 rb_erase(&n->rb_node, &hist);
686                 collapse__insert_entry(n);
687         }
688 }
689
690 /*
691  * reverse the map, sort on count.
692  */
693
694 static struct rb_root output_hists;
695
696 static void output__insert_entry(struct hist_entry *he)
697 {
698         struct rb_node **p = &output_hists.rb_node;
699         struct rb_node *parent = NULL;
700         struct hist_entry *iter;
701
702         while (*p != NULL) {
703                 parent = *p;
704                 iter = rb_entry(parent, struct hist_entry, rb_node);
705
706                 if (he->count > iter->count)
707                         p = &(*p)->rb_left;
708                 else
709                         p = &(*p)->rb_right;
710         }
711
712         rb_link_node(&he->rb_node, parent, p);
713         rb_insert_color(&he->rb_node, &output_hists);
714 }
715
716 static void output__resort(void)
717 {
718         struct rb_node *next;
719         struct hist_entry *n;
720         struct rb_root *tree = &hist;
721
722         if (sort__need_collapse)
723                 tree = &collapse_hists;
724
725         next = rb_first(tree);
726
727         while (next) {
728                 n = rb_entry(next, struct hist_entry, rb_node);
729                 next = rb_next(&n->rb_node);
730
731                 rb_erase(&n->rb_node, tree);
732                 output__insert_entry(n);
733         }
734 }
735
736 static void register_idle_thread(void)
737 {
738         struct thread *thread = threads__findnew(0);
739
740         if (thread == NULL ||
741                         thread__set_comm(thread, "[idle]")) {
742                 fprintf(stderr, "problem inserting idle task.\n");
743                 exit(-1);
744         }
745 }
746
747 static unsigned long total = 0,
748                      total_mmap = 0,
749                      total_comm = 0,
750                      total_fork = 0,
751                      total_unknown = 0;
752
753 static int
754 process_sample_event(event_t *event, unsigned long offset, unsigned long head)
755 {
756         char level;
757         int show = 0;
758         struct dso *dso = NULL;
759         struct thread *thread = threads__findnew(event->ip.pid);
760         u64 ip = event->ip.ip;
761         struct map *map = NULL;
762
763         dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",
764                 (void *)(offset + head),
765                 (void *)(long)(event->header.size),
766                 event->header.misc,
767                 event->ip.pid,
768                 (void *)(long)ip);
769
770         dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
771
772         if (thread == NULL) {
773                 fprintf(stderr, "problem processing %d event, skipping it.\n",
774                         event->header.type);
775                 return -1;
776         }
777
778         if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
779                 show = SHOW_KERNEL;
780                 level = 'k';
781
782                 dso = kernel_dso;
783
784                 dprintf(" ...... dso: %s\n", dso->name);
785
786         } else if (event->header.misc & PERF_EVENT_MISC_USER) {
787
788                 show = SHOW_USER;
789                 level = '.';
790
791                 map = thread__find_map(thread, ip);
792                 if (map != NULL) {
793                         ip = map->map_ip(map, ip);
794                         dso = map->dso;
795                 } else {
796                         /*
797                          * If this is outside of all known maps,
798                          * and is a negative address, try to look it
799                          * up in the kernel dso, as it might be a
800                          * vsyscall (which executes in user-mode):
801                          */
802                         if ((long long)ip < 0)
803                                 dso = kernel_dso;
804                 }
805                 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
806
807         } else {
808                 show = SHOW_HV;
809                 level = 'H';
810                 dprintf(" ...... dso: [hypervisor]\n");
811         }
812
813         if (show & show_mask) {
814                 struct symbol *sym = NULL;
815
816                 if (dso)
817                         sym = dso->find_symbol(dso, ip);
818
819                 if (hist_entry__add(thread, map, dso, sym, ip, level)) {
820                         fprintf(stderr,
821                 "problem incrementing symbol count, skipping event\n");
822                         return -1;
823                 }
824         }
825         total++;
826
827         return 0;
828 }
829
830 static int
831 process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
832 {
833         struct thread *thread = threads__findnew(event->mmap.pid);
834         struct map *map = map__new(&event->mmap);
835
836         dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
837                 (void *)(offset + head),
838                 (void *)(long)(event->header.size),
839                 event->mmap.pid,
840                 (void *)(long)event->mmap.start,
841                 (void *)(long)event->mmap.len,
842                 (void *)(long)event->mmap.pgoff,
843                 event->mmap.filename);
844
845         if (thread == NULL || map == NULL) {
846                 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
847                 return 0;
848         }
849
850         thread__insert_map(thread, map);
851         total_mmap++;
852
853         return 0;
854 }
855
856 static int
857 process_comm_event(event_t *event, unsigned long offset, unsigned long head)
858 {
859         struct thread *thread = threads__findnew(event->comm.pid);
860
861         dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
862                 (void *)(offset + head),
863                 (void *)(long)(event->header.size),
864                 event->comm.comm, event->comm.pid);
865
866         if (thread == NULL ||
867             thread__set_comm(thread, event->comm.comm)) {
868                 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
869                 return -1;
870         }
871         total_comm++;
872
873         return 0;
874 }
875
876 static int
877 process_fork_event(event_t *event, unsigned long offset, unsigned long head)
878 {
879         struct thread *thread = threads__findnew(event->fork.pid);
880         struct thread *parent = threads__findnew(event->fork.ppid);
881
882         dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
883                 (void *)(offset + head),
884                 (void *)(long)(event->header.size),
885                 event->fork.pid, event->fork.ppid);
886
887         if (!thread || !parent || thread__fork(thread, parent)) {
888                 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
889                 return -1;
890         }
891         total_fork++;
892
893         return 0;
894 }
895
896 static int
897 process_event(event_t *event, unsigned long offset, unsigned long head)
898 {
899         switch (event->header.type) {
900         case PERF_EVENT_SAMPLE:
901                 return process_sample_event(event, offset, head);
902
903         case PERF_EVENT_MMAP:
904                 return process_mmap_event(event, offset, head);
905
906         case PERF_EVENT_COMM:
907                 return process_comm_event(event, offset, head);
908
909         case PERF_EVENT_FORK:
910                 return process_fork_event(event, offset, head);
911         /*
912          * We dont process them right now but they are fine:
913          */
914
915         case PERF_EVENT_THROTTLE:
916         case PERF_EVENT_UNTHROTTLE:
917                 return 0;
918
919         default:
920                 return -1;
921         }
922
923         return 0;
924 }
925
926 static int
927 parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
928 {
929         char *line = NULL, *tmp, *tmp2;
930         static const char *prev_line;
931         static const char *prev_color;
932         unsigned int offset;
933         size_t line_len;
934         s64 line_ip;
935         int ret;
936         char *c;
937
938         if (getline(&line, &line_len, file) < 0)
939                 return -1;
940         if (!line)
941                 return -1;
942
943         c = strchr(line, '\n');
944         if (c)
945                 *c = 0;
946
947         line_ip = -1;
948         offset = 0;
949         ret = -2;
950
951         /*
952          * Strip leading spaces:
953          */
954         tmp = line;
955         while (*tmp) {
956                 if (*tmp != ' ')
957                         break;
958                 tmp++;
959         }
960
961         if (*tmp) {
962                 /*
963                  * Parse hexa addresses followed by ':'
964                  */
965                 line_ip = strtoull(tmp, &tmp2, 16);
966                 if (*tmp2 != ':')
967                         line_ip = -1;
968         }
969
970         if (line_ip != -1) {
971                 const char *path = NULL;
972                 unsigned int hits = 0;
973                 double percent = 0.0;
974                 char *color;
975                 struct sym_ext *sym_ext = sym->priv;
976
977                 offset = line_ip - start;
978                 if (offset < len)
979                         hits = sym->hist[offset];
980
981                 if (offset < len && sym_ext) {
982                         path = sym_ext[offset].path;
983                         percent = sym_ext[offset].percent;
984                 } else if (sym->hist_sum)
985                         percent = 100.0 * hits / sym->hist_sum;
986
987                 color = get_percent_color(percent);
988
989                 /*
990                  * Also color the filename and line if needed, with
991                  * the same color than the percentage. Don't print it
992                  * twice for close colored ip with the same filename:line
993                  */
994                 if (path) {
995                         if (!prev_line || strcmp(prev_line, path)
996                                        || color != prev_color) {
997                                 color_fprintf(stdout, color, " %s", path);
998                                 prev_line = path;
999                                 prev_color = color;
1000                         }
1001                 }
1002
1003                 color_fprintf(stdout, color, " %7.2f", percent);
1004                 printf(" :      ");
1005                 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", line);
1006         } else {
1007                 if (!*line)
1008                         printf("         :\n");
1009                 else
1010                         printf("         :      %s\n", line);
1011         }
1012
1013         return 0;
1014 }
1015
1016 static struct rb_root root_sym_ext;
1017
1018 static void insert_source_line(struct sym_ext *sym_ext)
1019 {
1020         struct sym_ext *iter;
1021         struct rb_node **p = &root_sym_ext.rb_node;
1022         struct rb_node *parent = NULL;
1023
1024         while (*p != NULL) {
1025                 parent = *p;
1026                 iter = rb_entry(parent, struct sym_ext, node);
1027
1028                 if (sym_ext->percent > iter->percent)
1029                         p = &(*p)->rb_left;
1030                 else
1031                         p = &(*p)->rb_right;
1032         }
1033
1034         rb_link_node(&sym_ext->node, parent, p);
1035         rb_insert_color(&sym_ext->node, &root_sym_ext);
1036 }
1037
1038 static void free_source_line(struct symbol *sym, int len)
1039 {
1040         struct sym_ext *sym_ext = sym->priv;
1041         int i;
1042
1043         if (!sym_ext)
1044                 return;
1045
1046         for (i = 0; i < len; i++)
1047                 free(sym_ext[i].path);
1048         free(sym_ext);
1049
1050         sym->priv = NULL;
1051         root_sym_ext = RB_ROOT;
1052 }
1053
1054 /* Get the filename:line for the colored entries */
1055 static void
1056 get_source_line(struct symbol *sym, u64 start, int len, char *filename)
1057 {
1058         int i;
1059         char cmd[PATH_MAX * 2];
1060         struct sym_ext *sym_ext;
1061
1062         if (!sym->hist_sum)
1063                 return;
1064
1065         sym->priv = calloc(len, sizeof(struct sym_ext));
1066         if (!sym->priv)
1067                 return;
1068
1069         sym_ext = sym->priv;
1070
1071         for (i = 0; i < len; i++) {
1072                 char *path = NULL;
1073                 size_t line_len;
1074                 u64 offset;
1075                 FILE *fp;
1076
1077                 sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
1078                 if (sym_ext[i].percent <= 0.5)
1079                         continue;
1080
1081                 offset = start + i;
1082                 sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
1083                 fp = popen(cmd, "r");
1084                 if (!fp)
1085                         continue;
1086
1087                 if (getline(&path, &line_len, fp) < 0 || !line_len)
1088                         goto next;
1089
1090                 sym_ext[i].path = malloc(sizeof(char) * line_len + 1);
1091                 if (!sym_ext[i].path)
1092                         goto next;
1093
1094                 strcpy(sym_ext[i].path, path);
1095                 insert_source_line(&sym_ext[i]);
1096
1097         next:
1098                 pclose(fp);
1099         }
1100 }
1101
1102 static void print_summary(char *filename)
1103 {
1104         struct sym_ext *sym_ext;
1105         struct rb_node *node;
1106
1107         printf("\nSorted summary for file %s\n", filename);
1108         printf("----------------------------------------------\n\n");
1109
1110         if (RB_EMPTY_ROOT(&root_sym_ext)) {
1111                 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
1112                 return;
1113         }
1114
1115         node = rb_first(&root_sym_ext);
1116         while (node) {
1117                 double percent;
1118                 char *color;
1119                 char *path;
1120
1121                 sym_ext = rb_entry(node, struct sym_ext, node);
1122                 percent = sym_ext->percent;
1123                 color = get_percent_color(percent);
1124                 path = sym_ext->path;
1125
1126                 color_fprintf(stdout, color, " %7.2f %s", percent, path);
1127                 node = rb_next(node);
1128         }
1129 }
1130
1131 static void annotate_sym(struct dso *dso, struct symbol *sym)
1132 {
1133         char *filename = dso->name, *d_filename;
1134         u64 start, end, len;
1135         char command[PATH_MAX*2];
1136         FILE *file;
1137
1138         if (!filename)
1139                 return;
1140         if (sym->module)
1141                 filename = sym->module->path;
1142         else if (dso == kernel_dso)
1143                 filename = vmlinux;
1144
1145         start = sym->obj_start;
1146         if (!start)
1147                 start = sym->start;
1148         if (full_paths)
1149                 d_filename = filename;
1150         else
1151                 d_filename = basename(filename);
1152
1153         end = start + sym->end - sym->start + 1;
1154         len = sym->end - sym->start;
1155
1156         if (print_line) {
1157                 get_source_line(sym, start, len, filename);
1158                 print_summary(filename);
1159         }
1160
1161         printf("\n\n------------------------------------------------\n");
1162         printf(" Percent |      Source code & Disassembly of %s\n", d_filename);
1163         printf("------------------------------------------------\n");
1164
1165         if (verbose >= 2)
1166                 printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
1167
1168         sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
1169                         (u64)start, (u64)end, filename, filename);
1170
1171         if (verbose >= 3)
1172                 printf("doing: %s\n", command);
1173
1174         file = popen(command, "r");
1175         if (!file)
1176                 return;
1177
1178         while (!feof(file)) {
1179                 if (parse_line(file, sym, start, len) < 0)
1180                         break;
1181         }
1182
1183         pclose(file);
1184         if (print_line)
1185                 free_source_line(sym, len);
1186 }
1187
1188 static void find_annotations(void)
1189 {
1190         struct rb_node *nd;
1191         struct dso *dso;
1192         int count = 0;
1193
1194         list_for_each_entry(dso, &dsos, node) {
1195
1196                 for (nd = rb_first(&dso->syms); nd; nd = rb_next(nd)) {
1197                         struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
1198
1199                         if (sym->hist) {
1200                                 annotate_sym(dso, sym);
1201                                 count++;
1202                         }
1203                 }
1204         }
1205
1206         if (!count)
1207                 printf(" Error: symbol '%s' not present amongst the samples.\n", sym_hist_filter);
1208 }
1209
1210 static int __cmd_annotate(void)
1211 {
1212         int ret, rc = EXIT_FAILURE;
1213         unsigned long offset = 0;
1214         unsigned long head = 0;
1215         struct stat stat;
1216         event_t *event;
1217         uint32_t size;
1218         char *buf;
1219
1220         register_idle_thread();
1221
1222         input = open(input_name, O_RDONLY);
1223         if (input < 0) {
1224                 perror("failed to open file");
1225                 exit(-1);
1226         }
1227
1228         ret = fstat(input, &stat);
1229         if (ret < 0) {
1230                 perror("failed to stat file");
1231                 exit(-1);
1232         }
1233
1234         if (!stat.st_size) {
1235                 fprintf(stderr, "zero-sized file, nothing to do!\n");
1236                 exit(0);
1237         }
1238
1239         if (load_kernel() < 0) {
1240                 perror("failed to load kernel symbols");
1241                 return EXIT_FAILURE;
1242         }
1243
1244 remap:
1245         buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
1246                            MAP_SHARED, input, offset);
1247         if (buf == MAP_FAILED) {
1248                 perror("failed to mmap file");
1249                 exit(-1);
1250         }
1251
1252 more:
1253         event = (event_t *)(buf + head);
1254
1255         size = event->header.size;
1256         if (!size)
1257                 size = 8;
1258
1259         if (head + event->header.size >= page_size * mmap_window) {
1260                 unsigned long shift = page_size * (head / page_size);
1261                 int ret;
1262
1263                 ret = munmap(buf, page_size * mmap_window);
1264                 assert(ret == 0);
1265
1266                 offset += shift;
1267                 head -= shift;
1268                 goto remap;
1269         }
1270
1271         size = event->header.size;
1272
1273         dprintf("%p [%p]: event: %d\n",
1274                         (void *)(offset + head),
1275                         (void *)(long)event->header.size,
1276                         event->header.type);
1277
1278         if (!size || process_event(event, offset, head) < 0) {
1279
1280                 dprintf("%p [%p]: skipping unknown header type: %d\n",
1281                         (void *)(offset + head),
1282                         (void *)(long)(event->header.size),
1283                         event->header.type);
1284
1285                 total_unknown++;
1286
1287                 /*
1288                  * assume we lost track of the stream, check alignment, and
1289                  * increment a single u64 in the hope to catch on again 'soon'.
1290                  */
1291
1292                 if (unlikely(head & 7))
1293                         head &= ~7ULL;
1294
1295                 size = 8;
1296         }
1297
1298         head += size;
1299
1300         if (offset + head < (unsigned long)stat.st_size)
1301                 goto more;
1302
1303         rc = EXIT_SUCCESS;
1304         close(input);
1305
1306         dprintf("      IP events: %10ld\n", total);
1307         dprintf("    mmap events: %10ld\n", total_mmap);
1308         dprintf("    comm events: %10ld\n", total_comm);
1309         dprintf("    fork events: %10ld\n", total_fork);
1310         dprintf(" unknown events: %10ld\n", total_unknown);
1311
1312         if (dump_trace)
1313                 return 0;
1314
1315         if (verbose >= 3)
1316                 threads__fprintf(stdout);
1317
1318         if (verbose >= 2)
1319                 dsos__fprintf(stdout);
1320
1321         collapse__resort();
1322         output__resort();
1323
1324         find_annotations();
1325
1326         return rc;
1327 }
1328
1329 static const char * const annotate_usage[] = {
1330         "perf annotate [<options>] <command>",
1331         NULL
1332 };
1333
1334 static const struct option options[] = {
1335         OPT_STRING('i', "input", &input_name, "file",
1336                     "input file name"),
1337         OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
1338                     "symbol to annotate"),
1339         OPT_BOOLEAN('v', "verbose", &verbose,
1340                     "be more verbose (show symbol address, etc)"),
1341         OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1342                     "dump raw trace in ASCII"),
1343         OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
1344         OPT_BOOLEAN('m', "modules", &modules,
1345                     "load module symbols - WARNING: use only with -k and LIVE kernel"),
1346         OPT_BOOLEAN('l', "print-line", &print_line,
1347                     "print matching source lines (may be slow)"),
1348         OPT_BOOLEAN('P', "full-paths", &full_paths,
1349                     "Don't shorten the displayed pathnames"),
1350         OPT_END()
1351 };
1352
1353 static void setup_sorting(void)
1354 {
1355         char *tmp, *tok, *str = strdup(sort_order);
1356
1357         for (tok = strtok_r(str, ", ", &tmp);
1358                         tok; tok = strtok_r(NULL, ", ", &tmp)) {
1359                 if (sort_dimension__add(tok) < 0) {
1360                         error("Unknown --sort key: `%s'", tok);
1361                         usage_with_options(annotate_usage, options);
1362                 }
1363         }
1364
1365         free(str);
1366 }
1367
1368 int cmd_annotate(int argc, const char **argv, const char *prefix __used)
1369 {
1370         symbol__init();
1371
1372         page_size = getpagesize();
1373
1374         argc = parse_options(argc, argv, options, annotate_usage, 0);
1375
1376         setup_sorting();
1377
1378         if (argc) {
1379                 /*
1380                  * Special case: if there's an argument left then assume tha
1381                  * it's a symbol filter:
1382                  */
1383                 if (argc > 1)
1384                         usage_with_options(annotate_usage, options);
1385
1386                 sym_hist_filter = argv[0];
1387         }
1388
1389         if (!sym_hist_filter)
1390                 usage_with_options(annotate_usage, options);
1391
1392         setup_pager();
1393
1394         return __cmd_annotate();
1395 }