1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 4 * 5 * Parts came from builtin-annotate.c, see those files for further 6 * copyright notes. 7 */ 8 9 #include <errno.h> 10 #include <inttypes.h> 11 #include <libgen.h> 12 #include <stdlib.h> 13 #include "util.h" // hex_width() 14 #include "ui/ui.h" 15 #include "sort.h" 16 #include "build-id.h" 17 #include "color.h" 18 #include "config.h" 19 #include "dso.h" 20 #include "env.h" 21 #include "map.h" 22 #include "maps.h" 23 #include "symbol.h" 24 #include "srcline.h" 25 #include "units.h" 26 #include "debug.h" 27 #include "annotate.h" 28 #include "evsel.h" 29 #include "evlist.h" 30 #include "bpf-event.h" 31 #include "bpf-utils.h" 32 #include "block-range.h" 33 #include "string2.h" 34 #include "util/event.h" 35 #include "arch/common.h" 36 #include <regex.h> 37 #include <pthread.h> 38 #include <linux/bitops.h> 39 #include <linux/kernel.h> 40 #include <linux/string.h> 41 #include <subcmd/parse-options.h> 42 #include <subcmd/run-command.h> 43 44 /* FIXME: For the HE_COLORSET */ 45 #include "ui/browser.h" 46 47 /* 48 * FIXME: Using the same values as slang.h, 49 * but that header may not be available everywhere 50 */ 51 #define LARROW_CHAR ((unsigned char)',') 52 #define RARROW_CHAR ((unsigned char)'+') 53 #define DARROW_CHAR ((unsigned char)'.') 54 #define UARROW_CHAR ((unsigned char)'-') 55 56 #include <linux/ctype.h> 57 58 struct annotation_options annotation__default_options = { 59 .use_offset = true, 60 .jump_arrows = true, 61 .annotate_src = true, 62 .offset_level = ANNOTATION__OFFSET_JUMP_TARGETS, 63 .percent_type = PERCENT_PERIOD_LOCAL, 64 }; 65 66 static regex_t file_lineno; 67 68 static struct ins_ops *ins__find(struct arch *arch, const char *name); 69 static void ins__sort(struct arch *arch); 70 static int disasm_line__parse(char *line, const char **namep, char **rawp); 71 72 struct arch { 73 const char *name; 74 struct ins *instructions; 75 size_t nr_instructions; 76 size_t nr_instructions_allocated; 77 struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); 78 bool sorted_instructions; 79 bool initialized; 80 void *priv; 81 unsigned int model; 82 unsigned int family; 83 int (*init)(struct arch *arch, char *cpuid); 84 bool (*ins_is_fused)(struct arch *arch, const char *ins1, 85 const char *ins2); 86 struct { 87 char comment_char; 88 char skip_functions_char; 89 } objdump; 90 }; 91 92 static struct ins_ops call_ops; 93 static struct ins_ops dec_ops; 94 static struct ins_ops jump_ops; 95 static struct ins_ops mov_ops; 96 static struct ins_ops nop_ops; 97 static struct ins_ops lock_ops; 98 static struct ins_ops ret_ops; 99 100 static int arch__grow_instructions(struct arch *arch) 101 { 102 struct ins *new_instructions; 103 size_t new_nr_allocated; 104 105 if (arch->nr_instructions_allocated == 0 && arch->instructions) 106 goto grow_from_non_allocated_table; 107 108 new_nr_allocated = arch->nr_instructions_allocated + 128; 109 new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins)); 110 if (new_instructions == NULL) 111 return -1; 112 113 out_update_instructions: 114 arch->instructions = new_instructions; 115 arch->nr_instructions_allocated = new_nr_allocated; 116 return 0; 117 118 grow_from_non_allocated_table: 119 new_nr_allocated = arch->nr_instructions + 128; 120 new_instructions = calloc(new_nr_allocated, sizeof(struct ins)); 121 if (new_instructions == NULL) 122 return -1; 123 124 memcpy(new_instructions, arch->instructions, arch->nr_instructions); 125 goto out_update_instructions; 126 } 127 128 static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) 129 { 130 struct ins *ins; 131 132 if (arch->nr_instructions == arch->nr_instructions_allocated && 133 arch__grow_instructions(arch)) 134 return -1; 135 136 ins = &arch->instructions[arch->nr_instructions]; 137 ins->name = strdup(name); 138 if (!ins->name) 139 return -1; 140 141 ins->ops = ops; 142 arch->nr_instructions++; 143 144 ins__sort(arch); 145 return 0; 146 } 147 148 #include "arch/arc/annotate/instructions.c" 149 #include "arch/arm/annotate/instructions.c" 150 #include "arch/arm64/annotate/instructions.c" 151 #include "arch/csky/annotate/instructions.c" 152 #include "arch/mips/annotate/instructions.c" 153 #include "arch/x86/annotate/instructions.c" 154 #include "arch/powerpc/annotate/instructions.c" 155 #include "arch/s390/annotate/instructions.c" 156 #include "arch/sparc/annotate/instructions.c" 157 158 static struct arch architectures[] = { 159 { 160 .name = "arc", 161 .init = arc__annotate_init, 162 }, 163 { 164 .name = "arm", 165 .init = arm__annotate_init, 166 }, 167 { 168 .name = "arm64", 169 .init = arm64__annotate_init, 170 }, 171 { 172 .name = "csky", 173 .init = csky__annotate_init, 174 }, 175 { 176 .name = "mips", 177 .init = mips__annotate_init, 178 .objdump = { 179 .comment_char = '#', 180 }, 181 }, 182 { 183 .name = "x86", 184 .init = x86__annotate_init, 185 .instructions = x86__instructions, 186 .nr_instructions = ARRAY_SIZE(x86__instructions), 187 .ins_is_fused = x86__ins_is_fused, 188 .objdump = { 189 .comment_char = '#', 190 }, 191 }, 192 { 193 .name = "powerpc", 194 .init = powerpc__annotate_init, 195 }, 196 { 197 .name = "s390", 198 .init = s390__annotate_init, 199 .objdump = { 200 .comment_char = '#', 201 }, 202 }, 203 { 204 .name = "sparc", 205 .init = sparc__annotate_init, 206 .objdump = { 207 .comment_char = '#', 208 }, 209 }, 210 }; 211 212 static void ins__delete(struct ins_operands *ops) 213 { 214 if (ops == NULL) 215 return; 216 zfree(&ops->source.raw); 217 zfree(&ops->source.name); 218 zfree(&ops->target.raw); 219 zfree(&ops->target.name); 220 } 221 222 static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, 223 struct ins_operands *ops, int max_ins_name) 224 { 225 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); 226 } 227 228 int ins__scnprintf(struct ins *ins, char *bf, size_t size, 229 struct ins_operands *ops, int max_ins_name) 230 { 231 if (ins->ops->scnprintf) 232 return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name); 233 234 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 235 } 236 237 bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) 238 { 239 if (!arch || !arch->ins_is_fused) 240 return false; 241 242 return arch->ins_is_fused(arch, ins1, ins2); 243 } 244 245 static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 246 { 247 char *endptr, *tok, *name; 248 struct map *map = ms->map; 249 struct addr_map_symbol target = { 250 .ms = { .map = map, }, 251 }; 252 253 ops->target.addr = strtoull(ops->raw, &endptr, 16); 254 255 name = strchr(endptr, '<'); 256 if (name == NULL) 257 goto indirect_call; 258 259 name++; 260 261 if (arch->objdump.skip_functions_char && 262 strchr(name, arch->objdump.skip_functions_char)) 263 return -1; 264 265 tok = strchr(name, '>'); 266 if (tok == NULL) 267 return -1; 268 269 *tok = '\0'; 270 ops->target.name = strdup(name); 271 *tok = '>'; 272 273 if (ops->target.name == NULL) 274 return -1; 275 find_target: 276 target.addr = map__objdump_2mem(map, ops->target.addr); 277 278 if (maps__find_ams(ms->maps, &target) == 0 && 279 map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) 280 ops->target.sym = target.ms.sym; 281 282 return 0; 283 284 indirect_call: 285 tok = strchr(endptr, '*'); 286 if (tok != NULL) { 287 endptr++; 288 289 /* Indirect call can use a non-rip register and offset: callq *0x8(%rbx). 290 * Do not parse such instruction. */ 291 if (strstr(endptr, "(%r") == NULL) 292 ops->target.addr = strtoull(endptr, NULL, 16); 293 } 294 goto find_target; 295 } 296 297 static int call__scnprintf(struct ins *ins, char *bf, size_t size, 298 struct ins_operands *ops, int max_ins_name) 299 { 300 if (ops->target.sym) 301 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); 302 303 if (ops->target.addr == 0) 304 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 305 306 if (ops->target.name) 307 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.name); 308 309 return scnprintf(bf, size, "%-*s *%" PRIx64, max_ins_name, ins->name, ops->target.addr); 310 } 311 312 static struct ins_ops call_ops = { 313 .parse = call__parse, 314 .scnprintf = call__scnprintf, 315 }; 316 317 bool ins__is_call(const struct ins *ins) 318 { 319 return ins->ops == &call_ops || ins->ops == &s390_call_ops; 320 } 321 322 /* 323 * Prevents from matching commas in the comment section, e.g.: 324 * ffff200008446e70: b.cs ffff2000084470f4 <generic_exec_single+0x314> // b.hs, b.nlast 325 * 326 * and skip comma as part of function arguments, e.g.: 327 * 1d8b4ac <linemap_lookup(line_maps const*, unsigned int)+0xcc> 328 */ 329 static inline const char *validate_comma(const char *c, struct ins_operands *ops) 330 { 331 if (ops->raw_comment && c > ops->raw_comment) 332 return NULL; 333 334 if (ops->raw_func_start && c > ops->raw_func_start) 335 return NULL; 336 337 return c; 338 } 339 340 static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 341 { 342 struct map *map = ms->map; 343 struct symbol *sym = ms->sym; 344 struct addr_map_symbol target = { 345 .ms = { .map = map, }, 346 }; 347 const char *c = strchr(ops->raw, ','); 348 u64 start, end; 349 350 ops->raw_comment = strchr(ops->raw, arch->objdump.comment_char); 351 ops->raw_func_start = strchr(ops->raw, '<'); 352 353 c = validate_comma(c, ops); 354 355 /* 356 * Examples of lines to parse for the _cpp_lex_token@@Base 357 * function: 358 * 359 * 1159e6c: jne 115aa32 <_cpp_lex_token@@Base+0xf92> 360 * 1159e8b: jne c469be <cpp_named_operator2name@@Base+0xa72> 361 * 362 * The first is a jump to an offset inside the same function, 363 * the second is to another function, i.e. that 0xa72 is an 364 * offset in the cpp_named_operator2name@@base function. 365 */ 366 /* 367 * skip over possible up to 2 operands to get to address, e.g.: 368 * tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0> 369 */ 370 if (c++ != NULL) { 371 ops->target.addr = strtoull(c, NULL, 16); 372 if (!ops->target.addr) { 373 c = strchr(c, ','); 374 c = validate_comma(c, ops); 375 if (c++ != NULL) 376 ops->target.addr = strtoull(c, NULL, 16); 377 } 378 } else { 379 ops->target.addr = strtoull(ops->raw, NULL, 16); 380 } 381 382 target.addr = map__objdump_2mem(map, ops->target.addr); 383 start = map->unmap_ip(map, sym->start), 384 end = map->unmap_ip(map, sym->end); 385 386 ops->target.outside = target.addr < start || target.addr > end; 387 388 /* 389 * FIXME: things like this in _cpp_lex_token (gcc's cc1 program): 390 391 cpp_named_operator2name@@Base+0xa72 392 393 * Point to a place that is after the cpp_named_operator2name 394 * boundaries, i.e. in the ELF symbol table for cc1 395 * cpp_named_operator2name is marked as being 32-bytes long, but it in 396 * fact is much larger than that, so we seem to need a symbols__find() 397 * routine that looks for >= current->start and < next_symbol->start, 398 * possibly just for C++ objects? 399 * 400 * For now lets just make some progress by marking jumps to outside the 401 * current function as call like. 402 * 403 * Actual navigation will come next, with further understanding of how 404 * the symbol searching and disassembly should be done. 405 */ 406 if (maps__find_ams(ms->maps, &target) == 0 && 407 map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) 408 ops->target.sym = target.ms.sym; 409 410 if (!ops->target.outside) { 411 ops->target.offset = target.addr - start; 412 ops->target.offset_avail = true; 413 } else { 414 ops->target.offset_avail = false; 415 } 416 417 return 0; 418 } 419 420 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 421 struct ins_operands *ops, int max_ins_name) 422 { 423 const char *c; 424 425 if (!ops->target.addr || ops->target.offset < 0) 426 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 427 428 if (ops->target.outside && ops->target.sym != NULL) 429 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); 430 431 c = strchr(ops->raw, ','); 432 c = validate_comma(c, ops); 433 434 if (c != NULL) { 435 const char *c2 = strchr(c + 1, ','); 436 437 c2 = validate_comma(c2, ops); 438 /* check for 3-op insn */ 439 if (c2 != NULL) 440 c = c2; 441 c++; 442 443 /* mirror arch objdump's space-after-comma style */ 444 if (*c == ' ') 445 c++; 446 } 447 448 return scnprintf(bf, size, "%-*s %.*s%" PRIx64, max_ins_name, 449 ins->name, c ? c - ops->raw : 0, ops->raw, 450 ops->target.offset); 451 } 452 453 static struct ins_ops jump_ops = { 454 .parse = jump__parse, 455 .scnprintf = jump__scnprintf, 456 }; 457 458 bool ins__is_jump(const struct ins *ins) 459 { 460 return ins->ops == &jump_ops; 461 } 462 463 static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) 464 { 465 char *endptr, *name, *t; 466 467 if (strstr(raw, "(%rip)") == NULL) 468 return 0; 469 470 *addrp = strtoull(comment, &endptr, 16); 471 if (endptr == comment) 472 return 0; 473 name = strchr(endptr, '<'); 474 if (name == NULL) 475 return -1; 476 477 name++; 478 479 t = strchr(name, '>'); 480 if (t == NULL) 481 return 0; 482 483 *t = '\0'; 484 *namep = strdup(name); 485 *t = '>'; 486 487 return 0; 488 } 489 490 static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 491 { 492 ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); 493 if (ops->locked.ops == NULL) 494 return 0; 495 496 if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0) 497 goto out_free_ops; 498 499 ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name); 500 501 if (ops->locked.ins.ops == NULL) 502 goto out_free_ops; 503 504 if (ops->locked.ins.ops->parse && 505 ops->locked.ins.ops->parse(arch, ops->locked.ops, ms) < 0) 506 goto out_free_ops; 507 508 return 0; 509 510 out_free_ops: 511 zfree(&ops->locked.ops); 512 return 0; 513 } 514 515 static int lock__scnprintf(struct ins *ins, char *bf, size_t size, 516 struct ins_operands *ops, int max_ins_name) 517 { 518 int printed; 519 520 if (ops->locked.ins.ops == NULL) 521 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 522 523 printed = scnprintf(bf, size, "%-*s ", max_ins_name, ins->name); 524 return printed + ins__scnprintf(&ops->locked.ins, bf + printed, 525 size - printed, ops->locked.ops, max_ins_name); 526 } 527 528 static void lock__delete(struct ins_operands *ops) 529 { 530 struct ins *ins = &ops->locked.ins; 531 532 if (ins->ops && ins->ops->free) 533 ins->ops->free(ops->locked.ops); 534 else 535 ins__delete(ops->locked.ops); 536 537 zfree(&ops->locked.ops); 538 zfree(&ops->target.raw); 539 zfree(&ops->target.name); 540 } 541 542 static struct ins_ops lock_ops = { 543 .free = lock__delete, 544 .parse = lock__parse, 545 .scnprintf = lock__scnprintf, 546 }; 547 548 static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) 549 { 550 char *s = strchr(ops->raw, ','), *target, *comment, prev; 551 552 if (s == NULL) 553 return -1; 554 555 *s = '\0'; 556 ops->source.raw = strdup(ops->raw); 557 *s = ','; 558 559 if (ops->source.raw == NULL) 560 return -1; 561 562 target = ++s; 563 comment = strchr(s, arch->objdump.comment_char); 564 565 if (comment != NULL) 566 s = comment - 1; 567 else 568 s = strchr(s, '\0') - 1; 569 570 while (s > target && isspace(s[0])) 571 --s; 572 s++; 573 prev = *s; 574 *s = '\0'; 575 576 ops->target.raw = strdup(target); 577 *s = prev; 578 579 if (ops->target.raw == NULL) 580 goto out_free_source; 581 582 if (comment == NULL) 583 return 0; 584 585 comment = skip_spaces(comment); 586 comment__symbol(ops->source.raw, comment + 1, &ops->source.addr, &ops->source.name); 587 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); 588 589 return 0; 590 591 out_free_source: 592 zfree(&ops->source.raw); 593 return -1; 594 } 595 596 static int mov__scnprintf(struct ins *ins, char *bf, size_t size, 597 struct ins_operands *ops, int max_ins_name) 598 { 599 return scnprintf(bf, size, "%-*s %s,%s", max_ins_name, ins->name, 600 ops->source.name ?: ops->source.raw, 601 ops->target.name ?: ops->target.raw); 602 } 603 604 static struct ins_ops mov_ops = { 605 .parse = mov__parse, 606 .scnprintf = mov__scnprintf, 607 }; 608 609 static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) 610 { 611 char *target, *comment, *s, prev; 612 613 target = s = ops->raw; 614 615 while (s[0] != '\0' && !isspace(s[0])) 616 ++s; 617 prev = *s; 618 *s = '\0'; 619 620 ops->target.raw = strdup(target); 621 *s = prev; 622 623 if (ops->target.raw == NULL) 624 return -1; 625 626 comment = strchr(s, arch->objdump.comment_char); 627 if (comment == NULL) 628 return 0; 629 630 comment = skip_spaces(comment); 631 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); 632 633 return 0; 634 } 635 636 static int dec__scnprintf(struct ins *ins, char *bf, size_t size, 637 struct ins_operands *ops, int max_ins_name) 638 { 639 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, 640 ops->target.name ?: ops->target.raw); 641 } 642 643 static struct ins_ops dec_ops = { 644 .parse = dec__parse, 645 .scnprintf = dec__scnprintf, 646 }; 647 648 static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, 649 struct ins_operands *ops __maybe_unused, int max_ins_name) 650 { 651 return scnprintf(bf, size, "%-*s", max_ins_name, "nop"); 652 } 653 654 static struct ins_ops nop_ops = { 655 .scnprintf = nop__scnprintf, 656 }; 657 658 static struct ins_ops ret_ops = { 659 .scnprintf = ins__raw_scnprintf, 660 }; 661 662 bool ins__is_ret(const struct ins *ins) 663 { 664 return ins->ops == &ret_ops; 665 } 666 667 bool ins__is_lock(const struct ins *ins) 668 { 669 return ins->ops == &lock_ops; 670 } 671 672 static int ins__key_cmp(const void *name, const void *insp) 673 { 674 const struct ins *ins = insp; 675 676 return strcmp(name, ins->name); 677 } 678 679 static int ins__cmp(const void *a, const void *b) 680 { 681 const struct ins *ia = a; 682 const struct ins *ib = b; 683 684 return strcmp(ia->name, ib->name); 685 } 686 687 static void ins__sort(struct arch *arch) 688 { 689 const int nmemb = arch->nr_instructions; 690 691 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); 692 } 693 694 static struct ins_ops *__ins__find(struct arch *arch, const char *name) 695 { 696 struct ins *ins; 697 const int nmemb = arch->nr_instructions; 698 699 if (!arch->sorted_instructions) { 700 ins__sort(arch); 701 arch->sorted_instructions = true; 702 } 703 704 ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); 705 return ins ? ins->ops : NULL; 706 } 707 708 static struct ins_ops *ins__find(struct arch *arch, const char *name) 709 { 710 struct ins_ops *ops = __ins__find(arch, name); 711 712 if (!ops && arch->associate_instruction_ops) 713 ops = arch->associate_instruction_ops(arch, name); 714 715 return ops; 716 } 717 718 static int arch__key_cmp(const void *name, const void *archp) 719 { 720 const struct arch *arch = archp; 721 722 return strcmp(name, arch->name); 723 } 724 725 static int arch__cmp(const void *a, const void *b) 726 { 727 const struct arch *aa = a; 728 const struct arch *ab = b; 729 730 return strcmp(aa->name, ab->name); 731 } 732 733 static void arch__sort(void) 734 { 735 const int nmemb = ARRAY_SIZE(architectures); 736 737 qsort(architectures, nmemb, sizeof(struct arch), arch__cmp); 738 } 739 740 static struct arch *arch__find(const char *name) 741 { 742 const int nmemb = ARRAY_SIZE(architectures); 743 static bool sorted; 744 745 if (!sorted) { 746 arch__sort(); 747 sorted = true; 748 } 749 750 return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp); 751 } 752 753 static struct annotated_source *annotated_source__new(void) 754 { 755 struct annotated_source *src = zalloc(sizeof(*src)); 756 757 if (src != NULL) 758 INIT_LIST_HEAD(&src->source); 759 760 return src; 761 } 762 763 static __maybe_unused void annotated_source__delete(struct annotated_source *src) 764 { 765 if (src == NULL) 766 return; 767 zfree(&src->histograms); 768 zfree(&src->cycles_hist); 769 free(src); 770 } 771 772 static int annotated_source__alloc_histograms(struct annotated_source *src, 773 size_t size, int nr_hists) 774 { 775 size_t sizeof_sym_hist; 776 777 /* 778 * Add buffer of one element for zero length symbol. 779 * When sample is taken from first instruction of 780 * zero length symbol, perf still resolves it and 781 * shows symbol name in perf report and allows to 782 * annotate it. 783 */ 784 if (size == 0) 785 size = 1; 786 787 /* Check for overflow when calculating sizeof_sym_hist */ 788 if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) 789 return -1; 790 791 sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry)); 792 793 /* Check for overflow in zalloc argument */ 794 if (sizeof_sym_hist > SIZE_MAX / nr_hists) 795 return -1; 796 797 src->sizeof_sym_hist = sizeof_sym_hist; 798 src->nr_histograms = nr_hists; 799 src->histograms = calloc(nr_hists, sizeof_sym_hist) ; 800 return src->histograms ? 0 : -1; 801 } 802 803 /* The cycles histogram is lazily allocated. */ 804 static int symbol__alloc_hist_cycles(struct symbol *sym) 805 { 806 struct annotation *notes = symbol__annotation(sym); 807 const size_t size = symbol__size(sym); 808 809 notes->src->cycles_hist = calloc(size, sizeof(struct cyc_hist)); 810 if (notes->src->cycles_hist == NULL) 811 return -1; 812 return 0; 813 } 814 815 void symbol__annotate_zero_histograms(struct symbol *sym) 816 { 817 struct annotation *notes = symbol__annotation(sym); 818 819 pthread_mutex_lock(¬es->lock); 820 if (notes->src != NULL) { 821 memset(notes->src->histograms, 0, 822 notes->src->nr_histograms * notes->src->sizeof_sym_hist); 823 if (notes->src->cycles_hist) 824 memset(notes->src->cycles_hist, 0, 825 symbol__size(sym) * sizeof(struct cyc_hist)); 826 } 827 pthread_mutex_unlock(¬es->lock); 828 } 829 830 static int __symbol__account_cycles(struct cyc_hist *ch, 831 u64 start, 832 unsigned offset, unsigned cycles, 833 unsigned have_start) 834 { 835 /* 836 * For now we can only account one basic block per 837 * final jump. But multiple could be overlapping. 838 * Always account the longest one. So when 839 * a shorter one has been already seen throw it away. 840 * 841 * We separately always account the full cycles. 842 */ 843 ch[offset].num_aggr++; 844 ch[offset].cycles_aggr += cycles; 845 846 if (cycles > ch[offset].cycles_max) 847 ch[offset].cycles_max = cycles; 848 849 if (ch[offset].cycles_min) { 850 if (cycles && cycles < ch[offset].cycles_min) 851 ch[offset].cycles_min = cycles; 852 } else 853 ch[offset].cycles_min = cycles; 854 855 if (!have_start && ch[offset].have_start) 856 return 0; 857 if (ch[offset].num) { 858 if (have_start && (!ch[offset].have_start || 859 ch[offset].start > start)) { 860 ch[offset].have_start = 0; 861 ch[offset].cycles = 0; 862 ch[offset].num = 0; 863 if (ch[offset].reset < 0xffff) 864 ch[offset].reset++; 865 } else if (have_start && 866 ch[offset].start < start) 867 return 0; 868 } 869 870 if (ch[offset].num < NUM_SPARKS) 871 ch[offset].cycles_spark[ch[offset].num] = cycles; 872 873 ch[offset].have_start = have_start; 874 ch[offset].start = start; 875 ch[offset].cycles += cycles; 876 ch[offset].num++; 877 return 0; 878 } 879 880 static int __symbol__inc_addr_samples(struct map_symbol *ms, 881 struct annotated_source *src, int evidx, u64 addr, 882 struct perf_sample *sample) 883 { 884 struct symbol *sym = ms->sym; 885 unsigned offset; 886 struct sym_hist *h; 887 888 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr)); 889 890 if ((addr < sym->start || addr >= sym->end) && 891 (addr != sym->end || sym->start != sym->end)) { 892 pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n", 893 __func__, __LINE__, sym->name, sym->start, addr, sym->end); 894 return -ERANGE; 895 } 896 897 offset = addr - sym->start; 898 h = annotated_source__histogram(src, evidx); 899 if (h == NULL) { 900 pr_debug("%s(%d): ENOMEM! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 ", func: %d\n", 901 __func__, __LINE__, sym->name, sym->start, addr, sym->end, sym->type == STT_FUNC); 902 return -ENOMEM; 903 } 904 h->nr_samples++; 905 h->addr[offset].nr_samples++; 906 h->period += sample->period; 907 h->addr[offset].period += sample->period; 908 909 pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 910 ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", 911 sym->start, sym->name, addr, addr - sym->start, evidx, 912 h->addr[offset].nr_samples, h->addr[offset].period); 913 return 0; 914 } 915 916 static struct cyc_hist *symbol__cycles_hist(struct symbol *sym) 917 { 918 struct annotation *notes = symbol__annotation(sym); 919 920 if (notes->src == NULL) { 921 notes->src = annotated_source__new(); 922 if (notes->src == NULL) 923 return NULL; 924 goto alloc_cycles_hist; 925 } 926 927 if (!notes->src->cycles_hist) { 928 alloc_cycles_hist: 929 symbol__alloc_hist_cycles(sym); 930 } 931 932 return notes->src->cycles_hist; 933 } 934 935 struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists) 936 { 937 struct annotation *notes = symbol__annotation(sym); 938 939 if (notes->src == NULL) { 940 notes->src = annotated_source__new(); 941 if (notes->src == NULL) 942 return NULL; 943 goto alloc_histograms; 944 } 945 946 if (notes->src->histograms == NULL) { 947 alloc_histograms: 948 annotated_source__alloc_histograms(notes->src, symbol__size(sym), 949 nr_hists); 950 } 951 952 return notes->src; 953 } 954 955 static int symbol__inc_addr_samples(struct map_symbol *ms, 956 struct evsel *evsel, u64 addr, 957 struct perf_sample *sample) 958 { 959 struct symbol *sym = ms->sym; 960 struct annotated_source *src; 961 962 if (sym == NULL) 963 return 0; 964 src = symbol__hists(sym, evsel->evlist->core.nr_entries); 965 return src ? __symbol__inc_addr_samples(ms, src, evsel->core.idx, addr, sample) : 0; 966 } 967 968 static int symbol__account_cycles(u64 addr, u64 start, 969 struct symbol *sym, unsigned cycles) 970 { 971 struct cyc_hist *cycles_hist; 972 unsigned offset; 973 974 if (sym == NULL) 975 return 0; 976 cycles_hist = symbol__cycles_hist(sym); 977 if (cycles_hist == NULL) 978 return -ENOMEM; 979 if (addr < sym->start || addr >= sym->end) 980 return -ERANGE; 981 982 if (start) { 983 if (start < sym->start || start >= sym->end) 984 return -ERANGE; 985 if (start >= addr) 986 start = 0; 987 } 988 offset = addr - sym->start; 989 return __symbol__account_cycles(cycles_hist, 990 start ? start - sym->start : 0, 991 offset, cycles, 992 !!start); 993 } 994 995 int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, 996 struct addr_map_symbol *start, 997 unsigned cycles) 998 { 999 u64 saddr = 0; 1000 int err; 1001 1002 if (!cycles) 1003 return 0; 1004 1005 /* 1006 * Only set start when IPC can be computed. We can only 1007 * compute it when the basic block is completely in a single 1008 * function. 1009 * Special case the case when the jump is elsewhere, but 1010 * it starts on the function start. 1011 */ 1012 if (start && 1013 (start->ms.sym == ams->ms.sym || 1014 (ams->ms.sym && 1015 start->addr == ams->ms.sym->start + ams->ms.map->start))) 1016 saddr = start->al_addr; 1017 if (saddr == 0) 1018 pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n", 1019 ams->addr, 1020 start ? start->addr : 0, 1021 ams->ms.sym ? ams->ms.sym->start + ams->ms.map->start : 0, 1022 saddr); 1023 err = symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles); 1024 if (err) 1025 pr_debug2("account_cycles failed %d\n", err); 1026 return err; 1027 } 1028 1029 static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end) 1030 { 1031 unsigned n_insn = 0; 1032 u64 offset; 1033 1034 for (offset = start; offset <= end; offset++) { 1035 if (notes->offsets[offset]) 1036 n_insn++; 1037 } 1038 return n_insn; 1039 } 1040 1041 static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch) 1042 { 1043 unsigned n_insn; 1044 unsigned int cover_insn = 0; 1045 u64 offset; 1046 1047 n_insn = annotation__count_insn(notes, start, end); 1048 if (n_insn && ch->num && ch->cycles) { 1049 float ipc = n_insn / ((double)ch->cycles / (double)ch->num); 1050 1051 /* Hide data when there are too many overlaps. */ 1052 if (ch->reset >= 0x7fff) 1053 return; 1054 1055 for (offset = start; offset <= end; offset++) { 1056 struct annotation_line *al = notes->offsets[offset]; 1057 1058 if (al && al->ipc == 0.0) { 1059 al->ipc = ipc; 1060 cover_insn++; 1061 } 1062 } 1063 1064 if (cover_insn) { 1065 notes->hit_cycles += ch->cycles; 1066 notes->hit_insn += n_insn * ch->num; 1067 notes->cover_insn += cover_insn; 1068 } 1069 } 1070 } 1071 1072 void annotation__compute_ipc(struct annotation *notes, size_t size) 1073 { 1074 s64 offset; 1075 1076 if (!notes->src || !notes->src->cycles_hist) 1077 return; 1078 1079 notes->total_insn = annotation__count_insn(notes, 0, size - 1); 1080 notes->hit_cycles = 0; 1081 notes->hit_insn = 0; 1082 notes->cover_insn = 0; 1083 1084 pthread_mutex_lock(¬es->lock); 1085 for (offset = size - 1; offset >= 0; --offset) { 1086 struct cyc_hist *ch; 1087 1088 ch = ¬es->src->cycles_hist[offset]; 1089 if (ch && ch->cycles) { 1090 struct annotation_line *al; 1091 1092 if (ch->have_start) 1093 annotation__count_and_fill(notes, ch->start, offset, ch); 1094 al = notes->offsets[offset]; 1095 if (al && ch->num_aggr) { 1096 al->cycles = ch->cycles_aggr / ch->num_aggr; 1097 al->cycles_max = ch->cycles_max; 1098 al->cycles_min = ch->cycles_min; 1099 } 1100 notes->have_cycles = true; 1101 } 1102 } 1103 pthread_mutex_unlock(¬es->lock); 1104 } 1105 1106 int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, 1107 struct evsel *evsel) 1108 { 1109 return symbol__inc_addr_samples(&ams->ms, evsel, ams->al_addr, sample); 1110 } 1111 1112 int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, 1113 struct evsel *evsel, u64 ip) 1114 { 1115 return symbol__inc_addr_samples(&he->ms, evsel, ip, sample); 1116 } 1117 1118 static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms) 1119 { 1120 dl->ins.ops = ins__find(arch, dl->ins.name); 1121 1122 if (!dl->ins.ops) 1123 return; 1124 1125 if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, ms) < 0) 1126 dl->ins.ops = NULL; 1127 } 1128 1129 static int disasm_line__parse(char *line, const char **namep, char **rawp) 1130 { 1131 char tmp, *name = skip_spaces(line); 1132 1133 if (name[0] == '\0') 1134 return -1; 1135 1136 *rawp = name + 1; 1137 1138 while ((*rawp)[0] != '\0' && !isspace((*rawp)[0])) 1139 ++*rawp; 1140 1141 tmp = (*rawp)[0]; 1142 (*rawp)[0] = '\0'; 1143 *namep = strdup(name); 1144 1145 if (*namep == NULL) 1146 goto out; 1147 1148 (*rawp)[0] = tmp; 1149 *rawp = strim(*rawp); 1150 1151 return 0; 1152 1153 out: 1154 return -1; 1155 } 1156 1157 struct annotate_args { 1158 struct arch *arch; 1159 struct map_symbol ms; 1160 struct evsel *evsel; 1161 struct annotation_options *options; 1162 s64 offset; 1163 char *line; 1164 int line_nr; 1165 char *fileloc; 1166 }; 1167 1168 static void annotation_line__init(struct annotation_line *al, 1169 struct annotate_args *args, 1170 int nr) 1171 { 1172 al->offset = args->offset; 1173 al->line = strdup(args->line); 1174 al->line_nr = args->line_nr; 1175 al->fileloc = args->fileloc; 1176 al->data_nr = nr; 1177 } 1178 1179 static void annotation_line__exit(struct annotation_line *al) 1180 { 1181 free_srcline(al->path); 1182 zfree(&al->line); 1183 } 1184 1185 static size_t disasm_line_size(int nr) 1186 { 1187 struct annotation_line *al; 1188 1189 return (sizeof(struct disasm_line) + (sizeof(al->data[0]) * nr)); 1190 } 1191 1192 /* 1193 * Allocating the disasm annotation line data with 1194 * following structure: 1195 * 1196 * ------------------------------------------- 1197 * struct disasm_line | struct annotation_line 1198 * ------------------------------------------- 1199 * 1200 * We have 'struct annotation_line' member as last member 1201 * of 'struct disasm_line' to have an easy access. 1202 */ 1203 static struct disasm_line *disasm_line__new(struct annotate_args *args) 1204 { 1205 struct disasm_line *dl = NULL; 1206 int nr = 1; 1207 1208 if (evsel__is_group_event(args->evsel)) 1209 nr = args->evsel->core.nr_members; 1210 1211 dl = zalloc(disasm_line_size(nr)); 1212 if (!dl) 1213 return NULL; 1214 1215 annotation_line__init(&dl->al, args, nr); 1216 if (dl->al.line == NULL) 1217 goto out_delete; 1218 1219 if (args->offset != -1) { 1220 if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) 1221 goto out_free_line; 1222 1223 disasm_line__init_ins(dl, args->arch, &args->ms); 1224 } 1225 1226 return dl; 1227 1228 out_free_line: 1229 zfree(&dl->al.line); 1230 out_delete: 1231 free(dl); 1232 return NULL; 1233 } 1234 1235 void disasm_line__free(struct disasm_line *dl) 1236 { 1237 if (dl->ins.ops && dl->ins.ops->free) 1238 dl->ins.ops->free(&dl->ops); 1239 else 1240 ins__delete(&dl->ops); 1241 zfree(&dl->ins.name); 1242 annotation_line__exit(&dl->al); 1243 free(dl); 1244 } 1245 1246 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name) 1247 { 1248 if (raw || !dl->ins.ops) 1249 return scnprintf(bf, size, "%-*s %s", max_ins_name, dl->ins.name, dl->ops.raw); 1250 1251 return ins__scnprintf(&dl->ins, bf, size, &dl->ops, max_ins_name); 1252 } 1253 1254 static void annotation_line__add(struct annotation_line *al, struct list_head *head) 1255 { 1256 list_add_tail(&al->node, head); 1257 } 1258 1259 struct annotation_line * 1260 annotation_line__next(struct annotation_line *pos, struct list_head *head) 1261 { 1262 list_for_each_entry_continue(pos, head, node) 1263 if (pos->offset >= 0) 1264 return pos; 1265 1266 return NULL; 1267 } 1268 1269 static const char *annotate__address_color(struct block_range *br) 1270 { 1271 double cov = block_range__coverage(br); 1272 1273 if (cov >= 0) { 1274 /* mark red for >75% coverage */ 1275 if (cov > 0.75) 1276 return PERF_COLOR_RED; 1277 1278 /* mark dull for <1% coverage */ 1279 if (cov < 0.01) 1280 return PERF_COLOR_NORMAL; 1281 } 1282 1283 return PERF_COLOR_MAGENTA; 1284 } 1285 1286 static const char *annotate__asm_color(struct block_range *br) 1287 { 1288 double cov = block_range__coverage(br); 1289 1290 if (cov >= 0) { 1291 /* mark dull for <1% coverage */ 1292 if (cov < 0.01) 1293 return PERF_COLOR_NORMAL; 1294 } 1295 1296 return PERF_COLOR_BLUE; 1297 } 1298 1299 static void annotate__branch_printf(struct block_range *br, u64 addr) 1300 { 1301 bool emit_comment = true; 1302 1303 if (!br) 1304 return; 1305 1306 #if 1 1307 if (br->is_target && br->start == addr) { 1308 struct block_range *branch = br; 1309 double p; 1310 1311 /* 1312 * Find matching branch to our target. 1313 */ 1314 while (!branch->is_branch) 1315 branch = block_range__next(branch); 1316 1317 p = 100 *(double)br->entry / branch->coverage; 1318 1319 if (p > 0.1) { 1320 if (emit_comment) { 1321 emit_comment = false; 1322 printf("\t#"); 1323 } 1324 1325 /* 1326 * The percentage of coverage joined at this target in relation 1327 * to the next branch. 1328 */ 1329 printf(" +%.2f%%", p); 1330 } 1331 } 1332 #endif 1333 if (br->is_branch && br->end == addr) { 1334 double p = 100*(double)br->taken / br->coverage; 1335 1336 if (p > 0.1) { 1337 if (emit_comment) { 1338 emit_comment = false; 1339 printf("\t#"); 1340 } 1341 1342 /* 1343 * The percentage of coverage leaving at this branch, and 1344 * its prediction ratio. 1345 */ 1346 printf(" -%.2f%% (p:%.2f%%)", p, 100*(double)br->pred / br->taken); 1347 } 1348 } 1349 } 1350 1351 static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_width) 1352 { 1353 s64 offset = dl->al.offset; 1354 const u64 addr = start + offset; 1355 struct block_range *br; 1356 1357 br = block_range__find(addr); 1358 color_fprintf(stdout, annotate__address_color(br), " %*" PRIx64 ":", addr_fmt_width, addr); 1359 color_fprintf(stdout, annotate__asm_color(br), "%s", dl->al.line); 1360 annotate__branch_printf(br, addr); 1361 return 0; 1362 } 1363 1364 static int 1365 annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start, 1366 struct evsel *evsel, u64 len, int min_pcnt, int printed, 1367 int max_lines, struct annotation_line *queue, int addr_fmt_width, 1368 int percent_type) 1369 { 1370 struct disasm_line *dl = container_of(al, struct disasm_line, al); 1371 static const char *prev_line; 1372 1373 if (al->offset != -1) { 1374 double max_percent = 0.0; 1375 int i, nr_percent = 1; 1376 const char *color; 1377 struct annotation *notes = symbol__annotation(sym); 1378 1379 for (i = 0; i < al->data_nr; i++) { 1380 double percent; 1381 1382 percent = annotation_data__percent(&al->data[i], 1383 percent_type); 1384 1385 if (percent > max_percent) 1386 max_percent = percent; 1387 } 1388 1389 if (al->data_nr > nr_percent) 1390 nr_percent = al->data_nr; 1391 1392 if (max_percent < min_pcnt) 1393 return -1; 1394 1395 if (max_lines && printed >= max_lines) 1396 return 1; 1397 1398 if (queue != NULL) { 1399 list_for_each_entry_from(queue, ¬es->src->source, node) { 1400 if (queue == al) 1401 break; 1402 annotation_line__print(queue, sym, start, evsel, len, 1403 0, 0, 1, NULL, addr_fmt_width, 1404 percent_type); 1405 } 1406 } 1407 1408 color = get_percent_color(max_percent); 1409 1410 for (i = 0; i < nr_percent; i++) { 1411 struct annotation_data *data = &al->data[i]; 1412 double percent; 1413 1414 percent = annotation_data__percent(data, percent_type); 1415 color = get_percent_color(percent); 1416 1417 if (symbol_conf.show_total_period) 1418 color_fprintf(stdout, color, " %11" PRIu64, 1419 data->he.period); 1420 else if (symbol_conf.show_nr_samples) 1421 color_fprintf(stdout, color, " %7" PRIu64, 1422 data->he.nr_samples); 1423 else 1424 color_fprintf(stdout, color, " %7.2f", percent); 1425 } 1426 1427 printf(" : "); 1428 1429 disasm_line__print(dl, start, addr_fmt_width); 1430 1431 /* 1432 * Also color the filename and line if needed, with 1433 * the same color than the percentage. Don't print it 1434 * twice for close colored addr with the same filename:line 1435 */ 1436 if (al->path) { 1437 if (!prev_line || strcmp(prev_line, al->path)) { 1438 color_fprintf(stdout, color, " // %s", al->path); 1439 prev_line = al->path; 1440 } 1441 } 1442 1443 printf("\n"); 1444 } else if (max_lines && printed >= max_lines) 1445 return 1; 1446 else { 1447 int width = symbol_conf.show_total_period ? 12 : 8; 1448 1449 if (queue) 1450 return -1; 1451 1452 if (evsel__is_group_event(evsel)) 1453 width *= evsel->core.nr_members; 1454 1455 if (!*al->line) 1456 printf(" %*s:\n", width, " "); 1457 else 1458 printf(" %*s: %-*d %s\n", width, " ", addr_fmt_width, al->line_nr, al->line); 1459 } 1460 1461 return 0; 1462 } 1463 1464 /* 1465 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw) 1466 * which looks like following 1467 * 1468 * 0000000000415500 <_init>: 1469 * 415500: sub $0x8,%rsp 1470 * 415504: mov 0x2f5ad5(%rip),%rax # 70afe0 <_DYNAMIC+0x2f8> 1471 * 41550b: test %rax,%rax 1472 * 41550e: je 415515 <_init+0x15> 1473 * 415510: callq 416e70 <__gmon_start__@plt> 1474 * 415515: add $0x8,%rsp 1475 * 415519: retq 1476 * 1477 * it will be parsed and saved into struct disasm_line as 1478 * <offset> <name> <ops.raw> 1479 * 1480 * The offset will be a relative offset from the start of the symbol and -1 1481 * means that it's not a disassembly line so should be treated differently. 1482 * The ops.raw part will be parsed further according to type of the instruction. 1483 */ 1484 static int symbol__parse_objdump_line(struct symbol *sym, 1485 struct annotate_args *args, 1486 char *parsed_line, int *line_nr, char **fileloc) 1487 { 1488 struct map *map = args->ms.map; 1489 struct annotation *notes = symbol__annotation(sym); 1490 struct disasm_line *dl; 1491 char *tmp; 1492 s64 line_ip, offset = -1; 1493 regmatch_t match[2]; 1494 1495 /* /filename:linenr ? Save line number and ignore. */ 1496 if (regexec(&file_lineno, parsed_line, 2, match, 0) == 0) { 1497 *line_nr = atoi(parsed_line + match[1].rm_so); 1498 *fileloc = strdup(parsed_line); 1499 return 0; 1500 } 1501 1502 /* Process hex address followed by ':'. */ 1503 line_ip = strtoull(parsed_line, &tmp, 16); 1504 if (parsed_line != tmp && tmp[0] == ':' && tmp[1] != '\0') { 1505 u64 start = map__rip_2objdump(map, sym->start), 1506 end = map__rip_2objdump(map, sym->end); 1507 1508 offset = line_ip - start; 1509 if ((u64)line_ip < start || (u64)line_ip >= end) 1510 offset = -1; 1511 else 1512 parsed_line = tmp + 1; 1513 } 1514 1515 args->offset = offset; 1516 args->line = parsed_line; 1517 args->line_nr = *line_nr; 1518 args->fileloc = *fileloc; 1519 args->ms.sym = sym; 1520 1521 dl = disasm_line__new(args); 1522 (*line_nr)++; 1523 1524 if (dl == NULL) 1525 return -1; 1526 1527 if (!disasm_line__has_local_offset(dl)) { 1528 dl->ops.target.offset = dl->ops.target.addr - 1529 map__rip_2objdump(map, sym->start); 1530 dl->ops.target.offset_avail = true; 1531 } 1532 1533 /* kcore has no symbols, so add the call target symbol */ 1534 if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) { 1535 struct addr_map_symbol target = { 1536 .addr = dl->ops.target.addr, 1537 .ms = { .map = map, }, 1538 }; 1539 1540 if (!maps__find_ams(args->ms.maps, &target) && 1541 target.ms.sym->start == target.al_addr) 1542 dl->ops.target.sym = target.ms.sym; 1543 } 1544 1545 annotation_line__add(&dl->al, ¬es->src->source); 1546 1547 return 0; 1548 } 1549 1550 static __attribute__((constructor)) void symbol__init_regexpr(void) 1551 { 1552 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED); 1553 } 1554 1555 static void delete_last_nop(struct symbol *sym) 1556 { 1557 struct annotation *notes = symbol__annotation(sym); 1558 struct list_head *list = ¬es->src->source; 1559 struct disasm_line *dl; 1560 1561 while (!list_empty(list)) { 1562 dl = list_entry(list->prev, struct disasm_line, al.node); 1563 1564 if (dl->ins.ops) { 1565 if (dl->ins.ops != &nop_ops) 1566 return; 1567 } else { 1568 if (!strstr(dl->al.line, " nop ") && 1569 !strstr(dl->al.line, " nopl ") && 1570 !strstr(dl->al.line, " nopw ")) 1571 return; 1572 } 1573 1574 list_del_init(&dl->al.node); 1575 disasm_line__free(dl); 1576 } 1577 } 1578 1579 int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, size_t buflen) 1580 { 1581 struct dso *dso = ms->map->dso; 1582 1583 BUG_ON(buflen == 0); 1584 1585 if (errnum >= 0) { 1586 str_error_r(errnum, buf, buflen); 1587 return 0; 1588 } 1589 1590 switch (errnum) { 1591 case SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX: { 1592 char bf[SBUILD_ID_SIZE + 15] = " with build id "; 1593 char *build_id_msg = NULL; 1594 1595 if (dso->has_build_id) { 1596 build_id__sprintf(&dso->bid, bf + 15); 1597 build_id_msg = bf; 1598 } 1599 scnprintf(buf, buflen, 1600 "No vmlinux file%s\nwas found in the path.\n\n" 1601 "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n" 1602 "Please use:\n\n" 1603 " perf buildid-cache -vu vmlinux\n\n" 1604 "or:\n\n" 1605 " --vmlinux vmlinux\n", build_id_msg ?: ""); 1606 } 1607 break; 1608 case SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF: 1609 scnprintf(buf, buflen, "Please link with binutils's libopcode to enable BPF annotation"); 1610 break; 1611 case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP: 1612 scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions."); 1613 break; 1614 case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING: 1615 scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization."); 1616 break; 1617 case SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE: 1618 scnprintf(buf, buflen, "Invalid BPF file: %s.", dso->long_name); 1619 break; 1620 case SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF: 1621 scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.", 1622 dso->long_name); 1623 break; 1624 default: 1625 scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); 1626 break; 1627 } 1628 1629 return 0; 1630 } 1631 1632 static int dso__disassemble_filename(struct dso *dso, char *filename, size_t filename_size) 1633 { 1634 char linkname[PATH_MAX]; 1635 char *build_id_filename; 1636 char *build_id_path = NULL; 1637 char *pos; 1638 int len; 1639 1640 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 1641 !dso__is_kcore(dso)) 1642 return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; 1643 1644 build_id_filename = dso__build_id_filename(dso, NULL, 0, false); 1645 if (build_id_filename) { 1646 __symbol__join_symfs(filename, filename_size, build_id_filename); 1647 free(build_id_filename); 1648 } else { 1649 if (dso->has_build_id) 1650 return ENOMEM; 1651 goto fallback; 1652 } 1653 1654 build_id_path = strdup(filename); 1655 if (!build_id_path) 1656 return ENOMEM; 1657 1658 /* 1659 * old style build-id cache has name of XX/XXXXXXX.. while 1660 * new style has XX/XXXXXXX../{elf,kallsyms,vdso}. 1661 * extract the build-id part of dirname in the new style only. 1662 */ 1663 pos = strrchr(build_id_path, '/'); 1664 if (pos && strlen(pos) < SBUILD_ID_SIZE - 2) 1665 dirname(build_id_path); 1666 1667 if (dso__is_kcore(dso)) 1668 goto fallback; 1669 1670 len = readlink(build_id_path, linkname, sizeof(linkname) - 1); 1671 if (len < 0) 1672 goto fallback; 1673 1674 linkname[len] = '\0'; 1675 if (strstr(linkname, DSO__NAME_KALLSYMS) || 1676 access(filename, R_OK)) { 1677 fallback: 1678 /* 1679 * If we don't have build-ids or the build-id file isn't in the 1680 * cache, or is just a kallsyms file, well, lets hope that this 1681 * DSO is the same as when 'perf record' ran. 1682 */ 1683 __symbol__join_symfs(filename, filename_size, dso->long_name); 1684 } 1685 1686 free(build_id_path); 1687 return 0; 1688 } 1689 1690 #if defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) 1691 #define PACKAGE "perf" 1692 #include <bfd.h> 1693 #include <dis-asm.h> 1694 #include <bpf/bpf.h> 1695 #include <bpf/btf.h> 1696 #include <bpf/libbpf.h> 1697 #include <linux/btf.h> 1698 1699 static int symbol__disassemble_bpf(struct symbol *sym, 1700 struct annotate_args *args) 1701 { 1702 struct annotation *notes = symbol__annotation(sym); 1703 struct annotation_options *opts = args->options; 1704 struct bpf_prog_linfo *prog_linfo = NULL; 1705 struct bpf_prog_info_node *info_node; 1706 int len = sym->end - sym->start; 1707 disassembler_ftype disassemble; 1708 struct map *map = args->ms.map; 1709 struct perf_bpil *info_linear; 1710 struct disassemble_info info; 1711 struct dso *dso = map->dso; 1712 int pc = 0, count, sub_id; 1713 struct btf *btf = NULL; 1714 char tpath[PATH_MAX]; 1715 size_t buf_size; 1716 int nr_skip = 0; 1717 char *buf; 1718 bfd *bfdf; 1719 int ret; 1720 FILE *s; 1721 1722 if (dso->binary_type != DSO_BINARY_TYPE__BPF_PROG_INFO) 1723 return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE; 1724 1725 pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__, 1726 sym->name, sym->start, sym->end - sym->start); 1727 1728 memset(tpath, 0, sizeof(tpath)); 1729 perf_exe(tpath, sizeof(tpath)); 1730 1731 bfdf = bfd_openr(tpath, NULL); 1732 assert(bfdf); 1733 assert(bfd_check_format(bfdf, bfd_object)); 1734 1735 s = open_memstream(&buf, &buf_size); 1736 if (!s) { 1737 ret = errno; 1738 goto out; 1739 } 1740 init_disassemble_info(&info, s, 1741 (fprintf_ftype) fprintf); 1742 1743 info.arch = bfd_get_arch(bfdf); 1744 info.mach = bfd_get_mach(bfdf); 1745 1746 info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, 1747 dso->bpf_prog.id); 1748 if (!info_node) { 1749 ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; 1750 goto out; 1751 } 1752 info_linear = info_node->info_linear; 1753 sub_id = dso->bpf_prog.sub_id; 1754 1755 info.buffer = (void *)(uintptr_t)(info_linear->info.jited_prog_insns); 1756 info.buffer_length = info_linear->info.jited_prog_len; 1757 1758 if (info_linear->info.nr_line_info) 1759 prog_linfo = bpf_prog_linfo__new(&info_linear->info); 1760 1761 if (info_linear->info.btf_id) { 1762 struct btf_node *node; 1763 1764 node = perf_env__find_btf(dso->bpf_prog.env, 1765 info_linear->info.btf_id); 1766 if (node) 1767 btf = btf__new((__u8 *)(node->data), 1768 node->data_size); 1769 } 1770 1771 disassemble_init_for_target(&info); 1772 1773 #ifdef DISASM_FOUR_ARGS_SIGNATURE 1774 disassemble = disassembler(info.arch, 1775 bfd_big_endian(bfdf), 1776 info.mach, 1777 bfdf); 1778 #else 1779 disassemble = disassembler(bfdf); 1780 #endif 1781 assert(disassemble); 1782 1783 fflush(s); 1784 do { 1785 const struct bpf_line_info *linfo = NULL; 1786 struct disasm_line *dl; 1787 size_t prev_buf_size; 1788 const char *srcline; 1789 u64 addr; 1790 1791 addr = pc + ((u64 *)(uintptr_t)(info_linear->info.jited_ksyms))[sub_id]; 1792 count = disassemble(pc, &info); 1793 1794 if (prog_linfo) 1795 linfo = bpf_prog_linfo__lfind_addr_func(prog_linfo, 1796 addr, sub_id, 1797 nr_skip); 1798 1799 if (linfo && btf) { 1800 srcline = btf__name_by_offset(btf, linfo->line_off); 1801 nr_skip++; 1802 } else 1803 srcline = NULL; 1804 1805 fprintf(s, "\n"); 1806 prev_buf_size = buf_size; 1807 fflush(s); 1808 1809 if (!opts->hide_src_code && srcline) { 1810 args->offset = -1; 1811 args->line = strdup(srcline); 1812 args->line_nr = 0; 1813 args->fileloc = NULL; 1814 args->ms.sym = sym; 1815 dl = disasm_line__new(args); 1816 if (dl) { 1817 annotation_line__add(&dl->al, 1818 ¬es->src->source); 1819 } 1820 } 1821 1822 args->offset = pc; 1823 args->line = buf + prev_buf_size; 1824 args->line_nr = 0; 1825 args->fileloc = NULL; 1826 args->ms.sym = sym; 1827 dl = disasm_line__new(args); 1828 if (dl) 1829 annotation_line__add(&dl->al, ¬es->src->source); 1830 1831 pc += count; 1832 } while (count > 0 && pc < len); 1833 1834 ret = 0; 1835 out: 1836 free(prog_linfo); 1837 btf__free(btf); 1838 fclose(s); 1839 bfd_close(bfdf); 1840 return ret; 1841 } 1842 #else // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) 1843 static int symbol__disassemble_bpf(struct symbol *sym __maybe_unused, 1844 struct annotate_args *args __maybe_unused) 1845 { 1846 return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF; 1847 } 1848 #endif // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) 1849 1850 static int 1851 symbol__disassemble_bpf_image(struct symbol *sym, 1852 struct annotate_args *args) 1853 { 1854 struct annotation *notes = symbol__annotation(sym); 1855 struct disasm_line *dl; 1856 1857 args->offset = -1; 1858 args->line = strdup("to be implemented"); 1859 args->line_nr = 0; 1860 args->fileloc = NULL; 1861 dl = disasm_line__new(args); 1862 if (dl) 1863 annotation_line__add(&dl->al, ¬es->src->source); 1864 1865 free(args->line); 1866 return 0; 1867 } 1868 1869 /* 1870 * Possibly create a new version of line with tabs expanded. Returns the 1871 * existing or new line, storage is updated if a new line is allocated. If 1872 * allocation fails then NULL is returned. 1873 */ 1874 static char *expand_tabs(char *line, char **storage, size_t *storage_len) 1875 { 1876 size_t i, src, dst, len, new_storage_len, num_tabs; 1877 char *new_line; 1878 size_t line_len = strlen(line); 1879 1880 for (num_tabs = 0, i = 0; i < line_len; i++) 1881 if (line[i] == '\t') 1882 num_tabs++; 1883 1884 if (num_tabs == 0) 1885 return line; 1886 1887 /* 1888 * Space for the line and '\0', less the leading and trailing 1889 * spaces. Each tab may introduce 7 additional spaces. 1890 */ 1891 new_storage_len = line_len + 1 + (num_tabs * 7); 1892 1893 new_line = malloc(new_storage_len); 1894 if (new_line == NULL) { 1895 pr_err("Failure allocating memory for tab expansion\n"); 1896 return NULL; 1897 } 1898 1899 /* 1900 * Copy regions starting at src and expand tabs. If there are two 1901 * adjacent tabs then 'src == i', the memcpy is of size 0 and the spaces 1902 * are inserted. 1903 */ 1904 for (i = 0, src = 0, dst = 0; i < line_len && num_tabs; i++) { 1905 if (line[i] == '\t') { 1906 len = i - src; 1907 memcpy(&new_line[dst], &line[src], len); 1908 dst += len; 1909 new_line[dst++] = ' '; 1910 while (dst % 8 != 0) 1911 new_line[dst++] = ' '; 1912 src = i + 1; 1913 num_tabs--; 1914 } 1915 } 1916 1917 /* Expand the last region. */ 1918 len = line_len - src; 1919 memcpy(&new_line[dst], &line[src], len); 1920 dst += len; 1921 new_line[dst] = '\0'; 1922 1923 free(*storage); 1924 *storage = new_line; 1925 *storage_len = new_storage_len; 1926 return new_line; 1927 1928 } 1929 1930 static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) 1931 { 1932 struct annotation_options *opts = args->options; 1933 struct map *map = args->ms.map; 1934 struct dso *dso = map->dso; 1935 char *command; 1936 FILE *file; 1937 char symfs_filename[PATH_MAX]; 1938 struct kcore_extract kce; 1939 bool delete_extract = false; 1940 bool decomp = false; 1941 int lineno = 0; 1942 char *fileloc = NULL; 1943 int nline; 1944 char *line; 1945 size_t line_len; 1946 const char *objdump_argv[] = { 1947 "/bin/sh", 1948 "-c", 1949 NULL, /* Will be the objdump command to run. */ 1950 "--", 1951 NULL, /* Will be the symfs path. */ 1952 NULL, 1953 }; 1954 struct child_process objdump_process; 1955 int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename)); 1956 1957 if (err) 1958 return err; 1959 1960 pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, 1961 symfs_filename, sym->name, map->unmap_ip(map, sym->start), 1962 map->unmap_ip(map, sym->end)); 1963 1964 pr_debug("annotating [%p] %30s : [%p] %30s\n", 1965 dso, dso->long_name, sym, sym->name); 1966 1967 if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) { 1968 return symbol__disassemble_bpf(sym, args); 1969 } else if (dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) { 1970 return symbol__disassemble_bpf_image(sym, args); 1971 } else if (dso__is_kcore(dso)) { 1972 kce.kcore_filename = symfs_filename; 1973 kce.addr = map__rip_2objdump(map, sym->start); 1974 kce.offs = sym->start; 1975 kce.len = sym->end - sym->start; 1976 if (!kcore_extract__create(&kce)) { 1977 delete_extract = true; 1978 strlcpy(symfs_filename, kce.extract_filename, 1979 sizeof(symfs_filename)); 1980 } 1981 } else if (dso__needs_decompress(dso)) { 1982 char tmp[KMOD_DECOMP_LEN]; 1983 1984 if (dso__decompress_kmodule_path(dso, symfs_filename, 1985 tmp, sizeof(tmp)) < 0) 1986 return -1; 1987 1988 decomp = true; 1989 strcpy(symfs_filename, tmp); 1990 } 1991 1992 err = asprintf(&command, 1993 "%s %s%s --start-address=0x%016" PRIx64 1994 " --stop-address=0x%016" PRIx64 1995 " -l -d %s %s %s %c%s%c %s%s -C \"$1\"", 1996 opts->objdump_path ?: "objdump", 1997 opts->disassembler_style ? "-M " : "", 1998 opts->disassembler_style ?: "", 1999 map__rip_2objdump(map, sym->start), 2000 map__rip_2objdump(map, sym->end), 2001 opts->show_asm_raw ? "" : "--no-show-raw-insn", 2002 opts->annotate_src ? "-S" : "", 2003 opts->prefix ? "--prefix " : "", 2004 opts->prefix ? '"' : ' ', 2005 opts->prefix ?: "", 2006 opts->prefix ? '"' : ' ', 2007 opts->prefix_strip ? "--prefix-strip=" : "", 2008 opts->prefix_strip ?: ""); 2009 2010 if (err < 0) { 2011 pr_err("Failure allocating memory for the command to run\n"); 2012 goto out_remove_tmp; 2013 } 2014 2015 pr_debug("Executing: %s\n", command); 2016 2017 objdump_argv[2] = command; 2018 objdump_argv[4] = symfs_filename; 2019 2020 /* Create a pipe to read from for stdout */ 2021 memset(&objdump_process, 0, sizeof(objdump_process)); 2022 objdump_process.argv = objdump_argv; 2023 objdump_process.out = -1; 2024 if (start_command(&objdump_process)) { 2025 pr_err("Failure starting to run %s\n", command); 2026 err = -1; 2027 goto out_free_command; 2028 } 2029 2030 file = fdopen(objdump_process.out, "r"); 2031 if (!file) { 2032 pr_err("Failure creating FILE stream for %s\n", command); 2033 /* 2034 * If we were using debug info should retry with 2035 * original binary. 2036 */ 2037 err = -1; 2038 goto out_close_stdout; 2039 } 2040 2041 /* Storage for getline. */ 2042 line = NULL; 2043 line_len = 0; 2044 2045 nline = 0; 2046 while (!feof(file)) { 2047 const char *match; 2048 char *expanded_line; 2049 2050 if (getline(&line, &line_len, file) < 0 || !line) 2051 break; 2052 2053 /* Skip lines containing "filename:" */ 2054 match = strstr(line, symfs_filename); 2055 if (match && match[strlen(symfs_filename)] == ':') 2056 continue; 2057 2058 expanded_line = strim(line); 2059 expanded_line = expand_tabs(expanded_line, &line, &line_len); 2060 if (!expanded_line) 2061 break; 2062 2063 /* 2064 * The source code line number (lineno) needs to be kept in 2065 * across calls to symbol__parse_objdump_line(), so that it 2066 * can associate it with the instructions till the next one. 2067 * See disasm_line__new() and struct disasm_line::line_nr. 2068 */ 2069 if (symbol__parse_objdump_line(sym, args, expanded_line, 2070 &lineno, &fileloc) < 0) 2071 break; 2072 nline++; 2073 } 2074 free(line); 2075 2076 err = finish_command(&objdump_process); 2077 if (err) 2078 pr_err("Error running %s\n", command); 2079 2080 if (nline == 0) { 2081 err = -1; 2082 pr_err("No output from %s\n", command); 2083 } 2084 2085 /* 2086 * kallsyms does not have symbol sizes so there may a nop at the end. 2087 * Remove it. 2088 */ 2089 if (dso__is_kcore(dso)) 2090 delete_last_nop(sym); 2091 2092 fclose(file); 2093 2094 out_close_stdout: 2095 close(objdump_process.out); 2096 2097 out_free_command: 2098 free(command); 2099 2100 out_remove_tmp: 2101 if (decomp) 2102 unlink(symfs_filename); 2103 2104 if (delete_extract) 2105 kcore_extract__delete(&kce); 2106 2107 return err; 2108 } 2109 2110 static void calc_percent(struct sym_hist *sym_hist, 2111 struct hists *hists, 2112 struct annotation_data *data, 2113 s64 offset, s64 end) 2114 { 2115 unsigned int hits = 0; 2116 u64 period = 0; 2117 2118 while (offset < end) { 2119 hits += sym_hist->addr[offset].nr_samples; 2120 period += sym_hist->addr[offset].period; 2121 ++offset; 2122 } 2123 2124 if (sym_hist->nr_samples) { 2125 data->he.period = period; 2126 data->he.nr_samples = hits; 2127 data->percent[PERCENT_HITS_LOCAL] = 100.0 * hits / sym_hist->nr_samples; 2128 } 2129 2130 if (hists->stats.nr_non_filtered_samples) 2131 data->percent[PERCENT_HITS_GLOBAL] = 100.0 * hits / hists->stats.nr_non_filtered_samples; 2132 2133 if (sym_hist->period) 2134 data->percent[PERCENT_PERIOD_LOCAL] = 100.0 * period / sym_hist->period; 2135 2136 if (hists->stats.total_period) 2137 data->percent[PERCENT_PERIOD_GLOBAL] = 100.0 * period / hists->stats.total_period; 2138 } 2139 2140 static void annotation__calc_percent(struct annotation *notes, 2141 struct evsel *leader, s64 len) 2142 { 2143 struct annotation_line *al, *next; 2144 struct evsel *evsel; 2145 2146 list_for_each_entry(al, ¬es->src->source, node) { 2147 s64 end; 2148 int i = 0; 2149 2150 if (al->offset == -1) 2151 continue; 2152 2153 next = annotation_line__next(al, ¬es->src->source); 2154 end = next ? next->offset : len; 2155 2156 for_each_group_evsel(evsel, leader) { 2157 struct hists *hists = evsel__hists(evsel); 2158 struct annotation_data *data; 2159 struct sym_hist *sym_hist; 2160 2161 BUG_ON(i >= al->data_nr); 2162 2163 sym_hist = annotation__histogram(notes, evsel->core.idx); 2164 data = &al->data[i++]; 2165 2166 calc_percent(sym_hist, hists, data, al->offset, end); 2167 } 2168 } 2169 } 2170 2171 void symbol__calc_percent(struct symbol *sym, struct evsel *evsel) 2172 { 2173 struct annotation *notes = symbol__annotation(sym); 2174 2175 annotation__calc_percent(notes, evsel, symbol__size(sym)); 2176 } 2177 2178 int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, 2179 struct annotation_options *options, struct arch **parch) 2180 { 2181 struct symbol *sym = ms->sym; 2182 struct annotation *notes = symbol__annotation(sym); 2183 struct annotate_args args = { 2184 .evsel = evsel, 2185 .options = options, 2186 }; 2187 struct perf_env *env = evsel__env(evsel); 2188 const char *arch_name = perf_env__arch(env); 2189 struct arch *arch; 2190 int err; 2191 2192 if (!arch_name) 2193 return errno; 2194 2195 args.arch = arch = arch__find(arch_name); 2196 if (arch == NULL) { 2197 pr_err("%s: unsupported arch %s\n", __func__, arch_name); 2198 return ENOTSUP; 2199 } 2200 2201 if (parch) 2202 *parch = arch; 2203 2204 if (arch->init) { 2205 err = arch->init(arch, env ? env->cpuid : NULL); 2206 if (err) { 2207 pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name); 2208 return err; 2209 } 2210 } 2211 2212 args.ms = *ms; 2213 notes->start = map__rip_2objdump(ms->map, sym->start); 2214 2215 return symbol__disassemble(sym, &args); 2216 } 2217 2218 static void insert_source_line(struct rb_root *root, struct annotation_line *al, 2219 struct annotation_options *opts) 2220 { 2221 struct annotation_line *iter; 2222 struct rb_node **p = &root->rb_node; 2223 struct rb_node *parent = NULL; 2224 int i, ret; 2225 2226 while (*p != NULL) { 2227 parent = *p; 2228 iter = rb_entry(parent, struct annotation_line, rb_node); 2229 2230 ret = strcmp(iter->path, al->path); 2231 if (ret == 0) { 2232 for (i = 0; i < al->data_nr; i++) { 2233 iter->data[i].percent_sum += annotation_data__percent(&al->data[i], 2234 opts->percent_type); 2235 } 2236 return; 2237 } 2238 2239 if (ret < 0) 2240 p = &(*p)->rb_left; 2241 else 2242 p = &(*p)->rb_right; 2243 } 2244 2245 for (i = 0; i < al->data_nr; i++) { 2246 al->data[i].percent_sum = annotation_data__percent(&al->data[i], 2247 opts->percent_type); 2248 } 2249 2250 rb_link_node(&al->rb_node, parent, p); 2251 rb_insert_color(&al->rb_node, root); 2252 } 2253 2254 static int cmp_source_line(struct annotation_line *a, struct annotation_line *b) 2255 { 2256 int i; 2257 2258 for (i = 0; i < a->data_nr; i++) { 2259 if (a->data[i].percent_sum == b->data[i].percent_sum) 2260 continue; 2261 return a->data[i].percent_sum > b->data[i].percent_sum; 2262 } 2263 2264 return 0; 2265 } 2266 2267 static void __resort_source_line(struct rb_root *root, struct annotation_line *al) 2268 { 2269 struct annotation_line *iter; 2270 struct rb_node **p = &root->rb_node; 2271 struct rb_node *parent = NULL; 2272 2273 while (*p != NULL) { 2274 parent = *p; 2275 iter = rb_entry(parent, struct annotation_line, rb_node); 2276 2277 if (cmp_source_line(al, iter)) 2278 p = &(*p)->rb_left; 2279 else 2280 p = &(*p)->rb_right; 2281 } 2282 2283 rb_link_node(&al->rb_node, parent, p); 2284 rb_insert_color(&al->rb_node, root); 2285 } 2286 2287 static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root) 2288 { 2289 struct annotation_line *al; 2290 struct rb_node *node; 2291 2292 node = rb_first(src_root); 2293 while (node) { 2294 struct rb_node *next; 2295 2296 al = rb_entry(node, struct annotation_line, rb_node); 2297 next = rb_next(node); 2298 rb_erase(node, src_root); 2299 2300 __resort_source_line(dest_root, al); 2301 node = next; 2302 } 2303 } 2304 2305 static void print_summary(struct rb_root *root, const char *filename) 2306 { 2307 struct annotation_line *al; 2308 struct rb_node *node; 2309 2310 printf("\nSorted summary for file %s\n", filename); 2311 printf("----------------------------------------------\n\n"); 2312 2313 if (RB_EMPTY_ROOT(root)) { 2314 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN); 2315 return; 2316 } 2317 2318 node = rb_first(root); 2319 while (node) { 2320 double percent, percent_max = 0.0; 2321 const char *color; 2322 char *path; 2323 int i; 2324 2325 al = rb_entry(node, struct annotation_line, rb_node); 2326 for (i = 0; i < al->data_nr; i++) { 2327 percent = al->data[i].percent_sum; 2328 color = get_percent_color(percent); 2329 color_fprintf(stdout, color, " %7.2f", percent); 2330 2331 if (percent > percent_max) 2332 percent_max = percent; 2333 } 2334 2335 path = al->path; 2336 color = get_percent_color(percent_max); 2337 color_fprintf(stdout, color, " %s\n", path); 2338 2339 node = rb_next(node); 2340 } 2341 } 2342 2343 static void symbol__annotate_hits(struct symbol *sym, struct evsel *evsel) 2344 { 2345 struct annotation *notes = symbol__annotation(sym); 2346 struct sym_hist *h = annotation__histogram(notes, evsel->core.idx); 2347 u64 len = symbol__size(sym), offset; 2348 2349 for (offset = 0; offset < len; ++offset) 2350 if (h->addr[offset].nr_samples != 0) 2351 printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, 2352 sym->start + offset, h->addr[offset].nr_samples); 2353 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples); 2354 } 2355 2356 static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start) 2357 { 2358 char bf[32]; 2359 struct annotation_line *line; 2360 2361 list_for_each_entry_reverse(line, lines, node) { 2362 if (line->offset != -1) 2363 return scnprintf(bf, sizeof(bf), "%" PRIx64, start + line->offset); 2364 } 2365 2366 return 0; 2367 } 2368 2369 int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel, 2370 struct annotation_options *opts) 2371 { 2372 struct map *map = ms->map; 2373 struct symbol *sym = ms->sym; 2374 struct dso *dso = map->dso; 2375 char *filename; 2376 const char *d_filename; 2377 const char *evsel_name = evsel__name(evsel); 2378 struct annotation *notes = symbol__annotation(sym); 2379 struct sym_hist *h = annotation__histogram(notes, evsel->core.idx); 2380 struct annotation_line *pos, *queue = NULL; 2381 u64 start = map__rip_2objdump(map, sym->start); 2382 int printed = 2, queue_len = 0, addr_fmt_width; 2383 int more = 0; 2384 bool context = opts->context; 2385 u64 len; 2386 int width = symbol_conf.show_total_period ? 12 : 8; 2387 int graph_dotted_len; 2388 char buf[512]; 2389 2390 filename = strdup(dso->long_name); 2391 if (!filename) 2392 return -ENOMEM; 2393 2394 if (opts->full_path) 2395 d_filename = filename; 2396 else 2397 d_filename = basename(filename); 2398 2399 len = symbol__size(sym); 2400 2401 if (evsel__is_group_event(evsel)) { 2402 width *= evsel->core.nr_members; 2403 evsel__group_desc(evsel, buf, sizeof(buf)); 2404 evsel_name = buf; 2405 } 2406 2407 graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples, " 2408 "percent: %s)\n", 2409 width, width, symbol_conf.show_total_period ? "Period" : 2410 symbol_conf.show_nr_samples ? "Samples" : "Percent", 2411 d_filename, evsel_name, h->nr_samples, 2412 percent_type_str(opts->percent_type)); 2413 2414 printf("%-*.*s----\n", 2415 graph_dotted_len, graph_dotted_len, graph_dotted_line); 2416 2417 if (verbose > 0) 2418 symbol__annotate_hits(sym, evsel); 2419 2420 addr_fmt_width = annotated_source__addr_fmt_width(¬es->src->source, start); 2421 2422 list_for_each_entry(pos, ¬es->src->source, node) { 2423 int err; 2424 2425 if (context && queue == NULL) { 2426 queue = pos; 2427 queue_len = 0; 2428 } 2429 2430 err = annotation_line__print(pos, sym, start, evsel, len, 2431 opts->min_pcnt, printed, opts->max_lines, 2432 queue, addr_fmt_width, opts->percent_type); 2433 2434 switch (err) { 2435 case 0: 2436 ++printed; 2437 if (context) { 2438 printed += queue_len; 2439 queue = NULL; 2440 queue_len = 0; 2441 } 2442 break; 2443 case 1: 2444 /* filtered by max_lines */ 2445 ++more; 2446 break; 2447 case -1: 2448 default: 2449 /* 2450 * Filtered by min_pcnt or non IP lines when 2451 * context != 0 2452 */ 2453 if (!context) 2454 break; 2455 if (queue_len == context) 2456 queue = list_entry(queue->node.next, typeof(*queue), node); 2457 else 2458 ++queue_len; 2459 break; 2460 } 2461 } 2462 2463 free(filename); 2464 2465 return more; 2466 } 2467 2468 static void FILE__set_percent_color(void *fp __maybe_unused, 2469 double percent __maybe_unused, 2470 bool current __maybe_unused) 2471 { 2472 } 2473 2474 static int FILE__set_jumps_percent_color(void *fp __maybe_unused, 2475 int nr __maybe_unused, bool current __maybe_unused) 2476 { 2477 return 0; 2478 } 2479 2480 static int FILE__set_color(void *fp __maybe_unused, int color __maybe_unused) 2481 { 2482 return 0; 2483 } 2484 2485 static void FILE__printf(void *fp, const char *fmt, ...) 2486 { 2487 va_list args; 2488 2489 va_start(args, fmt); 2490 vfprintf(fp, fmt, args); 2491 va_end(args); 2492 } 2493 2494 static void FILE__write_graph(void *fp, int graph) 2495 { 2496 const char *s; 2497 switch (graph) { 2498 2499 case DARROW_CHAR: s = "↓"; break; 2500 case UARROW_CHAR: s = "↑"; break; 2501 case LARROW_CHAR: s = "←"; break; 2502 case RARROW_CHAR: s = "→"; break; 2503 default: s = "?"; break; 2504 } 2505 2506 fputs(s, fp); 2507 } 2508 2509 static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp, 2510 struct annotation_options *opts) 2511 { 2512 struct annotation *notes = symbol__annotation(sym); 2513 struct annotation_write_ops wops = { 2514 .first_line = true, 2515 .obj = fp, 2516 .set_color = FILE__set_color, 2517 .set_percent_color = FILE__set_percent_color, 2518 .set_jumps_percent_color = FILE__set_jumps_percent_color, 2519 .printf = FILE__printf, 2520 .write_graph = FILE__write_graph, 2521 }; 2522 struct annotation_line *al; 2523 2524 list_for_each_entry(al, ¬es->src->source, node) { 2525 if (annotation_line__filter(al, notes)) 2526 continue; 2527 annotation_line__write(al, notes, &wops, opts); 2528 fputc('\n', fp); 2529 wops.first_line = false; 2530 } 2531 2532 return 0; 2533 } 2534 2535 int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel, 2536 struct annotation_options *opts) 2537 { 2538 const char *ev_name = evsel__name(evsel); 2539 char buf[1024]; 2540 char *filename; 2541 int err = -1; 2542 FILE *fp; 2543 2544 if (asprintf(&filename, "%s.annotation", ms->sym->name) < 0) 2545 return -1; 2546 2547 fp = fopen(filename, "w"); 2548 if (fp == NULL) 2549 goto out_free_filename; 2550 2551 if (evsel__is_group_event(evsel)) { 2552 evsel__group_desc(evsel, buf, sizeof(buf)); 2553 ev_name = buf; 2554 } 2555 2556 fprintf(fp, "%s() %s\nEvent: %s\n\n", 2557 ms->sym->name, ms->map->dso->long_name, ev_name); 2558 symbol__annotate_fprintf2(ms->sym, fp, opts); 2559 2560 fclose(fp); 2561 err = 0; 2562 out_free_filename: 2563 free(filename); 2564 return err; 2565 } 2566 2567 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx) 2568 { 2569 struct annotation *notes = symbol__annotation(sym); 2570 struct sym_hist *h = annotation__histogram(notes, evidx); 2571 2572 memset(h, 0, notes->src->sizeof_sym_hist); 2573 } 2574 2575 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) 2576 { 2577 struct annotation *notes = symbol__annotation(sym); 2578 struct sym_hist *h = annotation__histogram(notes, evidx); 2579 int len = symbol__size(sym), offset; 2580 2581 h->nr_samples = 0; 2582 for (offset = 0; offset < len; ++offset) { 2583 h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8; 2584 h->nr_samples += h->addr[offset].nr_samples; 2585 } 2586 } 2587 2588 void annotated_source__purge(struct annotated_source *as) 2589 { 2590 struct annotation_line *al, *n; 2591 2592 list_for_each_entry_safe(al, n, &as->source, node) { 2593 list_del_init(&al->node); 2594 disasm_line__free(disasm_line(al)); 2595 } 2596 } 2597 2598 static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp) 2599 { 2600 size_t printed; 2601 2602 if (dl->al.offset == -1) 2603 return fprintf(fp, "%s\n", dl->al.line); 2604 2605 printed = fprintf(fp, "%#" PRIx64 " %s", dl->al.offset, dl->ins.name); 2606 2607 if (dl->ops.raw[0] != '\0') { 2608 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ", 2609 dl->ops.raw); 2610 } 2611 2612 return printed + fprintf(fp, "\n"); 2613 } 2614 2615 size_t disasm__fprintf(struct list_head *head, FILE *fp) 2616 { 2617 struct disasm_line *pos; 2618 size_t printed = 0; 2619 2620 list_for_each_entry(pos, head, al.node) 2621 printed += disasm_line__fprintf(pos, fp); 2622 2623 return printed; 2624 } 2625 2626 bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym) 2627 { 2628 if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins) || 2629 !disasm_line__has_local_offset(dl) || dl->ops.target.offset < 0 || 2630 dl->ops.target.offset >= (s64)symbol__size(sym)) 2631 return false; 2632 2633 return true; 2634 } 2635 2636 void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym) 2637 { 2638 u64 offset, size = symbol__size(sym); 2639 2640 /* PLT symbols contain external offsets */ 2641 if (strstr(sym->name, "@plt")) 2642 return; 2643 2644 for (offset = 0; offset < size; ++offset) { 2645 struct annotation_line *al = notes->offsets[offset]; 2646 struct disasm_line *dl; 2647 2648 dl = disasm_line(al); 2649 2650 if (!disasm_line__is_valid_local_jump(dl, sym)) 2651 continue; 2652 2653 al = notes->offsets[dl->ops.target.offset]; 2654 2655 /* 2656 * FIXME: Oops, no jump target? Buggy disassembler? Or do we 2657 * have to adjust to the previous offset? 2658 */ 2659 if (al == NULL) 2660 continue; 2661 2662 if (++al->jump_sources > notes->max_jump_sources) 2663 notes->max_jump_sources = al->jump_sources; 2664 } 2665 } 2666 2667 void annotation__set_offsets(struct annotation *notes, s64 size) 2668 { 2669 struct annotation_line *al; 2670 2671 notes->max_line_len = 0; 2672 notes->nr_entries = 0; 2673 notes->nr_asm_entries = 0; 2674 2675 list_for_each_entry(al, ¬es->src->source, node) { 2676 size_t line_len = strlen(al->line); 2677 2678 if (notes->max_line_len < line_len) 2679 notes->max_line_len = line_len; 2680 al->idx = notes->nr_entries++; 2681 if (al->offset != -1) { 2682 al->idx_asm = notes->nr_asm_entries++; 2683 /* 2684 * FIXME: short term bandaid to cope with assembly 2685 * routines that comes with labels in the same column 2686 * as the address in objdump, sigh. 2687 * 2688 * E.g. copy_user_generic_unrolled 2689 */ 2690 if (al->offset < size) 2691 notes->offsets[al->offset] = al; 2692 } else 2693 al->idx_asm = -1; 2694 } 2695 } 2696 2697 static inline int width_jumps(int n) 2698 { 2699 if (n >= 100) 2700 return 5; 2701 if (n / 10) 2702 return 2; 2703 return 1; 2704 } 2705 2706 static int annotation__max_ins_name(struct annotation *notes) 2707 { 2708 int max_name = 0, len; 2709 struct annotation_line *al; 2710 2711 list_for_each_entry(al, ¬es->src->source, node) { 2712 if (al->offset == -1) 2713 continue; 2714 2715 len = strlen(disasm_line(al)->ins.name); 2716 if (max_name < len) 2717 max_name = len; 2718 } 2719 2720 return max_name; 2721 } 2722 2723 void annotation__init_column_widths(struct annotation *notes, struct symbol *sym) 2724 { 2725 notes->widths.addr = notes->widths.target = 2726 notes->widths.min_addr = hex_width(symbol__size(sym)); 2727 notes->widths.max_addr = hex_width(sym->end); 2728 notes->widths.jumps = width_jumps(notes->max_jump_sources); 2729 notes->widths.max_ins_name = annotation__max_ins_name(notes); 2730 } 2731 2732 void annotation__update_column_widths(struct annotation *notes) 2733 { 2734 if (notes->options->use_offset) 2735 notes->widths.target = notes->widths.min_addr; 2736 else 2737 notes->widths.target = notes->widths.max_addr; 2738 2739 notes->widths.addr = notes->widths.target; 2740 2741 if (notes->options->show_nr_jumps) 2742 notes->widths.addr += notes->widths.jumps + 1; 2743 } 2744 2745 static void annotation__calc_lines(struct annotation *notes, struct map *map, 2746 struct rb_root *root, 2747 struct annotation_options *opts) 2748 { 2749 struct annotation_line *al; 2750 struct rb_root tmp_root = RB_ROOT; 2751 2752 list_for_each_entry(al, ¬es->src->source, node) { 2753 double percent_max = 0.0; 2754 int i; 2755 2756 for (i = 0; i < al->data_nr; i++) { 2757 double percent; 2758 2759 percent = annotation_data__percent(&al->data[i], 2760 opts->percent_type); 2761 2762 if (percent > percent_max) 2763 percent_max = percent; 2764 } 2765 2766 if (percent_max <= 0.5) 2767 continue; 2768 2769 al->path = get_srcline(map->dso, notes->start + al->offset, NULL, 2770 false, true, notes->start + al->offset); 2771 insert_source_line(&tmp_root, al, opts); 2772 } 2773 2774 resort_source_line(root, &tmp_root); 2775 } 2776 2777 static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root, 2778 struct annotation_options *opts) 2779 { 2780 struct annotation *notes = symbol__annotation(ms->sym); 2781 2782 annotation__calc_lines(notes, ms->map, root, opts); 2783 } 2784 2785 int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, 2786 struct annotation_options *opts) 2787 { 2788 struct dso *dso = ms->map->dso; 2789 struct symbol *sym = ms->sym; 2790 struct rb_root source_line = RB_ROOT; 2791 struct hists *hists = evsel__hists(evsel); 2792 char buf[1024]; 2793 int err; 2794 2795 err = symbol__annotate2(ms, evsel, opts, NULL); 2796 if (err) { 2797 char msg[BUFSIZ]; 2798 2799 dso->annotate_warned = true; 2800 symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); 2801 ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 2802 return -1; 2803 } 2804 2805 if (opts->print_lines) { 2806 srcline_full_filename = opts->full_path; 2807 symbol__calc_lines(ms, &source_line, opts); 2808 print_summary(&source_line, dso->long_name); 2809 } 2810 2811 hists__scnprintf_title(hists, buf, sizeof(buf)); 2812 fprintf(stdout, "%s, [percent: %s]\n%s() %s\n", 2813 buf, percent_type_str(opts->percent_type), sym->name, dso->long_name); 2814 symbol__annotate_fprintf2(sym, stdout, opts); 2815 2816 annotated_source__purge(symbol__annotation(sym)->src); 2817 2818 return 0; 2819 } 2820 2821 int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel, 2822 struct annotation_options *opts) 2823 { 2824 struct dso *dso = ms->map->dso; 2825 struct symbol *sym = ms->sym; 2826 struct rb_root source_line = RB_ROOT; 2827 int err; 2828 2829 err = symbol__annotate(ms, evsel, opts, NULL); 2830 if (err) { 2831 char msg[BUFSIZ]; 2832 2833 dso->annotate_warned = true; 2834 symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); 2835 ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 2836 return -1; 2837 } 2838 2839 symbol__calc_percent(sym, evsel); 2840 2841 if (opts->print_lines) { 2842 srcline_full_filename = opts->full_path; 2843 symbol__calc_lines(ms, &source_line, opts); 2844 print_summary(&source_line, dso->long_name); 2845 } 2846 2847 symbol__annotate_printf(ms, evsel, opts); 2848 2849 annotated_source__purge(symbol__annotation(sym)->src); 2850 2851 return 0; 2852 } 2853 2854 bool ui__has_annotation(void) 2855 { 2856 return use_browser == 1 && perf_hpp_list.sym; 2857 } 2858 2859 2860 static double annotation_line__max_percent(struct annotation_line *al, 2861 struct annotation *notes, 2862 unsigned int percent_type) 2863 { 2864 double percent_max = 0.0; 2865 int i; 2866 2867 for (i = 0; i < notes->nr_events; i++) { 2868 double percent; 2869 2870 percent = annotation_data__percent(&al->data[i], 2871 percent_type); 2872 2873 if (percent > percent_max) 2874 percent_max = percent; 2875 } 2876 2877 return percent_max; 2878 } 2879 2880 static void disasm_line__write(struct disasm_line *dl, struct annotation *notes, 2881 void *obj, char *bf, size_t size, 2882 void (*obj__printf)(void *obj, const char *fmt, ...), 2883 void (*obj__write_graph)(void *obj, int graph)) 2884 { 2885 if (dl->ins.ops && dl->ins.ops->scnprintf) { 2886 if (ins__is_jump(&dl->ins)) { 2887 bool fwd; 2888 2889 if (dl->ops.target.outside) 2890 goto call_like; 2891 fwd = dl->ops.target.offset > dl->al.offset; 2892 obj__write_graph(obj, fwd ? DARROW_CHAR : UARROW_CHAR); 2893 obj__printf(obj, " "); 2894 } else if (ins__is_call(&dl->ins)) { 2895 call_like: 2896 obj__write_graph(obj, RARROW_CHAR); 2897 obj__printf(obj, " "); 2898 } else if (ins__is_ret(&dl->ins)) { 2899 obj__write_graph(obj, LARROW_CHAR); 2900 obj__printf(obj, " "); 2901 } else { 2902 obj__printf(obj, " "); 2903 } 2904 } else { 2905 obj__printf(obj, " "); 2906 } 2907 2908 disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset, notes->widths.max_ins_name); 2909 } 2910 2911 static void ipc_coverage_string(char *bf, int size, struct annotation *notes) 2912 { 2913 double ipc = 0.0, coverage = 0.0; 2914 2915 if (notes->hit_cycles) 2916 ipc = notes->hit_insn / ((double)notes->hit_cycles); 2917 2918 if (notes->total_insn) { 2919 coverage = notes->cover_insn * 100.0 / 2920 ((double)notes->total_insn); 2921 } 2922 2923 scnprintf(bf, size, "(Average IPC: %.2f, IPC Coverage: %.1f%%)", 2924 ipc, coverage); 2925 } 2926 2927 static void __annotation_line__write(struct annotation_line *al, struct annotation *notes, 2928 bool first_line, bool current_entry, bool change_color, int width, 2929 void *obj, unsigned int percent_type, 2930 int (*obj__set_color)(void *obj, int color), 2931 void (*obj__set_percent_color)(void *obj, double percent, bool current), 2932 int (*obj__set_jumps_percent_color)(void *obj, int nr, bool current), 2933 void (*obj__printf)(void *obj, const char *fmt, ...), 2934 void (*obj__write_graph)(void *obj, int graph)) 2935 2936 { 2937 double percent_max = annotation_line__max_percent(al, notes, percent_type); 2938 int pcnt_width = annotation__pcnt_width(notes), 2939 cycles_width = annotation__cycles_width(notes); 2940 bool show_title = false; 2941 char bf[256]; 2942 int printed; 2943 2944 if (first_line && (al->offset == -1 || percent_max == 0.0)) { 2945 if (notes->have_cycles) { 2946 if (al->ipc == 0.0 && al->cycles == 0) 2947 show_title = true; 2948 } else 2949 show_title = true; 2950 } 2951 2952 if (al->offset != -1 && percent_max != 0.0) { 2953 int i; 2954 2955 for (i = 0; i < notes->nr_events; i++) { 2956 double percent; 2957 2958 percent = annotation_data__percent(&al->data[i], percent_type); 2959 2960 obj__set_percent_color(obj, percent, current_entry); 2961 if (symbol_conf.show_total_period) { 2962 obj__printf(obj, "%11" PRIu64 " ", al->data[i].he.period); 2963 } else if (symbol_conf.show_nr_samples) { 2964 obj__printf(obj, "%6" PRIu64 " ", 2965 al->data[i].he.nr_samples); 2966 } else { 2967 obj__printf(obj, "%6.2f ", percent); 2968 } 2969 } 2970 } else { 2971 obj__set_percent_color(obj, 0, current_entry); 2972 2973 if (!show_title) 2974 obj__printf(obj, "%-*s", pcnt_width, " "); 2975 else { 2976 obj__printf(obj, "%-*s", pcnt_width, 2977 symbol_conf.show_total_period ? "Period" : 2978 symbol_conf.show_nr_samples ? "Samples" : "Percent"); 2979 } 2980 } 2981 2982 if (notes->have_cycles) { 2983 if (al->ipc) 2984 obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->ipc); 2985 else if (!show_title) 2986 obj__printf(obj, "%*s", ANNOTATION__IPC_WIDTH, " "); 2987 else 2988 obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC"); 2989 2990 if (!notes->options->show_minmax_cycle) { 2991 if (al->cycles) 2992 obj__printf(obj, "%*" PRIu64 " ", 2993 ANNOTATION__CYCLES_WIDTH - 1, al->cycles); 2994 else if (!show_title) 2995 obj__printf(obj, "%*s", 2996 ANNOTATION__CYCLES_WIDTH, " "); 2997 else 2998 obj__printf(obj, "%*s ", 2999 ANNOTATION__CYCLES_WIDTH - 1, 3000 "Cycle"); 3001 } else { 3002 if (al->cycles) { 3003 char str[32]; 3004 3005 scnprintf(str, sizeof(str), 3006 "%" PRIu64 "(%" PRIu64 "/%" PRIu64 ")", 3007 al->cycles, al->cycles_min, 3008 al->cycles_max); 3009 3010 obj__printf(obj, "%*s ", 3011 ANNOTATION__MINMAX_CYCLES_WIDTH - 1, 3012 str); 3013 } else if (!show_title) 3014 obj__printf(obj, "%*s", 3015 ANNOTATION__MINMAX_CYCLES_WIDTH, 3016 " "); 3017 else 3018 obj__printf(obj, "%*s ", 3019 ANNOTATION__MINMAX_CYCLES_WIDTH - 1, 3020 "Cycle(min/max)"); 3021 } 3022 3023 if (show_title && !*al->line) { 3024 ipc_coverage_string(bf, sizeof(bf), notes); 3025 obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf); 3026 } 3027 } 3028 3029 obj__printf(obj, " "); 3030 3031 if (!*al->line) 3032 obj__printf(obj, "%-*s", width - pcnt_width - cycles_width, " "); 3033 else if (al->offset == -1) { 3034 if (al->line_nr && notes->options->show_linenr) 3035 printed = scnprintf(bf, sizeof(bf), "%-*d ", notes->widths.addr + 1, al->line_nr); 3036 else 3037 printed = scnprintf(bf, sizeof(bf), "%-*s ", notes->widths.addr, " "); 3038 obj__printf(obj, bf); 3039 obj__printf(obj, "%-*s", width - printed - pcnt_width - cycles_width + 1, al->line); 3040 } else { 3041 u64 addr = al->offset; 3042 int color = -1; 3043 3044 if (!notes->options->use_offset) 3045 addr += notes->start; 3046 3047 if (!notes->options->use_offset) { 3048 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); 3049 } else { 3050 if (al->jump_sources && 3051 notes->options->offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) { 3052 if (notes->options->show_nr_jumps) { 3053 int prev; 3054 printed = scnprintf(bf, sizeof(bf), "%*d ", 3055 notes->widths.jumps, 3056 al->jump_sources); 3057 prev = obj__set_jumps_percent_color(obj, al->jump_sources, 3058 current_entry); 3059 obj__printf(obj, bf); 3060 obj__set_color(obj, prev); 3061 } 3062 print_addr: 3063 printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", 3064 notes->widths.target, addr); 3065 } else if (ins__is_call(&disasm_line(al)->ins) && 3066 notes->options->offset_level >= ANNOTATION__OFFSET_CALL) { 3067 goto print_addr; 3068 } else if (notes->options->offset_level == ANNOTATION__MAX_OFFSET_LEVEL) { 3069 goto print_addr; 3070 } else { 3071 printed = scnprintf(bf, sizeof(bf), "%-*s ", 3072 notes->widths.addr, " "); 3073 } 3074 } 3075 3076 if (change_color) 3077 color = obj__set_color(obj, HE_COLORSET_ADDR); 3078 obj__printf(obj, bf); 3079 if (change_color) 3080 obj__set_color(obj, color); 3081 3082 disasm_line__write(disasm_line(al), notes, obj, bf, sizeof(bf), obj__printf, obj__write_graph); 3083 3084 obj__printf(obj, "%-*s", width - pcnt_width - cycles_width - 3 - printed, bf); 3085 } 3086 3087 } 3088 3089 void annotation_line__write(struct annotation_line *al, struct annotation *notes, 3090 struct annotation_write_ops *wops, 3091 struct annotation_options *opts) 3092 { 3093 __annotation_line__write(al, notes, wops->first_line, wops->current_entry, 3094 wops->change_color, wops->width, wops->obj, 3095 opts->percent_type, 3096 wops->set_color, wops->set_percent_color, 3097 wops->set_jumps_percent_color, wops->printf, 3098 wops->write_graph); 3099 } 3100 3101 int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel, 3102 struct annotation_options *options, struct arch **parch) 3103 { 3104 struct symbol *sym = ms->sym; 3105 struct annotation *notes = symbol__annotation(sym); 3106 size_t size = symbol__size(sym); 3107 int nr_pcnt = 1, err; 3108 3109 notes->offsets = zalloc(size * sizeof(struct annotation_line *)); 3110 if (notes->offsets == NULL) 3111 return ENOMEM; 3112 3113 if (evsel__is_group_event(evsel)) 3114 nr_pcnt = evsel->core.nr_members; 3115 3116 err = symbol__annotate(ms, evsel, options, parch); 3117 if (err) 3118 goto out_free_offsets; 3119 3120 notes->options = options; 3121 3122 symbol__calc_percent(sym, evsel); 3123 3124 annotation__set_offsets(notes, size); 3125 annotation__mark_jump_targets(notes, sym); 3126 annotation__compute_ipc(notes, size); 3127 annotation__init_column_widths(notes, sym); 3128 notes->nr_events = nr_pcnt; 3129 3130 annotation__update_column_widths(notes); 3131 sym->annotate2 = true; 3132 3133 return 0; 3134 3135 out_free_offsets: 3136 zfree(¬es->offsets); 3137 return err; 3138 } 3139 3140 static int annotation__config(const char *var, const char *value, void *data) 3141 { 3142 struct annotation_options *opt = data; 3143 3144 if (!strstarts(var, "annotate.")) 3145 return 0; 3146 3147 if (!strcmp(var, "annotate.offset_level")) { 3148 perf_config_u8(&opt->offset_level, "offset_level", value); 3149 3150 if (opt->offset_level > ANNOTATION__MAX_OFFSET_LEVEL) 3151 opt->offset_level = ANNOTATION__MAX_OFFSET_LEVEL; 3152 else if (opt->offset_level < ANNOTATION__MIN_OFFSET_LEVEL) 3153 opt->offset_level = ANNOTATION__MIN_OFFSET_LEVEL; 3154 } else if (!strcmp(var, "annotate.hide_src_code")) { 3155 opt->hide_src_code = perf_config_bool("hide_src_code", value); 3156 } else if (!strcmp(var, "annotate.jump_arrows")) { 3157 opt->jump_arrows = perf_config_bool("jump_arrows", value); 3158 } else if (!strcmp(var, "annotate.show_linenr")) { 3159 opt->show_linenr = perf_config_bool("show_linenr", value); 3160 } else if (!strcmp(var, "annotate.show_nr_jumps")) { 3161 opt->show_nr_jumps = perf_config_bool("show_nr_jumps", value); 3162 } else if (!strcmp(var, "annotate.show_nr_samples")) { 3163 symbol_conf.show_nr_samples = perf_config_bool("show_nr_samples", 3164 value); 3165 } else if (!strcmp(var, "annotate.show_total_period")) { 3166 symbol_conf.show_total_period = perf_config_bool("show_total_period", 3167 value); 3168 } else if (!strcmp(var, "annotate.use_offset")) { 3169 opt->use_offset = perf_config_bool("use_offset", value); 3170 } else if (!strcmp(var, "annotate.disassembler_style")) { 3171 opt->disassembler_style = value; 3172 } else if (!strcmp(var, "annotate.demangle")) { 3173 symbol_conf.demangle = perf_config_bool("demangle", value); 3174 } else if (!strcmp(var, "annotate.demangle_kernel")) { 3175 symbol_conf.demangle_kernel = perf_config_bool("demangle_kernel", value); 3176 } else { 3177 pr_debug("%s variable unknown, ignoring...", var); 3178 } 3179 3180 return 0; 3181 } 3182 3183 void annotation_config__init(struct annotation_options *opt) 3184 { 3185 perf_config(annotation__config, opt); 3186 } 3187 3188 static unsigned int parse_percent_type(char *str1, char *str2) 3189 { 3190 unsigned int type = (unsigned int) -1; 3191 3192 if (!strcmp("period", str1)) { 3193 if (!strcmp("local", str2)) 3194 type = PERCENT_PERIOD_LOCAL; 3195 else if (!strcmp("global", str2)) 3196 type = PERCENT_PERIOD_GLOBAL; 3197 } 3198 3199 if (!strcmp("hits", str1)) { 3200 if (!strcmp("local", str2)) 3201 type = PERCENT_HITS_LOCAL; 3202 else if (!strcmp("global", str2)) 3203 type = PERCENT_HITS_GLOBAL; 3204 } 3205 3206 return type; 3207 } 3208 3209 int annotate_parse_percent_type(const struct option *opt, const char *_str, 3210 int unset __maybe_unused) 3211 { 3212 struct annotation_options *opts = opt->value; 3213 unsigned int type; 3214 char *str1, *str2; 3215 int err = -1; 3216 3217 str1 = strdup(_str); 3218 if (!str1) 3219 return -ENOMEM; 3220 3221 str2 = strchr(str1, '-'); 3222 if (!str2) 3223 goto out; 3224 3225 *str2++ = 0; 3226 3227 type = parse_percent_type(str1, str2); 3228 if (type == (unsigned int) -1) 3229 type = parse_percent_type(str2, str1); 3230 if (type != (unsigned int) -1) { 3231 opts->percent_type = type; 3232 err = 0; 3233 } 3234 3235 out: 3236 free(str1); 3237 return err; 3238 } 3239 3240 int annotate_check_args(struct annotation_options *args) 3241 { 3242 if (args->prefix_strip && !args->prefix) { 3243 pr_err("--prefix-strip requires --prefix\n"); 3244 return -1; 3245 } 3246 return 0; 3247 } 3248