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