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 addr2line(dso_name, addr, NULL, NULL, dso, true, node, sym); 357 return node; 358 } 359 360 #else /* HAVE_LIBBFD_SUPPORT */ 361 362 static int filename_split(char *filename, unsigned int *line_nr) 363 { 364 char *sep; 365 366 sep = strchr(filename, '\n'); 367 if (sep) 368 *sep = '\0'; 369 370 if (!strcmp(filename, "??:0")) 371 return 0; 372 373 sep = strchr(filename, ':'); 374 if (sep) { 375 *sep++ = '\0'; 376 *line_nr = strtoul(sep, NULL, 0); 377 return 1; 378 } 379 380 return 0; 381 } 382 383 static int addr2line(const char *dso_name, u64 addr, 384 char **file, unsigned int *line_nr, 385 struct dso *dso __maybe_unused, 386 bool unwind_inlines __maybe_unused, 387 struct inline_node *node __maybe_unused, 388 struct symbol *sym __maybe_unused) 389 { 390 FILE *fp; 391 char cmd[PATH_MAX]; 392 char *filename = NULL; 393 size_t len; 394 int ret = 0; 395 396 scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, 397 dso_name, addr); 398 399 fp = popen(cmd, "r"); 400 if (fp == NULL) { 401 pr_warning("popen failed for %s\n", dso_name); 402 return 0; 403 } 404 405 if (getline(&filename, &len, fp) < 0 || !len) { 406 pr_warning("addr2line has no output for %s\n", dso_name); 407 goto out; 408 } 409 410 ret = filename_split(filename, line_nr); 411 if (ret != 1) { 412 free(filename); 413 goto out; 414 } 415 416 *file = filename; 417 418 out: 419 pclose(fp); 420 return ret; 421 } 422 423 void dso__free_a2l(struct dso *dso __maybe_unused) 424 { 425 } 426 427 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 428 struct dso *dso __maybe_unused, 429 struct symbol *sym) 430 { 431 FILE *fp; 432 char cmd[PATH_MAX]; 433 struct inline_node *node; 434 char *filename = NULL; 435 size_t len; 436 unsigned int line_nr = 0; 437 438 scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64, 439 dso_name, addr); 440 441 fp = popen(cmd, "r"); 442 if (fp == NULL) { 443 pr_err("popen failed for %s\n", dso_name); 444 return NULL; 445 } 446 447 node = zalloc(sizeof(*node)); 448 if (node == NULL) { 449 perror("not enough memory for the inline node"); 450 goto out; 451 } 452 453 INIT_LIST_HEAD(&node->val); 454 node->addr = addr; 455 456 while (getline(&filename, &len, fp) != -1) { 457 char *srcline; 458 459 if (filename_split(filename, &line_nr) != 1) { 460 free(filename); 461 goto out; 462 } 463 464 srcline = srcline_from_fileline(filename, line_nr); 465 if (inline_list__append(sym, srcline, node) != 0) 466 goto out; 467 468 filename = NULL; 469 } 470 471 out: 472 pclose(fp); 473 474 return node; 475 } 476 477 #endif /* HAVE_LIBBFD_SUPPORT */ 478 479 /* 480 * Number of addr2line failures (without success) before disabling it for that 481 * dso. 482 */ 483 #define A2L_FAIL_LIMIT 123 484 485 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 486 bool show_sym, bool show_addr, bool unwind_inlines) 487 { 488 char *file = NULL; 489 unsigned line = 0; 490 char *srcline; 491 const char *dso_name; 492 493 if (!dso->has_srcline) 494 goto out; 495 496 dso_name = dso__name(dso); 497 if (dso_name == NULL) 498 goto out; 499 500 if (!addr2line(dso_name, addr, &file, &line, dso, 501 unwind_inlines, NULL, sym)) 502 goto out; 503 504 srcline = srcline_from_fileline(file, line); 505 free(file); 506 507 if (!srcline) 508 goto out; 509 510 dso->a2l_fails = 0; 511 512 return srcline; 513 514 out: 515 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 516 dso->has_srcline = 0; 517 dso__free_a2l(dso); 518 } 519 520 if (!show_addr) 521 return (show_sym && sym) ? 522 strndup(sym->name, sym->namelen) : NULL; 523 524 if (sym) { 525 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", 526 addr - sym->start) < 0) 527 return SRCLINE_UNKNOWN; 528 } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) 529 return SRCLINE_UNKNOWN; 530 return srcline; 531 } 532 533 void free_srcline(char *srcline) 534 { 535 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) 536 free(srcline); 537 } 538 539 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 540 bool show_sym, bool show_addr) 541 { 542 return __get_srcline(dso, addr, sym, show_sym, show_addr, false); 543 } 544 545 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, 546 struct symbol *sym) 547 { 548 const char *dso_name; 549 550 dso_name = dso__name(dso); 551 if (dso_name == NULL) 552 return NULL; 553 554 return addr2inlines(dso_name, addr, dso, sym); 555 } 556 557 void inline_node__delete(struct inline_node *node) 558 { 559 struct inline_list *ilist, *tmp; 560 561 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 562 list_del_init(&ilist->list); 563 free_srcline(ilist->srcline); 564 /* only the inlined symbols are owned by the list */ 565 if (ilist->symbol && ilist->symbol->inlined) 566 symbol__delete(ilist->symbol); 567 free(ilist); 568 } 569 570 free(node); 571 } 572 573 void inlines__tree_insert(struct rb_root *tree, struct inline_node *inlines) 574 { 575 struct rb_node **p = &tree->rb_node; 576 struct rb_node *parent = NULL; 577 const u64 addr = inlines->addr; 578 struct inline_node *i; 579 580 while (*p != NULL) { 581 parent = *p; 582 i = rb_entry(parent, struct inline_node, rb_node); 583 if (addr < i->addr) 584 p = &(*p)->rb_left; 585 else 586 p = &(*p)->rb_right; 587 } 588 rb_link_node(&inlines->rb_node, parent, p); 589 rb_insert_color(&inlines->rb_node, tree); 590 } 591 592 struct inline_node *inlines__tree_find(struct rb_root *tree, u64 addr) 593 { 594 struct rb_node *n = tree->rb_node; 595 596 while (n) { 597 struct inline_node *i = rb_entry(n, struct inline_node, 598 rb_node); 599 600 if (addr < i->addr) 601 n = n->rb_left; 602 else if (addr > i->addr) 603 n = n->rb_right; 604 else 605 return i; 606 } 607 608 return NULL; 609 } 610 611 void inlines__tree_delete(struct rb_root *tree) 612 { 613 struct inline_node *pos; 614 struct rb_node *next = rb_first(tree); 615 616 while (next) { 617 pos = rb_entry(next, struct inline_node, rb_node); 618 next = rb_next(&pos->rb_node); 619 rb_erase(&pos->rb_node, tree); 620 inline_node__delete(pos); 621 } 622 } 623