14 #include <sys/utsname.h>
16 #ifndef NT_GNU_BUILD_ID
17 #define NT_GNU_BUILD_ID 3
31 static void dsos__add(struct list_head *head, struct dso *dso);
32 static struct map *thread__find_map_by_name(struct thread *self, char *name);
33 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
34 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
35 static int dso__load_kernel_sym(struct dso *self, struct map *map,
36 struct thread *thread, symbol_filter_t filter);
37 unsigned int symbol__priv_size;
38 static int vmlinux_path__nr_entries;
39 static char **vmlinux_path;
41 static struct symbol_conf symbol_conf__defaults = {
43 .try_vmlinux_path = true,
46 static struct thread kthread_mem, *kthread = &kthread_mem;
48 bool dso__loaded(const struct dso *self, enum map_type type)
50 return self->loaded & (1 << type);
53 static void dso__set_loaded(struct dso *self, enum map_type type)
55 self->loaded |= (1 << type);
58 static void symbols__fixup_end(struct rb_root *self)
60 struct rb_node *nd, *prevnd = rb_first(self);
61 struct symbol *curr, *prev;
66 curr = rb_entry(prevnd, struct symbol, rb_node);
68 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
70 curr = rb_entry(nd, struct symbol, rb_node);
72 if (prev->end == prev->start)
73 prev->end = curr->start - 1;
77 if (curr->end == curr->start)
78 curr->end = roundup(curr->start, 4096);
81 static void __thread__fixup_maps_end(struct thread *self, enum map_type type)
83 struct map *prev, *curr;
84 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
89 curr = rb_entry(prevnd, struct map, rb_node);
91 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
93 curr = rb_entry(nd, struct map, rb_node);
94 prev->end = curr->start - 1;
98 * We still haven't the actual symbols, so guess the
99 * last map final address.
104 static void thread__fixup_maps_end(struct thread *self)
107 for (i = 0; i < MAP__NR_TYPES; ++i)
108 __thread__fixup_maps_end(self, i);
111 static struct symbol *symbol__new(u64 start, u64 len, const char *name)
113 size_t namelen = strlen(name) + 1;
114 struct symbol *self = zalloc(symbol__priv_size +
115 sizeof(*self) + namelen);
119 if (symbol__priv_size)
120 self = ((void *)self) + symbol__priv_size;
123 self->end = len ? start + len - 1 : start;
125 pr_debug3("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
127 memcpy(self->name, name, namelen);
132 static void symbol__delete(struct symbol *self)
134 free(((void *)self) - symbol__priv_size);
137 static size_t symbol__fprintf(struct symbol *self, FILE *fp)
139 return fprintf(fp, " %llx-%llx %s\n",
140 self->start, self->end, self->name);
143 static void dso__set_long_name(struct dso *self, char *name)
147 self->long_name = name;
148 self->long_name_len = strlen(name);
151 static void dso__set_basename(struct dso *self)
153 self->short_name = basename(self->long_name);
156 struct dso *dso__new(const char *name)
158 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
162 strcpy(self->name, name);
163 dso__set_long_name(self, self->name);
164 self->short_name = self->name;
165 for (i = 0; i < MAP__NR_TYPES; ++i)
166 self->symbols[i] = RB_ROOT;
167 self->find_symbol = dso__find_symbol;
168 self->slen_calculated = 0;
169 self->origin = DSO__ORIG_NOT_FOUND;
171 self->has_build_id = 0;
177 static void symbols__delete(struct rb_root *self)
180 struct rb_node *next = rb_first(self);
183 pos = rb_entry(next, struct symbol, rb_node);
184 next = rb_next(&pos->rb_node);
185 rb_erase(&pos->rb_node, self);
190 void dso__delete(struct dso *self)
193 for (i = 0; i < MAP__NR_TYPES; ++i)
194 symbols__delete(&self->symbols[i]);
195 if (self->long_name != self->name)
196 free(self->long_name);
200 void dso__set_build_id(struct dso *self, void *build_id)
202 memcpy(self->build_id, build_id, sizeof(self->build_id));
203 self->has_build_id = 1;
206 static void symbols__insert(struct rb_root *self, struct symbol *sym)
208 struct rb_node **p = &self->rb_node;
209 struct rb_node *parent = NULL;
210 const u64 ip = sym->start;
215 s = rb_entry(parent, struct symbol, rb_node);
221 rb_link_node(&sym->rb_node, parent, p);
222 rb_insert_color(&sym->rb_node, self);
225 static struct symbol *symbols__find(struct rb_root *self, u64 ip)
235 struct symbol *s = rb_entry(n, struct symbol, rb_node);
239 else if (ip > s->end)
248 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr)
250 return symbols__find(&self->symbols[type], addr);
253 int build_id__sprintf(u8 *self, int len, char *bf)
259 for (i = 0; i < len; ++i) {
260 sprintf(bid, "%02x", *raw);
268 size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
270 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
272 build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
273 return fprintf(fp, "%s", sbuild_id);
276 size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
279 size_t ret = fprintf(fp, "dso: %s (", self->short_name);
281 ret += dso__fprintf_buildid(self, fp);
282 ret += fprintf(fp, ")\n");
283 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
284 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
285 ret += symbol__fprintf(pos, fp);
292 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
293 * so that we can in the next step set the symbol ->end address and then
294 * call kernel_maps__split_kallsyms.
296 static int dso__load_all_kallsyms(struct dso *self, struct map *map)
300 struct rb_root *root = &self->symbols[map->type];
301 FILE *file = fopen("/proc/kallsyms", "r");
306 while (!feof(file)) {
313 line_len = getline(&line, &n, file);
320 line[--line_len] = '\0'; /* \n */
322 len = hex2u64(line, &start);
325 if (len + 2 >= line_len)
328 symbol_type = toupper(line[len]);
330 * We're interested only in code ('T'ext)
332 if (symbol_type != 'T' && symbol_type != 'W')
335 symbol_name = line + len + 2;
337 * Will fix up the end later, when we have all symbols sorted.
339 sym = symbol__new(start, 0, symbol_name);
342 goto out_delete_line;
344 * We will pass the symbols to the filter later, in
345 * map__split_kallsyms, when we have split the maps per module
347 symbols__insert(root, sym);
362 * Split the symbols into maps, making sure there are no overlaps, i.e. the
363 * kernel range is broken in several maps, named [kernel].N, as we don't have
364 * the original ELF section names vmlinux have.
366 static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread *thread,
367 symbol_filter_t filter)
369 struct map *curr_map = map;
372 struct rb_root *root = &self->symbols[map->type];
373 struct rb_node *next = rb_first(root);
374 int kernel_range = 0;
379 pos = rb_entry(next, struct symbol, rb_node);
380 next = rb_next(&pos->rb_node);
382 module = strchr(pos->name, '\t');
384 if (!thread->use_modules)
389 if (strcmp(self->name, module)) {
390 curr_map = thread__find_map_by_name(thread, module);
391 if (curr_map == NULL) {
392 pr_debug("/proc/{kallsyms,modules} "
398 * So that we look just like we get from .ko files,
399 * i.e. not prelinked, relative to map->start.
401 pos->start = curr_map->map_ip(curr_map, pos->start);
402 pos->end = curr_map->map_ip(curr_map, pos->end);
403 } else if (curr_map != map) {
404 char dso_name[PATH_MAX];
407 snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
410 dso = dso__new(dso_name);
414 curr_map = map__new2(pos->start, dso, map->type);
420 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
421 __thread__insert_map(thread, curr_map);
425 if (filter && filter(curr_map, pos)) {
426 discard_symbol: rb_erase(&pos->rb_node, root);
429 if (curr_map != map) {
430 rb_erase(&pos->rb_node, root);
431 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
441 static int dso__load_kallsyms(struct dso *self, struct map *map,
442 struct thread *thread, symbol_filter_t filter)
444 if (dso__load_all_kallsyms(self, map) < 0)
447 symbols__fixup_end(&self->symbols[map->type]);
448 self->origin = DSO__ORIG_KERNEL;
450 return dso__split_kallsyms(self, map, thread, filter);
453 size_t kernel_maps__fprintf(FILE *fp)
455 size_t printed = fprintf(fp, "Kernel maps:\n");
456 printed += thread__fprintf_maps(kthread, fp);
457 return printed + fprintf(fp, "END kernel maps\n");
460 static int dso__load_perf_map(struct dso *self, struct map *map,
461 symbol_filter_t filter)
468 file = fopen(self->long_name, "r");
472 while (!feof(file)) {
477 line_len = getline(&line, &n, file);
484 line[--line_len] = '\0'; /* \n */
486 len = hex2u64(line, &start);
489 if (len + 2 >= line_len)
492 len += hex2u64(line + len, &size);
495 if (len + 2 >= line_len)
498 sym = symbol__new(start, size, line + len);
501 goto out_delete_line;
503 if (filter && filter(map, sym))
506 symbols__insert(&self->symbols[map->type], sym);
523 * elf_symtab__for_each_symbol - iterate thru all the symbols
525 * @self: struct elf_symtab instance to iterate
527 * @sym: GElf_Sym iterator
529 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
530 for (idx = 0, gelf_getsym(syms, idx, &sym);\
532 idx++, gelf_getsym(syms, idx, &sym))
534 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
536 return GELF_ST_TYPE(sym->st_info);
539 static inline int elf_sym__is_function(const GElf_Sym *sym)
541 return elf_sym__type(sym) == STT_FUNC &&
543 sym->st_shndx != SHN_UNDEF;
546 static inline int elf_sym__is_label(const GElf_Sym *sym)
548 return elf_sym__type(sym) == STT_NOTYPE &&
550 sym->st_shndx != SHN_UNDEF &&
551 sym->st_shndx != SHN_ABS;
554 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
555 const Elf_Data *secstrs)
557 return secstrs->d_buf + shdr->sh_name;
560 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
561 const Elf_Data *secstrs)
563 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
566 static inline const char *elf_sym__name(const GElf_Sym *sym,
567 const Elf_Data *symstrs)
569 return symstrs->d_buf + sym->st_name;
572 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
573 GElf_Shdr *shp, const char *name,
579 while ((sec = elf_nextscn(elf, sec)) != NULL) {
582 gelf_getshdr(sec, shp);
583 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
584 if (!strcmp(name, str)) {
595 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
596 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
598 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
600 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
601 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
603 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
606 * We need to check if we have a .dynsym, so that we can handle the
607 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
608 * .dynsym or .symtab).
609 * And always look at the original dso, not at debuginfo packages, that
610 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
612 static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
613 symbol_filter_t filter)
615 uint32_t nr_rel_entries, idx;
620 GElf_Shdr shdr_rel_plt, shdr_dynsym;
621 Elf_Data *reldata, *syms, *symstrs;
622 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
625 char sympltname[1024];
627 int nr = 0, symidx, fd, err = 0;
629 fd = open(self->long_name, O_RDONLY);
633 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
637 if (gelf_getehdr(elf, &ehdr) == NULL)
640 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
641 ".dynsym", &dynsym_idx);
642 if (scn_dynsym == NULL)
645 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
647 if (scn_plt_rel == NULL) {
648 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
650 if (scn_plt_rel == NULL)
656 if (shdr_rel_plt.sh_link != dynsym_idx)
659 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
663 * Fetch the relocation section to find the idxes to the GOT
664 * and the symbols in the .dynsym they refer to.
666 reldata = elf_getdata(scn_plt_rel, NULL);
670 syms = elf_getdata(scn_dynsym, NULL);
674 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
675 if (scn_symstrs == NULL)
678 symstrs = elf_getdata(scn_symstrs, NULL);
682 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
683 plt_offset = shdr_plt.sh_offset;
685 if (shdr_rel_plt.sh_type == SHT_RELA) {
686 GElf_Rela pos_mem, *pos;
688 elf_section__for_each_rela(reldata, pos, pos_mem, idx,
690 symidx = GELF_R_SYM(pos->r_info);
691 plt_offset += shdr_plt.sh_entsize;
692 gelf_getsym(syms, symidx, &sym);
693 snprintf(sympltname, sizeof(sympltname),
694 "%s@plt", elf_sym__name(&sym, symstrs));
696 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
701 if (filter && filter(map, f))
704 symbols__insert(&self->symbols[map->type], f);
708 } else if (shdr_rel_plt.sh_type == SHT_REL) {
709 GElf_Rel pos_mem, *pos;
710 elf_section__for_each_rel(reldata, pos, pos_mem, idx,
712 symidx = GELF_R_SYM(pos->r_info);
713 plt_offset += shdr_plt.sh_entsize;
714 gelf_getsym(syms, symidx, &sym);
715 snprintf(sympltname, sizeof(sympltname),
716 "%s@plt", elf_sym__name(&sym, symstrs));
718 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
723 if (filter && filter(map, f))
726 symbols__insert(&self->symbols[map->type], f);
741 pr_warning("%s: problems reading %s PLT info.\n",
742 __func__, self->long_name);
746 static int dso__load_sym(struct dso *self, struct map *map,
747 struct thread *thread, const char *name, int fd,
748 symbol_filter_t filter, int kernel, int kmodule)
750 struct map *curr_map = map;
751 struct dso *curr_dso = self;
752 size_t dso_name_len = strlen(self->short_name);
753 Elf_Data *symstrs, *secstrs;
761 Elf_Scn *sec, *sec_strndx;
765 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
767 pr_err("%s: cannot read %s ELF file.\n", __func__, name);
771 if (gelf_getehdr(elf, &ehdr) == NULL) {
772 pr_err("%s: cannot get elf header.\n", __func__);
776 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
778 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
783 syms = elf_getdata(sec, NULL);
787 sec = elf_getscn(elf, shdr.sh_link);
791 symstrs = elf_getdata(sec, NULL);
795 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
796 if (sec_strndx == NULL)
799 secstrs = elf_getdata(sec_strndx, NULL);
803 nr_syms = shdr.sh_size / shdr.sh_entsize;
805 memset(&sym, 0, sizeof(sym));
807 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
808 elf_section_by_name(elf, &ehdr, &shdr,
811 } else self->adjust_symbols = 0;
813 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
815 const char *elf_name;
816 char *demangled = NULL;
817 int is_label = elf_sym__is_label(&sym);
818 const char *section_name;
820 if (!is_label && !elf_sym__is_function(&sym))
823 sec = elf_getscn(elf, sym.st_shndx);
827 gelf_getshdr(sec, &shdr);
829 if (is_label && !elf_sec__is_text(&shdr, secstrs))
832 elf_name = elf_sym__name(&sym, symstrs);
833 section_name = elf_sec__name(&shdr, secstrs);
835 if (kernel || kmodule) {
836 char dso_name[PATH_MAX];
838 if (strcmp(section_name,
839 curr_dso->short_name + dso_name_len) == 0)
842 if (strcmp(section_name, ".text") == 0) {
848 snprintf(dso_name, sizeof(dso_name),
849 "%s%s", self->short_name, section_name);
851 curr_map = thread__find_map_by_name(thread, dso_name);
852 if (curr_map == NULL) {
853 u64 start = sym.st_value;
856 start += map->start + shdr.sh_offset;
858 curr_dso = dso__new(dso_name);
859 if (curr_dso == NULL)
861 curr_map = map__new2(start, curr_dso,
863 if (curr_map == NULL) {
864 dso__delete(curr_dso);
867 curr_map->map_ip = identity__map_ip;
868 curr_map->unmap_ip = identity__map_ip;
869 curr_dso->origin = DSO__ORIG_KERNEL;
870 __thread__insert_map(kthread, curr_map);
871 dsos__add(&dsos__kernel, curr_dso);
873 curr_dso = curr_map->dso;
878 if (curr_dso->adjust_symbols) {
879 pr_debug2("adjusting symbol: st_value: %Lx sh_addr: "
880 "%Lx sh_offset: %Lx\n", (u64)sym.st_value,
881 (u64)shdr.sh_addr, (u64)shdr.sh_offset);
882 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
885 * We need to figure out if the object was created from C++ sources
886 * DWARF DW_compile_unit has this, but we don't always have access
889 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
890 if (demangled != NULL)
891 elf_name = demangled;
893 f = symbol__new(sym.st_value, sym.st_size, elf_name);
898 if (filter && filter(curr_map, f))
901 symbols__insert(&curr_dso->symbols[curr_map->type], f);
907 * For misannotated, zeroed, ASM function sizes.
910 symbols__fixup_end(&self->symbols[map->type]);
918 static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
920 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
923 static bool __dsos__read_build_ids(struct list_head *head)
925 bool have_build_id = false;
928 list_for_each_entry(pos, head, node)
929 if (filename__read_build_id(pos->long_name, pos->build_id,
930 sizeof(pos->build_id)) > 0) {
931 have_build_id = true;
932 pos->has_build_id = true;
935 return have_build_id;
938 bool dsos__read_build_ids(void)
940 return __dsos__read_build_ids(&dsos__kernel) ||
941 __dsos__read_build_ids(&dsos__user);
945 * Align offset to 4 bytes as needed for note name and descriptor data.
947 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
949 int filename__read_build_id(const char *filename, void *bf, size_t size)
960 if (size < BUILD_ID_SIZE)
963 fd = open(filename, O_RDONLY);
967 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
969 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
977 if (gelf_getehdr(elf, &ehdr) == NULL) {
978 pr_err("%s: cannot get elf header.\n", __func__);
982 sec = elf_section_by_name(elf, &ehdr, &shdr,
983 ".note.gnu.build-id", NULL);
985 sec = elf_section_by_name(elf, &ehdr, &shdr,
991 data = elf_getdata(sec, NULL);
996 while (ptr < (data->d_buf + data->d_size)) {
997 GElf_Nhdr *nhdr = ptr;
998 int namesz = NOTE_ALIGN(nhdr->n_namesz),
999 descsz = NOTE_ALIGN(nhdr->n_descsz);
1002 ptr += sizeof(*nhdr);
1005 if (nhdr->n_type == NT_GNU_BUILD_ID &&
1006 nhdr->n_namesz == sizeof("GNU")) {
1007 if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1008 memcpy(bf, ptr, BUILD_ID_SIZE);
1009 err = BUILD_ID_SIZE;
1023 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1027 if (size < BUILD_ID_SIZE)
1030 fd = open(filename, O_RDONLY);
1039 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1042 namesz = NOTE_ALIGN(nhdr.n_namesz);
1043 descsz = NOTE_ALIGN(nhdr.n_descsz);
1044 if (nhdr.n_type == NT_GNU_BUILD_ID &&
1045 nhdr.n_namesz == sizeof("GNU")) {
1046 if (read(fd, bf, namesz) != namesz)
1048 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1049 if (read(fd, build_id,
1050 BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1054 } else if (read(fd, bf, descsz) != descsz)
1057 int n = namesz + descsz;
1058 if (read(fd, bf, n) != n)
1067 char dso__symtab_origin(const struct dso *self)
1069 static const char origin[] = {
1070 [DSO__ORIG_KERNEL] = 'k',
1071 [DSO__ORIG_JAVA_JIT] = 'j',
1072 [DSO__ORIG_FEDORA] = 'f',
1073 [DSO__ORIG_UBUNTU] = 'u',
1074 [DSO__ORIG_BUILDID] = 'b',
1075 [DSO__ORIG_DSO] = 'd',
1076 [DSO__ORIG_KMODULE] = 'K',
1079 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
1081 return origin[self->origin];
1084 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1086 int size = PATH_MAX;
1088 u8 build_id[BUILD_ID_SIZE];
1092 dso__set_loaded(self, map->type);
1095 return dso__load_kernel_sym(self, map, kthread, filter);
1097 name = malloc(size);
1101 self->adjust_symbols = 0;
1103 if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1104 ret = dso__load_perf_map(self, map, filter);
1105 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
1106 DSO__ORIG_NOT_FOUND;
1110 self->origin = DSO__ORIG_FEDORA - 1;
1115 switch (self->origin) {
1116 case DSO__ORIG_FEDORA:
1117 snprintf(name, size, "/usr/lib/debug%s.debug",
1120 case DSO__ORIG_UBUNTU:
1121 snprintf(name, size, "/usr/lib/debug%s",
1124 case DSO__ORIG_BUILDID:
1125 if (filename__read_build_id(self->long_name, build_id,
1126 sizeof(build_id))) {
1127 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1129 build_id__sprintf(build_id, sizeof(build_id),
1131 snprintf(name, size,
1132 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1133 build_id_hex, build_id_hex + 2);
1134 if (self->has_build_id)
1135 goto compare_build_id;
1141 snprintf(name, size, "%s", self->long_name);
1148 if (self->has_build_id) {
1149 if (filename__read_build_id(name, build_id,
1150 sizeof(build_id)) < 0)
1153 if (!dso__build_id_equal(self, build_id))
1157 fd = open(name, O_RDONLY);
1160 ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0);
1164 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1170 int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1176 if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1181 static struct symbol *thread__find_symbol(struct thread *self, u64 ip,
1182 enum map_type type, struct map **mapp,
1183 symbol_filter_t filter)
1185 struct map *map = thread__find_map(self, type, ip);
1191 ip = map->map_ip(map, ip);
1192 return map__find_symbol(map, ip, filter);
1198 struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp,
1199 symbol_filter_t filter)
1201 return thread__find_symbol(kthread, ip, MAP__FUNCTION, mapp, filter);
1204 static struct map *thread__find_map_by_name(struct thread *self, char *name)
1208 for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
1209 struct map *map = rb_entry(nd, struct map, rb_node);
1211 if (map->dso && strcmp(map->dso->name, name) == 0)
1218 static int dsos__set_modules_path_dir(char *dirname)
1220 struct dirent *dent;
1221 DIR *dir = opendir(dirname);
1224 pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1228 while ((dent = readdir(dir)) != NULL) {
1229 char path[PATH_MAX];
1231 if (dent->d_type == DT_DIR) {
1232 if (!strcmp(dent->d_name, ".") ||
1233 !strcmp(dent->d_name, ".."))
1236 snprintf(path, sizeof(path), "%s/%s",
1237 dirname, dent->d_name);
1238 if (dsos__set_modules_path_dir(path) < 0)
1241 char *dot = strrchr(dent->d_name, '.'),
1246 if (dot == NULL || strcmp(dot, ".ko"))
1248 snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1249 (int)(dot - dent->d_name), dent->d_name);
1251 strxfrchar(dso_name, '-', '_');
1252 map = thread__find_map_by_name(kthread, dso_name);
1256 snprintf(path, sizeof(path), "%s/%s",
1257 dirname, dent->d_name);
1259 long_name = strdup(path);
1260 if (long_name == NULL)
1262 dso__set_long_name(map->dso, long_name);
1272 static int dsos__set_modules_path(void)
1275 char modules_path[PATH_MAX];
1277 if (uname(&uts) < 0)
1280 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1283 return dsos__set_modules_path_dir(modules_path);
1287 * Constructor variant for modules (where we know from /proc/modules where
1288 * they are loaded) and for vmlinux, where only after we load all the
1289 * symbols we'll know where it starts and ends.
1291 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1293 struct map *self = malloc(sizeof(*self));
1297 * ->end will be filled after we load all the symbols
1299 map__init(self, type, start, 0, 0, dso);
1305 static int thread__create_module_maps(struct thread *self)
1309 FILE *file = fopen("/proc/modules", "r");
1315 while (!feof(file)) {
1316 char name[PATH_MAX];
1322 line_len = getline(&line, &n, file);
1329 line[--line_len] = '\0'; /* \n */
1331 sep = strrchr(line, 'x');
1335 hex2u64(sep + 1, &start);
1337 sep = strchr(line, ' ');
1343 snprintf(name, sizeof(name), "[%s]", line);
1344 dso = dso__new(name);
1347 goto out_delete_line;
1349 map = map__new2(start, dso, MAP__FUNCTION);
1352 goto out_delete_line;
1355 snprintf(name, sizeof(name),
1356 "/sys/module/%s/notes/.note.gnu.build-id", line);
1357 if (sysfs__read_build_id(name, dso->build_id,
1358 sizeof(dso->build_id)) == 0)
1359 dso->has_build_id = true;
1361 dso->origin = DSO__ORIG_KMODULE;
1362 __thread__insert_map(self, map);
1363 dsos__add(&dsos__kernel, dso);
1369 return dsos__set_modules_path();
1377 static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *thread,
1378 const char *vmlinux, symbol_filter_t filter)
1382 if (self->has_build_id) {
1383 u8 build_id[BUILD_ID_SIZE];
1385 if (filename__read_build_id(vmlinux, build_id,
1386 sizeof(build_id)) < 0) {
1387 pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1390 if (!dso__build_id_equal(self, build_id)) {
1391 char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1392 vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1394 build_id__sprintf(self->build_id,
1395 sizeof(self->build_id),
1397 build_id__sprintf(build_id, sizeof(build_id),
1399 pr_debug("build_id in %s is %s while expected is %s, "
1400 "ignoring it\n", vmlinux, vmlinux_build_id,
1406 fd = open(vmlinux, O_RDONLY);
1410 dso__set_loaded(self, map->type);
1411 err = dso__load_sym(self, map, thread, self->long_name, fd, filter, 1, 0);
1417 static int dso__load_kernel_sym(struct dso *self, struct map *map,
1418 struct thread *thread, symbol_filter_t filter)
1423 if (vmlinux_path != NULL) {
1425 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1426 vmlinux_path__nr_entries);
1427 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1428 err = dso__load_vmlinux(self, map, thread,
1429 vmlinux_path[i], filter);
1431 pr_debug("Using %s for symbols\n",
1433 dso__set_long_name(self,
1434 strdup(vmlinux_path[i]));
1440 is_kallsyms = self->long_name[0] == '[';
1444 err = dso__load_vmlinux(self, map, thread, self->long_name, filter);
1446 pr_info("The file %s cannot be used, "
1447 "trying to use /proc/kallsyms...", self->long_name);
1449 err = dso__load_kallsyms(self, map, thread, filter);
1450 if (err > 0 && !is_kallsyms)
1451 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1456 map__fixup_start(map);
1457 map__fixup_end(map);
1463 LIST_HEAD(dsos__user);
1464 LIST_HEAD(dsos__kernel);
1467 static void dsos__add(struct list_head *head, struct dso *dso)
1469 list_add_tail(&dso->node, head);
1472 static struct dso *dsos__find(struct list_head *head, const char *name)
1476 list_for_each_entry(pos, head, node)
1477 if (strcmp(pos->name, name) == 0)
1482 struct dso *dsos__findnew(const char *name)
1484 struct dso *dso = dsos__find(&dsos__user, name);
1487 dso = dso__new(name);
1489 dsos__add(&dsos__user, dso);
1490 dso__set_basename(dso);
1497 static void __dsos__fprintf(struct list_head *head, FILE *fp)
1501 list_for_each_entry(pos, head, node) {
1503 for (i = 0; i < MAP__NR_TYPES; ++i)
1504 dso__fprintf(pos, i, fp);
1508 void dsos__fprintf(FILE *fp)
1510 __dsos__fprintf(&dsos__kernel, fp);
1511 __dsos__fprintf(&dsos__user, fp);
1514 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp)
1519 list_for_each_entry(pos, head, node) {
1520 ret += dso__fprintf_buildid(pos, fp);
1521 ret += fprintf(fp, " %s\n", pos->long_name);
1526 size_t dsos__fprintf_buildid(FILE *fp)
1528 return (__dsos__fprintf_buildid(&dsos__kernel, fp) +
1529 __dsos__fprintf_buildid(&dsos__user, fp));
1532 static int thread__create_kernel_map(struct thread *self, const char *vmlinux)
1535 struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]");
1540 kmap = map__new2(0, kernel, MAP__FUNCTION);
1542 goto out_delete_kernel_dso;
1544 kmap->map_ip = kmap->unmap_ip = identity__map_ip;
1545 kernel->short_name = "[kernel]";
1548 vdso = dso__new("[vdso]");
1550 goto out_delete_kernel_map;
1551 dso__set_loaded(vdso, MAP__FUNCTION);
1553 if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
1554 sizeof(kernel->build_id)) == 0)
1555 kernel->has_build_id = true;
1557 __thread__insert_map(self, kmap);
1558 dsos__add(&dsos__kernel, kernel);
1559 dsos__add(&dsos__user, vdso);
1563 out_delete_kernel_map:
1565 out_delete_kernel_dso:
1566 dso__delete(kernel);
1570 static void vmlinux_path__exit(void)
1572 while (--vmlinux_path__nr_entries >= 0) {
1573 free(vmlinux_path[vmlinux_path__nr_entries]);
1574 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1578 vmlinux_path = NULL;
1581 static int vmlinux_path__init(void)
1586 if (uname(&uts) < 0)
1589 vmlinux_path = malloc(sizeof(char *) * 5);
1590 if (vmlinux_path == NULL)
1593 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1594 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1596 ++vmlinux_path__nr_entries;
1597 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1598 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1600 ++vmlinux_path__nr_entries;
1601 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1602 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1603 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1605 ++vmlinux_path__nr_entries;
1606 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1607 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1608 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1610 ++vmlinux_path__nr_entries;
1611 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1613 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1614 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1616 ++vmlinux_path__nr_entries;
1621 vmlinux_path__exit();
1625 int symbol__init(struct symbol_conf *conf)
1627 const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
1629 elf_version(EV_CURRENT);
1630 symbol__priv_size = pconf->priv_size;
1631 thread__init(kthread, 0);
1633 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1636 if (thread__create_kernel_map(kthread, pconf->vmlinux_name) < 0) {
1637 vmlinux_path__exit();
1641 kthread->use_modules = pconf->use_modules;
1642 if (pconf->use_modules && thread__create_module_maps(kthread) < 0)
1643 pr_debug("Failed to load list of modules in use, "
1646 * Now that we have all the maps created, just set the ->end of them:
1648 thread__fixup_maps_end(kthread);