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 197 if (a2l->found) 198 return; 199 200 if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) 201 return; 202 203 pc = a2l->addr; 204 vma = bfd_get_section_vma(abfd, section); 205 size = bfd_get_section_size(section); 206 207 if (pc < vma || pc >= vma + size) 208 return; 209 210 a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, 211 &a2l->filename, &a2l->funcname, 212 &a2l->line); 213 214 if (a2l->filename && !strlen(a2l->filename)) 215 a2l->filename = NULL; 216 } 217 218 static struct a2l_data *addr2line_init(const char *path) 219 { 220 bfd *abfd; 221 struct a2l_data *a2l = NULL; 222 223 abfd = bfd_openr(path, NULL); 224 if (abfd == NULL) 225 return NULL; 226 227 if (!bfd_check_format(abfd, bfd_object)) 228 goto out; 229 230 a2l = zalloc(sizeof(*a2l)); 231 if (a2l == NULL) 232 goto out; 233 234 a2l->abfd = abfd; 235 a2l->input = strdup(path); 236 if (a2l->input == NULL) 237 goto out; 238 239 if (slurp_symtab(abfd, a2l)) 240 goto out; 241 242 return a2l; 243 244 out: 245 if (a2l) { 246 zfree((char **)&a2l->input); 247 free(a2l); 248 } 249 bfd_close(abfd); 250 return NULL; 251 } 252 253 static void addr2line_cleanup(struct a2l_data *a2l) 254 { 255 if (a2l->abfd) 256 bfd_close(a2l->abfd); 257 zfree((char **)&a2l->input); 258 zfree(&a2l->syms); 259 free(a2l); 260 } 261 262 #define MAX_INLINE_NEST 1024 263 264 static int inline_list__append_dso_a2l(struct dso *dso, 265 struct inline_node *node, 266 struct symbol *sym) 267 { 268 struct a2l_data *a2l = dso->a2l; 269 struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname); 270 char *srcline = NULL; 271 272 if (a2l->filename) 273 srcline = srcline_from_fileline(a2l->filename, a2l->line); 274 275 return inline_list__append(inline_sym, srcline, node); 276 } 277 278 static int addr2line(const char *dso_name, u64 addr, 279 char **file, unsigned int *line, struct dso *dso, 280 bool unwind_inlines, struct inline_node *node, 281 struct symbol *sym) 282 { 283 int ret = 0; 284 struct a2l_data *a2l = dso->a2l; 285 286 if (!a2l) { 287 dso->a2l = addr2line_init(dso_name); 288 a2l = dso->a2l; 289 } 290 291 if (a2l == NULL) { 292 if (!symbol_conf.disable_add2line_warn) 293 pr_warning("addr2line_init failed for %s\n", dso_name); 294 return 0; 295 } 296 297 a2l->addr = addr; 298 a2l->found = false; 299 300 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 301 302 if (!a2l->found) 303 return 0; 304 305 if (unwind_inlines) { 306 int cnt = 0; 307 308 if (node && inline_list__append_dso_a2l(dso, node, sym)) 309 return 0; 310 311 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, 312 &a2l->funcname, &a2l->line) && 313 cnt++ < MAX_INLINE_NEST) { 314 315 if (a2l->filename && !strlen(a2l->filename)) 316 a2l->filename = NULL; 317 318 if (node != NULL) { 319 if (inline_list__append_dso_a2l(dso, node, sym)) 320 return 0; 321 // found at least one inline frame 322 ret = 1; 323 } 324 } 325 } 326 327 if (file) { 328 *file = a2l->filename ? strdup(a2l->filename) : NULL; 329 ret = *file ? 1 : 0; 330 } 331 332 if (line) 333 *line = a2l->line; 334 335 return ret; 336 } 337 338 void dso__free_a2l(struct dso *dso) 339 { 340 struct a2l_data *a2l = dso->a2l; 341 342 if (!a2l) 343 return; 344 345 addr2line_cleanup(a2l); 346 347 dso->a2l = NULL; 348 } 349 350 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 351 struct dso *dso, struct symbol *sym) 352 { 353 struct inline_node *node; 354 355 node = zalloc(sizeof(*node)); 356 if (node == NULL) { 357 perror("not enough memory for the inline node"); 358 return NULL; 359 } 360 361 INIT_LIST_HEAD(&node->val); 362 node->addr = addr; 363 364 addr2line(dso_name, addr, NULL, NULL, dso, true, node, sym); 365 return node; 366 } 367 368 #else /* HAVE_LIBBFD_SUPPORT */ 369 370 static int filename_split(char *filename, unsigned int *line_nr) 371 { 372 char *sep; 373 374 sep = strchr(filename, '\n'); 375 if (sep) 376 *sep = '\0'; 377 378 if (!strcmp(filename, "??:0")) 379 return 0; 380 381 sep = strchr(filename, ':'); 382 if (sep) { 383 *sep++ = '\0'; 384 *line_nr = strtoul(sep, NULL, 0); 385 return 1; 386 } 387 388 return 0; 389 } 390 391 static int addr2line(const char *dso_name, u64 addr, 392 char **file, unsigned int *line_nr, 393 struct dso *dso __maybe_unused, 394 bool unwind_inlines __maybe_unused, 395 struct inline_node *node __maybe_unused, 396 struct symbol *sym __maybe_unused) 397 { 398 FILE *fp; 399 char cmd[PATH_MAX]; 400 char *filename = NULL; 401 size_t len; 402 int ret = 0; 403 404 scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, 405 dso_name, addr); 406 407 fp = popen(cmd, "r"); 408 if (fp == NULL) { 409 pr_warning("popen failed for %s\n", dso_name); 410 return 0; 411 } 412 413 if (getline(&filename, &len, fp) < 0 || !len) { 414 pr_warning("addr2line has no output for %s\n", dso_name); 415 goto out; 416 } 417 418 ret = filename_split(filename, line_nr); 419 if (ret != 1) { 420 free(filename); 421 goto out; 422 } 423 424 *file = filename; 425 426 out: 427 pclose(fp); 428 return ret; 429 } 430 431 void dso__free_a2l(struct dso *dso __maybe_unused) 432 { 433 } 434 435 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 436 struct dso *dso __maybe_unused, 437 struct symbol *sym) 438 { 439 FILE *fp; 440 char cmd[PATH_MAX]; 441 struct inline_node *node; 442 char *filename = NULL; 443 char *funcname = NULL; 444 size_t filelen, funclen; 445 unsigned int line_nr = 0; 446 447 scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i -f %016"PRIx64, 448 dso_name, addr); 449 450 fp = popen(cmd, "r"); 451 if (fp == NULL) { 452 pr_err("popen failed for %s\n", dso_name); 453 return NULL; 454 } 455 456 node = zalloc(sizeof(*node)); 457 if (node == NULL) { 458 perror("not enough memory for the inline node"); 459 goto out; 460 } 461 462 INIT_LIST_HEAD(&node->val); 463 node->addr = addr; 464 465 /* addr2line -f generates two lines for each inlined functions */ 466 while (getline(&funcname, &funclen, fp) != -1) { 467 char *srcline; 468 struct symbol *inline_sym; 469 470 strim(funcname); 471 472 if (getline(&filename, &filelen, fp) == -1) 473 goto out; 474 475 if (filename_split(filename, &line_nr) != 1) 476 goto out; 477 478 srcline = srcline_from_fileline(filename, line_nr); 479 inline_sym = new_inline_sym(dso, sym, funcname); 480 481 if (inline_list__append(inline_sym, srcline, node) != 0) { 482 free(srcline); 483 if (inline_sym && inline_sym->inlined) 484 symbol__delete(inline_sym); 485 goto out; 486 } 487 } 488 489 out: 490 pclose(fp); 491 free(filename); 492 free(funcname); 493 494 return node; 495 } 496 497 #endif /* HAVE_LIBBFD_SUPPORT */ 498 499 /* 500 * Number of addr2line failures (without success) before disabling it for that 501 * dso. 502 */ 503 #define A2L_FAIL_LIMIT 123 504 505 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 506 bool show_sym, bool show_addr, bool unwind_inlines, 507 u64 ip) 508 { 509 char *file = NULL; 510 unsigned line = 0; 511 char *srcline; 512 const char *dso_name; 513 514 if (!dso->has_srcline) 515 goto out; 516 517 dso_name = dso__name(dso); 518 if (dso_name == NULL) 519 goto out; 520 521 if (!addr2line(dso_name, addr, &file, &line, dso, 522 unwind_inlines, NULL, sym)) 523 goto out; 524 525 srcline = srcline_from_fileline(file, line); 526 free(file); 527 528 if (!srcline) 529 goto out; 530 531 dso->a2l_fails = 0; 532 533 return srcline; 534 535 out: 536 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 537 dso->has_srcline = 0; 538 dso__free_a2l(dso); 539 } 540 541 if (!show_addr) 542 return (show_sym && sym) ? 543 strndup(sym->name, sym->namelen) : NULL; 544 545 if (sym) { 546 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", 547 ip - sym->start) < 0) 548 return SRCLINE_UNKNOWN; 549 } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) 550 return SRCLINE_UNKNOWN; 551 return srcline; 552 } 553 554 /* Returns filename and fills in line number in line */ 555 char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line) 556 { 557 char *file = NULL; 558 const char *dso_name; 559 560 if (!dso->has_srcline) 561 goto out; 562 563 dso_name = dso__name(dso); 564 if (dso_name == NULL) 565 goto out; 566 567 if (!addr2line(dso_name, addr, &file, line, dso, true, NULL, NULL)) 568 goto out; 569 570 dso->a2l_fails = 0; 571 return file; 572 573 out: 574 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 575 dso->has_srcline = 0; 576 dso__free_a2l(dso); 577 } 578 579 return NULL; 580 } 581 582 void free_srcline(char *srcline) 583 { 584 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) 585 free(srcline); 586 } 587 588 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 589 bool show_sym, bool show_addr, u64 ip) 590 { 591 return __get_srcline(dso, addr, sym, show_sym, show_addr, false, ip); 592 } 593 594 struct srcline_node { 595 u64 addr; 596 char *srcline; 597 struct rb_node rb_node; 598 }; 599 600 void srcline__tree_insert(struct rb_root_cached *tree, u64 addr, char *srcline) 601 { 602 struct rb_node **p = &tree->rb_root.rb_node; 603 struct rb_node *parent = NULL; 604 struct srcline_node *i, *node; 605 bool leftmost = true; 606 607 node = zalloc(sizeof(struct srcline_node)); 608 if (!node) { 609 perror("not enough memory for the srcline node"); 610 return; 611 } 612 613 node->addr = addr; 614 node->srcline = srcline; 615 616 while (*p != NULL) { 617 parent = *p; 618 i = rb_entry(parent, struct srcline_node, rb_node); 619 if (addr < i->addr) 620 p = &(*p)->rb_left; 621 else { 622 p = &(*p)->rb_right; 623 leftmost = false; 624 } 625 } 626 rb_link_node(&node->rb_node, parent, p); 627 rb_insert_color_cached(&node->rb_node, tree, leftmost); 628 } 629 630 char *srcline__tree_find(struct rb_root_cached *tree, u64 addr) 631 { 632 struct rb_node *n = tree->rb_root.rb_node; 633 634 while (n) { 635 struct srcline_node *i = rb_entry(n, struct srcline_node, 636 rb_node); 637 638 if (addr < i->addr) 639 n = n->rb_left; 640 else if (addr > i->addr) 641 n = n->rb_right; 642 else 643 return i->srcline; 644 } 645 646 return NULL; 647 } 648 649 void srcline__tree_delete(struct rb_root_cached *tree) 650 { 651 struct srcline_node *pos; 652 struct rb_node *next = rb_first_cached(tree); 653 654 while (next) { 655 pos = rb_entry(next, struct srcline_node, rb_node); 656 next = rb_next(&pos->rb_node); 657 rb_erase_cached(&pos->rb_node, tree); 658 free_srcline(pos->srcline); 659 zfree(&pos); 660 } 661 } 662 663 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, 664 struct symbol *sym) 665 { 666 const char *dso_name; 667 668 dso_name = dso__name(dso); 669 if (dso_name == NULL) 670 return NULL; 671 672 return addr2inlines(dso_name, addr, dso, sym); 673 } 674 675 void inline_node__delete(struct inline_node *node) 676 { 677 struct inline_list *ilist, *tmp; 678 679 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 680 list_del_init(&ilist->list); 681 free_srcline(ilist->srcline); 682 /* only the inlined symbols are owned by the list */ 683 if (ilist->symbol && ilist->symbol->inlined) 684 symbol__delete(ilist->symbol); 685 free(ilist); 686 } 687 688 free(node); 689 } 690 691 void inlines__tree_insert(struct rb_root_cached *tree, 692 struct inline_node *inlines) 693 { 694 struct rb_node **p = &tree->rb_root.rb_node; 695 struct rb_node *parent = NULL; 696 const u64 addr = inlines->addr; 697 struct inline_node *i; 698 bool leftmost = true; 699 700 while (*p != NULL) { 701 parent = *p; 702 i = rb_entry(parent, struct inline_node, rb_node); 703 if (addr < i->addr) 704 p = &(*p)->rb_left; 705 else { 706 p = &(*p)->rb_right; 707 leftmost = false; 708 } 709 } 710 rb_link_node(&inlines->rb_node, parent, p); 711 rb_insert_color_cached(&inlines->rb_node, tree, leftmost); 712 } 713 714 struct inline_node *inlines__tree_find(struct rb_root_cached *tree, u64 addr) 715 { 716 struct rb_node *n = tree->rb_root.rb_node; 717 718 while (n) { 719 struct inline_node *i = rb_entry(n, struct inline_node, 720 rb_node); 721 722 if (addr < i->addr) 723 n = n->rb_left; 724 else if (addr > i->addr) 725 n = n->rb_right; 726 else 727 return i; 728 } 729 730 return NULL; 731 } 732 733 void inlines__tree_delete(struct rb_root_cached *tree) 734 { 735 struct inline_node *pos; 736 struct rb_node *next = rb_first_cached(tree); 737 738 while (next) { 739 pos = rb_entry(next, struct inline_node, rb_node); 740 next = rb_next(&pos->rb_node); 741 rb_erase_cached(&pos->rb_node, tree); 742 inline_node__delete(pos); 743 } 744 } 745