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