1 // SPDX-License-Identifier: GPL-2.0 2 #include <inttypes.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #include <linux/kernel.h> 8 #include <linux/string.h> 9 #include <linux/zalloc.h> 10 11 #include "util/dso.h" 12 #include "util/debug.h" 13 #include "util/callchain.h" 14 #include "util/symbol_conf.h" 15 #include "srcline.h" 16 #include "string2.h" 17 #include "symbol.h" 18 19 bool srcline_full_filename; 20 21 static const char *dso__name(struct dso *dso) 22 { 23 const char *dso_name; 24 25 if (dso->symsrc_filename) 26 dso_name = dso->symsrc_filename; 27 else 28 dso_name = dso->long_name; 29 30 if (dso_name[0] == '[') 31 return NULL; 32 33 if (!strncmp(dso_name, "/tmp/perf-", 10)) 34 return NULL; 35 36 return dso_name; 37 } 38 39 static int inline_list__append(struct symbol *symbol, char *srcline, 40 struct inline_node *node) 41 { 42 struct inline_list *ilist; 43 44 ilist = zalloc(sizeof(*ilist)); 45 if (ilist == NULL) 46 return -1; 47 48 ilist->symbol = symbol; 49 ilist->srcline = srcline; 50 51 if (callchain_param.order == ORDER_CALLEE) 52 list_add_tail(&ilist->list, &node->val); 53 else 54 list_add(&ilist->list, &node->val); 55 56 return 0; 57 } 58 59 /* basename version that takes a const input string */ 60 static const char *gnu_basename(const char *path) 61 { 62 const char *base = strrchr(path, '/'); 63 64 return base ? base + 1 : path; 65 } 66 67 static char *srcline_from_fileline(const char *file, unsigned int line) 68 { 69 char *srcline; 70 71 if (!file) 72 return NULL; 73 74 if (!srcline_full_filename) 75 file = gnu_basename(file); 76 77 if (asprintf(&srcline, "%s:%u", file, line) < 0) 78 return NULL; 79 80 return srcline; 81 } 82 83 static struct symbol *new_inline_sym(struct dso *dso, 84 struct symbol *base_sym, 85 const char *funcname) 86 { 87 struct symbol *inline_sym; 88 char *demangled = NULL; 89 90 if (!funcname) 91 funcname = "??"; 92 93 if (dso) { 94 demangled = dso__demangle_sym(dso, 0, funcname); 95 if (demangled) 96 funcname = demangled; 97 } 98 99 if (base_sym && strcmp(funcname, base_sym->name) == 0) { 100 /* reuse the real, existing symbol */ 101 inline_sym = base_sym; 102 /* ensure that we don't alias an inlined symbol, which could 103 * lead to double frees in inline_node__delete 104 */ 105 assert(!base_sym->inlined); 106 } else { 107 /* create a fake symbol for the inline frame */ 108 inline_sym = symbol__new(base_sym ? base_sym->start : 0, 109 base_sym ? (base_sym->end - base_sym->start) : 0, 110 base_sym ? base_sym->binding : 0, 111 base_sym ? base_sym->type : 0, 112 funcname); 113 if (inline_sym) 114 inline_sym->inlined = 1; 115 } 116 117 free(demangled); 118 119 return inline_sym; 120 } 121 122 #ifdef HAVE_LIBBFD_SUPPORT 123 124 /* 125 * Implement addr2line using libbfd. 126 */ 127 #define PACKAGE "perf" 128 #include <bfd.h> 129 130 struct a2l_data { 131 const char *input; 132 u64 addr; 133 134 bool found; 135 const char *filename; 136 const char *funcname; 137 unsigned line; 138 139 bfd *abfd; 140 asymbol **syms; 141 }; 142 143 static int bfd_error(const char *string) 144 { 145 const char *errmsg; 146 147 errmsg = bfd_errmsg(bfd_get_error()); 148 fflush(stdout); 149 150 if (string) 151 pr_debug("%s: %s\n", string, errmsg); 152 else 153 pr_debug("%s\n", errmsg); 154 155 return -1; 156 } 157 158 static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) 159 { 160 long storage; 161 long symcount; 162 asymbol **syms; 163 bfd_boolean dynamic = FALSE; 164 165 if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) 166 return bfd_error(bfd_get_filename(abfd)); 167 168 storage = bfd_get_symtab_upper_bound(abfd); 169 if (storage == 0L) { 170 storage = bfd_get_dynamic_symtab_upper_bound(abfd); 171 dynamic = TRUE; 172 } 173 if (storage < 0L) 174 return bfd_error(bfd_get_filename(abfd)); 175 176 syms = malloc(storage); 177 if (dynamic) 178 symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); 179 else 180 symcount = bfd_canonicalize_symtab(abfd, syms); 181 182 if (symcount < 0) { 183 free(syms); 184 return bfd_error(bfd_get_filename(abfd)); 185 } 186 187 a2l->syms = syms; 188 return 0; 189 } 190 191 static void find_address_in_section(bfd *abfd, asection *section, void *data) 192 { 193 bfd_vma pc, vma; 194 bfd_size_type size; 195 struct a2l_data *a2l = data; 196 flagword flags; 197 198 if (a2l->found) 199 return; 200 201 #ifdef bfd_get_section_flags 202 flags = bfd_get_section_flags(abfd, section); 203 #else 204 flags = bfd_section_flags(section); 205 #endif 206 if ((flags & SEC_ALLOC) == 0) 207 return; 208 209 pc = a2l->addr; 210 #ifdef bfd_get_section_vma 211 vma = bfd_get_section_vma(abfd, section); 212 #else 213 vma = bfd_section_vma(section); 214 #endif 215 #ifdef bfd_get_section_size 216 size = bfd_get_section_size(section); 217 #else 218 size = bfd_section_size(section); 219 #endif 220 221 if (pc < vma || pc >= vma + size) 222 return; 223 224 a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, 225 &a2l->filename, &a2l->funcname, 226 &a2l->line); 227 228 if (a2l->filename && !strlen(a2l->filename)) 229 a2l->filename = NULL; 230 } 231 232 static struct a2l_data *addr2line_init(const char *path) 233 { 234 bfd *abfd; 235 struct a2l_data *a2l = NULL; 236 237 abfd = bfd_openr(path, NULL); 238 if (abfd == NULL) 239 return NULL; 240 241 if (!bfd_check_format(abfd, bfd_object)) 242 goto out; 243 244 a2l = zalloc(sizeof(*a2l)); 245 if (a2l == NULL) 246 goto out; 247 248 a2l->abfd = abfd; 249 a2l->input = strdup(path); 250 if (a2l->input == NULL) 251 goto out; 252 253 if (slurp_symtab(abfd, a2l)) 254 goto out; 255 256 return a2l; 257 258 out: 259 if (a2l) { 260 zfree((char **)&a2l->input); 261 free(a2l); 262 } 263 bfd_close(abfd); 264 return NULL; 265 } 266 267 static void addr2line_cleanup(struct a2l_data *a2l) 268 { 269 if (a2l->abfd) 270 bfd_close(a2l->abfd); 271 zfree((char **)&a2l->input); 272 zfree(&a2l->syms); 273 free(a2l); 274 } 275 276 #define MAX_INLINE_NEST 1024 277 278 static int inline_list__append_dso_a2l(struct dso *dso, 279 struct inline_node *node, 280 struct symbol *sym) 281 { 282 struct a2l_data *a2l = dso->a2l; 283 struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname); 284 char *srcline = NULL; 285 286 if (a2l->filename) 287 srcline = srcline_from_fileline(a2l->filename, a2l->line); 288 289 return inline_list__append(inline_sym, srcline, node); 290 } 291 292 static int addr2line(const char *dso_name, u64 addr, 293 char **file, unsigned int *line, struct dso *dso, 294 bool unwind_inlines, struct inline_node *node, 295 struct symbol *sym) 296 { 297 int ret = 0; 298 struct a2l_data *a2l = dso->a2l; 299 300 if (!a2l) { 301 dso->a2l = addr2line_init(dso_name); 302 a2l = dso->a2l; 303 } 304 305 if (a2l == NULL) { 306 if (!symbol_conf.disable_add2line_warn) 307 pr_warning("addr2line_init failed for %s\n", dso_name); 308 return 0; 309 } 310 311 a2l->addr = addr; 312 a2l->found = false; 313 314 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 315 316 if (!a2l->found) 317 return 0; 318 319 if (unwind_inlines) { 320 int cnt = 0; 321 322 if (node && inline_list__append_dso_a2l(dso, node, sym)) 323 return 0; 324 325 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, 326 &a2l->funcname, &a2l->line) && 327 cnt++ < MAX_INLINE_NEST) { 328 329 if (a2l->filename && !strlen(a2l->filename)) 330 a2l->filename = NULL; 331 332 if (node != NULL) { 333 if (inline_list__append_dso_a2l(dso, node, sym)) 334 return 0; 335 // found at least one inline frame 336 ret = 1; 337 } 338 } 339 } 340 341 if (file) { 342 *file = a2l->filename ? strdup(a2l->filename) : NULL; 343 ret = *file ? 1 : 0; 344 } 345 346 if (line) 347 *line = a2l->line; 348 349 return ret; 350 } 351 352 void dso__free_a2l(struct dso *dso) 353 { 354 struct a2l_data *a2l = dso->a2l; 355 356 if (!a2l) 357 return; 358 359 addr2line_cleanup(a2l); 360 361 dso->a2l = NULL; 362 } 363 364 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 365 struct dso *dso, struct symbol *sym) 366 { 367 struct inline_node *node; 368 369 node = zalloc(sizeof(*node)); 370 if (node == NULL) { 371 perror("not enough memory for the inline node"); 372 return NULL; 373 } 374 375 INIT_LIST_HEAD(&node->val); 376 node->addr = addr; 377 378 addr2line(dso_name, addr, NULL, NULL, dso, true, node, sym); 379 return node; 380 } 381 382 #else /* HAVE_LIBBFD_SUPPORT */ 383 384 static int filename_split(char *filename, unsigned int *line_nr) 385 { 386 char *sep; 387 388 sep = strchr(filename, '\n'); 389 if (sep) 390 *sep = '\0'; 391 392 if (!strcmp(filename, "??:0")) 393 return 0; 394 395 sep = strchr(filename, ':'); 396 if (sep) { 397 *sep++ = '\0'; 398 *line_nr = strtoul(sep, NULL, 0); 399 return 1; 400 } 401 402 return 0; 403 } 404 405 static int addr2line(const char *dso_name, u64 addr, 406 char **file, unsigned int *line_nr, 407 struct dso *dso __maybe_unused, 408 bool unwind_inlines __maybe_unused, 409 struct inline_node *node __maybe_unused, 410 struct symbol *sym __maybe_unused) 411 { 412 FILE *fp; 413 char cmd[PATH_MAX]; 414 char *filename = NULL; 415 size_t len; 416 int ret = 0; 417 418 scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, 419 dso_name, addr); 420 421 fp = popen(cmd, "r"); 422 if (fp == NULL) { 423 pr_warning("popen failed for %s\n", dso_name); 424 return 0; 425 } 426 427 if (getline(&filename, &len, fp) < 0 || !len) { 428 pr_warning("addr2line has no output for %s\n", dso_name); 429 goto out; 430 } 431 432 ret = filename_split(filename, line_nr); 433 if (ret != 1) { 434 free(filename); 435 goto out; 436 } 437 438 *file = filename; 439 440 out: 441 pclose(fp); 442 return ret; 443 } 444 445 void dso__free_a2l(struct dso *dso __maybe_unused) 446 { 447 } 448 449 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 450 struct dso *dso __maybe_unused, 451 struct symbol *sym) 452 { 453 FILE *fp; 454 char cmd[PATH_MAX]; 455 struct inline_node *node; 456 char *filename = NULL; 457 char *funcname = NULL; 458 size_t filelen, funclen; 459 unsigned int line_nr = 0; 460 461 scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i -f %016"PRIx64, 462 dso_name, addr); 463 464 fp = popen(cmd, "r"); 465 if (fp == NULL) { 466 pr_err("popen failed for %s\n", dso_name); 467 return NULL; 468 } 469 470 node = zalloc(sizeof(*node)); 471 if (node == NULL) { 472 perror("not enough memory for the inline node"); 473 goto out; 474 } 475 476 INIT_LIST_HEAD(&node->val); 477 node->addr = addr; 478 479 /* addr2line -f generates two lines for each inlined functions */ 480 while (getline(&funcname, &funclen, fp) != -1) { 481 char *srcline; 482 struct symbol *inline_sym; 483 484 strim(funcname); 485 486 if (getline(&filename, &filelen, fp) == -1) 487 goto out; 488 489 if (filename_split(filename, &line_nr) != 1) 490 goto out; 491 492 srcline = srcline_from_fileline(filename, line_nr); 493 inline_sym = new_inline_sym(dso, sym, funcname); 494 495 if (inline_list__append(inline_sym, srcline, node) != 0) { 496 free(srcline); 497 if (inline_sym && inline_sym->inlined) 498 symbol__delete(inline_sym); 499 goto out; 500 } 501 } 502 503 out: 504 pclose(fp); 505 free(filename); 506 free(funcname); 507 508 return node; 509 } 510 511 #endif /* HAVE_LIBBFD_SUPPORT */ 512 513 /* 514 * Number of addr2line failures (without success) before disabling it for that 515 * dso. 516 */ 517 #define A2L_FAIL_LIMIT 123 518 519 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 520 bool show_sym, bool show_addr, bool unwind_inlines, 521 u64 ip) 522 { 523 char *file = NULL; 524 unsigned line = 0; 525 char *srcline; 526 const char *dso_name; 527 528 if (!dso->has_srcline) 529 goto out; 530 531 dso_name = dso__name(dso); 532 if (dso_name == NULL) 533 goto out; 534 535 if (!addr2line(dso_name, addr, &file, &line, dso, 536 unwind_inlines, NULL, sym)) 537 goto out; 538 539 srcline = srcline_from_fileline(file, line); 540 free(file); 541 542 if (!srcline) 543 goto out; 544 545 dso->a2l_fails = 0; 546 547 return srcline; 548 549 out: 550 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 551 dso->has_srcline = 0; 552 dso__free_a2l(dso); 553 } 554 555 if (!show_addr) 556 return (show_sym && sym) ? 557 strndup(sym->name, sym->namelen) : NULL; 558 559 if (sym) { 560 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", 561 ip - sym->start) < 0) 562 return SRCLINE_UNKNOWN; 563 } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) 564 return SRCLINE_UNKNOWN; 565 return srcline; 566 } 567 568 /* Returns filename and fills in line number in line */ 569 char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line) 570 { 571 char *file = NULL; 572 const char *dso_name; 573 574 if (!dso->has_srcline) 575 goto out; 576 577 dso_name = dso__name(dso); 578 if (dso_name == NULL) 579 goto out; 580 581 if (!addr2line(dso_name, addr, &file, line, dso, true, NULL, NULL)) 582 goto out; 583 584 dso->a2l_fails = 0; 585 return file; 586 587 out: 588 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 589 dso->has_srcline = 0; 590 dso__free_a2l(dso); 591 } 592 593 return NULL; 594 } 595 596 void free_srcline(char *srcline) 597 { 598 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) 599 free(srcline); 600 } 601 602 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 603 bool show_sym, bool show_addr, u64 ip) 604 { 605 return __get_srcline(dso, addr, sym, show_sym, show_addr, false, ip); 606 } 607 608 struct srcline_node { 609 u64 addr; 610 char *srcline; 611 struct rb_node rb_node; 612 }; 613 614 void srcline__tree_insert(struct rb_root_cached *tree, u64 addr, char *srcline) 615 { 616 struct rb_node **p = &tree->rb_root.rb_node; 617 struct rb_node *parent = NULL; 618 struct srcline_node *i, *node; 619 bool leftmost = true; 620 621 node = zalloc(sizeof(struct srcline_node)); 622 if (!node) { 623 perror("not enough memory for the srcline node"); 624 return; 625 } 626 627 node->addr = addr; 628 node->srcline = srcline; 629 630 while (*p != NULL) { 631 parent = *p; 632 i = rb_entry(parent, struct srcline_node, rb_node); 633 if (addr < i->addr) 634 p = &(*p)->rb_left; 635 else { 636 p = &(*p)->rb_right; 637 leftmost = false; 638 } 639 } 640 rb_link_node(&node->rb_node, parent, p); 641 rb_insert_color_cached(&node->rb_node, tree, leftmost); 642 } 643 644 char *srcline__tree_find(struct rb_root_cached *tree, u64 addr) 645 { 646 struct rb_node *n = tree->rb_root.rb_node; 647 648 while (n) { 649 struct srcline_node *i = rb_entry(n, struct srcline_node, 650 rb_node); 651 652 if (addr < i->addr) 653 n = n->rb_left; 654 else if (addr > i->addr) 655 n = n->rb_right; 656 else 657 return i->srcline; 658 } 659 660 return NULL; 661 } 662 663 void srcline__tree_delete(struct rb_root_cached *tree) 664 { 665 struct srcline_node *pos; 666 struct rb_node *next = rb_first_cached(tree); 667 668 while (next) { 669 pos = rb_entry(next, struct srcline_node, rb_node); 670 next = rb_next(&pos->rb_node); 671 rb_erase_cached(&pos->rb_node, tree); 672 free_srcline(pos->srcline); 673 zfree(&pos); 674 } 675 } 676 677 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, 678 struct symbol *sym) 679 { 680 const char *dso_name; 681 682 dso_name = dso__name(dso); 683 if (dso_name == NULL) 684 return NULL; 685 686 return addr2inlines(dso_name, addr, dso, sym); 687 } 688 689 void inline_node__delete(struct inline_node *node) 690 { 691 struct inline_list *ilist, *tmp; 692 693 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 694 list_del_init(&ilist->list); 695 free_srcline(ilist->srcline); 696 /* only the inlined symbols are owned by the list */ 697 if (ilist->symbol && ilist->symbol->inlined) 698 symbol__delete(ilist->symbol); 699 free(ilist); 700 } 701 702 free(node); 703 } 704 705 void inlines__tree_insert(struct rb_root_cached *tree, 706 struct inline_node *inlines) 707 { 708 struct rb_node **p = &tree->rb_root.rb_node; 709 struct rb_node *parent = NULL; 710 const u64 addr = inlines->addr; 711 struct inline_node *i; 712 bool leftmost = true; 713 714 while (*p != NULL) { 715 parent = *p; 716 i = rb_entry(parent, struct inline_node, rb_node); 717 if (addr < i->addr) 718 p = &(*p)->rb_left; 719 else { 720 p = &(*p)->rb_right; 721 leftmost = false; 722 } 723 } 724 rb_link_node(&inlines->rb_node, parent, p); 725 rb_insert_color_cached(&inlines->rb_node, tree, leftmost); 726 } 727 728 struct inline_node *inlines__tree_find(struct rb_root_cached *tree, u64 addr) 729 { 730 struct rb_node *n = tree->rb_root.rb_node; 731 732 while (n) { 733 struct inline_node *i = rb_entry(n, struct inline_node, 734 rb_node); 735 736 if (addr < i->addr) 737 n = n->rb_left; 738 else if (addr > i->addr) 739 n = n->rb_right; 740 else 741 return i; 742 } 743 744 return NULL; 745 } 746 747 void inlines__tree_delete(struct rb_root_cached *tree) 748 { 749 struct inline_node *pos; 750 struct rb_node *next = rb_first_cached(tree); 751 752 while (next) { 753 pos = rb_entry(next, struct inline_node, rb_node); 754 next = rb_next(&pos->rb_node); 755 rb_erase_cached(&pos->rb_node, tree); 756 inline_node__delete(pos); 757 } 758 } 759