1 // SPDX-License-Identifier: GPL-2.0 2 #include <inttypes.h> 3 #include <signal.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <sys/types.h> 8 9 #include <linux/kernel.h> 10 #include <linux/string.h> 11 #include <linux/zalloc.h> 12 13 #include <api/io.h> 14 15 #include "util/dso.h" 16 #include "util/debug.h" 17 #include "util/callchain.h" 18 #include "util/symbol_conf.h" 19 #include "srcline.h" 20 #include "string2.h" 21 #include "symbol.h" 22 #include "subcmd/run-command.h" 23 24 /* If addr2line doesn't return data for 1 second then timeout. */ 25 int addr2line_timeout_ms = 1 * 1000; 26 bool srcline_full_filename; 27 28 char *srcline__unknown = (char *)"??:0"; 29 30 static const char *srcline_dso_name(struct dso *dso) 31 { 32 const char *dso_name; 33 34 if (dso__symsrc_filename(dso)) 35 dso_name = dso__symsrc_filename(dso); 36 else 37 dso_name = dso__long_name(dso); 38 39 if (dso_name[0] == '[') 40 return NULL; 41 42 if (is_perf_pid_map_name(dso_name)) 43 return NULL; 44 45 return dso_name; 46 } 47 48 static int inline_list__append(struct symbol *symbol, char *srcline, 49 struct inline_node *node) 50 { 51 struct inline_list *ilist; 52 53 ilist = zalloc(sizeof(*ilist)); 54 if (ilist == NULL) 55 return -1; 56 57 ilist->symbol = symbol; 58 ilist->srcline = srcline; 59 60 if (callchain_param.order == ORDER_CALLEE) 61 list_add_tail(&ilist->list, &node->val); 62 else 63 list_add(&ilist->list, &node->val); 64 65 return 0; 66 } 67 68 /* basename version that takes a const input string */ 69 static const char *gnu_basename(const char *path) 70 { 71 const char *base = strrchr(path, '/'); 72 73 return base ? base + 1 : path; 74 } 75 76 static char *srcline_from_fileline(const char *file, unsigned int line) 77 { 78 char *srcline; 79 80 if (!file) 81 return NULL; 82 83 if (!srcline_full_filename) 84 file = gnu_basename(file); 85 86 if (asprintf(&srcline, "%s:%u", file, line) < 0) 87 return NULL; 88 89 return srcline; 90 } 91 92 static struct symbol *new_inline_sym(struct dso *dso, 93 struct symbol *base_sym, 94 const char *funcname) 95 { 96 struct symbol *inline_sym; 97 char *demangled = NULL; 98 99 if (!funcname) 100 funcname = "??"; 101 102 if (dso) { 103 demangled = dso__demangle_sym(dso, 0, funcname); 104 if (demangled) 105 funcname = demangled; 106 } 107 108 if (base_sym && strcmp(funcname, base_sym->name) == 0) { 109 /* reuse the real, existing symbol */ 110 inline_sym = base_sym; 111 /* ensure that we don't alias an inlined symbol, which could 112 * lead to double frees in inline_node__delete 113 */ 114 assert(!base_sym->inlined); 115 } else { 116 /* create a fake symbol for the inline frame */ 117 inline_sym = symbol__new(base_sym ? base_sym->start : 0, 118 base_sym ? (base_sym->end - base_sym->start) : 0, 119 base_sym ? base_sym->binding : 0, 120 base_sym ? base_sym->type : 0, 121 funcname); 122 if (inline_sym) 123 inline_sym->inlined = 1; 124 } 125 126 free(demangled); 127 128 return inline_sym; 129 } 130 131 #define MAX_INLINE_NEST 1024 132 133 #ifdef HAVE_LIBBFD_SUPPORT 134 135 /* 136 * Implement addr2line using libbfd. 137 */ 138 #define PACKAGE "perf" 139 #include <bfd.h> 140 141 struct a2l_data { 142 const char *input; 143 u64 addr; 144 145 bool found; 146 const char *filename; 147 const char *funcname; 148 unsigned line; 149 150 bfd *abfd; 151 asymbol **syms; 152 }; 153 154 static int bfd_error(const char *string) 155 { 156 const char *errmsg; 157 158 errmsg = bfd_errmsg(bfd_get_error()); 159 fflush(stdout); 160 161 if (string) 162 pr_debug("%s: %s\n", string, errmsg); 163 else 164 pr_debug("%s\n", errmsg); 165 166 return -1; 167 } 168 169 static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) 170 { 171 long storage; 172 long symcount; 173 asymbol **syms; 174 bfd_boolean dynamic = FALSE; 175 176 if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) 177 return bfd_error(bfd_get_filename(abfd)); 178 179 storage = bfd_get_symtab_upper_bound(abfd); 180 if (storage == 0L) { 181 storage = bfd_get_dynamic_symtab_upper_bound(abfd); 182 dynamic = TRUE; 183 } 184 if (storage < 0L) 185 return bfd_error(bfd_get_filename(abfd)); 186 187 syms = malloc(storage); 188 if (dynamic) 189 symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); 190 else 191 symcount = bfd_canonicalize_symtab(abfd, syms); 192 193 if (symcount < 0) { 194 free(syms); 195 return bfd_error(bfd_get_filename(abfd)); 196 } 197 198 a2l->syms = syms; 199 return 0; 200 } 201 202 static void find_address_in_section(bfd *abfd, asection *section, void *data) 203 { 204 bfd_vma pc, vma; 205 bfd_size_type size; 206 struct a2l_data *a2l = data; 207 flagword flags; 208 209 if (a2l->found) 210 return; 211 212 #ifdef bfd_get_section_flags 213 flags = bfd_get_section_flags(abfd, section); 214 #else 215 flags = bfd_section_flags(section); 216 #endif 217 if ((flags & SEC_ALLOC) == 0) 218 return; 219 220 pc = a2l->addr; 221 #ifdef bfd_get_section_vma 222 vma = bfd_get_section_vma(abfd, section); 223 #else 224 vma = bfd_section_vma(section); 225 #endif 226 #ifdef bfd_get_section_size 227 size = bfd_get_section_size(section); 228 #else 229 size = bfd_section_size(section); 230 #endif 231 232 if (pc < vma || pc >= vma + size) 233 return; 234 235 a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, 236 &a2l->filename, &a2l->funcname, 237 &a2l->line); 238 239 if (a2l->filename && !strlen(a2l->filename)) 240 a2l->filename = NULL; 241 } 242 243 static struct a2l_data *addr2line_init(const char *path) 244 { 245 bfd *abfd; 246 struct a2l_data *a2l = NULL; 247 248 abfd = bfd_openr(path, NULL); 249 if (abfd == NULL) 250 return NULL; 251 252 if (!bfd_check_format(abfd, bfd_object)) 253 goto out; 254 255 a2l = zalloc(sizeof(*a2l)); 256 if (a2l == NULL) 257 goto out; 258 259 a2l->abfd = abfd; 260 a2l->input = strdup(path); 261 if (a2l->input == NULL) 262 goto out; 263 264 if (slurp_symtab(abfd, a2l)) 265 goto out; 266 267 return a2l; 268 269 out: 270 if (a2l) { 271 zfree((char **)&a2l->input); 272 free(a2l); 273 } 274 bfd_close(abfd); 275 return NULL; 276 } 277 278 static void addr2line_cleanup(struct a2l_data *a2l) 279 { 280 if (a2l->abfd) 281 bfd_close(a2l->abfd); 282 zfree((char **)&a2l->input); 283 zfree(&a2l->syms); 284 free(a2l); 285 } 286 287 static int inline_list__append_dso_a2l(struct dso *dso, 288 struct inline_node *node, 289 struct symbol *sym) 290 { 291 struct a2l_data *a2l = dso__a2l(dso); 292 struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname); 293 char *srcline = NULL; 294 295 if (a2l->filename) 296 srcline = srcline_from_fileline(a2l->filename, a2l->line); 297 298 return inline_list__append(inline_sym, srcline, node); 299 } 300 301 static int addr2line(const char *dso_name, u64 addr, 302 char **file, unsigned int *line, struct dso *dso, 303 bool unwind_inlines, struct inline_node *node, 304 struct symbol *sym) 305 { 306 int ret = 0; 307 struct a2l_data *a2l = dso__a2l(dso); 308 309 if (!a2l) { 310 a2l = addr2line_init(dso_name); 311 dso__set_a2l(dso, a2l); 312 } 313 314 if (a2l == NULL) { 315 if (!symbol_conf.disable_add2line_warn) 316 pr_warning("addr2line_init failed for %s\n", dso_name); 317 return 0; 318 } 319 320 a2l->addr = addr; 321 a2l->found = false; 322 323 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 324 325 if (!a2l->found) 326 return 0; 327 328 if (unwind_inlines) { 329 int cnt = 0; 330 331 if (node && inline_list__append_dso_a2l(dso, node, sym)) 332 return 0; 333 334 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, 335 &a2l->funcname, &a2l->line) && 336 cnt++ < MAX_INLINE_NEST) { 337 338 if (a2l->filename && !strlen(a2l->filename)) 339 a2l->filename = NULL; 340 341 if (node != NULL) { 342 if (inline_list__append_dso_a2l(dso, node, sym)) 343 return 0; 344 // found at least one inline frame 345 ret = 1; 346 } 347 } 348 } 349 350 if (file) { 351 *file = a2l->filename ? strdup(a2l->filename) : NULL; 352 ret = *file ? 1 : 0; 353 } 354 355 if (line) 356 *line = a2l->line; 357 358 return ret; 359 } 360 361 void dso__free_a2l(struct dso *dso) 362 { 363 struct a2l_data *a2l = dso__a2l(dso); 364 365 if (!a2l) 366 return; 367 368 addr2line_cleanup(a2l); 369 370 dso__set_a2l(dso, NULL); 371 } 372 373 #else /* HAVE_LIBBFD_SUPPORT */ 374 375 static int filename_split(char *filename, unsigned int *line_nr) 376 { 377 char *sep; 378 379 sep = strchr(filename, '\n'); 380 if (sep) 381 *sep = '\0'; 382 383 if (!strcmp(filename, "??:0")) 384 return 0; 385 386 sep = strchr(filename, ':'); 387 if (sep) { 388 *sep++ = '\0'; 389 *line_nr = strtoul(sep, NULL, 0); 390 return 1; 391 } 392 pr_debug("addr2line missing ':' in filename split\n"); 393 return 0; 394 } 395 396 static void addr2line_subprocess_cleanup(struct child_process *a2l) 397 { 398 if (a2l->pid != -1) { 399 kill(a2l->pid, SIGKILL); 400 finish_command(a2l); /* ignore result, we don't care */ 401 a2l->pid = -1; 402 close(a2l->in); 403 close(a2l->out); 404 } 405 406 free(a2l); 407 } 408 409 static struct child_process *addr2line_subprocess_init(const char *addr2line_path, 410 const char *binary_path) 411 { 412 const char *argv[] = { 413 addr2line_path ?: "addr2line", 414 "-e", binary_path, 415 "-a", "-i", "-f", NULL 416 }; 417 struct child_process *a2l = zalloc(sizeof(*a2l)); 418 int start_command_status = 0; 419 420 if (a2l == NULL) { 421 pr_err("Failed to allocate memory for addr2line"); 422 return NULL; 423 } 424 425 a2l->pid = -1; 426 a2l->in = -1; 427 a2l->out = -1; 428 a2l->no_stderr = 1; 429 430 a2l->argv = argv; 431 start_command_status = start_command(a2l); 432 a2l->argv = NULL; /* it's not used after start_command; avoid dangling pointers */ 433 434 if (start_command_status != 0) { 435 pr_warning("could not start addr2line (%s) for %s: start_command return code %d\n", 436 addr2line_path, binary_path, start_command_status); 437 addr2line_subprocess_cleanup(a2l); 438 return NULL; 439 } 440 441 return a2l; 442 } 443 444 enum a2l_style { 445 BROKEN, 446 GNU_BINUTILS, 447 LLVM, 448 }; 449 450 static enum a2l_style addr2line_configure(struct child_process *a2l, const char *dso_name) 451 { 452 static bool cached; 453 static enum a2l_style style; 454 455 if (!cached) { 456 char buf[128]; 457 struct io io; 458 int ch; 459 int lines; 460 461 if (write(a2l->in, ",\n", 2) != 2) 462 return BROKEN; 463 464 io__init(&io, a2l->out, buf, sizeof(buf)); 465 ch = io__get_char(&io); 466 if (ch == ',') { 467 style = LLVM; 468 cached = true; 469 lines = 1; 470 pr_debug("Detected LLVM addr2line style\n"); 471 } else if (ch == '0') { 472 style = GNU_BINUTILS; 473 cached = true; 474 lines = 3; 475 pr_debug("Detected binutils addr2line style\n"); 476 } else { 477 if (!symbol_conf.disable_add2line_warn) { 478 char *output = NULL; 479 size_t output_len; 480 481 io__getline(&io, &output, &output_len); 482 pr_warning("%s %s: addr2line configuration failed\n", 483 __func__, dso_name); 484 pr_warning("\t%c%s", ch, output); 485 } 486 pr_debug("Unknown/broken addr2line style\n"); 487 return BROKEN; 488 } 489 while (lines) { 490 ch = io__get_char(&io); 491 if (ch <= 0) 492 break; 493 if (ch == '\n') 494 lines--; 495 } 496 /* Ignore SIGPIPE in the event addr2line exits. */ 497 signal(SIGPIPE, SIG_IGN); 498 } 499 return style; 500 } 501 502 static int read_addr2line_record(struct io *io, 503 enum a2l_style style, 504 const char *dso_name, 505 u64 addr, 506 bool first, 507 char **function, 508 char **filename, 509 unsigned int *line_nr) 510 { 511 /* 512 * Returns: 513 * -1 ==> error 514 * 0 ==> sentinel (or other ill-formed) record read 515 * 1 ==> a genuine record read 516 */ 517 char *line = NULL; 518 size_t line_len = 0; 519 unsigned int dummy_line_nr = 0; 520 int ret = -1; 521 522 if (function != NULL) 523 zfree(function); 524 525 if (filename != NULL) 526 zfree(filename); 527 528 if (line_nr != NULL) 529 *line_nr = 0; 530 531 /* 532 * Read the first line. Without an error this will be: 533 * - for the first line an address like 0x1234, 534 * - the binutils sentinel 0x0000000000000000, 535 * - the llvm-addr2line the sentinel ',' character, 536 * - the function name line for an inlined function. 537 */ 538 if (io__getline(io, &line, &line_len) < 0 || !line_len) 539 goto error; 540 541 pr_debug("%s %s: addr2line read address for sentinel: %s", __func__, dso_name, line); 542 if (style == LLVM && line_len == 2 && line[0] == ',') { 543 /* Found the llvm-addr2line sentinel character. */ 544 zfree(&line); 545 return 0; 546 } else if (style == GNU_BINUTILS && (!first || addr != 0)) { 547 int zero_count = 0, non_zero_count = 0; 548 /* 549 * Check for binutils sentinel ignoring it for the case the 550 * requested address is 0. 551 */ 552 553 /* A given address should always start 0x. */ 554 if (line_len >= 2 || line[0] != '0' || line[1] != 'x') { 555 for (size_t i = 2; i < line_len; i++) { 556 if (line[i] == '0') 557 zero_count++; 558 else if (line[i] != '\n') 559 non_zero_count++; 560 } 561 if (!non_zero_count) { 562 int ch; 563 564 if (first && !zero_count) { 565 /* Line was erroneous just '0x'. */ 566 goto error; 567 } 568 /* 569 * Line was 0x0..0, the sentinel for binutils. Remove 570 * the function and filename lines. 571 */ 572 zfree(&line); 573 do { 574 ch = io__get_char(io); 575 } while (ch > 0 && ch != '\n'); 576 do { 577 ch = io__get_char(io); 578 } while (ch > 0 && ch != '\n'); 579 return 0; 580 } 581 } 582 } 583 /* Read the second function name line (if inline data then this is the first line). */ 584 if (first && (io__getline(io, &line, &line_len) < 0 || !line_len)) 585 goto error; 586 587 pr_debug("%s %s: addr2line read line: %s", __func__, dso_name, line); 588 if (function != NULL) 589 *function = strdup(strim(line)); 590 591 zfree(&line); 592 line_len = 0; 593 594 /* Read the third filename and line number line. */ 595 if (io__getline(io, &line, &line_len) < 0 || !line_len) 596 goto error; 597 598 pr_debug("%s %s: addr2line filename:number : %s", __func__, dso_name, line); 599 if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0 && 600 style == GNU_BINUTILS) { 601 ret = 0; 602 goto error; 603 } 604 605 if (filename != NULL) 606 *filename = strdup(line); 607 608 zfree(&line); 609 line_len = 0; 610 611 return 1; 612 613 error: 614 free(line); 615 if (function != NULL) 616 zfree(function); 617 if (filename != NULL) 618 zfree(filename); 619 return ret; 620 } 621 622 static int inline_list__append_record(struct dso *dso, 623 struct inline_node *node, 624 struct symbol *sym, 625 const char *function, 626 const char *filename, 627 unsigned int line_nr) 628 { 629 struct symbol *inline_sym = new_inline_sym(dso, sym, function); 630 631 return inline_list__append(inline_sym, srcline_from_fileline(filename, line_nr), node); 632 } 633 634 static int addr2line(const char *dso_name, u64 addr, 635 char **file, unsigned int *line_nr, 636 struct dso *dso, 637 bool unwind_inlines, 638 struct inline_node *node, 639 struct symbol *sym __maybe_unused) 640 { 641 struct child_process *a2l = dso__a2l(dso); 642 char *record_function = NULL; 643 char *record_filename = NULL; 644 unsigned int record_line_nr = 0; 645 int record_status = -1; 646 int ret = 0; 647 size_t inline_count = 0; 648 int len; 649 char buf[128]; 650 ssize_t written; 651 struct io io = { .eof = false }; 652 enum a2l_style a2l_style; 653 654 if (!a2l) { 655 if (!filename__has_section(dso_name, ".debug_line")) 656 goto out; 657 658 dso__set_a2l(dso, 659 addr2line_subprocess_init(symbol_conf.addr2line_path, dso_name)); 660 a2l = dso__a2l(dso); 661 } 662 663 if (a2l == NULL) { 664 if (!symbol_conf.disable_add2line_warn) 665 pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__, dso_name); 666 goto out; 667 } 668 a2l_style = addr2line_configure(a2l, dso_name); 669 if (a2l_style == BROKEN) 670 goto out; 671 672 /* 673 * Send our request and then *deliberately* send something that can't be 674 * interpreted as a valid address to ask addr2line about (namely, 675 * ","). This causes addr2line to first write out the answer to our 676 * request, in an unbounded/unknown number of records, and then to write 677 * out the lines "0x0...0", "??" and "??:0", for GNU binutils, or "," 678 * for llvm-addr2line, so that we can detect when it has finished giving 679 * us anything useful. 680 */ 681 len = snprintf(buf, sizeof(buf), "%016"PRIx64"\n,\n", addr); 682 written = len > 0 ? write(a2l->in, buf, len) : -1; 683 if (written != len) { 684 if (!symbol_conf.disable_add2line_warn) 685 pr_warning("%s %s: could not send request\n", __func__, dso_name); 686 goto out; 687 } 688 io__init(&io, a2l->out, buf, sizeof(buf)); 689 io.timeout_ms = addr2line_timeout_ms; 690 switch (read_addr2line_record(&io, a2l_style, dso_name, addr, /*first=*/true, 691 &record_function, &record_filename, &record_line_nr)) { 692 case -1: 693 if (!symbol_conf.disable_add2line_warn) 694 pr_warning("%s %s: could not read first record\n", __func__, dso_name); 695 goto out; 696 case 0: 697 /* 698 * The first record was invalid, so return failure, but first 699 * read another record, since we sent a sentinel ',' for the 700 * sake of detected the last inlined function. Treat this as the 701 * first of a record as the ',' generates a new start with GNU 702 * binutils, also force a non-zero address as we're no longer 703 * reading that record. 704 */ 705 switch (read_addr2line_record(&io, a2l_style, dso_name, 706 /*addr=*/1, /*first=*/true, 707 NULL, NULL, NULL)) { 708 case -1: 709 if (!symbol_conf.disable_add2line_warn) 710 pr_warning("%s %s: could not read sentinel record\n", 711 __func__, dso_name); 712 break; 713 case 0: 714 /* The sentinel as expected. */ 715 break; 716 default: 717 if (!symbol_conf.disable_add2line_warn) 718 pr_warning("%s %s: unexpected record instead of sentinel", 719 __func__, dso_name); 720 break; 721 } 722 goto out; 723 default: 724 /* First record as expected. */ 725 break; 726 } 727 728 if (file) { 729 *file = strdup(record_filename); 730 ret = 1; 731 } 732 if (line_nr) 733 *line_nr = record_line_nr; 734 735 if (unwind_inlines) { 736 if (node && inline_list__append_record(dso, node, sym, 737 record_function, 738 record_filename, 739 record_line_nr)) { 740 ret = 0; 741 goto out; 742 } 743 } 744 745 /* 746 * We have to read the records even if we don't care about the inline 747 * info. This isn't the first record and force the address to non-zero 748 * as we're reading records beyond the first. 749 */ 750 while ((record_status = read_addr2line_record(&io, 751 a2l_style, 752 dso_name, 753 /*addr=*/1, 754 /*first=*/false, 755 &record_function, 756 &record_filename, 757 &record_line_nr)) == 1) { 758 if (unwind_inlines && node && inline_count++ < MAX_INLINE_NEST) { 759 if (inline_list__append_record(dso, node, sym, 760 record_function, 761 record_filename, 762 record_line_nr)) { 763 ret = 0; 764 goto out; 765 } 766 ret = 1; /* found at least one inline frame */ 767 } 768 } 769 770 out: 771 free(record_function); 772 free(record_filename); 773 if (io.eof) { 774 dso__set_a2l(dso, NULL); 775 addr2line_subprocess_cleanup(a2l); 776 } 777 return ret; 778 } 779 780 void dso__free_a2l(struct dso *dso) 781 { 782 struct child_process *a2l = dso__a2l(dso); 783 784 if (!a2l) 785 return; 786 787 addr2line_subprocess_cleanup(a2l); 788 789 dso__set_a2l(dso, NULL); 790 } 791 792 #endif /* HAVE_LIBBFD_SUPPORT */ 793 794 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 795 struct dso *dso, struct symbol *sym) 796 { 797 struct inline_node *node; 798 799 node = zalloc(sizeof(*node)); 800 if (node == NULL) { 801 perror("not enough memory for the inline node"); 802 return NULL; 803 } 804 805 INIT_LIST_HEAD(&node->val); 806 node->addr = addr; 807 808 addr2line(dso_name, addr, NULL, NULL, dso, true, node, sym); 809 return node; 810 } 811 812 /* 813 * Number of addr2line failures (without success) before disabling it for that 814 * dso. 815 */ 816 #define A2L_FAIL_LIMIT 123 817 818 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 819 bool show_sym, bool show_addr, bool unwind_inlines, 820 u64 ip) 821 { 822 char *file = NULL; 823 unsigned line = 0; 824 char *srcline; 825 const char *dso_name; 826 827 if (!dso__has_srcline(dso)) 828 goto out; 829 830 dso_name = srcline_dso_name(dso); 831 if (dso_name == NULL) 832 goto out_err; 833 834 if (!addr2line(dso_name, addr, &file, &line, dso, 835 unwind_inlines, NULL, sym)) 836 goto out_err; 837 838 srcline = srcline_from_fileline(file, line); 839 free(file); 840 841 if (!srcline) 842 goto out_err; 843 844 dso__set_a2l_fails(dso, 0); 845 846 return srcline; 847 848 out_err: 849 dso__set_a2l_fails(dso, dso__a2l_fails(dso) + 1); 850 if (dso__a2l_fails(dso) > A2L_FAIL_LIMIT) { 851 dso__set_has_srcline(dso, false); 852 dso__free_a2l(dso); 853 } 854 out: 855 if (!show_addr) 856 return (show_sym && sym) ? 857 strndup(sym->name, sym->namelen) : SRCLINE_UNKNOWN; 858 859 if (sym) { 860 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", 861 ip - sym->start) < 0) 862 return SRCLINE_UNKNOWN; 863 } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso__short_name(dso), addr) < 0) 864 return SRCLINE_UNKNOWN; 865 return srcline; 866 } 867 868 /* Returns filename and fills in line number in line */ 869 char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line) 870 { 871 char *file = NULL; 872 const char *dso_name; 873 874 if (!dso__has_srcline(dso)) 875 return NULL; 876 877 dso_name = srcline_dso_name(dso); 878 if (dso_name == NULL) 879 goto out_err; 880 881 if (!addr2line(dso_name, addr, &file, line, dso, true, NULL, NULL)) 882 goto out_err; 883 884 dso__set_a2l_fails(dso, 0); 885 return file; 886 887 out_err: 888 dso__set_a2l_fails(dso, dso__a2l_fails(dso) + 1); 889 if (dso__a2l_fails(dso) > A2L_FAIL_LIMIT) { 890 dso__set_has_srcline(dso, false); 891 dso__free_a2l(dso); 892 } 893 894 return NULL; 895 } 896 897 void zfree_srcline(char **srcline) 898 { 899 if (*srcline == NULL) 900 return; 901 902 if (*srcline != SRCLINE_UNKNOWN) 903 free(*srcline); 904 905 *srcline = NULL; 906 } 907 908 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 909 bool show_sym, bool show_addr, u64 ip) 910 { 911 return __get_srcline(dso, addr, sym, show_sym, show_addr, false, ip); 912 } 913 914 struct srcline_node { 915 u64 addr; 916 char *srcline; 917 struct rb_node rb_node; 918 }; 919 920 void srcline__tree_insert(struct rb_root_cached *tree, u64 addr, char *srcline) 921 { 922 struct rb_node **p = &tree->rb_root.rb_node; 923 struct rb_node *parent = NULL; 924 struct srcline_node *i, *node; 925 bool leftmost = true; 926 927 node = zalloc(sizeof(struct srcline_node)); 928 if (!node) { 929 perror("not enough memory for the srcline node"); 930 return; 931 } 932 933 node->addr = addr; 934 node->srcline = srcline; 935 936 while (*p != NULL) { 937 parent = *p; 938 i = rb_entry(parent, struct srcline_node, rb_node); 939 if (addr < i->addr) 940 p = &(*p)->rb_left; 941 else { 942 p = &(*p)->rb_right; 943 leftmost = false; 944 } 945 } 946 rb_link_node(&node->rb_node, parent, p); 947 rb_insert_color_cached(&node->rb_node, tree, leftmost); 948 } 949 950 char *srcline__tree_find(struct rb_root_cached *tree, u64 addr) 951 { 952 struct rb_node *n = tree->rb_root.rb_node; 953 954 while (n) { 955 struct srcline_node *i = rb_entry(n, struct srcline_node, 956 rb_node); 957 958 if (addr < i->addr) 959 n = n->rb_left; 960 else if (addr > i->addr) 961 n = n->rb_right; 962 else 963 return i->srcline; 964 } 965 966 return NULL; 967 } 968 969 void srcline__tree_delete(struct rb_root_cached *tree) 970 { 971 struct srcline_node *pos; 972 struct rb_node *next = rb_first_cached(tree); 973 974 while (next) { 975 pos = rb_entry(next, struct srcline_node, rb_node); 976 next = rb_next(&pos->rb_node); 977 rb_erase_cached(&pos->rb_node, tree); 978 zfree_srcline(&pos->srcline); 979 zfree(&pos); 980 } 981 } 982 983 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, 984 struct symbol *sym) 985 { 986 const char *dso_name; 987 988 dso_name = srcline_dso_name(dso); 989 if (dso_name == NULL) 990 return NULL; 991 992 return addr2inlines(dso_name, addr, dso, sym); 993 } 994 995 void inline_node__delete(struct inline_node *node) 996 { 997 struct inline_list *ilist, *tmp; 998 999 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 1000 list_del_init(&ilist->list); 1001 zfree_srcline(&ilist->srcline); 1002 /* only the inlined symbols are owned by the list */ 1003 if (ilist->symbol && ilist->symbol->inlined) 1004 symbol__delete(ilist->symbol); 1005 free(ilist); 1006 } 1007 1008 free(node); 1009 } 1010 1011 void inlines__tree_insert(struct rb_root_cached *tree, 1012 struct inline_node *inlines) 1013 { 1014 struct rb_node **p = &tree->rb_root.rb_node; 1015 struct rb_node *parent = NULL; 1016 const u64 addr = inlines->addr; 1017 struct inline_node *i; 1018 bool leftmost = true; 1019 1020 while (*p != NULL) { 1021 parent = *p; 1022 i = rb_entry(parent, struct inline_node, rb_node); 1023 if (addr < i->addr) 1024 p = &(*p)->rb_left; 1025 else { 1026 p = &(*p)->rb_right; 1027 leftmost = false; 1028 } 1029 } 1030 rb_link_node(&inlines->rb_node, parent, p); 1031 rb_insert_color_cached(&inlines->rb_node, tree, leftmost); 1032 } 1033 1034 struct inline_node *inlines__tree_find(struct rb_root_cached *tree, u64 addr) 1035 { 1036 struct rb_node *n = tree->rb_root.rb_node; 1037 1038 while (n) { 1039 struct inline_node *i = rb_entry(n, struct inline_node, 1040 rb_node); 1041 1042 if (addr < i->addr) 1043 n = n->rb_left; 1044 else if (addr > i->addr) 1045 n = n->rb_right; 1046 else 1047 return i; 1048 } 1049 1050 return NULL; 1051 } 1052 1053 void inlines__tree_delete(struct rb_root_cached *tree) 1054 { 1055 struct inline_node *pos; 1056 struct rb_node *next = rb_first_cached(tree); 1057 1058 while (next) { 1059 pos = rb_entry(next, struct inline_node, rb_node); 1060 next = rb_next(&pos->rb_node); 1061 rb_erase_cached(&pos->rb_node, tree); 1062 inline_node__delete(pos); 1063 } 1064 } 1065