]> git.ipfire.org Git - thirdparty/linux.git/blame - tools/perf/util/annotate.c
perf annotate: Finish the generalization of annotate_browser__write()
[thirdparty/linux.git] / tools / perf / util / annotate.c
CommitLineData
78f7defe
ACM
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
a43783ae 10#include <errno.h>
fd20e811 11#include <inttypes.h>
78f7defe 12#include "util.h"
48c65bda
NK
13#include "ui/ui.h"
14#include "sort.h"
78f7defe
ACM
15#include "build-id.h"
16#include "color.h"
17#include "cache.h"
18#include "symbol.h"
19#include "debug.h"
20#include "annotate.h"
db8fd07a 21#include "evsel.h"
70fbe057 22#include "block-range.h"
a067558e 23#include "string2.h"
786c1b51 24#include "arch/common.h"
e592488c 25#include <regex.h>
ce6f4fab 26#include <pthread.h>
4383db88 27#include <linux/bitops.h>
877a7a11 28#include <linux/kernel.h>
78f7defe 29
a1e9b74c
ACM
30/* FIXME: For the HE_COLORSET */
31#include "ui/browser.h"
32
33/*
34 * FIXME: Using the same values as slang.h,
35 * but that header may not be available everywhere
36 */
37#define LARROW_CHAR 0x1B
38#define RARROW_CHAR 0x1A
39#define DARROW_CHAR 0x19
40#define UARROW_CHAR 0x18
41
3d689ed6
ACM
42#include "sane_ctype.h"
43
f69b64f7 44const char *disassembler_style;
7a4ec938 45const char *objdump_path;
e592488c 46static regex_t file_lineno;
f69b64f7 47
75b49202 48static struct ins_ops *ins__find(struct arch *arch, const char *name);
2a1ff812 49static void ins__sort(struct arch *arch);
75b49202 50static int disasm_line__parse(char *line, const char **namep, char **rawp);
7a997fe4 51
786c1b51
ACM
52struct arch {
53 const char *name;
763d8960
ACM
54 struct ins *instructions;
55 size_t nr_instructions;
2a1ff812
ACM
56 size_t nr_instructions_allocated;
57 struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name);
763d8960 58 bool sorted_instructions;
0781ea92
ACM
59 bool initialized;
60 void *priv;
69fb09f6
JY
61 unsigned int model;
62 unsigned int family;
696e2457 63 int (*init)(struct arch *arch, char *cpuid);
69fb09f6
JY
64 bool (*ins_is_fused)(struct arch *arch, const char *ins1,
65 const char *ins2);
786c1b51
ACM
66 struct {
67 char comment_char;
9c2fb451 68 char skip_functions_char;
786c1b51
ACM
69 } objdump;
70};
71
763d8960
ACM
72static struct ins_ops call_ops;
73static struct ins_ops dec_ops;
74static struct ins_ops jump_ops;
75static struct ins_ops mov_ops;
76static struct ins_ops nop_ops;
77static struct ins_ops lock_ops;
78static struct ins_ops ret_ops;
79
2a1ff812
ACM
80static int arch__grow_instructions(struct arch *arch)
81{
82 struct ins *new_instructions;
83 size_t new_nr_allocated;
84
85 if (arch->nr_instructions_allocated == 0 && arch->instructions)
86 goto grow_from_non_allocated_table;
87
88 new_nr_allocated = arch->nr_instructions_allocated + 128;
89 new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins));
90 if (new_instructions == NULL)
91 return -1;
92
93out_update_instructions:
94 arch->instructions = new_instructions;
95 arch->nr_instructions_allocated = new_nr_allocated;
96 return 0;
97
98grow_from_non_allocated_table:
99 new_nr_allocated = arch->nr_instructions + 128;
100 new_instructions = calloc(new_nr_allocated, sizeof(struct ins));
101 if (new_instructions == NULL)
102 return -1;
103
104 memcpy(new_instructions, arch->instructions, arch->nr_instructions);
105 goto out_update_instructions;
106}
107
acc9bfb5 108static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops)
2a1ff812
ACM
109{
110 struct ins *ins;
111
112 if (arch->nr_instructions == arch->nr_instructions_allocated &&
113 arch__grow_instructions(arch))
114 return -1;
115
116 ins = &arch->instructions[arch->nr_instructions];
117 ins->name = strdup(name);
118 if (!ins->name)
119 return -1;
120
121 ins->ops = ops;
122 arch->nr_instructions++;
123
124 ins__sort(arch);
125 return 0;
126}
127
763d8960 128#include "arch/arm/annotate/instructions.c"
0fcb1da4 129#include "arch/arm64/annotate/instructions.c"
763d8960 130#include "arch/x86/annotate/instructions.c"
dbdebdc5 131#include "arch/powerpc/annotate/instructions.c"
d9f8dfa9 132#include "arch/s390/annotate/instructions.c"
763d8960 133
786c1b51
ACM
134static struct arch architectures[] = {
135 {
136 .name = "arm",
acc9bfb5 137 .init = arm__annotate_init,
786c1b51 138 },
0fcb1da4
KP
139 {
140 .name = "arm64",
141 .init = arm64__annotate_init,
142 },
786c1b51
ACM
143 {
144 .name = "x86",
696e2457 145 .init = x86__annotate_init,
763d8960
ACM
146 .instructions = x86__instructions,
147 .nr_instructions = ARRAY_SIZE(x86__instructions),
69fb09f6 148 .ins_is_fused = x86__ins_is_fused,
786c1b51
ACM
149 .objdump = {
150 .comment_char = '#',
151 },
152 },
dbdebdc5
RB
153 {
154 .name = "powerpc",
155 .init = powerpc__annotate_init,
156 },
e77852b3
CB
157 {
158 .name = "s390",
d9f8dfa9 159 .init = s390__annotate_init,
e77852b3
CB
160 .objdump = {
161 .comment_char = '#',
162 },
163 },
786c1b51
ACM
164};
165
c46219ac
ACM
166static void ins__delete(struct ins_operands *ops)
167{
3995614d
ACM
168 if (ops == NULL)
169 return;
74cf249d
ACM
170 zfree(&ops->source.raw);
171 zfree(&ops->source.name);
172 zfree(&ops->target.raw);
173 zfree(&ops->target.name);
c46219ac
ACM
174}
175
5417072b
ACM
176static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
177 struct ins_operands *ops)
178{
648388ae 179 return scnprintf(bf, size, "%-6s %s", ins->name, ops->raw);
5417072b
ACM
180}
181
182int ins__scnprintf(struct ins *ins, char *bf, size_t size,
183 struct ins_operands *ops)
184{
185 if (ins->ops->scnprintf)
186 return ins->ops->scnprintf(ins, bf, size, ops);
187
188 return ins__raw_scnprintf(ins, bf, size, ops);
189}
190
69fb09f6
JY
191bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2)
192{
193 if (!arch || !arch->ins_is_fused)
194 return false;
195
196 return arch->ins_is_fused(arch, ins1, ins2);
197}
198
9c2fb451 199static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map)
d86b0597 200{
d2232885 201 char *endptr, *tok, *name;
696703af
ACM
202 struct addr_map_symbol target = {
203 .map = map,
204 };
d2232885 205
44d1a3ed 206 ops->target.addr = strtoull(ops->raw, &endptr, 16);
d2232885
ACM
207
208 name = strchr(endptr, '<');
209 if (name == NULL)
210 goto indirect_call;
211
212 name++;
213
9c2fb451
ACM
214 if (arch->objdump.skip_functions_char &&
215 strchr(name, arch->objdump.skip_functions_char))
cfef25b8 216 return -1;
cfef25b8 217
d2232885
ACM
218 tok = strchr(name, '>');
219 if (tok == NULL)
220 return -1;
221
222 *tok = '\0';
44d1a3ed 223 ops->target.name = strdup(name);
d2232885
ACM
224 *tok = '>';
225
696703af
ACM
226 if (ops->target.name == NULL)
227 return -1;
228find_target:
229 target.addr = map__objdump_2mem(map, ops->target.addr);
d2232885 230
696703af
ACM
231 if (map_groups__find_ams(&target) == 0 &&
232 map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
233 ops->target.sym = target.sym;
e8ea1561 234
d86b0597 235 return 0;
696703af
ACM
236
237indirect_call:
238 tok = strchr(endptr, '*');
239 if (tok != NULL)
240 ops->target.addr = strtoull(tok + 1, NULL, 16);
241 goto find_target;
d86b0597
ACM
242}
243
d2232885 244static int call__scnprintf(struct ins *ins, char *bf, size_t size,
5417072b 245 struct ins_operands *ops)
d2232885 246{
696703af
ACM
247 if (ops->target.sym)
248 return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name);
d2232885 249
e8ea1561
ACM
250 if (ops->target.addr == 0)
251 return ins__raw_scnprintf(ins, bf, size, ops);
252
4c9cb2c2
ACM
253 if (ops->target.name)
254 return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.name);
255
648388ae 256 return scnprintf(bf, size, "%-6s *%" PRIx64, ins->name, ops->target.addr);
d2232885
ACM
257}
258
d86b0597 259static struct ins_ops call_ops = {
d2232885
ACM
260 .parse = call__parse,
261 .scnprintf = call__scnprintf,
d86b0597
ACM
262};
263
264bool ins__is_call(const struct ins *ins)
265{
0b58a77c 266 return ins->ops == &call_ops || ins->ops == &s390_call_ops;
d86b0597
ACM
267}
268
786c1b51 269static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
4f9d0325 270{
c7e6ead7 271 const char *s = strchr(ops->raw, '+');
3ee2eb6d 272 const char *c = strchr(ops->raw, ',');
4f9d0325 273
b13bbeee
KP
274 /*
275 * skip over possible up to 2 operands to get to address, e.g.:
276 * tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
277 */
278 if (c++ != NULL) {
3ee2eb6d 279 ops->target.addr = strtoull(c, NULL, 16);
b13bbeee
KP
280 if (!ops->target.addr) {
281 c = strchr(c, ',');
282 if (c++ != NULL)
283 ops->target.addr = strtoull(c, NULL, 16);
284 }
285 } else {
3ee2eb6d 286 ops->target.addr = strtoull(ops->raw, NULL, 16);
b13bbeee 287 }
fb29fa58 288
e216874c 289 if (s++ != NULL) {
bbb7f846 290 ops->target.offset = strtoull(s, NULL, 16);
e216874c
RB
291 ops->target.offset_avail = true;
292 } else {
293 ops->target.offset_avail = false;
294 }
4f9d0325 295
4f9d0325
ACM
296 return 0;
297}
298
c7e6ead7 299static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
5417072b 300 struct ins_operands *ops)
28548d78 301{
b13bbeee
KP
302 const char *c = strchr(ops->raw, ',');
303
e216874c 304 if (!ops->target.addr || ops->target.offset < 0)
bec60e50
RB
305 return ins__raw_scnprintf(ins, bf, size, ops);
306
b13bbeee
KP
307 if (c != NULL) {
308 const char *c2 = strchr(c + 1, ',');
309
310 /* check for 3-op insn */
311 if (c2 != NULL)
312 c = c2;
313 c++;
314
315 /* mirror arch objdump's space-after-comma style */
316 if (*c == ' ')
317 c++;
318 }
319
648388ae 320 return scnprintf(bf, size, "%-6s %.*s%" PRIx64,
b13bbeee
KP
321 ins->name, c ? c - ops->raw : 0, ops->raw,
322 ops->target.offset);
28548d78
ACM
323}
324
4f9d0325 325static struct ins_ops jump_ops = {
c7e6ead7
ACM
326 .parse = jump__parse,
327 .scnprintf = jump__scnprintf,
4f9d0325
ACM
328};
329
330bool ins__is_jump(const struct ins *ins)
331{
332 return ins->ops == &jump_ops;
333}
334
6de783b6
ACM
335static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
336{
337 char *endptr, *name, *t;
338
339 if (strstr(raw, "(%rip)") == NULL)
340 return 0;
341
342 *addrp = strtoull(comment, &endptr, 16);
35a8a148
TR
343 if (endptr == comment)
344 return 0;
6de783b6
ACM
345 name = strchr(endptr, '<');
346 if (name == NULL)
347 return -1;
348
349 name++;
350
351 t = strchr(name, '>');
352 if (t == NULL)
353 return 0;
354
355 *t = '\0';
356 *namep = strdup(name);
357 *t = '>';
358
359 return 0;
360}
361
786c1b51 362static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map)
7a997fe4 363{
7a997fe4
ACM
364 ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
365 if (ops->locked.ops == NULL)
366 return 0;
367
75b49202 368 if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0)
7a997fe4
ACM
369 goto out_free_ops;
370
75b49202 371 ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name);
0fb9f2aa 372
75b49202 373 if (ops->locked.ins.ops == NULL)
2ba34aaa 374 goto out_free_ops;
7a997fe4 375
75b49202
ACM
376 if (ops->locked.ins.ops->parse &&
377 ops->locked.ins.ops->parse(arch, ops->locked.ops, map) < 0)
be81908c 378 goto out_free_ops;
7a997fe4
ACM
379
380 return 0;
381
382out_free_ops:
04662523 383 zfree(&ops->locked.ops);
7a997fe4
ACM
384 return 0;
385}
386
387static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
388 struct ins_operands *ops)
389{
390 int printed;
391
75b49202 392 if (ops->locked.ins.ops == NULL)
7a997fe4
ACM
393 return ins__raw_scnprintf(ins, bf, size, ops);
394
648388ae 395 printed = scnprintf(bf, size, "%-6s ", ins->name);
75b49202 396 return printed + ins__scnprintf(&ops->locked.ins, bf + printed,
7a997fe4
ACM
397 size - printed, ops->locked.ops);
398}
399
c46219ac
ACM
400static void lock__delete(struct ins_operands *ops)
401{
75b49202 402 struct ins *ins = &ops->locked.ins;
0fb9f2aa 403
75b49202 404 if (ins->ops && ins->ops->free)
0fb9f2aa
RV
405 ins->ops->free(ops->locked.ops);
406 else
407 ins__delete(ops->locked.ops);
408
74cf249d
ACM
409 zfree(&ops->locked.ops);
410 zfree(&ops->target.raw);
411 zfree(&ops->target.name);
c46219ac
ACM
412}
413
7a997fe4 414static struct ins_ops lock_ops = {
c46219ac 415 .free = lock__delete,
7a997fe4
ACM
416 .parse = lock__parse,
417 .scnprintf = lock__scnprintf,
418};
419
786c1b51 420static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map *map __maybe_unused)
6de783b6
ACM
421{
422 char *s = strchr(ops->raw, ','), *target, *comment, prev;
423
424 if (s == NULL)
425 return -1;
426
427 *s = '\0';
428 ops->source.raw = strdup(ops->raw);
429 *s = ',';
48000a1a 430
6de783b6
ACM
431 if (ops->source.raw == NULL)
432 return -1;
433
434 target = ++s;
786c1b51 435 comment = strchr(s, arch->objdump.comment_char);
1e2bb043
AC
436
437 if (comment != NULL)
438 s = comment - 1;
439 else
440 s = strchr(s, '\0') - 1;
6de783b6 441
1e2bb043
AC
442 while (s > target && isspace(s[0]))
443 --s;
444 s++;
6de783b6
ACM
445 prev = *s;
446 *s = '\0';
447
448 ops->target.raw = strdup(target);
449 *s = prev;
450
451 if (ops->target.raw == NULL)
452 goto out_free_source;
453
6de783b6
ACM
454 if (comment == NULL)
455 return 0;
456
4597cf06 457 comment = ltrim(comment);
35a8a148
TR
458 comment__symbol(ops->source.raw, comment + 1, &ops->source.addr, &ops->source.name);
459 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name);
6de783b6
ACM
460
461 return 0;
462
463out_free_source:
04662523 464 zfree(&ops->source.raw);
6de783b6
ACM
465 return -1;
466}
467
468static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
469 struct ins_operands *ops)
470{
648388ae 471 return scnprintf(bf, size, "%-6s %s,%s", ins->name,
6de783b6
ACM
472 ops->source.name ?: ops->source.raw,
473 ops->target.name ?: ops->target.raw);
474}
475
476static struct ins_ops mov_ops = {
477 .parse = mov__parse,
478 .scnprintf = mov__scnprintf,
479};
480
786c1b51 481static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
a43712c4
ACM
482{
483 char *target, *comment, *s, prev;
484
485 target = s = ops->raw;
486
487 while (s[0] != '\0' && !isspace(s[0]))
488 ++s;
489 prev = *s;
490 *s = '\0';
491
492 ops->target.raw = strdup(target);
493 *s = prev;
494
495 if (ops->target.raw == NULL)
496 return -1;
497
859afa6c 498 comment = strchr(s, arch->objdump.comment_char);
a43712c4
ACM
499 if (comment == NULL)
500 return 0;
501
4597cf06 502 comment = ltrim(comment);
35a8a148 503 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name);
a43712c4
ACM
504
505 return 0;
506}
507
508static int dec__scnprintf(struct ins *ins, char *bf, size_t size,
509 struct ins_operands *ops)
510{
648388ae 511 return scnprintf(bf, size, "%-6s %s", ins->name,
a43712c4
ACM
512 ops->target.name ?: ops->target.raw);
513}
514
515static struct ins_ops dec_ops = {
516 .parse = dec__parse,
517 .scnprintf = dec__scnprintf,
518};
519
1d037ca1
IT
520static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size,
521 struct ins_operands *ops __maybe_unused)
b9818e93 522{
648388ae 523 return scnprintf(bf, size, "%-6s", "nop");
b9818e93
ACM
524}
525
526static struct ins_ops nop_ops = {
527 .scnprintf = nop__scnprintf,
528};
529
6ef94929
NR
530static struct ins_ops ret_ops = {
531 .scnprintf = ins__raw_scnprintf,
532};
533
534bool ins__is_ret(const struct ins *ins)
535{
536 return ins->ops == &ret_ops;
537}
538
7e63a13a
JY
539bool ins__is_lock(const struct ins *ins)
540{
541 return ins->ops == &lock_ops;
542}
543
7e4c1498 544static int ins__key_cmp(const void *name, const void *insp)
4f9d0325
ACM
545{
546 const struct ins *ins = insp;
547
548 return strcmp(name, ins->name);
549}
550
7e4c1498
CR
551static int ins__cmp(const void *a, const void *b)
552{
553 const struct ins *ia = a;
554 const struct ins *ib = b;
555
556 return strcmp(ia->name, ib->name);
557}
558
763d8960 559static void ins__sort(struct arch *arch)
7e4c1498 560{
763d8960 561 const int nmemb = arch->nr_instructions;
7e4c1498 562
763d8960 563 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp);
7e4c1498
CR
564}
565
2a1ff812 566static struct ins_ops *__ins__find(struct arch *arch, const char *name)
4f9d0325 567{
75b49202 568 struct ins *ins;
763d8960 569 const int nmemb = arch->nr_instructions;
7e4c1498 570
763d8960
ACM
571 if (!arch->sorted_instructions) {
572 ins__sort(arch);
573 arch->sorted_instructions = true;
7e4c1498 574 }
4f9d0325 575
75b49202
ACM
576 ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp);
577 return ins ? ins->ops : NULL;
4f9d0325
ACM
578}
579
2a1ff812
ACM
580static struct ins_ops *ins__find(struct arch *arch, const char *name)
581{
582 struct ins_ops *ops = __ins__find(arch, name);
583
584 if (!ops && arch->associate_instruction_ops)
585 ops = arch->associate_instruction_ops(arch, name);
586
587 return ops;
588}
589
786c1b51
ACM
590static int arch__key_cmp(const void *name, const void *archp)
591{
592 const struct arch *arch = archp;
593
594 return strcmp(name, arch->name);
595}
596
597static int arch__cmp(const void *a, const void *b)
598{
599 const struct arch *aa = a;
600 const struct arch *ab = b;
601
602 return strcmp(aa->name, ab->name);
603}
604
605static void arch__sort(void)
606{
607 const int nmemb = ARRAY_SIZE(architectures);
608
609 qsort(architectures, nmemb, sizeof(struct arch), arch__cmp);
610}
611
612static struct arch *arch__find(const char *name)
613{
614 const int nmemb = ARRAY_SIZE(architectures);
615 static bool sorted;
616
617 if (!sorted) {
618 arch__sort();
619 sorted = true;
620 }
621
622 return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp);
623}
624
d04b35f8 625int symbol__alloc_hist(struct symbol *sym)
ce6f4fab
ACM
626{
627 struct annotation *notes = symbol__annotation(sym);
331c7cb3 628 size_t size = symbol__size(sym);
8696329b
CS
629 size_t sizeof_sym_hist;
630
331c7cb3
RB
631 /*
632 * Add buffer of one element for zero length symbol.
633 * When sample is taken from first instruction of
634 * zero length symbol, perf still resolves it and
635 * shows symbol name in perf report and allows to
636 * annotate it.
637 */
638 if (size == 0)
639 size = 1;
640
8696329b 641 /* Check for overflow when calculating sizeof_sym_hist */
896bccd3 642 if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry))
8696329b
CS
643 return -1;
644
896bccd3 645 sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry));
8696329b
CS
646
647 /* Check for overflow in zalloc argument */
648 if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src))
649 / symbol_conf.nr_events)
650 return -1;
ce6f4fab 651
d04b35f8 652 notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
ce6f4fab
ACM
653 if (notes->src == NULL)
654 return -1;
655 notes->src->sizeof_sym_hist = sizeof_sym_hist;
d04b35f8 656 notes->src->nr_histograms = symbol_conf.nr_events;
ce6f4fab
ACM
657 INIT_LIST_HEAD(&notes->src->source);
658 return 0;
78f7defe
ACM
659}
660
d4957633
AK
661/* The cycles histogram is lazily allocated. */
662static int symbol__alloc_hist_cycles(struct symbol *sym)
663{
664 struct annotation *notes = symbol__annotation(sym);
665 const size_t size = symbol__size(sym);
666
667 notes->src->cycles_hist = calloc(size, sizeof(struct cyc_hist));
668 if (notes->src->cycles_hist == NULL)
669 return -1;
670 return 0;
671}
672
36532461
ACM
673void symbol__annotate_zero_histograms(struct symbol *sym)
674{
675 struct annotation *notes = symbol__annotation(sym);
676
ce6f4fab 677 pthread_mutex_lock(&notes->lock);
d4957633 678 if (notes->src != NULL) {
ce6f4fab
ACM
679 memset(notes->src->histograms, 0,
680 notes->src->nr_histograms * notes->src->sizeof_sym_hist);
d4957633
AK
681 if (notes->src->cycles_hist)
682 memset(notes->src->cycles_hist, 0,
683 symbol__size(sym) * sizeof(struct cyc_hist));
684 }
ce6f4fab 685 pthread_mutex_unlock(&notes->lock);
36532461
ACM
686}
687
d4957633
AK
688static int __symbol__account_cycles(struct annotation *notes,
689 u64 start,
690 unsigned offset, unsigned cycles,
691 unsigned have_start)
692{
693 struct cyc_hist *ch;
694
695 ch = notes->src->cycles_hist;
696 /*
697 * For now we can only account one basic block per
698 * final jump. But multiple could be overlapping.
699 * Always account the longest one. So when
700 * a shorter one has been already seen throw it away.
701 *
702 * We separately always account the full cycles.
703 */
704 ch[offset].num_aggr++;
705 ch[offset].cycles_aggr += cycles;
706
707 if (!have_start && ch[offset].have_start)
708 return 0;
709 if (ch[offset].num) {
710 if (have_start && (!ch[offset].have_start ||
711 ch[offset].start > start)) {
712 ch[offset].have_start = 0;
713 ch[offset].cycles = 0;
714 ch[offset].num = 0;
715 if (ch[offset].reset < 0xffff)
716 ch[offset].reset++;
717 } else if (have_start &&
718 ch[offset].start < start)
719 return 0;
720 }
721 ch[offset].have_start = have_start;
722 ch[offset].start = start;
723 ch[offset].cycles += cycles;
724 ch[offset].num++;
725 return 0;
726}
727
b66d8c0c 728static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
bab89f6a 729 struct annotation *notes, int evidx, u64 addr,
461c17f0 730 struct perf_sample *sample)
78f7defe 731{
2f525d01 732 unsigned offset;
78f7defe
ACM
733 struct sym_hist *h;
734
78f7defe
ACM
735 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
736
edee44be
RB
737 if ((addr < sym->start || addr >= sym->end) &&
738 (addr != sym->end || sym->start != sym->end)) {
e3d006ce
ACM
739 pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n",
740 __func__, __LINE__, sym->name, sym->start, addr, sym->end);
31d68e7b 741 return -ERANGE;
e3d006ce 742 }
78f7defe 743
2f525d01
ACM
744 offset = addr - sym->start;
745 h = annotation__histogram(notes, evidx);
8158683d 746 h->nr_samples++;
896bccd3 747 h->addr[offset].nr_samples++;
461c17f0
TS
748 h->period += sample->period;
749 h->addr[offset].period += sample->period;
78f7defe
ACM
750
751 pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64
461c17f0
TS
752 ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n",
753 sym->start, sym->name, addr, addr - sym->start, evidx,
754 h->addr[offset].nr_samples, h->addr[offset].period);
78f7defe
ACM
755 return 0;
756}
757
d4957633 758static struct annotation *symbol__get_annotation(struct symbol *sym, bool cycles)
83be34a7
AK
759{
760 struct annotation *notes = symbol__annotation(sym);
761
762 if (notes->src == NULL) {
763 if (symbol__alloc_hist(sym) < 0)
764 return NULL;
765 }
d4957633
AK
766 if (!notes->src->cycles_hist && cycles) {
767 if (symbol__alloc_hist_cycles(sym) < 0)
768 return NULL;
769 }
83be34a7
AK
770 return notes;
771}
772
44e83039 773static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
bab89f6a
TS
774 int evidx, u64 addr,
775 struct perf_sample *sample)
b66d8c0c
ACM
776{
777 struct annotation *notes;
778
48c65bda 779 if (sym == NULL)
b66d8c0c 780 return 0;
d4957633 781 notes = symbol__get_annotation(sym, false);
83be34a7
AK
782 if (notes == NULL)
783 return -ENOMEM;
bab89f6a 784 return __symbol__inc_addr_samples(sym, map, notes, evidx, addr, sample);
b66d8c0c
ACM
785}
786
d4957633
AK
787static int symbol__account_cycles(u64 addr, u64 start,
788 struct symbol *sym, unsigned cycles)
789{
790 struct annotation *notes;
791 unsigned offset;
792
793 if (sym == NULL)
794 return 0;
795 notes = symbol__get_annotation(sym, true);
796 if (notes == NULL)
797 return -ENOMEM;
798 if (addr < sym->start || addr >= sym->end)
799 return -ERANGE;
800
801 if (start) {
802 if (start < sym->start || start >= sym->end)
803 return -ERANGE;
804 if (start >= addr)
805 start = 0;
806 }
807 offset = addr - sym->start;
808 return __symbol__account_cycles(notes,
809 start ? start - sym->start : 0,
810 offset, cycles,
811 !!start);
812}
813
814int addr_map_symbol__account_cycles(struct addr_map_symbol *ams,
815 struct addr_map_symbol *start,
816 unsigned cycles)
817{
3d7245b0 818 u64 saddr = 0;
d4957633
AK
819 int err;
820
821 if (!cycles)
822 return 0;
823
824 /*
825 * Only set start when IPC can be computed. We can only
826 * compute it when the basic block is completely in a single
827 * function.
828 * Special case the case when the jump is elsewhere, but
829 * it starts on the function start.
830 */
831 if (start &&
832 (start->sym == ams->sym ||
833 (ams->sym &&
834 start->addr == ams->sym->start + ams->map->start)))
835 saddr = start->al_addr;
836 if (saddr == 0)
3d7245b0 837 pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n",
d4957633
AK
838 ams->addr,
839 start ? start->addr : 0,
840 ams->sym ? ams->sym->start + ams->map->start : 0,
841 saddr);
842 err = symbol__account_cycles(ams->al_addr, saddr, ams->sym, cycles);
843 if (err)
844 pr_debug2("account_cycles failed %d\n", err);
845 return err;
846}
847
f56c083b
ACM
848static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end)
849{
850 unsigned n_insn = 0;
851 u64 offset;
852
853 for (offset = start; offset <= end; offset++) {
854 if (notes->offsets[offset])
855 n_insn++;
856 }
857 return n_insn;
858}
859
860static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch)
861{
862 unsigned n_insn;
863 u64 offset;
864
865 n_insn = annotation__count_insn(notes, start, end);
866 if (n_insn && ch->num && ch->cycles) {
867 float ipc = n_insn / ((double)ch->cycles / (double)ch->num);
868
869 /* Hide data when there are too many overlaps. */
870 if (ch->reset >= 0x7fff || ch->reset >= ch->num / 2)
871 return;
872
873 for (offset = start; offset <= end; offset++) {
874 struct annotation_line *al = notes->offsets[offset];
875
876 if (al)
877 al->ipc = ipc;
878 }
879 }
880}
881
882void annotation__compute_ipc(struct annotation *notes, size_t size)
883{
884 u64 offset;
885
886 if (!notes->src || !notes->src->cycles_hist)
887 return;
888
889 pthread_mutex_lock(&notes->lock);
890 for (offset = 0; offset < size; ++offset) {
891 struct cyc_hist *ch;
892
893 ch = &notes->src->cycles_hist[offset];
894 if (ch && ch->cycles) {
895 struct annotation_line *al;
896
897 if (ch->have_start)
898 annotation__count_and_fill(notes, ch->start, offset, ch);
899 al = notes->offsets[offset];
900 if (al && ch->num_aggr)
901 al->cycles = ch->cycles_aggr / ch->num_aggr;
902 notes->have_cycles = true;
903 }
904 }
905 pthread_mutex_unlock(&notes->lock);
906}
907
bab89f6a
TS
908int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample,
909 int evidx)
0f4e7a24 910{
bab89f6a 911 return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr, sample);
0f4e7a24
ACM
912}
913
bab89f6a
TS
914int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample,
915 int evidx, u64 ip)
f626adff 916{
bab89f6a 917 return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample);
f626adff
ACM
918}
919
786c1b51 920static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map)
4f9d0325 921{
75b49202 922 dl->ins.ops = ins__find(arch, dl->ins.name);
4f9d0325 923
75b49202 924 if (!dl->ins.ops)
4f9d0325
ACM
925 return;
926
75b49202
ACM
927 if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, map) < 0)
928 dl->ins.ops = NULL;
4f9d0325
ACM
929}
930
75b49202 931static int disasm_line__parse(char *line, const char **namep, char **rawp)
7a997fe4 932{
4597cf06 933 char tmp, *name = ltrim(line);
7a997fe4
ACM
934
935 if (name[0] == '\0')
936 return -1;
937
938 *rawp = name + 1;
939
940 while ((*rawp)[0] != '\0' && !isspace((*rawp)[0]))
941 ++*rawp;
942
943 tmp = (*rawp)[0];
944 (*rawp)[0] = '\0';
945 *namep = strdup(name);
946
947 if (*namep == NULL)
948 goto out_free_name;
949
950 (*rawp)[0] = tmp;
4597cf06 951 *rawp = ltrim(*rawp);
7a997fe4
ACM
952
953 return 0;
954
955out_free_name:
75b49202
ACM
956 free((void *)namep);
957 *namep = NULL;
7a997fe4
ACM
958 return -1;
959}
960
ea07c5aa
JO
961struct annotate_args {
962 size_t privsize;
24fe7b88 963 struct arch *arch;
1a04db70 964 struct map *map;
d03a686e 965 struct perf_evsel *evsel;
4748834f
JO
966 s64 offset;
967 char *line;
968 int line_nr;
ea07c5aa
JO
969};
970
c835e191
JO
971static void annotation_line__delete(struct annotation_line *al)
972{
973 void *ptr = (void *) al - al->privsize;
974
8b4c74dc 975 free_srcline(al->path);
c835e191
JO
976 zfree(&al->line);
977 free(ptr);
978}
979
980/*
981 * Allocating the annotation line data with following
982 * structure:
983 *
984 * --------------------------------------
985 * private space | struct annotation_line
986 * --------------------------------------
987 *
988 * Size of the private space is stored in 'struct annotation_line'.
989 *
990 */
991static struct annotation_line *
992annotation_line__new(struct annotate_args *args, size_t privsize)
993{
994 struct annotation_line *al;
7e304557 995 struct perf_evsel *evsel = args->evsel;
c835e191 996 size_t size = privsize + sizeof(*al);
7e304557
JO
997 int nr = 1;
998
999 if (perf_evsel__is_group_event(evsel))
1000 nr = evsel->nr_members;
1001
1002 size += sizeof(al->samples[0]) * nr;
c835e191
JO
1003
1004 al = zalloc(size);
1005 if (al) {
1006 al = (void *) al + privsize;
1007 al->privsize = privsize;
1008 al->offset = args->offset;
1009 al->line = strdup(args->line);
1010 al->line_nr = args->line_nr;
7e304557 1011 al->samples_nr = nr;
c835e191
JO
1012 }
1013
1014 return al;
1015}
1016
1017/*
1018 * Allocating the disasm annotation line data with
1019 * following structure:
1020 *
1021 * ------------------------------------------------------------
1022 * privsize space | struct disasm_line | struct annotation_line
1023 * ------------------------------------------------------------
1024 *
1025 * We have 'struct annotation_line' member as last member
1026 * of 'struct disasm_line' to have an easy access.
1027 *
1028 */
4748834f 1029static struct disasm_line *disasm_line__new(struct annotate_args *args)
78f7defe 1030{
c835e191
JO
1031 struct disasm_line *dl = NULL;
1032 struct annotation_line *al;
1033 size_t privsize = args->privsize + offsetof(struct disasm_line, al);
78f7defe 1034
c835e191
JO
1035 al = annotation_line__new(args, privsize);
1036 if (al != NULL) {
1037 dl = disasm_line(al);
d5490b96
JO
1038
1039 if (dl->al.line == NULL)
058b4cc9 1040 goto out_delete;
5145418b 1041
4748834f 1042 if (args->offset != -1) {
d5490b96 1043 if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0)
5145418b
ACM
1044 goto out_free_line;
1045
1a04db70 1046 disasm_line__init_ins(dl, args->arch, args->map);
5145418b 1047 }
78f7defe
ACM
1048 }
1049
29ed6e76 1050 return dl;
5145418b
ACM
1051
1052out_free_line:
d5490b96 1053 zfree(&dl->al.line);
058b4cc9 1054out_delete:
29ed6e76 1055 free(dl);
058b4cc9 1056 return NULL;
78f7defe
ACM
1057}
1058
29ed6e76 1059void disasm_line__free(struct disasm_line *dl)
78f7defe 1060{
75b49202
ACM
1061 if (dl->ins.ops && dl->ins.ops->free)
1062 dl->ins.ops->free(&dl->ops);
c46219ac
ACM
1063 else
1064 ins__delete(&dl->ops);
75b49202
ACM
1065 free((void *)dl->ins.name);
1066 dl->ins.name = NULL;
c835e191 1067 annotation_line__delete(&dl->al);
78f7defe
ACM
1068}
1069
5417072b
ACM
1070int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
1071{
75b49202 1072 if (raw || !dl->ins.ops)
648388ae 1073 return scnprintf(bf, size, "%-6s %s", dl->ins.name, dl->ops.raw);
5417072b 1074
75b49202 1075 return ins__scnprintf(&dl->ins, bf, size, &dl->ops);
5417072b
ACM
1076}
1077
82b9d7ff 1078static void annotation_line__add(struct annotation_line *al, struct list_head *head)
78f7defe 1079{
82b9d7ff 1080 list_add_tail(&al->node, head);
78f7defe
ACM
1081}
1082
c4c72436
JO
1083struct annotation_line *
1084annotation_line__next(struct annotation_line *pos, struct list_head *head)
78f7defe 1085{
c4c72436
JO
1086 list_for_each_entry_continue(pos, head, node)
1087 if (pos->offset >= 0)
78f7defe
ACM
1088 return pos;
1089
1090 return NULL;
1091}
1092
70fbe057
PZ
1093static const char *annotate__address_color(struct block_range *br)
1094{
1095 double cov = block_range__coverage(br);
1096
1097 if (cov >= 0) {
1098 /* mark red for >75% coverage */
1099 if (cov > 0.75)
1100 return PERF_COLOR_RED;
1101
1102 /* mark dull for <1% coverage */
1103 if (cov < 0.01)
1104 return PERF_COLOR_NORMAL;
1105 }
1106
1107 return PERF_COLOR_MAGENTA;
1108}
1109
1110static const char *annotate__asm_color(struct block_range *br)
1111{
1112 double cov = block_range__coverage(br);
1113
1114 if (cov >= 0) {
1115 /* mark dull for <1% coverage */
1116 if (cov < 0.01)
1117 return PERF_COLOR_NORMAL;
1118 }
1119
1120 return PERF_COLOR_BLUE;
1121}
1122
1123static void annotate__branch_printf(struct block_range *br, u64 addr)
1124{
1125 bool emit_comment = true;
1126
1127 if (!br)
1128 return;
1129
1130#if 1
1131 if (br->is_target && br->start == addr) {
1132 struct block_range *branch = br;
1133 double p;
1134
1135 /*
1136 * Find matching branch to our target.
1137 */
1138 while (!branch->is_branch)
1139 branch = block_range__next(branch);
1140
1141 p = 100 *(double)br->entry / branch->coverage;
1142
1143 if (p > 0.1) {
1144 if (emit_comment) {
1145 emit_comment = false;
1146 printf("\t#");
1147 }
1148
1149 /*
1150 * The percentage of coverage joined at this target in relation
1151 * to the next branch.
1152 */
1153 printf(" +%.2f%%", p);
1154 }
1155 }
1156#endif
1157 if (br->is_branch && br->end == addr) {
1158 double p = 100*(double)br->taken / br->coverage;
1159
1160 if (p > 0.1) {
1161 if (emit_comment) {
1162 emit_comment = false;
1163 printf("\t#");
1164 }
1165
1166 /*
1167 * The percentage of coverage leaving at this branch, and
1168 * its prediction ratio.
1169 */
1170 printf(" -%.2f%% (p:%.2f%%)", p, 100*(double)br->pred / br->taken);
1171 }
1172 }
1173}
1174
f48e7c40 1175static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_width)
78f7defe 1176{
29971f9a
JO
1177 s64 offset = dl->al.offset;
1178 const u64 addr = start + offset;
1179 struct block_range *br;
1180
1181 br = block_range__find(addr);
f48e7c40 1182 color_fprintf(stdout, annotate__address_color(br), " %*" PRIx64 ":", addr_fmt_width, addr);
29971f9a
JO
1183 color_fprintf(stdout, annotate__asm_color(br), "%s", dl->al.line);
1184 annotate__branch_printf(br, addr);
1185 return 0;
1186}
1187
1188static int
1189annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start,
1190 struct perf_evsel *evsel, u64 len, int min_pcnt, int printed,
f48e7c40 1191 int max_lines, struct annotation_line *queue, int addr_fmt_width)
29971f9a
JO
1192{
1193 struct disasm_line *dl = container_of(al, struct disasm_line, al);
78f7defe
ACM
1194 static const char *prev_line;
1195 static const char *prev_color;
1196
29971f9a 1197 if (al->offset != -1) {
f681d593 1198 double max_percent = 0.0;
b1dd4432 1199 int i, nr_percent = 1;
78f7defe
ACM
1200 const char *color;
1201 struct annotation *notes = symbol__annotation(sym);
ce6f4fab 1202
29971f9a
JO
1203 for (i = 0; i < al->samples_nr; i++) {
1204 struct annotation_data *sample = &al->samples[i];
78f7defe 1205
f681d593
JO
1206 if (sample->percent > max_percent)
1207 max_percent = sample->percent;
b1dd4432
NK
1208 }
1209
1210 if (max_percent < min_pcnt)
36532461
ACM
1211 return -1;
1212
e3087b80 1213 if (max_lines && printed >= max_lines)
36532461 1214 return 1;
d040bd36 1215
d5e3d747 1216 if (queue != NULL) {
29971f9a
JO
1217 list_for_each_entry_from(queue, &notes->src->source, node) {
1218 if (queue == al)
d5e3d747 1219 break;
29971f9a 1220 annotation_line__print(queue, sym, start, evsel, len,
f48e7c40 1221 0, 0, 1, NULL, addr_fmt_width);
d5e3d747
ACM
1222 }
1223 }
1224
b1dd4432 1225 color = get_percent_color(max_percent);
78f7defe
ACM
1226
1227 /*
1228 * Also color the filename and line if needed, with
1229 * the same color than the percentage. Don't print it
1230 * twice for close colored addr with the same filename:line
1231 */
29971f9a
JO
1232 if (al->path) {
1233 if (!prev_line || strcmp(prev_line, al->path)
78f7defe 1234 || color != prev_color) {
29971f9a
JO
1235 color_fprintf(stdout, color, " %s", al->path);
1236 prev_line = al->path;
78f7defe
ACM
1237 prev_color = color;
1238 }
1239 }
1240
b1dd4432 1241 for (i = 0; i < nr_percent; i++) {
29971f9a 1242 struct annotation_data *sample = &al->samples[i];
f681d593
JO
1243
1244 color = get_percent_color(sample->percent);
0c4a5bce
ML
1245
1246 if (symbol_conf.show_total_period)
ce9ee4a2 1247 color_fprintf(stdout, color, " %11" PRIu64,
f681d593 1248 sample->he.period);
1ac39372
TS
1249 else if (symbol_conf.show_nr_samples)
1250 color_fprintf(stdout, color, " %7" PRIu64,
f681d593 1251 sample->he.nr_samples);
0c4a5bce 1252 else
f681d593 1253 color_fprintf(stdout, color, " %7.2f", sample->percent);
b1dd4432
NK
1254 }
1255
f48e7c40 1256 printf(" : ");
70fbe057 1257
f48e7c40 1258 disasm_line__print(dl, start, addr_fmt_width);
70fbe057 1259 printf("\n");
e3087b80 1260 } else if (max_lines && printed >= max_lines)
36532461
ACM
1261 return 1;
1262 else {
ce9ee4a2 1263 int width = symbol_conf.show_total_period ? 12 : 8;
b1dd4432 1264
d5e3d747
ACM
1265 if (queue)
1266 return -1;
1267
759ff497 1268 if (perf_evsel__is_group_event(evsel))
b1dd4432
NK
1269 width *= evsel->nr_members;
1270
29971f9a 1271 if (!*al->line)
b1dd4432 1272 printf(" %*s:\n", width, " ");
78f7defe 1273 else
f48e7c40 1274 printf(" %*s: %*s %s\n", width, " ", addr_fmt_width, " ", al->line);
78f7defe 1275 }
36532461
ACM
1276
1277 return 0;
78f7defe
ACM
1278}
1279
3aec150a
NK
1280/*
1281 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw)
1282 * which looks like following
1283 *
1284 * 0000000000415500 <_init>:
1285 * 415500: sub $0x8,%rsp
1286 * 415504: mov 0x2f5ad5(%rip),%rax # 70afe0 <_DYNAMIC+0x2f8>
1287 * 41550b: test %rax,%rax
1288 * 41550e: je 415515 <_init+0x15>
1289 * 415510: callq 416e70 <__gmon_start__@plt>
1290 * 415515: add $0x8,%rsp
1291 * 415519: retq
1292 *
1293 * it will be parsed and saved into struct disasm_line as
1294 * <offset> <name> <ops.raw>
1295 *
1296 * The offset will be a relative offset from the start of the symbol and -1
1297 * means that it's not a disassembly line so should be treated differently.
1298 * The ops.raw part will be parsed further according to type of the instruction.
1299 */
1a04db70 1300static int symbol__parse_objdump_line(struct symbol *sym, FILE *file,
ea07c5aa 1301 struct annotate_args *args,
e592488c 1302 int *line_nr)
78f7defe 1303{
1a04db70 1304 struct map *map = args->map;
ce6f4fab 1305 struct annotation *notes = symbol__annotation(sym);
29ed6e76 1306 struct disasm_line *dl;
4597cf06 1307 char *line = NULL, *parsed_line, *tmp, *tmp2;
78f7defe
ACM
1308 size_t line_len;
1309 s64 line_ip, offset = -1;
e592488c 1310 regmatch_t match[2];
78f7defe
ACM
1311
1312 if (getline(&line, &line_len, file) < 0)
1313 return -1;
1314
1315 if (!line)
1316 return -1;
1317
78f7defe 1318 line_ip = -1;
4597cf06 1319 parsed_line = rtrim(line);
78f7defe 1320
e592488c 1321 /* /filename:linenr ? Save line number and ignore. */
986a5bc0
TS
1322 if (regexec(&file_lineno, parsed_line, 2, match, 0) == 0) {
1323 *line_nr = atoi(parsed_line + match[1].rm_so);
e592488c
AK
1324 return 0;
1325 }
1326
4597cf06 1327 tmp = ltrim(parsed_line);
78f7defe
ACM
1328 if (*tmp) {
1329 /*
1330 * Parse hexa addresses followed by ':'
1331 */
1332 line_ip = strtoull(tmp, &tmp2, 16);
1333 if (*tmp2 != ':' || tmp == tmp2 || tmp2[1] == '\0')
1334 line_ip = -1;
1335 }
1336
1337 if (line_ip != -1) {
1338 u64 start = map__rip_2objdump(map, sym->start),
1339 end = map__rip_2objdump(map, sym->end);
1340
1341 offset = line_ip - start;
2c241bd3 1342 if ((u64)line_ip < start || (u64)line_ip >= end)
78f7defe 1343 offset = -1;
058b4cc9
ACM
1344 else
1345 parsed_line = tmp2 + 1;
a31b7cc0 1346 }
78f7defe 1347
4748834f
JO
1348 args->offset = offset;
1349 args->line = parsed_line;
1350 args->line_nr = *line_nr;
1351
1352 dl = disasm_line__new(args);
058b4cc9 1353 free(line);
e592488c 1354 (*line_nr)++;
058b4cc9 1355
29ed6e76 1356 if (dl == NULL)
78f7defe 1357 return -1;
058b4cc9 1358
e216874c 1359 if (!disasm_line__has_offset(dl)) {
bbb7f846
AH
1360 dl->ops.target.offset = dl->ops.target.addr -
1361 map__rip_2objdump(map, sym->start);
e216874c
RB
1362 dl->ops.target.offset_avail = true;
1363 }
bbb7f846 1364
696703af
ACM
1365 /* kcore has no symbols, so add the call target symbol */
1366 if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) {
6e427ab0
AH
1367 struct addr_map_symbol target = {
1368 .map = map,
1369 .addr = dl->ops.target.addr,
1370 };
1371
be39db9f 1372 if (!map_groups__find_ams(&target) &&
6e427ab0 1373 target.sym->start == target.al_addr)
696703af 1374 dl->ops.target.sym = target.sym;
b178170a
AH
1375 }
1376
82b9d7ff 1377 annotation_line__add(&dl->al, &notes->src->source);
78f7defe
ACM
1378
1379 return 0;
1380}
1381
e592488c
AK
1382static __attribute__((constructor)) void symbol__init_regexpr(void)
1383{
1384 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED);
1385}
1386
484a5e74
AH
1387static void delete_last_nop(struct symbol *sym)
1388{
1389 struct annotation *notes = symbol__annotation(sym);
1390 struct list_head *list = &notes->src->source;
1391 struct disasm_line *dl;
1392
1393 while (!list_empty(list)) {
a17c4ca0 1394 dl = list_entry(list->prev, struct disasm_line, al.node);
484a5e74 1395
75b49202
ACM
1396 if (dl->ins.ops) {
1397 if (dl->ins.ops != &nop_ops)
484a5e74
AH
1398 return;
1399 } else {
d5490b96
JO
1400 if (!strstr(dl->al.line, " nop ") &&
1401 !strstr(dl->al.line, " nopl ") &&
1402 !strstr(dl->al.line, " nopw "))
484a5e74
AH
1403 return;
1404 }
1405
a17c4ca0 1406 list_del(&dl->al.node);
484a5e74
AH
1407 disasm_line__free(dl);
1408 }
1409}
1410
ee51d851
ACM
1411int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *map,
1412 int errnum, char *buf, size_t buflen)
1413{
1414 struct dso *dso = map->dso;
1415
1416 BUG_ON(buflen == 0);
1417
1418 if (errnum >= 0) {
1419 str_error_r(errnum, buf, buflen);
1420 return 0;
1421 }
1422
1423 switch (errnum) {
1424 case SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX: {
1425 char bf[SBUILD_ID_SIZE + 15] = " with build id ";
1426 char *build_id_msg = NULL;
1427
1428 if (dso->has_build_id) {
1429 build_id__sprintf(dso->build_id,
1430 sizeof(dso->build_id), bf + 15);
1431 build_id_msg = bf;
1432 }
1433 scnprintf(buf, buflen,
1434 "No vmlinux file%s\nwas found in the path.\n\n"
1435 "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n"
1436 "Please use:\n\n"
1437 " perf buildid-cache -vu vmlinux\n\n"
1438 "or:\n\n"
1439 " --vmlinux vmlinux\n", build_id_msg ?: "");
1440 }
1441 break;
1442 default:
1443 scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum);
1444 break;
1445 }
1446
1447 return 0;
1448}
1449
05ed3ac9 1450static int dso__disassemble_filename(struct dso *dso, char *filename, size_t filename_size)
78f7defe 1451{
05ed3ac9
ACM
1452 char linkname[PATH_MAX];
1453 char *build_id_filename;
6ebd2547 1454 char *build_id_path = NULL;
3619ef76 1455 char *pos;
78f7defe 1456
c12944f7
ACM
1457 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
1458 !dso__is_kcore(dso))
05ed3ac9 1459 return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX;
c12944f7 1460
d2396999 1461 build_id_filename = dso__build_id_filename(dso, NULL, 0, false);
05ed3ac9
ACM
1462 if (build_id_filename) {
1463 __symbol__join_symfs(filename, filename_size, build_id_filename);
1464 free(build_id_filename);
3caee094 1465 } else {
ee51d851
ACM
1466 if (dso->has_build_id)
1467 return ENOMEM;
78f7defe 1468 goto fallback;
3caee094
ACM
1469 }
1470
6ebd2547
TS
1471 build_id_path = strdup(filename);
1472 if (!build_id_path)
1473 return -1;
1474
3619ef76
NK
1475 /*
1476 * old style build-id cache has name of XX/XXXXXXX.. while
1477 * new style has XX/XXXXXXX../{elf,kallsyms,vdso}.
1478 * extract the build-id part of dirname in the new style only.
1479 */
1480 pos = strrchr(build_id_path, '/');
1481 if (pos && strlen(pos) < SBUILD_ID_SIZE - 2)
1482 dirname(build_id_path);
6ebd2547 1483
3caee094 1484 if (dso__is_kcore(dso) ||
6ebd2547 1485 readlink(build_id_path, linkname, sizeof(linkname)) < 0 ||
05ed3ac9
ACM
1486 strstr(linkname, DSO__NAME_KALLSYMS) ||
1487 access(filename, R_OK)) {
78f7defe
ACM
1488fallback:
1489 /*
1490 * If we don't have build-ids or the build-id file isn't in the
1491 * cache, or is just a kallsyms file, well, lets hope that this
1492 * DSO is the same as when 'perf record' ran.
1493 */
05ed3ac9 1494 __symbol__join_symfs(filename, filename_size, dso->long_name);
78f7defe
ACM
1495 }
1496
6ebd2547 1497 free(build_id_path);
05ed3ac9
ACM
1498 return 0;
1499}
1500
1a04db70 1501static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
05ed3ac9 1502{
1a04db70 1503 struct map *map = args->map;
05ed3ac9 1504 struct dso *dso = map->dso;
6810158d 1505 char *command;
05ed3ac9
ACM
1506 FILE *file;
1507 char symfs_filename[PATH_MAX];
1508 struct kcore_extract kce;
1509 bool delete_extract = false;
1510 int stdout_fd[2];
1511 int lineno = 0;
1512 int nline;
1513 pid_t pid;
1514 int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename));
1515
1516 if (err)
1517 return err;
1518
78f7defe 1519 pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
3caee094 1520 symfs_filename, sym->name, map->unmap_ip(map, sym->start),
78f7defe
ACM
1521 map->unmap_ip(map, sym->end));
1522
78f7defe
ACM
1523 pr_debug("annotating [%p] %30s : [%p] %30s\n",
1524 dso, dso->long_name, sym, sym->name);
1525
afba19d9
AH
1526 if (dso__is_kcore(dso)) {
1527 kce.kcore_filename = symfs_filename;
1528 kce.addr = map__rip_2objdump(map, sym->start);
1529 kce.offs = sym->start;
2c241bd3 1530 kce.len = sym->end - sym->start;
afba19d9
AH
1531 if (!kcore_extract__create(&kce)) {
1532 delete_extract = true;
1533 strlcpy(symfs_filename, kce.extract_filename,
1534 sizeof(symfs_filename));
afba19d9 1535 }
2c7da8c5 1536 } else if (dso__needs_decompress(dso)) {
3c84fd53 1537 char tmp[KMOD_DECOMP_LEN];
2c7da8c5 1538
3c84fd53
NK
1539 if (dso__decompress_kmodule_path(dso, symfs_filename,
1540 tmp, sizeof(tmp)) < 0)
3caee094 1541 goto out;
2c7da8c5
JO
1542
1543 strcpy(symfs_filename, tmp);
afba19d9
AH
1544 }
1545
6810158d 1546 err = asprintf(&command,
7a4ec938 1547 "%s %s%s --start-address=0x%016" PRIx64
3e6a2a7f 1548 " --stop-address=0x%016" PRIx64
7b4500bc 1549 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
7a4ec938 1550 objdump_path ? objdump_path : "objdump",
f69b64f7
AK
1551 disassembler_style ? "-M " : "",
1552 disassembler_style ? disassembler_style : "",
78f7defe 1553 map__rip_2objdump(map, sym->start),
2c241bd3 1554 map__rip_2objdump(map, sym->end),
3e6a2a7f
SE
1555 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
1556 symbol_conf.annotate_src ? "-S" : "",
3caee094 1557 symfs_filename, symfs_filename);
78f7defe 1558
6810158d
ACM
1559 if (err < 0) {
1560 pr_err("Failure allocating memory for the command to run\n");
1561 goto out_remove_tmp;
1562 }
1563
78f7defe
ACM
1564 pr_debug("Executing: %s\n", command);
1565
9955d0be
ACM
1566 err = -1;
1567 if (pipe(stdout_fd) < 0) {
1568 pr_err("Failure creating the pipe to run %s\n", command);
6810158d 1569 goto out_free_command;
9955d0be
ACM
1570 }
1571
1572 pid = fork();
1573 if (pid < 0) {
1574 pr_err("Failure forking to run %s\n", command);
1575 goto out_close_stdout;
1576 }
1577
1578 if (pid == 0) {
1579 close(stdout_fd[0]);
1580 dup2(stdout_fd[1], 1);
1581 close(stdout_fd[1]);
1582 execl("/bin/sh", "sh", "-c", command, NULL);
1583 perror(command);
1584 exit(-1);
1585 }
1586
1587 close(stdout_fd[1]);
1588
1589 file = fdopen(stdout_fd[0], "r");
62ec9b3f 1590 if (!file) {
9955d0be 1591 pr_err("Failure creating FILE stream for %s\n", command);
62ec9b3f
AK
1592 /*
1593 * If we were using debug info should retry with
1594 * original binary.
1595 */
6810158d 1596 goto out_free_command;
62ec9b3f 1597 }
78f7defe 1598
62ec9b3f
AK
1599 nline = 0;
1600 while (!feof(file)) {
ed7b339f
ACM
1601 /*
1602 * The source code line number (lineno) needs to be kept in
1603 * accross calls to symbol__parse_objdump_line(), so that it
1604 * can associate it with the instructions till the next one.
1605 * See disasm_line__new() and struct disasm_line::line_nr.
1606 */
1a04db70 1607 if (symbol__parse_objdump_line(sym, file, args, &lineno) < 0)
78f7defe 1608 break;
62ec9b3f
AK
1609 nline++;
1610 }
1611
1612 if (nline == 0)
1613 pr_err("No output from %s\n", command);
78f7defe 1614
484a5e74
AH
1615 /*
1616 * kallsyms does not have symbol sizes so there may a nop at the end.
1617 * Remove it.
1618 */
1619 if (dso__is_kcore(dso))
1620 delete_last_nop(sym);
1621
9955d0be
ACM
1622 fclose(file);
1623 err = 0;
6810158d
ACM
1624out_free_command:
1625 free(command);
2c7da8c5 1626out_remove_tmp:
9955d0be
ACM
1627 close(stdout_fd[0]);
1628
2c7da8c5
JO
1629 if (dso__needs_decompress(dso))
1630 unlink(symfs_filename);
3caee094 1631
afba19d9
AH
1632 if (delete_extract)
1633 kcore_extract__delete(&kce);
c12944f7 1634out:
78f7defe 1635 return err;
9955d0be
ACM
1636
1637out_close_stdout:
1638 close(stdout_fd[1]);
6810158d 1639 goto out_free_command;
78f7defe
ACM
1640}
1641
073ae601
JO
1642static void calc_percent(struct sym_hist *hist,
1643 struct annotation_data *sample,
1644 s64 offset, s64 end)
1645{
1646 unsigned int hits = 0;
1647 u64 period = 0;
1648
1649 while (offset < end) {
1650 hits += hist->addr[offset].nr_samples;
1651 period += hist->addr[offset].period;
1652 ++offset;
1653 }
1654
1655 if (hist->nr_samples) {
1656 sample->he.period = period;
1657 sample->he.nr_samples = hits;
1658 sample->percent = 100.0 * hits / hist->nr_samples;
1659 }
1660}
1661
9e4e0a9d
JO
1662static void annotation__calc_percent(struct annotation *notes,
1663 struct perf_evsel *evsel, s64 len)
073ae601
JO
1664{
1665 struct annotation_line *al, *next;
1666
1667 list_for_each_entry(al, &notes->src->source, node) {
1668 s64 end;
1669 int i;
1670
1671 if (al->offset == -1)
1672 continue;
1673
1674 next = annotation_line__next(al, &notes->src->source);
1675 end = next ? next->offset : len;
1676
1677 for (i = 0; i < al->samples_nr; i++) {
1678 struct annotation_data *sample;
1679 struct sym_hist *hist;
1680
1681 hist = annotation__histogram(notes, evsel->idx + i);
1682 sample = &al->samples[i];
1683
1684 calc_percent(hist, sample, al->offset, end);
1685 }
1686 }
073ae601
JO
1687}
1688
9e4e0a9d 1689void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel)
073ae601
JO
1690{
1691 struct annotation *notes = symbol__annotation(sym);
1692
9e4e0a9d 1693 annotation__calc_percent(notes, evsel, symbol__size(sym));
073ae601
JO
1694}
1695
c34df25b 1696int symbol__annotate(struct symbol *sym, struct map *map,
d03a686e 1697 struct perf_evsel *evsel, size_t privsize,
5449f13c 1698 struct arch **parch)
c34df25b 1699{
ea07c5aa
JO
1700 struct annotate_args args = {
1701 .privsize = privsize,
1a04db70 1702 .map = map,
d03a686e 1703 .evsel = evsel,
ea07c5aa 1704 };
5449f13c 1705 struct perf_env *env = perf_evsel__env(evsel);
3285deba 1706 const char *arch_name = perf_env__arch(env);
c34df25b
JO
1707 struct arch *arch;
1708 int err;
1709
c34df25b
JO
1710 if (!arch_name)
1711 return -1;
1712
24fe7b88 1713 args.arch = arch = arch__find(arch_name);
c34df25b
JO
1714 if (arch == NULL)
1715 return -ENOTSUP;
1716
1717 if (parch)
1718 *parch = arch;
1719
1720 if (arch->init) {
5449f13c 1721 err = arch->init(arch, env ? env->cpuid : NULL);
c34df25b
JO
1722 if (err) {
1723 pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name);
1724 return err;
1725 }
1726 }
1727
05d3f1a1 1728 return symbol__disassemble(sym, &args);
c34df25b
JO
1729}
1730
8b4c74dc 1731static void insert_source_line(struct rb_root *root, struct annotation_line *al)
78f7defe 1732{
8b4c74dc 1733 struct annotation_line *iter;
78f7defe
ACM
1734 struct rb_node **p = &root->rb_node;
1735 struct rb_node *parent = NULL;
1491c22a 1736 int i, ret;
78f7defe
ACM
1737
1738 while (*p != NULL) {
1739 parent = *p;
8b4c74dc 1740 iter = rb_entry(parent, struct annotation_line, rb_node);
78f7defe 1741
8b4c74dc 1742 ret = strcmp(iter->path, al->path);
41127965 1743 if (ret == 0) {
8b4c74dc
JO
1744 for (i = 0; i < al->samples_nr; i++)
1745 iter->samples[i].percent_sum += al->samples[i].percent;
41127965
NK
1746 return;
1747 }
1748
1749 if (ret < 0)
1750 p = &(*p)->rb_left;
1751 else
1752 p = &(*p)->rb_right;
1753 }
1754
8b4c74dc
JO
1755 for (i = 0; i < al->samples_nr; i++)
1756 al->samples[i].percent_sum = al->samples[i].percent;
41127965 1757
8b4c74dc
JO
1758 rb_link_node(&al->rb_node, parent, p);
1759 rb_insert_color(&al->rb_node, root);
41127965
NK
1760}
1761
8b4c74dc 1762static int cmp_source_line(struct annotation_line *a, struct annotation_line *b)
1491c22a
NK
1763{
1764 int i;
1765
8b4c74dc 1766 for (i = 0; i < a->samples_nr; i++) {
276af92f 1767 if (a->samples[i].percent_sum == b->samples[i].percent_sum)
1491c22a 1768 continue;
276af92f 1769 return a->samples[i].percent_sum > b->samples[i].percent_sum;
1491c22a
NK
1770 }
1771
1772 return 0;
1773}
1774
8b4c74dc 1775static void __resort_source_line(struct rb_root *root, struct annotation_line *al)
41127965 1776{
8b4c74dc 1777 struct annotation_line *iter;
41127965
NK
1778 struct rb_node **p = &root->rb_node;
1779 struct rb_node *parent = NULL;
1780
1781 while (*p != NULL) {
1782 parent = *p;
8b4c74dc 1783 iter = rb_entry(parent, struct annotation_line, rb_node);
41127965 1784
8b4c74dc 1785 if (cmp_source_line(al, iter))
78f7defe
ACM
1786 p = &(*p)->rb_left;
1787 else
1788 p = &(*p)->rb_right;
1789 }
1790
8b4c74dc
JO
1791 rb_link_node(&al->rb_node, parent, p);
1792 rb_insert_color(&al->rb_node, root);
78f7defe
ACM
1793}
1794
41127965
NK
1795static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
1796{
8b4c74dc 1797 struct annotation_line *al;
41127965
NK
1798 struct rb_node *node;
1799
1800 node = rb_first(src_root);
1801 while (node) {
1802 struct rb_node *next;
1803
8b4c74dc 1804 al = rb_entry(node, struct annotation_line, rb_node);
41127965
NK
1805 next = rb_next(node);
1806 rb_erase(node, src_root);
1807
8b4c74dc 1808 __resort_source_line(dest_root, al);
41127965
NK
1809 node = next;
1810 }
1811}
1812
78f7defe
ACM
1813static void print_summary(struct rb_root *root, const char *filename)
1814{
8b4c74dc 1815 struct annotation_line *al;
78f7defe
ACM
1816 struct rb_node *node;
1817
1818 printf("\nSorted summary for file %s\n", filename);
1819 printf("----------------------------------------------\n\n");
1820
1821 if (RB_EMPTY_ROOT(root)) {
1822 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
1823 return;
1824 }
1825
1826 node = rb_first(root);
1827 while (node) {
1491c22a 1828 double percent, percent_max = 0.0;
78f7defe
ACM
1829 const char *color;
1830 char *path;
1491c22a 1831 int i;
78f7defe 1832
8b4c74dc
JO
1833 al = rb_entry(node, struct annotation_line, rb_node);
1834 for (i = 0; i < al->samples_nr; i++) {
1835 percent = al->samples[i].percent_sum;
1491c22a
NK
1836 color = get_percent_color(percent);
1837 color_fprintf(stdout, color, " %7.2f", percent);
1838
1839 if (percent > percent_max)
1840 percent_max = percent;
1841 }
1842
8b4c74dc 1843 path = al->path;
1491c22a 1844 color = get_percent_color(percent_max);
f048d548 1845 color_fprintf(stdout, color, " %s\n", path);
78f7defe 1846
78f7defe
ACM
1847 node = rb_next(node);
1848 }
1849}
1850
db8fd07a 1851static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel)
78f7defe
ACM
1852{
1853 struct annotation *notes = symbol__annotation(sym);
db8fd07a 1854 struct sym_hist *h = annotation__histogram(notes, evsel->idx);
1b2e2df4 1855 u64 len = symbol__size(sym), offset;
78f7defe
ACM
1856
1857 for (offset = 0; offset < len; ++offset)
896bccd3 1858 if (h->addr[offset].nr_samples != 0)
78f7defe 1859 printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
896bccd3 1860 sym->start + offset, h->addr[offset].nr_samples);
8158683d 1861 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples);
78f7defe
ACM
1862}
1863
f48e7c40
JO
1864static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start)
1865{
1866 char bf[32];
1867 struct annotation_line *line;
1868
1869 list_for_each_entry_reverse(line, lines, node) {
1870 if (line->offset != -1)
1871 return scnprintf(bf, sizeof(bf), "%" PRIx64, start + line->offset);
1872 }
1873
1874 return 0;
1875}
1876
db8fd07a
NK
1877int symbol__annotate_printf(struct symbol *sym, struct map *map,
1878 struct perf_evsel *evsel, bool full_paths,
1879 int min_pcnt, int max_lines, int context)
78f7defe
ACM
1880{
1881 struct dso *dso = map->dso;
bfd14b9a
DA
1882 char *filename;
1883 const char *d_filename;
9cdbadce 1884 const char *evsel_name = perf_evsel__name(evsel);
ce6f4fab 1885 struct annotation *notes = symbol__annotation(sym);
135cce1b 1886 struct sym_hist *h = annotation__histogram(notes, evsel->idx);
8f25b819 1887 struct annotation_line *pos, *queue = NULL;
058b4cc9 1888 u64 start = map__rip_2objdump(map, sym->start);
f48e7c40 1889 int printed = 2, queue_len = 0, addr_fmt_width;
36532461 1890 int more = 0;
78f7defe 1891 u64 len;
ce9ee4a2 1892 int width = symbol_conf.show_total_period ? 12 : 8;
53dd9b5f 1893 int graph_dotted_len;
78f7defe 1894
bfd14b9a
DA
1895 filename = strdup(dso->long_name);
1896 if (!filename)
1897 return -ENOMEM;
1898
78f7defe
ACM
1899 if (full_paths)
1900 d_filename = filename;
1901 else
1902 d_filename = basename(filename);
1903
1b2e2df4 1904 len = symbol__size(sym);
b1dd4432 1905
759ff497 1906 if (perf_evsel__is_group_event(evsel))
b1dd4432 1907 width *= evsel->nr_members;
78f7defe 1908
135cce1b 1909 graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n",
1ac39372
TS
1910 width, width, symbol_conf.show_total_period ? "Period" :
1911 symbol_conf.show_nr_samples ? "Samples" : "Percent",
38d2dcd0 1912 d_filename, evsel_name, h->nr_samples);
9cdbadce 1913
53dd9b5f 1914 printf("%-*.*s----\n",
9cdbadce 1915 graph_dotted_len, graph_dotted_len, graph_dotted_line);
78f7defe 1916
bb963e16 1917 if (verbose > 0)
db8fd07a 1918 symbol__annotate_hits(sym, evsel);
78f7defe 1919
f48e7c40
JO
1920 addr_fmt_width = annotated_source__addr_fmt_width(&notes->src->source, start);
1921
8f25b819
JO
1922 list_for_each_entry(pos, &notes->src->source, node) {
1923 int err;
1924
d5e3d747
ACM
1925 if (context && queue == NULL) {
1926 queue = pos;
1927 queue_len = 0;
1928 }
1929
8f25b819
JO
1930 err = annotation_line__print(pos, sym, start, evsel, len,
1931 min_pcnt, printed, max_lines,
f48e7c40 1932 queue, addr_fmt_width);
8f25b819
JO
1933
1934 switch (err) {
36532461
ACM
1935 case 0:
1936 ++printed;
d5e3d747
ACM
1937 if (context) {
1938 printed += queue_len;
1939 queue = NULL;
1940 queue_len = 0;
1941 }
36532461
ACM
1942 break;
1943 case 1:
1944 /* filtered by max_lines */
1945 ++more;
d040bd36 1946 break;
36532461
ACM
1947 case -1:
1948 default:
d5e3d747
ACM
1949 /*
1950 * Filtered by min_pcnt or non IP lines when
1951 * context != 0
1952 */
1953 if (!context)
1954 break;
1955 if (queue_len == context)
8f25b819 1956 queue = list_entry(queue->node.next, typeof(*queue), node);
d5e3d747
ACM
1957 else
1958 ++queue_len;
36532461
ACM
1959 break;
1960 }
1961 }
1962
bfd14b9a
DA
1963 free(filename);
1964
36532461
ACM
1965 return more;
1966}
f1e2701d 1967
36532461
ACM
1968void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
1969{
1970 struct annotation *notes = symbol__annotation(sym);
1971 struct sym_hist *h = annotation__histogram(notes, evidx);
1972
ce6f4fab 1973 memset(h, 0, notes->src->sizeof_sym_hist);
36532461
ACM
1974}
1975
ce6f4fab 1976void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
36532461
ACM
1977{
1978 struct annotation *notes = symbol__annotation(sym);
1979 struct sym_hist *h = annotation__histogram(notes, evidx);
1b2e2df4 1980 int len = symbol__size(sym), offset;
36532461 1981
8158683d 1982 h->nr_samples = 0;
8b84a568 1983 for (offset = 0; offset < len; ++offset) {
896bccd3 1984 h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8;
8158683d 1985 h->nr_samples += h->addr[offset].nr_samples;
f1e2701d
ACM
1986 }
1987}
1988
f8eb37bd 1989void annotated_source__purge(struct annotated_source *as)
f1e2701d 1990{
f8eb37bd 1991 struct annotation_line *al, *n;
f1e2701d 1992
f8eb37bd
JO
1993 list_for_each_entry_safe(al, n, &as->source, node) {
1994 list_del(&al->node);
1995 disasm_line__free(disasm_line(al));
f1e2701d
ACM
1996 }
1997}
1998
5145418b
ACM
1999static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
2000{
2001 size_t printed;
2002
d5490b96
JO
2003 if (dl->al.offset == -1)
2004 return fprintf(fp, "%s\n", dl->al.line);
5145418b 2005
d5490b96 2006 printed = fprintf(fp, "%#" PRIx64 " %s", dl->al.offset, dl->ins.name);
5145418b 2007
c7e6ead7 2008 if (dl->ops.raw[0] != '\0') {
5145418b 2009 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",
c7e6ead7 2010 dl->ops.raw);
5145418b
ACM
2011 }
2012
2013 return printed + fprintf(fp, "\n");
2014}
2015
2016size_t disasm__fprintf(struct list_head *head, FILE *fp)
2017{
2018 struct disasm_line *pos;
2019 size_t printed = 0;
2020
a17c4ca0 2021 list_for_each_entry(pos, head, al.node)
5145418b
ACM
2022 printed += disasm_line__fprintf(pos, fp);
2023
2024 return printed;
2025}
2026
0db45bcf
ACM
2027
2028bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym)
2029{
2030 if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins) ||
2031 !disasm_line__has_offset(dl) || dl->ops.target.offset < 0 ||
2032 dl->ops.target.offset >= (s64)symbol__size(sym))
2033 return false;
2034
2035 return true;
2036}
2037
2038void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym)
2039{
2040 u64 offset, size = symbol__size(sym);
2041
2042 /* PLT symbols contain external offsets */
2043 if (strstr(sym->name, "@plt"))
2044 return;
2045
2046 for (offset = 0; offset < size; ++offset) {
2047 struct annotation_line *al = notes->offsets[offset];
2048 struct disasm_line *dl;
2049
2050 dl = disasm_line(al);
2051
2052 if (!disasm_line__is_valid_jump(dl, sym))
2053 continue;
2054
2055 al = notes->offsets[dl->ops.target.offset];
2056
2057 /*
2058 * FIXME: Oops, no jump target? Buggy disassembler? Or do we
2059 * have to adjust to the previous offset?
2060 */
2061 if (al == NULL)
2062 continue;
2063
2064 if (++al->jump_sources > notes->max_jump_sources)
2065 notes->max_jump_sources = al->jump_sources;
2066
2067 ++notes->nr_jumps;
2068 }
2069}
2070
5bc49f61
ACM
2071void annotation__set_offsets(struct annotation *notes, s64 size)
2072{
2073 struct annotation_line *al;
2074
2075 notes->max_line_len = 0;
2076
2077 list_for_each_entry(al, &notes->src->source, node) {
2078 size_t line_len = strlen(al->line);
2079
2080 if (notes->max_line_len < line_len)
2081 notes->max_line_len = line_len;
2082 al->idx = notes->nr_entries++;
2083 if (al->offset != -1) {
2084 al->idx_asm = notes->nr_asm_entries++;
2085 /*
2086 * FIXME: short term bandaid to cope with assembly
2087 * routines that comes with labels in the same column
2088 * as the address in objdump, sigh.
2089 *
2090 * E.g. copy_user_generic_unrolled
2091 */
2092 if (al->offset < size)
2093 notes->offsets[al->offset] = al;
2094 } else
2095 al->idx_asm = -1;
2096 }
2097}
2098
b8b0d819
ACM
2099static inline int width_jumps(int n)
2100{
2101 if (n >= 100)
2102 return 5;
2103 if (n / 10)
2104 return 2;
2105 return 1;
2106}
2107
2108void annotation__init_column_widths(struct annotation *notes, struct symbol *sym)
2109{
2110 notes->widths.addr = notes->widths.target =
2111 notes->widths.min_addr = hex_width(symbol__size(sym));
2112 notes->widths.max_addr = hex_width(sym->end);
2113 notes->widths.jumps = width_jumps(notes->max_jump_sources);
2114}
2115
7232bf7a
ACM
2116void annotation__update_column_widths(struct annotation *notes)
2117{
2118 if (notes->options->use_offset)
2119 notes->widths.target = notes->widths.min_addr;
2120 else
2121 notes->widths.target = notes->widths.max_addr;
2122
2123 notes->widths.addr = notes->widths.target;
2124
2125 if (notes->options->show_nr_jumps)
2126 notes->widths.addr += notes->widths.jumps + 1;
2127}
2128
8b4c74dc
JO
2129static void annotation__calc_lines(struct annotation *notes, struct map *map,
2130 struct rb_root *root, u64 start)
2131{
2132 struct annotation_line *al;
2133 struct rb_root tmp_root = RB_ROOT;
2134
2135 list_for_each_entry(al, &notes->src->source, node) {
2136 double percent_max = 0.0;
2137 int i;
2138
2139 for (i = 0; i < al->samples_nr; i++) {
2140 struct annotation_data *sample;
2141
2142 sample = &al->samples[i];
2143
2144 if (sample->percent > percent_max)
2145 percent_max = sample->percent;
2146 }
2147
2148 if (percent_max <= 0.5)
2149 continue;
2150
935f5a9d
JY
2151 al->path = get_srcline(map->dso, start + al->offset, NULL,
2152 false, true, start + al->offset);
8b4c74dc
JO
2153 insert_source_line(&tmp_root, al);
2154 }
2155
2156 resort_source_line(root, &tmp_root);
2157}
2158
2159static void symbol__calc_lines(struct symbol *sym, struct map *map,
2160 struct rb_root *root)
2161{
2162 struct annotation *notes = symbol__annotation(sym);
2163 u64 start = map__rip_2objdump(map, sym->start);
2164
2165 annotation__calc_lines(notes, map, root, start);
2166}
2167
db8fd07a
NK
2168int symbol__tty_annotate(struct symbol *sym, struct map *map,
2169 struct perf_evsel *evsel, bool print_lines,
2170 bool full_paths, int min_pcnt, int max_lines)
f1e2701d
ACM
2171{
2172 struct dso *dso = map->dso;
f1e2701d 2173 struct rb_root source_line = RB_ROOT;
f1e2701d 2174
5449f13c 2175 if (symbol__annotate(sym, map, evsel, 0, NULL) < 0)
f1e2701d
ACM
2176 return -1;
2177
05d3f1a1
JO
2178 symbol__calc_percent(sym, evsel);
2179
f1e2701d 2180 if (print_lines) {
4a4c03c1 2181 srcline_full_filename = full_paths;
8b4c74dc 2182 symbol__calc_lines(sym, map, &source_line);
86c98cab 2183 print_summary(&source_line, dso->long_name);
78f7defe
ACM
2184 }
2185
db8fd07a 2186 symbol__annotate_printf(sym, map, evsel, full_paths,
d5e3d747 2187 min_pcnt, max_lines, 0);
78f7defe 2188
f8eb37bd 2189 annotated_source__purge(symbol__annotation(sym)->src);
f1e2701d 2190
78f7defe
ACM
2191 return 0;
2192}
f626adff 2193
48c65bda
NK
2194bool ui__has_annotation(void)
2195{
2e0453af 2196 return use_browser == 1 && perf_hpp_list.sym;
48c65bda 2197}
ecda45bd 2198
2f025ea0
ACM
2199
2200double annotation_line__max_percent(struct annotation_line *al, struct annotation *notes)
2201{
2202 double percent_max = 0.0;
2203 int i;
2204
2205 for (i = 0; i < notes->nr_events; i++) {
2206 if (al->samples[i].percent > percent_max)
2207 percent_max = al->samples[i].percent;
2208 }
2209
2210 return percent_max;
2211}
2212
2ba5eca1
ACM
2213static void set_percent_color_stub(void *obj __maybe_unused,
2214 double percent __maybe_unused,
2215 bool current __maybe_unused)
2216{
2217}
2218
a1e9b74c
ACM
2219static void disasm_line__write(struct disasm_line *dl, struct annotation *notes,
2220 void *obj, char *bf, size_t size,
2221 void (*obj__printf)(void *obj, const char *fmt, ...),
2222 void (*obj__write_graph)(void *obj, int graph))
2223{
2224 if (dl->ins.ops && dl->ins.ops->scnprintf) {
2225 if (ins__is_jump(&dl->ins)) {
2226 bool fwd = dl->ops.target.offset > dl->al.offset;
2227
2228 obj__write_graph(obj, fwd ? DARROW_CHAR : UARROW_CHAR);
2229 obj__printf(obj, " ");
2230 } else if (ins__is_call(&dl->ins)) {
2231 obj__write_graph(obj, RARROW_CHAR);
2232 obj__printf(obj, " ");
2233 } else if (ins__is_ret(&dl->ins)) {
2234 obj__write_graph(obj, LARROW_CHAR);
2235 obj__printf(obj, " ");
2236 } else {
2237 obj__printf(obj, " ");
2238 }
2239 } else {
2240 obj__printf(obj, " ");
2241 }
2242
2243 disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset);
2244}
2245
2246void annotation_line__write(struct annotation_line *al, struct annotation *notes,
2247 bool first_line, bool current_entry, bool change_color, int width,
2248 void *obj,
2249 int (*obj__set_color)(void *obj, int color),
2250 void (*obj__set_percent_color)(void *obj, double percent, bool current),
2251 int (*obj__set_jumps_percent_color)(void *obj, int nr, bool current),
2252 void (*obj__printf)(void *obj, const char *fmt, ...),
2253 void (*obj__write_graph)(void *obj, int graph))
2ba5eca1
ACM
2254{
2255 double percent_max = annotation_line__max_percent(al, notes);
a1e9b74c
ACM
2256 int pcnt_width = annotation__pcnt_width(notes),
2257 cycles_width = annotation__cycles_width(notes);
2ba5eca1 2258 bool show_title = false;
a1e9b74c
ACM
2259 char bf[256];
2260 int printed;
2ba5eca1
ACM
2261
2262 if (first_line && (al->offset == -1 || percent_max == 0.0)) {
2263 if (notes->have_cycles) {
2264 if (al->ipc == 0.0 && al->cycles == 0)
2265 show_title = true;
2266 } else
2267 show_title = true;
2268 }
2269
2270 if (!obj__set_percent_color)
2271 obj__set_percent_color = set_percent_color_stub;
2272
2273 if (al->offset != -1 && percent_max != 0.0) {
2274 int i;
2275
2276 for (i = 0; i < notes->nr_events; i++) {
2277 obj__set_percent_color(obj, al->samples[i].percent, current_entry);
2278 if (notes->options->show_total_period) {
2279 obj__printf(obj, "%11" PRIu64 " ", al->samples[i].he.period);
2280 } else if (notes->options->show_nr_samples) {
2281 obj__printf(obj, "%6" PRIu64 " ",
2282 al->samples[i].he.nr_samples);
2283 } else {
2284 obj__printf(obj, "%6.2f ",
2285 al->samples[i].percent);
2286 }
2287 }
2288 } else {
2ba5eca1
ACM
2289 obj__set_percent_color(obj, 0, current_entry);
2290
2291 if (!show_title)
a1e9b74c 2292 obj__printf(obj, "%-*s", pcnt_width, " ");
2ba5eca1 2293 else {
a1e9b74c 2294 obj__printf(obj, "%-*s", pcnt_width,
2ba5eca1
ACM
2295 notes->options->show_total_period ? "Period" :
2296 notes->options->show_nr_samples ? "Samples" : "Percent");
2297 }
2298 }
2299
2300 if (notes->have_cycles) {
2301 if (al->ipc)
2302 obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->ipc);
2303 else if (!show_title)
2304 obj__printf(obj, "%*s", ANNOTATION__IPC_WIDTH, " ");
2305 else
2306 obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC");
2307
2308 if (al->cycles)
2309 obj__printf(obj, "%*" PRIu64 " ",
2310 ANNOTATION__CYCLES_WIDTH - 1, al->cycles);
2311 else if (!show_title)
2312 obj__printf(obj, "%*s", ANNOTATION__CYCLES_WIDTH, " ");
2313 else
2314 obj__printf(obj, "%*s ", ANNOTATION__CYCLES_WIDTH - 1, "Cycle");
2315 }
2316
2317 obj__printf(obj, " ");
a1e9b74c
ACM
2318
2319 if (!*al->line)
2320 obj__printf(obj, "%-*s", width - pcnt_width - cycles_width, " ");
2321 else if (al->offset == -1) {
2322 if (al->line_nr && notes->options->show_linenr)
2323 printed = scnprintf(bf, sizeof(bf), "%-*d ", notes->widths.addr + 1, al->line_nr);
2324 else
2325 printed = scnprintf(bf, sizeof(bf), "%-*s ", notes->widths.addr, " ");
2326 obj__printf(obj, bf);
2327 obj__printf(obj, "%-*s", width - printed - pcnt_width - cycles_width + 1, al->line);
2328 } else {
2329 u64 addr = al->offset;
2330 int color = -1;
2331
2332 if (!notes->options->use_offset)
2333 addr += notes->start;
2334
2335 if (!notes->options->use_offset) {
2336 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
2337 } else {
2338 if (al->jump_sources) {
2339 if (notes->options->show_nr_jumps) {
2340 int prev;
2341 printed = scnprintf(bf, sizeof(bf), "%*d ",
2342 notes->widths.jumps,
2343 al->jump_sources);
2344 prev = obj__set_jumps_percent_color(obj, al->jump_sources,
2345 current_entry);
2346 obj__printf(obj, bf);
2347 obj__set_color(obj, prev);
2348 }
2349
2350 printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
2351 notes->widths.target, addr);
2352 } else {
2353 printed = scnprintf(bf, sizeof(bf), "%-*s ",
2354 notes->widths.addr, " ");
2355 }
2356 }
2357
2358 if (change_color)
2359 color = obj__set_color(obj, HE_COLORSET_ADDR);
2360 obj__printf(obj, bf);
2361 if (change_color)
2362 obj__set_color(obj, color);
2363
2364 disasm_line__write(disasm_line(al), notes, obj, bf, sizeof(bf), obj__printf, obj__write_graph);
2365
2366 obj__printf(obj, "%-*s", width - pcnt_width - cycles_width - 3 - printed, bf);
2367 }
2368
2ba5eca1
ACM
2369}
2370
ecda45bd
ACM
2371int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel,
2372 struct annotation_options *options, struct arch **parch)
2373{
2374 struct annotation *notes = symbol__annotation(sym);
2375 size_t size = symbol__size(sym);
2376 int nr_pcnt = 1, err;
2377
2378 notes->offsets = zalloc(size * sizeof(struct annotation_line *));
2379 if (notes->offsets == NULL)
2380 return -1;
2381
2382 if (perf_evsel__is_group_event(evsel))
2383 nr_pcnt = evsel->nr_members;
2384
2385 err = symbol__annotate(sym, map, evsel, 0, parch);
2386 if (err)
2387 goto out_free_offsets;
2388
2389 notes->options = options;
2390
2391 symbol__calc_percent(sym, evsel);
2392
2393 notes->start = map__rip_2objdump(map, sym->start);
2394
2395 annotation__set_offsets(notes, size);
2396 annotation__mark_jump_targets(notes, sym);
2397 annotation__compute_ipc(notes, size);
2398 annotation__init_column_widths(notes, sym);
2399 notes->nr_events = nr_pcnt;
2400
2401 annotation__update_column_widths(notes);
2402
2403 return 0;
2404
2405out_free_offsets:
2406 zfree(&notes->offsets);
2407 return -1;
2408}