11 #include <sys/param.h>
22 #include <sys/utsname.h>
24 #ifndef NT_GNU_BUILD_ID
25 #define NT_GNU_BUILD_ID 3
28 static void dsos__add(struct list_head
*head
, struct dso
*dso
);
29 static struct map
*map__new2(u64 start
, struct dso
*dso
, enum map_type type
);
30 static int dso__load_kernel_sym(struct dso
*self
, struct map
*map
,
31 symbol_filter_t filter
);
32 static int dso__load_guest_kernel_sym(struct dso
*self
, struct map
*map
,
33 symbol_filter_t filter
);
34 static int vmlinux_path__nr_entries
;
35 static char **vmlinux_path
;
37 struct symbol_conf symbol_conf
= {
38 .exclude_other
= true,
40 .try_vmlinux_path
= true,
43 bool dso__loaded(const struct dso
*self
, enum map_type type
)
45 return self
->loaded
& (1 << type
);
48 bool dso__sorted_by_name(const struct dso
*self
, enum map_type type
)
50 return self
->sorted_by_name
& (1 << type
);
53 static void dso__set_sorted_by_name(struct dso
*self
, enum map_type type
)
55 self
->sorted_by_name
|= (1 << type
);
58 bool symbol_type__is_a(char symbol_type
, enum map_type map_type
)
62 return symbol_type
== 'T' || symbol_type
== 'W';
64 return symbol_type
== 'D' || symbol_type
== 'd';
70 static void symbols__fixup_end(struct rb_root
*self
)
72 struct rb_node
*nd
, *prevnd
= rb_first(self
);
73 struct symbol
*curr
, *prev
;
78 curr
= rb_entry(prevnd
, struct symbol
, rb_node
);
80 for (nd
= rb_next(prevnd
); nd
; nd
= rb_next(nd
)) {
82 curr
= rb_entry(nd
, struct symbol
, rb_node
);
84 if (prev
->end
== prev
->start
)
85 prev
->end
= curr
->start
- 1;
89 if (curr
->end
== curr
->start
)
90 curr
->end
= roundup(curr
->start
, 4096);
93 static void __map_groups__fixup_end(struct map_groups
*self
, enum map_type type
)
95 struct map
*prev
, *curr
;
96 struct rb_node
*nd
, *prevnd
= rb_first(&self
->maps
[type
]);
101 curr
= rb_entry(prevnd
, struct map
, rb_node
);
103 for (nd
= rb_next(prevnd
); nd
; nd
= rb_next(nd
)) {
105 curr
= rb_entry(nd
, struct map
, rb_node
);
106 prev
->end
= curr
->start
- 1;
110 * We still haven't the actual symbols, so guess the
111 * last map final address.
116 static void map_groups__fixup_end(struct map_groups
*self
)
119 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
120 __map_groups__fixup_end(self
, i
);
123 static struct symbol
*symbol__new(u64 start
, u64 len
, const char *name
)
125 size_t namelen
= strlen(name
) + 1;
126 struct symbol
*self
= calloc(1, (symbol_conf
.priv_size
+
127 sizeof(*self
) + namelen
));
131 if (symbol_conf
.priv_size
)
132 self
= ((void *)self
) + symbol_conf
.priv_size
;
135 self
->end
= len
? start
+ len
- 1 : start
;
136 self
->namelen
= namelen
- 1;
138 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__
, name
, start
, self
->end
);
140 memcpy(self
->name
, name
, namelen
);
145 void symbol__delete(struct symbol
*self
)
147 free(((void *)self
) - symbol_conf
.priv_size
);
150 static size_t symbol__fprintf(struct symbol
*self
, FILE *fp
)
152 return fprintf(fp
, " %llx-%llx %s\n",
153 self
->start
, self
->end
, self
->name
);
156 void dso__set_long_name(struct dso
*self
, char *name
)
160 self
->long_name
= name
;
161 self
->long_name_len
= strlen(name
);
164 static void dso__set_short_name(struct dso
*self
, const char *name
)
168 self
->short_name
= name
;
169 self
->short_name_len
= strlen(name
);
172 static void dso__set_basename(struct dso
*self
)
174 dso__set_short_name(self
, basename(self
->long_name
));
177 struct dso
*dso__new(const char *name
)
179 struct dso
*self
= calloc(1, sizeof(*self
) + strlen(name
) + 1);
183 strcpy(self
->name
, name
);
184 dso__set_long_name(self
, self
->name
);
185 dso__set_short_name(self
, self
->name
);
186 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
187 self
->symbols
[i
] = self
->symbol_names
[i
] = RB_ROOT
;
188 self
->slen_calculated
= 0;
189 self
->origin
= DSO__ORIG_NOT_FOUND
;
191 self
->sorted_by_name
= 0;
192 self
->has_build_id
= 0;
193 self
->kernel
= DSO_TYPE_USER
;
194 INIT_LIST_HEAD(&self
->node
);
200 static void symbols__delete(struct rb_root
*self
)
203 struct rb_node
*next
= rb_first(self
);
206 pos
= rb_entry(next
, struct symbol
, rb_node
);
207 next
= rb_next(&pos
->rb_node
);
208 rb_erase(&pos
->rb_node
, self
);
213 void dso__delete(struct dso
*self
)
216 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
217 symbols__delete(&self
->symbols
[i
]);
218 if (self
->long_name
!= self
->name
)
219 free(self
->long_name
);
223 void dso__set_build_id(struct dso
*self
, void *build_id
)
225 memcpy(self
->build_id
, build_id
, sizeof(self
->build_id
));
226 self
->has_build_id
= 1;
229 static void symbols__insert(struct rb_root
*self
, struct symbol
*sym
)
231 struct rb_node
**p
= &self
->rb_node
;
232 struct rb_node
*parent
= NULL
;
233 const u64 ip
= sym
->start
;
238 s
= rb_entry(parent
, struct symbol
, rb_node
);
244 rb_link_node(&sym
->rb_node
, parent
, p
);
245 rb_insert_color(&sym
->rb_node
, self
);
248 static struct symbol
*symbols__find(struct rb_root
*self
, u64 ip
)
258 struct symbol
*s
= rb_entry(n
, struct symbol
, rb_node
);
262 else if (ip
> s
->end
)
271 struct symbol_name_rb_node
{
272 struct rb_node rb_node
;
276 static void symbols__insert_by_name(struct rb_root
*self
, struct symbol
*sym
)
278 struct rb_node
**p
= &self
->rb_node
;
279 struct rb_node
*parent
= NULL
;
280 struct symbol_name_rb_node
*symn
= ((void *)sym
) - sizeof(*parent
), *s
;
284 s
= rb_entry(parent
, struct symbol_name_rb_node
, rb_node
);
285 if (strcmp(sym
->name
, s
->sym
.name
) < 0)
290 rb_link_node(&symn
->rb_node
, parent
, p
);
291 rb_insert_color(&symn
->rb_node
, self
);
294 static void symbols__sort_by_name(struct rb_root
*self
, struct rb_root
*source
)
298 for (nd
= rb_first(source
); nd
; nd
= rb_next(nd
)) {
299 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
300 symbols__insert_by_name(self
, pos
);
304 static struct symbol
*symbols__find_by_name(struct rb_root
*self
, const char *name
)
314 struct symbol_name_rb_node
*s
;
317 s
= rb_entry(n
, struct symbol_name_rb_node
, rb_node
);
318 cmp
= strcmp(name
, s
->sym
.name
);
331 struct symbol
*dso__find_symbol(struct dso
*self
,
332 enum map_type type
, u64 addr
)
334 return symbols__find(&self
->symbols
[type
], addr
);
337 struct symbol
*dso__find_symbol_by_name(struct dso
*self
, enum map_type type
,
340 return symbols__find_by_name(&self
->symbol_names
[type
], name
);
343 void dso__sort_by_name(struct dso
*self
, enum map_type type
)
345 dso__set_sorted_by_name(self
, type
);
346 return symbols__sort_by_name(&self
->symbol_names
[type
],
347 &self
->symbols
[type
]);
350 int build_id__sprintf(const u8
*self
, int len
, char *bf
)
353 const u8
*raw
= self
;
356 for (i
= 0; i
< len
; ++i
) {
357 sprintf(bid
, "%02x", *raw
);
365 size_t dso__fprintf_buildid(struct dso
*self
, FILE *fp
)
367 char sbuild_id
[BUILD_ID_SIZE
* 2 + 1];
369 build_id__sprintf(self
->build_id
, sizeof(self
->build_id
), sbuild_id
);
370 return fprintf(fp
, "%s", sbuild_id
);
373 size_t dso__fprintf(struct dso
*self
, enum map_type type
, FILE *fp
)
376 size_t ret
= fprintf(fp
, "dso: %s (", self
->short_name
);
378 if (self
->short_name
!= self
->long_name
)
379 ret
+= fprintf(fp
, "%s, ", self
->long_name
);
380 ret
+= fprintf(fp
, "%s, %sloaded, ", map_type__name
[type
],
381 self
->loaded
? "" : "NOT ");
382 ret
+= dso__fprintf_buildid(self
, fp
);
383 ret
+= fprintf(fp
, ")\n");
384 for (nd
= rb_first(&self
->symbols
[type
]); nd
; nd
= rb_next(nd
)) {
385 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
386 ret
+= symbol__fprintf(pos
, fp
);
392 int kallsyms__parse(const char *filename
, void *arg
,
393 int (*process_symbol
)(void *arg
, const char *name
,
394 char type
, u64 start
))
399 FILE *file
= fopen(filename
, "r");
404 while (!feof(file
)) {
410 line_len
= getline(&line
, &n
, file
);
411 if (line_len
< 0 || !line
)
414 line
[--line_len
] = '\0'; /* \n */
416 len
= hex2u64(line
, &start
);
419 if (len
+ 2 >= line_len
)
422 symbol_type
= toupper(line
[len
]);
423 symbol_name
= line
+ len
+ 2;
425 err
= process_symbol(arg
, symbol_name
, symbol_type
, start
);
438 struct process_kallsyms_args
{
443 static int map__process_kallsym_symbol(void *arg
, const char *name
,
444 char type
, u64 start
)
447 struct process_kallsyms_args
*a
= arg
;
448 struct rb_root
*root
= &a
->dso
->symbols
[a
->map
->type
];
450 if (!symbol_type__is_a(type
, a
->map
->type
))
454 * Will fix up the end later, when we have all symbols sorted.
456 sym
= symbol__new(start
, 0, name
);
461 * We will pass the symbols to the filter later, in
462 * map__split_kallsyms, when we have split the maps per module
464 symbols__insert(root
, sym
);
470 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
471 * so that we can in the next step set the symbol ->end address and then
472 * call kernel_maps__split_kallsyms.
474 static int dso__load_all_kallsyms(struct dso
*self
, const char *filename
,
477 struct process_kallsyms_args args
= { .map
= map
, .dso
= self
, };
478 return kallsyms__parse(filename
, &args
, map__process_kallsym_symbol
);
482 * Split the symbols into maps, making sure there are no overlaps, i.e. the
483 * kernel range is broken in several maps, named [kernel].N, as we don't have
484 * the original ELF section names vmlinux have.
486 static int dso__split_kallsyms(struct dso
*self
, struct map
*map
,
487 symbol_filter_t filter
)
489 struct map_groups
*kmaps
= map__kmap(map
)->kmaps
;
490 struct machine
*machine
= kmaps
->machine
;
491 struct map
*curr_map
= map
;
494 struct rb_root
*root
= &self
->symbols
[map
->type
];
495 struct rb_node
*next
= rb_first(root
);
496 int kernel_range
= 0;
501 pos
= rb_entry(next
, struct symbol
, rb_node
);
502 next
= rb_next(&pos
->rb_node
);
504 module
= strchr(pos
->name
, '\t');
506 if (!symbol_conf
.use_modules
)
511 if (strcmp(curr_map
->dso
->short_name
, module
)) {
512 if (curr_map
!= map
&&
513 self
->kernel
== DSO_TYPE_GUEST_KERNEL
&&
514 machine__is_default_guest(machine
)) {
516 * We assume all symbols of a module are
517 * continuous in * kallsyms, so curr_map
518 * points to a module and all its
519 * symbols are in its kmap. Mark it as
522 dso__set_loaded(curr_map
->dso
,
526 curr_map
= map_groups__find_by_name(kmaps
,
528 if (curr_map
== NULL
) {
529 pr_debug("%s/proc/{kallsyms,modules} "
530 "inconsistency while looking "
531 "for \"%s\" module!\n",
532 machine
->root_dir
, module
);
537 if (curr_map
->dso
->loaded
&&
538 !machine__is_default_guest(machine
))
542 * So that we look just like we get from .ko files,
543 * i.e. not prelinked, relative to map->start.
545 pos
->start
= curr_map
->map_ip(curr_map
, pos
->start
);
546 pos
->end
= curr_map
->map_ip(curr_map
, pos
->end
);
547 } else if (curr_map
!= map
) {
548 char dso_name
[PATH_MAX
];
551 if (self
->kernel
== DSO_TYPE_GUEST_KERNEL
)
552 snprintf(dso_name
, sizeof(dso_name
),
556 snprintf(dso_name
, sizeof(dso_name
),
560 dso
= dso__new(dso_name
);
564 dso
->kernel
= self
->kernel
;
566 curr_map
= map__new2(pos
->start
, dso
, map
->type
);
567 if (curr_map
== NULL
) {
572 curr_map
->map_ip
= curr_map
->unmap_ip
= identity__map_ip
;
573 map_groups__insert(kmaps
, curr_map
);
577 if (filter
&& filter(curr_map
, pos
)) {
578 discard_symbol
: rb_erase(&pos
->rb_node
, root
);
581 if (curr_map
!= map
) {
582 rb_erase(&pos
->rb_node
, root
);
583 symbols__insert(&curr_map
->dso
->symbols
[curr_map
->type
], pos
);
589 if (curr_map
!= map
&&
590 self
->kernel
== DSO_TYPE_GUEST_KERNEL
&&
591 machine__is_default_guest(kmaps
->machine
)) {
592 dso__set_loaded(curr_map
->dso
, curr_map
->type
);
598 int dso__load_kallsyms(struct dso
*self
, const char *filename
,
599 struct map
*map
, symbol_filter_t filter
)
601 if (dso__load_all_kallsyms(self
, filename
, map
) < 0)
604 symbols__fixup_end(&self
->symbols
[map
->type
]);
605 if (self
->kernel
== DSO_TYPE_GUEST_KERNEL
)
606 self
->origin
= DSO__ORIG_GUEST_KERNEL
;
608 self
->origin
= DSO__ORIG_KERNEL
;
610 return dso__split_kallsyms(self
, map
, filter
);
613 static int dso__load_perf_map(struct dso
*self
, struct map
*map
,
614 symbol_filter_t filter
)
621 file
= fopen(self
->long_name
, "r");
625 while (!feof(file
)) {
630 line_len
= getline(&line
, &n
, file
);
637 line
[--line_len
] = '\0'; /* \n */
639 len
= hex2u64(line
, &start
);
642 if (len
+ 2 >= line_len
)
645 len
+= hex2u64(line
+ len
, &size
);
648 if (len
+ 2 >= line_len
)
651 sym
= symbol__new(start
, size
, line
+ len
);
654 goto out_delete_line
;
656 if (filter
&& filter(map
, sym
))
659 symbols__insert(&self
->symbols
[map
->type
], sym
);
676 * elf_symtab__for_each_symbol - iterate thru all the symbols
678 * @self: struct elf_symtab instance to iterate
680 * @sym: GElf_Sym iterator
682 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
683 for (idx = 0, gelf_getsym(syms, idx, &sym);\
685 idx++, gelf_getsym(syms, idx, &sym))
687 static inline uint8_t elf_sym__type(const GElf_Sym
*sym
)
689 return GELF_ST_TYPE(sym
->st_info
);
692 static inline int elf_sym__is_function(const GElf_Sym
*sym
)
694 return elf_sym__type(sym
) == STT_FUNC
&&
696 sym
->st_shndx
!= SHN_UNDEF
;
699 static inline bool elf_sym__is_object(const GElf_Sym
*sym
)
701 return elf_sym__type(sym
) == STT_OBJECT
&&
703 sym
->st_shndx
!= SHN_UNDEF
;
706 static inline int elf_sym__is_label(const GElf_Sym
*sym
)
708 return elf_sym__type(sym
) == STT_NOTYPE
&&
710 sym
->st_shndx
!= SHN_UNDEF
&&
711 sym
->st_shndx
!= SHN_ABS
;
714 static inline const char *elf_sec__name(const GElf_Shdr
*shdr
,
715 const Elf_Data
*secstrs
)
717 return secstrs
->d_buf
+ shdr
->sh_name
;
720 static inline int elf_sec__is_text(const GElf_Shdr
*shdr
,
721 const Elf_Data
*secstrs
)
723 return strstr(elf_sec__name(shdr
, secstrs
), "text") != NULL
;
726 static inline bool elf_sec__is_data(const GElf_Shdr
*shdr
,
727 const Elf_Data
*secstrs
)
729 return strstr(elf_sec__name(shdr
, secstrs
), "data") != NULL
;
732 static inline const char *elf_sym__name(const GElf_Sym
*sym
,
733 const Elf_Data
*symstrs
)
735 return symstrs
->d_buf
+ sym
->st_name
;
738 static Elf_Scn
*elf_section_by_name(Elf
*elf
, GElf_Ehdr
*ep
,
739 GElf_Shdr
*shp
, const char *name
,
745 while ((sec
= elf_nextscn(elf
, sec
)) != NULL
) {
748 gelf_getshdr(sec
, shp
);
749 str
= elf_strptr(elf
, ep
->e_shstrndx
, shp
->sh_name
);
750 if (!strcmp(name
, str
)) {
761 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
762 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
764 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
766 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
767 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
769 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
772 * We need to check if we have a .dynsym, so that we can handle the
773 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
774 * .dynsym or .symtab).
775 * And always look at the original dso, not at debuginfo packages, that
776 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
778 static int dso__synthesize_plt_symbols(struct dso
*self
, struct map
*map
,
779 symbol_filter_t filter
)
781 uint32_t nr_rel_entries
, idx
;
786 GElf_Shdr shdr_rel_plt
, shdr_dynsym
;
787 Elf_Data
*reldata
, *syms
, *symstrs
;
788 Elf_Scn
*scn_plt_rel
, *scn_symstrs
, *scn_dynsym
;
791 char sympltname
[1024];
793 int nr
= 0, symidx
, fd
, err
= 0;
795 fd
= open(self
->long_name
, O_RDONLY
);
799 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
803 if (gelf_getehdr(elf
, &ehdr
) == NULL
)
806 scn_dynsym
= elf_section_by_name(elf
, &ehdr
, &shdr_dynsym
,
807 ".dynsym", &dynsym_idx
);
808 if (scn_dynsym
== NULL
)
811 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
813 if (scn_plt_rel
== NULL
) {
814 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
816 if (scn_plt_rel
== NULL
)
822 if (shdr_rel_plt
.sh_link
!= dynsym_idx
)
825 if (elf_section_by_name(elf
, &ehdr
, &shdr_plt
, ".plt", NULL
) == NULL
)
829 * Fetch the relocation section to find the idxes to the GOT
830 * and the symbols in the .dynsym they refer to.
832 reldata
= elf_getdata(scn_plt_rel
, NULL
);
836 syms
= elf_getdata(scn_dynsym
, NULL
);
840 scn_symstrs
= elf_getscn(elf
, shdr_dynsym
.sh_link
);
841 if (scn_symstrs
== NULL
)
844 symstrs
= elf_getdata(scn_symstrs
, NULL
);
848 nr_rel_entries
= shdr_rel_plt
.sh_size
/ shdr_rel_plt
.sh_entsize
;
849 plt_offset
= shdr_plt
.sh_offset
;
851 if (shdr_rel_plt
.sh_type
== SHT_RELA
) {
852 GElf_Rela pos_mem
, *pos
;
854 elf_section__for_each_rela(reldata
, pos
, pos_mem
, idx
,
856 symidx
= GELF_R_SYM(pos
->r_info
);
857 plt_offset
+= shdr_plt
.sh_entsize
;
858 gelf_getsym(syms
, symidx
, &sym
);
859 snprintf(sympltname
, sizeof(sympltname
),
860 "%s@plt", elf_sym__name(&sym
, symstrs
));
862 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
867 if (filter
&& filter(map
, f
))
870 symbols__insert(&self
->symbols
[map
->type
], f
);
874 } else if (shdr_rel_plt
.sh_type
== SHT_REL
) {
875 GElf_Rel pos_mem
, *pos
;
876 elf_section__for_each_rel(reldata
, pos
, pos_mem
, idx
,
878 symidx
= GELF_R_SYM(pos
->r_info
);
879 plt_offset
+= shdr_plt
.sh_entsize
;
880 gelf_getsym(syms
, symidx
, &sym
);
881 snprintf(sympltname
, sizeof(sympltname
),
882 "%s@plt", elf_sym__name(&sym
, symstrs
));
884 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
889 if (filter
&& filter(map
, f
))
892 symbols__insert(&self
->symbols
[map
->type
], f
);
907 pr_debug("%s: problems reading %s PLT info.\n",
908 __func__
, self
->long_name
);
912 static bool elf_sym__is_a(GElf_Sym
*self
, enum map_type type
)
916 return elf_sym__is_function(self
);
918 return elf_sym__is_object(self
);
924 static bool elf_sec__is_a(GElf_Shdr
*self
, Elf_Data
*secstrs
, enum map_type type
)
928 return elf_sec__is_text(self
, secstrs
);
930 return elf_sec__is_data(self
, secstrs
);
936 static size_t elf_addr_to_index(Elf
*elf
, GElf_Addr addr
)
942 while ((sec
= elf_nextscn(elf
, sec
)) != NULL
) {
943 gelf_getshdr(sec
, &shdr
);
945 if ((addr
>= shdr
.sh_addr
) &&
946 (addr
< (shdr
.sh_addr
+ shdr
.sh_size
)))
955 static int dso__load_sym(struct dso
*self
, struct map
*map
, const char *name
,
956 int fd
, symbol_filter_t filter
, int kmodule
)
958 struct kmap
*kmap
= self
->kernel
? map__kmap(map
) : NULL
;
959 struct map
*curr_map
= map
;
960 struct dso
*curr_dso
= self
;
961 Elf_Data
*symstrs
, *secstrs
;
966 GElf_Shdr shdr
, opdshdr
;
967 Elf_Data
*syms
, *opddata
= NULL
;
969 Elf_Scn
*sec
, *sec_strndx
, *opdsec
;
974 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
976 pr_err("%s: cannot read %s ELF file.\n", __func__
, name
);
980 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
981 pr_err("%s: cannot get elf header.\n", __func__
);
985 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".symtab", NULL
);
987 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".dynsym", NULL
);
992 opdsec
= elf_section_by_name(elf
, &ehdr
, &opdshdr
, ".opd", &opdidx
);
994 opddata
= elf_rawdata(opdsec
, NULL
);
996 syms
= elf_getdata(sec
, NULL
);
1000 sec
= elf_getscn(elf
, shdr
.sh_link
);
1004 symstrs
= elf_getdata(sec
, NULL
);
1005 if (symstrs
== NULL
)
1008 sec_strndx
= elf_getscn(elf
, ehdr
.e_shstrndx
);
1009 if (sec_strndx
== NULL
)
1012 secstrs
= elf_getdata(sec_strndx
, NULL
);
1013 if (secstrs
== NULL
)
1016 nr_syms
= shdr
.sh_size
/ shdr
.sh_entsize
;
1018 memset(&sym
, 0, sizeof(sym
));
1019 if (self
->kernel
== DSO_TYPE_USER
) {
1020 self
->adjust_symbols
= (ehdr
.e_type
== ET_EXEC
||
1021 elf_section_by_name(elf
, &ehdr
, &shdr
,
1022 ".gnu.prelink_undo",
1024 } else self
->adjust_symbols
= 0;
1026 elf_symtab__for_each_symbol(syms
, nr_syms
, idx
, sym
) {
1028 const char *elf_name
= elf_sym__name(&sym
, symstrs
);
1029 char *demangled
= NULL
;
1030 int is_label
= elf_sym__is_label(&sym
);
1031 const char *section_name
;
1033 if (kmap
&& kmap
->ref_reloc_sym
&& kmap
->ref_reloc_sym
->name
&&
1034 strcmp(elf_name
, kmap
->ref_reloc_sym
->name
) == 0)
1035 kmap
->ref_reloc_sym
->unrelocated_addr
= sym
.st_value
;
1037 if (!is_label
&& !elf_sym__is_a(&sym
, map
->type
))
1040 if (opdsec
&& sym
.st_shndx
== opdidx
) {
1041 u32 offset
= sym
.st_value
- opdshdr
.sh_addr
;
1042 u64
*opd
= opddata
->d_buf
+ offset
;
1043 sym
.st_value
= *opd
;
1044 sym
.st_shndx
= elf_addr_to_index(elf
, sym
.st_value
);
1047 sec
= elf_getscn(elf
, sym
.st_shndx
);
1051 gelf_getshdr(sec
, &shdr
);
1053 if (is_label
&& !elf_sec__is_a(&shdr
, secstrs
, map
->type
))
1056 section_name
= elf_sec__name(&shdr
, secstrs
);
1058 if (self
->kernel
!= DSO_TYPE_USER
|| kmodule
) {
1059 char dso_name
[PATH_MAX
];
1061 if (strcmp(section_name
,
1062 (curr_dso
->short_name
+
1063 self
->short_name_len
)) == 0)
1066 if (strcmp(section_name
, ".text") == 0) {
1072 snprintf(dso_name
, sizeof(dso_name
),
1073 "%s%s", self
->short_name
, section_name
);
1075 curr_map
= map_groups__find_by_name(kmap
->kmaps
, map
->type
, dso_name
);
1076 if (curr_map
== NULL
) {
1077 u64 start
= sym
.st_value
;
1080 start
+= map
->start
+ shdr
.sh_offset
;
1082 curr_dso
= dso__new(dso_name
);
1083 if (curr_dso
== NULL
)
1085 curr_dso
->kernel
= self
->kernel
;
1086 curr_map
= map__new2(start
, curr_dso
,
1088 if (curr_map
== NULL
) {
1089 dso__delete(curr_dso
);
1092 curr_map
->map_ip
= identity__map_ip
;
1093 curr_map
->unmap_ip
= identity__map_ip
;
1094 curr_dso
->origin
= self
->origin
;
1095 map_groups__insert(kmap
->kmaps
, curr_map
);
1096 dsos__add(&self
->node
, curr_dso
);
1097 dso__set_loaded(curr_dso
, map
->type
);
1099 curr_dso
= curr_map
->dso
;
1104 if (curr_dso
->adjust_symbols
) {
1105 pr_debug4("%s: adjusting symbol: st_value: %#Lx "
1106 "sh_addr: %#Lx sh_offset: %#Lx\n", __func__
,
1107 (u64
)sym
.st_value
, (u64
)shdr
.sh_addr
,
1108 (u64
)shdr
.sh_offset
);
1109 sym
.st_value
-= shdr
.sh_addr
- shdr
.sh_offset
;
1112 * We need to figure out if the object was created from C++ sources
1113 * DWARF DW_compile_unit has this, but we don't always have access
1116 demangled
= bfd_demangle(NULL
, elf_name
, DMGL_PARAMS
| DMGL_ANSI
);
1117 if (demangled
!= NULL
)
1118 elf_name
= demangled
;
1120 f
= symbol__new(sym
.st_value
, sym
.st_size
, elf_name
);
1125 if (filter
&& filter(curr_map
, f
))
1128 symbols__insert(&curr_dso
->symbols
[curr_map
->type
], f
);
1134 * For misannotated, zeroed, ASM function sizes.
1137 symbols__fixup_end(&self
->symbols
[map
->type
]);
1140 * We need to fixup this here too because we create new
1141 * maps here, for things like vsyscall sections.
1143 __map_groups__fixup_end(kmap
->kmaps
, map
->type
);
1153 static bool dso__build_id_equal(const struct dso
*self
, u8
*build_id
)
1155 return memcmp(self
->build_id
, build_id
, sizeof(self
->build_id
)) == 0;
1158 bool __dsos__read_build_ids(struct list_head
*head
, bool with_hits
)
1160 bool have_build_id
= false;
1163 list_for_each_entry(pos
, head
, node
) {
1164 if (with_hits
&& !pos
->hit
)
1166 if (pos
->has_build_id
) {
1167 have_build_id
= true;
1170 if (filename__read_build_id(pos
->long_name
, pos
->build_id
,
1171 sizeof(pos
->build_id
)) > 0) {
1172 have_build_id
= true;
1173 pos
->has_build_id
= true;
1177 return have_build_id
;
1181 * Align offset to 4 bytes as needed for note name and descriptor data.
1183 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
1185 int filename__read_build_id(const char *filename
, void *bf
, size_t size
)
1196 if (size
< BUILD_ID_SIZE
)
1199 fd
= open(filename
, O_RDONLY
);
1203 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
1205 pr_debug2("%s: cannot read %s ELF file.\n", __func__
, filename
);
1210 if (ek
!= ELF_K_ELF
)
1213 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
1214 pr_err("%s: cannot get elf header.\n", __func__
);
1218 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
,
1219 ".note.gnu.build-id", NULL
);
1221 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
,
1227 data
= elf_getdata(sec
, NULL
);
1232 while (ptr
< (data
->d_buf
+ data
->d_size
)) {
1233 GElf_Nhdr
*nhdr
= ptr
;
1234 int namesz
= NOTE_ALIGN(nhdr
->n_namesz
),
1235 descsz
= NOTE_ALIGN(nhdr
->n_descsz
);
1238 ptr
+= sizeof(*nhdr
);
1241 if (nhdr
->n_type
== NT_GNU_BUILD_ID
&&
1242 nhdr
->n_namesz
== sizeof("GNU")) {
1243 if (memcmp(name
, "GNU", sizeof("GNU")) == 0) {
1244 memcpy(bf
, ptr
, BUILD_ID_SIZE
);
1245 err
= BUILD_ID_SIZE
;
1259 int sysfs__read_build_id(const char *filename
, void *build_id
, size_t size
)
1263 if (size
< BUILD_ID_SIZE
)
1266 fd
= open(filename
, O_RDONLY
);
1275 if (read(fd
, &nhdr
, sizeof(nhdr
)) != sizeof(nhdr
))
1278 namesz
= NOTE_ALIGN(nhdr
.n_namesz
);
1279 descsz
= NOTE_ALIGN(nhdr
.n_descsz
);
1280 if (nhdr
.n_type
== NT_GNU_BUILD_ID
&&
1281 nhdr
.n_namesz
== sizeof("GNU")) {
1282 if (read(fd
, bf
, namesz
) != namesz
)
1284 if (memcmp(bf
, "GNU", sizeof("GNU")) == 0) {
1285 if (read(fd
, build_id
,
1286 BUILD_ID_SIZE
) == BUILD_ID_SIZE
) {
1290 } else if (read(fd
, bf
, descsz
) != descsz
)
1293 int n
= namesz
+ descsz
;
1294 if (read(fd
, bf
, n
) != n
)
1303 char dso__symtab_origin(const struct dso
*self
)
1305 static const char origin
[] = {
1306 [DSO__ORIG_KERNEL
] = 'k',
1307 [DSO__ORIG_JAVA_JIT
] = 'j',
1308 [DSO__ORIG_BUILD_ID_CACHE
] = 'B',
1309 [DSO__ORIG_FEDORA
] = 'f',
1310 [DSO__ORIG_UBUNTU
] = 'u',
1311 [DSO__ORIG_BUILDID
] = 'b',
1312 [DSO__ORIG_DSO
] = 'd',
1313 [DSO__ORIG_KMODULE
] = 'K',
1314 [DSO__ORIG_GUEST_KERNEL
] = 'g',
1315 [DSO__ORIG_GUEST_KMODULE
] = 'G',
1318 if (self
== NULL
|| self
->origin
== DSO__ORIG_NOT_FOUND
)
1320 return origin
[self
->origin
];
1323 int dso__load(struct dso
*self
, struct map
*map
, symbol_filter_t filter
)
1325 int size
= PATH_MAX
;
1327 u8 build_id
[BUILD_ID_SIZE
];
1330 struct machine
*machine
;
1331 const char *root_dir
;
1333 dso__set_loaded(self
, map
->type
);
1335 if (self
->kernel
== DSO_TYPE_KERNEL
)
1336 return dso__load_kernel_sym(self
, map
, filter
);
1337 else if (self
->kernel
== DSO_TYPE_GUEST_KERNEL
)
1338 return dso__load_guest_kernel_sym(self
, map
, filter
);
1340 if (map
->groups
&& map
->groups
->machine
)
1341 machine
= map
->groups
->machine
;
1345 name
= malloc(size
);
1349 self
->adjust_symbols
= 0;
1351 if (strncmp(self
->name
, "/tmp/perf-", 10) == 0) {
1352 ret
= dso__load_perf_map(self
, map
, filter
);
1353 self
->origin
= ret
> 0 ? DSO__ORIG_JAVA_JIT
:
1354 DSO__ORIG_NOT_FOUND
;
1358 self
->origin
= DSO__ORIG_BUILD_ID_CACHE
;
1359 if (dso__build_id_filename(self
, name
, size
) != NULL
)
1364 switch (self
->origin
) {
1365 case DSO__ORIG_FEDORA
:
1366 snprintf(name
, size
, "/usr/lib/debug%s.debug",
1369 case DSO__ORIG_UBUNTU
:
1370 snprintf(name
, size
, "/usr/lib/debug%s",
1373 case DSO__ORIG_BUILDID
:
1374 if (filename__read_build_id(self
->long_name
, build_id
,
1375 sizeof(build_id
))) {
1376 char build_id_hex
[BUILD_ID_SIZE
* 2 + 1];
1377 build_id__sprintf(build_id
, sizeof(build_id
),
1379 snprintf(name
, size
,
1380 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1381 build_id_hex
, build_id_hex
+ 2);
1382 if (self
->has_build_id
)
1383 goto compare_build_id
;
1389 snprintf(name
, size
, "%s", self
->long_name
);
1391 case DSO__ORIG_GUEST_KMODULE
:
1392 if (map
->groups
&& map
->groups
->machine
)
1393 root_dir
= map
->groups
->machine
->root_dir
;
1396 snprintf(name
, size
, "%s%s", root_dir
, self
->long_name
);
1403 if (self
->has_build_id
) {
1404 if (filename__read_build_id(name
, build_id
,
1405 sizeof(build_id
)) < 0)
1408 if (!dso__build_id_equal(self
, build_id
))
1412 fd
= open(name
, O_RDONLY
);
1415 ret
= dso__load_sym(self
, map
, name
, fd
, filter
, 0);
1419 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1425 int nr_plt
= dso__synthesize_plt_symbols(self
, map
, filter
);
1431 if (ret
< 0 && strstr(self
->name
, " (deleted)") != NULL
)
1436 struct map
*map_groups__find_by_name(struct map_groups
*self
,
1437 enum map_type type
, const char *name
)
1441 for (nd
= rb_first(&self
->maps
[type
]); nd
; nd
= rb_next(nd
)) {
1442 struct map
*map
= rb_entry(nd
, struct map
, rb_node
);
1444 if (map
->dso
&& strcmp(map
->dso
->short_name
, name
) == 0)
1451 static int dso__kernel_module_get_build_id(struct dso
*self
,
1452 const char *root_dir
)
1454 char filename
[PATH_MAX
];
1456 * kernel module short names are of the form "[module]" and
1457 * we need just "module" here.
1459 const char *name
= self
->short_name
+ 1;
1461 snprintf(filename
, sizeof(filename
),
1462 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1463 root_dir
, (int)strlen(name
) - 1, name
);
1465 if (sysfs__read_build_id(filename
, self
->build_id
,
1466 sizeof(self
->build_id
)) == 0)
1467 self
->has_build_id
= true;
1472 static int map_groups__set_modules_path_dir(struct map_groups
*self
,
1473 const char *dir_name
)
1475 struct dirent
*dent
;
1476 DIR *dir
= opendir(dir_name
);
1479 pr_debug("%s: cannot open %s dir\n", __func__
, dir_name
);
1483 while ((dent
= readdir(dir
)) != NULL
) {
1484 char path
[PATH_MAX
];
1487 /*sshfs might return bad dent->d_type, so we have to stat*/
1488 sprintf(path
, "%s/%s", dir_name
, dent
->d_name
);
1489 if (stat(path
, &st
))
1492 if (S_ISDIR(st
.st_mode
)) {
1493 if (!strcmp(dent
->d_name
, ".") ||
1494 !strcmp(dent
->d_name
, ".."))
1497 snprintf(path
, sizeof(path
), "%s/%s",
1498 dir_name
, dent
->d_name
);
1499 if (map_groups__set_modules_path_dir(self
, path
) < 0)
1502 char *dot
= strrchr(dent
->d_name
, '.'),
1507 if (dot
== NULL
|| strcmp(dot
, ".ko"))
1509 snprintf(dso_name
, sizeof(dso_name
), "[%.*s]",
1510 (int)(dot
- dent
->d_name
), dent
->d_name
);
1512 strxfrchar(dso_name
, '-', '_');
1513 map
= map_groups__find_by_name(self
, MAP__FUNCTION
, dso_name
);
1517 snprintf(path
, sizeof(path
), "%s/%s",
1518 dir_name
, dent
->d_name
);
1520 long_name
= strdup(path
);
1521 if (long_name
== NULL
)
1523 dso__set_long_name(map
->dso
, long_name
);
1524 dso__kernel_module_get_build_id(map
->dso
, "");
1534 static char *get_kernel_version(const char *root_dir
)
1536 char version
[PATH_MAX
];
1539 const char *prefix
= "Linux version ";
1541 sprintf(version
, "%s/proc/version", root_dir
);
1542 file
= fopen(version
, "r");
1547 tmp
= fgets(version
, sizeof(version
), file
);
1550 name
= strstr(version
, prefix
);
1553 name
+= strlen(prefix
);
1554 tmp
= strchr(name
, ' ');
1558 return strdup(name
);
1561 static int machine__set_modules_path(struct machine
*self
)
1564 char modules_path
[PATH_MAX
];
1566 version
= get_kernel_version(self
->root_dir
);
1570 snprintf(modules_path
, sizeof(modules_path
), "%s/lib/modules/%s/kernel",
1571 self
->root_dir
, version
);
1574 return map_groups__set_modules_path_dir(&self
->kmaps
, modules_path
);
1578 * Constructor variant for modules (where we know from /proc/modules where
1579 * they are loaded) and for vmlinux, where only after we load all the
1580 * symbols we'll know where it starts and ends.
1582 static struct map
*map__new2(u64 start
, struct dso
*dso
, enum map_type type
)
1584 struct map
*self
= calloc(1, (sizeof(*self
) +
1585 (dso
->kernel
? sizeof(struct kmap
) : 0)));
1588 * ->end will be filled after we load all the symbols
1590 map__init(self
, type
, start
, 0, 0, dso
);
1596 struct map
*machine__new_module(struct machine
*self
, u64 start
,
1597 const char *filename
)
1600 struct dso
*dso
= __dsos__findnew(&self
->kernel_dsos
, filename
);
1605 map
= map__new2(start
, dso
, MAP__FUNCTION
);
1609 if (machine__is_host(self
))
1610 dso
->origin
= DSO__ORIG_KMODULE
;
1612 dso
->origin
= DSO__ORIG_GUEST_KMODULE
;
1613 map_groups__insert(&self
->kmaps
, map
);
1617 static int machine__create_modules(struct machine
*self
)
1623 const char *modules
;
1624 char path
[PATH_MAX
];
1626 if (machine__is_default_guest(self
))
1627 modules
= symbol_conf
.default_guest_modules
;
1629 sprintf(path
, "%s/proc/modules", self
->root_dir
);
1633 file
= fopen(modules
, "r");
1637 while (!feof(file
)) {
1638 char name
[PATH_MAX
];
1643 line_len
= getline(&line
, &n
, file
);
1650 line
[--line_len
] = '\0'; /* \n */
1652 sep
= strrchr(line
, 'x');
1656 hex2u64(sep
+ 1, &start
);
1658 sep
= strchr(line
, ' ');
1664 snprintf(name
, sizeof(name
), "[%s]", line
);
1665 map
= machine__new_module(self
, start
, name
);
1667 goto out_delete_line
;
1668 dso__kernel_module_get_build_id(map
->dso
, self
->root_dir
);
1674 return machine__set_modules_path(self
);
1682 static int dso__load_vmlinux(struct dso
*self
, struct map
*map
,
1683 const char *vmlinux
, symbol_filter_t filter
)
1687 if (self
->has_build_id
) {
1688 u8 build_id
[BUILD_ID_SIZE
];
1690 if (filename__read_build_id(vmlinux
, build_id
,
1691 sizeof(build_id
)) < 0) {
1692 pr_debug("No build_id in %s, ignoring it\n", vmlinux
);
1695 if (!dso__build_id_equal(self
, build_id
)) {
1696 char expected_build_id
[BUILD_ID_SIZE
* 2 + 1],
1697 vmlinux_build_id
[BUILD_ID_SIZE
* 2 + 1];
1699 build_id__sprintf(self
->build_id
,
1700 sizeof(self
->build_id
),
1702 build_id__sprintf(build_id
, sizeof(build_id
),
1704 pr_debug("build_id in %s is %s while expected is %s, "
1705 "ignoring it\n", vmlinux
, vmlinux_build_id
,
1711 fd
= open(vmlinux
, O_RDONLY
);
1715 dso__set_loaded(self
, map
->type
);
1716 err
= dso__load_sym(self
, map
, vmlinux
, fd
, filter
, 0);
1720 pr_debug("Using %s for symbols\n", vmlinux
);
1725 int dso__load_vmlinux_path(struct dso
*self
, struct map
*map
,
1726 symbol_filter_t filter
)
1731 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1732 vmlinux_path__nr_entries
+ 1);
1734 filename
= dso__build_id_filename(self
, NULL
, 0);
1735 if (filename
!= NULL
) {
1736 err
= dso__load_vmlinux(self
, map
, filename
, filter
);
1738 dso__set_long_name(self
, filename
);
1744 for (i
= 0; i
< vmlinux_path__nr_entries
; ++i
) {
1745 err
= dso__load_vmlinux(self
, map
, vmlinux_path
[i
], filter
);
1747 dso__set_long_name(self
, strdup(vmlinux_path
[i
]));
1755 static int dso__load_kernel_sym(struct dso
*self
, struct map
*map
,
1756 symbol_filter_t filter
)
1759 const char *kallsyms_filename
= NULL
;
1760 char *kallsyms_allocated_filename
= NULL
;
1762 * Step 1: if the user specified a vmlinux filename, use it and only
1763 * it, reporting errors to the user if it cannot be used.
1765 * For instance, try to analyse an ARM perf.data file _without_ a
1766 * build-id, or if the user specifies the wrong path to the right
1767 * vmlinux file, obviously we can't fallback to another vmlinux (a
1768 * x86_86 one, on the machine where analysis is being performed, say),
1769 * or worse, /proc/kallsyms.
1771 * If the specified file _has_ a build-id and there is a build-id
1772 * section in the perf.data file, we will still do the expected
1773 * validation in dso__load_vmlinux and will bail out if they don't
1776 if (symbol_conf
.vmlinux_name
!= NULL
) {
1777 err
= dso__load_vmlinux(self
, map
,
1778 symbol_conf
.vmlinux_name
, filter
);
1780 dso__set_long_name(self
,
1781 strdup(symbol_conf
.vmlinux_name
));
1787 if (vmlinux_path
!= NULL
) {
1788 err
= dso__load_vmlinux_path(self
, map
, filter
);
1794 * Say the kernel DSO was created when processing the build-id header table,
1795 * we have a build-id, so check if it is the same as the running kernel,
1796 * using it if it is.
1798 if (self
->has_build_id
) {
1799 u8 kallsyms_build_id
[BUILD_ID_SIZE
];
1800 char sbuild_id
[BUILD_ID_SIZE
* 2 + 1];
1802 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id
,
1803 sizeof(kallsyms_build_id
)) == 0) {
1804 if (dso__build_id_equal(self
, kallsyms_build_id
)) {
1805 kallsyms_filename
= "/proc/kallsyms";
1810 * Now look if we have it on the build-id cache in
1811 * $HOME/.debug/[kernel.kallsyms].
1813 build_id__sprintf(self
->build_id
, sizeof(self
->build_id
),
1816 if (asprintf(&kallsyms_allocated_filename
,
1817 "%s/.debug/[kernel.kallsyms]/%s",
1818 getenv("HOME"), sbuild_id
) == -1) {
1819 pr_err("Not enough memory for kallsyms file lookup\n");
1823 kallsyms_filename
= kallsyms_allocated_filename
;
1825 if (access(kallsyms_filename
, F_OK
)) {
1826 pr_err("No kallsyms or vmlinux with build-id %s "
1827 "was found\n", sbuild_id
);
1828 free(kallsyms_allocated_filename
);
1833 * Last resort, if we don't have a build-id and couldn't find
1834 * any vmlinux file, try the running kernel kallsyms table.
1836 kallsyms_filename
= "/proc/kallsyms";
1840 err
= dso__load_kallsyms(self
, kallsyms_filename
, map
, filter
);
1842 pr_debug("Using %s for symbols\n", kallsyms_filename
);
1843 free(kallsyms_allocated_filename
);
1847 if (kallsyms_filename
!= NULL
)
1848 dso__set_long_name(self
, strdup("[kernel.kallsyms]"));
1849 map__fixup_start(map
);
1850 map__fixup_end(map
);
1856 static int dso__load_guest_kernel_sym(struct dso
*self
, struct map
*map
,
1857 symbol_filter_t filter
)
1860 const char *kallsyms_filename
= NULL
;
1861 struct machine
*machine
;
1862 char path
[PATH_MAX
];
1865 pr_debug("Guest kernel map hasn't the point to groups\n");
1868 machine
= map
->groups
->machine
;
1870 if (machine__is_default_guest(machine
)) {
1872 * if the user specified a vmlinux filename, use it and only
1873 * it, reporting errors to the user if it cannot be used.
1874 * Or use file guest_kallsyms inputted by user on commandline
1876 if (symbol_conf
.default_guest_vmlinux_name
!= NULL
) {
1877 err
= dso__load_vmlinux(self
, map
,
1878 symbol_conf
.default_guest_vmlinux_name
, filter
);
1882 kallsyms_filename
= symbol_conf
.default_guest_kallsyms
;
1883 if (!kallsyms_filename
)
1886 sprintf(path
, "%s/proc/kallsyms", machine
->root_dir
);
1887 kallsyms_filename
= path
;
1890 err
= dso__load_kallsyms(self
, kallsyms_filename
, map
, filter
);
1892 pr_debug("Using %s for symbols\n", kallsyms_filename
);
1896 if (kallsyms_filename
!= NULL
) {
1897 machine__mmap_name(machine
, path
, sizeof(path
));
1898 dso__set_long_name(self
, strdup(path
));
1900 map__fixup_start(map
);
1901 map__fixup_end(map
);
1907 static void dsos__add(struct list_head
*head
, struct dso
*dso
)
1909 list_add_tail(&dso
->node
, head
);
1912 static struct dso
*dsos__find(struct list_head
*head
, const char *name
)
1916 list_for_each_entry(pos
, head
, node
)
1917 if (strcmp(pos
->long_name
, name
) == 0)
1922 struct dso
*__dsos__findnew(struct list_head
*head
, const char *name
)
1924 struct dso
*dso
= dsos__find(head
, name
);
1927 dso
= dso__new(name
);
1929 dsos__add(head
, dso
);
1930 dso__set_basename(dso
);
1937 size_t __dsos__fprintf(struct list_head
*head
, FILE *fp
)
1942 list_for_each_entry(pos
, head
, node
) {
1944 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
1945 ret
+= dso__fprintf(pos
, i
, fp
);
1951 size_t machines__fprintf_dsos(struct rb_root
*self
, FILE *fp
)
1956 for (nd
= rb_first(self
); nd
; nd
= rb_next(nd
)) {
1957 struct machine
*pos
= rb_entry(nd
, struct machine
, rb_node
);
1958 ret
+= __dsos__fprintf(&pos
->kernel_dsos
, fp
);
1959 ret
+= __dsos__fprintf(&pos
->user_dsos
, fp
);
1965 static size_t __dsos__fprintf_buildid(struct list_head
*head
, FILE *fp
,
1971 list_for_each_entry(pos
, head
, node
) {
1972 if (with_hits
&& !pos
->hit
)
1974 ret
+= dso__fprintf_buildid(pos
, fp
);
1975 ret
+= fprintf(fp
, " %s\n", pos
->long_name
);
1980 size_t machine__fprintf_dsos_buildid(struct machine
*self
, FILE *fp
, bool with_hits
)
1982 return __dsos__fprintf_buildid(&self
->kernel_dsos
, fp
, with_hits
) +
1983 __dsos__fprintf_buildid(&self
->user_dsos
, fp
, with_hits
);
1986 size_t machines__fprintf_dsos_buildid(struct rb_root
*self
, FILE *fp
, bool with_hits
)
1991 for (nd
= rb_first(self
); nd
; nd
= rb_next(nd
)) {
1992 struct machine
*pos
= rb_entry(nd
, struct machine
, rb_node
);
1993 ret
+= machine__fprintf_dsos_buildid(pos
, fp
, with_hits
);
1998 struct dso
*dso__new_kernel(const char *name
)
2000 struct dso
*self
= dso__new(name
?: "[kernel.kallsyms]");
2003 dso__set_short_name(self
, "[kernel]");
2004 self
->kernel
= DSO_TYPE_KERNEL
;
2010 static struct dso
*dso__new_guest_kernel(struct machine
*machine
,
2014 struct dso
*self
= dso__new(name
?: machine__mmap_name(machine
, bf
, sizeof(bf
)));
2017 dso__set_short_name(self
, "[guest.kernel]");
2018 self
->kernel
= DSO_TYPE_GUEST_KERNEL
;
2024 void dso__read_running_kernel_build_id(struct dso
*self
, struct machine
*machine
)
2026 char path
[PATH_MAX
];
2028 if (machine__is_default_guest(machine
))
2030 sprintf(path
, "%s/sys/kernel/notes", machine
->root_dir
);
2031 if (sysfs__read_build_id(path
, self
->build_id
,
2032 sizeof(self
->build_id
)) == 0)
2033 self
->has_build_id
= true;
2036 static struct dso
*machine__create_kernel(struct machine
*self
)
2038 const char *vmlinux_name
= NULL
;
2041 if (machine__is_host(self
)) {
2042 vmlinux_name
= symbol_conf
.vmlinux_name
;
2043 kernel
= dso__new_kernel(vmlinux_name
);
2045 if (machine__is_default_guest(self
))
2046 vmlinux_name
= symbol_conf
.default_guest_vmlinux_name
;
2047 kernel
= dso__new_guest_kernel(self
, vmlinux_name
);
2050 if (kernel
!= NULL
) {
2051 dso__read_running_kernel_build_id(kernel
, self
);
2052 dsos__add(&self
->kernel_dsos
, kernel
);
2057 int __machine__create_kernel_maps(struct machine
*self
, struct dso
*kernel
)
2061 for (type
= 0; type
< MAP__NR_TYPES
; ++type
) {
2064 self
->vmlinux_maps
[type
] = map__new2(0, kernel
, type
);
2065 if (self
->vmlinux_maps
[type
] == NULL
)
2068 self
->vmlinux_maps
[type
]->map_ip
=
2069 self
->vmlinux_maps
[type
]->unmap_ip
= identity__map_ip
;
2071 kmap
= map__kmap(self
->vmlinux_maps
[type
]);
2072 kmap
->kmaps
= &self
->kmaps
;
2073 map_groups__insert(&self
->kmaps
, self
->vmlinux_maps
[type
]);
2079 int machine__create_kernel_maps(struct machine
*self
)
2081 struct dso
*kernel
= machine__create_kernel(self
);
2083 if (kernel
== NULL
||
2084 __machine__create_kernel_maps(self
, kernel
) < 0)
2087 if (symbol_conf
.use_modules
&& machine__create_modules(self
) < 0)
2088 pr_debug("Problems creating module maps, continuing anyway...\n");
2090 * Now that we have all the maps created, just set the ->end of them:
2092 map_groups__fixup_end(&self
->kmaps
);
2096 static void vmlinux_path__exit(void)
2098 while (--vmlinux_path__nr_entries
>= 0) {
2099 free(vmlinux_path
[vmlinux_path__nr_entries
]);
2100 vmlinux_path
[vmlinux_path__nr_entries
] = NULL
;
2104 vmlinux_path
= NULL
;
2107 static int vmlinux_path__init(void)
2112 if (uname(&uts
) < 0)
2115 vmlinux_path
= malloc(sizeof(char *) * 5);
2116 if (vmlinux_path
== NULL
)
2119 vmlinux_path
[vmlinux_path__nr_entries
] = strdup("vmlinux");
2120 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
2122 ++vmlinux_path__nr_entries
;
2123 vmlinux_path
[vmlinux_path__nr_entries
] = strdup("/boot/vmlinux");
2124 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
2126 ++vmlinux_path__nr_entries
;
2127 snprintf(bf
, sizeof(bf
), "/boot/vmlinux-%s", uts
.release
);
2128 vmlinux_path
[vmlinux_path__nr_entries
] = strdup(bf
);
2129 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
2131 ++vmlinux_path__nr_entries
;
2132 snprintf(bf
, sizeof(bf
), "/lib/modules/%s/build/vmlinux", uts
.release
);
2133 vmlinux_path
[vmlinux_path__nr_entries
] = strdup(bf
);
2134 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
2136 ++vmlinux_path__nr_entries
;
2137 snprintf(bf
, sizeof(bf
), "/usr/lib/debug/lib/modules/%s/vmlinux",
2139 vmlinux_path
[vmlinux_path__nr_entries
] = strdup(bf
);
2140 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
2142 ++vmlinux_path__nr_entries
;
2147 vmlinux_path__exit();
2151 size_t machine__fprintf_vmlinux_path(struct machine
*self
, FILE *fp
)
2155 struct dso
*kdso
= self
->vmlinux_maps
[MAP__FUNCTION
]->dso
;
2157 if (kdso
->has_build_id
) {
2158 char filename
[PATH_MAX
];
2159 if (dso__build_id_filename(kdso
, filename
, sizeof(filename
)))
2160 printed
+= fprintf(fp
, "[0] %s\n", filename
);
2163 for (i
= 0; i
< vmlinux_path__nr_entries
; ++i
)
2164 printed
+= fprintf(fp
, "[%d] %s\n",
2165 i
+ kdso
->has_build_id
, vmlinux_path
[i
]);
2170 static int setup_list(struct strlist
**list
, const char *list_str
,
2171 const char *list_name
)
2173 if (list_str
== NULL
)
2176 *list
= strlist__new(true, list_str
);
2178 pr_err("problems parsing %s list\n", list_name
);
2184 int symbol__init(void)
2186 elf_version(EV_CURRENT
);
2187 if (symbol_conf
.sort_by_name
)
2188 symbol_conf
.priv_size
+= (sizeof(struct symbol_name_rb_node
) -
2189 sizeof(struct symbol
));
2191 if (symbol_conf
.try_vmlinux_path
&& vmlinux_path__init() < 0)
2194 if (symbol_conf
.field_sep
&& *symbol_conf
.field_sep
== '.') {
2195 pr_err("'.' is the only non valid --field-separator argument\n");
2199 if (setup_list(&symbol_conf
.dso_list
,
2200 symbol_conf
.dso_list_str
, "dso") < 0)
2203 if (setup_list(&symbol_conf
.comm_list
,
2204 symbol_conf
.comm_list_str
, "comm") < 0)
2205 goto out_free_dso_list
;
2207 if (setup_list(&symbol_conf
.sym_list
,
2208 symbol_conf
.sym_list_str
, "symbol") < 0)
2209 goto out_free_comm_list
;
2214 strlist__delete(symbol_conf
.dso_list
);
2216 strlist__delete(symbol_conf
.comm_list
);
2220 int machines__create_kernel_maps(struct rb_root
*self
, pid_t pid
)
2222 struct machine
*machine
= machines__findnew(self
, pid
);
2224 if (machine
== NULL
)
2227 return machine__create_kernel_maps(machine
);
2230 static int hex(char ch
)
2232 if ((ch
>= '0') && (ch
<= '9'))
2234 if ((ch
>= 'a') && (ch
<= 'f'))
2235 return ch
- 'a' + 10;
2236 if ((ch
>= 'A') && (ch
<= 'F'))
2237 return ch
- 'A' + 10;
2242 * While we find nice hex chars, build a long_val.
2243 * Return number of chars processed.
2245 int hex2u64(const char *ptr
, u64
*long_val
)
2247 const char *p
= ptr
;
2251 const int hex_val
= hex(*p
);
2256 *long_val
= (*long_val
<< 4) | hex_val
;
2263 char *strxfrchar(char *s
, char from
, char to
)
2267 while ((p
= strchr(p
, from
)) != NULL
)
2273 int machines__create_guest_kernel_maps(struct rb_root
*self
)
2276 struct dirent
**namelist
= NULL
;
2278 char path
[PATH_MAX
];
2281 if (symbol_conf
.default_guest_vmlinux_name
||
2282 symbol_conf
.default_guest_modules
||
2283 symbol_conf
.default_guest_kallsyms
) {
2284 machines__create_kernel_maps(self
, DEFAULT_GUEST_KERNEL_ID
);
2287 if (symbol_conf
.guestmount
) {
2288 items
= scandir(symbol_conf
.guestmount
, &namelist
, NULL
, NULL
);
2291 for (i
= 0; i
< items
; i
++) {
2292 if (!isdigit(namelist
[i
]->d_name
[0])) {
2293 /* Filter out . and .. */
2296 pid
= atoi(namelist
[i
]->d_name
);
2297 sprintf(path
, "%s/%s/proc/kallsyms",
2298 symbol_conf
.guestmount
,
2299 namelist
[i
]->d_name
);
2300 ret
= access(path
, R_OK
);
2302 pr_debug("Can't access file %s\n", path
);
2305 machines__create_kernel_maps(self
, pid
);
2314 int machine__load_kallsyms(struct machine
*self
, const char *filename
,
2315 enum map_type type
, symbol_filter_t filter
)
2317 struct map
*map
= self
->vmlinux_maps
[type
];
2318 int ret
= dso__load_kallsyms(map
->dso
, filename
, map
, filter
);
2321 dso__set_loaded(map
->dso
, type
);
2323 * Since /proc/kallsyms will have multiple sessions for the
2324 * kernel, with modules between them, fixup the end of all
2327 __map_groups__fixup_end(&self
->kmaps
, type
);
2333 int machine__load_vmlinux_path(struct machine
*self
, enum map_type type
,
2334 symbol_filter_t filter
)
2336 struct map
*map
= self
->vmlinux_maps
[type
];
2337 int ret
= dso__load_vmlinux_path(map
->dso
, map
, filter
);
2340 dso__set_loaded(map
->dso
, type
);
2341 map__reloc_vmlinux(map
);