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