]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - tools/perf/util/symbol.c
12 #include <sys/utsname.h>
14 const char *sym_hist_filter
;
27 static void dsos__add(struct dso
*dso
);
28 static struct dso
*dsos__find(const char *name
);
30 static struct rb_root kernel_maps
;
32 static void dso__set_symbols_end(struct dso
*self
)
34 struct rb_node
*nd
, *prevnd
= rb_first(&self
->syms
);
39 for (nd
= rb_next(prevnd
); nd
; nd
= rb_next(nd
)) {
40 struct symbol
*prev
= rb_entry(prevnd
, struct symbol
, rb_node
),
41 *curr
= rb_entry(nd
, struct symbol
, rb_node
);
43 if (prev
->end
== prev
->start
)
44 prev
->end
= curr
->start
- 1;
49 static void kernel_maps__fixup_sym_end(void)
51 struct map
*prev
, *curr
;
52 struct rb_node
*nd
, *prevnd
= rb_first(&kernel_maps
);
57 curr
= rb_entry(prevnd
, struct map
, rb_node
);
58 dso__set_symbols_end(curr
->dso
);
60 for (nd
= rb_next(prevnd
); nd
; nd
= rb_next(nd
)) {
62 curr
= rb_entry(nd
, struct map
, rb_node
);
63 prev
->end
= curr
->start
- 1;
64 dso__set_symbols_end(curr
->dso
);
68 static struct symbol
*symbol__new(u64 start
, u64 len
, const char *name
,
69 unsigned int priv_size
, int v
)
71 size_t namelen
= strlen(name
) + 1;
72 struct symbol
*self
= calloc(1, priv_size
+ sizeof(*self
) + namelen
);
78 printf("new symbol: %016Lx [%08lx]: %s, hist: %p\n",
79 start
, (unsigned long)len
, name
, self
->hist
);
84 if (sym_hist_filter
&& !strcmp(name
, sym_hist_filter
))
85 self
->hist
= calloc(sizeof(u64
), len
);
88 memset(self
, 0, priv_size
);
89 self
= ((void *)self
) + priv_size
;
92 self
->end
= len
? start
+ len
- 1 : start
;
93 memcpy(self
->name
, name
, namelen
);
98 static void symbol__delete(struct symbol
*self
, unsigned int priv_size
)
100 free(((void *)self
) - priv_size
);
103 static size_t symbol__fprintf(struct symbol
*self
, FILE *fp
)
105 return fprintf(fp
, " %llx-%llx %s\n",
106 self
->start
, self
->end
, self
->name
);
109 struct dso
*dso__new(const char *name
, unsigned int sym_priv_size
)
111 struct dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
114 strcpy(self
->name
, name
);
115 self
->long_name
= self
->name
;
116 self
->short_name
= self
->name
;
117 self
->syms
= RB_ROOT
;
118 self
->sym_priv_size
= sym_priv_size
;
119 self
->find_symbol
= dso__find_symbol
;
120 self
->slen_calculated
= 0;
121 self
->origin
= DSO__ORIG_NOT_FOUND
;
127 static void dso__delete_symbols(struct dso
*self
)
130 struct rb_node
*next
= rb_first(&self
->syms
);
133 pos
= rb_entry(next
, struct symbol
, rb_node
);
134 next
= rb_next(&pos
->rb_node
);
135 rb_erase(&pos
->rb_node
, &self
->syms
);
136 symbol__delete(pos
, self
->sym_priv_size
);
140 void dso__delete(struct dso
*self
)
142 dso__delete_symbols(self
);
143 if (self
->long_name
!= self
->name
)
144 free(self
->long_name
);
148 static void dso__insert_symbol(struct dso
*self
, struct symbol
*sym
)
150 struct rb_node
**p
= &self
->syms
.rb_node
;
151 struct rb_node
*parent
= NULL
;
152 const u64 ip
= sym
->start
;
157 s
= rb_entry(parent
, struct symbol
, rb_node
);
163 rb_link_node(&sym
->rb_node
, parent
, p
);
164 rb_insert_color(&sym
->rb_node
, &self
->syms
);
167 struct symbol
*dso__find_symbol(struct dso
*self
, u64 ip
)
174 n
= self
->syms
.rb_node
;
177 struct symbol
*s
= rb_entry(n
, struct symbol
, rb_node
);
181 else if (ip
> s
->end
)
190 size_t dso__fprintf(struct dso
*self
, FILE *fp
)
192 size_t ret
= fprintf(fp
, "dso: %s\n", self
->short_name
);
195 for (nd
= rb_first(&self
->syms
); nd
; nd
= rb_next(nd
)) {
196 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
197 ret
+= symbol__fprintf(pos
, fp
);
203 static int maps__load_kallsyms(symbol_filter_t filter
, int use_modules
, int v
)
205 struct map
*map
= kernel_map
;
208 FILE *file
= fopen("/proc/kallsyms", "r");
214 while (!feof(file
)) {
219 char *module
, *symbol_name
;
221 line_len
= getline(&line
, &n
, file
);
228 line
[--line_len
] = '\0'; /* \n */
230 len
= hex2u64(line
, &start
);
233 if (len
+ 2 >= line_len
)
236 symbol_type
= toupper(line
[len
]);
238 * We're interested only in code ('T'ext)
240 if (symbol_type
!= 'T' && symbol_type
!= 'W')
243 symbol_name
= line
+ len
+ 2;
244 module
= strchr(symbol_name
, '\t');
246 char *module_name_end
;
251 module
= strchr(module
+ 1, '[');
254 module_name_end
= strchr(module
+ 1, ']');
255 if (!module_name_end
)
257 *(module_name_end
+ 1) = '\0';
258 if (strcmp(map
->dso
->name
, module
)) {
259 map
= kernel_maps__find_by_dso_name(module
);
261 fputs("/proc/{kallsyms,modules} "
262 "inconsistency!\n", stderr
);
266 start
= map
->map_ip(map
, start
);
270 * Well fix up the end later, when we have all sorted.
272 sym
= symbol__new(start
, 0, symbol_name
,
273 map
->dso
->sym_priv_size
, v
);
276 goto out_delete_line
;
278 if (filter
&& filter(map
, sym
))
279 symbol__delete(sym
, map
->dso
->sym_priv_size
);
281 dso__insert_symbol(map
->dso
, sym
);
297 static size_t kernel_maps__fprintf(FILE *fp
)
299 size_t printed
= fprintf(stderr
, "Kernel maps:\n");
302 printed
+= map__fprintf(kernel_map
, fp
);
303 printed
+= dso__fprintf(kernel_map
->dso
, fp
);
305 for (nd
= rb_first(&kernel_maps
); nd
; nd
= rb_next(nd
)) {
306 struct map
*pos
= rb_entry(nd
, struct map
, rb_node
);
308 printed
+= map__fprintf(pos
, fp
);
309 printed
+= dso__fprintf(pos
->dso
, fp
);
312 return printed
+ fprintf(stderr
, "END kernel maps\n");
315 static int dso__load_perf_map(struct dso
*self
, struct map
*map
,
316 symbol_filter_t filter
, int v
)
323 file
= fopen(self
->long_name
, "r");
327 while (!feof(file
)) {
332 line_len
= getline(&line
, &n
, file
);
339 line
[--line_len
] = '\0'; /* \n */
341 len
= hex2u64(line
, &start
);
344 if (len
+ 2 >= line_len
)
347 len
+= hex2u64(line
+ len
, &size
);
350 if (len
+ 2 >= line_len
)
353 sym
= symbol__new(start
, size
, line
+ len
,
354 self
->sym_priv_size
, v
);
357 goto out_delete_line
;
359 if (filter
&& filter(map
, sym
))
360 symbol__delete(sym
, self
->sym_priv_size
);
362 dso__insert_symbol(self
, sym
);
379 * elf_symtab__for_each_symbol - iterate thru all the symbols
381 * @self: struct elf_symtab instance to iterate
383 * @sym: GElf_Sym iterator
385 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
386 for (idx = 0, gelf_getsym(syms, idx, &sym);\
388 idx++, gelf_getsym(syms, idx, &sym))
390 static inline uint8_t elf_sym__type(const GElf_Sym
*sym
)
392 return GELF_ST_TYPE(sym
->st_info
);
395 static inline int elf_sym__is_function(const GElf_Sym
*sym
)
397 return elf_sym__type(sym
) == STT_FUNC
&&
399 sym
->st_shndx
!= SHN_UNDEF
;
402 static inline int elf_sym__is_label(const GElf_Sym
*sym
)
404 return elf_sym__type(sym
) == STT_NOTYPE
&&
406 sym
->st_shndx
!= SHN_UNDEF
&&
407 sym
->st_shndx
!= SHN_ABS
;
410 static inline const char *elf_sec__name(const GElf_Shdr
*shdr
,
411 const Elf_Data
*secstrs
)
413 return secstrs
->d_buf
+ shdr
->sh_name
;
416 static inline int elf_sec__is_text(const GElf_Shdr
*shdr
,
417 const Elf_Data
*secstrs
)
419 return strstr(elf_sec__name(shdr
, secstrs
), "text") != NULL
;
422 static inline const char *elf_sym__name(const GElf_Sym
*sym
,
423 const Elf_Data
*symstrs
)
425 return symstrs
->d_buf
+ sym
->st_name
;
428 static Elf_Scn
*elf_section_by_name(Elf
*elf
, GElf_Ehdr
*ep
,
429 GElf_Shdr
*shp
, const char *name
,
435 while ((sec
= elf_nextscn(elf
, sec
)) != NULL
) {
438 gelf_getshdr(sec
, shp
);
439 str
= elf_strptr(elf
, ep
->e_shstrndx
, shp
->sh_name
);
440 if (!strcmp(name
, str
)) {
451 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
452 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
454 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
456 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
457 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
459 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
462 * We need to check if we have a .dynsym, so that we can handle the
463 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
464 * .dynsym or .symtab).
465 * And always look at the original dso, not at debuginfo packages, that
466 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
468 static int dso__synthesize_plt_symbols(struct dso
*self
, int v
)
470 uint32_t nr_rel_entries
, idx
;
475 GElf_Shdr shdr_rel_plt
, shdr_dynsym
;
476 Elf_Data
*reldata
, *syms
, *symstrs
;
477 Elf_Scn
*scn_plt_rel
, *scn_symstrs
, *scn_dynsym
;
480 char sympltname
[1024];
482 int nr
= 0, symidx
, fd
, err
= 0;
484 fd
= open(self
->long_name
, O_RDONLY
);
488 elf
= elf_begin(fd
, ELF_C_READ_MMAP
, NULL
);
492 if (gelf_getehdr(elf
, &ehdr
) == NULL
)
495 scn_dynsym
= elf_section_by_name(elf
, &ehdr
, &shdr_dynsym
,
496 ".dynsym", &dynsym_idx
);
497 if (scn_dynsym
== NULL
)
500 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
502 if (scn_plt_rel
== NULL
) {
503 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
505 if (scn_plt_rel
== NULL
)
511 if (shdr_rel_plt
.sh_link
!= dynsym_idx
)
514 if (elf_section_by_name(elf
, &ehdr
, &shdr_plt
, ".plt", NULL
) == NULL
)
518 * Fetch the relocation section to find the idxes to the GOT
519 * and the symbols in the .dynsym they refer to.
521 reldata
= elf_getdata(scn_plt_rel
, NULL
);
525 syms
= elf_getdata(scn_dynsym
, NULL
);
529 scn_symstrs
= elf_getscn(elf
, shdr_dynsym
.sh_link
);
530 if (scn_symstrs
== NULL
)
533 symstrs
= elf_getdata(scn_symstrs
, NULL
);
537 nr_rel_entries
= shdr_rel_plt
.sh_size
/ shdr_rel_plt
.sh_entsize
;
538 plt_offset
= shdr_plt
.sh_offset
;
540 if (shdr_rel_plt
.sh_type
== SHT_RELA
) {
541 GElf_Rela pos_mem
, *pos
;
543 elf_section__for_each_rela(reldata
, pos
, pos_mem
, idx
,
545 symidx
= GELF_R_SYM(pos
->r_info
);
546 plt_offset
+= shdr_plt
.sh_entsize
;
547 gelf_getsym(syms
, symidx
, &sym
);
548 snprintf(sympltname
, sizeof(sympltname
),
549 "%s@plt", elf_sym__name(&sym
, symstrs
));
551 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
552 sympltname
, self
->sym_priv_size
, v
);
556 dso__insert_symbol(self
, f
);
559 } else if (shdr_rel_plt
.sh_type
== SHT_REL
) {
560 GElf_Rel pos_mem
, *pos
;
561 elf_section__for_each_rel(reldata
, pos
, pos_mem
, idx
,
563 symidx
= GELF_R_SYM(pos
->r_info
);
564 plt_offset
+= shdr_plt
.sh_entsize
;
565 gelf_getsym(syms
, symidx
, &sym
);
566 snprintf(sympltname
, sizeof(sympltname
),
567 "%s@plt", elf_sym__name(&sym
, symstrs
));
569 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
570 sympltname
, self
->sym_priv_size
, v
);
574 dso__insert_symbol(self
, f
);
588 fprintf(stderr
, "%s: problems reading %s PLT info.\n",
589 __func__
, self
->long_name
);
593 static int dso__load_sym(struct dso
*self
, struct map
*map
, const char *name
,
594 int fd
, symbol_filter_t filter
, int kernel
,
597 Elf_Data
*symstrs
, *secstrs
;
605 Elf_Scn
*sec
, *sec_strndx
;
609 elf
= elf_begin(fd
, ELF_C_READ_MMAP
, NULL
);
612 fprintf(stderr
, "%s: cannot read %s ELF file.\n",
617 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
619 fprintf(stderr
, "%s: cannot get elf header.\n", __func__
);
623 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".symtab", NULL
);
625 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".dynsym", NULL
);
630 syms
= elf_getdata(sec
, NULL
);
634 sec
= elf_getscn(elf
, shdr
.sh_link
);
638 symstrs
= elf_getdata(sec
, NULL
);
642 sec_strndx
= elf_getscn(elf
, ehdr
.e_shstrndx
);
643 if (sec_strndx
== NULL
)
646 secstrs
= elf_getdata(sec_strndx
, NULL
);
650 nr_syms
= shdr
.sh_size
/ shdr
.sh_entsize
;
652 memset(&sym
, 0, sizeof(sym
));
654 self
->adjust_symbols
= (ehdr
.e_type
== ET_EXEC
||
655 elf_section_by_name(elf
, &ehdr
, &shdr
,
658 } else self
->adjust_symbols
= 0;
660 elf_symtab__for_each_symbol(syms
, nr_syms
, idx
, sym
) {
662 const char *elf_name
;
664 int is_label
= elf_sym__is_label(&sym
);
665 const char *section_name
;
668 if (!is_label
&& !elf_sym__is_function(&sym
))
671 sec
= elf_getscn(elf
, sym
.st_shndx
);
675 gelf_getshdr(sec
, &shdr
);
677 if (is_label
&& !elf_sec__is_text(&shdr
, secstrs
))
680 section_name
= elf_sec__name(&shdr
, secstrs
);
682 if ((kernel
|| kmodule
)) {
683 if (strstr(section_name
, ".init"))
684 sh_offset
= shdr
.sh_offset
;
687 if (self
->adjust_symbols
) {
689 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
690 (u64
)sym
.st_value
, (u64
)shdr
.sh_addr
, (u64
)shdr
.sh_offset
);
692 sym
.st_value
-= shdr
.sh_addr
- shdr
.sh_offset
;
695 * We need to figure out if the object was created from C++ sources
696 * DWARF DW_compile_unit has this, but we don't always have access
699 elf_name
= elf_sym__name(&sym
, symstrs
);
700 demangled
= bfd_demangle(NULL
, elf_name
, DMGL_PARAMS
| DMGL_ANSI
);
701 if (demangled
!= NULL
)
702 elf_name
= demangled
;
704 f
= symbol__new(sym
.st_value
+ sh_offset
, sym
.st_size
, elf_name
,
705 self
->sym_priv_size
, v
);
710 if (filter
&& filter(map
, f
))
711 symbol__delete(f
, self
->sym_priv_size
);
713 dso__insert_symbol(self
, f
);
725 #define BUILD_ID_SIZE 128
727 static char *dso__read_build_id(struct dso
*self
, int v
)
732 Elf_Data
*build_id_data
;
734 char *build_id
= NULL
, *bid
;
737 int fd
= open(self
->long_name
, O_RDONLY
);
742 elf
= elf_begin(fd
, ELF_C_READ_MMAP
, NULL
);
745 fprintf(stderr
, "%s: cannot read %s ELF file.\n",
746 __func__
, self
->long_name
);
750 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
752 fprintf(stderr
, "%s: cannot get elf header.\n", __func__
);
756 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".note.gnu.build-id", NULL
);
760 build_id_data
= elf_getdata(sec
, NULL
);
761 if (build_id_data
== NULL
)
763 build_id
= malloc(BUILD_ID_SIZE
);
764 if (build_id
== NULL
)
766 raw
= build_id_data
->d_buf
+ 16;
769 for (i
= 0; i
< 20; ++i
) {
770 sprintf(bid
, "%02x", *raw
);
775 printf("%s(%s): %s\n", __func__
, self
->long_name
, build_id
);
784 char dso__symtab_origin(const struct dso
*self
)
786 static const char origin
[] = {
787 [DSO__ORIG_KERNEL
] = 'k',
788 [DSO__ORIG_JAVA_JIT
] = 'j',
789 [DSO__ORIG_FEDORA
] = 'f',
790 [DSO__ORIG_UBUNTU
] = 'u',
791 [DSO__ORIG_BUILDID
] = 'b',
792 [DSO__ORIG_DSO
] = 'd',
793 [DSO__ORIG_KMODULE
] = 'K',
796 if (self
== NULL
|| self
->origin
== DSO__ORIG_NOT_FOUND
)
798 return origin
[self
->origin
];
801 int dso__load(struct dso
*self
, struct map
*map
, symbol_filter_t filter
, int v
)
804 char *name
= malloc(size
), *build_id
= NULL
;
811 self
->adjust_symbols
= 0;
813 if (strncmp(self
->name
, "/tmp/perf-", 10) == 0) {
814 ret
= dso__load_perf_map(self
, map
, filter
, v
);
815 self
->origin
= ret
> 0 ? DSO__ORIG_JAVA_JIT
:
820 self
->origin
= DSO__ORIG_FEDORA
- 1;
825 switch (self
->origin
) {
826 case DSO__ORIG_FEDORA
:
827 snprintf(name
, size
, "/usr/lib/debug%s.debug",
830 case DSO__ORIG_UBUNTU
:
831 snprintf(name
, size
, "/usr/lib/debug%s",
834 case DSO__ORIG_BUILDID
:
835 build_id
= dso__read_build_id(self
, v
);
836 if (build_id
!= NULL
) {
838 "/usr/lib/debug/.build-id/%.2s/%s.debug",
839 build_id
, build_id
+ 2);
846 snprintf(name
, size
, "%s", self
->long_name
);
853 fd
= open(name
, O_RDONLY
);
856 ret
= dso__load_sym(self
, map
, name
, fd
, filter
, 0, 0, v
);
860 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
866 int nr_plt
= dso__synthesize_plt_symbols(self
, v
);
872 if (ret
< 0 && strstr(self
->name
, " (deleted)") != NULL
)
877 struct map
*kernel_map
;
879 static void kernel_maps__insert(struct map
*map
)
881 maps__insert(&kernel_maps
, map
);
884 struct symbol
*kernel_maps__find_symbol(u64 ip
, struct map
**mapp
)
887 * We can't have kernel_map in kernel_maps because it spans an address
888 * space that includes the modules. The right way to fix this is to
889 * create several maps, so that we don't have overlapping ranges with
890 * modules. For now lets look first on the kernel dso.
892 struct map
*map
= maps__find(&kernel_maps
, ip
);
896 ip
= map
->map_ip(map
, ip
);
897 sym
= map
->dso
->find_symbol(map
->dso
, ip
);
900 sym
= map
->dso
->find_symbol(map
->dso
, ip
);
909 struct map
*kernel_maps__find_by_dso_name(const char *name
)
913 for (nd
= rb_first(&kernel_maps
); nd
; nd
= rb_next(nd
)) {
914 struct map
*map
= rb_entry(nd
, struct map
, rb_node
);
916 if (map
->dso
&& strcmp(map
->dso
->name
, name
) == 0)
923 static int dso__load_module_sym(struct dso
*self
, struct map
*map
,
924 symbol_filter_t filter
, int v
)
926 int err
= 0, fd
= open(self
->long_name
, O_RDONLY
);
930 fprintf(stderr
, "%s: cannot open %s\n",
931 __func__
, self
->long_name
);
935 err
= dso__load_sym(self
, map
, self
->long_name
, fd
, filter
, 0, 1, v
);
941 static int dsos__load_modules_sym_dir(char *dirname
,
942 symbol_filter_t filter
, int v
)
945 int nr_symbols
= 0, err
;
946 DIR *dir
= opendir(dirname
);
950 fprintf(stderr
, "%s: cannot open %s dir\n", __func__
,
955 while ((dent
= readdir(dir
)) != NULL
) {
958 if (dent
->d_type
== DT_DIR
) {
959 if (!strcmp(dent
->d_name
, ".") ||
960 !strcmp(dent
->d_name
, ".."))
963 snprintf(path
, sizeof(path
), "%s/%s",
964 dirname
, dent
->d_name
);
965 err
= dsos__load_modules_sym_dir(path
, filter
, v
);
969 char *dot
= strrchr(dent
->d_name
, '.'),
972 struct rb_node
*last
;
974 if (dot
== NULL
|| strcmp(dot
, ".ko"))
976 snprintf(dso_name
, sizeof(dso_name
), "[%.*s]",
977 (int)(dot
- dent
->d_name
), dent
->d_name
);
979 strxfrchar(dso_name
, '-', '_');
980 map
= kernel_maps__find_by_dso_name(dso_name
);
984 snprintf(path
, sizeof(path
), "%s/%s",
985 dirname
, dent
->d_name
);
987 map
->dso
->long_name
= strdup(path
);
988 if (map
->dso
->long_name
== NULL
)
991 err
= dso__load_module_sym(map
->dso
, map
, filter
, v
);
994 last
= rb_last(&map
->dso
->syms
);
997 sym
= rb_entry(last
, struct symbol
, rb_node
);
998 map
->end
= map
->start
+ sym
->end
;
1010 static int dsos__load_modules_sym(symbol_filter_t filter
, int v
)
1013 char modules_path
[PATH_MAX
];
1015 if (uname(&uts
) < 0)
1018 snprintf(modules_path
, sizeof(modules_path
), "/lib/modules/%s/kernel",
1021 return dsos__load_modules_sym_dir(modules_path
, filter
, v
);
1025 * Constructor variant for modules (where we know from /proc/modules where
1026 * they are loaded) and for vmlinux, where only after we load all the
1027 * symbols we'll know where it starts and ends.
1029 static struct map
*map__new2(u64 start
, struct dso
*dso
)
1031 struct map
*self
= malloc(sizeof(*self
));
1034 self
->start
= start
;
1036 * Will be filled after we load all the symbols
1042 self
->map_ip
= map__map_ip
;
1043 RB_CLEAR_NODE(&self
->rb_node
);
1048 static int dsos__load_modules(unsigned int sym_priv_size
)
1052 FILE *file
= fopen("/proc/modules", "r");
1058 while (!feof(file
)) {
1059 char name
[PATH_MAX
];
1065 line_len
= getline(&line
, &n
, file
);
1072 line
[--line_len
] = '\0'; /* \n */
1074 sep
= strrchr(line
, 'x');
1078 hex2u64(sep
+ 1, &start
);
1080 sep
= strchr(line
, ' ');
1086 snprintf(name
, sizeof(name
), "[%s]", line
);
1087 dso
= dso__new(name
, sym_priv_size
);
1090 goto out_delete_line
;
1092 map
= map__new2(start
, dso
);
1095 goto out_delete_line
;
1098 dso
->origin
= DSO__ORIG_KMODULE
;
1099 kernel_maps__insert(map
);
1114 static int dso__load_vmlinux(struct dso
*self
, struct map
*map
,
1115 const char *vmlinux
,
1116 symbol_filter_t filter
, int v
)
1118 int err
, fd
= open(vmlinux
, O_RDONLY
);
1123 err
= dso__load_sym(self
, map
, self
->long_name
, fd
, filter
, 1, 0, v
);
1130 int dsos__load_kernel(const char *vmlinux
, unsigned int sym_priv_size
,
1131 symbol_filter_t filter
, int v
, int use_modules
)
1134 struct dso
*dso
= dso__new(vmlinux
, sym_priv_size
);
1139 dso
->short_name
= "[kernel]";
1140 kernel_map
= map__new2(0, dso
);
1141 if (kernel_map
== NULL
)
1142 goto out_delete_dso
;
1144 kernel_map
->map_ip
= vdso__map_ip
;
1146 if (use_modules
&& dsos__load_modules(sym_priv_size
) < 0) {
1147 fprintf(stderr
, "Failed to load list of modules in use! "
1153 err
= dso__load_vmlinux(dso
, kernel_map
, vmlinux
, filter
, v
);
1154 if (err
> 0 && use_modules
) {
1155 int syms
= dsos__load_modules_sym(filter
, v
);
1158 fprintf(stderr
, "Failed to read module symbols!"
1159 " Continuing...\n");
1166 err
= maps__load_kallsyms(filter
, use_modules
, v
);
1169 struct rb_node
*node
= rb_first(&dso
->syms
);
1170 struct symbol
*sym
= rb_entry(node
, struct symbol
, rb_node
);
1172 * Now that we have all sorted out, just set the ->end of all
1173 * symbols that still don't have it.
1175 dso__set_symbols_end(dso
);
1176 kernel_maps__fixup_sym_end();
1178 kernel_map
->start
= sym
->start
;
1179 node
= rb_last(&dso
->syms
);
1180 sym
= rb_entry(node
, struct symbol
, rb_node
);
1181 kernel_map
->end
= sym
->end
;
1183 dso
->origin
= DSO__ORIG_KERNEL
;
1185 * XXX See kernel_maps__find_symbol comment
1186 * kernel_maps__insert(kernel_map)
1191 kernel_maps__fprintf(stderr
);
1204 const char *vmlinux_name
= "vmlinux";
1207 static void dsos__add(struct dso
*dso
)
1209 list_add_tail(&dso
->node
, &dsos
);
1212 static struct dso
*dsos__find(const char *name
)
1216 list_for_each_entry(pos
, &dsos
, node
)
1217 if (strcmp(pos
->name
, name
) == 0)
1222 struct dso
*dsos__findnew(const char *name
)
1224 struct dso
*dso
= dsos__find(name
);
1230 dso
= dso__new(name
, 0);
1232 goto out_delete_dso
;
1234 nr
= dso__load(dso
, NULL
, NULL
, verbose
);
1236 eprintf("Failed to open: %s\n", name
);
1237 goto out_delete_dso
;
1240 eprintf("No symbols found in: %s, maybe install a debug package?\n", name
);
1251 void dsos__fprintf(FILE *fp
)
1255 list_for_each_entry(pos
, &dsos
, node
)
1256 dso__fprintf(pos
, fp
);
1259 int load_kernel(void)
1261 if (dsos__load_kernel(vmlinux_name
, 0, NULL
, verbose
, modules
) <= 0)
1264 vdso
= dso__new("[vdso]", 0);
1273 void symbol__init(void)
1275 elf_version(EV_CURRENT
);