1 #include "util.h" 2 #include "../perf.h" 3 #include "string.h" 4 #include "symbol.h" 5 #include "thread.h" 6 7 #include "debug.h" 8 9 #include <asm/bug.h> 10 #include <libelf.h> 11 #include <gelf.h> 12 #include <elf.h> 13 #include <limits.h> 14 #include <sys/utsname.h> 15 16 #ifndef NT_GNU_BUILD_ID 17 #define NT_GNU_BUILD_ID 3 18 #endif 19 20 enum dso_origin { 21 DSO__ORIG_KERNEL = 0, 22 DSO__ORIG_JAVA_JIT, 23 DSO__ORIG_FEDORA, 24 DSO__ORIG_UBUNTU, 25 DSO__ORIG_BUILDID, 26 DSO__ORIG_DSO, 27 DSO__ORIG_KMODULE, 28 DSO__ORIG_NOT_FOUND, 29 }; 30 31 static void dsos__add(struct list_head *head, struct dso *dso); 32 static struct map *thread__find_map_by_name(struct thread *self, char *name); 33 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 34 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); 35 static int dso__load_kernel_sym(struct dso *self, struct map *map, 36 struct thread *thread, symbol_filter_t filter); 37 unsigned int symbol__priv_size; 38 static int vmlinux_path__nr_entries; 39 static char **vmlinux_path; 40 41 static struct symbol_conf symbol_conf__defaults = { 42 .use_modules = true, 43 .try_vmlinux_path = true, 44 }; 45 46 static struct thread kthread_mem; 47 struct thread *kthread = &kthread_mem; 48 49 bool dso__loaded(const struct dso *self, enum map_type type) 50 { 51 return self->loaded & (1 << type); 52 } 53 54 static void dso__set_loaded(struct dso *self, enum map_type type) 55 { 56 self->loaded |= (1 << type); 57 } 58 59 static void symbols__fixup_end(struct rb_root *self) 60 { 61 struct rb_node *nd, *prevnd = rb_first(self); 62 struct symbol *curr, *prev; 63 64 if (prevnd == NULL) 65 return; 66 67 curr = rb_entry(prevnd, struct symbol, rb_node); 68 69 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 70 prev = curr; 71 curr = rb_entry(nd, struct symbol, rb_node); 72 73 if (prev->end == prev->start) 74 prev->end = curr->start - 1; 75 } 76 77 /* Last entry */ 78 if (curr->end == curr->start) 79 curr->end = roundup(curr->start, 4096); 80 } 81 82 static void __thread__fixup_maps_end(struct thread *self, enum map_type type) 83 { 84 struct map *prev, *curr; 85 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]); 86 87 if (prevnd == NULL) 88 return; 89 90 curr = rb_entry(prevnd, struct map, rb_node); 91 92 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 93 prev = curr; 94 curr = rb_entry(nd, struct map, rb_node); 95 prev->end = curr->start - 1; 96 } 97 98 /* 99 * We still haven't the actual symbols, so guess the 100 * last map final address. 101 */ 102 curr->end = ~0UL; 103 } 104 105 static void thread__fixup_maps_end(struct thread *self) 106 { 107 int i; 108 for (i = 0; i < MAP__NR_TYPES; ++i) 109 __thread__fixup_maps_end(self, i); 110 } 111 112 static struct symbol *symbol__new(u64 start, u64 len, const char *name) 113 { 114 size_t namelen = strlen(name) + 1; 115 struct symbol *self = zalloc(symbol__priv_size + 116 sizeof(*self) + namelen); 117 if (self == NULL) 118 return NULL; 119 120 if (symbol__priv_size) 121 self = ((void *)self) + symbol__priv_size; 122 123 self->start = start; 124 self->end = len ? start + len - 1 : start; 125 126 pr_debug3("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); 127 128 memcpy(self->name, name, namelen); 129 130 return self; 131 } 132 133 static void symbol__delete(struct symbol *self) 134 { 135 free(((void *)self) - symbol__priv_size); 136 } 137 138 static size_t symbol__fprintf(struct symbol *self, FILE *fp) 139 { 140 return fprintf(fp, " %llx-%llx %s\n", 141 self->start, self->end, self->name); 142 } 143 144 static void dso__set_long_name(struct dso *self, char *name) 145 { 146 if (name == NULL) 147 return; 148 self->long_name = name; 149 self->long_name_len = strlen(name); 150 } 151 152 static void dso__set_basename(struct dso *self) 153 { 154 self->short_name = basename(self->long_name); 155 } 156 157 struct dso *dso__new(const char *name) 158 { 159 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); 160 161 if (self != NULL) { 162 int i; 163 strcpy(self->name, name); 164 dso__set_long_name(self, self->name); 165 self->short_name = self->name; 166 for (i = 0; i < MAP__NR_TYPES; ++i) 167 self->symbols[i] = RB_ROOT; 168 self->find_symbol = dso__find_symbol; 169 self->slen_calculated = 0; 170 self->origin = DSO__ORIG_NOT_FOUND; 171 self->loaded = 0; 172 self->has_build_id = 0; 173 } 174 175 return self; 176 } 177 178 static void symbols__delete(struct rb_root *self) 179 { 180 struct symbol *pos; 181 struct rb_node *next = rb_first(self); 182 183 while (next) { 184 pos = rb_entry(next, struct symbol, rb_node); 185 next = rb_next(&pos->rb_node); 186 rb_erase(&pos->rb_node, self); 187 symbol__delete(pos); 188 } 189 } 190 191 void dso__delete(struct dso *self) 192 { 193 int i; 194 for (i = 0; i < MAP__NR_TYPES; ++i) 195 symbols__delete(&self->symbols[i]); 196 if (self->long_name != self->name) 197 free(self->long_name); 198 free(self); 199 } 200 201 void dso__set_build_id(struct dso *self, void *build_id) 202 { 203 memcpy(self->build_id, build_id, sizeof(self->build_id)); 204 self->has_build_id = 1; 205 } 206 207 static void symbols__insert(struct rb_root *self, struct symbol *sym) 208 { 209 struct rb_node **p = &self->rb_node; 210 struct rb_node *parent = NULL; 211 const u64 ip = sym->start; 212 struct symbol *s; 213 214 while (*p != NULL) { 215 parent = *p; 216 s = rb_entry(parent, struct symbol, rb_node); 217 if (ip < s->start) 218 p = &(*p)->rb_left; 219 else 220 p = &(*p)->rb_right; 221 } 222 rb_link_node(&sym->rb_node, parent, p); 223 rb_insert_color(&sym->rb_node, self); 224 } 225 226 static struct symbol *symbols__find(struct rb_root *self, u64 ip) 227 { 228 struct rb_node *n; 229 230 if (self == NULL) 231 return NULL; 232 233 n = self->rb_node; 234 235 while (n) { 236 struct symbol *s = rb_entry(n, struct symbol, rb_node); 237 238 if (ip < s->start) 239 n = n->rb_left; 240 else if (ip > s->end) 241 n = n->rb_right; 242 else 243 return s; 244 } 245 246 return NULL; 247 } 248 249 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr) 250 { 251 return symbols__find(&self->symbols[type], addr); 252 } 253 254 int build_id__sprintf(u8 *self, int len, char *bf) 255 { 256 char *bid = bf; 257 u8 *raw = self; 258 int i; 259 260 for (i = 0; i < len; ++i) { 261 sprintf(bid, "%02x", *raw); 262 ++raw; 263 bid += 2; 264 } 265 266 return raw - self; 267 } 268 269 size_t dso__fprintf_buildid(struct dso *self, FILE *fp) 270 { 271 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 272 273 build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id); 274 return fprintf(fp, "%s", sbuild_id); 275 } 276 277 size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) 278 { 279 struct rb_node *nd; 280 size_t ret = fprintf(fp, "dso: %s (", self->short_name); 281 282 ret += dso__fprintf_buildid(self, fp); 283 ret += fprintf(fp, ")\n"); 284 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) { 285 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 286 ret += symbol__fprintf(pos, fp); 287 } 288 289 return ret; 290 } 291 292 /* 293 * Loads the function entries in /proc/kallsyms into kernel_map->dso, 294 * so that we can in the next step set the symbol ->end address and then 295 * call kernel_maps__split_kallsyms. 296 */ 297 static int dso__load_all_kallsyms(struct dso *self, struct map *map) 298 { 299 char *line = NULL; 300 size_t n; 301 struct rb_root *root = &self->symbols[map->type]; 302 FILE *file = fopen("/proc/kallsyms", "r"); 303 304 if (file == NULL) 305 goto out_failure; 306 307 while (!feof(file)) { 308 u64 start; 309 struct symbol *sym; 310 int line_len, len; 311 char symbol_type; 312 char *symbol_name; 313 314 line_len = getline(&line, &n, file); 315 if (line_len < 0) 316 break; 317 318 if (!line) 319 goto out_failure; 320 321 line[--line_len] = '\0'; /* \n */ 322 323 len = hex2u64(line, &start); 324 325 len++; 326 if (len + 2 >= line_len) 327 continue; 328 329 symbol_type = toupper(line[len]); 330 /* 331 * We're interested only in code ('T'ext) 332 */ 333 if (symbol_type != 'T' && symbol_type != 'W') 334 continue; 335 336 symbol_name = line + len + 2; 337 /* 338 * Will fix up the end later, when we have all symbols sorted. 339 */ 340 sym = symbol__new(start, 0, symbol_name); 341 342 if (sym == NULL) 343 goto out_delete_line; 344 /* 345 * We will pass the symbols to the filter later, in 346 * map__split_kallsyms, when we have split the maps per module 347 */ 348 symbols__insert(root, sym); 349 } 350 351 free(line); 352 fclose(file); 353 354 return 0; 355 356 out_delete_line: 357 free(line); 358 out_failure: 359 return -1; 360 } 361 362 /* 363 * Split the symbols into maps, making sure there are no overlaps, i.e. the 364 * kernel range is broken in several maps, named [kernel].N, as we don't have 365 * the original ELF section names vmlinux have. 366 */ 367 static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread *thread, 368 symbol_filter_t filter) 369 { 370 struct map *curr_map = map; 371 struct symbol *pos; 372 int count = 0; 373 struct rb_root *root = &self->symbols[map->type]; 374 struct rb_node *next = rb_first(root); 375 int kernel_range = 0; 376 377 while (next) { 378 char *module; 379 380 pos = rb_entry(next, struct symbol, rb_node); 381 next = rb_next(&pos->rb_node); 382 383 module = strchr(pos->name, '\t'); 384 if (module) { 385 if (!thread->use_modules) 386 goto discard_symbol; 387 388 *module++ = '\0'; 389 390 if (strcmp(self->name, module)) { 391 curr_map = thread__find_map_by_name(thread, module); 392 if (curr_map == NULL) { 393 pr_debug("/proc/{kallsyms,modules} " 394 "inconsistency!\n"); 395 return -1; 396 } 397 } 398 /* 399 * So that we look just like we get from .ko files, 400 * i.e. not prelinked, relative to map->start. 401 */ 402 pos->start = curr_map->map_ip(curr_map, pos->start); 403 pos->end = curr_map->map_ip(curr_map, pos->end); 404 } else if (curr_map != map) { 405 char dso_name[PATH_MAX]; 406 struct dso *dso; 407 408 snprintf(dso_name, sizeof(dso_name), "[kernel].%d", 409 kernel_range++); 410 411 dso = dso__new(dso_name); 412 if (dso == NULL) 413 return -1; 414 415 curr_map = map__new2(pos->start, dso, map->type); 416 if (map == NULL) { 417 dso__delete(dso); 418 return -1; 419 } 420 421 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 422 __thread__insert_map(thread, curr_map); 423 ++kernel_range; 424 } 425 426 if (filter && filter(curr_map, pos)) { 427 discard_symbol: rb_erase(&pos->rb_node, root); 428 symbol__delete(pos); 429 } else { 430 if (curr_map != map) { 431 rb_erase(&pos->rb_node, root); 432 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); 433 } 434 count++; 435 } 436 } 437 438 return count; 439 } 440 441 442 static int dso__load_kallsyms(struct dso *self, struct map *map, 443 struct thread *thread, symbol_filter_t filter) 444 { 445 if (dso__load_all_kallsyms(self, map) < 0) 446 return -1; 447 448 symbols__fixup_end(&self->symbols[map->type]); 449 self->origin = DSO__ORIG_KERNEL; 450 451 return dso__split_kallsyms(self, map, thread, filter); 452 } 453 454 size_t kernel_maps__fprintf(FILE *fp) 455 { 456 size_t printed = fprintf(fp, "Kernel maps:\n"); 457 printed += thread__fprintf_maps(kthread, fp); 458 return printed + fprintf(fp, "END kernel maps\n"); 459 } 460 461 static int dso__load_perf_map(struct dso *self, struct map *map, 462 symbol_filter_t filter) 463 { 464 char *line = NULL; 465 size_t n; 466 FILE *file; 467 int nr_syms = 0; 468 469 file = fopen(self->long_name, "r"); 470 if (file == NULL) 471 goto out_failure; 472 473 while (!feof(file)) { 474 u64 start, size; 475 struct symbol *sym; 476 int line_len, len; 477 478 line_len = getline(&line, &n, file); 479 if (line_len < 0) 480 break; 481 482 if (!line) 483 goto out_failure; 484 485 line[--line_len] = '\0'; /* \n */ 486 487 len = hex2u64(line, &start); 488 489 len++; 490 if (len + 2 >= line_len) 491 continue; 492 493 len += hex2u64(line + len, &size); 494 495 len++; 496 if (len + 2 >= line_len) 497 continue; 498 499 sym = symbol__new(start, size, line + len); 500 501 if (sym == NULL) 502 goto out_delete_line; 503 504 if (filter && filter(map, sym)) 505 symbol__delete(sym); 506 else { 507 symbols__insert(&self->symbols[map->type], sym); 508 nr_syms++; 509 } 510 } 511 512 free(line); 513 fclose(file); 514 515 return nr_syms; 516 517 out_delete_line: 518 free(line); 519 out_failure: 520 return -1; 521 } 522 523 /** 524 * elf_symtab__for_each_symbol - iterate thru all the symbols 525 * 526 * @self: struct elf_symtab instance to iterate 527 * @idx: uint32_t idx 528 * @sym: GElf_Sym iterator 529 */ 530 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \ 531 for (idx = 0, gelf_getsym(syms, idx, &sym);\ 532 idx < nr_syms; \ 533 idx++, gelf_getsym(syms, idx, &sym)) 534 535 static inline uint8_t elf_sym__type(const GElf_Sym *sym) 536 { 537 return GELF_ST_TYPE(sym->st_info); 538 } 539 540 static inline int elf_sym__is_function(const GElf_Sym *sym) 541 { 542 return elf_sym__type(sym) == STT_FUNC && 543 sym->st_name != 0 && 544 sym->st_shndx != SHN_UNDEF; 545 } 546 547 static inline int elf_sym__is_label(const GElf_Sym *sym) 548 { 549 return elf_sym__type(sym) == STT_NOTYPE && 550 sym->st_name != 0 && 551 sym->st_shndx != SHN_UNDEF && 552 sym->st_shndx != SHN_ABS; 553 } 554 555 static inline const char *elf_sec__name(const GElf_Shdr *shdr, 556 const Elf_Data *secstrs) 557 { 558 return secstrs->d_buf + shdr->sh_name; 559 } 560 561 static inline int elf_sec__is_text(const GElf_Shdr *shdr, 562 const Elf_Data *secstrs) 563 { 564 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; 565 } 566 567 static inline const char *elf_sym__name(const GElf_Sym *sym, 568 const Elf_Data *symstrs) 569 { 570 return symstrs->d_buf + sym->st_name; 571 } 572 573 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 574 GElf_Shdr *shp, const char *name, 575 size_t *idx) 576 { 577 Elf_Scn *sec = NULL; 578 size_t cnt = 1; 579 580 while ((sec = elf_nextscn(elf, sec)) != NULL) { 581 char *str; 582 583 gelf_getshdr(sec, shp); 584 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); 585 if (!strcmp(name, str)) { 586 if (idx) 587 *idx = cnt; 588 break; 589 } 590 ++cnt; 591 } 592 593 return sec; 594 } 595 596 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \ 597 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \ 598 idx < nr_entries; \ 599 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem)) 600 601 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \ 602 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \ 603 idx < nr_entries; \ 604 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem)) 605 606 /* 607 * We need to check if we have a .dynsym, so that we can handle the 608 * .plt, synthesizing its symbols, that aren't on the symtabs (be it 609 * .dynsym or .symtab). 610 * And always look at the original dso, not at debuginfo packages, that 611 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 612 */ 613 static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, 614 symbol_filter_t filter) 615 { 616 uint32_t nr_rel_entries, idx; 617 GElf_Sym sym; 618 u64 plt_offset; 619 GElf_Shdr shdr_plt; 620 struct symbol *f; 621 GElf_Shdr shdr_rel_plt, shdr_dynsym; 622 Elf_Data *reldata, *syms, *symstrs; 623 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym; 624 size_t dynsym_idx; 625 GElf_Ehdr ehdr; 626 char sympltname[1024]; 627 Elf *elf; 628 int nr = 0, symidx, fd, err = 0; 629 630 fd = open(self->long_name, O_RDONLY); 631 if (fd < 0) 632 goto out; 633 634 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 635 if (elf == NULL) 636 goto out_close; 637 638 if (gelf_getehdr(elf, &ehdr) == NULL) 639 goto out_elf_end; 640 641 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym, 642 ".dynsym", &dynsym_idx); 643 if (scn_dynsym == NULL) 644 goto out_elf_end; 645 646 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 647 ".rela.plt", NULL); 648 if (scn_plt_rel == NULL) { 649 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 650 ".rel.plt", NULL); 651 if (scn_plt_rel == NULL) 652 goto out_elf_end; 653 } 654 655 err = -1; 656 657 if (shdr_rel_plt.sh_link != dynsym_idx) 658 goto out_elf_end; 659 660 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL) 661 goto out_elf_end; 662 663 /* 664 * Fetch the relocation section to find the idxes to the GOT 665 * and the symbols in the .dynsym they refer to. 666 */ 667 reldata = elf_getdata(scn_plt_rel, NULL); 668 if (reldata == NULL) 669 goto out_elf_end; 670 671 syms = elf_getdata(scn_dynsym, NULL); 672 if (syms == NULL) 673 goto out_elf_end; 674 675 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link); 676 if (scn_symstrs == NULL) 677 goto out_elf_end; 678 679 symstrs = elf_getdata(scn_symstrs, NULL); 680 if (symstrs == NULL) 681 goto out_elf_end; 682 683 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; 684 plt_offset = shdr_plt.sh_offset; 685 686 if (shdr_rel_plt.sh_type == SHT_RELA) { 687 GElf_Rela pos_mem, *pos; 688 689 elf_section__for_each_rela(reldata, pos, pos_mem, idx, 690 nr_rel_entries) { 691 symidx = GELF_R_SYM(pos->r_info); 692 plt_offset += shdr_plt.sh_entsize; 693 gelf_getsym(syms, symidx, &sym); 694 snprintf(sympltname, sizeof(sympltname), 695 "%s@plt", elf_sym__name(&sym, symstrs)); 696 697 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 698 sympltname); 699 if (!f) 700 goto out_elf_end; 701 702 if (filter && filter(map, f)) 703 symbol__delete(f); 704 else { 705 symbols__insert(&self->symbols[map->type], f); 706 ++nr; 707 } 708 } 709 } else if (shdr_rel_plt.sh_type == SHT_REL) { 710 GElf_Rel pos_mem, *pos; 711 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 712 nr_rel_entries) { 713 symidx = GELF_R_SYM(pos->r_info); 714 plt_offset += shdr_plt.sh_entsize; 715 gelf_getsym(syms, symidx, &sym); 716 snprintf(sympltname, sizeof(sympltname), 717 "%s@plt", elf_sym__name(&sym, symstrs)); 718 719 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 720 sympltname); 721 if (!f) 722 goto out_elf_end; 723 724 if (filter && filter(map, f)) 725 symbol__delete(f); 726 else { 727 symbols__insert(&self->symbols[map->type], f); 728 ++nr; 729 } 730 } 731 } 732 733 err = 0; 734 out_elf_end: 735 elf_end(elf); 736 out_close: 737 close(fd); 738 739 if (err == 0) 740 return nr; 741 out: 742 pr_warning("%s: problems reading %s PLT info.\n", 743 __func__, self->long_name); 744 return 0; 745 } 746 747 static int dso__load_sym(struct dso *self, struct map *map, 748 struct thread *thread, const char *name, int fd, 749 symbol_filter_t filter, int kernel, int kmodule) 750 { 751 struct map *curr_map = map; 752 struct dso *curr_dso = self; 753 size_t dso_name_len = strlen(self->short_name); 754 Elf_Data *symstrs, *secstrs; 755 uint32_t nr_syms; 756 int err = -1; 757 uint32_t idx; 758 GElf_Ehdr ehdr; 759 GElf_Shdr shdr; 760 Elf_Data *syms; 761 GElf_Sym sym; 762 Elf_Scn *sec, *sec_strndx; 763 Elf *elf; 764 int nr = 0; 765 766 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 767 if (elf == NULL) { 768 pr_err("%s: cannot read %s ELF file.\n", __func__, name); 769 goto out_close; 770 } 771 772 if (gelf_getehdr(elf, &ehdr) == NULL) { 773 pr_err("%s: cannot get elf header.\n", __func__); 774 goto out_elf_end; 775 } 776 777 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL); 778 if (sec == NULL) { 779 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL); 780 if (sec == NULL) 781 goto out_elf_end; 782 } 783 784 syms = elf_getdata(sec, NULL); 785 if (syms == NULL) 786 goto out_elf_end; 787 788 sec = elf_getscn(elf, shdr.sh_link); 789 if (sec == NULL) 790 goto out_elf_end; 791 792 symstrs = elf_getdata(sec, NULL); 793 if (symstrs == NULL) 794 goto out_elf_end; 795 796 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); 797 if (sec_strndx == NULL) 798 goto out_elf_end; 799 800 secstrs = elf_getdata(sec_strndx, NULL); 801 if (secstrs == NULL) 802 goto out_elf_end; 803 804 nr_syms = shdr.sh_size / shdr.sh_entsize; 805 806 memset(&sym, 0, sizeof(sym)); 807 if (!kernel) { 808 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 809 elf_section_by_name(elf, &ehdr, &shdr, 810 ".gnu.prelink_undo", 811 NULL) != NULL); 812 } else self->adjust_symbols = 0; 813 814 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 815 struct symbol *f; 816 const char *elf_name; 817 char *demangled = NULL; 818 int is_label = elf_sym__is_label(&sym); 819 const char *section_name; 820 821 if (!is_label && !elf_sym__is_function(&sym)) 822 continue; 823 824 sec = elf_getscn(elf, sym.st_shndx); 825 if (!sec) 826 goto out_elf_end; 827 828 gelf_getshdr(sec, &shdr); 829 830 if (is_label && !elf_sec__is_text(&shdr, secstrs)) 831 continue; 832 833 elf_name = elf_sym__name(&sym, symstrs); 834 section_name = elf_sec__name(&shdr, secstrs); 835 836 if (kernel || kmodule) { 837 char dso_name[PATH_MAX]; 838 839 if (strcmp(section_name, 840 curr_dso->short_name + dso_name_len) == 0) 841 goto new_symbol; 842 843 if (strcmp(section_name, ".text") == 0) { 844 curr_map = map; 845 curr_dso = self; 846 goto new_symbol; 847 } 848 849 snprintf(dso_name, sizeof(dso_name), 850 "%s%s", self->short_name, section_name); 851 852 curr_map = thread__find_map_by_name(thread, dso_name); 853 if (curr_map == NULL) { 854 u64 start = sym.st_value; 855 856 if (kmodule) 857 start += map->start + shdr.sh_offset; 858 859 curr_dso = dso__new(dso_name); 860 if (curr_dso == NULL) 861 goto out_elf_end; 862 curr_map = map__new2(start, curr_dso, 863 MAP__FUNCTION); 864 if (curr_map == NULL) { 865 dso__delete(curr_dso); 866 goto out_elf_end; 867 } 868 curr_map->map_ip = identity__map_ip; 869 curr_map->unmap_ip = identity__map_ip; 870 curr_dso->origin = DSO__ORIG_KERNEL; 871 __thread__insert_map(kthread, curr_map); 872 dsos__add(&dsos__kernel, curr_dso); 873 } else 874 curr_dso = curr_map->dso; 875 876 goto new_symbol; 877 } 878 879 if (curr_dso->adjust_symbols) { 880 pr_debug2("adjusting symbol: st_value: %Lx sh_addr: " 881 "%Lx sh_offset: %Lx\n", (u64)sym.st_value, 882 (u64)shdr.sh_addr, (u64)shdr.sh_offset); 883 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 884 } 885 /* 886 * We need to figure out if the object was created from C++ sources 887 * DWARF DW_compile_unit has this, but we don't always have access 888 * to it... 889 */ 890 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 891 if (demangled != NULL) 892 elf_name = demangled; 893 new_symbol: 894 f = symbol__new(sym.st_value, sym.st_size, elf_name); 895 free(demangled); 896 if (!f) 897 goto out_elf_end; 898 899 if (filter && filter(curr_map, f)) 900 symbol__delete(f); 901 else { 902 symbols__insert(&curr_dso->symbols[curr_map->type], f); 903 nr++; 904 } 905 } 906 907 /* 908 * For misannotated, zeroed, ASM function sizes. 909 */ 910 if (nr > 0) 911 symbols__fixup_end(&self->symbols[map->type]); 912 err = nr; 913 out_elf_end: 914 elf_end(elf); 915 out_close: 916 return err; 917 } 918 919 static bool dso__build_id_equal(const struct dso *self, u8 *build_id) 920 { 921 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0; 922 } 923 924 static bool __dsos__read_build_ids(struct list_head *head) 925 { 926 bool have_build_id = false; 927 struct dso *pos; 928 929 list_for_each_entry(pos, head, node) 930 if (filename__read_build_id(pos->long_name, pos->build_id, 931 sizeof(pos->build_id)) > 0) { 932 have_build_id = true; 933 pos->has_build_id = true; 934 } 935 936 return have_build_id; 937 } 938 939 bool dsos__read_build_ids(void) 940 { 941 bool kbuildids = __dsos__read_build_ids(&dsos__kernel), 942 ubuildids = __dsos__read_build_ids(&dsos__user); 943 return kbuildids || ubuildids; 944 } 945 946 /* 947 * Align offset to 4 bytes as needed for note name and descriptor data. 948 */ 949 #define NOTE_ALIGN(n) (((n) + 3) & -4U) 950 951 int filename__read_build_id(const char *filename, void *bf, size_t size) 952 { 953 int fd, err = -1; 954 GElf_Ehdr ehdr; 955 GElf_Shdr shdr; 956 Elf_Data *data; 957 Elf_Scn *sec; 958 Elf_Kind ek; 959 void *ptr; 960 Elf *elf; 961 962 if (size < BUILD_ID_SIZE) 963 goto out; 964 965 fd = open(filename, O_RDONLY); 966 if (fd < 0) 967 goto out; 968 969 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 970 if (elf == NULL) { 971 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename); 972 goto out_close; 973 } 974 975 ek = elf_kind(elf); 976 if (ek != ELF_K_ELF) 977 goto out_elf_end; 978 979 if (gelf_getehdr(elf, &ehdr) == NULL) { 980 pr_err("%s: cannot get elf header.\n", __func__); 981 goto out_elf_end; 982 } 983 984 sec = elf_section_by_name(elf, &ehdr, &shdr, 985 ".note.gnu.build-id", NULL); 986 if (sec == NULL) { 987 sec = elf_section_by_name(elf, &ehdr, &shdr, 988 ".notes", NULL); 989 if (sec == NULL) 990 goto out_elf_end; 991 } 992 993 data = elf_getdata(sec, NULL); 994 if (data == NULL) 995 goto out_elf_end; 996 997 ptr = data->d_buf; 998 while (ptr < (data->d_buf + data->d_size)) { 999 GElf_Nhdr *nhdr = ptr; 1000 int namesz = NOTE_ALIGN(nhdr->n_namesz), 1001 descsz = NOTE_ALIGN(nhdr->n_descsz); 1002 const char *name; 1003 1004 ptr += sizeof(*nhdr); 1005 name = ptr; 1006 ptr += namesz; 1007 if (nhdr->n_type == NT_GNU_BUILD_ID && 1008 nhdr->n_namesz == sizeof("GNU")) { 1009 if (memcmp(name, "GNU", sizeof("GNU")) == 0) { 1010 memcpy(bf, ptr, BUILD_ID_SIZE); 1011 err = BUILD_ID_SIZE; 1012 break; 1013 } 1014 } 1015 ptr += descsz; 1016 } 1017 out_elf_end: 1018 elf_end(elf); 1019 out_close: 1020 close(fd); 1021 out: 1022 return err; 1023 } 1024 1025 int sysfs__read_build_id(const char *filename, void *build_id, size_t size) 1026 { 1027 int fd, err = -1; 1028 1029 if (size < BUILD_ID_SIZE) 1030 goto out; 1031 1032 fd = open(filename, O_RDONLY); 1033 if (fd < 0) 1034 goto out; 1035 1036 while (1) { 1037 char bf[BUFSIZ]; 1038 GElf_Nhdr nhdr; 1039 int namesz, descsz; 1040 1041 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr)) 1042 break; 1043 1044 namesz = NOTE_ALIGN(nhdr.n_namesz); 1045 descsz = NOTE_ALIGN(nhdr.n_descsz); 1046 if (nhdr.n_type == NT_GNU_BUILD_ID && 1047 nhdr.n_namesz == sizeof("GNU")) { 1048 if (read(fd, bf, namesz) != namesz) 1049 break; 1050 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) { 1051 if (read(fd, build_id, 1052 BUILD_ID_SIZE) == BUILD_ID_SIZE) { 1053 err = 0; 1054 break; 1055 } 1056 } else if (read(fd, bf, descsz) != descsz) 1057 break; 1058 } else { 1059 int n = namesz + descsz; 1060 if (read(fd, bf, n) != n) 1061 break; 1062 } 1063 } 1064 close(fd); 1065 out: 1066 return err; 1067 } 1068 1069 char dso__symtab_origin(const struct dso *self) 1070 { 1071 static const char origin[] = { 1072 [DSO__ORIG_KERNEL] = 'k', 1073 [DSO__ORIG_JAVA_JIT] = 'j', 1074 [DSO__ORIG_FEDORA] = 'f', 1075 [DSO__ORIG_UBUNTU] = 'u', 1076 [DSO__ORIG_BUILDID] = 'b', 1077 [DSO__ORIG_DSO] = 'd', 1078 [DSO__ORIG_KMODULE] = 'K', 1079 }; 1080 1081 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 1082 return '!'; 1083 return origin[self->origin]; 1084 } 1085 1086 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1087 { 1088 int size = PATH_MAX; 1089 char *name; 1090 u8 build_id[BUILD_ID_SIZE]; 1091 int ret = -1; 1092 int fd; 1093 1094 dso__set_loaded(self, map->type); 1095 1096 if (self->kernel) 1097 return dso__load_kernel_sym(self, map, kthread, filter); 1098 1099 name = malloc(size); 1100 if (!name) 1101 return -1; 1102 1103 self->adjust_symbols = 0; 1104 1105 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 1106 ret = dso__load_perf_map(self, map, filter); 1107 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 1108 DSO__ORIG_NOT_FOUND; 1109 return ret; 1110 } 1111 1112 self->origin = DSO__ORIG_FEDORA - 1; 1113 1114 more: 1115 do { 1116 self->origin++; 1117 switch (self->origin) { 1118 case DSO__ORIG_FEDORA: 1119 snprintf(name, size, "/usr/lib/debug%s.debug", 1120 self->long_name); 1121 break; 1122 case DSO__ORIG_UBUNTU: 1123 snprintf(name, size, "/usr/lib/debug%s", 1124 self->long_name); 1125 break; 1126 case DSO__ORIG_BUILDID: 1127 if (filename__read_build_id(self->long_name, build_id, 1128 sizeof(build_id))) { 1129 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1130 1131 build_id__sprintf(build_id, sizeof(build_id), 1132 build_id_hex); 1133 snprintf(name, size, 1134 "/usr/lib/debug/.build-id/%.2s/%s.debug", 1135 build_id_hex, build_id_hex + 2); 1136 if (self->has_build_id) 1137 goto compare_build_id; 1138 break; 1139 } 1140 self->origin++; 1141 /* Fall thru */ 1142 case DSO__ORIG_DSO: 1143 snprintf(name, size, "%s", self->long_name); 1144 break; 1145 1146 default: 1147 goto out; 1148 } 1149 1150 if (self->has_build_id) { 1151 if (filename__read_build_id(name, build_id, 1152 sizeof(build_id)) < 0) 1153 goto more; 1154 compare_build_id: 1155 if (!dso__build_id_equal(self, build_id)) 1156 goto more; 1157 } 1158 1159 fd = open(name, O_RDONLY); 1160 } while (fd < 0); 1161 1162 ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0); 1163 close(fd); 1164 1165 /* 1166 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!? 1167 */ 1168 if (!ret) 1169 goto more; 1170 1171 if (ret > 0) { 1172 int nr_plt = dso__synthesize_plt_symbols(self, map, filter); 1173 if (nr_plt > 0) 1174 ret += nr_plt; 1175 } 1176 out: 1177 free(name); 1178 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 1179 return 0; 1180 return ret; 1181 } 1182 1183 static struct map *thread__find_map_by_name(struct thread *self, char *name) 1184 { 1185 struct rb_node *nd; 1186 1187 for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { 1188 struct map *map = rb_entry(nd, struct map, rb_node); 1189 1190 if (map->dso && strcmp(map->dso->name, name) == 0) 1191 return map; 1192 } 1193 1194 return NULL; 1195 } 1196 1197 static int dsos__set_modules_path_dir(char *dirname) 1198 { 1199 struct dirent *dent; 1200 DIR *dir = opendir(dirname); 1201 1202 if (!dir) { 1203 pr_debug("%s: cannot open %s dir\n", __func__, dirname); 1204 return -1; 1205 } 1206 1207 while ((dent = readdir(dir)) != NULL) { 1208 char path[PATH_MAX]; 1209 1210 if (dent->d_type == DT_DIR) { 1211 if (!strcmp(dent->d_name, ".") || 1212 !strcmp(dent->d_name, "..")) 1213 continue; 1214 1215 snprintf(path, sizeof(path), "%s/%s", 1216 dirname, dent->d_name); 1217 if (dsos__set_modules_path_dir(path) < 0) 1218 goto failure; 1219 } else { 1220 char *dot = strrchr(dent->d_name, '.'), 1221 dso_name[PATH_MAX]; 1222 struct map *map; 1223 char *long_name; 1224 1225 if (dot == NULL || strcmp(dot, ".ko")) 1226 continue; 1227 snprintf(dso_name, sizeof(dso_name), "[%.*s]", 1228 (int)(dot - dent->d_name), dent->d_name); 1229 1230 strxfrchar(dso_name, '-', '_'); 1231 map = thread__find_map_by_name(kthread, dso_name); 1232 if (map == NULL) 1233 continue; 1234 1235 snprintf(path, sizeof(path), "%s/%s", 1236 dirname, dent->d_name); 1237 1238 long_name = strdup(path); 1239 if (long_name == NULL) 1240 goto failure; 1241 dso__set_long_name(map->dso, long_name); 1242 } 1243 } 1244 1245 return 0; 1246 failure: 1247 closedir(dir); 1248 return -1; 1249 } 1250 1251 static int dsos__set_modules_path(void) 1252 { 1253 struct utsname uts; 1254 char modules_path[PATH_MAX]; 1255 1256 if (uname(&uts) < 0) 1257 return -1; 1258 1259 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", 1260 uts.release); 1261 1262 return dsos__set_modules_path_dir(modules_path); 1263 } 1264 1265 /* 1266 * Constructor variant for modules (where we know from /proc/modules where 1267 * they are loaded) and for vmlinux, where only after we load all the 1268 * symbols we'll know where it starts and ends. 1269 */ 1270 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 1271 { 1272 struct map *self = malloc(sizeof(*self)); 1273 1274 if (self != NULL) { 1275 /* 1276 * ->end will be filled after we load all the symbols 1277 */ 1278 map__init(self, type, start, 0, 0, dso); 1279 } 1280 1281 return self; 1282 } 1283 1284 static int thread__create_module_maps(struct thread *self) 1285 { 1286 char *line = NULL; 1287 size_t n; 1288 FILE *file = fopen("/proc/modules", "r"); 1289 struct map *map; 1290 1291 if (file == NULL) 1292 return -1; 1293 1294 while (!feof(file)) { 1295 char name[PATH_MAX]; 1296 u64 start; 1297 struct dso *dso; 1298 char *sep; 1299 int line_len; 1300 1301 line_len = getline(&line, &n, file); 1302 if (line_len < 0) 1303 break; 1304 1305 if (!line) 1306 goto out_failure; 1307 1308 line[--line_len] = '\0'; /* \n */ 1309 1310 sep = strrchr(line, 'x'); 1311 if (sep == NULL) 1312 continue; 1313 1314 hex2u64(sep + 1, &start); 1315 1316 sep = strchr(line, ' '); 1317 if (sep == NULL) 1318 continue; 1319 1320 *sep = '\0'; 1321 1322 snprintf(name, sizeof(name), "[%s]", line); 1323 dso = dso__new(name); 1324 1325 if (dso == NULL) 1326 goto out_delete_line; 1327 1328 map = map__new2(start, dso, MAP__FUNCTION); 1329 if (map == NULL) { 1330 dso__delete(dso); 1331 goto out_delete_line; 1332 } 1333 1334 snprintf(name, sizeof(name), 1335 "/sys/module/%s/notes/.note.gnu.build-id", line); 1336 if (sysfs__read_build_id(name, dso->build_id, 1337 sizeof(dso->build_id)) == 0) 1338 dso->has_build_id = true; 1339 1340 dso->origin = DSO__ORIG_KMODULE; 1341 __thread__insert_map(self, map); 1342 dsos__add(&dsos__kernel, dso); 1343 } 1344 1345 free(line); 1346 fclose(file); 1347 1348 return dsos__set_modules_path(); 1349 1350 out_delete_line: 1351 free(line); 1352 out_failure: 1353 return -1; 1354 } 1355 1356 static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *thread, 1357 const char *vmlinux, symbol_filter_t filter) 1358 { 1359 int err = -1, fd; 1360 1361 if (self->has_build_id) { 1362 u8 build_id[BUILD_ID_SIZE]; 1363 1364 if (filename__read_build_id(vmlinux, build_id, 1365 sizeof(build_id)) < 0) { 1366 pr_debug("No build_id in %s, ignoring it\n", vmlinux); 1367 return -1; 1368 } 1369 if (!dso__build_id_equal(self, build_id)) { 1370 char expected_build_id[BUILD_ID_SIZE * 2 + 1], 1371 vmlinux_build_id[BUILD_ID_SIZE * 2 + 1]; 1372 1373 build_id__sprintf(self->build_id, 1374 sizeof(self->build_id), 1375 expected_build_id); 1376 build_id__sprintf(build_id, sizeof(build_id), 1377 vmlinux_build_id); 1378 pr_debug("build_id in %s is %s while expected is %s, " 1379 "ignoring it\n", vmlinux, vmlinux_build_id, 1380 expected_build_id); 1381 return -1; 1382 } 1383 } 1384 1385 fd = open(vmlinux, O_RDONLY); 1386 if (fd < 0) 1387 return -1; 1388 1389 dso__set_loaded(self, map->type); 1390 err = dso__load_sym(self, map, thread, self->long_name, fd, filter, 1, 0); 1391 close(fd); 1392 1393 return err; 1394 } 1395 1396 static int dso__load_kernel_sym(struct dso *self, struct map *map, 1397 struct thread *thread, symbol_filter_t filter) 1398 { 1399 int err; 1400 bool is_kallsyms; 1401 1402 if (vmlinux_path != NULL) { 1403 int i; 1404 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1405 vmlinux_path__nr_entries); 1406 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1407 err = dso__load_vmlinux(self, map, thread, 1408 vmlinux_path[i], filter); 1409 if (err > 0) { 1410 pr_debug("Using %s for symbols\n", 1411 vmlinux_path[i]); 1412 dso__set_long_name(self, 1413 strdup(vmlinux_path[i])); 1414 goto out_fixup; 1415 } 1416 } 1417 } 1418 1419 is_kallsyms = self->long_name[0] == '['; 1420 if (is_kallsyms) 1421 goto do_kallsyms; 1422 1423 err = dso__load_vmlinux(self, map, thread, self->long_name, filter); 1424 if (err <= 0) { 1425 pr_info("The file %s cannot be used, " 1426 "trying to use /proc/kallsyms...", self->long_name); 1427 do_kallsyms: 1428 err = dso__load_kallsyms(self, map, thread, filter); 1429 if (err > 0 && !is_kallsyms) 1430 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 1431 } 1432 1433 if (err > 0) { 1434 out_fixup: 1435 map__fixup_start(map); 1436 map__fixup_end(map); 1437 } 1438 1439 return err; 1440 } 1441 1442 LIST_HEAD(dsos__user); 1443 LIST_HEAD(dsos__kernel); 1444 struct dso *vdso; 1445 1446 static void dsos__add(struct list_head *head, struct dso *dso) 1447 { 1448 list_add_tail(&dso->node, head); 1449 } 1450 1451 static struct dso *dsos__find(struct list_head *head, const char *name) 1452 { 1453 struct dso *pos; 1454 1455 list_for_each_entry(pos, head, node) 1456 if (strcmp(pos->name, name) == 0) 1457 return pos; 1458 return NULL; 1459 } 1460 1461 struct dso *dsos__findnew(const char *name) 1462 { 1463 struct dso *dso = dsos__find(&dsos__user, name); 1464 1465 if (!dso) { 1466 dso = dso__new(name); 1467 if (dso != NULL) { 1468 dsos__add(&dsos__user, dso); 1469 dso__set_basename(dso); 1470 } 1471 } 1472 1473 return dso; 1474 } 1475 1476 static void __dsos__fprintf(struct list_head *head, FILE *fp) 1477 { 1478 struct dso *pos; 1479 1480 list_for_each_entry(pos, head, node) { 1481 int i; 1482 for (i = 0; i < MAP__NR_TYPES; ++i) 1483 dso__fprintf(pos, i, fp); 1484 } 1485 } 1486 1487 void dsos__fprintf(FILE *fp) 1488 { 1489 __dsos__fprintf(&dsos__kernel, fp); 1490 __dsos__fprintf(&dsos__user, fp); 1491 } 1492 1493 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp) 1494 { 1495 struct dso *pos; 1496 size_t ret = 0; 1497 1498 list_for_each_entry(pos, head, node) { 1499 ret += dso__fprintf_buildid(pos, fp); 1500 ret += fprintf(fp, " %s\n", pos->long_name); 1501 } 1502 return ret; 1503 } 1504 1505 size_t dsos__fprintf_buildid(FILE *fp) 1506 { 1507 return (__dsos__fprintf_buildid(&dsos__kernel, fp) + 1508 __dsos__fprintf_buildid(&dsos__user, fp)); 1509 } 1510 1511 static int thread__create_kernel_map(struct thread *self, const char *vmlinux) 1512 { 1513 struct map *kmap; 1514 struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]"); 1515 1516 if (kernel == NULL) 1517 return -1; 1518 1519 kmap = map__new2(0, kernel, MAP__FUNCTION); 1520 if (kmap == NULL) 1521 goto out_delete_kernel_dso; 1522 1523 kmap->map_ip = kmap->unmap_ip = identity__map_ip; 1524 kernel->short_name = "[kernel]"; 1525 kernel->kernel = 1; 1526 1527 vdso = dso__new("[vdso]"); 1528 if (vdso == NULL) 1529 goto out_delete_kernel_map; 1530 dso__set_loaded(vdso, MAP__FUNCTION); 1531 1532 if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id, 1533 sizeof(kernel->build_id)) == 0) 1534 kernel->has_build_id = true; 1535 1536 __thread__insert_map(self, kmap); 1537 dsos__add(&dsos__kernel, kernel); 1538 dsos__add(&dsos__user, vdso); 1539 1540 return 0; 1541 1542 out_delete_kernel_map: 1543 map__delete(kmap); 1544 out_delete_kernel_dso: 1545 dso__delete(kernel); 1546 return -1; 1547 } 1548 1549 static void vmlinux_path__exit(void) 1550 { 1551 while (--vmlinux_path__nr_entries >= 0) { 1552 free(vmlinux_path[vmlinux_path__nr_entries]); 1553 vmlinux_path[vmlinux_path__nr_entries] = NULL; 1554 } 1555 1556 free(vmlinux_path); 1557 vmlinux_path = NULL; 1558 } 1559 1560 static int vmlinux_path__init(void) 1561 { 1562 struct utsname uts; 1563 char bf[PATH_MAX]; 1564 1565 if (uname(&uts) < 0) 1566 return -1; 1567 1568 vmlinux_path = malloc(sizeof(char *) * 5); 1569 if (vmlinux_path == NULL) 1570 return -1; 1571 1572 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux"); 1573 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1574 goto out_fail; 1575 ++vmlinux_path__nr_entries; 1576 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux"); 1577 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1578 goto out_fail; 1579 ++vmlinux_path__nr_entries; 1580 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); 1581 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1582 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1583 goto out_fail; 1584 ++vmlinux_path__nr_entries; 1585 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release); 1586 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1587 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1588 goto out_fail; 1589 ++vmlinux_path__nr_entries; 1590 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", 1591 uts.release); 1592 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1593 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1594 goto out_fail; 1595 ++vmlinux_path__nr_entries; 1596 1597 return 0; 1598 1599 out_fail: 1600 vmlinux_path__exit(); 1601 return -1; 1602 } 1603 1604 int symbol__init(struct symbol_conf *conf) 1605 { 1606 const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; 1607 1608 elf_version(EV_CURRENT); 1609 symbol__priv_size = pconf->priv_size; 1610 thread__init(kthread, 0); 1611 1612 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) 1613 return -1; 1614 1615 if (thread__create_kernel_map(kthread, pconf->vmlinux_name) < 0) { 1616 vmlinux_path__exit(); 1617 return -1; 1618 } 1619 1620 kthread->use_modules = pconf->use_modules; 1621 if (pconf->use_modules && thread__create_module_maps(kthread) < 0) 1622 pr_debug("Failed to load list of modules in use, " 1623 "continuing...\n"); 1624 /* 1625 * Now that we have all the maps created, just set the ->end of them: 1626 */ 1627 thread__fixup_maps_end(kthread); 1628 return 0; 1629 } 1630