12 const char *sym_hist_filter
;
24 static struct symbol
*symbol__new(u64 start
, u64 len
,
25 const char *name
, unsigned int priv_size
,
28 size_t namelen
= strlen(name
) + 1;
29 struct symbol
*self
= calloc(1, priv_size
+ sizeof(*self
) + namelen
);
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
);
38 self
->obj_start
= obj_start
;
42 if (sym_hist_filter
&& !strcmp(name
, sym_hist_filter
))
43 self
->hist
= calloc(sizeof(u64
), len
);
46 memset(self
, 0, priv_size
);
47 self
= ((void *)self
) + priv_size
;
50 self
->end
= len
? start
+ len
- 1 : start
;
51 memcpy(self
->name
, name
, namelen
);
56 static void symbol__delete(struct symbol
*self
, unsigned int priv_size
)
58 free(((void *)self
) - priv_size
);
61 static size_t symbol__fprintf(struct symbol
*self
, FILE *fp
)
64 return fprintf(fp
, " %llx-%llx %s\n",
65 self
->start
, self
->end
, self
->name
);
67 return fprintf(fp
, " %llx-%llx %s \t[%s]\n",
68 self
->start
, self
->end
, self
->name
, self
->module
->name
);
71 struct dso
*dso__new(const char *name
, unsigned int sym_priv_size
)
73 struct dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
76 strcpy(self
->name
, name
);
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
;
87 static void dso__delete_symbols(struct dso
*self
)
90 struct rb_node
*next
= rb_first(&self
->syms
);
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
);
100 void dso__delete(struct dso
*self
)
102 dso__delete_symbols(self
);
106 static void dso__insert_symbol(struct dso
*self
, struct symbol
*sym
)
108 struct rb_node
**p
= &self
->syms
.rb_node
;
109 struct rb_node
*parent
= NULL
;
110 const u64 ip
= sym
->start
;
115 s
= rb_entry(parent
, struct symbol
, rb_node
);
121 rb_link_node(&sym
->rb_node
, parent
, p
);
122 rb_insert_color(&sym
->rb_node
, &self
->syms
);
125 struct symbol
*dso__find_symbol(struct dso
*self
, u64 ip
)
132 n
= self
->syms
.rb_node
;
135 struct symbol
*s
= rb_entry(n
, struct symbol
, rb_node
);
139 else if (ip
> s
->end
)
148 size_t dso__fprintf(struct dso
*self
, FILE *fp
)
150 size_t ret
= fprintf(fp
, "dso: %s\n", self
->name
);
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
);
161 static int dso__load_kallsyms(struct dso
*self
, symbol_filter_t filter
, int v
)
163 struct rb_node
*nd
, *prevnd
;
166 FILE *file
= fopen("/proc/kallsyms", "r");
172 while (!feof(file
)) {
178 line_len
= getline(&line
, &n
, file
);
185 line
[--line_len
] = '\0'; /* \n */
187 len
= hex2u64(line
, &start
);
190 if (len
+ 2 >= line_len
)
193 symbol_type
= toupper(line
[len
]);
195 * We're interested only in code ('T'ext)
197 if (symbol_type
!= 'T' && symbol_type
!= 'W')
200 * Well fix up the end later, when we have all sorted.
202 sym
= symbol__new(start
, 0xdead, line
+ len
+ 2,
203 self
->sym_priv_size
, 0, v
);
206 goto out_delete_line
;
208 if (filter
&& filter(self
, sym
))
209 symbol__delete(sym
, self
->sym_priv_size
);
211 dso__insert_symbol(self
, sym
);
217 * Now that we have all sorted out, just set the ->end of all
220 prevnd
= rb_first(&self
->syms
);
223 goto out_delete_line
;
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
);
229 prev
->end
= curr
->start
- 1;
244 static int dso__load_perf_map(struct dso
*self
, symbol_filter_t filter
, int v
)
251 file
= fopen(self
->name
, "r");
255 while (!feof(file
)) {
260 line_len
= getline(&line
, &n
, file
);
267 line
[--line_len
] = '\0'; /* \n */
269 len
= hex2u64(line
, &start
);
272 if (len
+ 2 >= line_len
)
275 len
+= hex2u64(line
+ len
, &size
);
278 if (len
+ 2 >= line_len
)
281 sym
= symbol__new(start
, size
, line
+ len
,
282 self
->sym_priv_size
, start
, v
);
285 goto out_delete_line
;
287 if (filter
&& filter(self
, sym
))
288 symbol__delete(sym
, self
->sym_priv_size
);
290 dso__insert_symbol(self
, sym
);
307 * elf_symtab__for_each_symbol - iterate thru all the symbols
309 * @self: struct elf_symtab instance to iterate
311 * @sym: GElf_Sym iterator
313 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
314 for (idx = 0, gelf_getsym(syms, idx, &sym);\
316 idx++, gelf_getsym(syms, idx, &sym))
318 static inline uint8_t elf_sym__type(const GElf_Sym
*sym
)
320 return GELF_ST_TYPE(sym
->st_info
);
323 static inline int elf_sym__is_function(const GElf_Sym
*sym
)
325 return elf_sym__type(sym
) == STT_FUNC
&&
327 sym
->st_shndx
!= SHN_UNDEF
;
330 static inline int elf_sym__is_label(const GElf_Sym
*sym
)
332 return elf_sym__type(sym
) == STT_NOTYPE
&&
334 sym
->st_shndx
!= SHN_UNDEF
&&
335 sym
->st_shndx
!= SHN_ABS
;
338 static inline const char *elf_sec__name(const GElf_Shdr
*shdr
,
339 const Elf_Data
*secstrs
)
341 return secstrs
->d_buf
+ shdr
->sh_name
;
344 static inline int elf_sec__is_text(const GElf_Shdr
*shdr
,
345 const Elf_Data
*secstrs
)
347 return strstr(elf_sec__name(shdr
, secstrs
), "text") != NULL
;
350 static inline const char *elf_sym__name(const GElf_Sym
*sym
,
351 const Elf_Data
*symstrs
)
353 return symstrs
->d_buf
+ sym
->st_name
;
356 static Elf_Scn
*elf_section_by_name(Elf
*elf
, GElf_Ehdr
*ep
,
357 GElf_Shdr
*shp
, const char *name
,
363 while ((sec
= elf_nextscn(elf
, sec
)) != NULL
) {
366 gelf_getshdr(sec
, shp
);
367 str
= elf_strptr(elf
, ep
->e_shstrndx
, shp
->sh_name
);
368 if (!strcmp(name
, str
)) {
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); \
382 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
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); \
387 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
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).
396 static int dso__synthesize_plt_symbols(struct dso
*self
, int v
)
398 uint32_t nr_rel_entries
, idx
;
403 GElf_Shdr shdr_rel_plt
, shdr_dynsym
;
404 Elf_Data
*reldata
, *syms
, *symstrs
;
405 Elf_Scn
*scn_plt_rel
, *scn_symstrs
, *scn_dynsym
;
408 char sympltname
[1024];
410 int nr
= 0, symidx
, fd
, err
= 0;
412 fd
= open(self
->name
, O_RDONLY
);
416 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
420 if (gelf_getehdr(elf
, &ehdr
) == NULL
)
423 scn_dynsym
= elf_section_by_name(elf
, &ehdr
, &shdr_dynsym
,
424 ".dynsym", &dynsym_idx
);
425 if (scn_dynsym
== NULL
)
428 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
430 if (scn_plt_rel
== NULL
) {
431 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
433 if (scn_plt_rel
== NULL
)
439 if (shdr_rel_plt
.sh_link
!= dynsym_idx
)
442 if (elf_section_by_name(elf
, &ehdr
, &shdr_plt
, ".plt", NULL
) == NULL
)
446 * Fetch the relocation section to find the idxes to the GOT
447 * and the symbols in the .dynsym they refer to.
449 reldata
= elf_getdata(scn_plt_rel
, NULL
);
453 syms
= elf_getdata(scn_dynsym
, NULL
);
457 scn_symstrs
= elf_getscn(elf
, shdr_dynsym
.sh_link
);
458 if (scn_symstrs
== NULL
)
461 symstrs
= elf_getdata(scn_symstrs
, NULL
);
465 nr_rel_entries
= shdr_rel_plt
.sh_size
/ shdr_rel_plt
.sh_entsize
;
466 plt_offset
= shdr_plt
.sh_offset
;
468 if (shdr_rel_plt
.sh_type
== SHT_RELA
) {
469 GElf_Rela pos_mem
, *pos
;
471 elf_section__for_each_rela(reldata
, pos
, pos_mem
, idx
,
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
));
479 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
480 sympltname
, self
->sym_priv_size
, 0, v
);
484 dso__insert_symbol(self
, f
);
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
,
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
));
497 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
498 sympltname
, self
->sym_priv_size
, 0, v
);
502 dso__insert_symbol(self
, f
);
516 fprintf(stderr
, "%s: problems reading %s PLT info.\n",
517 __func__
, self
->name
);
521 static int dso__load_sym(struct dso
*self
, int fd
, const char *name
,
522 symbol_filter_t filter
, int v
, struct module
*mod
)
524 Elf_Data
*symstrs
, *secstrs
;
532 Elf_Scn
*sec
, *sec_strndx
;
534 int nr
= 0, kernel
= !strcmp("[kernel]", self
->name
);
536 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
539 fprintf(stderr
, "%s: cannot read %s ELF file.\n",
544 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
546 fprintf(stderr
, "%s: cannot get elf header.\n", __func__
);
550 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".symtab", NULL
);
552 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".dynsym", NULL
);
557 syms
= elf_getdata(sec
, NULL
);
561 sec
= elf_getscn(elf
, shdr
.sh_link
);
565 symstrs
= elf_getdata(sec
, NULL
);
569 sec_strndx
= elf_getscn(elf
, ehdr
.e_shstrndx
);
570 if (sec_strndx
== NULL
)
573 secstrs
= elf_getdata(sec_strndx
, NULL
);
577 nr_syms
= shdr
.sh_size
/ shdr
.sh_entsize
;
579 memset(&sym
, 0, sizeof(sym
));
581 self
->adjust_symbols
= (ehdr
.e_type
== ET_EXEC
||
582 elf_section_by_name(elf
, &ehdr
, &shdr
,
585 } else self
->adjust_symbols
= 0;
587 elf_symtab__for_each_symbol(syms
, nr_syms
, idx
, sym
) {
589 const char *elf_name
;
592 struct section
*section
= NULL
;
593 int is_label
= elf_sym__is_label(&sym
);
594 const char *section_name
;
596 if (!is_label
&& !elf_sym__is_function(&sym
))
599 sec
= elf_getscn(elf
, sym
.st_shndx
);
603 gelf_getshdr(sec
, &shdr
);
605 if (is_label
&& !elf_sec__is_text(&shdr
, secstrs
))
608 section_name
= elf_sec__name(&shdr
, secstrs
);
609 obj_start
= sym
.st_value
;
611 if (self
->adjust_symbols
) {
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
);
616 sym
.st_value
-= shdr
.sh_addr
- shdr
.sh_offset
;
620 section
= mod
->sections
->find_section(mod
->sections
, section_name
);
622 sym
.st_value
+= section
->vma
;
624 fprintf(stderr
, "dso__load_sym() module %s lookup of %s failed\n",
625 mod
->name
, section_name
);
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
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
;
639 f
= symbol__new(sym
.st_value
, sym
.st_size
, elf_name
,
640 self
->sym_priv_size
, obj_start
, v
);
645 if (filter
&& filter(self
, f
))
646 symbol__delete(f
, self
->sym_priv_size
);
649 dso__insert_symbol(self
, f
);
661 #define BUILD_ID_SIZE 128
663 static char *dso__read_build_id(struct dso
*self
, int v
)
668 Elf_Data
*build_id_data
;
670 char *build_id
= NULL
, *bid
;
673 int fd
= open(self
->name
, O_RDONLY
);
678 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
681 fprintf(stderr
, "%s: cannot read %s ELF file.\n",
682 __func__
, self
->name
);
686 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
688 fprintf(stderr
, "%s: cannot get elf header.\n", __func__
);
692 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".note.gnu.build-id", NULL
);
696 build_id_data
= elf_getdata(sec
, NULL
);
697 if (build_id_data
== NULL
)
699 build_id
= malloc(BUILD_ID_SIZE
);
700 if (build_id
== NULL
)
702 raw
= build_id_data
->d_buf
+ 16;
705 for (i
= 0; i
< 20; ++i
) {
706 sprintf(bid
, "%02x", *raw
);
711 printf("%s(%s): %s\n", __func__
, self
->name
, build_id
);
720 char dso__symtab_origin(const struct dso
*self
)
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',
731 if (self
== NULL
|| self
->origin
== DSO__ORIG_NOT_FOUND
)
733 return origin
[self
->origin
];
736 int dso__load(struct dso
*self
, symbol_filter_t filter
, int v
)
739 char *name
= malloc(size
), *build_id
= NULL
;
746 self
->adjust_symbols
= 0;
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
:
755 self
->origin
= DSO__ORIG_FEDORA
- 1;
760 switch (self
->origin
) {
761 case DSO__ORIG_FEDORA
:
762 snprintf(name
, size
, "/usr/lib/debug%s.debug", self
->name
);
764 case DSO__ORIG_UBUNTU
:
765 snprintf(name
, size
, "/usr/lib/debug%s", self
->name
);
767 case DSO__ORIG_BUILDID
:
768 build_id
= dso__read_build_id(self
, v
);
769 if (build_id
!= NULL
) {
771 "/usr/lib/debug/.build-id/%.2s/%s.debug",
772 build_id
, build_id
+ 2);
779 snprintf(name
, size
, "%s", self
->name
);
786 fd
= open(name
, O_RDONLY
);
789 ret
= dso__load_sym(self
, fd
, name
, filter
, v
, NULL
);
793 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
799 int nr_plt
= dso__synthesize_plt_symbols(self
, v
);
805 if (ret
< 0 && strstr(self
->name
, " (deleted)") != NULL
)
810 static int dso__load_module(struct dso
*self
, struct mod_dso
*mods
, const char *name
,
811 symbol_filter_t filter
, int v
)
813 struct module
*mod
= mod_dso__find_module(mods
, name
);
816 if (mod
== NULL
|| !mod
->active
)
819 fd
= open(mod
->path
, O_RDONLY
);
824 err
= dso__load_sym(self
, fd
, name
, filter
, v
, mod
);
830 int dso__load_modules(struct dso
*self
, symbol_filter_t filter
, int v
)
832 struct mod_dso
*mods
= mod_dso__new_dso("modules");
834 struct rb_node
*next
;
837 err
= mod_dso__load_modules(mods
);
843 * Iterate over modules, and load active symbols.
845 next
= rb_first(&mods
->mods
);
847 pos
= rb_entry(next
, struct module
, rb_node
);
848 err
= dso__load_module(self
, mods
, pos
->name
, filter
, v
);
853 next
= rb_next(&pos
->rb_node
);
858 mod_dso__delete_modules(mods
);
859 mod_dso__delete_self(mods
);
866 static inline void dso__fill_symbol_holes(struct dso
*self
)
868 struct symbol
*prev
= NULL
;
871 for (nd
= rb_last(&self
->syms
); nd
; nd
= rb_prev(nd
)) {
872 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
876 int alias
= pos
->start
== prev
->start
;
879 hole
= prev
->start
- pos
->end
- 1;
883 pos
->end
= prev
->end
;
885 pos
->end
= prev
->start
- 1;
892 static int dso__load_vmlinux(struct dso
*self
, const char *vmlinux
,
893 symbol_filter_t filter
, int v
)
895 int err
, fd
= open(vmlinux
, O_RDONLY
);
900 err
= dso__load_sym(self
, fd
, vmlinux
, filter
, v
, NULL
);
903 dso__fill_symbol_holes(self
);
910 int dso__load_kernel(struct dso
*self
, const char *vmlinux
,
911 symbol_filter_t filter
, int v
, int use_modules
)
916 err
= dso__load_vmlinux(self
, vmlinux
, filter
, v
);
917 if (err
> 0 && use_modules
) {
918 int syms
= dso__load_modules(self
, filter
, v
);
921 fprintf(stderr
, "dso__load_modules failed!\n");
929 err
= dso__load_kallsyms(self
, filter
, v
);
932 self
->origin
= DSO__ORIG_KERNEL
;
938 struct dso
*kernel_dso
;
940 struct dso
*hypervisor_dso
;
942 const char *vmlinux_name
= "vmlinux";
945 static void dsos__add(struct dso
*dso
)
947 list_add_tail(&dso
->node
, &dsos
);
950 static struct dso
*dsos__find(const char *name
)
954 list_for_each_entry(pos
, &dsos
, node
)
955 if (strcmp(pos
->name
, name
) == 0)
960 struct dso
*dsos__findnew(const char *name
)
962 struct dso
*dso
= dsos__find(name
);
968 dso
= dso__new(name
, 0);
972 nr
= dso__load(dso
, NULL
, verbose
);
974 eprintf("Failed to open: %s\n", name
);
978 eprintf("No symbols found in: %s, maybe install a debug package?\n", name
);
989 void dsos__fprintf(FILE *fp
)
993 list_for_each_entry(pos
, &dsos
, node
)
994 dso__fprintf(pos
, fp
);
997 static struct symbol
*vdso__find_symbol(struct dso
*dso
, u64 ip
)
999 return dso__find_symbol(dso
, ip
);
1002 int load_kernel(void)
1006 kernel_dso
= dso__new("[kernel]", 0);
1010 err
= dso__load_kernel(kernel_dso
, vmlinux_name
, NULL
, verbose
, modules
);
1012 dso__delete(kernel_dso
);
1015 dsos__add(kernel_dso
);
1017 vdso
= dso__new("[vdso]", 0);
1021 vdso
->find_symbol
= vdso__find_symbol
;
1025 hypervisor_dso
= dso__new("[hypervisor]", 0);
1026 if (!hypervisor_dso
)
1028 dsos__add(hypervisor_dso
);
1034 void symbol__init(void)
1036 elf_version(EV_CURRENT
);