xref: /openbmc/linux/tools/perf/util/annotate.c (revision 8fdff1dc)
1 /*
2  * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3  *
4  * Parts came from builtin-annotate.c, see those files for further
5  * copyright notes.
6  *
7  * Released under the GPL v2. (and only v2, not any later version)
8  */
9 
10 #include "util.h"
11 #include "build-id.h"
12 #include "color.h"
13 #include "cache.h"
14 #include "symbol.h"
15 #include "debug.h"
16 #include "annotate.h"
17 #include <pthread.h>
18 #include <linux/bitops.h>
19 
20 const char 	*disassembler_style;
21 const char	*objdump_path;
22 
23 static struct ins *ins__find(const char *name);
24 static int disasm_line__parse(char *line, char **namep, char **rawp);
25 
26 static void ins__delete(struct ins_operands *ops)
27 {
28 	free(ops->source.raw);
29 	free(ops->source.name);
30 	free(ops->target.raw);
31 	free(ops->target.name);
32 }
33 
34 static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
35 			      struct ins_operands *ops)
36 {
37 	return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->raw);
38 }
39 
40 int ins__scnprintf(struct ins *ins, char *bf, size_t size,
41 		  struct ins_operands *ops)
42 {
43 	if (ins->ops->scnprintf)
44 		return ins->ops->scnprintf(ins, bf, size, ops);
45 
46 	return ins__raw_scnprintf(ins, bf, size, ops);
47 }
48 
49 static int call__parse(struct ins_operands *ops)
50 {
51 	char *endptr, *tok, *name;
52 
53 	ops->target.addr = strtoull(ops->raw, &endptr, 16);
54 
55 	name = strchr(endptr, '<');
56 	if (name == NULL)
57 		goto indirect_call;
58 
59 	name++;
60 
61 	tok = strchr(name, '>');
62 	if (tok == NULL)
63 		return -1;
64 
65 	*tok = '\0';
66 	ops->target.name = strdup(name);
67 	*tok = '>';
68 
69 	return ops->target.name == NULL ? -1 : 0;
70 
71 indirect_call:
72 	tok = strchr(endptr, '(');
73 	if (tok != NULL) {
74 		ops->target.addr = 0;
75 		return 0;
76 	}
77 
78 	tok = strchr(endptr, '*');
79 	if (tok == NULL)
80 		return -1;
81 
82 	ops->target.addr = strtoull(tok + 1, NULL, 16);
83 	return 0;
84 }
85 
86 static int call__scnprintf(struct ins *ins, char *bf, size_t size,
87 			   struct ins_operands *ops)
88 {
89 	if (ops->target.name)
90 		return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->target.name);
91 
92 	if (ops->target.addr == 0)
93 		return ins__raw_scnprintf(ins, bf, size, ops);
94 
95 	return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, ops->target.addr);
96 }
97 
98 static struct ins_ops call_ops = {
99 	.parse	   = call__parse,
100 	.scnprintf = call__scnprintf,
101 };
102 
103 bool ins__is_call(const struct ins *ins)
104 {
105 	return ins->ops == &call_ops;
106 }
107 
108 static int jump__parse(struct ins_operands *ops)
109 {
110 	const char *s = strchr(ops->raw, '+');
111 
112 	ops->target.addr = strtoll(ops->raw, NULL, 16);
113 
114 	if (s++ != NULL)
115 		ops->target.offset = strtoll(s, NULL, 16);
116 	else
117 		ops->target.offset = UINT64_MAX;
118 
119 	return 0;
120 }
121 
122 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
123 			   struct ins_operands *ops)
124 {
125 	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
126 }
127 
128 static struct ins_ops jump_ops = {
129 	.parse	   = jump__parse,
130 	.scnprintf = jump__scnprintf,
131 };
132 
133 bool ins__is_jump(const struct ins *ins)
134 {
135 	return ins->ops == &jump_ops;
136 }
137 
138 static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
139 {
140 	char *endptr, *name, *t;
141 
142 	if (strstr(raw, "(%rip)") == NULL)
143 		return 0;
144 
145 	*addrp = strtoull(comment, &endptr, 16);
146 	name = strchr(endptr, '<');
147 	if (name == NULL)
148 		return -1;
149 
150 	name++;
151 
152 	t = strchr(name, '>');
153 	if (t == NULL)
154 		return 0;
155 
156 	*t = '\0';
157 	*namep = strdup(name);
158 	*t = '>';
159 
160 	return 0;
161 }
162 
163 static int lock__parse(struct ins_operands *ops)
164 {
165 	char *name;
166 
167 	ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
168 	if (ops->locked.ops == NULL)
169 		return 0;
170 
171 	if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0)
172 		goto out_free_ops;
173 
174 	ops->locked.ins = ins__find(name);
175 	if (ops->locked.ins == NULL)
176 		goto out_free_ops;
177 
178 	if (!ops->locked.ins->ops)
179 		return 0;
180 
181 	if (ops->locked.ins->ops->parse)
182 		ops->locked.ins->ops->parse(ops->locked.ops);
183 
184 	return 0;
185 
186 out_free_ops:
187 	free(ops->locked.ops);
188 	ops->locked.ops = NULL;
189 	return 0;
190 }
191 
192 static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
193 			   struct ins_operands *ops)
194 {
195 	int printed;
196 
197 	if (ops->locked.ins == NULL)
198 		return ins__raw_scnprintf(ins, bf, size, ops);
199 
200 	printed = scnprintf(bf, size, "%-6.6s ", ins->name);
201 	return printed + ins__scnprintf(ops->locked.ins, bf + printed,
202 					size - printed, ops->locked.ops);
203 }
204 
205 static void lock__delete(struct ins_operands *ops)
206 {
207 	free(ops->locked.ops);
208 	free(ops->target.raw);
209 	free(ops->target.name);
210 }
211 
212 static struct ins_ops lock_ops = {
213 	.free	   = lock__delete,
214 	.parse	   = lock__parse,
215 	.scnprintf = lock__scnprintf,
216 };
217 
218 static int mov__parse(struct ins_operands *ops)
219 {
220 	char *s = strchr(ops->raw, ','), *target, *comment, prev;
221 
222 	if (s == NULL)
223 		return -1;
224 
225 	*s = '\0';
226 	ops->source.raw = strdup(ops->raw);
227 	*s = ',';
228 
229 	if (ops->source.raw == NULL)
230 		return -1;
231 
232 	target = ++s;
233 
234 	while (s[0] != '\0' && !isspace(s[0]))
235 		++s;
236 	prev = *s;
237 	*s = '\0';
238 
239 	ops->target.raw = strdup(target);
240 	*s = prev;
241 
242 	if (ops->target.raw == NULL)
243 		goto out_free_source;
244 
245 	comment = strchr(s, '#');
246 	if (comment == NULL)
247 		return 0;
248 
249 	while (comment[0] != '\0' && isspace(comment[0]))
250 		++comment;
251 
252 	comment__symbol(ops->source.raw, comment, &ops->source.addr, &ops->source.name);
253 	comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name);
254 
255 	return 0;
256 
257 out_free_source:
258 	free(ops->source.raw);
259 	ops->source.raw = NULL;
260 	return -1;
261 }
262 
263 static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
264 			   struct ins_operands *ops)
265 {
266 	return scnprintf(bf, size, "%-6.6s %s,%s", ins->name,
267 			 ops->source.name ?: ops->source.raw,
268 			 ops->target.name ?: ops->target.raw);
269 }
270 
271 static struct ins_ops mov_ops = {
272 	.parse	   = mov__parse,
273 	.scnprintf = mov__scnprintf,
274 };
275 
276 static int dec__parse(struct ins_operands *ops)
277 {
278 	char *target, *comment, *s, prev;
279 
280 	target = s = ops->raw;
281 
282 	while (s[0] != '\0' && !isspace(s[0]))
283 		++s;
284 	prev = *s;
285 	*s = '\0';
286 
287 	ops->target.raw = strdup(target);
288 	*s = prev;
289 
290 	if (ops->target.raw == NULL)
291 		return -1;
292 
293 	comment = strchr(s, '#');
294 	if (comment == NULL)
295 		return 0;
296 
297 	while (comment[0] != '\0' && isspace(comment[0]))
298 		++comment;
299 
300 	comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name);
301 
302 	return 0;
303 }
304 
305 static int dec__scnprintf(struct ins *ins, char *bf, size_t size,
306 			   struct ins_operands *ops)
307 {
308 	return scnprintf(bf, size, "%-6.6s %s", ins->name,
309 			 ops->target.name ?: ops->target.raw);
310 }
311 
312 static struct ins_ops dec_ops = {
313 	.parse	   = dec__parse,
314 	.scnprintf = dec__scnprintf,
315 };
316 
317 static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size,
318 			  struct ins_operands *ops __maybe_unused)
319 {
320 	return scnprintf(bf, size, "%-6.6s", "nop");
321 }
322 
323 static struct ins_ops nop_ops = {
324 	.scnprintf = nop__scnprintf,
325 };
326 
327 /*
328  * Must be sorted by name!
329  */
330 static struct ins instructions[] = {
331 	{ .name = "add",   .ops  = &mov_ops, },
332 	{ .name = "addl",  .ops  = &mov_ops, },
333 	{ .name = "addq",  .ops  = &mov_ops, },
334 	{ .name = "addw",  .ops  = &mov_ops, },
335 	{ .name = "and",   .ops  = &mov_ops, },
336 	{ .name = "bts",   .ops  = &mov_ops, },
337 	{ .name = "call",  .ops  = &call_ops, },
338 	{ .name = "callq", .ops  = &call_ops, },
339 	{ .name = "cmp",   .ops  = &mov_ops, },
340 	{ .name = "cmpb",  .ops  = &mov_ops, },
341 	{ .name = "cmpl",  .ops  = &mov_ops, },
342 	{ .name = "cmpq",  .ops  = &mov_ops, },
343 	{ .name = "cmpw",  .ops  = &mov_ops, },
344 	{ .name = "cmpxch", .ops  = &mov_ops, },
345 	{ .name = "dec",   .ops  = &dec_ops, },
346 	{ .name = "decl",  .ops  = &dec_ops, },
347 	{ .name = "imul",  .ops  = &mov_ops, },
348 	{ .name = "inc",   .ops  = &dec_ops, },
349 	{ .name = "incl",  .ops  = &dec_ops, },
350 	{ .name = "ja",	   .ops  = &jump_ops, },
351 	{ .name = "jae",   .ops  = &jump_ops, },
352 	{ .name = "jb",	   .ops  = &jump_ops, },
353 	{ .name = "jbe",   .ops  = &jump_ops, },
354 	{ .name = "jc",	   .ops  = &jump_ops, },
355 	{ .name = "jcxz",  .ops  = &jump_ops, },
356 	{ .name = "je",	   .ops  = &jump_ops, },
357 	{ .name = "jecxz", .ops  = &jump_ops, },
358 	{ .name = "jg",	   .ops  = &jump_ops, },
359 	{ .name = "jge",   .ops  = &jump_ops, },
360 	{ .name = "jl",    .ops  = &jump_ops, },
361 	{ .name = "jle",   .ops  = &jump_ops, },
362 	{ .name = "jmp",   .ops  = &jump_ops, },
363 	{ .name = "jmpq",  .ops  = &jump_ops, },
364 	{ .name = "jna",   .ops  = &jump_ops, },
365 	{ .name = "jnae",  .ops  = &jump_ops, },
366 	{ .name = "jnb",   .ops  = &jump_ops, },
367 	{ .name = "jnbe",  .ops  = &jump_ops, },
368 	{ .name = "jnc",   .ops  = &jump_ops, },
369 	{ .name = "jne",   .ops  = &jump_ops, },
370 	{ .name = "jng",   .ops  = &jump_ops, },
371 	{ .name = "jnge",  .ops  = &jump_ops, },
372 	{ .name = "jnl",   .ops  = &jump_ops, },
373 	{ .name = "jnle",  .ops  = &jump_ops, },
374 	{ .name = "jno",   .ops  = &jump_ops, },
375 	{ .name = "jnp",   .ops  = &jump_ops, },
376 	{ .name = "jns",   .ops  = &jump_ops, },
377 	{ .name = "jnz",   .ops  = &jump_ops, },
378 	{ .name = "jo",	   .ops  = &jump_ops, },
379 	{ .name = "jp",	   .ops  = &jump_ops, },
380 	{ .name = "jpe",   .ops  = &jump_ops, },
381 	{ .name = "jpo",   .ops  = &jump_ops, },
382 	{ .name = "jrcxz", .ops  = &jump_ops, },
383 	{ .name = "js",	   .ops  = &jump_ops, },
384 	{ .name = "jz",	   .ops  = &jump_ops, },
385 	{ .name = "lea",   .ops  = &mov_ops, },
386 	{ .name = "lock",  .ops  = &lock_ops, },
387 	{ .name = "mov",   .ops  = &mov_ops, },
388 	{ .name = "movb",  .ops  = &mov_ops, },
389 	{ .name = "movdqa",.ops  = &mov_ops, },
390 	{ .name = "movl",  .ops  = &mov_ops, },
391 	{ .name = "movq",  .ops  = &mov_ops, },
392 	{ .name = "movslq", .ops  = &mov_ops, },
393 	{ .name = "movzbl", .ops  = &mov_ops, },
394 	{ .name = "movzwl", .ops  = &mov_ops, },
395 	{ .name = "nop",   .ops  = &nop_ops, },
396 	{ .name = "nopl",  .ops  = &nop_ops, },
397 	{ .name = "nopw",  .ops  = &nop_ops, },
398 	{ .name = "or",    .ops  = &mov_ops, },
399 	{ .name = "orl",   .ops  = &mov_ops, },
400 	{ .name = "test",  .ops  = &mov_ops, },
401 	{ .name = "testb", .ops  = &mov_ops, },
402 	{ .name = "testl", .ops  = &mov_ops, },
403 	{ .name = "xadd",  .ops  = &mov_ops, },
404 	{ .name = "xbeginl", .ops  = &jump_ops, },
405 	{ .name = "xbeginq", .ops  = &jump_ops, },
406 };
407 
408 static int ins__cmp(const void *name, const void *insp)
409 {
410 	const struct ins *ins = insp;
411 
412 	return strcmp(name, ins->name);
413 }
414 
415 static struct ins *ins__find(const char *name)
416 {
417 	const int nmemb = ARRAY_SIZE(instructions);
418 
419 	return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__cmp);
420 }
421 
422 int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym)
423 {
424 	struct annotation *notes = symbol__annotation(sym);
425 	pthread_mutex_init(&notes->lock, NULL);
426 	return 0;
427 }
428 
429 int symbol__alloc_hist(struct symbol *sym)
430 {
431 	struct annotation *notes = symbol__annotation(sym);
432 	const size_t size = symbol__size(sym);
433 	size_t sizeof_sym_hist;
434 
435 	/* Check for overflow when calculating sizeof_sym_hist */
436 	if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64))
437 		return -1;
438 
439 	sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));
440 
441 	/* Check for overflow in zalloc argument */
442 	if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src))
443 				/ symbol_conf.nr_events)
444 		return -1;
445 
446 	notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
447 	if (notes->src == NULL)
448 		return -1;
449 	notes->src->sizeof_sym_hist = sizeof_sym_hist;
450 	notes->src->nr_histograms   = symbol_conf.nr_events;
451 	INIT_LIST_HEAD(&notes->src->source);
452 	return 0;
453 }
454 
455 void symbol__annotate_zero_histograms(struct symbol *sym)
456 {
457 	struct annotation *notes = symbol__annotation(sym);
458 
459 	pthread_mutex_lock(&notes->lock);
460 	if (notes->src != NULL)
461 		memset(notes->src->histograms, 0,
462 		       notes->src->nr_histograms * notes->src->sizeof_sym_hist);
463 	pthread_mutex_unlock(&notes->lock);
464 }
465 
466 int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
467 			     int evidx, u64 addr)
468 {
469 	unsigned offset;
470 	struct annotation *notes;
471 	struct sym_hist *h;
472 
473 	notes = symbol__annotation(sym);
474 	if (notes->src == NULL)
475 		return -ENOMEM;
476 
477 	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
478 
479 	if (addr < sym->start || addr > sym->end)
480 		return -ERANGE;
481 
482 	offset = addr - sym->start;
483 	h = annotation__histogram(notes, evidx);
484 	h->sum++;
485 	h->addr[offset]++;
486 
487 	pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64
488 		  ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name,
489 		  addr, addr - sym->start, evidx, h->addr[offset]);
490 	return 0;
491 }
492 
493 static void disasm_line__init_ins(struct disasm_line *dl)
494 {
495 	dl->ins = ins__find(dl->name);
496 
497 	if (dl->ins == NULL)
498 		return;
499 
500 	if (!dl->ins->ops)
501 		return;
502 
503 	if (dl->ins->ops->parse)
504 		dl->ins->ops->parse(&dl->ops);
505 }
506 
507 static int disasm_line__parse(char *line, char **namep, char **rawp)
508 {
509 	char *name = line, tmp;
510 
511 	while (isspace(name[0]))
512 		++name;
513 
514 	if (name[0] == '\0')
515 		return -1;
516 
517 	*rawp = name + 1;
518 
519 	while ((*rawp)[0] != '\0' && !isspace((*rawp)[0]))
520 		++*rawp;
521 
522 	tmp = (*rawp)[0];
523 	(*rawp)[0] = '\0';
524 	*namep = strdup(name);
525 
526 	if (*namep == NULL)
527 		goto out_free_name;
528 
529 	(*rawp)[0] = tmp;
530 
531 	if ((*rawp)[0] != '\0') {
532 		(*rawp)++;
533 		while (isspace((*rawp)[0]))
534 			++(*rawp);
535 	}
536 
537 	return 0;
538 
539 out_free_name:
540 	free(*namep);
541 	*namep = NULL;
542 	return -1;
543 }
544 
545 static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize)
546 {
547 	struct disasm_line *dl = zalloc(sizeof(*dl) + privsize);
548 
549 	if (dl != NULL) {
550 		dl->offset = offset;
551 		dl->line = strdup(line);
552 		if (dl->line == NULL)
553 			goto out_delete;
554 
555 		if (offset != -1) {
556 			if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0)
557 				goto out_free_line;
558 
559 			disasm_line__init_ins(dl);
560 		}
561 	}
562 
563 	return dl;
564 
565 out_free_line:
566 	free(dl->line);
567 out_delete:
568 	free(dl);
569 	return NULL;
570 }
571 
572 void disasm_line__free(struct disasm_line *dl)
573 {
574 	free(dl->line);
575 	free(dl->name);
576 	if (dl->ins && dl->ins->ops->free)
577 		dl->ins->ops->free(&dl->ops);
578 	else
579 		ins__delete(&dl->ops);
580 	free(dl);
581 }
582 
583 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
584 {
585 	if (raw || !dl->ins)
586 		return scnprintf(bf, size, "%-6.6s %s", dl->name, dl->ops.raw);
587 
588 	return ins__scnprintf(dl->ins, bf, size, &dl->ops);
589 }
590 
591 static void disasm__add(struct list_head *head, struct disasm_line *line)
592 {
593 	list_add_tail(&line->node, head);
594 }
595 
596 struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos)
597 {
598 	list_for_each_entry_continue(pos, head, node)
599 		if (pos->offset >= 0)
600 			return pos;
601 
602 	return NULL;
603 }
604 
605 static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 start,
606 		      int evidx, u64 len, int min_pcnt, int printed,
607 		      int max_lines, struct disasm_line *queue)
608 {
609 	static const char *prev_line;
610 	static const char *prev_color;
611 
612 	if (dl->offset != -1) {
613 		const char *path = NULL;
614 		unsigned int hits = 0;
615 		double percent = 0.0;
616 		const char *color;
617 		struct annotation *notes = symbol__annotation(sym);
618 		struct source_line *src_line = notes->src->lines;
619 		struct sym_hist *h = annotation__histogram(notes, evidx);
620 		s64 offset = dl->offset;
621 		const u64 addr = start + offset;
622 		struct disasm_line *next;
623 
624 		next = disasm__get_next_ip_line(&notes->src->source, dl);
625 
626 		while (offset < (s64)len &&
627 		       (next == NULL || offset < next->offset)) {
628 			if (src_line) {
629 				if (path == NULL)
630 					path = src_line[offset].path;
631 				percent += src_line[offset].percent;
632 			} else
633 				hits += h->addr[offset];
634 
635 			++offset;
636 		}
637 
638 		if (src_line == NULL && h->sum)
639 			percent = 100.0 * hits / h->sum;
640 
641 		if (percent < min_pcnt)
642 			return -1;
643 
644 		if (max_lines && printed >= max_lines)
645 			return 1;
646 
647 		if (queue != NULL) {
648 			list_for_each_entry_from(queue, &notes->src->source, node) {
649 				if (queue == dl)
650 					break;
651 				disasm_line__print(queue, sym, start, evidx, len,
652 						    0, 0, 1, NULL);
653 			}
654 		}
655 
656 		color = get_percent_color(percent);
657 
658 		/*
659 		 * Also color the filename and line if needed, with
660 		 * the same color than the percentage. Don't print it
661 		 * twice for close colored addr with the same filename:line
662 		 */
663 		if (path) {
664 			if (!prev_line || strcmp(prev_line, path)
665 				       || color != prev_color) {
666 				color_fprintf(stdout, color, " %s", path);
667 				prev_line = path;
668 				prev_color = color;
669 			}
670 		}
671 
672 		color_fprintf(stdout, color, " %7.2f", percent);
673 		printf(" :	");
674 		color_fprintf(stdout, PERF_COLOR_MAGENTA, "  %" PRIx64 ":", addr);
675 		color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", dl->line);
676 	} else if (max_lines && printed >= max_lines)
677 		return 1;
678 	else {
679 		if (queue)
680 			return -1;
681 
682 		if (!*dl->line)
683 			printf("         :\n");
684 		else
685 			printf("         :	%s\n", dl->line);
686 	}
687 
688 	return 0;
689 }
690 
691 static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
692 				      FILE *file, size_t privsize)
693 {
694 	struct annotation *notes = symbol__annotation(sym);
695 	struct disasm_line *dl;
696 	char *line = NULL, *parsed_line, *tmp, *tmp2, *c;
697 	size_t line_len;
698 	s64 line_ip, offset = -1;
699 
700 	if (getline(&line, &line_len, file) < 0)
701 		return -1;
702 
703 	if (!line)
704 		return -1;
705 
706 	while (line_len != 0 && isspace(line[line_len - 1]))
707 		line[--line_len] = '\0';
708 
709 	c = strchr(line, '\n');
710 	if (c)
711 		*c = 0;
712 
713 	line_ip = -1;
714 	parsed_line = line;
715 
716 	/*
717 	 * Strip leading spaces:
718 	 */
719 	tmp = line;
720 	while (*tmp) {
721 		if (*tmp != ' ')
722 			break;
723 		tmp++;
724 	}
725 
726 	if (*tmp) {
727 		/*
728 		 * Parse hexa addresses followed by ':'
729 		 */
730 		line_ip = strtoull(tmp, &tmp2, 16);
731 		if (*tmp2 != ':' || tmp == tmp2 || tmp2[1] == '\0')
732 			line_ip = -1;
733 	}
734 
735 	if (line_ip != -1) {
736 		u64 start = map__rip_2objdump(map, sym->start),
737 		    end = map__rip_2objdump(map, sym->end);
738 
739 		offset = line_ip - start;
740 		if (offset < 0 || (u64)line_ip > end)
741 			offset = -1;
742 		else
743 			parsed_line = tmp2 + 1;
744 	}
745 
746 	dl = disasm_line__new(offset, parsed_line, privsize);
747 	free(line);
748 
749 	if (dl == NULL)
750 		return -1;
751 
752 	disasm__add(&notes->src->source, dl);
753 
754 	return 0;
755 }
756 
757 int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
758 {
759 	struct dso *dso = map->dso;
760 	char *filename = dso__build_id_filename(dso, NULL, 0);
761 	bool free_filename = true;
762 	char command[PATH_MAX * 2];
763 	FILE *file;
764 	int err = 0;
765 	char symfs_filename[PATH_MAX];
766 
767 	if (filename) {
768 		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
769 			 symbol_conf.symfs, filename);
770 	}
771 
772 	if (filename == NULL) {
773 		if (dso->has_build_id) {
774 			pr_err("Can't annotate %s: not enough memory\n",
775 			       sym->name);
776 			return -ENOMEM;
777 		}
778 		goto fallback;
779 	} else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
780 		   strstr(command, "[kernel.kallsyms]") ||
781 		   access(symfs_filename, R_OK)) {
782 		free(filename);
783 fallback:
784 		/*
785 		 * If we don't have build-ids or the build-id file isn't in the
786 		 * cache, or is just a kallsyms file, well, lets hope that this
787 		 * DSO is the same as when 'perf record' ran.
788 		 */
789 		filename = dso->long_name;
790 		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
791 			 symbol_conf.symfs, filename);
792 		free_filename = false;
793 	}
794 
795 	if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
796 		char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
797 		char *build_id_msg = NULL;
798 
799 		if (dso->annotate_warned)
800 			goto out_free_filename;
801 
802 		if (dso->has_build_id) {
803 			build_id__sprintf(dso->build_id,
804 					  sizeof(dso->build_id), bf + 15);
805 			build_id_msg = bf;
806 		}
807 		err = -ENOENT;
808 		dso->annotate_warned = 1;
809 		pr_err("Can't annotate %s:\n\n"
810 		       "No vmlinux file%s\nwas found in the path.\n\n"
811 		       "Please use:\n\n"
812 		       "  perf buildid-cache -av vmlinux\n\n"
813 		       "or:\n\n"
814 		       "  --vmlinux vmlinux\n",
815 		       sym->name, build_id_msg ?: "");
816 		goto out_free_filename;
817 	}
818 
819 	pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
820 		 filename, sym->name, map->unmap_ip(map, sym->start),
821 		 map->unmap_ip(map, sym->end));
822 
823 	pr_debug("annotating [%p] %30s : [%p] %30s\n",
824 		 dso, dso->long_name, sym, sym->name);
825 
826 	snprintf(command, sizeof(command),
827 		 "%s %s%s --start-address=0x%016" PRIx64
828 		 " --stop-address=0x%016" PRIx64
829 		 " -d %s %s -C %s|grep -v %s|expand",
830 		 objdump_path ? objdump_path : "objdump",
831 		 disassembler_style ? "-M " : "",
832 		 disassembler_style ? disassembler_style : "",
833 		 map__rip_2objdump(map, sym->start),
834 		 map__rip_2objdump(map, sym->end+1),
835 		 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
836 		 symbol_conf.annotate_src ? "-S" : "",
837 		 symfs_filename, filename);
838 
839 	pr_debug("Executing: %s\n", command);
840 
841 	file = popen(command, "r");
842 	if (!file)
843 		goto out_free_filename;
844 
845 	while (!feof(file))
846 		if (symbol__parse_objdump_line(sym, map, file, privsize) < 0)
847 			break;
848 
849 	pclose(file);
850 out_free_filename:
851 	if (free_filename)
852 		free(filename);
853 	return err;
854 }
855 
856 static void insert_source_line(struct rb_root *root, struct source_line *src_line)
857 {
858 	struct source_line *iter;
859 	struct rb_node **p = &root->rb_node;
860 	struct rb_node *parent = NULL;
861 	int ret;
862 
863 	while (*p != NULL) {
864 		parent = *p;
865 		iter = rb_entry(parent, struct source_line, node);
866 
867 		ret = strcmp(iter->path, src_line->path);
868 		if (ret == 0) {
869 			iter->percent_sum += src_line->percent;
870 			return;
871 		}
872 
873 		if (ret < 0)
874 			p = &(*p)->rb_left;
875 		else
876 			p = &(*p)->rb_right;
877 	}
878 
879 	src_line->percent_sum = src_line->percent;
880 
881 	rb_link_node(&src_line->node, parent, p);
882 	rb_insert_color(&src_line->node, root);
883 }
884 
885 static void __resort_source_line(struct rb_root *root, struct source_line *src_line)
886 {
887 	struct source_line *iter;
888 	struct rb_node **p = &root->rb_node;
889 	struct rb_node *parent = NULL;
890 
891 	while (*p != NULL) {
892 		parent = *p;
893 		iter = rb_entry(parent, struct source_line, node);
894 
895 		if (src_line->percent_sum > iter->percent_sum)
896 			p = &(*p)->rb_left;
897 		else
898 			p = &(*p)->rb_right;
899 	}
900 
901 	rb_link_node(&src_line->node, parent, p);
902 	rb_insert_color(&src_line->node, root);
903 }
904 
905 static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
906 {
907 	struct source_line *src_line;
908 	struct rb_node *node;
909 
910 	node = rb_first(src_root);
911 	while (node) {
912 		struct rb_node *next;
913 
914 		src_line = rb_entry(node, struct source_line, node);
915 		next = rb_next(node);
916 		rb_erase(node, src_root);
917 
918 		__resort_source_line(dest_root, src_line);
919 		node = next;
920 	}
921 }
922 
923 static void symbol__free_source_line(struct symbol *sym, int len)
924 {
925 	struct annotation *notes = symbol__annotation(sym);
926 	struct source_line *src_line = notes->src->lines;
927 	int i;
928 
929 	for (i = 0; i < len; i++)
930 		free(src_line[i].path);
931 
932 	free(src_line);
933 	notes->src->lines = NULL;
934 }
935 
936 /* Get the filename:line for the colored entries */
937 static int symbol__get_source_line(struct symbol *sym, struct map *map,
938 				   int evidx, struct rb_root *root, int len,
939 				   const char *filename)
940 {
941 	u64 start;
942 	int i;
943 	char cmd[PATH_MAX * 2];
944 	struct source_line *src_line;
945 	struct annotation *notes = symbol__annotation(sym);
946 	struct sym_hist *h = annotation__histogram(notes, evidx);
947 	struct rb_root tmp_root = RB_ROOT;
948 
949 	if (!h->sum)
950 		return 0;
951 
952 	src_line = notes->src->lines = calloc(len, sizeof(struct source_line));
953 	if (!notes->src->lines)
954 		return -1;
955 
956 	start = map__rip_2objdump(map, sym->start);
957 
958 	for (i = 0; i < len; i++) {
959 		char *path = NULL;
960 		size_t line_len;
961 		u64 offset;
962 		FILE *fp;
963 
964 		src_line[i].percent = 100.0 * h->addr[i] / h->sum;
965 		if (src_line[i].percent <= 0.5)
966 			continue;
967 
968 		offset = start + i;
969 		sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
970 		fp = popen(cmd, "r");
971 		if (!fp)
972 			continue;
973 
974 		if (getline(&path, &line_len, fp) < 0 || !line_len)
975 			goto next;
976 
977 		src_line[i].path = malloc(sizeof(char) * line_len + 1);
978 		if (!src_line[i].path)
979 			goto next;
980 
981 		strcpy(src_line[i].path, path);
982 		insert_source_line(&tmp_root, &src_line[i]);
983 
984 	next:
985 		pclose(fp);
986 	}
987 
988 	resort_source_line(root, &tmp_root);
989 	return 0;
990 }
991 
992 static void print_summary(struct rb_root *root, const char *filename)
993 {
994 	struct source_line *src_line;
995 	struct rb_node *node;
996 
997 	printf("\nSorted summary for file %s\n", filename);
998 	printf("----------------------------------------------\n\n");
999 
1000 	if (RB_EMPTY_ROOT(root)) {
1001 		printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
1002 		return;
1003 	}
1004 
1005 	node = rb_first(root);
1006 	while (node) {
1007 		double percent;
1008 		const char *color;
1009 		char *path;
1010 
1011 		src_line = rb_entry(node, struct source_line, node);
1012 		percent = src_line->percent_sum;
1013 		color = get_percent_color(percent);
1014 		path = src_line->path;
1015 
1016 		color_fprintf(stdout, color, " %7.2f %s", percent, path);
1017 		node = rb_next(node);
1018 	}
1019 }
1020 
1021 static void symbol__annotate_hits(struct symbol *sym, int evidx)
1022 {
1023 	struct annotation *notes = symbol__annotation(sym);
1024 	struct sym_hist *h = annotation__histogram(notes, evidx);
1025 	u64 len = symbol__size(sym), offset;
1026 
1027 	for (offset = 0; offset < len; ++offset)
1028 		if (h->addr[offset] != 0)
1029 			printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
1030 			       sym->start + offset, h->addr[offset]);
1031 	printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
1032 }
1033 
1034 int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
1035 			    bool full_paths, int min_pcnt, int max_lines,
1036 			    int context)
1037 {
1038 	struct dso *dso = map->dso;
1039 	char *filename;
1040 	const char *d_filename;
1041 	struct annotation *notes = symbol__annotation(sym);
1042 	struct disasm_line *pos, *queue = NULL;
1043 	u64 start = map__rip_2objdump(map, sym->start);
1044 	int printed = 2, queue_len = 0;
1045 	int more = 0;
1046 	u64 len;
1047 
1048 	filename = strdup(dso->long_name);
1049 	if (!filename)
1050 		return -ENOMEM;
1051 
1052 	if (full_paths)
1053 		d_filename = filename;
1054 	else
1055 		d_filename = basename(filename);
1056 
1057 	len = symbol__size(sym);
1058 
1059 	printf(" Percent |	Source code & Disassembly of %s\n", d_filename);
1060 	printf("------------------------------------------------\n");
1061 
1062 	if (verbose)
1063 		symbol__annotate_hits(sym, evidx);
1064 
1065 	list_for_each_entry(pos, &notes->src->source, node) {
1066 		if (context && queue == NULL) {
1067 			queue = pos;
1068 			queue_len = 0;
1069 		}
1070 
1071 		switch (disasm_line__print(pos, sym, start, evidx, len,
1072 					    min_pcnt, printed, max_lines,
1073 					    queue)) {
1074 		case 0:
1075 			++printed;
1076 			if (context) {
1077 				printed += queue_len;
1078 				queue = NULL;
1079 				queue_len = 0;
1080 			}
1081 			break;
1082 		case 1:
1083 			/* filtered by max_lines */
1084 			++more;
1085 			break;
1086 		case -1:
1087 		default:
1088 			/*
1089 			 * Filtered by min_pcnt or non IP lines when
1090 			 * context != 0
1091 			 */
1092 			if (!context)
1093 				break;
1094 			if (queue_len == context)
1095 				queue = list_entry(queue->node.next, typeof(*queue), node);
1096 			else
1097 				++queue_len;
1098 			break;
1099 		}
1100 	}
1101 
1102 	free(filename);
1103 
1104 	return more;
1105 }
1106 
1107 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
1108 {
1109 	struct annotation *notes = symbol__annotation(sym);
1110 	struct sym_hist *h = annotation__histogram(notes, evidx);
1111 
1112 	memset(h, 0, notes->src->sizeof_sym_hist);
1113 }
1114 
1115 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
1116 {
1117 	struct annotation *notes = symbol__annotation(sym);
1118 	struct sym_hist *h = annotation__histogram(notes, evidx);
1119 	int len = symbol__size(sym), offset;
1120 
1121 	h->sum = 0;
1122 	for (offset = 0; offset < len; ++offset) {
1123 		h->addr[offset] = h->addr[offset] * 7 / 8;
1124 		h->sum += h->addr[offset];
1125 	}
1126 }
1127 
1128 void disasm__purge(struct list_head *head)
1129 {
1130 	struct disasm_line *pos, *n;
1131 
1132 	list_for_each_entry_safe(pos, n, head, node) {
1133 		list_del(&pos->node);
1134 		disasm_line__free(pos);
1135 	}
1136 }
1137 
1138 static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
1139 {
1140 	size_t printed;
1141 
1142 	if (dl->offset == -1)
1143 		return fprintf(fp, "%s\n", dl->line);
1144 
1145 	printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->name);
1146 
1147 	if (dl->ops.raw[0] != '\0') {
1148 		printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",
1149 				   dl->ops.raw);
1150 	}
1151 
1152 	return printed + fprintf(fp, "\n");
1153 }
1154 
1155 size_t disasm__fprintf(struct list_head *head, FILE *fp)
1156 {
1157 	struct disasm_line *pos;
1158 	size_t printed = 0;
1159 
1160 	list_for_each_entry(pos, head, node)
1161 		printed += disasm_line__fprintf(pos, fp);
1162 
1163 	return printed;
1164 }
1165 
1166 int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
1167 			 bool print_lines, bool full_paths, int min_pcnt,
1168 			 int max_lines)
1169 {
1170 	struct dso *dso = map->dso;
1171 	const char *filename = dso->long_name;
1172 	struct rb_root source_line = RB_ROOT;
1173 	u64 len;
1174 
1175 	if (symbol__annotate(sym, map, 0) < 0)
1176 		return -1;
1177 
1178 	len = symbol__size(sym);
1179 
1180 	if (print_lines) {
1181 		symbol__get_source_line(sym, map, evidx, &source_line,
1182 					len, filename);
1183 		print_summary(&source_line, filename);
1184 	}
1185 
1186 	symbol__annotate_printf(sym, map, evidx, full_paths,
1187 				min_pcnt, max_lines, 0);
1188 	if (print_lines)
1189 		symbol__free_source_line(sym, len);
1190 
1191 	disasm__purge(&symbol__annotation(sym)->src->source);
1192 
1193 	return 0;
1194 }
1195