16 #include <sys/utsname.h>
18 #ifndef NT_GNU_BUILD_ID
19 #define NT_GNU_BUILD_ID 3
25 DSO__ORIG_BUILD_ID_CACHE
,
34 static void dsos__add(struct list_head
*head
, struct dso
*dso
);
35 static struct map
*map__new2(u64 start
, struct dso
*dso
, enum map_type type
);
36 static int dso__load_kernel_sym(struct dso
*self
, struct map
*map
,
37 struct perf_session
*session
, symbol_filter_t filter
);
38 static int vmlinux_path__nr_entries
;
39 static char **vmlinux_path
;
41 struct symbol_conf symbol_conf
= {
42 .exclude_other
= true,
44 .try_vmlinux_path
= true,
47 bool dso__loaded(const struct dso
*self
, enum map_type type
)
49 return self
->loaded
& (1 << type
);
52 bool dso__sorted_by_name(const struct dso
*self
, enum map_type type
)
54 return self
->sorted_by_name
& (1 << type
);
57 static void dso__set_loaded(struct dso
*self
, enum map_type type
)
59 self
->loaded
|= (1 << type
);
62 static void dso__set_sorted_by_name(struct dso
*self
, enum map_type type
)
64 self
->sorted_by_name
|= (1 << type
);
67 bool symbol_type__is_a(char symbol_type
, enum map_type map_type
)
71 return symbol_type
== 'T' || symbol_type
== 'W';
73 return symbol_type
== 'D' || symbol_type
== 'd';
79 static void symbols__fixup_end(struct rb_root
*self
)
81 struct rb_node
*nd
, *prevnd
= rb_first(self
);
82 struct symbol
*curr
, *prev
;
87 curr
= rb_entry(prevnd
, struct symbol
, rb_node
);
89 for (nd
= rb_next(prevnd
); nd
; nd
= rb_next(nd
)) {
91 curr
= rb_entry(nd
, struct symbol
, rb_node
);
93 if (prev
->end
== prev
->start
)
94 prev
->end
= curr
->start
- 1;
98 if (curr
->end
== curr
->start
)
99 curr
->end
= roundup(curr
->start
, 4096);
102 static void __map_groups__fixup_end(struct map_groups
*self
, enum map_type type
)
104 struct map
*prev
, *curr
;
105 struct rb_node
*nd
, *prevnd
= rb_first(&self
->maps
[type
]);
110 curr
= rb_entry(prevnd
, struct map
, rb_node
);
112 for (nd
= rb_next(prevnd
); nd
; nd
= rb_next(nd
)) {
114 curr
= rb_entry(nd
, struct map
, rb_node
);
115 prev
->end
= curr
->start
- 1;
119 * We still haven't the actual symbols, so guess the
120 * last map final address.
125 static void map_groups__fixup_end(struct map_groups
*self
)
128 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
129 __map_groups__fixup_end(self
, i
);
132 static struct symbol
*symbol__new(u64 start
, u64 len
, const char *name
)
134 size_t namelen
= strlen(name
) + 1;
135 struct symbol
*self
= zalloc(symbol_conf
.priv_size
+
136 sizeof(*self
) + namelen
);
140 if (symbol_conf
.priv_size
)
141 self
= ((void *)self
) + symbol_conf
.priv_size
;
144 self
->end
= len
? start
+ len
- 1 : start
;
146 pr_debug3("%s: %s %#Lx-%#Lx\n", __func__
, name
, start
, self
->end
);
148 memcpy(self
->name
, name
, namelen
);
153 static void symbol__delete(struct symbol
*self
)
155 free(((void *)self
) - symbol_conf
.priv_size
);
158 static size_t symbol__fprintf(struct symbol
*self
, FILE *fp
)
160 return fprintf(fp
, " %llx-%llx %s\n",
161 self
->start
, self
->end
, self
->name
);
164 static void dso__set_long_name(struct dso
*self
, char *name
)
168 self
->long_name
= name
;
169 self
->long_name_len
= strlen(name
);
172 static void dso__set_basename(struct dso
*self
)
174 self
->short_name
= basename(self
->long_name
);
177 struct dso
*dso__new(const char *name
)
179 struct dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
183 strcpy(self
->name
, name
);
184 dso__set_long_name(self
, self
->name
);
185 self
->short_name
= 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;
198 static void symbols__delete(struct rb_root
*self
)
201 struct rb_node
*next
= rb_first(self
);
204 pos
= rb_entry(next
, struct symbol
, rb_node
);
205 next
= rb_next(&pos
->rb_node
);
206 rb_erase(&pos
->rb_node
, self
);
211 void dso__delete(struct dso
*self
)
214 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
215 symbols__delete(&self
->symbols
[i
]);
216 if (self
->long_name
!= self
->name
)
217 free(self
->long_name
);
221 void dso__set_build_id(struct dso
*self
, void *build_id
)
223 memcpy(self
->build_id
, build_id
, sizeof(self
->build_id
));
224 self
->has_build_id
= 1;
227 static void symbols__insert(struct rb_root
*self
, struct symbol
*sym
)
229 struct rb_node
**p
= &self
->rb_node
;
230 struct rb_node
*parent
= NULL
;
231 const u64 ip
= sym
->start
;
236 s
= rb_entry(parent
, struct symbol
, rb_node
);
242 rb_link_node(&sym
->rb_node
, parent
, p
);
243 rb_insert_color(&sym
->rb_node
, self
);
246 static struct symbol
*symbols__find(struct rb_root
*self
, u64 ip
)
256 struct symbol
*s
= rb_entry(n
, struct symbol
, rb_node
);
260 else if (ip
> s
->end
)
269 struct symbol_name_rb_node
{
270 struct rb_node rb_node
;
274 static void symbols__insert_by_name(struct rb_root
*self
, struct symbol
*sym
)
276 struct rb_node
**p
= &self
->rb_node
;
277 struct rb_node
*parent
= NULL
;
278 struct symbol_name_rb_node
*symn
= ((void *)sym
) - sizeof(*parent
), *s
;
282 s
= rb_entry(parent
, struct symbol_name_rb_node
, rb_node
);
283 if (strcmp(sym
->name
, s
->sym
.name
) < 0)
288 rb_link_node(&symn
->rb_node
, parent
, p
);
289 rb_insert_color(&symn
->rb_node
, self
);
292 static void symbols__sort_by_name(struct rb_root
*self
, struct rb_root
*source
)
296 for (nd
= rb_first(source
); nd
; nd
= rb_next(nd
)) {
297 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
298 symbols__insert_by_name(self
, pos
);
302 static struct symbol
*symbols__find_by_name(struct rb_root
*self
, const char *name
)
312 struct symbol_name_rb_node
*s
;
315 s
= rb_entry(n
, struct symbol_name_rb_node
, rb_node
);
316 cmp
= strcmp(name
, s
->sym
.name
);
329 struct symbol
*dso__find_symbol(struct dso
*self
,
330 enum map_type type
, u64 addr
)
332 return symbols__find(&self
->symbols
[type
], addr
);
335 struct symbol
*dso__find_symbol_by_name(struct dso
*self
, enum map_type type
,
338 return symbols__find_by_name(&self
->symbol_names
[type
], name
);
341 void dso__sort_by_name(struct dso
*self
, enum map_type type
)
343 dso__set_sorted_by_name(self
, type
);
344 return symbols__sort_by_name(&self
->symbol_names
[type
],
345 &self
->symbols
[type
]);
348 int build_id__sprintf(u8
*self
, int len
, char *bf
)
354 for (i
= 0; i
< len
; ++i
) {
355 sprintf(bid
, "%02x", *raw
);
363 size_t dso__fprintf_buildid(struct dso
*self
, FILE *fp
)
365 char sbuild_id
[BUILD_ID_SIZE
* 2 + 1];
367 build_id__sprintf(self
->build_id
, sizeof(self
->build_id
), sbuild_id
);
368 return fprintf(fp
, "%s", sbuild_id
);
371 size_t dso__fprintf(struct dso
*self
, enum map_type type
, FILE *fp
)
374 size_t ret
= fprintf(fp
, "dso: %s (", self
->short_name
);
376 ret
+= dso__fprintf_buildid(self
, fp
);
377 ret
+= fprintf(fp
, ")\n");
378 for (nd
= rb_first(&self
->symbols
[type
]); nd
; nd
= rb_next(nd
)) {
379 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
380 ret
+= symbol__fprintf(pos
, fp
);
386 int kallsyms__parse(void *arg
, int (*process_symbol
)(void *arg
, const char *name
,
387 char type
, u64 start
))
392 FILE *file
= fopen("/proc/kallsyms", "r");
397 while (!feof(file
)) {
403 line_len
= getline(&line
, &n
, file
);
410 line
[--line_len
] = '\0'; /* \n */
412 len
= hex2u64(line
, &start
);
415 if (len
+ 2 >= line_len
)
418 symbol_type
= toupper(line
[len
]);
419 symbol_name
= line
+ len
+ 2;
421 err
= process_symbol(arg
, symbol_name
, symbol_type
, start
);
434 struct process_kallsyms_args
{
439 static int map__process_kallsym_symbol(void *arg
, const char *name
,
440 char type
, u64 start
)
443 struct process_kallsyms_args
*a
= arg
;
444 struct rb_root
*root
= &a
->dso
->symbols
[a
->map
->type
];
446 if (!symbol_type__is_a(type
, a
->map
->type
))
450 * Will fix up the end later, when we have all symbols sorted.
452 sym
= symbol__new(start
, 0, name
);
457 * We will pass the symbols to the filter later, in
458 * map__split_kallsyms, when we have split the maps per module
460 symbols__insert(root
, sym
);
465 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
466 * so that we can in the next step set the symbol ->end address and then
467 * call kernel_maps__split_kallsyms.
469 static int dso__load_all_kallsyms(struct dso
*self
, struct map
*map
)
471 struct process_kallsyms_args args
= { .map
= map
, .dso
= self
, };
472 return kallsyms__parse(&args
, map__process_kallsym_symbol
);
476 * Split the symbols into maps, making sure there are no overlaps, i.e. the
477 * kernel range is broken in several maps, named [kernel].N, as we don't have
478 * the original ELF section names vmlinux have.
480 static int dso__split_kallsyms(struct dso
*self
, struct map
*map
,
481 struct perf_session
*session
, symbol_filter_t filter
)
483 struct map
*curr_map
= map
;
486 struct rb_root
*root
= &self
->symbols
[map
->type
];
487 struct rb_node
*next
= rb_first(root
);
488 int kernel_range
= 0;
493 pos
= rb_entry(next
, struct symbol
, rb_node
);
494 next
= rb_next(&pos
->rb_node
);
496 module
= strchr(pos
->name
, '\t');
498 if (!symbol_conf
.use_modules
)
503 if (strcmp(self
->name
, module
)) {
504 curr_map
= map_groups__find_by_name(&session
->kmaps
, map
->type
, module
);
505 if (curr_map
== NULL
) {
506 pr_debug("/proc/{kallsyms,modules} "
512 * So that we look just like we get from .ko files,
513 * i.e. not prelinked, relative to map->start.
515 pos
->start
= curr_map
->map_ip(curr_map
, pos
->start
);
516 pos
->end
= curr_map
->map_ip(curr_map
, pos
->end
);
517 } else if (curr_map
!= map
) {
518 char dso_name
[PATH_MAX
];
521 snprintf(dso_name
, sizeof(dso_name
), "[kernel].%d",
524 dso
= dso__new(dso_name
);
528 curr_map
= map__new2(pos
->start
, dso
, map
->type
);
534 curr_map
->map_ip
= curr_map
->unmap_ip
= identity__map_ip
;
535 map_groups__insert(&session
->kmaps
, curr_map
);
539 if (filter
&& filter(curr_map
, pos
)) {
540 discard_symbol
: rb_erase(&pos
->rb_node
, root
);
543 if (curr_map
!= map
) {
544 rb_erase(&pos
->rb_node
, root
);
545 symbols__insert(&curr_map
->dso
->symbols
[curr_map
->type
], pos
);
555 static int dso__load_kallsyms(struct dso
*self
, struct map
*map
,
556 struct perf_session
*session
, symbol_filter_t filter
)
558 if (dso__load_all_kallsyms(self
, map
) < 0)
561 symbols__fixup_end(&self
->symbols
[map
->type
]);
562 self
->origin
= DSO__ORIG_KERNEL
;
564 return dso__split_kallsyms(self
, map
, session
, filter
);
567 static int dso__load_perf_map(struct dso
*self
, struct map
*map
,
568 symbol_filter_t filter
)
575 file
= fopen(self
->long_name
, "r");
579 while (!feof(file
)) {
584 line_len
= getline(&line
, &n
, file
);
591 line
[--line_len
] = '\0'; /* \n */
593 len
= hex2u64(line
, &start
);
596 if (len
+ 2 >= line_len
)
599 len
+= hex2u64(line
+ len
, &size
);
602 if (len
+ 2 >= line_len
)
605 sym
= symbol__new(start
, size
, line
+ len
);
608 goto out_delete_line
;
610 if (filter
&& filter(map
, sym
))
613 symbols__insert(&self
->symbols
[map
->type
], sym
);
630 * elf_symtab__for_each_symbol - iterate thru all the symbols
632 * @self: struct elf_symtab instance to iterate
634 * @sym: GElf_Sym iterator
636 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
637 for (idx = 0, gelf_getsym(syms, idx, &sym);\
639 idx++, gelf_getsym(syms, idx, &sym))
641 static inline uint8_t elf_sym__type(const GElf_Sym
*sym
)
643 return GELF_ST_TYPE(sym
->st_info
);
646 static inline int elf_sym__is_function(const GElf_Sym
*sym
)
648 return elf_sym__type(sym
) == STT_FUNC
&&
650 sym
->st_shndx
!= SHN_UNDEF
;
653 static inline bool elf_sym__is_object(const GElf_Sym
*sym
)
655 return elf_sym__type(sym
) == STT_OBJECT
&&
657 sym
->st_shndx
!= SHN_UNDEF
;
660 static inline int elf_sym__is_label(const GElf_Sym
*sym
)
662 return elf_sym__type(sym
) == STT_NOTYPE
&&
664 sym
->st_shndx
!= SHN_UNDEF
&&
665 sym
->st_shndx
!= SHN_ABS
;
668 static inline const char *elf_sec__name(const GElf_Shdr
*shdr
,
669 const Elf_Data
*secstrs
)
671 return secstrs
->d_buf
+ shdr
->sh_name
;
674 static inline int elf_sec__is_text(const GElf_Shdr
*shdr
,
675 const Elf_Data
*secstrs
)
677 return strstr(elf_sec__name(shdr
, secstrs
), "text") != NULL
;
680 static inline bool elf_sec__is_data(const GElf_Shdr
*shdr
,
681 const Elf_Data
*secstrs
)
683 return strstr(elf_sec__name(shdr
, secstrs
), "data") != NULL
;
686 static inline const char *elf_sym__name(const GElf_Sym
*sym
,
687 const Elf_Data
*symstrs
)
689 return symstrs
->d_buf
+ sym
->st_name
;
692 static Elf_Scn
*elf_section_by_name(Elf
*elf
, GElf_Ehdr
*ep
,
693 GElf_Shdr
*shp
, const char *name
,
699 while ((sec
= elf_nextscn(elf
, sec
)) != NULL
) {
702 gelf_getshdr(sec
, shp
);
703 str
= elf_strptr(elf
, ep
->e_shstrndx
, shp
->sh_name
);
704 if (!strcmp(name
, str
)) {
715 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
716 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
718 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
720 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
721 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
723 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
726 * We need to check if we have a .dynsym, so that we can handle the
727 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
728 * .dynsym or .symtab).
729 * And always look at the original dso, not at debuginfo packages, that
730 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
732 static int dso__synthesize_plt_symbols(struct dso
*self
, struct map
*map
,
733 symbol_filter_t filter
)
735 uint32_t nr_rel_entries
, idx
;
740 GElf_Shdr shdr_rel_plt
, shdr_dynsym
;
741 Elf_Data
*reldata
, *syms
, *symstrs
;
742 Elf_Scn
*scn_plt_rel
, *scn_symstrs
, *scn_dynsym
;
745 char sympltname
[1024];
747 int nr
= 0, symidx
, fd
, err
= 0;
749 fd
= open(self
->long_name
, O_RDONLY
);
753 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
757 if (gelf_getehdr(elf
, &ehdr
) == NULL
)
760 scn_dynsym
= elf_section_by_name(elf
, &ehdr
, &shdr_dynsym
,
761 ".dynsym", &dynsym_idx
);
762 if (scn_dynsym
== NULL
)
765 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
767 if (scn_plt_rel
== NULL
) {
768 scn_plt_rel
= elf_section_by_name(elf
, &ehdr
, &shdr_rel_plt
,
770 if (scn_plt_rel
== NULL
)
776 if (shdr_rel_plt
.sh_link
!= dynsym_idx
)
779 if (elf_section_by_name(elf
, &ehdr
, &shdr_plt
, ".plt", NULL
) == NULL
)
783 * Fetch the relocation section to find the idxes to the GOT
784 * and the symbols in the .dynsym they refer to.
786 reldata
= elf_getdata(scn_plt_rel
, NULL
);
790 syms
= elf_getdata(scn_dynsym
, NULL
);
794 scn_symstrs
= elf_getscn(elf
, shdr_dynsym
.sh_link
);
795 if (scn_symstrs
== NULL
)
798 symstrs
= elf_getdata(scn_symstrs
, NULL
);
802 nr_rel_entries
= shdr_rel_plt
.sh_size
/ shdr_rel_plt
.sh_entsize
;
803 plt_offset
= shdr_plt
.sh_offset
;
805 if (shdr_rel_plt
.sh_type
== SHT_RELA
) {
806 GElf_Rela pos_mem
, *pos
;
808 elf_section__for_each_rela(reldata
, pos
, pos_mem
, idx
,
810 symidx
= GELF_R_SYM(pos
->r_info
);
811 plt_offset
+= shdr_plt
.sh_entsize
;
812 gelf_getsym(syms
, symidx
, &sym
);
813 snprintf(sympltname
, sizeof(sympltname
),
814 "%s@plt", elf_sym__name(&sym
, symstrs
));
816 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
821 if (filter
&& filter(map
, f
))
824 symbols__insert(&self
->symbols
[map
->type
], f
);
828 } else if (shdr_rel_plt
.sh_type
== SHT_REL
) {
829 GElf_Rel pos_mem
, *pos
;
830 elf_section__for_each_rel(reldata
, pos
, pos_mem
, idx
,
832 symidx
= GELF_R_SYM(pos
->r_info
);
833 plt_offset
+= shdr_plt
.sh_entsize
;
834 gelf_getsym(syms
, symidx
, &sym
);
835 snprintf(sympltname
, sizeof(sympltname
),
836 "%s@plt", elf_sym__name(&sym
, symstrs
));
838 f
= symbol__new(plt_offset
, shdr_plt
.sh_entsize
,
843 if (filter
&& filter(map
, f
))
846 symbols__insert(&self
->symbols
[map
->type
], f
);
861 pr_warning("%s: problems reading %s PLT info.\n",
862 __func__
, self
->long_name
);
866 static bool elf_sym__is_a(GElf_Sym
*self
, enum map_type type
)
870 return elf_sym__is_function(self
);
872 return elf_sym__is_object(self
);
878 static bool elf_sec__is_a(GElf_Shdr
*self
, Elf_Data
*secstrs
, enum map_type type
)
882 return elf_sec__is_text(self
, secstrs
);
884 return elf_sec__is_data(self
, secstrs
);
890 static int dso__load_sym(struct dso
*self
, struct map
*map
,
891 struct perf_session
*session
, const char *name
, int fd
,
892 symbol_filter_t filter
, int kernel
, int kmodule
)
894 struct map
*curr_map
= map
;
895 struct dso
*curr_dso
= self
;
896 size_t dso_name_len
= strlen(self
->short_name
);
897 Elf_Data
*symstrs
, *secstrs
;
905 Elf_Scn
*sec
, *sec_strndx
;
909 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
911 pr_err("%s: cannot read %s ELF file.\n", __func__
, name
);
915 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
916 pr_err("%s: cannot get elf header.\n", __func__
);
920 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".symtab", NULL
);
922 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
, ".dynsym", NULL
);
927 syms
= elf_getdata(sec
, NULL
);
931 sec
= elf_getscn(elf
, shdr
.sh_link
);
935 symstrs
= elf_getdata(sec
, NULL
);
939 sec_strndx
= elf_getscn(elf
, ehdr
.e_shstrndx
);
940 if (sec_strndx
== NULL
)
943 secstrs
= elf_getdata(sec_strndx
, NULL
);
947 nr_syms
= shdr
.sh_size
/ shdr
.sh_entsize
;
949 memset(&sym
, 0, sizeof(sym
));
951 self
->adjust_symbols
= (ehdr
.e_type
== ET_EXEC
||
952 elf_section_by_name(elf
, &ehdr
, &shdr
,
955 } else self
->adjust_symbols
= 0;
957 elf_symtab__for_each_symbol(syms
, nr_syms
, idx
, sym
) {
959 const char *elf_name
= elf_sym__name(&sym
, symstrs
);
960 char *demangled
= NULL
;
961 int is_label
= elf_sym__is_label(&sym
);
962 const char *section_name
;
964 if (kernel
&& session
->ref_reloc_sym
.name
!= NULL
&&
965 strcmp(elf_name
, session
->ref_reloc_sym
.name
) == 0)
966 perf_session__reloc_vmlinux_maps(session
, sym
.st_value
);
968 if (!is_label
&& !elf_sym__is_a(&sym
, map
->type
))
971 sec
= elf_getscn(elf
, sym
.st_shndx
);
975 gelf_getshdr(sec
, &shdr
);
977 if (is_label
&& !elf_sec__is_a(&shdr
, secstrs
, map
->type
))
980 section_name
= elf_sec__name(&shdr
, secstrs
);
982 if (kernel
|| kmodule
) {
983 char dso_name
[PATH_MAX
];
985 if (strcmp(section_name
,
986 curr_dso
->short_name
+ dso_name_len
) == 0)
989 if (strcmp(section_name
, ".text") == 0) {
995 snprintf(dso_name
, sizeof(dso_name
),
996 "%s%s", self
->short_name
, section_name
);
998 curr_map
= map_groups__find_by_name(&session
->kmaps
, map
->type
, dso_name
);
999 if (curr_map
== NULL
) {
1000 u64 start
= sym
.st_value
;
1003 start
+= map
->start
+ shdr
.sh_offset
;
1005 curr_dso
= dso__new(dso_name
);
1006 if (curr_dso
== NULL
)
1008 curr_map
= map__new2(start
, curr_dso
,
1010 if (curr_map
== NULL
) {
1011 dso__delete(curr_dso
);
1014 curr_map
->map_ip
= identity__map_ip
;
1015 curr_map
->unmap_ip
= identity__map_ip
;
1016 curr_dso
->origin
= DSO__ORIG_KERNEL
;
1017 map_groups__insert(&session
->kmaps
, curr_map
);
1018 dsos__add(&dsos__kernel
, curr_dso
);
1020 curr_dso
= curr_map
->dso
;
1025 if (curr_dso
->adjust_symbols
) {
1026 pr_debug2("adjusting symbol: st_value: %Lx sh_addr: "
1027 "%Lx sh_offset: %Lx\n", (u64
)sym
.st_value
,
1028 (u64
)shdr
.sh_addr
, (u64
)shdr
.sh_offset
);
1029 sym
.st_value
-= shdr
.sh_addr
- shdr
.sh_offset
;
1032 * We need to figure out if the object was created from C++ sources
1033 * DWARF DW_compile_unit has this, but we don't always have access
1036 demangled
= bfd_demangle(NULL
, elf_name
, DMGL_PARAMS
| DMGL_ANSI
);
1037 if (demangled
!= NULL
)
1038 elf_name
= demangled
;
1040 f
= symbol__new(sym
.st_value
, sym
.st_size
, elf_name
);
1045 if (filter
&& filter(curr_map
, f
))
1048 symbols__insert(&curr_dso
->symbols
[curr_map
->type
], f
);
1054 * For misannotated, zeroed, ASM function sizes.
1057 symbols__fixup_end(&self
->symbols
[map
->type
]);
1065 static bool dso__build_id_equal(const struct dso
*self
, u8
*build_id
)
1067 return memcmp(self
->build_id
, build_id
, sizeof(self
->build_id
)) == 0;
1070 static bool __dsos__read_build_ids(struct list_head
*head
)
1072 bool have_build_id
= false;
1075 list_for_each_entry(pos
, head
, node
)
1076 if (filename__read_build_id(pos
->long_name
, pos
->build_id
,
1077 sizeof(pos
->build_id
)) > 0) {
1078 have_build_id
= true;
1079 pos
->has_build_id
= true;
1082 return have_build_id
;
1085 bool dsos__read_build_ids(void)
1087 bool kbuildids
= __dsos__read_build_ids(&dsos__kernel
),
1088 ubuildids
= __dsos__read_build_ids(&dsos__user
);
1089 return kbuildids
|| ubuildids
;
1093 * Align offset to 4 bytes as needed for note name and descriptor data.
1095 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
1097 int filename__read_build_id(const char *filename
, void *bf
, size_t size
)
1108 if (size
< BUILD_ID_SIZE
)
1111 fd
= open(filename
, O_RDONLY
);
1115 elf
= elf_begin(fd
, PERF_ELF_C_READ_MMAP
, NULL
);
1117 pr_debug2("%s: cannot read %s ELF file.\n", __func__
, filename
);
1122 if (ek
!= ELF_K_ELF
)
1125 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
1126 pr_err("%s: cannot get elf header.\n", __func__
);
1130 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
,
1131 ".note.gnu.build-id", NULL
);
1133 sec
= elf_section_by_name(elf
, &ehdr
, &shdr
,
1139 data
= elf_getdata(sec
, NULL
);
1144 while (ptr
< (data
->d_buf
+ data
->d_size
)) {
1145 GElf_Nhdr
*nhdr
= ptr
;
1146 int namesz
= NOTE_ALIGN(nhdr
->n_namesz
),
1147 descsz
= NOTE_ALIGN(nhdr
->n_descsz
);
1150 ptr
+= sizeof(*nhdr
);
1153 if (nhdr
->n_type
== NT_GNU_BUILD_ID
&&
1154 nhdr
->n_namesz
== sizeof("GNU")) {
1155 if (memcmp(name
, "GNU", sizeof("GNU")) == 0) {
1156 memcpy(bf
, ptr
, BUILD_ID_SIZE
);
1157 err
= BUILD_ID_SIZE
;
1171 int sysfs__read_build_id(const char *filename
, void *build_id
, size_t size
)
1175 if (size
< BUILD_ID_SIZE
)
1178 fd
= open(filename
, O_RDONLY
);
1187 if (read(fd
, &nhdr
, sizeof(nhdr
)) != sizeof(nhdr
))
1190 namesz
= NOTE_ALIGN(nhdr
.n_namesz
);
1191 descsz
= NOTE_ALIGN(nhdr
.n_descsz
);
1192 if (nhdr
.n_type
== NT_GNU_BUILD_ID
&&
1193 nhdr
.n_namesz
== sizeof("GNU")) {
1194 if (read(fd
, bf
, namesz
) != namesz
)
1196 if (memcmp(bf
, "GNU", sizeof("GNU")) == 0) {
1197 if (read(fd
, build_id
,
1198 BUILD_ID_SIZE
) == BUILD_ID_SIZE
) {
1202 } else if (read(fd
, bf
, descsz
) != descsz
)
1205 int n
= namesz
+ descsz
;
1206 if (read(fd
, bf
, n
) != n
)
1215 char dso__symtab_origin(const struct dso
*self
)
1217 static const char origin
[] = {
1218 [DSO__ORIG_KERNEL
] = 'k',
1219 [DSO__ORIG_JAVA_JIT
] = 'j',
1220 [DSO__ORIG_BUILD_ID_CACHE
] = 'B',
1221 [DSO__ORIG_FEDORA
] = 'f',
1222 [DSO__ORIG_UBUNTU
] = 'u',
1223 [DSO__ORIG_BUILDID
] = 'b',
1224 [DSO__ORIG_DSO
] = 'd',
1225 [DSO__ORIG_KMODULE
] = 'K',
1228 if (self
== NULL
|| self
->origin
== DSO__ORIG_NOT_FOUND
)
1230 return origin
[self
->origin
];
1233 int dso__load(struct dso
*self
, struct map
*map
, struct perf_session
*session
,
1234 symbol_filter_t filter
)
1236 int size
= PATH_MAX
;
1238 u8 build_id
[BUILD_ID_SIZE
];
1239 char build_id_hex
[BUILD_ID_SIZE
* 2 + 1];
1243 dso__set_loaded(self
, map
->type
);
1246 return dso__load_kernel_sym(self
, map
, session
, filter
);
1248 name
= malloc(size
);
1252 self
->adjust_symbols
= 0;
1254 if (strncmp(self
->name
, "/tmp/perf-", 10) == 0) {
1255 ret
= dso__load_perf_map(self
, map
, filter
);
1256 self
->origin
= ret
> 0 ? DSO__ORIG_JAVA_JIT
:
1257 DSO__ORIG_NOT_FOUND
;
1261 self
->origin
= DSO__ORIG_BUILD_ID_CACHE
;
1263 if (self
->has_build_id
) {
1264 build_id__sprintf(self
->build_id
, sizeof(self
->build_id
),
1266 snprintf(name
, size
, "%s/%s/.build-id/%.2s/%s",
1267 getenv("HOME"), DEBUG_CACHE_DIR
,
1268 build_id_hex
, build_id_hex
+ 2);
1274 switch (self
->origin
) {
1275 case DSO__ORIG_FEDORA
:
1276 snprintf(name
, size
, "/usr/lib/debug%s.debug",
1279 case DSO__ORIG_UBUNTU
:
1280 snprintf(name
, size
, "/usr/lib/debug%s",
1283 case DSO__ORIG_BUILDID
:
1284 if (filename__read_build_id(self
->long_name
, build_id
,
1285 sizeof(build_id
))) {
1286 build_id__sprintf(build_id
, sizeof(build_id
),
1288 snprintf(name
, size
,
1289 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1290 build_id_hex
, build_id_hex
+ 2);
1291 if (self
->has_build_id
)
1292 goto compare_build_id
;
1298 snprintf(name
, size
, "%s", self
->long_name
);
1305 if (self
->has_build_id
) {
1306 if (filename__read_build_id(name
, build_id
,
1307 sizeof(build_id
)) < 0)
1310 if (!dso__build_id_equal(self
, build_id
))
1314 fd
= open(name
, O_RDONLY
);
1317 ret
= dso__load_sym(self
, map
, NULL
, name
, fd
, filter
, 0, 0);
1321 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1327 int nr_plt
= dso__synthesize_plt_symbols(self
, map
, filter
);
1333 if (ret
< 0 && strstr(self
->name
, " (deleted)") != NULL
)
1338 struct map
*map_groups__find_by_name(struct map_groups
*self
,
1339 enum map_type type
, const char *name
)
1343 for (nd
= rb_first(&self
->maps
[type
]); nd
; nd
= rb_next(nd
)) {
1344 struct map
*map
= rb_entry(nd
, struct map
, rb_node
);
1346 if (map
->dso
&& strcmp(map
->dso
->name
, name
) == 0)
1353 static int perf_session__set_modules_path_dir(struct perf_session
*self
, char *dirname
)
1355 struct dirent
*dent
;
1356 DIR *dir
= opendir(dirname
);
1359 pr_debug("%s: cannot open %s dir\n", __func__
, dirname
);
1363 while ((dent
= readdir(dir
)) != NULL
) {
1364 char path
[PATH_MAX
];
1366 if (dent
->d_type
== DT_DIR
) {
1367 if (!strcmp(dent
->d_name
, ".") ||
1368 !strcmp(dent
->d_name
, ".."))
1371 snprintf(path
, sizeof(path
), "%s/%s",
1372 dirname
, dent
->d_name
);
1373 if (perf_session__set_modules_path_dir(self
, path
) < 0)
1376 char *dot
= strrchr(dent
->d_name
, '.'),
1381 if (dot
== NULL
|| strcmp(dot
, ".ko"))
1383 snprintf(dso_name
, sizeof(dso_name
), "[%.*s]",
1384 (int)(dot
- dent
->d_name
), dent
->d_name
);
1386 strxfrchar(dso_name
, '-', '_');
1387 map
= map_groups__find_by_name(&self
->kmaps
, MAP__FUNCTION
, dso_name
);
1391 snprintf(path
, sizeof(path
), "%s/%s",
1392 dirname
, dent
->d_name
);
1394 long_name
= strdup(path
);
1395 if (long_name
== NULL
)
1397 dso__set_long_name(map
->dso
, long_name
);
1407 static int perf_session__set_modules_path(struct perf_session
*self
)
1410 char modules_path
[PATH_MAX
];
1412 if (uname(&uts
) < 0)
1415 snprintf(modules_path
, sizeof(modules_path
), "/lib/modules/%s/kernel",
1418 return perf_session__set_modules_path_dir(self
, modules_path
);
1422 * Constructor variant for modules (where we know from /proc/modules where
1423 * they are loaded) and for vmlinux, where only after we load all the
1424 * symbols we'll know where it starts and ends.
1426 static struct map
*map__new2(u64 start
, struct dso
*dso
, enum map_type type
)
1428 struct map
*self
= malloc(sizeof(*self
));
1432 * ->end will be filled after we load all the symbols
1434 map__init(self
, type
, start
, 0, 0, dso
);
1440 static int perf_session__create_module_maps(struct perf_session
*self
)
1444 FILE *file
= fopen("/proc/modules", "r");
1450 while (!feof(file
)) {
1451 char name
[PATH_MAX
];
1457 line_len
= getline(&line
, &n
, file
);
1464 line
[--line_len
] = '\0'; /* \n */
1466 sep
= strrchr(line
, 'x');
1470 hex2u64(sep
+ 1, &start
);
1472 sep
= strchr(line
, ' ');
1478 snprintf(name
, sizeof(name
), "[%s]", line
);
1479 dso
= dso__new(name
);
1482 goto out_delete_line
;
1484 map
= map__new2(start
, dso
, MAP__FUNCTION
);
1487 goto out_delete_line
;
1490 snprintf(name
, sizeof(name
),
1491 "/sys/module/%s/notes/.note.gnu.build-id", line
);
1492 if (sysfs__read_build_id(name
, dso
->build_id
,
1493 sizeof(dso
->build_id
)) == 0)
1494 dso
->has_build_id
= true;
1496 dso
->origin
= DSO__ORIG_KMODULE
;
1497 map_groups__insert(&self
->kmaps
, map
);
1498 dsos__add(&dsos__kernel
, dso
);
1504 return perf_session__set_modules_path(self
);
1512 static int dso__load_vmlinux(struct dso
*self
, struct map
*map
,
1513 struct perf_session
*session
,
1514 const char *vmlinux
, symbol_filter_t filter
)
1518 if (self
->has_build_id
) {
1519 u8 build_id
[BUILD_ID_SIZE
];
1521 if (filename__read_build_id(vmlinux
, build_id
,
1522 sizeof(build_id
)) < 0) {
1523 pr_debug("No build_id in %s, ignoring it\n", vmlinux
);
1526 if (!dso__build_id_equal(self
, build_id
)) {
1527 char expected_build_id
[BUILD_ID_SIZE
* 2 + 1],
1528 vmlinux_build_id
[BUILD_ID_SIZE
* 2 + 1];
1530 build_id__sprintf(self
->build_id
,
1531 sizeof(self
->build_id
),
1533 build_id__sprintf(build_id
, sizeof(build_id
),
1535 pr_debug("build_id in %s is %s while expected is %s, "
1536 "ignoring it\n", vmlinux
, vmlinux_build_id
,
1542 fd
= open(vmlinux
, O_RDONLY
);
1546 dso__set_loaded(self
, map
->type
);
1547 err
= dso__load_sym(self
, map
, session
, self
->long_name
, fd
, filter
, 1, 0);
1553 static int dso__load_kernel_sym(struct dso
*self
, struct map
*map
,
1554 struct perf_session
*session
, symbol_filter_t filter
)
1559 if (vmlinux_path
!= NULL
) {
1561 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1562 vmlinux_path__nr_entries
);
1563 for (i
= 0; i
< vmlinux_path__nr_entries
; ++i
) {
1564 err
= dso__load_vmlinux(self
, map
, session
,
1565 vmlinux_path
[i
], filter
);
1567 pr_debug("Using %s for symbols\n",
1569 dso__set_long_name(self
,
1570 strdup(vmlinux_path
[i
]));
1576 is_kallsyms
= self
->long_name
[0] == '[';
1580 err
= dso__load_vmlinux(self
, map
, session
, self
->long_name
, filter
);
1582 pr_info("The file %s cannot be used, "
1583 "trying to use /proc/kallsyms...", self
->long_name
);
1585 err
= dso__load_kallsyms(self
, map
, session
, filter
);
1586 if (err
> 0 && !is_kallsyms
)
1587 dso__set_long_name(self
, strdup("[kernel.kallsyms]"));
1592 map__fixup_start(map
);
1593 map__fixup_end(map
);
1599 LIST_HEAD(dsos__user
);
1600 LIST_HEAD(dsos__kernel
);
1603 static void dsos__add(struct list_head
*head
, struct dso
*dso
)
1605 list_add_tail(&dso
->node
, head
);
1608 static struct dso
*dsos__find(struct list_head
*head
, const char *name
)
1612 list_for_each_entry(pos
, head
, node
)
1613 if (strcmp(pos
->name
, name
) == 0)
1618 struct dso
*dsos__findnew(const char *name
)
1620 struct dso
*dso
= dsos__find(&dsos__user
, name
);
1623 dso
= dso__new(name
);
1625 dsos__add(&dsos__user
, dso
);
1626 dso__set_basename(dso
);
1633 static void __dsos__fprintf(struct list_head
*head
, FILE *fp
)
1637 list_for_each_entry(pos
, head
, node
) {
1639 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
1640 dso__fprintf(pos
, i
, fp
);
1644 void dsos__fprintf(FILE *fp
)
1646 __dsos__fprintf(&dsos__kernel
, fp
);
1647 __dsos__fprintf(&dsos__user
, fp
);
1650 static size_t __dsos__fprintf_buildid(struct list_head
*head
, FILE *fp
)
1655 list_for_each_entry(pos
, head
, node
) {
1656 ret
+= dso__fprintf_buildid(pos
, fp
);
1657 ret
+= fprintf(fp
, " %s\n", pos
->long_name
);
1662 size_t dsos__fprintf_buildid(FILE *fp
)
1664 return (__dsos__fprintf_buildid(&dsos__kernel
, fp
) +
1665 __dsos__fprintf_buildid(&dsos__user
, fp
));
1668 static struct dso
*dsos__create_kernel(const char *vmlinux
)
1670 struct dso
*kernel
= dso__new(vmlinux
?: "[kernel.kallsyms]");
1675 kernel
->short_name
= "[kernel]";
1678 vdso
= dso__new("[vdso]");
1680 goto out_delete_kernel_dso
;
1681 dso__set_loaded(vdso
, MAP__FUNCTION
);
1683 if (sysfs__read_build_id("/sys/kernel/notes", kernel
->build_id
,
1684 sizeof(kernel
->build_id
)) == 0)
1685 kernel
->has_build_id
= true;
1687 dsos__add(&dsos__kernel
, kernel
);
1688 dsos__add(&dsos__user
, vdso
);
1692 out_delete_kernel_dso
:
1693 dso__delete(kernel
);
1697 static int map_groups__create_kernel_maps(struct map_groups
*self
,
1698 struct map
*vmlinux_maps
[MAP__NR_TYPES
],
1699 const char *vmlinux
)
1701 struct dso
*kernel
= dsos__create_kernel(vmlinux
);
1707 for (type
= 0; type
< MAP__NR_TYPES
; ++type
) {
1708 vmlinux_maps
[type
] = map__new2(0, kernel
, type
);
1709 if (vmlinux_maps
[type
] == NULL
)
1712 vmlinux_maps
[type
]->map_ip
=
1713 vmlinux_maps
[type
]->unmap_ip
= identity__map_ip
;
1714 map_groups__insert(self
, vmlinux_maps
[type
]);
1720 static void vmlinux_path__exit(void)
1722 while (--vmlinux_path__nr_entries
>= 0) {
1723 free(vmlinux_path
[vmlinux_path__nr_entries
]);
1724 vmlinux_path
[vmlinux_path__nr_entries
] = NULL
;
1728 vmlinux_path
= NULL
;
1731 static int vmlinux_path__init(void)
1736 if (uname(&uts
) < 0)
1739 vmlinux_path
= malloc(sizeof(char *) * 5);
1740 if (vmlinux_path
== NULL
)
1743 vmlinux_path
[vmlinux_path__nr_entries
] = strdup("vmlinux");
1744 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
1746 ++vmlinux_path__nr_entries
;
1747 vmlinux_path
[vmlinux_path__nr_entries
] = strdup("/boot/vmlinux");
1748 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
1750 ++vmlinux_path__nr_entries
;
1751 snprintf(bf
, sizeof(bf
), "/boot/vmlinux-%s", uts
.release
);
1752 vmlinux_path
[vmlinux_path__nr_entries
] = strdup(bf
);
1753 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
1755 ++vmlinux_path__nr_entries
;
1756 snprintf(bf
, sizeof(bf
), "/lib/modules/%s/build/vmlinux", uts
.release
);
1757 vmlinux_path
[vmlinux_path__nr_entries
] = strdup(bf
);
1758 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
1760 ++vmlinux_path__nr_entries
;
1761 snprintf(bf
, sizeof(bf
), "/usr/lib/debug/lib/modules/%s/vmlinux",
1763 vmlinux_path
[vmlinux_path__nr_entries
] = strdup(bf
);
1764 if (vmlinux_path
[vmlinux_path__nr_entries
] == NULL
)
1766 ++vmlinux_path__nr_entries
;
1771 vmlinux_path__exit();
1775 static int setup_list(struct strlist
**list
, const char *list_str
,
1776 const char *list_name
)
1778 if (list_str
== NULL
)
1781 *list
= strlist__new(true, list_str
);
1783 pr_err("problems parsing %s list\n", list_name
);
1789 int symbol__init(void)
1791 elf_version(EV_CURRENT
);
1792 if (symbol_conf
.sort_by_name
)
1793 symbol_conf
.priv_size
+= (sizeof(struct symbol_name_rb_node
) -
1794 sizeof(struct symbol
));
1796 if (symbol_conf
.try_vmlinux_path
&& vmlinux_path__init() < 0)
1799 if (symbol_conf
.field_sep
&& *symbol_conf
.field_sep
== '.') {
1800 pr_err("'.' is the only non valid --field-separator argument\n");
1804 if (setup_list(&symbol_conf
.dso_list
,
1805 symbol_conf
.dso_list_str
, "dso") < 0)
1808 if (setup_list(&symbol_conf
.comm_list
,
1809 symbol_conf
.comm_list_str
, "comm") < 0)
1810 goto out_free_dso_list
;
1812 if (setup_list(&symbol_conf
.sym_list
,
1813 symbol_conf
.sym_list_str
, "symbol") < 0)
1814 goto out_free_comm_list
;
1819 strlist__delete(symbol_conf
.dso_list
);
1821 strlist__delete(symbol_conf
.comm_list
);
1825 int perf_session__create_kernel_maps(struct perf_session
*self
)
1827 if (map_groups__create_kernel_maps(&self
->kmaps
, self
->vmlinux_maps
,
1828 symbol_conf
.vmlinux_name
) < 0)
1831 if (symbol_conf
.use_modules
&&
1832 perf_session__create_module_maps(self
) < 0)
1833 pr_debug("Failed to load list of modules for session %s, "
1834 "continuing...\n", self
->filename
);
1836 * Now that we have all the maps created, just set the ->end of them:
1838 map_groups__fixup_end(&self
->kmaps
);