1 #include "util.h" 2 #include "../perf.h" 3 #include "string.h" 4 #include "symbol.h" 5 6 #include "debug.h" 7 8 #include <libelf.h> 9 #include <gelf.h> 10 #include <elf.h> 11 12 const char *sym_hist_filter; 13 14 enum dso_origin { 15 DSO__ORIG_KERNEL = 0, 16 DSO__ORIG_JAVA_JIT, 17 DSO__ORIG_FEDORA, 18 DSO__ORIG_UBUNTU, 19 DSO__ORIG_BUILDID, 20 DSO__ORIG_DSO, 21 DSO__ORIG_NOT_FOUND, 22 }; 23 24 static struct symbol *symbol__new(u64 start, u64 len, 25 const char *name, unsigned int priv_size, 26 u64 obj_start, int v) 27 { 28 size_t namelen = strlen(name) + 1; 29 struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen); 30 31 if (!self) 32 return NULL; 33 34 if (v >= 2) 35 printf("new symbol: %016Lx [%08lx]: %s, hist: %p, obj_start: %p\n", 36 (u64)start, (unsigned long)len, name, self->hist, (void *)(unsigned long)obj_start); 37 38 self->obj_start= obj_start; 39 self->hist = NULL; 40 self->hist_sum = 0; 41 42 if (sym_hist_filter && !strcmp(name, sym_hist_filter)) 43 self->hist = calloc(sizeof(u64), len); 44 45 if (priv_size) { 46 memset(self, 0, priv_size); 47 self = ((void *)self) + priv_size; 48 } 49 self->start = start; 50 self->end = len ? start + len - 1 : start; 51 memcpy(self->name, name, namelen); 52 53 return self; 54 } 55 56 static void symbol__delete(struct symbol *self, unsigned int priv_size) 57 { 58 free(((void *)self) - priv_size); 59 } 60 61 static size_t symbol__fprintf(struct symbol *self, FILE *fp) 62 { 63 if (!self->module) 64 return fprintf(fp, " %llx-%llx %s\n", 65 self->start, self->end, self->name); 66 else 67 return fprintf(fp, " %llx-%llx %s \t[%s]\n", 68 self->start, self->end, self->name, self->module->name); 69 } 70 71 struct dso *dso__new(const char *name, unsigned int sym_priv_size) 72 { 73 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); 74 75 if (self != NULL) { 76 strcpy(self->name, name); 77 self->syms = RB_ROOT; 78 self->sym_priv_size = sym_priv_size; 79 self->find_symbol = dso__find_symbol; 80 self->slen_calculated = 0; 81 self->origin = DSO__ORIG_NOT_FOUND; 82 } 83 84 return self; 85 } 86 87 static void dso__delete_symbols(struct dso *self) 88 { 89 struct symbol *pos; 90 struct rb_node *next = rb_first(&self->syms); 91 92 while (next) { 93 pos = rb_entry(next, struct symbol, rb_node); 94 next = rb_next(&pos->rb_node); 95 rb_erase(&pos->rb_node, &self->syms); 96 symbol__delete(pos, self->sym_priv_size); 97 } 98 } 99 100 void dso__delete(struct dso *self) 101 { 102 dso__delete_symbols(self); 103 free(self); 104 } 105 106 static void dso__insert_symbol(struct dso *self, struct symbol *sym) 107 { 108 struct rb_node **p = &self->syms.rb_node; 109 struct rb_node *parent = NULL; 110 const u64 ip = sym->start; 111 struct symbol *s; 112 113 while (*p != NULL) { 114 parent = *p; 115 s = rb_entry(parent, struct symbol, rb_node); 116 if (ip < s->start) 117 p = &(*p)->rb_left; 118 else 119 p = &(*p)->rb_right; 120 } 121 rb_link_node(&sym->rb_node, parent, p); 122 rb_insert_color(&sym->rb_node, &self->syms); 123 } 124 125 struct symbol *dso__find_symbol(struct dso *self, u64 ip) 126 { 127 struct rb_node *n; 128 129 if (self == NULL) 130 return NULL; 131 132 n = self->syms.rb_node; 133 134 while (n) { 135 struct symbol *s = rb_entry(n, struct symbol, rb_node); 136 137 if (ip < s->start) 138 n = n->rb_left; 139 else if (ip > s->end) 140 n = n->rb_right; 141 else 142 return s; 143 } 144 145 return NULL; 146 } 147 148 size_t dso__fprintf(struct dso *self, FILE *fp) 149 { 150 size_t ret = fprintf(fp, "dso: %s\n", self->name); 151 152 struct rb_node *nd; 153 for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) { 154 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 155 ret += symbol__fprintf(pos, fp); 156 } 157 158 return ret; 159 } 160 161 static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v) 162 { 163 struct rb_node *nd, *prevnd; 164 char *line = NULL; 165 size_t n; 166 FILE *file = fopen("/proc/kallsyms", "r"); 167 int count = 0; 168 169 if (file == NULL) 170 goto out_failure; 171 172 while (!feof(file)) { 173 u64 start; 174 struct symbol *sym; 175 int line_len, len; 176 char symbol_type; 177 178 line_len = getline(&line, &n, file); 179 if (line_len < 0) 180 break; 181 182 if (!line) 183 goto out_failure; 184 185 line[--line_len] = '\0'; /* \n */ 186 187 len = hex2u64(line, &start); 188 189 len++; 190 if (len + 2 >= line_len) 191 continue; 192 193 symbol_type = toupper(line[len]); 194 /* 195 * We're interested only in code ('T'ext) 196 */ 197 if (symbol_type != 'T' && symbol_type != 'W') 198 continue; 199 /* 200 * Well fix up the end later, when we have all sorted. 201 */ 202 sym = symbol__new(start, 0xdead, line + len + 2, 203 self->sym_priv_size, 0, v); 204 205 if (sym == NULL) 206 goto out_delete_line; 207 208 if (filter && filter(self, sym)) 209 symbol__delete(sym, self->sym_priv_size); 210 else { 211 dso__insert_symbol(self, sym); 212 count++; 213 } 214 } 215 216 /* 217 * Now that we have all sorted out, just set the ->end of all 218 * symbols 219 */ 220 prevnd = rb_first(&self->syms); 221 222 if (prevnd == NULL) 223 goto out_delete_line; 224 225 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 226 struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node), 227 *curr = rb_entry(nd, struct symbol, rb_node); 228 229 prev->end = curr->start - 1; 230 prevnd = nd; 231 } 232 233 free(line); 234 fclose(file); 235 236 return count; 237 238 out_delete_line: 239 free(line); 240 out_failure: 241 return -1; 242 } 243 244 static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v) 245 { 246 char *line = NULL; 247 size_t n; 248 FILE *file; 249 int nr_syms = 0; 250 251 file = fopen(self->name, "r"); 252 if (file == NULL) 253 goto out_failure; 254 255 while (!feof(file)) { 256 u64 start, size; 257 struct symbol *sym; 258 int line_len, len; 259 260 line_len = getline(&line, &n, file); 261 if (line_len < 0) 262 break; 263 264 if (!line) 265 goto out_failure; 266 267 line[--line_len] = '\0'; /* \n */ 268 269 len = hex2u64(line, &start); 270 271 len++; 272 if (len + 2 >= line_len) 273 continue; 274 275 len += hex2u64(line + len, &size); 276 277 len++; 278 if (len + 2 >= line_len) 279 continue; 280 281 sym = symbol__new(start, size, line + len, 282 self->sym_priv_size, start, v); 283 284 if (sym == NULL) 285 goto out_delete_line; 286 287 if (filter && filter(self, sym)) 288 symbol__delete(sym, self->sym_priv_size); 289 else { 290 dso__insert_symbol(self, sym); 291 nr_syms++; 292 } 293 } 294 295 free(line); 296 fclose(file); 297 298 return nr_syms; 299 300 out_delete_line: 301 free(line); 302 out_failure: 303 return -1; 304 } 305 306 /** 307 * elf_symtab__for_each_symbol - iterate thru all the symbols 308 * 309 * @self: struct elf_symtab instance to iterate 310 * @idx: uint32_t idx 311 * @sym: GElf_Sym iterator 312 */ 313 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \ 314 for (idx = 0, gelf_getsym(syms, idx, &sym);\ 315 idx < nr_syms; \ 316 idx++, gelf_getsym(syms, idx, &sym)) 317 318 static inline uint8_t elf_sym__type(const GElf_Sym *sym) 319 { 320 return GELF_ST_TYPE(sym->st_info); 321 } 322 323 static inline int elf_sym__is_function(const GElf_Sym *sym) 324 { 325 return elf_sym__type(sym) == STT_FUNC && 326 sym->st_name != 0 && 327 sym->st_shndx != SHN_UNDEF; 328 } 329 330 static inline int elf_sym__is_label(const GElf_Sym *sym) 331 { 332 return elf_sym__type(sym) == STT_NOTYPE && 333 sym->st_name != 0 && 334 sym->st_shndx != SHN_UNDEF && 335 sym->st_shndx != SHN_ABS; 336 } 337 338 static inline const char *elf_sec__name(const GElf_Shdr *shdr, 339 const Elf_Data *secstrs) 340 { 341 return secstrs->d_buf + shdr->sh_name; 342 } 343 344 static inline int elf_sec__is_text(const GElf_Shdr *shdr, 345 const Elf_Data *secstrs) 346 { 347 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; 348 } 349 350 static inline const char *elf_sym__name(const GElf_Sym *sym, 351 const Elf_Data *symstrs) 352 { 353 return symstrs->d_buf + sym->st_name; 354 } 355 356 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 357 GElf_Shdr *shp, const char *name, 358 size_t *idx) 359 { 360 Elf_Scn *sec = NULL; 361 size_t cnt = 1; 362 363 while ((sec = elf_nextscn(elf, sec)) != NULL) { 364 char *str; 365 366 gelf_getshdr(sec, shp); 367 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); 368 if (!strcmp(name, str)) { 369 if (idx) 370 *idx = cnt; 371 break; 372 } 373 ++cnt; 374 } 375 376 return sec; 377 } 378 379 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \ 380 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \ 381 idx < nr_entries; \ 382 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem)) 383 384 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \ 385 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \ 386 idx < nr_entries; \ 387 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem)) 388 389 /* 390 * We need to check if we have a .dynsym, so that we can handle the 391 * .plt, synthesizing its symbols, that aren't on the symtabs (be it 392 * .dynsym or .symtab). 393 * And always look at the original dso, not at debuginfo packages, that 394 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 395 */ 396 static int dso__synthesize_plt_symbols(struct dso *self, int v) 397 { 398 uint32_t nr_rel_entries, idx; 399 GElf_Sym sym; 400 u64 plt_offset; 401 GElf_Shdr shdr_plt; 402 struct symbol *f; 403 GElf_Shdr shdr_rel_plt, shdr_dynsym; 404 Elf_Data *reldata, *syms, *symstrs; 405 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym; 406 size_t dynsym_idx; 407 GElf_Ehdr ehdr; 408 char sympltname[1024]; 409 Elf *elf; 410 int nr = 0, symidx, fd, err = 0; 411 412 fd = open(self->name, O_RDONLY); 413 if (fd < 0) 414 goto out; 415 416 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 417 if (elf == NULL) 418 goto out_close; 419 420 if (gelf_getehdr(elf, &ehdr) == NULL) 421 goto out_elf_end; 422 423 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym, 424 ".dynsym", &dynsym_idx); 425 if (scn_dynsym == NULL) 426 goto out_elf_end; 427 428 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 429 ".rela.plt", NULL); 430 if (scn_plt_rel == NULL) { 431 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 432 ".rel.plt", NULL); 433 if (scn_plt_rel == NULL) 434 goto out_elf_end; 435 } 436 437 err = -1; 438 439 if (shdr_rel_plt.sh_link != dynsym_idx) 440 goto out_elf_end; 441 442 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL) 443 goto out_elf_end; 444 445 /* 446 * Fetch the relocation section to find the idxes to the GOT 447 * and the symbols in the .dynsym they refer to. 448 */ 449 reldata = elf_getdata(scn_plt_rel, NULL); 450 if (reldata == NULL) 451 goto out_elf_end; 452 453 syms = elf_getdata(scn_dynsym, NULL); 454 if (syms == NULL) 455 goto out_elf_end; 456 457 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link); 458 if (scn_symstrs == NULL) 459 goto out_elf_end; 460 461 symstrs = elf_getdata(scn_symstrs, NULL); 462 if (symstrs == NULL) 463 goto out_elf_end; 464 465 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; 466 plt_offset = shdr_plt.sh_offset; 467 468 if (shdr_rel_plt.sh_type == SHT_RELA) { 469 GElf_Rela pos_mem, *pos; 470 471 elf_section__for_each_rela(reldata, pos, pos_mem, idx, 472 nr_rel_entries) { 473 symidx = GELF_R_SYM(pos->r_info); 474 plt_offset += shdr_plt.sh_entsize; 475 gelf_getsym(syms, symidx, &sym); 476 snprintf(sympltname, sizeof(sympltname), 477 "%s@plt", elf_sym__name(&sym, symstrs)); 478 479 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 480 sympltname, self->sym_priv_size, 0, v); 481 if (!f) 482 goto out_elf_end; 483 484 dso__insert_symbol(self, f); 485 ++nr; 486 } 487 } else if (shdr_rel_plt.sh_type == SHT_REL) { 488 GElf_Rel pos_mem, *pos; 489 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 490 nr_rel_entries) { 491 symidx = GELF_R_SYM(pos->r_info); 492 plt_offset += shdr_plt.sh_entsize; 493 gelf_getsym(syms, symidx, &sym); 494 snprintf(sympltname, sizeof(sympltname), 495 "%s@plt", elf_sym__name(&sym, symstrs)); 496 497 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 498 sympltname, self->sym_priv_size, 0, v); 499 if (!f) 500 goto out_elf_end; 501 502 dso__insert_symbol(self, f); 503 ++nr; 504 } 505 } 506 507 err = 0; 508 out_elf_end: 509 elf_end(elf); 510 out_close: 511 close(fd); 512 513 if (err == 0) 514 return nr; 515 out: 516 fprintf(stderr, "%s: problems reading %s PLT info.\n", 517 __func__, self->name); 518 return 0; 519 } 520 521 static int dso__load_sym(struct dso *self, int fd, const char *name, 522 symbol_filter_t filter, int v, struct module *mod) 523 { 524 Elf_Data *symstrs, *secstrs; 525 uint32_t nr_syms; 526 int err = -1; 527 uint32_t idx; 528 GElf_Ehdr ehdr; 529 GElf_Shdr shdr; 530 Elf_Data *syms; 531 GElf_Sym sym; 532 Elf_Scn *sec, *sec_strndx; 533 Elf *elf; 534 int nr = 0, kernel = !strcmp("[kernel]", self->name); 535 536 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 537 if (elf == NULL) { 538 if (v) 539 fprintf(stderr, "%s: cannot read %s ELF file.\n", 540 __func__, name); 541 goto out_close; 542 } 543 544 if (gelf_getehdr(elf, &ehdr) == NULL) { 545 if (v) 546 fprintf(stderr, "%s: cannot get elf header.\n", __func__); 547 goto out_elf_end; 548 } 549 550 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL); 551 if (sec == NULL) { 552 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL); 553 if (sec == NULL) 554 goto out_elf_end; 555 } 556 557 syms = elf_getdata(sec, NULL); 558 if (syms == NULL) 559 goto out_elf_end; 560 561 sec = elf_getscn(elf, shdr.sh_link); 562 if (sec == NULL) 563 goto out_elf_end; 564 565 symstrs = elf_getdata(sec, NULL); 566 if (symstrs == NULL) 567 goto out_elf_end; 568 569 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); 570 if (sec_strndx == NULL) 571 goto out_elf_end; 572 573 secstrs = elf_getdata(sec_strndx, NULL); 574 if (secstrs == NULL) 575 goto out_elf_end; 576 577 nr_syms = shdr.sh_size / shdr.sh_entsize; 578 579 memset(&sym, 0, sizeof(sym)); 580 if (!kernel) { 581 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 582 elf_section_by_name(elf, &ehdr, &shdr, 583 ".gnu.prelink_undo", 584 NULL) != NULL); 585 } else self->adjust_symbols = 0; 586 587 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 588 struct symbol *f; 589 const char *elf_name; 590 char *demangled; 591 u64 obj_start; 592 struct section *section = NULL; 593 int is_label = elf_sym__is_label(&sym); 594 const char *section_name; 595 596 if (!is_label && !elf_sym__is_function(&sym)) 597 continue; 598 599 sec = elf_getscn(elf, sym.st_shndx); 600 if (!sec) 601 goto out_elf_end; 602 603 gelf_getshdr(sec, &shdr); 604 605 if (is_label && !elf_sec__is_text(&shdr, secstrs)) 606 continue; 607 608 section_name = elf_sec__name(&shdr, secstrs); 609 obj_start = sym.st_value; 610 611 if (self->adjust_symbols) { 612 if (v >= 2) 613 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", 614 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); 615 616 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 617 } 618 619 if (mod) { 620 section = mod->sections->find_section(mod->sections, section_name); 621 if (section) 622 sym.st_value += section->vma; 623 else { 624 fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n", 625 mod->name, section_name); 626 goto out_elf_end; 627 } 628 } 629 /* 630 * We need to figure out if the object was created from C++ sources 631 * DWARF DW_compile_unit has this, but we don't always have access 632 * to it... 633 */ 634 elf_name = elf_sym__name(&sym, symstrs); 635 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 636 if (demangled != NULL) 637 elf_name = demangled; 638 639 f = symbol__new(sym.st_value, sym.st_size, elf_name, 640 self->sym_priv_size, obj_start, v); 641 free(demangled); 642 if (!f) 643 goto out_elf_end; 644 645 if (filter && filter(self, f)) 646 symbol__delete(f, self->sym_priv_size); 647 else { 648 f->module = mod; 649 dso__insert_symbol(self, f); 650 nr++; 651 } 652 } 653 654 err = nr; 655 out_elf_end: 656 elf_end(elf); 657 out_close: 658 return err; 659 } 660 661 #define BUILD_ID_SIZE 128 662 663 static char *dso__read_build_id(struct dso *self, int v) 664 { 665 int i; 666 GElf_Ehdr ehdr; 667 GElf_Shdr shdr; 668 Elf_Data *build_id_data; 669 Elf_Scn *sec; 670 char *build_id = NULL, *bid; 671 unsigned char *raw; 672 Elf *elf; 673 int fd = open(self->name, O_RDONLY); 674 675 if (fd < 0) 676 goto out; 677 678 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 679 if (elf == NULL) { 680 if (v) 681 fprintf(stderr, "%s: cannot read %s ELF file.\n", 682 __func__, self->name); 683 goto out_close; 684 } 685 686 if (gelf_getehdr(elf, &ehdr) == NULL) { 687 if (v) 688 fprintf(stderr, "%s: cannot get elf header.\n", __func__); 689 goto out_elf_end; 690 } 691 692 sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL); 693 if (sec == NULL) 694 goto out_elf_end; 695 696 build_id_data = elf_getdata(sec, NULL); 697 if (build_id_data == NULL) 698 goto out_elf_end; 699 build_id = malloc(BUILD_ID_SIZE); 700 if (build_id == NULL) 701 goto out_elf_end; 702 raw = build_id_data->d_buf + 16; 703 bid = build_id; 704 705 for (i = 0; i < 20; ++i) { 706 sprintf(bid, "%02x", *raw); 707 ++raw; 708 bid += 2; 709 } 710 if (v >= 2) 711 printf("%s(%s): %s\n", __func__, self->name, build_id); 712 out_elf_end: 713 elf_end(elf); 714 out_close: 715 close(fd); 716 out: 717 return build_id; 718 } 719 720 char dso__symtab_origin(const struct dso *self) 721 { 722 static const char origin[] = { 723 [DSO__ORIG_KERNEL] = 'k', 724 [DSO__ORIG_JAVA_JIT] = 'j', 725 [DSO__ORIG_FEDORA] = 'f', 726 [DSO__ORIG_UBUNTU] = 'u', 727 [DSO__ORIG_BUILDID] = 'b', 728 [DSO__ORIG_DSO] = 'd', 729 }; 730 731 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 732 return '!'; 733 return origin[self->origin]; 734 } 735 736 int dso__load(struct dso *self, symbol_filter_t filter, int v) 737 { 738 int size = PATH_MAX; 739 char *name = malloc(size), *build_id = NULL; 740 int ret = -1; 741 int fd; 742 743 if (!name) 744 return -1; 745 746 self->adjust_symbols = 0; 747 748 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 749 ret = dso__load_perf_map(self, filter, v); 750 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 751 DSO__ORIG_NOT_FOUND; 752 return ret; 753 } 754 755 self->origin = DSO__ORIG_FEDORA - 1; 756 757 more: 758 do { 759 self->origin++; 760 switch (self->origin) { 761 case DSO__ORIG_FEDORA: 762 snprintf(name, size, "/usr/lib/debug%s.debug", self->name); 763 break; 764 case DSO__ORIG_UBUNTU: 765 snprintf(name, size, "/usr/lib/debug%s", self->name); 766 break; 767 case DSO__ORIG_BUILDID: 768 build_id = dso__read_build_id(self, v); 769 if (build_id != NULL) { 770 snprintf(name, size, 771 "/usr/lib/debug/.build-id/%.2s/%s.debug", 772 build_id, build_id + 2); 773 free(build_id); 774 break; 775 } 776 self->origin++; 777 /* Fall thru */ 778 case DSO__ORIG_DSO: 779 snprintf(name, size, "%s", self->name); 780 break; 781 782 default: 783 goto out; 784 } 785 786 fd = open(name, O_RDONLY); 787 } while (fd < 0); 788 789 ret = dso__load_sym(self, fd, name, filter, v, NULL); 790 close(fd); 791 792 /* 793 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!? 794 */ 795 if (!ret) 796 goto more; 797 798 if (ret > 0) { 799 int nr_plt = dso__synthesize_plt_symbols(self, v); 800 if (nr_plt > 0) 801 ret += nr_plt; 802 } 803 out: 804 free(name); 805 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 806 return 0; 807 return ret; 808 } 809 810 static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name, 811 symbol_filter_t filter, int v) 812 { 813 struct module *mod = mod_dso__find_module(mods, name); 814 int err = 0, fd; 815 816 if (mod == NULL || !mod->active) 817 return err; 818 819 fd = open(mod->path, O_RDONLY); 820 821 if (fd < 0) 822 return err; 823 824 err = dso__load_sym(self, fd, name, filter, v, mod); 825 close(fd); 826 827 return err; 828 } 829 830 int dso__load_modules(struct dso *self, symbol_filter_t filter, int v) 831 { 832 struct mod_dso *mods = mod_dso__new_dso("modules"); 833 struct module *pos; 834 struct rb_node *next; 835 int err, count = 0; 836 837 err = mod_dso__load_modules(mods); 838 839 if (err <= 0) 840 return err; 841 842 /* 843 * Iterate over modules, and load active symbols. 844 */ 845 next = rb_first(&mods->mods); 846 while (next) { 847 pos = rb_entry(next, struct module, rb_node); 848 err = dso__load_module(self, mods, pos->name, filter, v); 849 850 if (err < 0) 851 break; 852 853 next = rb_next(&pos->rb_node); 854 count += err; 855 } 856 857 if (err < 0) { 858 mod_dso__delete_modules(mods); 859 mod_dso__delete_self(mods); 860 return err; 861 } 862 863 return count; 864 } 865 866 static inline void dso__fill_symbol_holes(struct dso *self) 867 { 868 struct symbol *prev = NULL; 869 struct rb_node *nd; 870 871 for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) { 872 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 873 874 if (prev) { 875 u64 hole = 0; 876 int alias = pos->start == prev->start; 877 878 if (!alias) 879 hole = prev->start - pos->end - 1; 880 881 if (hole || alias) { 882 if (alias) 883 pos->end = prev->end; 884 else if (hole) 885 pos->end = prev->start - 1; 886 } 887 } 888 prev = pos; 889 } 890 } 891 892 static int dso__load_vmlinux(struct dso *self, const char *vmlinux, 893 symbol_filter_t filter, int v) 894 { 895 int err, fd = open(vmlinux, O_RDONLY); 896 897 if (fd < 0) 898 return -1; 899 900 err = dso__load_sym(self, fd, vmlinux, filter, v, NULL); 901 902 if (err > 0) 903 dso__fill_symbol_holes(self); 904 905 close(fd); 906 907 return err; 908 } 909 910 int dso__load_kernel(struct dso *self, const char *vmlinux, 911 symbol_filter_t filter, int v, int use_modules) 912 { 913 int err = -1; 914 915 if (vmlinux) { 916 err = dso__load_vmlinux(self, vmlinux, filter, v); 917 if (err > 0 && use_modules) { 918 int syms = dso__load_modules(self, filter, v); 919 920 if (syms < 0) { 921 fprintf(stderr, "dso__load_modules failed!\n"); 922 return syms; 923 } 924 err += syms; 925 } 926 } 927 928 if (err <= 0) 929 err = dso__load_kallsyms(self, filter, v); 930 931 if (err > 0) 932 self->origin = DSO__ORIG_KERNEL; 933 934 return err; 935 } 936 937 LIST_HEAD(dsos); 938 struct dso *kernel_dso; 939 struct dso *vdso; 940 struct dso *hypervisor_dso; 941 942 const char *vmlinux_name = "vmlinux"; 943 int modules; 944 945 static void dsos__add(struct dso *dso) 946 { 947 list_add_tail(&dso->node, &dsos); 948 } 949 950 static struct dso *dsos__find(const char *name) 951 { 952 struct dso *pos; 953 954 list_for_each_entry(pos, &dsos, node) 955 if (strcmp(pos->name, name) == 0) 956 return pos; 957 return NULL; 958 } 959 960 struct dso *dsos__findnew(const char *name) 961 { 962 struct dso *dso = dsos__find(name); 963 int nr; 964 965 if (dso) 966 return dso; 967 968 dso = dso__new(name, 0); 969 if (!dso) 970 goto out_delete_dso; 971 972 nr = dso__load(dso, NULL, verbose); 973 if (nr < 0) { 974 eprintf("Failed to open: %s\n", name); 975 goto out_delete_dso; 976 } 977 if (!nr) 978 eprintf("No symbols found in: %s, maybe install a debug package?\n", name); 979 980 dsos__add(dso); 981 982 return dso; 983 984 out_delete_dso: 985 dso__delete(dso); 986 return NULL; 987 } 988 989 void dsos__fprintf(FILE *fp) 990 { 991 struct dso *pos; 992 993 list_for_each_entry(pos, &dsos, node) 994 dso__fprintf(pos, fp); 995 } 996 997 static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) 998 { 999 return dso__find_symbol(dso, ip); 1000 } 1001 1002 int load_kernel(void) 1003 { 1004 int err; 1005 1006 kernel_dso = dso__new("[kernel]", 0); 1007 if (!kernel_dso) 1008 return -1; 1009 1010 err = dso__load_kernel(kernel_dso, vmlinux_name, NULL, verbose, modules); 1011 if (err <= 0) { 1012 dso__delete(kernel_dso); 1013 kernel_dso = NULL; 1014 } else 1015 dsos__add(kernel_dso); 1016 1017 vdso = dso__new("[vdso]", 0); 1018 if (!vdso) 1019 return -1; 1020 1021 vdso->find_symbol = vdso__find_symbol; 1022 1023 dsos__add(vdso); 1024 1025 hypervisor_dso = dso__new("[hypervisor]", 0); 1026 if (!hypervisor_dso) 1027 return -1; 1028 dsos__add(hypervisor_dso); 1029 1030 return err; 1031 } 1032 1033 1034 void symbol__init(void) 1035 { 1036 elf_version(EV_CURRENT); 1037 } 1038