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 "annotate-data.h" 29 #include "evsel.h" 30 #include "evlist.h" 31 #include "bpf-event.h" 32 #include "bpf-utils.h" 33 #include "block-range.h" 34 #include "string2.h" 35 #include "dwarf-regs.h" 36 #include "util/event.h" 37 #include "util/sharded_mutex.h" 38 #include "arch/common.h" 39 #include "namespaces.h" 40 #include "thread.h" 41 #include "hashmap.h" 42 #include <regex.h> 43 #include <linux/bitops.h> 44 #include <linux/kernel.h> 45 #include <linux/string.h> 46 #include <linux/zalloc.h> 47 #include <subcmd/parse-options.h> 48 #include <subcmd/run-command.h> 49 50 /* FIXME: For the HE_COLORSET */ 51 #include "ui/browser.h" 52 53 /* 54 * FIXME: Using the same values as slang.h, 55 * but that header may not be available everywhere 56 */ 57 #define LARROW_CHAR ((unsigned char)',') 58 #define RARROW_CHAR ((unsigned char)'+') 59 #define DARROW_CHAR ((unsigned char)'.') 60 #define UARROW_CHAR ((unsigned char)'-') 61 62 #include <linux/ctype.h> 63 64 /* global annotation options */ 65 struct annotation_options annotate_opts; 66 67 static regex_t file_lineno; 68 69 static struct ins_ops *ins__find(struct arch *arch, const char *name); 70 static void ins__sort(struct arch *arch); 71 static int disasm_line__parse(char *line, const char **namep, char **rawp); 72 static int call__scnprintf(struct ins *ins, char *bf, size_t size, 73 struct ins_operands *ops, int max_ins_name); 74 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 75 struct ins_operands *ops, int max_ins_name); 76 77 struct arch { 78 const char *name; 79 struct ins *instructions; 80 size_t nr_instructions; 81 size_t nr_instructions_allocated; 82 struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); 83 bool sorted_instructions; 84 bool initialized; 85 const char *insn_suffix; 86 void *priv; 87 unsigned int model; 88 unsigned int family; 89 int (*init)(struct arch *arch, char *cpuid); 90 bool (*ins_is_fused)(struct arch *arch, const char *ins1, 91 const char *ins2); 92 struct { 93 char comment_char; 94 char skip_functions_char; 95 char register_char; 96 char memory_ref_char; 97 char imm_char; 98 } objdump; 99 }; 100 101 static struct ins_ops call_ops; 102 static struct ins_ops dec_ops; 103 static struct ins_ops jump_ops; 104 static struct ins_ops mov_ops; 105 static struct ins_ops nop_ops; 106 static struct ins_ops lock_ops; 107 static struct ins_ops ret_ops; 108 109 /* Data type collection debug statistics */ 110 struct annotated_data_stat ann_data_stat; 111 LIST_HEAD(ann_insn_stat); 112 113 /* Pseudo data types */ 114 struct annotated_data_type stackop_type = { 115 .self = { 116 .type_name = (char *)"(stack operation)", 117 .children = LIST_HEAD_INIT(stackop_type.self.children), 118 }, 119 }; 120 121 struct annotated_data_type canary_type = { 122 .self = { 123 .type_name = (char *)"(stack canary)", 124 .children = LIST_HEAD_INIT(canary_type.self.children), 125 }, 126 }; 127 128 static int arch__grow_instructions(struct arch *arch) 129 { 130 struct ins *new_instructions; 131 size_t new_nr_allocated; 132 133 if (arch->nr_instructions_allocated == 0 && arch->instructions) 134 goto grow_from_non_allocated_table; 135 136 new_nr_allocated = arch->nr_instructions_allocated + 128; 137 new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins)); 138 if (new_instructions == NULL) 139 return -1; 140 141 out_update_instructions: 142 arch->instructions = new_instructions; 143 arch->nr_instructions_allocated = new_nr_allocated; 144 return 0; 145 146 grow_from_non_allocated_table: 147 new_nr_allocated = arch->nr_instructions + 128; 148 new_instructions = calloc(new_nr_allocated, sizeof(struct ins)); 149 if (new_instructions == NULL) 150 return -1; 151 152 memcpy(new_instructions, arch->instructions, arch->nr_instructions); 153 goto out_update_instructions; 154 } 155 156 static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) 157 { 158 struct ins *ins; 159 160 if (arch->nr_instructions == arch->nr_instructions_allocated && 161 arch__grow_instructions(arch)) 162 return -1; 163 164 ins = &arch->instructions[arch->nr_instructions]; 165 ins->name = strdup(name); 166 if (!ins->name) 167 return -1; 168 169 ins->ops = ops; 170 arch->nr_instructions++; 171 172 ins__sort(arch); 173 return 0; 174 } 175 176 #include "arch/arc/annotate/instructions.c" 177 #include "arch/arm/annotate/instructions.c" 178 #include "arch/arm64/annotate/instructions.c" 179 #include "arch/csky/annotate/instructions.c" 180 #include "arch/loongarch/annotate/instructions.c" 181 #include "arch/mips/annotate/instructions.c" 182 #include "arch/x86/annotate/instructions.c" 183 #include "arch/powerpc/annotate/instructions.c" 184 #include "arch/riscv64/annotate/instructions.c" 185 #include "arch/s390/annotate/instructions.c" 186 #include "arch/sparc/annotate/instructions.c" 187 188 static struct arch architectures[] = { 189 { 190 .name = "arc", 191 .init = arc__annotate_init, 192 }, 193 { 194 .name = "arm", 195 .init = arm__annotate_init, 196 }, 197 { 198 .name = "arm64", 199 .init = arm64__annotate_init, 200 }, 201 { 202 .name = "csky", 203 .init = csky__annotate_init, 204 }, 205 { 206 .name = "mips", 207 .init = mips__annotate_init, 208 .objdump = { 209 .comment_char = '#', 210 }, 211 }, 212 { 213 .name = "x86", 214 .init = x86__annotate_init, 215 .instructions = x86__instructions, 216 .nr_instructions = ARRAY_SIZE(x86__instructions), 217 .insn_suffix = "bwlq", 218 .objdump = { 219 .comment_char = '#', 220 .register_char = '%', 221 .memory_ref_char = '(', 222 .imm_char = '$', 223 }, 224 }, 225 { 226 .name = "powerpc", 227 .init = powerpc__annotate_init, 228 }, 229 { 230 .name = "riscv64", 231 .init = riscv64__annotate_init, 232 }, 233 { 234 .name = "s390", 235 .init = s390__annotate_init, 236 .objdump = { 237 .comment_char = '#', 238 }, 239 }, 240 { 241 .name = "sparc", 242 .init = sparc__annotate_init, 243 .objdump = { 244 .comment_char = '#', 245 }, 246 }, 247 { 248 .name = "loongarch", 249 .init = loongarch__annotate_init, 250 .objdump = { 251 .comment_char = '#', 252 }, 253 }, 254 }; 255 256 static void ins__delete(struct ins_operands *ops) 257 { 258 if (ops == NULL) 259 return; 260 zfree(&ops->source.raw); 261 zfree(&ops->source.name); 262 zfree(&ops->target.raw); 263 zfree(&ops->target.name); 264 } 265 266 static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, 267 struct ins_operands *ops, int max_ins_name) 268 { 269 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); 270 } 271 272 int ins__scnprintf(struct ins *ins, char *bf, size_t size, 273 struct ins_operands *ops, int max_ins_name) 274 { 275 if (ins->ops->scnprintf) 276 return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name); 277 278 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 279 } 280 281 bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) 282 { 283 if (!arch || !arch->ins_is_fused) 284 return false; 285 286 return arch->ins_is_fused(arch, ins1, ins2); 287 } 288 289 static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 290 { 291 char *endptr, *tok, *name; 292 struct map *map = ms->map; 293 struct addr_map_symbol target = { 294 .ms = { .map = map, }, 295 }; 296 297 ops->target.addr = strtoull(ops->raw, &endptr, 16); 298 299 name = strchr(endptr, '<'); 300 if (name == NULL) 301 goto indirect_call; 302 303 name++; 304 305 if (arch->objdump.skip_functions_char && 306 strchr(name, arch->objdump.skip_functions_char)) 307 return -1; 308 309 tok = strchr(name, '>'); 310 if (tok == NULL) 311 return -1; 312 313 *tok = '\0'; 314 ops->target.name = strdup(name); 315 *tok = '>'; 316 317 if (ops->target.name == NULL) 318 return -1; 319 find_target: 320 target.addr = map__objdump_2mem(map, ops->target.addr); 321 322 if (maps__find_ams(ms->maps, &target) == 0 && 323 map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) 324 ops->target.sym = target.ms.sym; 325 326 return 0; 327 328 indirect_call: 329 tok = strchr(endptr, '*'); 330 if (tok != NULL) { 331 endptr++; 332 333 /* Indirect call can use a non-rip register and offset: callq *0x8(%rbx). 334 * Do not parse such instruction. */ 335 if (strstr(endptr, "(%r") == NULL) 336 ops->target.addr = strtoull(endptr, NULL, 16); 337 } 338 goto find_target; 339 } 340 341 static int call__scnprintf(struct ins *ins, char *bf, size_t size, 342 struct ins_operands *ops, int max_ins_name) 343 { 344 if (ops->target.sym) 345 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); 346 347 if (ops->target.addr == 0) 348 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 349 350 if (ops->target.name) 351 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.name); 352 353 return scnprintf(bf, size, "%-*s *%" PRIx64, max_ins_name, ins->name, ops->target.addr); 354 } 355 356 static struct ins_ops call_ops = { 357 .parse = call__parse, 358 .scnprintf = call__scnprintf, 359 }; 360 361 bool ins__is_call(const struct ins *ins) 362 { 363 return ins->ops == &call_ops || ins->ops == &s390_call_ops || ins->ops == &loongarch_call_ops; 364 } 365 366 /* 367 * Prevents from matching commas in the comment section, e.g.: 368 * ffff200008446e70: b.cs ffff2000084470f4 <generic_exec_single+0x314> // b.hs, b.nlast 369 * 370 * and skip comma as part of function arguments, e.g.: 371 * 1d8b4ac <linemap_lookup(line_maps const*, unsigned int)+0xcc> 372 */ 373 static inline const char *validate_comma(const char *c, struct ins_operands *ops) 374 { 375 if (ops->jump.raw_comment && c > ops->jump.raw_comment) 376 return NULL; 377 378 if (ops->jump.raw_func_start && c > ops->jump.raw_func_start) 379 return NULL; 380 381 return c; 382 } 383 384 static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 385 { 386 struct map *map = ms->map; 387 struct symbol *sym = ms->sym; 388 struct addr_map_symbol target = { 389 .ms = { .map = map, }, 390 }; 391 const char *c = strchr(ops->raw, ','); 392 u64 start, end; 393 394 ops->jump.raw_comment = strchr(ops->raw, arch->objdump.comment_char); 395 ops->jump.raw_func_start = strchr(ops->raw, '<'); 396 397 c = validate_comma(c, ops); 398 399 /* 400 * Examples of lines to parse for the _cpp_lex_token@@Base 401 * function: 402 * 403 * 1159e6c: jne 115aa32 <_cpp_lex_token@@Base+0xf92> 404 * 1159e8b: jne c469be <cpp_named_operator2name@@Base+0xa72> 405 * 406 * The first is a jump to an offset inside the same function, 407 * the second is to another function, i.e. that 0xa72 is an 408 * offset in the cpp_named_operator2name@@base function. 409 */ 410 /* 411 * skip over possible up to 2 operands to get to address, e.g.: 412 * tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0> 413 */ 414 if (c++ != NULL) { 415 ops->target.addr = strtoull(c, NULL, 16); 416 if (!ops->target.addr) { 417 c = strchr(c, ','); 418 c = validate_comma(c, ops); 419 if (c++ != NULL) 420 ops->target.addr = strtoull(c, NULL, 16); 421 } 422 } else { 423 ops->target.addr = strtoull(ops->raw, NULL, 16); 424 } 425 426 target.addr = map__objdump_2mem(map, ops->target.addr); 427 start = map__unmap_ip(map, sym->start); 428 end = map__unmap_ip(map, sym->end); 429 430 ops->target.outside = target.addr < start || target.addr > end; 431 432 /* 433 * FIXME: things like this in _cpp_lex_token (gcc's cc1 program): 434 435 cpp_named_operator2name@@Base+0xa72 436 437 * Point to a place that is after the cpp_named_operator2name 438 * boundaries, i.e. in the ELF symbol table for cc1 439 * cpp_named_operator2name is marked as being 32-bytes long, but it in 440 * fact is much larger than that, so we seem to need a symbols__find() 441 * routine that looks for >= current->start and < next_symbol->start, 442 * possibly just for C++ objects? 443 * 444 * For now lets just make some progress by marking jumps to outside the 445 * current function as call like. 446 * 447 * Actual navigation will come next, with further understanding of how 448 * the symbol searching and disassembly should be done. 449 */ 450 if (maps__find_ams(ms->maps, &target) == 0 && 451 map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) 452 ops->target.sym = target.ms.sym; 453 454 if (!ops->target.outside) { 455 ops->target.offset = target.addr - start; 456 ops->target.offset_avail = true; 457 } else { 458 ops->target.offset_avail = false; 459 } 460 461 return 0; 462 } 463 464 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 465 struct ins_operands *ops, int max_ins_name) 466 { 467 const char *c; 468 469 if (!ops->target.addr || ops->target.offset < 0) 470 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 471 472 if (ops->target.outside && ops->target.sym != NULL) 473 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); 474 475 c = strchr(ops->raw, ','); 476 c = validate_comma(c, ops); 477 478 if (c != NULL) { 479 const char *c2 = strchr(c + 1, ','); 480 481 c2 = validate_comma(c2, ops); 482 /* check for 3-op insn */ 483 if (c2 != NULL) 484 c = c2; 485 c++; 486 487 /* mirror arch objdump's space-after-comma style */ 488 if (*c == ' ') 489 c++; 490 } 491 492 return scnprintf(bf, size, "%-*s %.*s%" PRIx64, max_ins_name, 493 ins->name, c ? c - ops->raw : 0, ops->raw, 494 ops->target.offset); 495 } 496 497 static void jump__delete(struct ins_operands *ops __maybe_unused) 498 { 499 /* 500 * The ops->jump.raw_comment and ops->jump.raw_func_start belong to the 501 * raw string, don't free them. 502 */ 503 } 504 505 static struct ins_ops jump_ops = { 506 .free = jump__delete, 507 .parse = jump__parse, 508 .scnprintf = jump__scnprintf, 509 }; 510 511 bool ins__is_jump(const struct ins *ins) 512 { 513 return ins->ops == &jump_ops || ins->ops == &loongarch_jump_ops; 514 } 515 516 static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) 517 { 518 char *endptr, *name, *t; 519 520 if (strstr(raw, "(%rip)") == NULL) 521 return 0; 522 523 *addrp = strtoull(comment, &endptr, 16); 524 if (endptr == comment) 525 return 0; 526 name = strchr(endptr, '<'); 527 if (name == NULL) 528 return -1; 529 530 name++; 531 532 t = strchr(name, '>'); 533 if (t == NULL) 534 return 0; 535 536 *t = '\0'; 537 *namep = strdup(name); 538 *t = '>'; 539 540 return 0; 541 } 542 543 static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 544 { 545 ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); 546 if (ops->locked.ops == NULL) 547 return 0; 548 549 if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0) 550 goto out_free_ops; 551 552 ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name); 553 554 if (ops->locked.ins.ops == NULL) 555 goto out_free_ops; 556 557 if (ops->locked.ins.ops->parse && 558 ops->locked.ins.ops->parse(arch, ops->locked.ops, ms) < 0) 559 goto out_free_ops; 560 561 return 0; 562 563 out_free_ops: 564 zfree(&ops->locked.ops); 565 return 0; 566 } 567 568 static int lock__scnprintf(struct ins *ins, char *bf, size_t size, 569 struct ins_operands *ops, int max_ins_name) 570 { 571 int printed; 572 573 if (ops->locked.ins.ops == NULL) 574 return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 575 576 printed = scnprintf(bf, size, "%-*s ", max_ins_name, ins->name); 577 return printed + ins__scnprintf(&ops->locked.ins, bf + printed, 578 size - printed, ops->locked.ops, max_ins_name); 579 } 580 581 static void lock__delete(struct ins_operands *ops) 582 { 583 struct ins *ins = &ops->locked.ins; 584 585 if (ins->ops && ins->ops->free) 586 ins->ops->free(ops->locked.ops); 587 else 588 ins__delete(ops->locked.ops); 589 590 zfree(&ops->locked.ops); 591 zfree(&ops->target.raw); 592 zfree(&ops->target.name); 593 } 594 595 static struct ins_ops lock_ops = { 596 .free = lock__delete, 597 .parse = lock__parse, 598 .scnprintf = lock__scnprintf, 599 }; 600 601 /* 602 * Check if the operand has more than one registers like x86 SIB addressing: 603 * 0x1234(%rax, %rbx, 8) 604 * 605 * But it doesn't care segment selectors like %gs:0x5678(%rcx), so just check 606 * the input string after 'memory_ref_char' if exists. 607 */ 608 static bool check_multi_regs(struct arch *arch, const char *op) 609 { 610 int count = 0; 611 612 if (arch->objdump.register_char == 0) 613 return false; 614 615 if (arch->objdump.memory_ref_char) { 616 op = strchr(op, arch->objdump.memory_ref_char); 617 if (op == NULL) 618 return false; 619 } 620 621 while ((op = strchr(op, arch->objdump.register_char)) != NULL) { 622 count++; 623 op++; 624 } 625 626 return count > 1; 627 } 628 629 static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) 630 { 631 char *s = strchr(ops->raw, ','), *target, *comment, prev; 632 633 if (s == NULL) 634 return -1; 635 636 *s = '\0'; 637 638 /* 639 * x86 SIB addressing has something like 0x8(%rax, %rcx, 1) 640 * then it needs to have the closing parenthesis. 641 */ 642 if (strchr(ops->raw, '(')) { 643 *s = ','; 644 s = strchr(ops->raw, ')'); 645 if (s == NULL || s[1] != ',') 646 return -1; 647 *++s = '\0'; 648 } 649 650 ops->source.raw = strdup(ops->raw); 651 *s = ','; 652 653 if (ops->source.raw == NULL) 654 return -1; 655 656 ops->source.multi_regs = check_multi_regs(arch, ops->source.raw); 657 658 target = skip_spaces(++s); 659 comment = strchr(s, arch->objdump.comment_char); 660 661 if (comment != NULL) 662 s = comment - 1; 663 else 664 s = strchr(s, '\0') - 1; 665 666 while (s > target && isspace(s[0])) 667 --s; 668 s++; 669 prev = *s; 670 *s = '\0'; 671 672 ops->target.raw = strdup(target); 673 *s = prev; 674 675 if (ops->target.raw == NULL) 676 goto out_free_source; 677 678 ops->target.multi_regs = check_multi_regs(arch, ops->target.raw); 679 680 if (comment == NULL) 681 return 0; 682 683 comment = skip_spaces(comment); 684 comment__symbol(ops->source.raw, comment + 1, &ops->source.addr, &ops->source.name); 685 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); 686 687 return 0; 688 689 out_free_source: 690 zfree(&ops->source.raw); 691 return -1; 692 } 693 694 static int mov__scnprintf(struct ins *ins, char *bf, size_t size, 695 struct ins_operands *ops, int max_ins_name) 696 { 697 return scnprintf(bf, size, "%-*s %s,%s", max_ins_name, ins->name, 698 ops->source.name ?: ops->source.raw, 699 ops->target.name ?: ops->target.raw); 700 } 701 702 static struct ins_ops mov_ops = { 703 .parse = mov__parse, 704 .scnprintf = mov__scnprintf, 705 }; 706 707 static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) 708 { 709 char *target, *comment, *s, prev; 710 711 target = s = ops->raw; 712 713 while (s[0] != '\0' && !isspace(s[0])) 714 ++s; 715 prev = *s; 716 *s = '\0'; 717 718 ops->target.raw = strdup(target); 719 *s = prev; 720 721 if (ops->target.raw == NULL) 722 return -1; 723 724 comment = strchr(s, arch->objdump.comment_char); 725 if (comment == NULL) 726 return 0; 727 728 comment = skip_spaces(comment); 729 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); 730 731 return 0; 732 } 733 734 static int dec__scnprintf(struct ins *ins, char *bf, size_t size, 735 struct ins_operands *ops, int max_ins_name) 736 { 737 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, 738 ops->target.name ?: ops->target.raw); 739 } 740 741 static struct ins_ops dec_ops = { 742 .parse = dec__parse, 743 .scnprintf = dec__scnprintf, 744 }; 745 746 static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, 747 struct ins_operands *ops __maybe_unused, int max_ins_name) 748 { 749 return scnprintf(bf, size, "%-*s", max_ins_name, "nop"); 750 } 751 752 static struct ins_ops nop_ops = { 753 .scnprintf = nop__scnprintf, 754 }; 755 756 static struct ins_ops ret_ops = { 757 .scnprintf = ins__raw_scnprintf, 758 }; 759 760 bool ins__is_ret(const struct ins *ins) 761 { 762 return ins->ops == &ret_ops; 763 } 764 765 bool ins__is_lock(const struct ins *ins) 766 { 767 return ins->ops == &lock_ops; 768 } 769 770 static int ins__key_cmp(const void *name, const void *insp) 771 { 772 const struct ins *ins = insp; 773 774 return strcmp(name, ins->name); 775 } 776 777 static int ins__cmp(const void *a, const void *b) 778 { 779 const struct ins *ia = a; 780 const struct ins *ib = b; 781 782 return strcmp(ia->name, ib->name); 783 } 784 785 static void ins__sort(struct arch *arch) 786 { 787 const int nmemb = arch->nr_instructions; 788 789 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); 790 } 791 792 static struct ins_ops *__ins__find(struct arch *arch, const char *name) 793 { 794 struct ins *ins; 795 const int nmemb = arch->nr_instructions; 796 797 if (!arch->sorted_instructions) { 798 ins__sort(arch); 799 arch->sorted_instructions = true; 800 } 801 802 ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); 803 if (ins) 804 return ins->ops; 805 806 if (arch->insn_suffix) { 807 char tmp[32]; 808 char suffix; 809 size_t len = strlen(name); 810 811 if (len == 0 || len >= sizeof(tmp)) 812 return NULL; 813 814 suffix = name[len - 1]; 815 if (strchr(arch->insn_suffix, suffix) == NULL) 816 return NULL; 817 818 strcpy(tmp, name); 819 tmp[len - 1] = '\0'; /* remove the suffix and check again */ 820 821 ins = bsearch(tmp, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); 822 } 823 return ins ? ins->ops : NULL; 824 } 825 826 static struct ins_ops *ins__find(struct arch *arch, const char *name) 827 { 828 struct ins_ops *ops = __ins__find(arch, name); 829 830 if (!ops && arch->associate_instruction_ops) 831 ops = arch->associate_instruction_ops(arch, name); 832 833 return ops; 834 } 835 836 static int arch__key_cmp(const void *name, const void *archp) 837 { 838 const struct arch *arch = archp; 839 840 return strcmp(name, arch->name); 841 } 842 843 static int arch__cmp(const void *a, const void *b) 844 { 845 const struct arch *aa = a; 846 const struct arch *ab = b; 847 848 return strcmp(aa->name, ab->name); 849 } 850 851 static void arch__sort(void) 852 { 853 const int nmemb = ARRAY_SIZE(architectures); 854 855 qsort(architectures, nmemb, sizeof(struct arch), arch__cmp); 856 } 857 858 static struct arch *arch__find(const char *name) 859 { 860 const int nmemb = ARRAY_SIZE(architectures); 861 static bool sorted; 862 863 if (!sorted) { 864 arch__sort(); 865 sorted = true; 866 } 867 868 return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp); 869 } 870 871 bool arch__is(struct arch *arch, const char *name) 872 { 873 return !strcmp(arch->name, name); 874 } 875 876 /* symbol histogram: key = offset << 16 | evsel->core.idx */ 877 static size_t sym_hist_hash(long key, void *ctx __maybe_unused) 878 { 879 return (key >> 16) + (key & 0xffff); 880 } 881 882 static bool sym_hist_equal(long key1, long key2, void *ctx __maybe_unused) 883 { 884 return key1 == key2; 885 } 886 887 static struct annotated_source *annotated_source__new(void) 888 { 889 struct annotated_source *src = zalloc(sizeof(*src)); 890 891 if (src != NULL) 892 INIT_LIST_HEAD(&src->source); 893 894 return src; 895 } 896 897 static __maybe_unused void annotated_source__delete(struct annotated_source *src) 898 { 899 if (src == NULL) 900 return; 901 902 hashmap__free(src->samples); 903 zfree(&src->histograms); 904 free(src); 905 } 906 907 static int annotated_source__alloc_histograms(struct annotated_source *src, 908 int nr_hists) 909 { 910 src->nr_histograms = nr_hists; 911 src->histograms = calloc(nr_hists, sizeof(*src->histograms)); 912 913 if (src->histograms == NULL) 914 return -1; 915 916 src->samples = hashmap__new(sym_hist_hash, sym_hist_equal, NULL); 917 if (src->samples == NULL) 918 zfree(&src->histograms); 919 920 return src->histograms ? 0 : -1; 921 } 922 923 void symbol__annotate_zero_histograms(struct symbol *sym) 924 { 925 struct annotation *notes = symbol__annotation(sym); 926 927 annotation__lock(notes); 928 if (notes->src != NULL) { 929 memset(notes->src->histograms, 0, 930 notes->src->nr_histograms * sizeof(*notes->src->histograms)); 931 hashmap__clear(notes->src->samples); 932 } 933 if (notes->branch && notes->branch->cycles_hist) { 934 memset(notes->branch->cycles_hist, 0, 935 symbol__size(sym) * sizeof(struct cyc_hist)); 936 } 937 annotation__unlock(notes); 938 } 939 940 static int __symbol__account_cycles(struct cyc_hist *ch, 941 u64 start, 942 unsigned offset, unsigned cycles, 943 unsigned have_start) 944 { 945 /* 946 * For now we can only account one basic block per 947 * final jump. But multiple could be overlapping. 948 * Always account the longest one. So when 949 * a shorter one has been already seen throw it away. 950 * 951 * We separately always account the full cycles. 952 */ 953 ch[offset].num_aggr++; 954 ch[offset].cycles_aggr += cycles; 955 956 if (cycles > ch[offset].cycles_max) 957 ch[offset].cycles_max = cycles; 958 959 if (ch[offset].cycles_min) { 960 if (cycles && cycles < ch[offset].cycles_min) 961 ch[offset].cycles_min = cycles; 962 } else 963 ch[offset].cycles_min = cycles; 964 965 if (!have_start && ch[offset].have_start) 966 return 0; 967 if (ch[offset].num) { 968 if (have_start && (!ch[offset].have_start || 969 ch[offset].start > start)) { 970 ch[offset].have_start = 0; 971 ch[offset].cycles = 0; 972 ch[offset].num = 0; 973 if (ch[offset].reset < 0xffff) 974 ch[offset].reset++; 975 } else if (have_start && 976 ch[offset].start < start) 977 return 0; 978 } 979 980 if (ch[offset].num < NUM_SPARKS) 981 ch[offset].cycles_spark[ch[offset].num] = cycles; 982 983 ch[offset].have_start = have_start; 984 ch[offset].start = start; 985 ch[offset].cycles += cycles; 986 ch[offset].num++; 987 return 0; 988 } 989 990 static int __symbol__inc_addr_samples(struct map_symbol *ms, 991 struct annotated_source *src, int evidx, u64 addr, 992 struct perf_sample *sample) 993 { 994 struct symbol *sym = ms->sym; 995 long hash_key; 996 u64 offset; 997 struct sym_hist *h; 998 struct sym_hist_entry *entry; 999 1000 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr)); 1001 1002 if ((addr < sym->start || addr >= sym->end) && 1003 (addr != sym->end || sym->start != sym->end)) { 1004 pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n", 1005 __func__, __LINE__, sym->name, sym->start, addr, sym->end); 1006 return -ERANGE; 1007 } 1008 1009 offset = addr - sym->start; 1010 h = annotated_source__histogram(src, evidx); 1011 if (h == NULL) { 1012 pr_debug("%s(%d): ENOMEM! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 ", func: %d\n", 1013 __func__, __LINE__, sym->name, sym->start, addr, sym->end, sym->type == STT_FUNC); 1014 return -ENOMEM; 1015 } 1016 1017 hash_key = offset << 16 | evidx; 1018 if (!hashmap__find(src->samples, hash_key, &entry)) { 1019 entry = zalloc(sizeof(*entry)); 1020 if (entry == NULL) 1021 return -ENOMEM; 1022 1023 if (hashmap__add(src->samples, hash_key, entry) < 0) 1024 return -ENOMEM; 1025 } 1026 1027 h->nr_samples++; 1028 h->period += sample->period; 1029 entry->nr_samples++; 1030 entry->period += sample->period; 1031 1032 pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 1033 ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", 1034 sym->start, sym->name, addr, addr - sym->start, evidx, 1035 entry->nr_samples, entry->period); 1036 return 0; 1037 } 1038 1039 struct annotated_branch *annotation__get_branch(struct annotation *notes) 1040 { 1041 if (notes == NULL) 1042 return NULL; 1043 1044 if (notes->branch == NULL) 1045 notes->branch = zalloc(sizeof(*notes->branch)); 1046 1047 return notes->branch; 1048 } 1049 1050 static struct cyc_hist *symbol__cycles_hist(struct symbol *sym) 1051 { 1052 struct annotation *notes = symbol__annotation(sym); 1053 struct annotated_branch *branch; 1054 1055 branch = annotation__get_branch(notes); 1056 if (branch == NULL) 1057 return NULL; 1058 1059 if (branch->cycles_hist == NULL) { 1060 const size_t size = symbol__size(sym); 1061 1062 branch->cycles_hist = calloc(size, sizeof(struct cyc_hist)); 1063 } 1064 1065 return branch->cycles_hist; 1066 } 1067 1068 struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists) 1069 { 1070 struct annotation *notes = symbol__annotation(sym); 1071 1072 if (notes->src == NULL) { 1073 notes->src = annotated_source__new(); 1074 if (notes->src == NULL) 1075 return NULL; 1076 goto alloc_histograms; 1077 } 1078 1079 if (notes->src->histograms == NULL) { 1080 alloc_histograms: 1081 annotated_source__alloc_histograms(notes->src, nr_hists); 1082 } 1083 1084 return notes->src; 1085 } 1086 1087 static int symbol__inc_addr_samples(struct map_symbol *ms, 1088 struct evsel *evsel, u64 addr, 1089 struct perf_sample *sample) 1090 { 1091 struct symbol *sym = ms->sym; 1092 struct annotated_source *src; 1093 1094 if (sym == NULL) 1095 return 0; 1096 src = symbol__hists(sym, evsel->evlist->core.nr_entries); 1097 return src ? __symbol__inc_addr_samples(ms, src, evsel->core.idx, addr, sample) : 0; 1098 } 1099 1100 static int symbol__account_cycles(u64 addr, u64 start, 1101 struct symbol *sym, unsigned cycles) 1102 { 1103 struct cyc_hist *cycles_hist; 1104 unsigned offset; 1105 1106 if (sym == NULL) 1107 return 0; 1108 cycles_hist = symbol__cycles_hist(sym); 1109 if (cycles_hist == NULL) 1110 return -ENOMEM; 1111 if (addr < sym->start || addr >= sym->end) 1112 return -ERANGE; 1113 1114 if (start) { 1115 if (start < sym->start || start >= sym->end) 1116 return -ERANGE; 1117 if (start >= addr) 1118 start = 0; 1119 } 1120 offset = addr - sym->start; 1121 return __symbol__account_cycles(cycles_hist, 1122 start ? start - sym->start : 0, 1123 offset, cycles, 1124 !!start); 1125 } 1126 1127 int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, 1128 struct addr_map_symbol *start, 1129 unsigned cycles) 1130 { 1131 u64 saddr = 0; 1132 int err; 1133 1134 if (!cycles) 1135 return 0; 1136 1137 /* 1138 * Only set start when IPC can be computed. We can only 1139 * compute it when the basic block is completely in a single 1140 * function. 1141 * Special case the case when the jump is elsewhere, but 1142 * it starts on the function start. 1143 */ 1144 if (start && 1145 (start->ms.sym == ams->ms.sym || 1146 (ams->ms.sym && 1147 start->addr == ams->ms.sym->start + map__start(ams->ms.map)))) 1148 saddr = start->al_addr; 1149 if (saddr == 0) 1150 pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n", 1151 ams->addr, 1152 start ? start->addr : 0, 1153 ams->ms.sym ? ams->ms.sym->start + map__start(ams->ms.map) : 0, 1154 saddr); 1155 err = symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles); 1156 if (err) 1157 pr_debug2("account_cycles failed %d\n", err); 1158 return err; 1159 } 1160 1161 static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end) 1162 { 1163 unsigned n_insn = 0; 1164 u64 offset; 1165 1166 for (offset = start; offset <= end; offset++) { 1167 if (notes->src->offsets[offset]) 1168 n_insn++; 1169 } 1170 return n_insn; 1171 } 1172 1173 static void annotated_branch__delete(struct annotated_branch *branch) 1174 { 1175 if (branch) { 1176 zfree(&branch->cycles_hist); 1177 free(branch); 1178 } 1179 } 1180 1181 static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch) 1182 { 1183 unsigned n_insn; 1184 unsigned int cover_insn = 0; 1185 u64 offset; 1186 1187 n_insn = annotation__count_insn(notes, start, end); 1188 if (n_insn && ch->num && ch->cycles) { 1189 struct annotated_branch *branch; 1190 float ipc = n_insn / ((double)ch->cycles / (double)ch->num); 1191 1192 /* Hide data when there are too many overlaps. */ 1193 if (ch->reset >= 0x7fff) 1194 return; 1195 1196 for (offset = start; offset <= end; offset++) { 1197 struct annotation_line *al = notes->src->offsets[offset]; 1198 1199 if (al && al->cycles && al->cycles->ipc == 0.0) { 1200 al->cycles->ipc = ipc; 1201 cover_insn++; 1202 } 1203 } 1204 1205 branch = annotation__get_branch(notes); 1206 if (cover_insn && branch) { 1207 branch->hit_cycles += ch->cycles; 1208 branch->hit_insn += n_insn * ch->num; 1209 branch->cover_insn += cover_insn; 1210 } 1211 } 1212 } 1213 1214 static int annotation__compute_ipc(struct annotation *notes, size_t size) 1215 { 1216 int err = 0; 1217 s64 offset; 1218 1219 if (!notes->branch || !notes->branch->cycles_hist) 1220 return 0; 1221 1222 notes->branch->total_insn = annotation__count_insn(notes, 0, size - 1); 1223 notes->branch->hit_cycles = 0; 1224 notes->branch->hit_insn = 0; 1225 notes->branch->cover_insn = 0; 1226 1227 annotation__lock(notes); 1228 for (offset = size - 1; offset >= 0; --offset) { 1229 struct cyc_hist *ch; 1230 1231 ch = ¬es->branch->cycles_hist[offset]; 1232 if (ch && ch->cycles) { 1233 struct annotation_line *al; 1234 1235 al = notes->src->offsets[offset]; 1236 if (al && al->cycles == NULL) { 1237 al->cycles = zalloc(sizeof(*al->cycles)); 1238 if (al->cycles == NULL) { 1239 err = ENOMEM; 1240 break; 1241 } 1242 } 1243 if (ch->have_start) 1244 annotation__count_and_fill(notes, ch->start, offset, ch); 1245 if (al && ch->num_aggr) { 1246 al->cycles->avg = ch->cycles_aggr / ch->num_aggr; 1247 al->cycles->max = ch->cycles_max; 1248 al->cycles->min = ch->cycles_min; 1249 } 1250 } 1251 } 1252 1253 if (err) { 1254 while (++offset < (s64)size) { 1255 struct cyc_hist *ch = ¬es->branch->cycles_hist[offset]; 1256 1257 if (ch && ch->cycles) { 1258 struct annotation_line *al = notes->src->offsets[offset]; 1259 if (al) 1260 zfree(&al->cycles); 1261 } 1262 } 1263 } 1264 1265 annotation__unlock(notes); 1266 return 0; 1267 } 1268 1269 int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, 1270 struct evsel *evsel) 1271 { 1272 return symbol__inc_addr_samples(&ams->ms, evsel, ams->al_addr, sample); 1273 } 1274 1275 int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, 1276 struct evsel *evsel, u64 ip) 1277 { 1278 return symbol__inc_addr_samples(&he->ms, evsel, ip, sample); 1279 } 1280 1281 static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms) 1282 { 1283 dl->ins.ops = ins__find(arch, dl->ins.name); 1284 1285 if (!dl->ins.ops) 1286 return; 1287 1288 if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, ms) < 0) 1289 dl->ins.ops = NULL; 1290 } 1291 1292 static int disasm_line__parse(char *line, const char **namep, char **rawp) 1293 { 1294 char tmp, *name = skip_spaces(line); 1295 1296 if (name[0] == '\0') 1297 return -1; 1298 1299 *rawp = name + 1; 1300 1301 while ((*rawp)[0] != '\0' && !isspace((*rawp)[0])) 1302 ++*rawp; 1303 1304 tmp = (*rawp)[0]; 1305 (*rawp)[0] = '\0'; 1306 *namep = strdup(name); 1307 1308 if (*namep == NULL) 1309 goto out; 1310 1311 (*rawp)[0] = tmp; 1312 *rawp = strim(*rawp); 1313 1314 return 0; 1315 1316 out: 1317 return -1; 1318 } 1319 1320 struct annotate_args { 1321 struct arch *arch; 1322 struct map_symbol ms; 1323 struct evsel *evsel; 1324 struct annotation_options *options; 1325 s64 offset; 1326 char *line; 1327 int line_nr; 1328 char *fileloc; 1329 }; 1330 1331 static void annotation_line__init(struct annotation_line *al, 1332 struct annotate_args *args, 1333 int nr) 1334 { 1335 al->offset = args->offset; 1336 al->line = strdup(args->line); 1337 al->line_nr = args->line_nr; 1338 al->fileloc = args->fileloc; 1339 al->data_nr = nr; 1340 } 1341 1342 static void annotation_line__exit(struct annotation_line *al) 1343 { 1344 zfree_srcline(&al->path); 1345 zfree(&al->line); 1346 zfree(&al->cycles); 1347 } 1348 1349 static size_t disasm_line_size(int nr) 1350 { 1351 struct annotation_line *al; 1352 1353 return (sizeof(struct disasm_line) + (sizeof(al->data[0]) * nr)); 1354 } 1355 1356 /* 1357 * Allocating the disasm annotation line data with 1358 * following structure: 1359 * 1360 * ------------------------------------------- 1361 * struct disasm_line | struct annotation_line 1362 * ------------------------------------------- 1363 * 1364 * We have 'struct annotation_line' member as last member 1365 * of 'struct disasm_line' to have an easy access. 1366 */ 1367 static struct disasm_line *disasm_line__new(struct annotate_args *args) 1368 { 1369 struct disasm_line *dl = NULL; 1370 int nr = 1; 1371 1372 if (evsel__is_group_event(args->evsel)) 1373 nr = args->evsel->core.nr_members; 1374 1375 dl = zalloc(disasm_line_size(nr)); 1376 if (!dl) 1377 return NULL; 1378 1379 annotation_line__init(&dl->al, args, nr); 1380 if (dl->al.line == NULL) 1381 goto out_delete; 1382 1383 if (args->offset != -1) { 1384 if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) 1385 goto out_free_line; 1386 1387 disasm_line__init_ins(dl, args->arch, &args->ms); 1388 } 1389 1390 return dl; 1391 1392 out_free_line: 1393 zfree(&dl->al.line); 1394 out_delete: 1395 free(dl); 1396 return NULL; 1397 } 1398 1399 void disasm_line__free(struct disasm_line *dl) 1400 { 1401 if (dl->ins.ops && dl->ins.ops->free) 1402 dl->ins.ops->free(&dl->ops); 1403 else 1404 ins__delete(&dl->ops); 1405 zfree(&dl->ins.name); 1406 annotation_line__exit(&dl->al); 1407 free(dl); 1408 } 1409 1410 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name) 1411 { 1412 if (raw || !dl->ins.ops) 1413 return scnprintf(bf, size, "%-*s %s", max_ins_name, dl->ins.name, dl->ops.raw); 1414 1415 return ins__scnprintf(&dl->ins, bf, size, &dl->ops, max_ins_name); 1416 } 1417 1418 void annotation__exit(struct annotation *notes) 1419 { 1420 annotated_source__delete(notes->src); 1421 annotated_branch__delete(notes->branch); 1422 } 1423 1424 static struct sharded_mutex *sharded_mutex; 1425 1426 static void annotation__init_sharded_mutex(void) 1427 { 1428 /* As many mutexes as there are CPUs. */ 1429 sharded_mutex = sharded_mutex__new(cpu__max_present_cpu().cpu); 1430 } 1431 1432 static size_t annotation__hash(const struct annotation *notes) 1433 { 1434 return (size_t)notes; 1435 } 1436 1437 static struct mutex *annotation__get_mutex(const struct annotation *notes) 1438 { 1439 static pthread_once_t once = PTHREAD_ONCE_INIT; 1440 1441 pthread_once(&once, annotation__init_sharded_mutex); 1442 if (!sharded_mutex) 1443 return NULL; 1444 1445 return sharded_mutex__get_mutex(sharded_mutex, annotation__hash(notes)); 1446 } 1447 1448 void annotation__lock(struct annotation *notes) 1449 NO_THREAD_SAFETY_ANALYSIS 1450 { 1451 struct mutex *mutex = annotation__get_mutex(notes); 1452 1453 if (mutex) 1454 mutex_lock(mutex); 1455 } 1456 1457 void annotation__unlock(struct annotation *notes) 1458 NO_THREAD_SAFETY_ANALYSIS 1459 { 1460 struct mutex *mutex = annotation__get_mutex(notes); 1461 1462 if (mutex) 1463 mutex_unlock(mutex); 1464 } 1465 1466 bool annotation__trylock(struct annotation *notes) 1467 { 1468 struct mutex *mutex = annotation__get_mutex(notes); 1469 1470 if (!mutex) 1471 return false; 1472 1473 return mutex_trylock(mutex); 1474 } 1475 1476 1477 static void annotation_line__add(struct annotation_line *al, struct list_head *head) 1478 { 1479 list_add_tail(&al->node, head); 1480 } 1481 1482 struct annotation_line * 1483 annotation_line__next(struct annotation_line *pos, struct list_head *head) 1484 { 1485 list_for_each_entry_continue(pos, head, node) 1486 if (pos->offset >= 0) 1487 return pos; 1488 1489 return NULL; 1490 } 1491 1492 static const char *annotate__address_color(struct block_range *br) 1493 { 1494 double cov = block_range__coverage(br); 1495 1496 if (cov >= 0) { 1497 /* mark red for >75% coverage */ 1498 if (cov > 0.75) 1499 return PERF_COLOR_RED; 1500 1501 /* mark dull for <1% coverage */ 1502 if (cov < 0.01) 1503 return PERF_COLOR_NORMAL; 1504 } 1505 1506 return PERF_COLOR_MAGENTA; 1507 } 1508 1509 static const char *annotate__asm_color(struct block_range *br) 1510 { 1511 double cov = block_range__coverage(br); 1512 1513 if (cov >= 0) { 1514 /* mark dull for <1% coverage */ 1515 if (cov < 0.01) 1516 return PERF_COLOR_NORMAL; 1517 } 1518 1519 return PERF_COLOR_BLUE; 1520 } 1521 1522 static void annotate__branch_printf(struct block_range *br, u64 addr) 1523 { 1524 bool emit_comment = true; 1525 1526 if (!br) 1527 return; 1528 1529 #if 1 1530 if (br->is_target && br->start == addr) { 1531 struct block_range *branch = br; 1532 double p; 1533 1534 /* 1535 * Find matching branch to our target. 1536 */ 1537 while (!branch->is_branch) 1538 branch = block_range__next(branch); 1539 1540 p = 100 *(double)br->entry / branch->coverage; 1541 1542 if (p > 0.1) { 1543 if (emit_comment) { 1544 emit_comment = false; 1545 printf("\t#"); 1546 } 1547 1548 /* 1549 * The percentage of coverage joined at this target in relation 1550 * to the next branch. 1551 */ 1552 printf(" +%.2f%%", p); 1553 } 1554 } 1555 #endif 1556 if (br->is_branch && br->end == addr) { 1557 double p = 100*(double)br->taken / br->coverage; 1558 1559 if (p > 0.1) { 1560 if (emit_comment) { 1561 emit_comment = false; 1562 printf("\t#"); 1563 } 1564 1565 /* 1566 * The percentage of coverage leaving at this branch, and 1567 * its prediction ratio. 1568 */ 1569 printf(" -%.2f%% (p:%.2f%%)", p, 100*(double)br->pred / br->taken); 1570 } 1571 } 1572 } 1573 1574 static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_width) 1575 { 1576 s64 offset = dl->al.offset; 1577 const u64 addr = start + offset; 1578 struct block_range *br; 1579 1580 br = block_range__find(addr); 1581 color_fprintf(stdout, annotate__address_color(br), " %*" PRIx64 ":", addr_fmt_width, addr); 1582 color_fprintf(stdout, annotate__asm_color(br), "%s", dl->al.line); 1583 annotate__branch_printf(br, addr); 1584 return 0; 1585 } 1586 1587 static int 1588 annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start, 1589 struct evsel *evsel, u64 len, int min_pcnt, int printed, 1590 int max_lines, struct annotation_line *queue, int addr_fmt_width, 1591 int percent_type) 1592 { 1593 struct disasm_line *dl = container_of(al, struct disasm_line, al); 1594 static const char *prev_line; 1595 1596 if (al->offset != -1) { 1597 double max_percent = 0.0; 1598 int i, nr_percent = 1; 1599 const char *color; 1600 struct annotation *notes = symbol__annotation(sym); 1601 1602 for (i = 0; i < al->data_nr; i++) { 1603 double percent; 1604 1605 percent = annotation_data__percent(&al->data[i], 1606 percent_type); 1607 1608 if (percent > max_percent) 1609 max_percent = percent; 1610 } 1611 1612 if (al->data_nr > nr_percent) 1613 nr_percent = al->data_nr; 1614 1615 if (max_percent < min_pcnt) 1616 return -1; 1617 1618 if (max_lines && printed >= max_lines) 1619 return 1; 1620 1621 if (queue != NULL) { 1622 list_for_each_entry_from(queue, ¬es->src->source, node) { 1623 if (queue == al) 1624 break; 1625 annotation_line__print(queue, sym, start, evsel, len, 1626 0, 0, 1, NULL, addr_fmt_width, 1627 percent_type); 1628 } 1629 } 1630 1631 color = get_percent_color(max_percent); 1632 1633 for (i = 0; i < nr_percent; i++) { 1634 struct annotation_data *data = &al->data[i]; 1635 double percent; 1636 1637 percent = annotation_data__percent(data, percent_type); 1638 color = get_percent_color(percent); 1639 1640 if (symbol_conf.show_total_period) 1641 color_fprintf(stdout, color, " %11" PRIu64, 1642 data->he.period); 1643 else if (symbol_conf.show_nr_samples) 1644 color_fprintf(stdout, color, " %7" PRIu64, 1645 data->he.nr_samples); 1646 else 1647 color_fprintf(stdout, color, " %7.2f", percent); 1648 } 1649 1650 printf(" : "); 1651 1652 disasm_line__print(dl, start, addr_fmt_width); 1653 1654 /* 1655 * Also color the filename and line if needed, with 1656 * the same color than the percentage. Don't print it 1657 * twice for close colored addr with the same filename:line 1658 */ 1659 if (al->path) { 1660 if (!prev_line || strcmp(prev_line, al->path)) { 1661 color_fprintf(stdout, color, " // %s", al->path); 1662 prev_line = al->path; 1663 } 1664 } 1665 1666 printf("\n"); 1667 } else if (max_lines && printed >= max_lines) 1668 return 1; 1669 else { 1670 int width = symbol_conf.show_total_period ? 12 : 8; 1671 1672 if (queue) 1673 return -1; 1674 1675 if (evsel__is_group_event(evsel)) 1676 width *= evsel->core.nr_members; 1677 1678 if (!*al->line) 1679 printf(" %*s:\n", width, " "); 1680 else 1681 printf(" %*s: %-*d %s\n", width, " ", addr_fmt_width, al->line_nr, al->line); 1682 } 1683 1684 return 0; 1685 } 1686 1687 /* 1688 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw) 1689 * which looks like following 1690 * 1691 * 0000000000415500 <_init>: 1692 * 415500: sub $0x8,%rsp 1693 * 415504: mov 0x2f5ad5(%rip),%rax # 70afe0 <_DYNAMIC+0x2f8> 1694 * 41550b: test %rax,%rax 1695 * 41550e: je 415515 <_init+0x15> 1696 * 415510: callq 416e70 <__gmon_start__@plt> 1697 * 415515: add $0x8,%rsp 1698 * 415519: retq 1699 * 1700 * it will be parsed and saved into struct disasm_line as 1701 * <offset> <name> <ops.raw> 1702 * 1703 * The offset will be a relative offset from the start of the symbol and -1 1704 * means that it's not a disassembly line so should be treated differently. 1705 * The ops.raw part will be parsed further according to type of the instruction. 1706 */ 1707 static int symbol__parse_objdump_line(struct symbol *sym, 1708 struct annotate_args *args, 1709 char *parsed_line, int *line_nr, char **fileloc) 1710 { 1711 struct map *map = args->ms.map; 1712 struct annotation *notes = symbol__annotation(sym); 1713 struct disasm_line *dl; 1714 char *tmp; 1715 s64 line_ip, offset = -1; 1716 regmatch_t match[2]; 1717 1718 /* /filename:linenr ? Save line number and ignore. */ 1719 if (regexec(&file_lineno, parsed_line, 2, match, 0) == 0) { 1720 *line_nr = atoi(parsed_line + match[1].rm_so); 1721 free(*fileloc); 1722 *fileloc = strdup(parsed_line); 1723 return 0; 1724 } 1725 1726 /* Process hex address followed by ':'. */ 1727 line_ip = strtoull(parsed_line, &tmp, 16); 1728 if (parsed_line != tmp && tmp[0] == ':' && tmp[1] != '\0') { 1729 u64 start = map__rip_2objdump(map, sym->start), 1730 end = map__rip_2objdump(map, sym->end); 1731 1732 offset = line_ip - start; 1733 if ((u64)line_ip < start || (u64)line_ip >= end) 1734 offset = -1; 1735 else 1736 parsed_line = tmp + 1; 1737 } 1738 1739 args->offset = offset; 1740 args->line = parsed_line; 1741 args->line_nr = *line_nr; 1742 args->fileloc = *fileloc; 1743 args->ms.sym = sym; 1744 1745 dl = disasm_line__new(args); 1746 (*line_nr)++; 1747 1748 if (dl == NULL) 1749 return -1; 1750 1751 if (!disasm_line__has_local_offset(dl)) { 1752 dl->ops.target.offset = dl->ops.target.addr - 1753 map__rip_2objdump(map, sym->start); 1754 dl->ops.target.offset_avail = true; 1755 } 1756 1757 /* kcore has no symbols, so add the call target symbol */ 1758 if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) { 1759 struct addr_map_symbol target = { 1760 .addr = dl->ops.target.addr, 1761 .ms = { .map = map, }, 1762 }; 1763 1764 if (!maps__find_ams(args->ms.maps, &target) && 1765 target.ms.sym->start == target.al_addr) 1766 dl->ops.target.sym = target.ms.sym; 1767 } 1768 1769 annotation_line__add(&dl->al, ¬es->src->source); 1770 return 0; 1771 } 1772 1773 static __attribute__((constructor)) void symbol__init_regexpr(void) 1774 { 1775 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED); 1776 } 1777 1778 static void delete_last_nop(struct symbol *sym) 1779 { 1780 struct annotation *notes = symbol__annotation(sym); 1781 struct list_head *list = ¬es->src->source; 1782 struct disasm_line *dl; 1783 1784 while (!list_empty(list)) { 1785 dl = list_entry(list->prev, struct disasm_line, al.node); 1786 1787 if (dl->ins.ops) { 1788 if (dl->ins.ops != &nop_ops) 1789 return; 1790 } else { 1791 if (!strstr(dl->al.line, " nop ") && 1792 !strstr(dl->al.line, " nopl ") && 1793 !strstr(dl->al.line, " nopw ")) 1794 return; 1795 } 1796 1797 list_del_init(&dl->al.node); 1798 disasm_line__free(dl); 1799 } 1800 } 1801 1802 int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, size_t buflen) 1803 { 1804 struct dso *dso = map__dso(ms->map); 1805 1806 BUG_ON(buflen == 0); 1807 1808 if (errnum >= 0) { 1809 str_error_r(errnum, buf, buflen); 1810 return 0; 1811 } 1812 1813 switch (errnum) { 1814 case SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX: { 1815 char bf[SBUILD_ID_SIZE + 15] = " with build id "; 1816 char *build_id_msg = NULL; 1817 1818 if (dso->has_build_id) { 1819 build_id__sprintf(&dso->bid, bf + 15); 1820 build_id_msg = bf; 1821 } 1822 scnprintf(buf, buflen, 1823 "No vmlinux file%s\nwas found in the path.\n\n" 1824 "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n" 1825 "Please use:\n\n" 1826 " perf buildid-cache -vu vmlinux\n\n" 1827 "or:\n\n" 1828 " --vmlinux vmlinux\n", build_id_msg ?: ""); 1829 } 1830 break; 1831 case SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF: 1832 scnprintf(buf, buflen, "Please link with binutils's libopcode to enable BPF annotation"); 1833 break; 1834 case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP: 1835 scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions."); 1836 break; 1837 case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING: 1838 scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization."); 1839 break; 1840 case SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE: 1841 scnprintf(buf, buflen, "Invalid BPF file: %s.", dso->long_name); 1842 break; 1843 case SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF: 1844 scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.", 1845 dso->long_name); 1846 break; 1847 default: 1848 scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); 1849 break; 1850 } 1851 1852 return 0; 1853 } 1854 1855 static int dso__disassemble_filename(struct dso *dso, char *filename, size_t filename_size) 1856 { 1857 char linkname[PATH_MAX]; 1858 char *build_id_filename; 1859 char *build_id_path = NULL; 1860 char *pos; 1861 int len; 1862 1863 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 1864 !dso__is_kcore(dso)) 1865 return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; 1866 1867 build_id_filename = dso__build_id_filename(dso, NULL, 0, false); 1868 if (build_id_filename) { 1869 __symbol__join_symfs(filename, filename_size, build_id_filename); 1870 free(build_id_filename); 1871 } else { 1872 if (dso->has_build_id) 1873 return ENOMEM; 1874 goto fallback; 1875 } 1876 1877 build_id_path = strdup(filename); 1878 if (!build_id_path) 1879 return ENOMEM; 1880 1881 /* 1882 * old style build-id cache has name of XX/XXXXXXX.. while 1883 * new style has XX/XXXXXXX../{elf,kallsyms,vdso}. 1884 * extract the build-id part of dirname in the new style only. 1885 */ 1886 pos = strrchr(build_id_path, '/'); 1887 if (pos && strlen(pos) < SBUILD_ID_SIZE - 2) 1888 dirname(build_id_path); 1889 1890 if (dso__is_kcore(dso)) 1891 goto fallback; 1892 1893 len = readlink(build_id_path, linkname, sizeof(linkname) - 1); 1894 if (len < 0) 1895 goto fallback; 1896 1897 linkname[len] = '\0'; 1898 if (strstr(linkname, DSO__NAME_KALLSYMS) || 1899 access(filename, R_OK)) { 1900 fallback: 1901 /* 1902 * If we don't have build-ids or the build-id file isn't in the 1903 * cache, or is just a kallsyms file, well, lets hope that this 1904 * DSO is the same as when 'perf record' ran. 1905 */ 1906 if (dso->kernel && dso->long_name[0] == '/') 1907 snprintf(filename, filename_size, "%s", dso->long_name); 1908 else 1909 __symbol__join_symfs(filename, filename_size, dso->long_name); 1910 1911 mutex_lock(&dso->lock); 1912 if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) { 1913 char *new_name = dso__filename_with_chroot(dso, filename); 1914 if (new_name) { 1915 strlcpy(filename, new_name, filename_size); 1916 free(new_name); 1917 } 1918 } 1919 mutex_unlock(&dso->lock); 1920 } 1921 1922 free(build_id_path); 1923 return 0; 1924 } 1925 1926 #if defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) 1927 #define PACKAGE "perf" 1928 #include <bfd.h> 1929 #include <dis-asm.h> 1930 #include <bpf/bpf.h> 1931 #include <bpf/btf.h> 1932 #include <bpf/libbpf.h> 1933 #include <linux/btf.h> 1934 #include <tools/dis-asm-compat.h> 1935 1936 static int symbol__disassemble_bpf(struct symbol *sym, 1937 struct annotate_args *args) 1938 { 1939 struct annotation *notes = symbol__annotation(sym); 1940 struct bpf_prog_linfo *prog_linfo = NULL; 1941 struct bpf_prog_info_node *info_node; 1942 int len = sym->end - sym->start; 1943 disassembler_ftype disassemble; 1944 struct map *map = args->ms.map; 1945 struct perf_bpil *info_linear; 1946 struct disassemble_info info; 1947 struct dso *dso = map__dso(map); 1948 int pc = 0, count, sub_id; 1949 struct btf *btf = NULL; 1950 char tpath[PATH_MAX]; 1951 size_t buf_size; 1952 int nr_skip = 0; 1953 char *buf; 1954 bfd *bfdf; 1955 int ret; 1956 FILE *s; 1957 1958 if (dso->binary_type != DSO_BINARY_TYPE__BPF_PROG_INFO) 1959 return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE; 1960 1961 pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__, 1962 sym->name, sym->start, sym->end - sym->start); 1963 1964 memset(tpath, 0, sizeof(tpath)); 1965 perf_exe(tpath, sizeof(tpath)); 1966 1967 bfdf = bfd_openr(tpath, NULL); 1968 if (bfdf == NULL) 1969 abort(); 1970 1971 if (!bfd_check_format(bfdf, bfd_object)) 1972 abort(); 1973 1974 s = open_memstream(&buf, &buf_size); 1975 if (!s) { 1976 ret = errno; 1977 goto out; 1978 } 1979 init_disassemble_info_compat(&info, s, 1980 (fprintf_ftype) fprintf, 1981 fprintf_styled); 1982 info.arch = bfd_get_arch(bfdf); 1983 info.mach = bfd_get_mach(bfdf); 1984 1985 info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, 1986 dso->bpf_prog.id); 1987 if (!info_node) { 1988 ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; 1989 goto out; 1990 } 1991 info_linear = info_node->info_linear; 1992 sub_id = dso->bpf_prog.sub_id; 1993 1994 info.buffer = (void *)(uintptr_t)(info_linear->info.jited_prog_insns); 1995 info.buffer_length = info_linear->info.jited_prog_len; 1996 1997 if (info_linear->info.nr_line_info) 1998 prog_linfo = bpf_prog_linfo__new(&info_linear->info); 1999 2000 if (info_linear->info.btf_id) { 2001 struct btf_node *node; 2002 2003 node = perf_env__find_btf(dso->bpf_prog.env, 2004 info_linear->info.btf_id); 2005 if (node) 2006 btf = btf__new((__u8 *)(node->data), 2007 node->data_size); 2008 } 2009 2010 disassemble_init_for_target(&info); 2011 2012 #ifdef DISASM_FOUR_ARGS_SIGNATURE 2013 disassemble = disassembler(info.arch, 2014 bfd_big_endian(bfdf), 2015 info.mach, 2016 bfdf); 2017 #else 2018 disassemble = disassembler(bfdf); 2019 #endif 2020 if (disassemble == NULL) 2021 abort(); 2022 2023 fflush(s); 2024 do { 2025 const struct bpf_line_info *linfo = NULL; 2026 struct disasm_line *dl; 2027 size_t prev_buf_size; 2028 const char *srcline; 2029 u64 addr; 2030 2031 addr = pc + ((u64 *)(uintptr_t)(info_linear->info.jited_ksyms))[sub_id]; 2032 count = disassemble(pc, &info); 2033 2034 if (prog_linfo) 2035 linfo = bpf_prog_linfo__lfind_addr_func(prog_linfo, 2036 addr, sub_id, 2037 nr_skip); 2038 2039 if (linfo && btf) { 2040 srcline = btf__name_by_offset(btf, linfo->line_off); 2041 nr_skip++; 2042 } else 2043 srcline = NULL; 2044 2045 fprintf(s, "\n"); 2046 prev_buf_size = buf_size; 2047 fflush(s); 2048 2049 if (!annotate_opts.hide_src_code && srcline) { 2050 args->offset = -1; 2051 args->line = strdup(srcline); 2052 args->line_nr = 0; 2053 args->fileloc = NULL; 2054 args->ms.sym = sym; 2055 dl = disasm_line__new(args); 2056 if (dl) { 2057 annotation_line__add(&dl->al, 2058 ¬es->src->source); 2059 } 2060 } 2061 2062 args->offset = pc; 2063 args->line = buf + prev_buf_size; 2064 args->line_nr = 0; 2065 args->fileloc = NULL; 2066 args->ms.sym = sym; 2067 dl = disasm_line__new(args); 2068 if (dl) 2069 annotation_line__add(&dl->al, ¬es->src->source); 2070 2071 pc += count; 2072 } while (count > 0 && pc < len); 2073 2074 ret = 0; 2075 out: 2076 free(prog_linfo); 2077 btf__free(btf); 2078 fclose(s); 2079 bfd_close(bfdf); 2080 return ret; 2081 } 2082 #else // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) 2083 static int symbol__disassemble_bpf(struct symbol *sym __maybe_unused, 2084 struct annotate_args *args __maybe_unused) 2085 { 2086 return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF; 2087 } 2088 #endif // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) 2089 2090 static int 2091 symbol__disassemble_bpf_image(struct symbol *sym, 2092 struct annotate_args *args) 2093 { 2094 struct annotation *notes = symbol__annotation(sym); 2095 struct disasm_line *dl; 2096 2097 args->offset = -1; 2098 args->line = strdup("to be implemented"); 2099 args->line_nr = 0; 2100 args->fileloc = NULL; 2101 dl = disasm_line__new(args); 2102 if (dl) 2103 annotation_line__add(&dl->al, ¬es->src->source); 2104 2105 zfree(&args->line); 2106 return 0; 2107 } 2108 2109 /* 2110 * Possibly create a new version of line with tabs expanded. Returns the 2111 * existing or new line, storage is updated if a new line is allocated. If 2112 * allocation fails then NULL is returned. 2113 */ 2114 static char *expand_tabs(char *line, char **storage, size_t *storage_len) 2115 { 2116 size_t i, src, dst, len, new_storage_len, num_tabs; 2117 char *new_line; 2118 size_t line_len = strlen(line); 2119 2120 for (num_tabs = 0, i = 0; i < line_len; i++) 2121 if (line[i] == '\t') 2122 num_tabs++; 2123 2124 if (num_tabs == 0) 2125 return line; 2126 2127 /* 2128 * Space for the line and '\0', less the leading and trailing 2129 * spaces. Each tab may introduce 7 additional spaces. 2130 */ 2131 new_storage_len = line_len + 1 + (num_tabs * 7); 2132 2133 new_line = malloc(new_storage_len); 2134 if (new_line == NULL) { 2135 pr_err("Failure allocating memory for tab expansion\n"); 2136 return NULL; 2137 } 2138 2139 /* 2140 * Copy regions starting at src and expand tabs. If there are two 2141 * adjacent tabs then 'src == i', the memcpy is of size 0 and the spaces 2142 * are inserted. 2143 */ 2144 for (i = 0, src = 0, dst = 0; i < line_len && num_tabs; i++) { 2145 if (line[i] == '\t') { 2146 len = i - src; 2147 memcpy(&new_line[dst], &line[src], len); 2148 dst += len; 2149 new_line[dst++] = ' '; 2150 while (dst % 8 != 0) 2151 new_line[dst++] = ' '; 2152 src = i + 1; 2153 num_tabs--; 2154 } 2155 } 2156 2157 /* Expand the last region. */ 2158 len = line_len - src; 2159 memcpy(&new_line[dst], &line[src], len); 2160 dst += len; 2161 new_line[dst] = '\0'; 2162 2163 free(*storage); 2164 *storage = new_line; 2165 *storage_len = new_storage_len; 2166 return new_line; 2167 2168 } 2169 2170 static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) 2171 { 2172 struct annotation_options *opts = &annotate_opts; 2173 struct map *map = args->ms.map; 2174 struct dso *dso = map__dso(map); 2175 char *command; 2176 FILE *file; 2177 char symfs_filename[PATH_MAX]; 2178 struct kcore_extract kce; 2179 bool delete_extract = false; 2180 bool decomp = false; 2181 int lineno = 0; 2182 char *fileloc = NULL; 2183 int nline; 2184 char *line; 2185 size_t line_len; 2186 const char *objdump_argv[] = { 2187 "/bin/sh", 2188 "-c", 2189 NULL, /* Will be the objdump command to run. */ 2190 "--", 2191 NULL, /* Will be the symfs path. */ 2192 NULL, 2193 }; 2194 struct child_process objdump_process; 2195 int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename)); 2196 2197 if (err) 2198 return err; 2199 2200 pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, 2201 symfs_filename, sym->name, map__unmap_ip(map, sym->start), 2202 map__unmap_ip(map, sym->end)); 2203 2204 pr_debug("annotating [%p] %30s : [%p] %30s\n", 2205 dso, dso->long_name, sym, sym->name); 2206 2207 if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) { 2208 return symbol__disassemble_bpf(sym, args); 2209 } else if (dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) { 2210 return symbol__disassemble_bpf_image(sym, args); 2211 } else if (dso__is_kcore(dso)) { 2212 kce.kcore_filename = symfs_filename; 2213 kce.addr = map__rip_2objdump(map, sym->start); 2214 kce.offs = sym->start; 2215 kce.len = sym->end - sym->start; 2216 if (!kcore_extract__create(&kce)) { 2217 delete_extract = true; 2218 strlcpy(symfs_filename, kce.extract_filename, 2219 sizeof(symfs_filename)); 2220 } 2221 } else if (dso__needs_decompress(dso)) { 2222 char tmp[KMOD_DECOMP_LEN]; 2223 2224 if (dso__decompress_kmodule_path(dso, symfs_filename, 2225 tmp, sizeof(tmp)) < 0) 2226 return -1; 2227 2228 decomp = true; 2229 strcpy(symfs_filename, tmp); 2230 } 2231 2232 err = asprintf(&command, 2233 "%s %s%s --start-address=0x%016" PRIx64 2234 " --stop-address=0x%016" PRIx64 2235 " %s -d %s %s %s %c%s%c %s%s -C \"$1\"", 2236 opts->objdump_path ?: "objdump", 2237 opts->disassembler_style ? "-M " : "", 2238 opts->disassembler_style ?: "", 2239 map__rip_2objdump(map, sym->start), 2240 map__rip_2objdump(map, sym->end), 2241 opts->show_linenr ? "-l" : "", 2242 opts->show_asm_raw ? "" : "--no-show-raw-insn", 2243 opts->annotate_src ? "-S" : "", 2244 opts->prefix ? "--prefix " : "", 2245 opts->prefix ? '"' : ' ', 2246 opts->prefix ?: "", 2247 opts->prefix ? '"' : ' ', 2248 opts->prefix_strip ? "--prefix-strip=" : "", 2249 opts->prefix_strip ?: ""); 2250 2251 if (err < 0) { 2252 pr_err("Failure allocating memory for the command to run\n"); 2253 goto out_remove_tmp; 2254 } 2255 2256 pr_debug("Executing: %s\n", command); 2257 2258 objdump_argv[2] = command; 2259 objdump_argv[4] = symfs_filename; 2260 2261 /* Create a pipe to read from for stdout */ 2262 memset(&objdump_process, 0, sizeof(objdump_process)); 2263 objdump_process.argv = objdump_argv; 2264 objdump_process.out = -1; 2265 objdump_process.err = -1; 2266 objdump_process.no_stderr = 1; 2267 if (start_command(&objdump_process)) { 2268 pr_err("Failure starting to run %s\n", command); 2269 err = -1; 2270 goto out_free_command; 2271 } 2272 2273 file = fdopen(objdump_process.out, "r"); 2274 if (!file) { 2275 pr_err("Failure creating FILE stream for %s\n", command); 2276 /* 2277 * If we were using debug info should retry with 2278 * original binary. 2279 */ 2280 err = -1; 2281 goto out_close_stdout; 2282 } 2283 2284 /* Storage for getline. */ 2285 line = NULL; 2286 line_len = 0; 2287 2288 nline = 0; 2289 while (!feof(file)) { 2290 const char *match; 2291 char *expanded_line; 2292 2293 if (getline(&line, &line_len, file) < 0 || !line) 2294 break; 2295 2296 /* Skip lines containing "filename:" */ 2297 match = strstr(line, symfs_filename); 2298 if (match && match[strlen(symfs_filename)] == ':') 2299 continue; 2300 2301 expanded_line = strim(line); 2302 expanded_line = expand_tabs(expanded_line, &line, &line_len); 2303 if (!expanded_line) 2304 break; 2305 2306 /* 2307 * The source code line number (lineno) needs to be kept in 2308 * across calls to symbol__parse_objdump_line(), so that it 2309 * can associate it with the instructions till the next one. 2310 * See disasm_line__new() and struct disasm_line::line_nr. 2311 */ 2312 if (symbol__parse_objdump_line(sym, args, expanded_line, 2313 &lineno, &fileloc) < 0) 2314 break; 2315 nline++; 2316 } 2317 free(line); 2318 free(fileloc); 2319 2320 err = finish_command(&objdump_process); 2321 if (err) 2322 pr_err("Error running %s\n", command); 2323 2324 if (nline == 0) { 2325 err = -1; 2326 pr_err("No output from %s\n", command); 2327 } 2328 2329 /* 2330 * kallsyms does not have symbol sizes so there may a nop at the end. 2331 * Remove it. 2332 */ 2333 if (dso__is_kcore(dso)) 2334 delete_last_nop(sym); 2335 2336 fclose(file); 2337 2338 out_close_stdout: 2339 close(objdump_process.out); 2340 2341 out_free_command: 2342 free(command); 2343 2344 out_remove_tmp: 2345 if (decomp) 2346 unlink(symfs_filename); 2347 2348 if (delete_extract) 2349 kcore_extract__delete(&kce); 2350 2351 return err; 2352 } 2353 2354 static void calc_percent(struct annotation *notes, 2355 struct evsel *evsel, 2356 struct annotation_data *data, 2357 s64 offset, s64 end) 2358 { 2359 struct hists *hists = evsel__hists(evsel); 2360 int evidx = evsel->core.idx; 2361 struct sym_hist *sym_hist = annotation__histogram(notes, evidx); 2362 unsigned int hits = 0; 2363 u64 period = 0; 2364 2365 while (offset < end) { 2366 struct sym_hist_entry *entry; 2367 2368 entry = annotated_source__hist_entry(notes->src, evidx, offset); 2369 if (entry) { 2370 hits += entry->nr_samples; 2371 period += entry->period; 2372 } 2373 ++offset; 2374 } 2375 2376 if (sym_hist->nr_samples) { 2377 data->he.period = period; 2378 data->he.nr_samples = hits; 2379 data->percent[PERCENT_HITS_LOCAL] = 100.0 * hits / sym_hist->nr_samples; 2380 } 2381 2382 if (hists->stats.nr_non_filtered_samples) 2383 data->percent[PERCENT_HITS_GLOBAL] = 100.0 * hits / hists->stats.nr_non_filtered_samples; 2384 2385 if (sym_hist->period) 2386 data->percent[PERCENT_PERIOD_LOCAL] = 100.0 * period / sym_hist->period; 2387 2388 if (hists->stats.total_period) 2389 data->percent[PERCENT_PERIOD_GLOBAL] = 100.0 * period / hists->stats.total_period; 2390 } 2391 2392 static void annotation__calc_percent(struct annotation *notes, 2393 struct evsel *leader, s64 len) 2394 { 2395 struct annotation_line *al, *next; 2396 struct evsel *evsel; 2397 2398 list_for_each_entry(al, ¬es->src->source, node) { 2399 s64 end; 2400 int i = 0; 2401 2402 if (al->offset == -1) 2403 continue; 2404 2405 next = annotation_line__next(al, ¬es->src->source); 2406 end = next ? next->offset : len; 2407 2408 for_each_group_evsel(evsel, leader) { 2409 struct annotation_data *data; 2410 2411 BUG_ON(i >= al->data_nr); 2412 2413 data = &al->data[i++]; 2414 2415 calc_percent(notes, evsel, data, al->offset, end); 2416 } 2417 } 2418 } 2419 2420 void symbol__calc_percent(struct symbol *sym, struct evsel *evsel) 2421 { 2422 struct annotation *notes = symbol__annotation(sym); 2423 2424 annotation__calc_percent(notes, evsel, symbol__size(sym)); 2425 } 2426 2427 static int evsel__get_arch(struct evsel *evsel, struct arch **parch) 2428 { 2429 struct perf_env *env = evsel__env(evsel); 2430 const char *arch_name = perf_env__arch(env); 2431 struct arch *arch; 2432 int err; 2433 2434 if (!arch_name) 2435 return errno; 2436 2437 *parch = arch = arch__find(arch_name); 2438 if (arch == NULL) { 2439 pr_err("%s: unsupported arch %s\n", __func__, arch_name); 2440 return ENOTSUP; 2441 } 2442 2443 if (arch->init) { 2444 err = arch->init(arch, env ? env->cpuid : NULL); 2445 if (err) { 2446 pr_err("%s: failed to initialize %s arch priv area\n", 2447 __func__, arch->name); 2448 return err; 2449 } 2450 } 2451 return 0; 2452 } 2453 2454 int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, 2455 struct arch **parch) 2456 { 2457 struct symbol *sym = ms->sym; 2458 struct annotation *notes = symbol__annotation(sym); 2459 struct annotate_args args = { 2460 .evsel = evsel, 2461 .options = &annotate_opts, 2462 }; 2463 struct arch *arch = NULL; 2464 int err; 2465 2466 err = evsel__get_arch(evsel, &arch); 2467 if (err < 0) 2468 return err; 2469 2470 if (parch) 2471 *parch = arch; 2472 2473 args.arch = arch; 2474 args.ms = *ms; 2475 if (annotate_opts.full_addr) 2476 notes->start = map__objdump_2mem(ms->map, ms->sym->start); 2477 else 2478 notes->start = map__rip_2objdump(ms->map, ms->sym->start); 2479 2480 return symbol__disassemble(sym, &args); 2481 } 2482 2483 static void insert_source_line(struct rb_root *root, struct annotation_line *al) 2484 { 2485 struct annotation_line *iter; 2486 struct rb_node **p = &root->rb_node; 2487 struct rb_node *parent = NULL; 2488 unsigned int percent_type = annotate_opts.percent_type; 2489 int i, ret; 2490 2491 while (*p != NULL) { 2492 parent = *p; 2493 iter = rb_entry(parent, struct annotation_line, rb_node); 2494 2495 ret = strcmp(iter->path, al->path); 2496 if (ret == 0) { 2497 for (i = 0; i < al->data_nr; i++) { 2498 iter->data[i].percent_sum += annotation_data__percent(&al->data[i], 2499 percent_type); 2500 } 2501 return; 2502 } 2503 2504 if (ret < 0) 2505 p = &(*p)->rb_left; 2506 else 2507 p = &(*p)->rb_right; 2508 } 2509 2510 for (i = 0; i < al->data_nr; i++) { 2511 al->data[i].percent_sum = annotation_data__percent(&al->data[i], 2512 percent_type); 2513 } 2514 2515 rb_link_node(&al->rb_node, parent, p); 2516 rb_insert_color(&al->rb_node, root); 2517 } 2518 2519 static int cmp_source_line(struct annotation_line *a, struct annotation_line *b) 2520 { 2521 int i; 2522 2523 for (i = 0; i < a->data_nr; i++) { 2524 if (a->data[i].percent_sum == b->data[i].percent_sum) 2525 continue; 2526 return a->data[i].percent_sum > b->data[i].percent_sum; 2527 } 2528 2529 return 0; 2530 } 2531 2532 static void __resort_source_line(struct rb_root *root, struct annotation_line *al) 2533 { 2534 struct annotation_line *iter; 2535 struct rb_node **p = &root->rb_node; 2536 struct rb_node *parent = NULL; 2537 2538 while (*p != NULL) { 2539 parent = *p; 2540 iter = rb_entry(parent, struct annotation_line, rb_node); 2541 2542 if (cmp_source_line(al, iter)) 2543 p = &(*p)->rb_left; 2544 else 2545 p = &(*p)->rb_right; 2546 } 2547 2548 rb_link_node(&al->rb_node, parent, p); 2549 rb_insert_color(&al->rb_node, root); 2550 } 2551 2552 static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root) 2553 { 2554 struct annotation_line *al; 2555 struct rb_node *node; 2556 2557 node = rb_first(src_root); 2558 while (node) { 2559 struct rb_node *next; 2560 2561 al = rb_entry(node, struct annotation_line, rb_node); 2562 next = rb_next(node); 2563 rb_erase(node, src_root); 2564 2565 __resort_source_line(dest_root, al); 2566 node = next; 2567 } 2568 } 2569 2570 static void print_summary(struct rb_root *root, const char *filename) 2571 { 2572 struct annotation_line *al; 2573 struct rb_node *node; 2574 2575 printf("\nSorted summary for file %s\n", filename); 2576 printf("----------------------------------------------\n\n"); 2577 2578 if (RB_EMPTY_ROOT(root)) { 2579 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN); 2580 return; 2581 } 2582 2583 node = rb_first(root); 2584 while (node) { 2585 double percent, percent_max = 0.0; 2586 const char *color; 2587 char *path; 2588 int i; 2589 2590 al = rb_entry(node, struct annotation_line, rb_node); 2591 for (i = 0; i < al->data_nr; i++) { 2592 percent = al->data[i].percent_sum; 2593 color = get_percent_color(percent); 2594 color_fprintf(stdout, color, " %7.2f", percent); 2595 2596 if (percent > percent_max) 2597 percent_max = percent; 2598 } 2599 2600 path = al->path; 2601 color = get_percent_color(percent_max); 2602 color_fprintf(stdout, color, " %s\n", path); 2603 2604 node = rb_next(node); 2605 } 2606 } 2607 2608 static void symbol__annotate_hits(struct symbol *sym, struct evsel *evsel) 2609 { 2610 int evidx = evsel->core.idx; 2611 struct annotation *notes = symbol__annotation(sym); 2612 struct sym_hist *h = annotation__histogram(notes, evidx); 2613 u64 len = symbol__size(sym), offset; 2614 2615 for (offset = 0; offset < len; ++offset) { 2616 struct sym_hist_entry *entry; 2617 2618 entry = annotated_source__hist_entry(notes->src, evidx, offset); 2619 if (entry && entry->nr_samples != 0) 2620 printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, 2621 sym->start + offset, entry->nr_samples); 2622 } 2623 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples); 2624 } 2625 2626 static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start) 2627 { 2628 char bf[32]; 2629 struct annotation_line *line; 2630 2631 list_for_each_entry_reverse(line, lines, node) { 2632 if (line->offset != -1) 2633 return scnprintf(bf, sizeof(bf), "%" PRIx64, start + line->offset); 2634 } 2635 2636 return 0; 2637 } 2638 2639 int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel) 2640 { 2641 struct map *map = ms->map; 2642 struct symbol *sym = ms->sym; 2643 struct dso *dso = map__dso(map); 2644 char *filename; 2645 const char *d_filename; 2646 const char *evsel_name = evsel__name(evsel); 2647 struct annotation *notes = symbol__annotation(sym); 2648 struct sym_hist *h = annotation__histogram(notes, evsel->core.idx); 2649 struct annotation_line *pos, *queue = NULL; 2650 struct annotation_options *opts = &annotate_opts; 2651 u64 start = map__rip_2objdump(map, sym->start); 2652 int printed = 2, queue_len = 0, addr_fmt_width; 2653 int more = 0; 2654 bool context = opts->context; 2655 u64 len; 2656 int width = symbol_conf.show_total_period ? 12 : 8; 2657 int graph_dotted_len; 2658 char buf[512]; 2659 2660 filename = strdup(dso->long_name); 2661 if (!filename) 2662 return -ENOMEM; 2663 2664 if (opts->full_path) 2665 d_filename = filename; 2666 else 2667 d_filename = basename(filename); 2668 2669 len = symbol__size(sym); 2670 2671 if (evsel__is_group_event(evsel)) { 2672 width *= evsel->core.nr_members; 2673 evsel__group_desc(evsel, buf, sizeof(buf)); 2674 evsel_name = buf; 2675 } 2676 2677 graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples, " 2678 "percent: %s)\n", 2679 width, width, symbol_conf.show_total_period ? "Period" : 2680 symbol_conf.show_nr_samples ? "Samples" : "Percent", 2681 d_filename, evsel_name, h->nr_samples, 2682 percent_type_str(opts->percent_type)); 2683 2684 printf("%-*.*s----\n", 2685 graph_dotted_len, graph_dotted_len, graph_dotted_line); 2686 2687 if (verbose > 0) 2688 symbol__annotate_hits(sym, evsel); 2689 2690 addr_fmt_width = annotated_source__addr_fmt_width(¬es->src->source, start); 2691 2692 list_for_each_entry(pos, ¬es->src->source, node) { 2693 int err; 2694 2695 if (context && queue == NULL) { 2696 queue = pos; 2697 queue_len = 0; 2698 } 2699 2700 err = annotation_line__print(pos, sym, start, evsel, len, 2701 opts->min_pcnt, printed, opts->max_lines, 2702 queue, addr_fmt_width, opts->percent_type); 2703 2704 switch (err) { 2705 case 0: 2706 ++printed; 2707 if (context) { 2708 printed += queue_len; 2709 queue = NULL; 2710 queue_len = 0; 2711 } 2712 break; 2713 case 1: 2714 /* filtered by max_lines */ 2715 ++more; 2716 break; 2717 case -1: 2718 default: 2719 /* 2720 * Filtered by min_pcnt or non IP lines when 2721 * context != 0 2722 */ 2723 if (!context) 2724 break; 2725 if (queue_len == context) 2726 queue = list_entry(queue->node.next, typeof(*queue), node); 2727 else 2728 ++queue_len; 2729 break; 2730 } 2731 } 2732 2733 free(filename); 2734 2735 return more; 2736 } 2737 2738 static void FILE__set_percent_color(void *fp __maybe_unused, 2739 double percent __maybe_unused, 2740 bool current __maybe_unused) 2741 { 2742 } 2743 2744 static int FILE__set_jumps_percent_color(void *fp __maybe_unused, 2745 int nr __maybe_unused, bool current __maybe_unused) 2746 { 2747 return 0; 2748 } 2749 2750 static int FILE__set_color(void *fp __maybe_unused, int color __maybe_unused) 2751 { 2752 return 0; 2753 } 2754 2755 static void FILE__printf(void *fp, const char *fmt, ...) 2756 { 2757 va_list args; 2758 2759 va_start(args, fmt); 2760 vfprintf(fp, fmt, args); 2761 va_end(args); 2762 } 2763 2764 static void FILE__write_graph(void *fp, int graph) 2765 { 2766 const char *s; 2767 switch (graph) { 2768 2769 case DARROW_CHAR: s = "↓"; break; 2770 case UARROW_CHAR: s = "↑"; break; 2771 case LARROW_CHAR: s = "←"; break; 2772 case RARROW_CHAR: s = "→"; break; 2773 default: s = "?"; break; 2774 } 2775 2776 fputs(s, fp); 2777 } 2778 2779 static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp) 2780 { 2781 struct annotation *notes = symbol__annotation(sym); 2782 struct annotation_write_ops wops = { 2783 .first_line = true, 2784 .obj = fp, 2785 .set_color = FILE__set_color, 2786 .set_percent_color = FILE__set_percent_color, 2787 .set_jumps_percent_color = FILE__set_jumps_percent_color, 2788 .printf = FILE__printf, 2789 .write_graph = FILE__write_graph, 2790 }; 2791 struct annotation_line *al; 2792 2793 list_for_each_entry(al, ¬es->src->source, node) { 2794 if (annotation_line__filter(al)) 2795 continue; 2796 annotation_line__write(al, notes, &wops); 2797 fputc('\n', fp); 2798 wops.first_line = false; 2799 } 2800 2801 return 0; 2802 } 2803 2804 int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel) 2805 { 2806 const char *ev_name = evsel__name(evsel); 2807 char buf[1024]; 2808 char *filename; 2809 int err = -1; 2810 FILE *fp; 2811 2812 if (asprintf(&filename, "%s.annotation", ms->sym->name) < 0) 2813 return -1; 2814 2815 fp = fopen(filename, "w"); 2816 if (fp == NULL) 2817 goto out_free_filename; 2818 2819 if (evsel__is_group_event(evsel)) { 2820 evsel__group_desc(evsel, buf, sizeof(buf)); 2821 ev_name = buf; 2822 } 2823 2824 fprintf(fp, "%s() %s\nEvent: %s\n\n", 2825 ms->sym->name, map__dso(ms->map)->long_name, ev_name); 2826 symbol__annotate_fprintf2(ms->sym, fp); 2827 2828 fclose(fp); 2829 err = 0; 2830 out_free_filename: 2831 free(filename); 2832 return err; 2833 } 2834 2835 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx) 2836 { 2837 struct annotation *notes = symbol__annotation(sym); 2838 struct sym_hist *h = annotation__histogram(notes, evidx); 2839 2840 memset(h, 0, sizeof(*notes->src->histograms) * notes->src->nr_histograms); 2841 } 2842 2843 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) 2844 { 2845 struct annotation *notes = symbol__annotation(sym); 2846 struct sym_hist *h = annotation__histogram(notes, evidx); 2847 int len = symbol__size(sym), offset; 2848 2849 h->nr_samples = 0; 2850 for (offset = 0; offset < len; ++offset) { 2851 struct sym_hist_entry *entry; 2852 2853 entry = annotated_source__hist_entry(notes->src, evidx, offset); 2854 if (entry == NULL) 2855 continue; 2856 2857 entry->nr_samples = entry->nr_samples * 7 / 8; 2858 h->nr_samples += entry->nr_samples; 2859 } 2860 } 2861 2862 void annotated_source__purge(struct annotated_source *as) 2863 { 2864 struct annotation_line *al, *n; 2865 2866 list_for_each_entry_safe(al, n, &as->source, node) { 2867 list_del_init(&al->node); 2868 disasm_line__free(disasm_line(al)); 2869 } 2870 } 2871 2872 static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp) 2873 { 2874 size_t printed; 2875 2876 if (dl->al.offset == -1) 2877 return fprintf(fp, "%s\n", dl->al.line); 2878 2879 printed = fprintf(fp, "%#" PRIx64 " %s", dl->al.offset, dl->ins.name); 2880 2881 if (dl->ops.raw[0] != '\0') { 2882 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ", 2883 dl->ops.raw); 2884 } 2885 2886 return printed + fprintf(fp, "\n"); 2887 } 2888 2889 size_t disasm__fprintf(struct list_head *head, FILE *fp) 2890 { 2891 struct disasm_line *pos; 2892 size_t printed = 0; 2893 2894 list_for_each_entry(pos, head, al.node) 2895 printed += disasm_line__fprintf(pos, fp); 2896 2897 return printed; 2898 } 2899 2900 bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym) 2901 { 2902 if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins) || 2903 !disasm_line__has_local_offset(dl) || dl->ops.target.offset < 0 || 2904 dl->ops.target.offset >= (s64)symbol__size(sym)) 2905 return false; 2906 2907 return true; 2908 } 2909 2910 void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym) 2911 { 2912 u64 offset, size = symbol__size(sym); 2913 2914 /* PLT symbols contain external offsets */ 2915 if (strstr(sym->name, "@plt")) 2916 return; 2917 2918 for (offset = 0; offset < size; ++offset) { 2919 struct annotation_line *al = notes->src->offsets[offset]; 2920 struct disasm_line *dl; 2921 2922 dl = disasm_line(al); 2923 2924 if (!disasm_line__is_valid_local_jump(dl, sym)) 2925 continue; 2926 2927 al = notes->src->offsets[dl->ops.target.offset]; 2928 2929 /* 2930 * FIXME: Oops, no jump target? Buggy disassembler? Or do we 2931 * have to adjust to the previous offset? 2932 */ 2933 if (al == NULL) 2934 continue; 2935 2936 if (++al->jump_sources > notes->max_jump_sources) 2937 notes->max_jump_sources = al->jump_sources; 2938 } 2939 } 2940 2941 void annotation__set_offsets(struct annotation *notes, s64 size) 2942 { 2943 struct annotation_line *al; 2944 struct annotated_source *src = notes->src; 2945 2946 src->max_line_len = 0; 2947 src->nr_entries = 0; 2948 src->nr_asm_entries = 0; 2949 2950 list_for_each_entry(al, &src->source, node) { 2951 size_t line_len = strlen(al->line); 2952 2953 if (src->max_line_len < line_len) 2954 src->max_line_len = line_len; 2955 al->idx = src->nr_entries++; 2956 if (al->offset != -1) { 2957 al->idx_asm = src->nr_asm_entries++; 2958 /* 2959 * FIXME: short term bandaid to cope with assembly 2960 * routines that comes with labels in the same column 2961 * as the address in objdump, sigh. 2962 * 2963 * E.g. copy_user_generic_unrolled 2964 */ 2965 if (al->offset < size) 2966 notes->src->offsets[al->offset] = al; 2967 } else 2968 al->idx_asm = -1; 2969 } 2970 } 2971 2972 static inline int width_jumps(int n) 2973 { 2974 if (n >= 100) 2975 return 5; 2976 if (n / 10) 2977 return 2; 2978 return 1; 2979 } 2980 2981 static int annotation__max_ins_name(struct annotation *notes) 2982 { 2983 int max_name = 0, len; 2984 struct annotation_line *al; 2985 2986 list_for_each_entry(al, ¬es->src->source, node) { 2987 if (al->offset == -1) 2988 continue; 2989 2990 len = strlen(disasm_line(al)->ins.name); 2991 if (max_name < len) 2992 max_name = len; 2993 } 2994 2995 return max_name; 2996 } 2997 2998 void annotation__init_column_widths(struct annotation *notes, struct symbol *sym) 2999 { 3000 notes->widths.addr = notes->widths.target = 3001 notes->widths.min_addr = hex_width(symbol__size(sym)); 3002 notes->widths.max_addr = hex_width(sym->end); 3003 notes->widths.jumps = width_jumps(notes->max_jump_sources); 3004 notes->widths.max_ins_name = annotation__max_ins_name(notes); 3005 } 3006 3007 void annotation__update_column_widths(struct annotation *notes) 3008 { 3009 if (annotate_opts.use_offset) 3010 notes->widths.target = notes->widths.min_addr; 3011 else if (annotate_opts.full_addr) 3012 notes->widths.target = BITS_PER_LONG / 4; 3013 else 3014 notes->widths.target = notes->widths.max_addr; 3015 3016 notes->widths.addr = notes->widths.target; 3017 3018 if (annotate_opts.show_nr_jumps) 3019 notes->widths.addr += notes->widths.jumps + 1; 3020 } 3021 3022 void annotation__toggle_full_addr(struct annotation *notes, struct map_symbol *ms) 3023 { 3024 annotate_opts.full_addr = !annotate_opts.full_addr; 3025 3026 if (annotate_opts.full_addr) 3027 notes->start = map__objdump_2mem(ms->map, ms->sym->start); 3028 else 3029 notes->start = map__rip_2objdump(ms->map, ms->sym->start); 3030 3031 annotation__update_column_widths(notes); 3032 } 3033 3034 static void annotation__calc_lines(struct annotation *notes, struct map *map, 3035 struct rb_root *root) 3036 { 3037 struct annotation_line *al; 3038 struct rb_root tmp_root = RB_ROOT; 3039 3040 list_for_each_entry(al, ¬es->src->source, node) { 3041 double percent_max = 0.0; 3042 int i; 3043 3044 for (i = 0; i < al->data_nr; i++) { 3045 double percent; 3046 3047 percent = annotation_data__percent(&al->data[i], 3048 annotate_opts.percent_type); 3049 3050 if (percent > percent_max) 3051 percent_max = percent; 3052 } 3053 3054 if (percent_max <= 0.5) 3055 continue; 3056 3057 al->path = get_srcline(map__dso(map), notes->start + al->offset, NULL, 3058 false, true, notes->start + al->offset); 3059 insert_source_line(&tmp_root, al); 3060 } 3061 3062 resort_source_line(root, &tmp_root); 3063 } 3064 3065 static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root) 3066 { 3067 struct annotation *notes = symbol__annotation(ms->sym); 3068 3069 annotation__calc_lines(notes, ms->map, root); 3070 } 3071 3072 int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel) 3073 { 3074 struct dso *dso = map__dso(ms->map); 3075 struct symbol *sym = ms->sym; 3076 struct rb_root source_line = RB_ROOT; 3077 struct hists *hists = evsel__hists(evsel); 3078 char buf[1024]; 3079 int err; 3080 3081 err = symbol__annotate2(ms, evsel, NULL); 3082 if (err) { 3083 char msg[BUFSIZ]; 3084 3085 dso->annotate_warned = true; 3086 symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); 3087 ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 3088 return -1; 3089 } 3090 3091 if (annotate_opts.print_lines) { 3092 srcline_full_filename = annotate_opts.full_path; 3093 symbol__calc_lines(ms, &source_line); 3094 print_summary(&source_line, dso->long_name); 3095 } 3096 3097 hists__scnprintf_title(hists, buf, sizeof(buf)); 3098 fprintf(stdout, "%s, [percent: %s]\n%s() %s\n", 3099 buf, percent_type_str(annotate_opts.percent_type), sym->name, 3100 dso->long_name); 3101 symbol__annotate_fprintf2(sym, stdout); 3102 3103 annotated_source__purge(symbol__annotation(sym)->src); 3104 3105 return 0; 3106 } 3107 3108 int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel) 3109 { 3110 struct dso *dso = map__dso(ms->map); 3111 struct symbol *sym = ms->sym; 3112 struct rb_root source_line = RB_ROOT; 3113 int err; 3114 3115 err = symbol__annotate(ms, evsel, NULL); 3116 if (err) { 3117 char msg[BUFSIZ]; 3118 3119 dso->annotate_warned = true; 3120 symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); 3121 ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 3122 return -1; 3123 } 3124 3125 symbol__calc_percent(sym, evsel); 3126 3127 if (annotate_opts.print_lines) { 3128 srcline_full_filename = annotate_opts.full_path; 3129 symbol__calc_lines(ms, &source_line); 3130 print_summary(&source_line, dso->long_name); 3131 } 3132 3133 symbol__annotate_printf(ms, evsel); 3134 3135 annotated_source__purge(symbol__annotation(sym)->src); 3136 3137 return 0; 3138 } 3139 3140 bool ui__has_annotation(void) 3141 { 3142 return use_browser == 1 && perf_hpp_list.sym; 3143 } 3144 3145 3146 static double annotation_line__max_percent(struct annotation_line *al, 3147 struct annotation *notes, 3148 unsigned int percent_type) 3149 { 3150 double percent_max = 0.0; 3151 int i; 3152 3153 for (i = 0; i < notes->nr_events; i++) { 3154 double percent; 3155 3156 percent = annotation_data__percent(&al->data[i], 3157 percent_type); 3158 3159 if (percent > percent_max) 3160 percent_max = percent; 3161 } 3162 3163 return percent_max; 3164 } 3165 3166 static void disasm_line__write(struct disasm_line *dl, struct annotation *notes, 3167 void *obj, char *bf, size_t size, 3168 void (*obj__printf)(void *obj, const char *fmt, ...), 3169 void (*obj__write_graph)(void *obj, int graph)) 3170 { 3171 if (dl->ins.ops && dl->ins.ops->scnprintf) { 3172 if (ins__is_jump(&dl->ins)) { 3173 bool fwd; 3174 3175 if (dl->ops.target.outside) 3176 goto call_like; 3177 fwd = dl->ops.target.offset > dl->al.offset; 3178 obj__write_graph(obj, fwd ? DARROW_CHAR : UARROW_CHAR); 3179 obj__printf(obj, " "); 3180 } else if (ins__is_call(&dl->ins)) { 3181 call_like: 3182 obj__write_graph(obj, RARROW_CHAR); 3183 obj__printf(obj, " "); 3184 } else if (ins__is_ret(&dl->ins)) { 3185 obj__write_graph(obj, LARROW_CHAR); 3186 obj__printf(obj, " "); 3187 } else { 3188 obj__printf(obj, " "); 3189 } 3190 } else { 3191 obj__printf(obj, " "); 3192 } 3193 3194 disasm_line__scnprintf(dl, bf, size, !annotate_opts.use_offset, notes->widths.max_ins_name); 3195 } 3196 3197 static void ipc_coverage_string(char *bf, int size, struct annotation *notes) 3198 { 3199 double ipc = 0.0, coverage = 0.0; 3200 struct annotated_branch *branch = annotation__get_branch(notes); 3201 3202 if (branch && branch->hit_cycles) 3203 ipc = branch->hit_insn / ((double)branch->hit_cycles); 3204 3205 if (branch && branch->total_insn) { 3206 coverage = branch->cover_insn * 100.0 / 3207 ((double)branch->total_insn); 3208 } 3209 3210 scnprintf(bf, size, "(Average IPC: %.2f, IPC Coverage: %.1f%%)", 3211 ipc, coverage); 3212 } 3213 3214 static void __annotation_line__write(struct annotation_line *al, struct annotation *notes, 3215 bool first_line, bool current_entry, bool change_color, int width, 3216 void *obj, unsigned int percent_type, 3217 int (*obj__set_color)(void *obj, int color), 3218 void (*obj__set_percent_color)(void *obj, double percent, bool current), 3219 int (*obj__set_jumps_percent_color)(void *obj, int nr, bool current), 3220 void (*obj__printf)(void *obj, const char *fmt, ...), 3221 void (*obj__write_graph)(void *obj, int graph)) 3222 3223 { 3224 double percent_max = annotation_line__max_percent(al, notes, percent_type); 3225 int pcnt_width = annotation__pcnt_width(notes), 3226 cycles_width = annotation__cycles_width(notes); 3227 bool show_title = false; 3228 char bf[256]; 3229 int printed; 3230 3231 if (first_line && (al->offset == -1 || percent_max == 0.0)) { 3232 if (notes->branch && al->cycles) { 3233 if (al->cycles->ipc == 0.0 && al->cycles->avg == 0) 3234 show_title = true; 3235 } else 3236 show_title = true; 3237 } 3238 3239 if (al->offset != -1 && percent_max != 0.0) { 3240 int i; 3241 3242 for (i = 0; i < notes->nr_events; i++) { 3243 double percent; 3244 3245 percent = annotation_data__percent(&al->data[i], percent_type); 3246 3247 obj__set_percent_color(obj, percent, current_entry); 3248 if (symbol_conf.show_total_period) { 3249 obj__printf(obj, "%11" PRIu64 " ", al->data[i].he.period); 3250 } else if (symbol_conf.show_nr_samples) { 3251 obj__printf(obj, "%6" PRIu64 " ", 3252 al->data[i].he.nr_samples); 3253 } else { 3254 obj__printf(obj, "%6.2f ", percent); 3255 } 3256 } 3257 } else { 3258 obj__set_percent_color(obj, 0, current_entry); 3259 3260 if (!show_title) 3261 obj__printf(obj, "%-*s", pcnt_width, " "); 3262 else { 3263 obj__printf(obj, "%-*s", pcnt_width, 3264 symbol_conf.show_total_period ? "Period" : 3265 symbol_conf.show_nr_samples ? "Samples" : "Percent"); 3266 } 3267 } 3268 3269 if (notes->branch) { 3270 if (al->cycles && al->cycles->ipc) 3271 obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->cycles->ipc); 3272 else if (!show_title) 3273 obj__printf(obj, "%*s", ANNOTATION__IPC_WIDTH, " "); 3274 else 3275 obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC"); 3276 3277 if (!annotate_opts.show_minmax_cycle) { 3278 if (al->cycles && al->cycles->avg) 3279 obj__printf(obj, "%*" PRIu64 " ", 3280 ANNOTATION__CYCLES_WIDTH - 1, al->cycles->avg); 3281 else if (!show_title) 3282 obj__printf(obj, "%*s", 3283 ANNOTATION__CYCLES_WIDTH, " "); 3284 else 3285 obj__printf(obj, "%*s ", 3286 ANNOTATION__CYCLES_WIDTH - 1, 3287 "Cycle"); 3288 } else { 3289 if (al->cycles) { 3290 char str[32]; 3291 3292 scnprintf(str, sizeof(str), 3293 "%" PRIu64 "(%" PRIu64 "/%" PRIu64 ")", 3294 al->cycles->avg, al->cycles->min, 3295 al->cycles->max); 3296 3297 obj__printf(obj, "%*s ", 3298 ANNOTATION__MINMAX_CYCLES_WIDTH - 1, 3299 str); 3300 } else if (!show_title) 3301 obj__printf(obj, "%*s", 3302 ANNOTATION__MINMAX_CYCLES_WIDTH, 3303 " "); 3304 else 3305 obj__printf(obj, "%*s ", 3306 ANNOTATION__MINMAX_CYCLES_WIDTH - 1, 3307 "Cycle(min/max)"); 3308 } 3309 3310 if (show_title && !*al->line) { 3311 ipc_coverage_string(bf, sizeof(bf), notes); 3312 obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf); 3313 } 3314 } 3315 3316 obj__printf(obj, " "); 3317 3318 if (!*al->line) 3319 obj__printf(obj, "%-*s", width - pcnt_width - cycles_width, " "); 3320 else if (al->offset == -1) { 3321 if (al->line_nr && annotate_opts.show_linenr) 3322 printed = scnprintf(bf, sizeof(bf), "%-*d ", notes->widths.addr + 1, al->line_nr); 3323 else 3324 printed = scnprintf(bf, sizeof(bf), "%-*s ", notes->widths.addr, " "); 3325 obj__printf(obj, bf); 3326 obj__printf(obj, "%-*s", width - printed - pcnt_width - cycles_width + 1, al->line); 3327 } else { 3328 u64 addr = al->offset; 3329 int color = -1; 3330 3331 if (!annotate_opts.use_offset) 3332 addr += notes->start; 3333 3334 if (!annotate_opts.use_offset) { 3335 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); 3336 } else { 3337 if (al->jump_sources && 3338 annotate_opts.offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) { 3339 if (annotate_opts.show_nr_jumps) { 3340 int prev; 3341 printed = scnprintf(bf, sizeof(bf), "%*d ", 3342 notes->widths.jumps, 3343 al->jump_sources); 3344 prev = obj__set_jumps_percent_color(obj, al->jump_sources, 3345 current_entry); 3346 obj__printf(obj, bf); 3347 obj__set_color(obj, prev); 3348 } 3349 print_addr: 3350 printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", 3351 notes->widths.target, addr); 3352 } else if (ins__is_call(&disasm_line(al)->ins) && 3353 annotate_opts.offset_level >= ANNOTATION__OFFSET_CALL) { 3354 goto print_addr; 3355 } else if (annotate_opts.offset_level == ANNOTATION__MAX_OFFSET_LEVEL) { 3356 goto print_addr; 3357 } else { 3358 printed = scnprintf(bf, sizeof(bf), "%-*s ", 3359 notes->widths.addr, " "); 3360 } 3361 } 3362 3363 if (change_color) 3364 color = obj__set_color(obj, HE_COLORSET_ADDR); 3365 obj__printf(obj, bf); 3366 if (change_color) 3367 obj__set_color(obj, color); 3368 3369 disasm_line__write(disasm_line(al), notes, obj, bf, sizeof(bf), obj__printf, obj__write_graph); 3370 3371 obj__printf(obj, "%-*s", width - pcnt_width - cycles_width - 3 - printed, bf); 3372 } 3373 3374 } 3375 3376 void annotation_line__write(struct annotation_line *al, struct annotation *notes, 3377 struct annotation_write_ops *wops) 3378 { 3379 __annotation_line__write(al, notes, wops->first_line, wops->current_entry, 3380 wops->change_color, wops->width, wops->obj, 3381 annotate_opts.percent_type, 3382 wops->set_color, wops->set_percent_color, 3383 wops->set_jumps_percent_color, wops->printf, 3384 wops->write_graph); 3385 } 3386 3387 int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel, 3388 struct arch **parch) 3389 { 3390 struct symbol *sym = ms->sym; 3391 struct annotation *notes = symbol__annotation(sym); 3392 size_t size = symbol__size(sym); 3393 int nr_pcnt = 1, err; 3394 3395 notes->src->offsets = zalloc(size * sizeof(struct annotation_line *)); 3396 if (notes->src->offsets == NULL) 3397 return ENOMEM; 3398 3399 if (evsel__is_group_event(evsel)) 3400 nr_pcnt = evsel->core.nr_members; 3401 3402 err = symbol__annotate(ms, evsel, parch); 3403 if (err) 3404 goto out_free_offsets; 3405 3406 symbol__calc_percent(sym, evsel); 3407 3408 annotation__set_offsets(notes, size); 3409 annotation__mark_jump_targets(notes, sym); 3410 3411 err = annotation__compute_ipc(notes, size); 3412 if (err) 3413 goto out_free_offsets; 3414 3415 annotation__init_column_widths(notes, sym); 3416 notes->nr_events = nr_pcnt; 3417 3418 annotation__update_column_widths(notes); 3419 sym->annotate2 = 1; 3420 3421 return 0; 3422 3423 out_free_offsets: 3424 zfree(¬es->src->offsets); 3425 return err; 3426 } 3427 3428 static int annotation__config(const char *var, const char *value, void *data) 3429 { 3430 struct annotation_options *opt = data; 3431 3432 if (!strstarts(var, "annotate.")) 3433 return 0; 3434 3435 if (!strcmp(var, "annotate.offset_level")) { 3436 perf_config_u8(&opt->offset_level, "offset_level", value); 3437 3438 if (opt->offset_level > ANNOTATION__MAX_OFFSET_LEVEL) 3439 opt->offset_level = ANNOTATION__MAX_OFFSET_LEVEL; 3440 else if (opt->offset_level < ANNOTATION__MIN_OFFSET_LEVEL) 3441 opt->offset_level = ANNOTATION__MIN_OFFSET_LEVEL; 3442 } else if (!strcmp(var, "annotate.hide_src_code")) { 3443 opt->hide_src_code = perf_config_bool("hide_src_code", value); 3444 } else if (!strcmp(var, "annotate.jump_arrows")) { 3445 opt->jump_arrows = perf_config_bool("jump_arrows", value); 3446 } else if (!strcmp(var, "annotate.show_linenr")) { 3447 opt->show_linenr = perf_config_bool("show_linenr", value); 3448 } else if (!strcmp(var, "annotate.show_nr_jumps")) { 3449 opt->show_nr_jumps = perf_config_bool("show_nr_jumps", value); 3450 } else if (!strcmp(var, "annotate.show_nr_samples")) { 3451 symbol_conf.show_nr_samples = perf_config_bool("show_nr_samples", 3452 value); 3453 } else if (!strcmp(var, "annotate.show_total_period")) { 3454 symbol_conf.show_total_period = perf_config_bool("show_total_period", 3455 value); 3456 } else if (!strcmp(var, "annotate.use_offset")) { 3457 opt->use_offset = perf_config_bool("use_offset", value); 3458 } else if (!strcmp(var, "annotate.disassembler_style")) { 3459 opt->disassembler_style = strdup(value); 3460 if (!opt->disassembler_style) { 3461 pr_err("Not enough memory for annotate.disassembler_style\n"); 3462 return -1; 3463 } 3464 } else if (!strcmp(var, "annotate.objdump")) { 3465 opt->objdump_path = strdup(value); 3466 if (!opt->objdump_path) { 3467 pr_err("Not enough memory for annotate.objdump\n"); 3468 return -1; 3469 } 3470 } else if (!strcmp(var, "annotate.addr2line")) { 3471 symbol_conf.addr2line_path = strdup(value); 3472 if (!symbol_conf.addr2line_path) { 3473 pr_err("Not enough memory for annotate.addr2line\n"); 3474 return -1; 3475 } 3476 } else if (!strcmp(var, "annotate.demangle")) { 3477 symbol_conf.demangle = perf_config_bool("demangle", value); 3478 } else if (!strcmp(var, "annotate.demangle_kernel")) { 3479 symbol_conf.demangle_kernel = perf_config_bool("demangle_kernel", value); 3480 } else { 3481 pr_debug("%s variable unknown, ignoring...", var); 3482 } 3483 3484 return 0; 3485 } 3486 3487 void annotation_options__init(void) 3488 { 3489 struct annotation_options *opt = &annotate_opts; 3490 3491 memset(opt, 0, sizeof(*opt)); 3492 3493 /* Default values. */ 3494 opt->use_offset = true; 3495 opt->jump_arrows = true; 3496 opt->annotate_src = true; 3497 opt->offset_level = ANNOTATION__OFFSET_JUMP_TARGETS; 3498 opt->percent_type = PERCENT_PERIOD_LOCAL; 3499 } 3500 3501 void annotation_options__exit(void) 3502 { 3503 zfree(&annotate_opts.disassembler_style); 3504 zfree(&annotate_opts.objdump_path); 3505 } 3506 3507 void annotation_config__init(void) 3508 { 3509 perf_config(annotation__config, &annotate_opts); 3510 } 3511 3512 static unsigned int parse_percent_type(char *str1, char *str2) 3513 { 3514 unsigned int type = (unsigned int) -1; 3515 3516 if (!strcmp("period", str1)) { 3517 if (!strcmp("local", str2)) 3518 type = PERCENT_PERIOD_LOCAL; 3519 else if (!strcmp("global", str2)) 3520 type = PERCENT_PERIOD_GLOBAL; 3521 } 3522 3523 if (!strcmp("hits", str1)) { 3524 if (!strcmp("local", str2)) 3525 type = PERCENT_HITS_LOCAL; 3526 else if (!strcmp("global", str2)) 3527 type = PERCENT_HITS_GLOBAL; 3528 } 3529 3530 return type; 3531 } 3532 3533 int annotate_parse_percent_type(const struct option *opt __maybe_unused, const char *_str, 3534 int unset __maybe_unused) 3535 { 3536 unsigned int type; 3537 char *str1, *str2; 3538 int err = -1; 3539 3540 str1 = strdup(_str); 3541 if (!str1) 3542 return -ENOMEM; 3543 3544 str2 = strchr(str1, '-'); 3545 if (!str2) 3546 goto out; 3547 3548 *str2++ = 0; 3549 3550 type = parse_percent_type(str1, str2); 3551 if (type == (unsigned int) -1) 3552 type = parse_percent_type(str2, str1); 3553 if (type != (unsigned int) -1) { 3554 annotate_opts.percent_type = type; 3555 err = 0; 3556 } 3557 3558 out: 3559 free(str1); 3560 return err; 3561 } 3562 3563 int annotate_check_args(void) 3564 { 3565 struct annotation_options *args = &annotate_opts; 3566 3567 if (args->prefix_strip && !args->prefix) { 3568 pr_err("--prefix-strip requires --prefix\n"); 3569 return -1; 3570 } 3571 return 0; 3572 } 3573 3574 /* 3575 * Get register number and access offset from the given instruction. 3576 * It assumes AT&T x86 asm format like OFFSET(REG). Maybe it needs 3577 * to revisit the format when it handles different architecture. 3578 * Fills @reg and @offset when return 0. 3579 */ 3580 static int extract_reg_offset(struct arch *arch, const char *str, 3581 struct annotated_op_loc *op_loc) 3582 { 3583 char *p; 3584 char *regname; 3585 3586 if (arch->objdump.register_char == 0) 3587 return -1; 3588 3589 /* 3590 * It should start from offset, but it's possible to skip 0 3591 * in the asm. So 0(%rax) should be same as (%rax). 3592 * 3593 * However, it also start with a segment select register like 3594 * %gs:0x18(%rbx). In that case it should skip the part. 3595 */ 3596 if (*str == arch->objdump.register_char) { 3597 if (arch__is(arch, "x86")) { 3598 /* FIXME: Handle other segment registers */ 3599 if (!strncmp(str, "%gs:", 4)) 3600 op_loc->segment = INSN_SEG_X86_GS; 3601 } 3602 3603 while (*str && !isdigit(*str) && 3604 *str != arch->objdump.memory_ref_char) 3605 str++; 3606 } 3607 3608 op_loc->offset = strtol(str, &p, 0); 3609 3610 p = strchr(p, arch->objdump.register_char); 3611 if (p == NULL) 3612 return -1; 3613 3614 regname = strdup(p); 3615 if (regname == NULL) 3616 return -1; 3617 3618 op_loc->reg1 = get_dwarf_regnum(regname, 0); 3619 free(regname); 3620 3621 /* Get the second register */ 3622 if (op_loc->multi_regs) { 3623 p = strchr(p + 1, arch->objdump.register_char); 3624 if (p == NULL) 3625 return -1; 3626 3627 regname = strdup(p); 3628 if (regname == NULL) 3629 return -1; 3630 3631 op_loc->reg2 = get_dwarf_regnum(regname, 0); 3632 free(regname); 3633 } 3634 return 0; 3635 } 3636 3637 /** 3638 * annotate_get_insn_location - Get location of instruction 3639 * @arch: the architecture info 3640 * @dl: the target instruction 3641 * @loc: a buffer to save the data 3642 * 3643 * Get detailed location info (register and offset) in the instruction. 3644 * It needs both source and target operand and whether it accesses a 3645 * memory location. The offset field is meaningful only when the 3646 * corresponding mem flag is set. The reg2 field is meaningful only 3647 * when multi_regs flag is set. 3648 * 3649 * Some examples on x86: 3650 * 3651 * mov (%rax), %rcx # src_reg1 = rax, src_mem = 1, src_offset = 0 3652 * # dst_reg1 = rcx, dst_mem = 0 3653 * 3654 * mov 0x18, %r8 # src_reg1 = -1, src_mem = 0 3655 * # dst_reg1 = r8, dst_mem = 0 3656 * 3657 * mov %rsi, 8(%rbx,%rcx,4) # src_reg1 = rsi, src_mem = 0, dst_multi_regs = 0 3658 * # dst_reg1 = rbx, dst_reg2 = rcx, dst_mem = 1 3659 * # dst_multi_regs = 1, dst_offset = 8 3660 */ 3661 int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, 3662 struct annotated_insn_loc *loc) 3663 { 3664 struct ins_operands *ops; 3665 struct annotated_op_loc *op_loc; 3666 int i; 3667 3668 if (!strcmp(dl->ins.name, "lock")) 3669 ops = dl->ops.locked.ops; 3670 else 3671 ops = &dl->ops; 3672 3673 if (ops == NULL) 3674 return -1; 3675 3676 memset(loc, 0, sizeof(*loc)); 3677 3678 for_each_insn_op_loc(loc, i, op_loc) { 3679 const char *insn_str = ops->source.raw; 3680 bool multi_regs = ops->source.multi_regs; 3681 3682 if (i == INSN_OP_TARGET) { 3683 insn_str = ops->target.raw; 3684 multi_regs = ops->target.multi_regs; 3685 } 3686 3687 /* Invalidate the register by default */ 3688 op_loc->reg1 = -1; 3689 op_loc->reg2 = -1; 3690 3691 if (insn_str == NULL) 3692 continue; 3693 3694 if (strchr(insn_str, arch->objdump.memory_ref_char)) { 3695 op_loc->mem_ref = true; 3696 op_loc->multi_regs = multi_regs; 3697 extract_reg_offset(arch, insn_str, op_loc); 3698 } else { 3699 char *s, *p = NULL; 3700 3701 if (arch__is(arch, "x86")) { 3702 /* FIXME: Handle other segment registers */ 3703 if (!strncmp(insn_str, "%gs:", 4)) { 3704 op_loc->segment = INSN_SEG_X86_GS; 3705 op_loc->offset = strtol(insn_str + 4, 3706 &p, 0); 3707 if (p && p != insn_str + 4) 3708 op_loc->imm = true; 3709 continue; 3710 } 3711 } 3712 3713 s = strdup(insn_str); 3714 if (s == NULL) 3715 return -1; 3716 3717 if (*s == arch->objdump.register_char) 3718 op_loc->reg1 = get_dwarf_regnum(s, 0); 3719 else if (*s == arch->objdump.imm_char) { 3720 op_loc->offset = strtol(s + 1, &p, 0); 3721 if (p && p != s + 1) 3722 op_loc->imm = true; 3723 } 3724 free(s); 3725 } 3726 } 3727 3728 return 0; 3729 } 3730 3731 static void symbol__ensure_annotate(struct map_symbol *ms, struct evsel *evsel) 3732 { 3733 struct disasm_line *dl, *tmp_dl; 3734 struct annotation *notes; 3735 3736 notes = symbol__annotation(ms->sym); 3737 if (!list_empty(¬es->src->source)) 3738 return; 3739 3740 if (symbol__annotate(ms, evsel, NULL) < 0) 3741 return; 3742 3743 /* remove non-insn disasm lines for simplicity */ 3744 list_for_each_entry_safe(dl, tmp_dl, ¬es->src->source, al.node) { 3745 if (dl->al.offset == -1) { 3746 list_del(&dl->al.node); 3747 free(dl); 3748 } 3749 } 3750 } 3751 3752 static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip, 3753 bool allow_update) 3754 { 3755 struct disasm_line *dl; 3756 struct annotation *notes; 3757 3758 notes = symbol__annotation(sym); 3759 3760 list_for_each_entry(dl, ¬es->src->source, al.node) { 3761 if (sym->start + dl->al.offset == ip) { 3762 /* 3763 * llvm-objdump places "lock" in a separate line and 3764 * in that case, we want to get the next line. 3765 */ 3766 if (!strcmp(dl->ins.name, "lock") && 3767 *dl->ops.raw == '\0' && allow_update) { 3768 ip++; 3769 continue; 3770 } 3771 return dl; 3772 } 3773 } 3774 return NULL; 3775 } 3776 3777 static struct annotated_item_stat *annotate_data_stat(struct list_head *head, 3778 const char *name) 3779 { 3780 struct annotated_item_stat *istat; 3781 3782 list_for_each_entry(istat, head, list) { 3783 if (!strcmp(istat->name, name)) 3784 return istat; 3785 } 3786 3787 istat = zalloc(sizeof(*istat)); 3788 if (istat == NULL) 3789 return NULL; 3790 3791 istat->name = strdup(name); 3792 if (istat->name == NULL) { 3793 free(istat); 3794 return NULL; 3795 } 3796 3797 list_add_tail(&istat->list, head); 3798 return istat; 3799 } 3800 3801 static bool is_stack_operation(struct arch *arch, struct disasm_line *dl) 3802 { 3803 if (arch__is(arch, "x86")) { 3804 if (!strncmp(dl->ins.name, "push", 4) || 3805 !strncmp(dl->ins.name, "pop", 3) || 3806 !strncmp(dl->ins.name, "ret", 3)) 3807 return true; 3808 } 3809 3810 return false; 3811 } 3812 3813 static bool is_stack_canary(struct arch *arch, struct annotated_op_loc *loc) 3814 { 3815 /* On x86_64, %gs:40 is used for stack canary */ 3816 if (arch__is(arch, "x86")) { 3817 if (loc->segment == INSN_SEG_X86_GS && loc->imm && 3818 loc->offset == 40) 3819 return true; 3820 } 3821 3822 return false; 3823 } 3824 3825 u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset, 3826 struct disasm_line *dl) 3827 { 3828 struct annotation *notes; 3829 struct disasm_line *next; 3830 u64 addr; 3831 3832 notes = symbol__annotation(ms->sym); 3833 /* 3834 * PC-relative addressing starts from the next instruction address 3835 * But the IP is for the current instruction. Since disasm_line 3836 * doesn't have the instruction size, calculate it using the next 3837 * disasm_line. If it's the last one, we can use symbol's end 3838 * address directly. 3839 */ 3840 if (&dl->al.node == notes->src->source.prev) 3841 addr = ms->sym->end + offset; 3842 else { 3843 next = list_next_entry(dl, al.node); 3844 addr = ip + (next->al.offset - dl->al.offset) + offset; 3845 } 3846 return map__rip_2objdump(ms->map, addr); 3847 } 3848 3849 /** 3850 * hist_entry__get_data_type - find data type for given hist entry 3851 * @he: hist entry 3852 * 3853 * This function first annotates the instruction at @he->ip and extracts 3854 * register and offset info from it. Then it searches the DWARF debug 3855 * info to get a variable and type information using the address, register, 3856 * and offset. 3857 */ 3858 struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) 3859 { 3860 struct map_symbol *ms = &he->ms; 3861 struct evsel *evsel = hists_to_evsel(he->hists); 3862 struct arch *arch; 3863 struct disasm_line *dl; 3864 struct annotated_insn_loc loc; 3865 struct annotated_op_loc *op_loc; 3866 struct annotated_data_type *mem_type; 3867 struct annotated_item_stat *istat; 3868 u64 ip = he->ip; 3869 int i; 3870 3871 ann_data_stat.total++; 3872 3873 if (ms->map == NULL || ms->sym == NULL) { 3874 ann_data_stat.no_sym++; 3875 return NULL; 3876 } 3877 3878 if (!symbol_conf.init_annotation) { 3879 ann_data_stat.no_sym++; 3880 return NULL; 3881 } 3882 3883 if (evsel__get_arch(evsel, &arch) < 0) { 3884 ann_data_stat.no_insn++; 3885 return NULL; 3886 } 3887 3888 /* Make sure it runs objdump to get disasm of the function */ 3889 symbol__ensure_annotate(ms, evsel); 3890 3891 /* 3892 * Get a disasm to extract the location from the insn. 3893 * This is too slow... 3894 */ 3895 dl = find_disasm_line(ms->sym, ip, /*allow_update=*/true); 3896 if (dl == NULL) { 3897 ann_data_stat.no_insn++; 3898 return NULL; 3899 } 3900 3901 retry: 3902 istat = annotate_data_stat(&ann_insn_stat, dl->ins.name); 3903 if (istat == NULL) { 3904 ann_data_stat.no_insn++; 3905 return NULL; 3906 } 3907 3908 if (annotate_get_insn_location(arch, dl, &loc) < 0) { 3909 ann_data_stat.no_insn_ops++; 3910 istat->bad++; 3911 return NULL; 3912 } 3913 3914 if (is_stack_operation(arch, dl)) { 3915 istat->good++; 3916 he->mem_type_off = 0; 3917 return &stackop_type; 3918 } 3919 3920 for_each_insn_op_loc(&loc, i, op_loc) { 3921 struct data_loc_info dloc = { 3922 .arch = arch, 3923 .thread = he->thread, 3924 .ms = ms, 3925 /* Recalculate IP for LOCK prefix or insn fusion */ 3926 .ip = ms->sym->start + dl->al.offset, 3927 .cpumode = he->cpumode, 3928 .op = op_loc, 3929 }; 3930 3931 if (!op_loc->mem_ref && op_loc->segment == INSN_SEG_NONE) 3932 continue; 3933 3934 /* Recalculate IP because of LOCK prefix or insn fusion */ 3935 ip = ms->sym->start + dl->al.offset; 3936 3937 /* PC-relative addressing */ 3938 if (op_loc->reg1 == DWARF_REG_PC) { 3939 dloc.var_addr = annotate_calc_pcrel(ms, dloc.ip, 3940 op_loc->offset, dl); 3941 } 3942 3943 /* This CPU access in kernel - pretend PC-relative addressing */ 3944 if (map__dso(ms->map)->kernel && arch__is(arch, "x86") && 3945 op_loc->segment == INSN_SEG_X86_GS && op_loc->imm) { 3946 dloc.var_addr = op_loc->offset; 3947 op_loc->reg1 = DWARF_REG_PC; 3948 } 3949 3950 mem_type = find_data_type(&dloc); 3951 3952 if (mem_type == NULL && is_stack_canary(arch, op_loc)) { 3953 mem_type = &canary_type; 3954 dloc.type_offset = 0; 3955 } 3956 3957 if (mem_type) 3958 istat->good++; 3959 else 3960 istat->bad++; 3961 3962 if (symbol_conf.annotate_data_sample) { 3963 annotated_data_type__update_samples(mem_type, evsel, 3964 dloc.type_offset, 3965 he->stat.nr_events, 3966 he->stat.period); 3967 } 3968 he->mem_type_off = dloc.type_offset; 3969 return mem_type; 3970 } 3971 3972 /* 3973 * Some instructions can be fused and the actual memory access came 3974 * from the previous instruction. 3975 */ 3976 if (dl->al.offset > 0) { 3977 struct disasm_line *prev_dl; 3978 3979 prev_dl = list_prev_entry(dl, al.node); 3980 if (ins__is_fused(arch, prev_dl->ins.name, dl->ins.name)) { 3981 dl = prev_dl; 3982 goto retry; 3983 } 3984 } 3985 3986 ann_data_stat.no_mem_ops++; 3987 istat->bad++; 3988 return NULL; 3989 } 3990 3991 /* Basic block traversal (BFS) data structure */ 3992 struct basic_block_data { 3993 struct list_head queue; 3994 struct list_head visited; 3995 }; 3996 3997 /* 3998 * During the traversal, it needs to know the parent block where the current 3999 * block block started from. Note that single basic block can be parent of 4000 * two child basic blocks (in case of condition jump). 4001 */ 4002 struct basic_block_link { 4003 struct list_head node; 4004 struct basic_block_link *parent; 4005 struct annotated_basic_block *bb; 4006 }; 4007 4008 /* Check any of basic block in the list already has the offset */ 4009 static bool basic_block_has_offset(struct list_head *head, s64 offset) 4010 { 4011 struct basic_block_link *link; 4012 4013 list_for_each_entry(link, head, node) { 4014 s64 begin_offset = link->bb->begin->al.offset; 4015 s64 end_offset = link->bb->end->al.offset; 4016 4017 if (begin_offset <= offset && offset <= end_offset) 4018 return true; 4019 } 4020 return false; 4021 } 4022 4023 static bool is_new_basic_block(struct basic_block_data *bb_data, 4024 struct disasm_line *dl) 4025 { 4026 s64 offset = dl->al.offset; 4027 4028 if (basic_block_has_offset(&bb_data->visited, offset)) 4029 return false; 4030 if (basic_block_has_offset(&bb_data->queue, offset)) 4031 return false; 4032 return true; 4033 } 4034 4035 /* Add a basic block starting from dl and link it to the parent */ 4036 static int add_basic_block(struct basic_block_data *bb_data, 4037 struct basic_block_link *parent, 4038 struct disasm_line *dl) 4039 { 4040 struct annotated_basic_block *bb; 4041 struct basic_block_link *link; 4042 4043 if (dl == NULL) 4044 return -1; 4045 4046 if (!is_new_basic_block(bb_data, dl)) 4047 return 0; 4048 4049 bb = zalloc(sizeof(*bb)); 4050 if (bb == NULL) 4051 return -1; 4052 4053 bb->begin = dl; 4054 bb->end = dl; 4055 INIT_LIST_HEAD(&bb->list); 4056 4057 link = malloc(sizeof(*link)); 4058 if (link == NULL) { 4059 free(bb); 4060 return -1; 4061 } 4062 4063 link->bb = bb; 4064 link->parent = parent; 4065 list_add_tail(&link->node, &bb_data->queue); 4066 return 0; 4067 } 4068 4069 /* Returns true when it finds the target in the current basic block */ 4070 static bool process_basic_block(struct basic_block_data *bb_data, 4071 struct basic_block_link *link, 4072 struct symbol *sym, u64 target) 4073 { 4074 struct disasm_line *dl, *next_dl, *last_dl; 4075 struct annotation *notes = symbol__annotation(sym); 4076 bool found = false; 4077 4078 dl = link->bb->begin; 4079 /* Check if it's already visited */ 4080 if (basic_block_has_offset(&bb_data->visited, dl->al.offset)) 4081 return false; 4082 4083 last_dl = list_last_entry(¬es->src->source, 4084 struct disasm_line, al.node); 4085 4086 list_for_each_entry_from(dl, ¬es->src->source, al.node) { 4087 /* Found the target instruction */ 4088 if (sym->start + dl->al.offset == target) { 4089 found = true; 4090 break; 4091 } 4092 /* End of the function, finish the block */ 4093 if (dl == last_dl) 4094 break; 4095 /* 'return' instruction finishes the block */ 4096 if (dl->ins.ops == &ret_ops) 4097 break; 4098 /* normal instructions are part of the basic block */ 4099 if (dl->ins.ops != &jump_ops) 4100 continue; 4101 /* jump to a different function, tail call or return */ 4102 if (dl->ops.target.outside) 4103 break; 4104 /* jump instruction creates new basic block(s) */ 4105 next_dl = find_disasm_line(sym, sym->start + dl->ops.target.offset, 4106 /*allow_update=*/false); 4107 add_basic_block(bb_data, link, next_dl); 4108 4109 /* 4110 * FIXME: determine conditional jumps properly. 4111 * Conditional jumps create another basic block with the 4112 * next disasm line. 4113 */ 4114 if (!strstr(dl->ins.name, "jmp")) { 4115 next_dl = list_next_entry(dl, al.node); 4116 add_basic_block(bb_data, link, next_dl); 4117 } 4118 break; 4119 4120 } 4121 link->bb->end = dl; 4122 return found; 4123 } 4124 4125 /* 4126 * It founds a target basic block, build a proper linked list of basic blocks 4127 * by following the link recursively. 4128 */ 4129 static void link_found_basic_blocks(struct basic_block_link *link, 4130 struct list_head *head) 4131 { 4132 while (link) { 4133 struct basic_block_link *parent = link->parent; 4134 4135 list_move(&link->bb->list, head); 4136 list_del(&link->node); 4137 free(link); 4138 4139 link = parent; 4140 } 4141 } 4142 4143 static void delete_basic_blocks(struct basic_block_data *bb_data) 4144 { 4145 struct basic_block_link *link, *tmp; 4146 4147 list_for_each_entry_safe(link, tmp, &bb_data->queue, node) { 4148 list_del(&link->node); 4149 free(link->bb); 4150 free(link); 4151 } 4152 4153 list_for_each_entry_safe(link, tmp, &bb_data->visited, node) { 4154 list_del(&link->node); 4155 free(link->bb); 4156 free(link); 4157 } 4158 } 4159 4160 /** 4161 * annotate_get_basic_blocks - Get basic blocks for given address range 4162 * @sym: symbol to annotate 4163 * @src: source address 4164 * @dst: destination address 4165 * @head: list head to save basic blocks 4166 * 4167 * This function traverses disasm_lines from @src to @dst and save them in a 4168 * list of annotated_basic_block to @head. It uses BFS to find the shortest 4169 * path between two. The basic_block_link is to maintain parent links so 4170 * that it can build a list of blocks from the start. 4171 */ 4172 int annotate_get_basic_blocks(struct symbol *sym, s64 src, s64 dst, 4173 struct list_head *head) 4174 { 4175 struct basic_block_data bb_data = { 4176 .queue = LIST_HEAD_INIT(bb_data.queue), 4177 .visited = LIST_HEAD_INIT(bb_data.visited), 4178 }; 4179 struct basic_block_link *link; 4180 struct disasm_line *dl; 4181 int ret = -1; 4182 4183 dl = find_disasm_line(sym, src, /*allow_update=*/false); 4184 if (dl == NULL) 4185 return -1; 4186 4187 if (add_basic_block(&bb_data, /*parent=*/NULL, dl) < 0) 4188 return -1; 4189 4190 /* Find shortest path from src to dst using BFS */ 4191 while (!list_empty(&bb_data.queue)) { 4192 link = list_first_entry(&bb_data.queue, struct basic_block_link, node); 4193 4194 if (process_basic_block(&bb_data, link, sym, dst)) { 4195 link_found_basic_blocks(link, head); 4196 ret = 0; 4197 break; 4198 } 4199 list_move(&link->node, &bb_data.visited); 4200 } 4201 delete_basic_blocks(&bb_data); 4202 return ret; 4203 } 4204