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