symbol.c (9974f496782b7612e36a143bedda858f1cb953d4) symbol.c (6cfcc53ed4f3ecb9319e73a03f34f1eddcb644dd)
1#include "util.h"
2#include "../perf.h"
3#include "string.h"
4#include "symbol.h"
5
6#include <libelf.h>
7#include <gelf.h>
8#include <elf.h>

--- 21 unchanged lines hidden (view full) ---

30 if (sym_hist_filter && !strcmp(name, sym_hist_filter))
31 self->hist = calloc(sizeof(u64), len);
32
33 if (priv_size) {
34 memset(self, 0, priv_size);
35 self = ((void *)self) + priv_size;
36 }
37 self->start = start;
1#include "util.h"
2#include "../perf.h"
3#include "string.h"
4#include "symbol.h"
5
6#include <libelf.h>
7#include <gelf.h>
8#include <elf.h>

--- 21 unchanged lines hidden (view full) ---

30 if (sym_hist_filter && !strcmp(name, sym_hist_filter))
31 self->hist = calloc(sizeof(u64), len);
32
33 if (priv_size) {
34 memset(self, 0, priv_size);
35 self = ((void *)self) + priv_size;
36 }
37 self->start = start;
38 self->end = start + len - 1;
38 self->end = len ? start + len - 1 : start;
39 memcpy(self->name, name, namelen);
40
41 return self;
42}
43
44static void symbol__delete(struct symbol *self, unsigned int priv_size)
45{
46 free(((void *)self) - priv_size);
47}
48
49static size_t symbol__fprintf(struct symbol *self, FILE *fp)
50{
39 memcpy(self->name, name, namelen);
40
41 return self;
42}
43
44static void symbol__delete(struct symbol *self, unsigned int priv_size)
45{
46 free(((void *)self) - priv_size);
47}
48
49static size_t symbol__fprintf(struct symbol *self, FILE *fp)
50{
51 return fprintf(fp, " %llx-%llx %s\n",
51 if (!self->module)
52 return fprintf(fp, " %llx-%llx %s\n",
52 self->start, self->end, self->name);
53 self->start, self->end, self->name);
54 else
55 return fprintf(fp, " %llx-%llx %s \t[%s]\n",
56 self->start, self->end, self->name, self->module->name);
53}
54
55struct dso *dso__new(const char *name, unsigned int sym_priv_size)
56{
57 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
58
59 if (self != NULL) {
60 strcpy(self->name, name);

--- 244 unchanged lines hidden (view full) ---

305static inline int elf_sym__is_function(const GElf_Sym *sym)
306{
307 return elf_sym__type(sym) == STT_FUNC &&
308 sym->st_name != 0 &&
309 sym->st_shndx != SHN_UNDEF &&
310 sym->st_size != 0;
311}
312
57}
58
59struct dso *dso__new(const char *name, unsigned int sym_priv_size)
60{
61 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
62
63 if (self != NULL) {
64 strcpy(self->name, name);

--- 244 unchanged lines hidden (view full) ---

309static inline int elf_sym__is_function(const GElf_Sym *sym)
310{
311 return elf_sym__type(sym) == STT_FUNC &&
312 sym->st_name != 0 &&
313 sym->st_shndx != SHN_UNDEF &&
314 sym->st_size != 0;
315}
316
317static inline int elf_sym__is_label(const GElf_Sym *sym)
318{
319 return elf_sym__type(sym) == STT_NOTYPE &&
320 sym->st_name != 0 &&
321 sym->st_shndx != SHN_UNDEF &&
322 sym->st_shndx != SHN_ABS;
323}
324
325static inline const char *elf_sec__name(const GElf_Shdr *shdr,
326 const Elf_Data *secstrs)
327{
328 return secstrs->d_buf + shdr->sh_name;
329}
330
331static inline int elf_sec__is_text(const GElf_Shdr *shdr,
332 const Elf_Data *secstrs)
333{
334 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
335}
336
313static inline const char *elf_sym__name(const GElf_Sym *sym,
314 const Elf_Data *symstrs)
315{
316 return symstrs->d_buf + sym->st_name;
317}
318
319static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
320 GElf_Shdr *shp, const char *name,

--- 125 unchanged lines hidden (view full) ---

446 * I have to investigate, but probably should be ignored.
447 */
448 }
449
450 return nr;
451}
452
453static int dso__load_sym(struct dso *self, int fd, const char *name,
337static inline const char *elf_sym__name(const GElf_Sym *sym,
338 const Elf_Data *symstrs)
339{
340 return symstrs->d_buf + sym->st_name;
341}
342
343static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
344 GElf_Shdr *shp, const char *name,

--- 125 unchanged lines hidden (view full) ---

470 * I have to investigate, but probably should be ignored.
471 */
472 }
473
474 return nr;
475}
476
477static int dso__load_sym(struct dso *self, int fd, const char *name,
454 symbol_filter_t filter, int verbose)
478 symbol_filter_t filter, int verbose, struct module *mod)
455{
479{
456 Elf_Data *symstrs;
480 Elf_Data *symstrs, *secstrs;
457 uint32_t nr_syms;
458 int err = -1;
459 uint32_t index;
460 GElf_Ehdr ehdr;
461 GElf_Shdr shdr;
462 Elf_Data *syms;
463 GElf_Sym sym;
481 uint32_t nr_syms;
482 int err = -1;
483 uint32_t index;
484 GElf_Ehdr ehdr;
485 GElf_Shdr shdr;
486 Elf_Data *syms;
487 GElf_Sym sym;
464 Elf_Scn *sec, *sec_dynsym;
488 Elf_Scn *sec, *sec_dynsym, *sec_strndx;
465 Elf *elf;
466 size_t dynsym_idx;
467 int nr = 0;
468
469 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
470 if (elf == NULL) {
471 if (verbose)
472 fprintf(stderr, "%s: cannot read %s ELF file.\n",

--- 42 unchanged lines hidden (view full) ---

515 sec = elf_getscn(elf, shdr.sh_link);
516 if (sec == NULL)
517 goto out_elf_end;
518
519 symstrs = elf_getdata(sec, NULL);
520 if (symstrs == NULL)
521 goto out_elf_end;
522
489 Elf *elf;
490 size_t dynsym_idx;
491 int nr = 0;
492
493 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
494 if (elf == NULL) {
495 if (verbose)
496 fprintf(stderr, "%s: cannot read %s ELF file.\n",

--- 42 unchanged lines hidden (view full) ---

539 sec = elf_getscn(elf, shdr.sh_link);
540 if (sec == NULL)
541 goto out_elf_end;
542
543 symstrs = elf_getdata(sec, NULL);
544 if (symstrs == NULL)
545 goto out_elf_end;
546
547 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
548 if (sec_strndx == NULL)
549 goto out_elf_end;
550
551 secstrs = elf_getdata(sec_strndx, NULL);
552 if (symstrs == NULL)
553 goto out_elf_end;
554
523 nr_syms = shdr.sh_size / shdr.sh_entsize;
524
525 memset(&sym, 0, sizeof(sym));
526 self->prelinked = elf_section_by_name(elf, &ehdr, &shdr,
527 ".gnu.prelink_undo",
528 NULL) != NULL;
529 elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
530 struct symbol *f;
531 u64 obj_start;
555 nr_syms = shdr.sh_size / shdr.sh_entsize;
556
557 memset(&sym, 0, sizeof(sym));
558 self->prelinked = elf_section_by_name(elf, &ehdr, &shdr,
559 ".gnu.prelink_undo",
560 NULL) != NULL;
561 elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
562 struct symbol *f;
563 u64 obj_start;
564 struct section *section = NULL;
565 int is_label = elf_sym__is_label(&sym);
566 const char *section_name;
532
567
533 if (!elf_sym__is_function(&sym))
568 if (!is_label && !elf_sym__is_function(&sym))
534 continue;
535
536 sec = elf_getscn(elf, sym.st_shndx);
537 if (!sec)
538 goto out_elf_end;
539
540 gelf_getshdr(sec, &shdr);
569 continue;
570
571 sec = elf_getscn(elf, sym.st_shndx);
572 if (!sec)
573 goto out_elf_end;
574
575 gelf_getshdr(sec, &shdr);
576
577 if (is_label && !elf_sec__is_text(&shdr, secstrs))
578 continue;
579
580 section_name = elf_sec__name(&shdr, secstrs);
541 obj_start = sym.st_value;
542
543 if (self->prelinked) {
544 if (verbose >= 2)
545 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
546 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
547
548 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
549 }
550
581 obj_start = sym.st_value;
582
583 if (self->prelinked) {
584 if (verbose >= 2)
585 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
586 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
587
588 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
589 }
590
591 if (mod) {
592 section = mod->sections->find_section(mod->sections, section_name);
593 if (section)
594 sym.st_value += section->vma;
595 else {
596 fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n",
597 mod->name, section_name);
598 goto out_elf_end;
599 }
600 }
601
551 f = symbol__new(sym.st_value, sym.st_size,
552 elf_sym__name(&sym, symstrs),
553 self->sym_priv_size, obj_start, verbose);
554 if (!f)
555 goto out_elf_end;
556
557 if (filter && filter(self, f))
558 symbol__delete(f, self->sym_priv_size);
559 else {
602 f = symbol__new(sym.st_value, sym.st_size,
603 elf_sym__name(&sym, symstrs),
604 self->sym_priv_size, obj_start, verbose);
605 if (!f)
606 goto out_elf_end;
607
608 if (filter && filter(self, f))
609 symbol__delete(f, self->sym_priv_size);
610 else {
611 f->module = mod;
560 dso__insert_symbol(self, f);
561 nr++;
562 }
563 }
564
565 err = nr;
566out_elf_end:
567 elf_end(elf);

--- 33 unchanged lines hidden (view full) ---

601 default:
602 goto out;
603 }
604 variant++;
605
606 fd = open(name, O_RDONLY);
607 } while (fd < 0);
608
612 dso__insert_symbol(self, f);
613 nr++;
614 }
615 }
616
617 err = nr;
618out_elf_end:
619 elf_end(elf);

--- 33 unchanged lines hidden (view full) ---

653 default:
654 goto out;
655 }
656 variant++;
657
658 fd = open(name, O_RDONLY);
659 } while (fd < 0);
660
609 ret = dso__load_sym(self, fd, name, filter, verbose);
661 ret = dso__load_sym(self, fd, name, filter, verbose, NULL);
610 close(fd);
611
612 /*
613 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
614 */
615 if (!ret)
616 goto more;
617
618out:
619 free(name);
620 return ret;
621}
622
662 close(fd);
663
664 /*
665 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
666 */
667 if (!ret)
668 goto more;
669
670out:
671 free(name);
672 return ret;
673}
674
675static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name,
676 symbol_filter_t filter, int verbose)
677{
678 struct module *mod = mod_dso__find_module(mods, name);
679 int err = 0, fd;
680
681 if (mod == NULL || !mod->active)
682 return err;
683
684 fd = open(mod->path, O_RDONLY);
685
686 if (fd < 0)
687 return err;
688
689 err = dso__load_sym(self, fd, name, filter, verbose, mod);
690 close(fd);
691
692 return err;
693}
694
695int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose)
696{
697 struct mod_dso *mods = mod_dso__new_dso("modules");
698 struct module *pos;
699 struct rb_node *next;
700 int err;
701
702 err = mod_dso__load_modules(mods);
703
704 if (err <= 0)
705 return err;
706
707 /*
708 * Iterate over modules, and load active symbols.
709 */
710 next = rb_first(&mods->mods);
711 while (next) {
712 pos = rb_entry(next, struct module, rb_node);
713 err = dso__load_module(self, mods, pos->name, filter, verbose);
714
715 if (err < 0)
716 break;
717
718 next = rb_next(&pos->rb_node);
719 }
720
721 if (err < 0) {
722 mod_dso__delete_modules(mods);
723 mod_dso__delete_self(mods);
724 }
725
726 return err;
727}
728
729static inline void dso__fill_symbol_holes(struct dso *self)
730{
731 struct symbol *prev = NULL;
732 struct rb_node *nd;
733
734 for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) {
735 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
736
737 if (prev) {
738 u64 hole = 0;
739 int alias = pos->start == prev->start;
740
741 if (!alias)
742 hole = prev->start - pos->end - 1;
743
744 if (hole || alias) {
745 if (alias)
746 pos->end = prev->end;
747 else if (hole)
748 pos->end = prev->start - 1;
749 }
750 }
751 prev = pos;
752 }
753}
754
623static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
624 symbol_filter_t filter, int verbose)
625{
626 int err, fd = open(vmlinux, O_RDONLY);
627
628 if (fd < 0)
629 return -1;
630
755static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
756 symbol_filter_t filter, int verbose)
757{
758 int err, fd = open(vmlinux, O_RDONLY);
759
760 if (fd < 0)
761 return -1;
762
631 err = dso__load_sym(self, fd, vmlinux, filter, verbose);
763 err = dso__load_sym(self, fd, vmlinux, filter, verbose, NULL);
764
765 if (err > 0)
766 dso__fill_symbol_holes(self);
767
632 close(fd);
633
634 return err;
635}
636
637int dso__load_kernel(struct dso *self, const char *vmlinux,
768 close(fd);
769
770 return err;
771}
772
773int dso__load_kernel(struct dso *self, const char *vmlinux,
638 symbol_filter_t filter, int verbose)
774 symbol_filter_t filter, int verbose, int modules)
639{
640 int err = -1;
641
775{
776 int err = -1;
777
642 if (vmlinux)
778 if (vmlinux) {
643 err = dso__load_vmlinux(self, vmlinux, filter, verbose);
779 err = dso__load_vmlinux(self, vmlinux, filter, verbose);
780 if (err > 0 && modules)
781 err = dso__load_modules(self, filter, verbose);
782 }
644
645 if (err <= 0)
646 err = dso__load_kallsyms(self, filter, verbose);
647
648 return err;
649}
650
651void symbol__init(void)
652{
653 elf_version(EV_CURRENT);
654}
783
784 if (err <= 0)
785 err = dso__load_kallsyms(self, filter, verbose);
786
787 return err;
788}
789
790void symbol__init(void)
791{
792 elf_version(EV_CURRENT);
793}