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 sym->st_size != 0; 329 } 330 331 static inline int elf_sym__is_label(const GElf_Sym *sym) 332 { 333 return elf_sym__type(sym) == STT_NOTYPE && 334 sym->st_name != 0 && 335 sym->st_shndx != SHN_UNDEF && 336 sym->st_shndx != SHN_ABS; 337 } 338 339 static inline const char *elf_sec__name(const GElf_Shdr *shdr, 340 const Elf_Data *secstrs) 341 { 342 return secstrs->d_buf + shdr->sh_name; 343 } 344 345 static inline int elf_sec__is_text(const GElf_Shdr *shdr, 346 const Elf_Data *secstrs) 347 { 348 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; 349 } 350 351 static inline const char *elf_sym__name(const GElf_Sym *sym, 352 const Elf_Data *symstrs) 353 { 354 return symstrs->d_buf + sym->st_name; 355 } 356 357 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 358 GElf_Shdr *shp, const char *name, 359 size_t *idx) 360 { 361 Elf_Scn *sec = NULL; 362 size_t cnt = 1; 363 364 while ((sec = elf_nextscn(elf, sec)) != NULL) { 365 char *str; 366 367 gelf_getshdr(sec, shp); 368 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); 369 if (!strcmp(name, str)) { 370 if (idx) 371 *idx = cnt; 372 break; 373 } 374 ++cnt; 375 } 376 377 return sec; 378 } 379 380 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \ 381 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \ 382 idx < nr_entries; \ 383 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem)) 384 385 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \ 386 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \ 387 idx < nr_entries; \ 388 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem)) 389 390 /* 391 * We need to check if we have a .dynsym, so that we can handle the 392 * .plt, synthesizing its symbols, that aren't on the symtabs (be it 393 * .dynsym or .symtab). 394 * And always look at the original dso, not at debuginfo packages, that 395 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 396 */ 397 static int dso__synthesize_plt_symbols(struct dso *self, int v) 398 { 399 uint32_t nr_rel_entries, idx; 400 GElf_Sym sym; 401 u64 plt_offset; 402 GElf_Shdr shdr_plt; 403 struct symbol *f; 404 GElf_Shdr shdr_rel_plt, shdr_dynsym; 405 Elf_Data *reldata, *syms, *symstrs; 406 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym; 407 size_t dynsym_idx; 408 GElf_Ehdr ehdr; 409 char sympltname[1024]; 410 Elf *elf; 411 int nr = 0, symidx, fd, err = 0; 412 413 fd = open(self->name, O_RDONLY); 414 if (fd < 0) 415 goto out; 416 417 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 418 if (elf == NULL) 419 goto out_close; 420 421 if (gelf_getehdr(elf, &ehdr) == NULL) 422 goto out_elf_end; 423 424 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym, 425 ".dynsym", &dynsym_idx); 426 if (scn_dynsym == NULL) 427 goto out_elf_end; 428 429 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 430 ".rela.plt", NULL); 431 if (scn_plt_rel == NULL) { 432 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 433 ".rel.plt", NULL); 434 if (scn_plt_rel == NULL) 435 goto out_elf_end; 436 } 437 438 err = -1; 439 440 if (shdr_rel_plt.sh_link != dynsym_idx) 441 goto out_elf_end; 442 443 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL) 444 goto out_elf_end; 445 446 /* 447 * Fetch the relocation section to find the idxes to the GOT 448 * and the symbols in the .dynsym they refer to. 449 */ 450 reldata = elf_getdata(scn_plt_rel, NULL); 451 if (reldata == NULL) 452 goto out_elf_end; 453 454 syms = elf_getdata(scn_dynsym, NULL); 455 if (syms == NULL) 456 goto out_elf_end; 457 458 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link); 459 if (scn_symstrs == NULL) 460 goto out_elf_end; 461 462 symstrs = elf_getdata(scn_symstrs, NULL); 463 if (symstrs == NULL) 464 goto out_elf_end; 465 466 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; 467 plt_offset = shdr_plt.sh_offset; 468 469 if (shdr_rel_plt.sh_type == SHT_RELA) { 470 GElf_Rela pos_mem, *pos; 471 472 elf_section__for_each_rela(reldata, pos, pos_mem, idx, 473 nr_rel_entries) { 474 symidx = GELF_R_SYM(pos->r_info); 475 plt_offset += shdr_plt.sh_entsize; 476 gelf_getsym(syms, symidx, &sym); 477 snprintf(sympltname, sizeof(sympltname), 478 "%s@plt", elf_sym__name(&sym, symstrs)); 479 480 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 481 sympltname, self->sym_priv_size, 0, v); 482 if (!f) 483 goto out_elf_end; 484 485 dso__insert_symbol(self, f); 486 ++nr; 487 } 488 } else if (shdr_rel_plt.sh_type == SHT_REL) { 489 GElf_Rel pos_mem, *pos; 490 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 491 nr_rel_entries) { 492 symidx = GELF_R_SYM(pos->r_info); 493 plt_offset += shdr_plt.sh_entsize; 494 gelf_getsym(syms, symidx, &sym); 495 snprintf(sympltname, sizeof(sympltname), 496 "%s@plt", elf_sym__name(&sym, symstrs)); 497 498 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 499 sympltname, self->sym_priv_size, 0, v); 500 if (!f) 501 goto out_elf_end; 502 503 dso__insert_symbol(self, f); 504 ++nr; 505 } 506 } 507 508 err = 0; 509 out_elf_end: 510 elf_end(elf); 511 out_close: 512 close(fd); 513 514 if (err == 0) 515 return nr; 516 out: 517 fprintf(stderr, "%s: problems reading %s PLT info.\n", 518 __func__, self->name); 519 return 0; 520 } 521 522 static int dso__load_sym(struct dso *self, int fd, const char *name, 523 symbol_filter_t filter, int v, struct module *mod) 524 { 525 Elf_Data *symstrs, *secstrs; 526 uint32_t nr_syms; 527 int err = -1; 528 uint32_t idx; 529 GElf_Ehdr ehdr; 530 GElf_Shdr shdr; 531 Elf_Data *syms; 532 GElf_Sym sym; 533 Elf_Scn *sec, *sec_strndx; 534 Elf *elf; 535 int nr = 0, kernel = !strcmp("[kernel]", self->name); 536 537 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 538 if (elf == NULL) { 539 if (v) 540 fprintf(stderr, "%s: cannot read %s ELF file.\n", 541 __func__, name); 542 goto out_close; 543 } 544 545 if (gelf_getehdr(elf, &ehdr) == NULL) { 546 if (v) 547 fprintf(stderr, "%s: cannot get elf header.\n", __func__); 548 goto out_elf_end; 549 } 550 551 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL); 552 if (sec == NULL) { 553 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL); 554 if (sec == NULL) 555 goto out_elf_end; 556 } 557 558 syms = elf_getdata(sec, NULL); 559 if (syms == NULL) 560 goto out_elf_end; 561 562 sec = elf_getscn(elf, shdr.sh_link); 563 if (sec == NULL) 564 goto out_elf_end; 565 566 symstrs = elf_getdata(sec, NULL); 567 if (symstrs == NULL) 568 goto out_elf_end; 569 570 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); 571 if (sec_strndx == NULL) 572 goto out_elf_end; 573 574 secstrs = elf_getdata(sec_strndx, NULL); 575 if (secstrs == NULL) 576 goto out_elf_end; 577 578 nr_syms = shdr.sh_size / shdr.sh_entsize; 579 580 memset(&sym, 0, sizeof(sym)); 581 if (!kernel) { 582 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 583 elf_section_by_name(elf, &ehdr, &shdr, 584 ".gnu.prelink_undo", 585 NULL) != NULL); 586 } else self->adjust_symbols = 0; 587 588 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 589 struct symbol *f; 590 const char *elf_name; 591 char *demangled; 592 u64 obj_start; 593 struct section *section = NULL; 594 int is_label = elf_sym__is_label(&sym); 595 const char *section_name; 596 597 if (!is_label && !elf_sym__is_function(&sym)) 598 continue; 599 600 sec = elf_getscn(elf, sym.st_shndx); 601 if (!sec) 602 goto out_elf_end; 603 604 gelf_getshdr(sec, &shdr); 605 606 if (is_label && !elf_sec__is_text(&shdr, secstrs)) 607 continue; 608 609 section_name = elf_sec__name(&shdr, secstrs); 610 obj_start = sym.st_value; 611 612 if (self->adjust_symbols) { 613 if (v >= 2) 614 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", 615 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); 616 617 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 618 } 619 620 if (mod) { 621 section = mod->sections->find_section(mod->sections, section_name); 622 if (section) 623 sym.st_value += section->vma; 624 else { 625 fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n", 626 mod->name, section_name); 627 goto out_elf_end; 628 } 629 } 630 /* 631 * We need to figure out if the object was created from C++ sources 632 * DWARF DW_compile_unit has this, but we don't always have access 633 * to it... 634 */ 635 elf_name = elf_sym__name(&sym, symstrs); 636 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 637 if (demangled != NULL) 638 elf_name = demangled; 639 640 f = symbol__new(sym.st_value, sym.st_size, elf_name, 641 self->sym_priv_size, obj_start, v); 642 free(demangled); 643 if (!f) 644 goto out_elf_end; 645 646 if (filter && filter(self, f)) 647 symbol__delete(f, self->sym_priv_size); 648 else { 649 f->module = mod; 650 dso__insert_symbol(self, f); 651 nr++; 652 } 653 } 654 655 err = nr; 656 out_elf_end: 657 elf_end(elf); 658 out_close: 659 return err; 660 } 661 662 #define BUILD_ID_SIZE 128 663 664 static char *dso__read_build_id(struct dso *self, int v) 665 { 666 int i; 667 GElf_Ehdr ehdr; 668 GElf_Shdr shdr; 669 Elf_Data *build_id_data; 670 Elf_Scn *sec; 671 char *build_id = NULL, *bid; 672 unsigned char *raw; 673 Elf *elf; 674 int fd = open(self->name, O_RDONLY); 675 676 if (fd < 0) 677 goto out; 678 679 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 680 if (elf == NULL) { 681 if (v) 682 fprintf(stderr, "%s: cannot read %s ELF file.\n", 683 __func__, self->name); 684 goto out_close; 685 } 686 687 if (gelf_getehdr(elf, &ehdr) == NULL) { 688 if (v) 689 fprintf(stderr, "%s: cannot get elf header.\n", __func__); 690 goto out_elf_end; 691 } 692 693 sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL); 694 if (sec == NULL) 695 goto out_elf_end; 696 697 build_id_data = elf_getdata(sec, NULL); 698 if (build_id_data == NULL) 699 goto out_elf_end; 700 build_id = malloc(BUILD_ID_SIZE); 701 if (build_id == NULL) 702 goto out_elf_end; 703 raw = build_id_data->d_buf + 16; 704 bid = build_id; 705 706 for (i = 0; i < 20; ++i) { 707 sprintf(bid, "%02x", *raw); 708 ++raw; 709 bid += 2; 710 } 711 if (v >= 2) 712 printf("%s(%s): %s\n", __func__, self->name, build_id); 713 out_elf_end: 714 elf_end(elf); 715 out_close: 716 close(fd); 717 out: 718 return build_id; 719 } 720 721 char dso__symtab_origin(const struct dso *self) 722 { 723 static const char origin[] = { 724 [DSO__ORIG_KERNEL] = 'k', 725 [DSO__ORIG_JAVA_JIT] = 'j', 726 [DSO__ORIG_FEDORA] = 'f', 727 [DSO__ORIG_UBUNTU] = 'u', 728 [DSO__ORIG_BUILDID] = 'b', 729 [DSO__ORIG_DSO] = 'd', 730 }; 731 732 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 733 return '!'; 734 return origin[self->origin]; 735 } 736 737 int dso__load(struct dso *self, symbol_filter_t filter, int v) 738 { 739 int size = PATH_MAX; 740 char *name = malloc(size), *build_id = NULL; 741 int ret = -1; 742 int fd; 743 744 if (!name) 745 return -1; 746 747 self->adjust_symbols = 0; 748 749 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 750 ret = dso__load_perf_map(self, filter, v); 751 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 752 DSO__ORIG_NOT_FOUND; 753 return ret; 754 } 755 756 self->origin = DSO__ORIG_FEDORA - 1; 757 758 more: 759 do { 760 self->origin++; 761 switch (self->origin) { 762 case DSO__ORIG_FEDORA: 763 snprintf(name, size, "/usr/lib/debug%s.debug", self->name); 764 break; 765 case DSO__ORIG_UBUNTU: 766 snprintf(name, size, "/usr/lib/debug%s", self->name); 767 break; 768 case DSO__ORIG_BUILDID: 769 build_id = dso__read_build_id(self, v); 770 if (build_id != NULL) { 771 snprintf(name, size, 772 "/usr/lib/debug/.build-id/%.2s/%s.debug", 773 build_id, build_id + 2); 774 free(build_id); 775 break; 776 } 777 self->origin++; 778 /* Fall thru */ 779 case DSO__ORIG_DSO: 780 snprintf(name, size, "%s", self->name); 781 break; 782 783 default: 784 goto out; 785 } 786 787 fd = open(name, O_RDONLY); 788 } while (fd < 0); 789 790 ret = dso__load_sym(self, fd, name, filter, v, NULL); 791 close(fd); 792 793 /* 794 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!? 795 */ 796 if (!ret) 797 goto more; 798 799 if (ret > 0) { 800 int nr_plt = dso__synthesize_plt_symbols(self, v); 801 if (nr_plt > 0) 802 ret += nr_plt; 803 } 804 out: 805 free(name); 806 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 807 return 0; 808 return ret; 809 } 810 811 static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name, 812 symbol_filter_t filter, int v) 813 { 814 struct module *mod = mod_dso__find_module(mods, name); 815 int err = 0, fd; 816 817 if (mod == NULL || !mod->active) 818 return err; 819 820 fd = open(mod->path, O_RDONLY); 821 822 if (fd < 0) 823 return err; 824 825 err = dso__load_sym(self, fd, name, filter, v, mod); 826 close(fd); 827 828 return err; 829 } 830 831 int dso__load_modules(struct dso *self, symbol_filter_t filter, int v) 832 { 833 struct mod_dso *mods = mod_dso__new_dso("modules"); 834 struct module *pos; 835 struct rb_node *next; 836 int err, count = 0; 837 838 err = mod_dso__load_modules(mods); 839 840 if (err <= 0) 841 return err; 842 843 /* 844 * Iterate over modules, and load active symbols. 845 */ 846 next = rb_first(&mods->mods); 847 while (next) { 848 pos = rb_entry(next, struct module, rb_node); 849 err = dso__load_module(self, mods, pos->name, filter, v); 850 851 if (err < 0) 852 break; 853 854 next = rb_next(&pos->rb_node); 855 count += err; 856 } 857 858 if (err < 0) { 859 mod_dso__delete_modules(mods); 860 mod_dso__delete_self(mods); 861 return err; 862 } 863 864 return count; 865 } 866 867 static inline void dso__fill_symbol_holes(struct dso *self) 868 { 869 struct symbol *prev = NULL; 870 struct rb_node *nd; 871 872 for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) { 873 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 874 875 if (prev) { 876 u64 hole = 0; 877 int alias = pos->start == prev->start; 878 879 if (!alias) 880 hole = prev->start - pos->end - 1; 881 882 if (hole || alias) { 883 if (alias) 884 pos->end = prev->end; 885 else if (hole) 886 pos->end = prev->start - 1; 887 } 888 } 889 prev = pos; 890 } 891 } 892 893 static int dso__load_vmlinux(struct dso *self, const char *vmlinux, 894 symbol_filter_t filter, int v) 895 { 896 int err, fd = open(vmlinux, O_RDONLY); 897 898 if (fd < 0) 899 return -1; 900 901 err = dso__load_sym(self, fd, vmlinux, filter, v, NULL); 902 903 if (err > 0) 904 dso__fill_symbol_holes(self); 905 906 close(fd); 907 908 return err; 909 } 910 911 int dso__load_kernel(struct dso *self, const char *vmlinux, 912 symbol_filter_t filter, int v, int use_modules) 913 { 914 int err = -1; 915 916 if (vmlinux) { 917 err = dso__load_vmlinux(self, vmlinux, filter, v); 918 if (err > 0 && use_modules) { 919 int syms = dso__load_modules(self, filter, v); 920 921 if (syms < 0) { 922 fprintf(stderr, "dso__load_modules failed!\n"); 923 return syms; 924 } 925 err += syms; 926 } 927 } 928 929 if (err <= 0) 930 err = dso__load_kallsyms(self, filter, v); 931 932 if (err > 0) 933 self->origin = DSO__ORIG_KERNEL; 934 935 return err; 936 } 937 938 LIST_HEAD(dsos); 939 struct dso *kernel_dso; 940 struct dso *vdso; 941 struct dso *hypervisor_dso; 942 943 const char *vmlinux_name = "vmlinux"; 944 int modules; 945 946 static void dsos__add(struct dso *dso) 947 { 948 list_add_tail(&dso->node, &dsos); 949 } 950 951 static struct dso *dsos__find(const char *name) 952 { 953 struct dso *pos; 954 955 list_for_each_entry(pos, &dsos, node) 956 if (strcmp(pos->name, name) == 0) 957 return pos; 958 return NULL; 959 } 960 961 struct dso *dsos__findnew(const char *name) 962 { 963 struct dso *dso = dsos__find(name); 964 int nr; 965 966 if (dso) 967 return dso; 968 969 dso = dso__new(name, 0); 970 if (!dso) 971 goto out_delete_dso; 972 973 nr = dso__load(dso, NULL, verbose); 974 if (nr < 0) { 975 eprintf("Failed to open: %s\n", name); 976 goto out_delete_dso; 977 } 978 if (!nr) 979 eprintf("No symbols found in: %s, maybe install a debug package?\n", name); 980 981 dsos__add(dso); 982 983 return dso; 984 985 out_delete_dso: 986 dso__delete(dso); 987 return NULL; 988 } 989 990 void dsos__fprintf(FILE *fp) 991 { 992 struct dso *pos; 993 994 list_for_each_entry(pos, &dsos, node) 995 dso__fprintf(pos, fp); 996 } 997 998 static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) 999 { 1000 return dso__find_symbol(dso, ip); 1001 } 1002 1003 int load_kernel(void) 1004 { 1005 int err; 1006 1007 kernel_dso = dso__new("[kernel]", 0); 1008 if (!kernel_dso) 1009 return -1; 1010 1011 err = dso__load_kernel(kernel_dso, vmlinux_name, NULL, verbose, modules); 1012 if (err <= 0) { 1013 dso__delete(kernel_dso); 1014 kernel_dso = NULL; 1015 } else 1016 dsos__add(kernel_dso); 1017 1018 vdso = dso__new("[vdso]", 0); 1019 if (!vdso) 1020 return -1; 1021 1022 vdso->find_symbol = vdso__find_symbol; 1023 1024 dsos__add(vdso); 1025 1026 hypervisor_dso = dso__new("[hypervisor]", 0); 1027 if (!hypervisor_dso) 1028 return -1; 1029 dsos__add(hypervisor_dso); 1030 1031 return err; 1032 } 1033 1034 1035 void symbol__init(void) 1036 { 1037 elf_version(EV_CURRENT); 1038 } 1039