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