perf symbols: Better support for multiple symbol tables per dso
[safe/jmp/linux-2.6] / tools / perf / util / symbol.c
1 #include "util.h"
2 #include "../perf.h"
3 #include "string.h"
4 #include "symbol.h"
5 #include "thread.h"
6
7 #include "debug.h"
8
9 #include <asm/bug.h>
10 #include <libelf.h>
11 #include <gelf.h>
12 #include <elf.h>
13 #include <limits.h>
14 #include <sys/utsname.h>
15
16 #ifndef NT_GNU_BUILD_ID
17 #define NT_GNU_BUILD_ID 3
18 #endif
19
20 enum dso_origin {
21         DSO__ORIG_KERNEL = 0,
22         DSO__ORIG_JAVA_JIT,
23         DSO__ORIG_FEDORA,
24         DSO__ORIG_UBUNTU,
25         DSO__ORIG_BUILDID,
26         DSO__ORIG_DSO,
27         DSO__ORIG_KMODULE,
28         DSO__ORIG_NOT_FOUND,
29 };
30
31 static void dsos__add(struct list_head *head, struct dso *dso);
32 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
33 static void kernel_maps__insert(struct map *map);
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                                 symbol_filter_t filter);
37 unsigned int symbol__priv_size;
38 static int vmlinux_path__nr_entries;
39 static char **vmlinux_path;
40 static struct map *kernel_map__functions;
41
42 static struct symbol_conf symbol_conf__defaults = {
43         .use_modules      = true,
44         .try_vmlinux_path = true,
45 };
46
47 static struct rb_root kernel_maps__functions;
48
49 bool dso__loaded(const struct dso *self, enum map_type type)
50 {
51         return self->loaded & (1 << type);
52 }
53
54 static void dso__set_loaded(struct dso *self, enum map_type type)
55 {
56         self->loaded |= (1 << type);
57 }
58
59 static void symbols__fixup_end(struct rb_root *self)
60 {
61         struct rb_node *nd, *prevnd = rb_first(self);
62         struct symbol *curr, *prev;
63
64         if (prevnd == NULL)
65                 return;
66
67         curr = rb_entry(prevnd, struct symbol, rb_node);
68
69         for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
70                 prev = curr;
71                 curr = rb_entry(nd, struct symbol, rb_node);
72
73                 if (prev->end == prev->start)
74                         prev->end = curr->start - 1;
75         }
76
77         /* Last entry */
78         if (curr->end == curr->start)
79                 curr->end = roundup(curr->start, 4096);
80 }
81
82 static void kernel_maps__fixup_end(void)
83 {
84         struct map *prev, *curr;
85         struct rb_node *nd, *prevnd = rb_first(&kernel_maps__functions);
86
87         if (prevnd == NULL)
88                 return;
89
90         curr = rb_entry(prevnd, struct map, rb_node);
91
92         for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
93                 prev = curr;
94                 curr = rb_entry(nd, struct map, rb_node);
95                 prev->end = curr->start - 1;
96         }
97
98         /*
99          * We still haven't the actual symbols, so guess the
100          * last map final address.
101          */
102         curr->end = ~0UL;
103 }
104
105 static struct symbol *symbol__new(u64 start, u64 len, const char *name)
106 {
107         size_t namelen = strlen(name) + 1;
108         struct symbol *self = zalloc(symbol__priv_size +
109                                      sizeof(*self) + namelen);
110         if (self == NULL)
111                 return NULL;
112
113         if (symbol__priv_size)
114                 self = ((void *)self) + symbol__priv_size;
115
116         self->start = start;
117         self->end   = len ? start + len - 1 : start;
118
119         pr_debug3("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
120
121         memcpy(self->name, name, namelen);
122
123         return self;
124 }
125
126 static void symbol__delete(struct symbol *self)
127 {
128         free(((void *)self) - symbol__priv_size);
129 }
130
131 static size_t symbol__fprintf(struct symbol *self, FILE *fp)
132 {
133         return fprintf(fp, " %llx-%llx %s\n",
134                        self->start, self->end, self->name);
135 }
136
137 static void dso__set_long_name(struct dso *self, char *name)
138 {
139         if (name == NULL)
140                 return;
141         self->long_name = name;
142         self->long_name_len = strlen(name);
143 }
144
145 static void dso__set_basename(struct dso *self)
146 {
147         self->short_name = basename(self->long_name);
148 }
149
150 struct dso *dso__new(const char *name)
151 {
152         struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
153
154         if (self != NULL) {
155                 int i;
156                 strcpy(self->name, name);
157                 dso__set_long_name(self, self->name);
158                 self->short_name = self->name;
159                 for (i = 0; i < MAP__NR_TYPES; ++i)
160                         self->symbols[i] = RB_ROOT;
161                 self->find_symbol = dso__find_symbol;
162                 self->slen_calculated = 0;
163                 self->origin = DSO__ORIG_NOT_FOUND;
164                 self->loaded = 0;
165                 self->has_build_id = 0;
166         }
167
168         return self;
169 }
170
171 static void symbols__delete(struct rb_root *self)
172 {
173         struct symbol *pos;
174         struct rb_node *next = rb_first(self);
175
176         while (next) {
177                 pos = rb_entry(next, struct symbol, rb_node);
178                 next = rb_next(&pos->rb_node);
179                 rb_erase(&pos->rb_node, self);
180                 symbol__delete(pos);
181         }
182 }
183
184 void dso__delete(struct dso *self)
185 {
186         int i;
187         for (i = 0; i < MAP__NR_TYPES; ++i)
188                 symbols__delete(&self->symbols[i]);
189         if (self->long_name != self->name)
190                 free(self->long_name);
191         free(self);
192 }
193
194 void dso__set_build_id(struct dso *self, void *build_id)
195 {
196         memcpy(self->build_id, build_id, sizeof(self->build_id));
197         self->has_build_id = 1;
198 }
199
200 static void symbols__insert(struct rb_root *self, struct symbol *sym)
201 {
202         struct rb_node **p = &self->rb_node;
203         struct rb_node *parent = NULL;
204         const u64 ip = sym->start;
205         struct symbol *s;
206
207         while (*p != NULL) {
208                 parent = *p;
209                 s = rb_entry(parent, struct symbol, rb_node);
210                 if (ip < s->start)
211                         p = &(*p)->rb_left;
212                 else
213                         p = &(*p)->rb_right;
214         }
215         rb_link_node(&sym->rb_node, parent, p);
216         rb_insert_color(&sym->rb_node, self);
217 }
218
219 static struct symbol *symbols__find(struct rb_root *self, u64 ip)
220 {
221         struct rb_node *n;
222
223         if (self == NULL)
224                 return NULL;
225
226         n = self->rb_node;
227
228         while (n) {
229                 struct symbol *s = rb_entry(n, struct symbol, rb_node);
230
231                 if (ip < s->start)
232                         n = n->rb_left;
233                 else if (ip > s->end)
234                         n = n->rb_right;
235                 else
236                         return s;
237         }
238
239         return NULL;
240 }
241
242 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr)
243 {
244         return symbols__find(&self->symbols[type], addr);
245 }
246
247 int build_id__sprintf(u8 *self, int len, char *bf)
248 {
249         char *bid = bf;
250         u8 *raw = self;
251         int i;
252
253         for (i = 0; i < len; ++i) {
254                 sprintf(bid, "%02x", *raw);
255                 ++raw;
256                 bid += 2;
257         }
258
259         return raw - self;
260 }
261
262 size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
263 {
264         char sbuild_id[BUILD_ID_SIZE * 2 + 1];
265
266         build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
267         return fprintf(fp, "%s", sbuild_id);
268 }
269
270 static const char * map_type__name[MAP__NR_TYPES] = {
271         [MAP__FUNCTION] = "Functions",
272 };
273
274 size_t dso__fprintf(struct dso *self, FILE *fp)
275 {
276         int i;
277         struct rb_node *nd;
278         size_t ret = fprintf(fp, "dso: %s (", self->short_name);
279
280         ret += dso__fprintf_buildid(self, fp);
281         ret += fprintf(fp, ")\n");
282         for (i = 0; i < MAP__NR_TYPES; ++i) {
283                 ret += fprintf(fp, "%s:\n", map_type__name[i]);
284
285                 for (nd = rb_first(&self->symbols[i]); nd; nd = rb_next(nd)) {
286                         struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
287                         ret += symbol__fprintf(pos, fp);
288                 }
289         }
290
291         return ret;
292 }
293
294 /*
295  * Loads the function entries in /proc/kallsyms into kernel_map->dso,
296  * so that we can in the next step set the symbol ->end address and then
297  * call kernel_maps__split_kallsyms.
298  */
299 static int kernel_maps__load_all_kallsyms(void)
300 {
301         char *line = NULL;
302         size_t n;
303         FILE *file = fopen("/proc/kallsyms", "r");
304
305         if (file == NULL)
306                 goto out_failure;
307
308         while (!feof(file)) {
309                 u64 start;
310                 struct symbol *sym;
311                 int line_len, len;
312                 char symbol_type;
313                 char *symbol_name;
314
315                 line_len = getline(&line, &n, file);
316                 if (line_len < 0)
317                         break;
318
319                 if (!line)
320                         goto out_failure;
321
322                 line[--line_len] = '\0'; /* \n */
323
324                 len = hex2u64(line, &start);
325
326                 len++;
327                 if (len + 2 >= line_len)
328                         continue;
329
330                 symbol_type = toupper(line[len]);
331                 /*
332                  * We're interested only in code ('T'ext)
333                  */
334                 if (symbol_type != 'T' && symbol_type != 'W')
335                         continue;
336
337                 symbol_name = line + len + 2;
338                 /*
339                  * Will fix up the end later, when we have all symbols sorted.
340                  */
341                 sym = symbol__new(start, 0, symbol_name);
342
343                 if (sym == NULL)
344                         goto out_delete_line;
345
346                 /*
347                  * We will pass the symbols to the filter later, in
348                  * kernel_maps__split_kallsyms, when we have split the
349                  * maps per module
350                  */
351                 symbols__insert(&kernel_map__functions->dso->symbols[MAP__FUNCTION], sym);
352         }
353
354         free(line);
355         fclose(file);
356
357         return 0;
358
359 out_delete_line:
360         free(line);
361 out_failure:
362         return -1;
363 }
364
365 /*
366  * Split the symbols into maps, making sure there are no overlaps, i.e. the
367  * kernel range is broken in several maps, named [kernel].N, as we don't have
368  * the original ELF section names vmlinux have.
369  */
370 static int kernel_maps__split_kallsyms(symbol_filter_t filter)
371 {
372         struct map *map = kernel_map__functions;
373         struct symbol *pos;
374         int count = 0;
375         struct rb_node *next = rb_first(&kernel_map__functions->dso->symbols[map->type]);
376         int kernel_range = 0;
377
378         while (next) {
379                 char *module;
380
381                 pos = rb_entry(next, struct symbol, rb_node);
382                 next = rb_next(&pos->rb_node);
383
384                 module = strchr(pos->name, '\t');
385                 if (module) {
386                         *module++ = '\0';
387
388                         if (strcmp(map->dso->name, module)) {
389                                 map = kernel_maps__find_by_dso_name(module);
390                                 if (!map) {
391                                         pr_err("/proc/{kallsyms,modules} "
392                                                "inconsistency!\n");
393                                         return -1;
394                                 }
395                         }
396                         /*
397                          * So that we look just like we get from .ko files,
398                          * i.e. not prelinked, relative to map->start.
399                          */
400                         pos->start = map->map_ip(map, pos->start);
401                         pos->end   = map->map_ip(map, pos->end);
402                 } else if (map != kernel_map__functions) {
403                         char dso_name[PATH_MAX];
404                         struct dso *dso;
405
406                         snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
407                                  kernel_range++);
408
409                         dso = dso__new(dso_name);
410                         if (dso == NULL)
411                                 return -1;
412
413                         map = map__new2(pos->start, dso, MAP__FUNCTION);
414                         if (map == NULL) {
415                                 dso__delete(dso);
416                                 return -1;
417                         }
418
419                         map->map_ip = map->unmap_ip = identity__map_ip;
420                         kernel_maps__insert(map);
421                         ++kernel_range;
422                 }
423
424                 if (filter && filter(map, pos)) {
425                         rb_erase(&pos->rb_node, &kernel_map__functions->dso->symbols[map->type]);
426                         symbol__delete(pos);
427                 } else {
428                         if (map != kernel_map__functions) {
429                                 rb_erase(&pos->rb_node,
430                                          &kernel_map__functions->dso->symbols[map->type]);
431                                 symbols__insert(&map->dso->symbols[map->type], pos);
432                         }
433                         count++;
434                 }
435         }
436
437         return count;
438 }
439
440
441 static int kernel_maps__load_kallsyms(symbol_filter_t filter)
442 {
443         if (kernel_maps__load_all_kallsyms())
444                 return -1;
445
446         symbols__fixup_end(&kernel_map__functions->dso->symbols[MAP__FUNCTION]);
447         kernel_map__functions->dso->origin = DSO__ORIG_KERNEL;
448
449         return kernel_maps__split_kallsyms(filter);
450 }
451
452 size_t kernel_maps__fprintf(FILE *fp)
453 {
454         size_t printed = fprintf(fp, "Kernel maps:\n");
455         struct rb_node *nd;
456
457         for (nd = rb_first(&kernel_maps__functions); nd; nd = rb_next(nd)) {
458                 struct map *pos = rb_entry(nd, struct map, rb_node);
459
460                 printed += fprintf(fp, "Map:");
461                 printed += map__fprintf(pos, fp);
462                 if (verbose > 1) {
463                         printed += dso__fprintf(pos->dso, fp);
464                         printed += fprintf(fp, "--\n");
465                 }
466         }
467
468         return printed + fprintf(fp, "END kernel maps\n");
469 }
470
471 static int dso__load_perf_map(struct dso *self, struct map *map,
472                               symbol_filter_t filter)
473 {
474         char *line = NULL;
475         size_t n;
476         FILE *file;
477         int nr_syms = 0;
478
479         file = fopen(self->long_name, "r");
480         if (file == NULL)
481                 goto out_failure;
482
483         while (!feof(file)) {
484                 u64 start, size;
485                 struct symbol *sym;
486                 int line_len, len;
487
488                 line_len = getline(&line, &n, file);
489                 if (line_len < 0)
490                         break;
491
492                 if (!line)
493                         goto out_failure;
494
495                 line[--line_len] = '\0'; /* \n */
496
497                 len = hex2u64(line, &start);
498
499                 len++;
500                 if (len + 2 >= line_len)
501                         continue;
502
503                 len += hex2u64(line + len, &size);
504
505                 len++;
506                 if (len + 2 >= line_len)
507                         continue;
508
509                 sym = symbol__new(start, size, line + len);
510
511                 if (sym == NULL)
512                         goto out_delete_line;
513
514                 if (filter && filter(map, sym))
515                         symbol__delete(sym);
516                 else {
517                         symbols__insert(&self->symbols[map->type], sym);
518                         nr_syms++;
519                 }
520         }
521
522         free(line);
523         fclose(file);
524
525         return nr_syms;
526
527 out_delete_line:
528         free(line);
529 out_failure:
530         return -1;
531 }
532
533 /**
534  * elf_symtab__for_each_symbol - iterate thru all the symbols
535  *
536  * @self: struct elf_symtab instance to iterate
537  * @idx: uint32_t idx
538  * @sym: GElf_Sym iterator
539  */
540 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
541         for (idx = 0, gelf_getsym(syms, idx, &sym);\
542              idx < nr_syms; \
543              idx++, gelf_getsym(syms, idx, &sym))
544
545 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
546 {
547         return GELF_ST_TYPE(sym->st_info);
548 }
549
550 static inline int elf_sym__is_function(const GElf_Sym *sym)
551 {
552         return elf_sym__type(sym) == STT_FUNC &&
553                sym->st_name != 0 &&
554                sym->st_shndx != SHN_UNDEF;
555 }
556
557 static inline int elf_sym__is_label(const GElf_Sym *sym)
558 {
559         return elf_sym__type(sym) == STT_NOTYPE &&
560                 sym->st_name != 0 &&
561                 sym->st_shndx != SHN_UNDEF &&
562                 sym->st_shndx != SHN_ABS;
563 }
564
565 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
566                                         const Elf_Data *secstrs)
567 {
568         return secstrs->d_buf + shdr->sh_name;
569 }
570
571 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
572                                         const Elf_Data *secstrs)
573 {
574         return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
575 }
576
577 static inline const char *elf_sym__name(const GElf_Sym *sym,
578                                         const Elf_Data *symstrs)
579 {
580         return symstrs->d_buf + sym->st_name;
581 }
582
583 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
584                                     GElf_Shdr *shp, const char *name,
585                                     size_t *idx)
586 {
587         Elf_Scn *sec = NULL;
588         size_t cnt = 1;
589
590         while ((sec = elf_nextscn(elf, sec)) != NULL) {
591                 char *str;
592
593                 gelf_getshdr(sec, shp);
594                 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
595                 if (!strcmp(name, str)) {
596                         if (idx)
597                                 *idx = cnt;
598                         break;
599                 }
600                 ++cnt;
601         }
602
603         return sec;
604 }
605
606 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
607         for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
608              idx < nr_entries; \
609              ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
610
611 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
612         for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
613              idx < nr_entries; \
614              ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
615
616 /*
617  * We need to check if we have a .dynsym, so that we can handle the
618  * .plt, synthesizing its symbols, that aren't on the symtabs (be it
619  * .dynsym or .symtab).
620  * And always look at the original dso, not at debuginfo packages, that
621  * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
622  */
623 static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
624                                        symbol_filter_t filter)
625 {
626         uint32_t nr_rel_entries, idx;
627         GElf_Sym sym;
628         u64 plt_offset;
629         GElf_Shdr shdr_plt;
630         struct symbol *f;
631         GElf_Shdr shdr_rel_plt, shdr_dynsym;
632         Elf_Data *reldata, *syms, *symstrs;
633         Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
634         size_t dynsym_idx;
635         GElf_Ehdr ehdr;
636         char sympltname[1024];
637         Elf *elf;
638         int nr = 0, symidx, fd, err = 0;
639
640         fd = open(self->long_name, O_RDONLY);
641         if (fd < 0)
642                 goto out;
643
644         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
645         if (elf == NULL)
646                 goto out_close;
647
648         if (gelf_getehdr(elf, &ehdr) == NULL)
649                 goto out_elf_end;
650
651         scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
652                                          ".dynsym", &dynsym_idx);
653         if (scn_dynsym == NULL)
654                 goto out_elf_end;
655
656         scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
657                                           ".rela.plt", NULL);
658         if (scn_plt_rel == NULL) {
659                 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
660                                                   ".rel.plt", NULL);
661                 if (scn_plt_rel == NULL)
662                         goto out_elf_end;
663         }
664
665         err = -1;
666
667         if (shdr_rel_plt.sh_link != dynsym_idx)
668                 goto out_elf_end;
669
670         if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
671                 goto out_elf_end;
672
673         /*
674          * Fetch the relocation section to find the idxes to the GOT
675          * and the symbols in the .dynsym they refer to.
676          */
677         reldata = elf_getdata(scn_plt_rel, NULL);
678         if (reldata == NULL)
679                 goto out_elf_end;
680
681         syms = elf_getdata(scn_dynsym, NULL);
682         if (syms == NULL)
683                 goto out_elf_end;
684
685         scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
686         if (scn_symstrs == NULL)
687                 goto out_elf_end;
688
689         symstrs = elf_getdata(scn_symstrs, NULL);
690         if (symstrs == NULL)
691                 goto out_elf_end;
692
693         nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
694         plt_offset = shdr_plt.sh_offset;
695
696         if (shdr_rel_plt.sh_type == SHT_RELA) {
697                 GElf_Rela pos_mem, *pos;
698
699                 elf_section__for_each_rela(reldata, pos, pos_mem, idx,
700                                            nr_rel_entries) {
701                         symidx = GELF_R_SYM(pos->r_info);
702                         plt_offset += shdr_plt.sh_entsize;
703                         gelf_getsym(syms, symidx, &sym);
704                         snprintf(sympltname, sizeof(sympltname),
705                                  "%s@plt", elf_sym__name(&sym, symstrs));
706
707                         f = symbol__new(plt_offset, shdr_plt.sh_entsize,
708                                         sympltname);
709                         if (!f)
710                                 goto out_elf_end;
711
712                         if (filter && filter(map, f))
713                                 symbol__delete(f);
714                         else {
715                                 symbols__insert(&self->symbols[map->type], f);
716                                 ++nr;
717                         }
718                 }
719         } else if (shdr_rel_plt.sh_type == SHT_REL) {
720                 GElf_Rel pos_mem, *pos;
721                 elf_section__for_each_rel(reldata, pos, pos_mem, idx,
722                                           nr_rel_entries) {
723                         symidx = GELF_R_SYM(pos->r_info);
724                         plt_offset += shdr_plt.sh_entsize;
725                         gelf_getsym(syms, symidx, &sym);
726                         snprintf(sympltname, sizeof(sympltname),
727                                  "%s@plt", elf_sym__name(&sym, symstrs));
728
729                         f = symbol__new(plt_offset, shdr_plt.sh_entsize,
730                                         sympltname);
731                         if (!f)
732                                 goto out_elf_end;
733
734                         if (filter && filter(map, f))
735                                 symbol__delete(f);
736                         else {
737                                 symbols__insert(&self->symbols[map->type], f);
738                                 ++nr;
739                         }
740                 }
741         }
742
743         err = 0;
744 out_elf_end:
745         elf_end(elf);
746 out_close:
747         close(fd);
748
749         if (err == 0)
750                 return nr;
751 out:
752         pr_warning("%s: problems reading %s PLT info.\n",
753                    __func__, self->long_name);
754         return 0;
755 }
756
757 static int dso__load_sym(struct dso *self, struct map *map, const char *name,
758                          int fd, symbol_filter_t filter, int kernel,
759                          int kmodule)
760 {
761         struct map *curr_map = map;
762         struct dso *curr_dso = self;
763         size_t dso_name_len = strlen(self->short_name);
764         Elf_Data *symstrs, *secstrs;
765         uint32_t nr_syms;
766         int err = -1;
767         uint32_t idx;
768         GElf_Ehdr ehdr;
769         GElf_Shdr shdr;
770         Elf_Data *syms;
771         GElf_Sym sym;
772         Elf_Scn *sec, *sec_strndx;
773         Elf *elf;
774         int nr = 0;
775
776         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
777         if (elf == NULL) {
778                 pr_err("%s: cannot read %s ELF file.\n", __func__, name);
779                 goto out_close;
780         }
781
782         if (gelf_getehdr(elf, &ehdr) == NULL) {
783                 pr_err("%s: cannot get elf header.\n", __func__);
784                 goto out_elf_end;
785         }
786
787         sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
788         if (sec == NULL) {
789                 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
790                 if (sec == NULL)
791                         goto out_elf_end;
792         }
793
794         syms = elf_getdata(sec, NULL);
795         if (syms == NULL)
796                 goto out_elf_end;
797
798         sec = elf_getscn(elf, shdr.sh_link);
799         if (sec == NULL)
800                 goto out_elf_end;
801
802         symstrs = elf_getdata(sec, NULL);
803         if (symstrs == NULL)
804                 goto out_elf_end;
805
806         sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
807         if (sec_strndx == NULL)
808                 goto out_elf_end;
809
810         secstrs = elf_getdata(sec_strndx, NULL);
811         if (secstrs == NULL)
812                 goto out_elf_end;
813
814         nr_syms = shdr.sh_size / shdr.sh_entsize;
815
816         memset(&sym, 0, sizeof(sym));
817         if (!kernel) {
818                 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
819                                 elf_section_by_name(elf, &ehdr, &shdr,
820                                                      ".gnu.prelink_undo",
821                                                      NULL) != NULL);
822         } else self->adjust_symbols = 0;
823
824         elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
825                 struct symbol *f;
826                 const char *elf_name;
827                 char *demangled = NULL;
828                 int is_label = elf_sym__is_label(&sym);
829                 const char *section_name;
830
831                 if (!is_label && !elf_sym__is_function(&sym))
832                         continue;
833
834                 sec = elf_getscn(elf, sym.st_shndx);
835                 if (!sec)
836                         goto out_elf_end;
837
838                 gelf_getshdr(sec, &shdr);
839
840                 if (is_label && !elf_sec__is_text(&shdr, secstrs))
841                         continue;
842
843                 elf_name = elf_sym__name(&sym, symstrs);
844                 section_name = elf_sec__name(&shdr, secstrs);
845
846                 if (kernel || kmodule) {
847                         char dso_name[PATH_MAX];
848
849                         if (strcmp(section_name,
850                                    curr_dso->short_name + dso_name_len) == 0)
851                                 goto new_symbol;
852
853                         if (strcmp(section_name, ".text") == 0) {
854                                 curr_map = map;
855                                 curr_dso = self;
856                                 goto new_symbol;
857                         }
858
859                         snprintf(dso_name, sizeof(dso_name),
860                                  "%s%s", self->short_name, section_name);
861
862                         curr_map = kernel_maps__find_by_dso_name(dso_name);
863                         if (curr_map == NULL) {
864                                 u64 start = sym.st_value;
865
866                                 if (kmodule)
867                                         start += map->start + shdr.sh_offset;
868
869                                 curr_dso = dso__new(dso_name);
870                                 if (curr_dso == NULL)
871                                         goto out_elf_end;
872                                 curr_map = map__new2(start, curr_dso,
873                                                      MAP__FUNCTION);
874                                 if (curr_map == NULL) {
875                                         dso__delete(curr_dso);
876                                         goto out_elf_end;
877                                 }
878                                 curr_map->map_ip = identity__map_ip;
879                                 curr_map->unmap_ip = identity__map_ip;
880                                 curr_dso->origin = DSO__ORIG_KERNEL;
881                                 kernel_maps__insert(curr_map);
882                                 dsos__add(&dsos__kernel, curr_dso);
883                         } else
884                                 curr_dso = curr_map->dso;
885
886                         goto new_symbol;
887                 }
888
889                 if (curr_dso->adjust_symbols) {
890                         pr_debug2("adjusting symbol: st_value: %Lx sh_addr: "
891                                   "%Lx sh_offset: %Lx\n", (u64)sym.st_value,
892                                   (u64)shdr.sh_addr, (u64)shdr.sh_offset);
893                         sym.st_value -= shdr.sh_addr - shdr.sh_offset;
894                 }
895                 /*
896                  * We need to figure out if the object was created from C++ sources
897                  * DWARF DW_compile_unit has this, but we don't always have access
898                  * to it...
899                  */
900                 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
901                 if (demangled != NULL)
902                         elf_name = demangled;
903 new_symbol:
904                 f = symbol__new(sym.st_value, sym.st_size, elf_name);
905                 free(demangled);
906                 if (!f)
907                         goto out_elf_end;
908
909                 if (filter && filter(curr_map, f))
910                         symbol__delete(f);
911                 else {
912                         symbols__insert(&curr_dso->symbols[curr_map->type], f);
913                         nr++;
914                 }
915         }
916
917         /*
918          * For misannotated, zeroed, ASM function sizes.
919          */
920         if (nr > 0)
921                 symbols__fixup_end(&self->symbols[map->type]);
922         err = nr;
923 out_elf_end:
924         elf_end(elf);
925 out_close:
926         return err;
927 }
928
929 static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
930 {
931         return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
932 }
933
934 static bool __dsos__read_build_ids(struct list_head *head)
935 {
936         bool have_build_id = false;
937         struct dso *pos;
938
939         list_for_each_entry(pos, head, node)
940                 if (filename__read_build_id(pos->long_name, pos->build_id,
941                                             sizeof(pos->build_id)) > 0) {
942                         have_build_id     = true;
943                         pos->has_build_id = true;
944                 }
945
946         return have_build_id;
947 }
948
949 bool dsos__read_build_ids(void)
950 {
951         return __dsos__read_build_ids(&dsos__kernel) ||
952                __dsos__read_build_ids(&dsos__user);
953 }
954
955 /*
956  * Align offset to 4 bytes as needed for note name and descriptor data.
957  */
958 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
959
960 int filename__read_build_id(const char *filename, void *bf, size_t size)
961 {
962         int fd, err = -1;
963         GElf_Ehdr ehdr;
964         GElf_Shdr shdr;
965         Elf_Data *data;
966         Elf_Scn *sec;
967         Elf_Kind ek;
968         void *ptr;
969         Elf *elf;
970
971         if (size < BUILD_ID_SIZE)
972                 goto out;
973
974         fd = open(filename, O_RDONLY);
975         if (fd < 0)
976                 goto out;
977
978         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
979         if (elf == NULL) {
980                 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
981                 goto out_close;
982         }
983
984         ek = elf_kind(elf);
985         if (ek != ELF_K_ELF)
986                 goto out_elf_end;
987
988         if (gelf_getehdr(elf, &ehdr) == NULL) {
989                 pr_err("%s: cannot get elf header.\n", __func__);
990                 goto out_elf_end;
991         }
992
993         sec = elf_section_by_name(elf, &ehdr, &shdr,
994                                   ".note.gnu.build-id", NULL);
995         if (sec == NULL) {
996                 sec = elf_section_by_name(elf, &ehdr, &shdr,
997                                           ".notes", NULL);
998                 if (sec == NULL)
999                         goto out_elf_end;
1000         }
1001
1002         data = elf_getdata(sec, NULL);
1003         if (data == NULL)
1004                 goto out_elf_end;
1005
1006         ptr = data->d_buf;
1007         while (ptr < (data->d_buf + data->d_size)) {
1008                 GElf_Nhdr *nhdr = ptr;
1009                 int namesz = NOTE_ALIGN(nhdr->n_namesz),
1010                     descsz = NOTE_ALIGN(nhdr->n_descsz);
1011                 const char *name;
1012
1013                 ptr += sizeof(*nhdr);
1014                 name = ptr;
1015                 ptr += namesz;
1016                 if (nhdr->n_type == NT_GNU_BUILD_ID &&
1017                     nhdr->n_namesz == sizeof("GNU")) {
1018                         if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1019                                 memcpy(bf, ptr, BUILD_ID_SIZE);
1020                                 err = BUILD_ID_SIZE;
1021                                 break;
1022                         }
1023                 }
1024                 ptr += descsz;
1025         }
1026 out_elf_end:
1027         elf_end(elf);
1028 out_close:
1029         close(fd);
1030 out:
1031         return err;
1032 }
1033
1034 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1035 {
1036         int fd, err = -1;
1037
1038         if (size < BUILD_ID_SIZE)
1039                 goto out;
1040
1041         fd = open(filename, O_RDONLY);
1042         if (fd < 0)
1043                 goto out;
1044
1045         while (1) {
1046                 char bf[BUFSIZ];
1047                 GElf_Nhdr nhdr;
1048                 int namesz, descsz;
1049
1050                 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1051                         break;
1052
1053                 namesz = NOTE_ALIGN(nhdr.n_namesz);
1054                 descsz = NOTE_ALIGN(nhdr.n_descsz);
1055                 if (nhdr.n_type == NT_GNU_BUILD_ID &&
1056                     nhdr.n_namesz == sizeof("GNU")) {
1057                         if (read(fd, bf, namesz) != namesz)
1058                                 break;
1059                         if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1060                                 if (read(fd, build_id,
1061                                     BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1062                                         err = 0;
1063                                         break;
1064                                 }
1065                         } else if (read(fd, bf, descsz) != descsz)
1066                                 break;
1067                 } else {
1068                         int n = namesz + descsz;
1069                         if (read(fd, bf, n) != n)
1070                                 break;
1071                 }
1072         }
1073         close(fd);
1074 out:
1075         return err;
1076 }
1077
1078 char dso__symtab_origin(const struct dso *self)
1079 {
1080         static const char origin[] = {
1081                 [DSO__ORIG_KERNEL] =   'k',
1082                 [DSO__ORIG_JAVA_JIT] = 'j',
1083                 [DSO__ORIG_FEDORA] =   'f',
1084                 [DSO__ORIG_UBUNTU] =   'u',
1085                 [DSO__ORIG_BUILDID] =  'b',
1086                 [DSO__ORIG_DSO] =      'd',
1087                 [DSO__ORIG_KMODULE] =  'K',
1088         };
1089
1090         if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
1091                 return '!';
1092         return origin[self->origin];
1093 }
1094
1095 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1096 {
1097         int size = PATH_MAX;
1098         char *name;
1099         u8 build_id[BUILD_ID_SIZE];
1100         int ret = -1;
1101         int fd;
1102
1103         dso__set_loaded(self, map->type);
1104
1105         if (self->kernel)
1106                 return dso__load_kernel_sym(self, map, filter);
1107
1108         name = malloc(size);
1109         if (!name)
1110                 return -1;
1111
1112         self->adjust_symbols = 0;
1113
1114         if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1115                 ret = dso__load_perf_map(self, map, filter);
1116                 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
1117                                          DSO__ORIG_NOT_FOUND;
1118                 return ret;
1119         }
1120
1121         self->origin = DSO__ORIG_FEDORA - 1;
1122
1123 more:
1124         do {
1125                 self->origin++;
1126                 switch (self->origin) {
1127                 case DSO__ORIG_FEDORA:
1128                         snprintf(name, size, "/usr/lib/debug%s.debug",
1129                                  self->long_name);
1130                         break;
1131                 case DSO__ORIG_UBUNTU:
1132                         snprintf(name, size, "/usr/lib/debug%s",
1133                                  self->long_name);
1134                         break;
1135                 case DSO__ORIG_BUILDID:
1136                         if (filename__read_build_id(self->long_name, build_id,
1137                                                     sizeof(build_id))) {
1138                                 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1139
1140                                 build_id__sprintf(build_id, sizeof(build_id),
1141                                                   build_id_hex);
1142                                 snprintf(name, size,
1143                                          "/usr/lib/debug/.build-id/%.2s/%s.debug",
1144                                         build_id_hex, build_id_hex + 2);
1145                                 if (self->has_build_id)
1146                                         goto compare_build_id;
1147                                 break;
1148                         }
1149                         self->origin++;
1150                         /* Fall thru */
1151                 case DSO__ORIG_DSO:
1152                         snprintf(name, size, "%s", self->long_name);
1153                         break;
1154
1155                 default:
1156                         goto out;
1157                 }
1158
1159                 if (self->has_build_id) {
1160                         if (filename__read_build_id(name, build_id,
1161                                                     sizeof(build_id)) < 0)
1162                                 goto more;
1163 compare_build_id:
1164                         if (!dso__build_id_equal(self, build_id))
1165                                 goto more;
1166                 }
1167
1168                 fd = open(name, O_RDONLY);
1169         } while (fd < 0);
1170
1171         ret = dso__load_sym(self, map, name, fd, filter, 0, 0);
1172         close(fd);
1173
1174         /*
1175          * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1176          */
1177         if (!ret)
1178                 goto more;
1179
1180         if (ret > 0) {
1181                 int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1182                 if (nr_plt > 0)
1183                         ret += nr_plt;
1184         }
1185 out:
1186         free(name);
1187         if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1188                 return 0;
1189         return ret;
1190 }
1191
1192 static void kernel_maps__insert(struct map *map)
1193 {
1194         maps__insert(&kernel_maps__functions, map);
1195 }
1196
1197 struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp,
1198                                           symbol_filter_t filter)
1199 {
1200         struct map *map = maps__find(&kernel_maps__functions, ip);
1201
1202         if (mapp)
1203                 *mapp = map;
1204
1205         if (map) {
1206                 ip = map->map_ip(map, ip);
1207                 return map__find_symbol(map, ip, filter);
1208         } else
1209                 WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps__functions),
1210                           "Empty kernel_maps, was symbol__init() called?\n");
1211
1212         return NULL;
1213 }
1214
1215 struct map *kernel_maps__find_by_dso_name(const char *name)
1216 {
1217         struct rb_node *nd;
1218
1219         for (nd = rb_first(&kernel_maps__functions); nd; nd = rb_next(nd)) {
1220                 struct map *map = rb_entry(nd, struct map, rb_node);
1221
1222                 if (map->dso && strcmp(map->dso->name, name) == 0)
1223                         return map;
1224         }
1225
1226         return NULL;
1227 }
1228
1229 static int dsos__set_modules_path_dir(char *dirname)
1230 {
1231         struct dirent *dent;
1232         DIR *dir = opendir(dirname);
1233
1234         if (!dir) {
1235                 pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1236                 return -1;
1237         }
1238
1239         while ((dent = readdir(dir)) != NULL) {
1240                 char path[PATH_MAX];
1241
1242                 if (dent->d_type == DT_DIR) {
1243                         if (!strcmp(dent->d_name, ".") ||
1244                             !strcmp(dent->d_name, ".."))
1245                                 continue;
1246
1247                         snprintf(path, sizeof(path), "%s/%s",
1248                                  dirname, dent->d_name);
1249                         if (dsos__set_modules_path_dir(path) < 0)
1250                                 goto failure;
1251                 } else {
1252                         char *dot = strrchr(dent->d_name, '.'),
1253                              dso_name[PATH_MAX];
1254                         struct map *map;
1255                         char *long_name;
1256
1257                         if (dot == NULL || strcmp(dot, ".ko"))
1258                                 continue;
1259                         snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1260                                  (int)(dot - dent->d_name), dent->d_name);
1261
1262                         strxfrchar(dso_name, '-', '_');
1263                         map = kernel_maps__find_by_dso_name(dso_name);
1264                         if (map == NULL)
1265                                 continue;
1266
1267                         snprintf(path, sizeof(path), "%s/%s",
1268                                  dirname, dent->d_name);
1269
1270                         long_name = strdup(path);
1271                         if (long_name == NULL)
1272                                 goto failure;
1273                         dso__set_long_name(map->dso, long_name);
1274                 }
1275         }
1276
1277         return 0;
1278 failure:
1279         closedir(dir);
1280         return -1;
1281 }
1282
1283 static int dsos__set_modules_path(void)
1284 {
1285         struct utsname uts;
1286         char modules_path[PATH_MAX];
1287
1288         if (uname(&uts) < 0)
1289                 return -1;
1290
1291         snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1292                  uts.release);
1293
1294         return dsos__set_modules_path_dir(modules_path);
1295 }
1296
1297 /*
1298  * Constructor variant for modules (where we know from /proc/modules where
1299  * they are loaded) and for vmlinux, where only after we load all the
1300  * symbols we'll know where it starts and ends.
1301  */
1302 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1303 {
1304         struct map *self = malloc(sizeof(*self));
1305
1306         if (self != NULL) {
1307                 /*
1308                  * ->end will be filled after we load all the symbols
1309                  */
1310                 map__init(self, type, start, 0, 0, dso);
1311         }
1312
1313         return self;
1314 }
1315
1316 static int kernel_maps__create_module_maps(void)
1317 {
1318         char *line = NULL;
1319         size_t n;
1320         FILE *file = fopen("/proc/modules", "r");
1321         struct map *map;
1322
1323         if (file == NULL)
1324                 return -1;
1325
1326         while (!feof(file)) {
1327                 char name[PATH_MAX];
1328                 u64 start;
1329                 struct dso *dso;
1330                 char *sep;
1331                 int line_len;
1332
1333                 line_len = getline(&line, &n, file);
1334                 if (line_len < 0)
1335                         break;
1336
1337                 if (!line)
1338                         goto out_failure;
1339
1340                 line[--line_len] = '\0'; /* \n */
1341
1342                 sep = strrchr(line, 'x');
1343                 if (sep == NULL)
1344                         continue;
1345
1346                 hex2u64(sep + 1, &start);
1347
1348                 sep = strchr(line, ' ');
1349                 if (sep == NULL)
1350                         continue;
1351
1352                 *sep = '\0';
1353
1354                 snprintf(name, sizeof(name), "[%s]", line);
1355                 dso = dso__new(name);
1356
1357                 if (dso == NULL)
1358                         goto out_delete_line;
1359
1360                 map = map__new2(start, dso, MAP__FUNCTION);
1361                 if (map == NULL) {
1362                         dso__delete(dso);
1363                         goto out_delete_line;
1364                 }
1365
1366                 snprintf(name, sizeof(name),
1367                          "/sys/module/%s/notes/.note.gnu.build-id", line);
1368                 if (sysfs__read_build_id(name, dso->build_id,
1369                                          sizeof(dso->build_id)) == 0)
1370                         dso->has_build_id = true;
1371
1372                 dso->origin = DSO__ORIG_KMODULE;
1373                 kernel_maps__insert(map);
1374                 dsos__add(&dsos__kernel, dso);
1375         }
1376
1377         free(line);
1378         fclose(file);
1379
1380         return dsos__set_modules_path();
1381
1382 out_delete_line:
1383         free(line);
1384 out_failure:
1385         return -1;
1386 }
1387
1388 static int dso__load_vmlinux(struct dso *self, struct map *map,
1389                              const char *vmlinux, symbol_filter_t filter)
1390 {
1391         int err = -1, fd;
1392
1393         if (self->has_build_id) {
1394                 u8 build_id[BUILD_ID_SIZE];
1395
1396                 if (filename__read_build_id(vmlinux, build_id,
1397                                             sizeof(build_id)) < 0) {
1398                         pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1399                         return -1;
1400                 }
1401                 if (!dso__build_id_equal(self, build_id)) {
1402                         char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1403                              vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1404
1405                         build_id__sprintf(self->build_id,
1406                                           sizeof(self->build_id),
1407                                           expected_build_id);
1408                         build_id__sprintf(build_id, sizeof(build_id),
1409                                           vmlinux_build_id);
1410                         pr_debug("build_id in %s is %s while expected is %s, "
1411                                  "ignoring it\n", vmlinux, vmlinux_build_id,
1412                                  expected_build_id);
1413                         return -1;
1414                 }
1415         }
1416
1417         fd = open(vmlinux, O_RDONLY);
1418         if (fd < 0)
1419                 return -1;
1420
1421         dso__set_loaded(self, map->type);
1422         err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0);
1423
1424         close(fd);
1425
1426         return err;
1427 }
1428
1429 static int dso__load_kernel_sym(struct dso *self, struct map *map,
1430                                 symbol_filter_t filter)
1431 {
1432         int err;
1433         bool is_kallsyms;
1434
1435         if (vmlinux_path != NULL) {
1436                 int i;
1437                 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1438                          vmlinux_path__nr_entries);
1439                 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1440                         err = dso__load_vmlinux(self, map, vmlinux_path[i],
1441                                                 filter);
1442                         if (err > 0) {
1443                                 pr_debug("Using %s for symbols\n",
1444                                          vmlinux_path[i]);
1445                                 dso__set_long_name(self,
1446                                                    strdup(vmlinux_path[i]));
1447                                 goto out_fixup;
1448                         }
1449                 }
1450         }
1451
1452         is_kallsyms = self->long_name[0] == '[';
1453         if (is_kallsyms)
1454                 goto do_kallsyms;
1455
1456         err = dso__load_vmlinux(self, map, self->long_name, filter);
1457         if (err <= 0) {
1458                 pr_info("The file %s cannot be used, "
1459                         "trying to use /proc/kallsyms...", self->long_name);
1460                 sleep(2);
1461 do_kallsyms:
1462                 err = kernel_maps__load_kallsyms(filter);
1463                 if (err > 0 && !is_kallsyms)
1464                         dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1465         }
1466
1467         if (err > 0) {
1468 out_fixup:
1469                 map__fixup_start(map);
1470                 map__fixup_end(map);
1471         }
1472
1473         return err;
1474 }
1475
1476 LIST_HEAD(dsos__user);
1477 LIST_HEAD(dsos__kernel);
1478 struct dso *vdso;
1479
1480 static void dsos__add(struct list_head *head, struct dso *dso)
1481 {
1482         list_add_tail(&dso->node, head);
1483 }
1484
1485 static struct dso *dsos__find(struct list_head *head, const char *name)
1486 {
1487         struct dso *pos;
1488
1489         list_for_each_entry(pos, head, node)
1490                 if (strcmp(pos->name, name) == 0)
1491                         return pos;
1492         return NULL;
1493 }
1494
1495 struct dso *dsos__findnew(const char *name)
1496 {
1497         struct dso *dso = dsos__find(&dsos__user, name);
1498
1499         if (!dso) {
1500                 dso = dso__new(name);
1501                 if (dso != NULL) {
1502                         dsos__add(&dsos__user, dso);
1503                         dso__set_basename(dso);
1504                 }
1505         }
1506
1507         return dso;
1508 }
1509
1510 static void __dsos__fprintf(struct list_head *head, FILE *fp)
1511 {
1512         struct dso *pos;
1513
1514         list_for_each_entry(pos, head, node)
1515                 dso__fprintf(pos, fp);
1516 }
1517
1518 void dsos__fprintf(FILE *fp)
1519 {
1520         __dsos__fprintf(&dsos__kernel, fp);
1521         __dsos__fprintf(&dsos__user, fp);
1522 }
1523
1524 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp)
1525 {
1526         struct dso *pos;
1527         size_t ret = 0;
1528
1529         list_for_each_entry(pos, head, node) {
1530                 ret += dso__fprintf_buildid(pos, fp);
1531                 ret += fprintf(fp, " %s\n", pos->long_name);
1532         }
1533         return ret;
1534 }
1535
1536 size_t dsos__fprintf_buildid(FILE *fp)
1537 {
1538         return (__dsos__fprintf_buildid(&dsos__kernel, fp) +
1539                 __dsos__fprintf_buildid(&dsos__user, fp));
1540 }
1541
1542 static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
1543 {
1544         struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]");
1545
1546         if (kernel == NULL)
1547                 return -1;
1548
1549         kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION);
1550         if (kernel_map__functions == NULL)
1551                 goto out_delete_kernel_dso;
1552
1553         kernel_map__functions->map_ip    = kernel_map__functions->unmap_ip = identity__map_ip;
1554         kernel->short_name       = "[kernel]";
1555         kernel->kernel           = 1;
1556
1557         vdso = dso__new("[vdso]");
1558         if (vdso == NULL)
1559                 goto out_delete_kernel_map;
1560         dso__set_loaded(vdso, MAP__FUNCTION);
1561
1562         if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
1563                                  sizeof(kernel->build_id)) == 0)
1564                 kernel->has_build_id = true;
1565
1566         kernel_maps__insert(kernel_map__functions);
1567         dsos__add(&dsos__kernel, kernel);
1568         dsos__add(&dsos__user, vdso);
1569
1570         return 0;
1571
1572 out_delete_kernel_map:
1573         map__delete(kernel_map__functions);
1574         kernel_map__functions = NULL;
1575 out_delete_kernel_dso:
1576         dso__delete(kernel);
1577         return -1;
1578 }
1579
1580 static void vmlinux_path__exit(void)
1581 {
1582         while (--vmlinux_path__nr_entries >= 0) {
1583                 free(vmlinux_path[vmlinux_path__nr_entries]);
1584                 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1585         }
1586
1587         free(vmlinux_path);
1588         vmlinux_path = NULL;
1589 }
1590
1591 static int vmlinux_path__init(void)
1592 {
1593         struct utsname uts;
1594         char bf[PATH_MAX];
1595
1596         if (uname(&uts) < 0)
1597                 return -1;
1598
1599         vmlinux_path = malloc(sizeof(char *) * 5);
1600         if (vmlinux_path == NULL)
1601                 return -1;
1602
1603         vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1604         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1605                 goto out_fail;
1606         ++vmlinux_path__nr_entries;
1607         vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1608         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1609                 goto out_fail;
1610         ++vmlinux_path__nr_entries;
1611         snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1612         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1613         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1614                 goto out_fail;
1615         ++vmlinux_path__nr_entries;
1616         snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1617         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1618         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1619                 goto out_fail;
1620         ++vmlinux_path__nr_entries;
1621         snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1622                  uts.release);
1623         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1624         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1625                 goto out_fail;
1626         ++vmlinux_path__nr_entries;
1627
1628         return 0;
1629
1630 out_fail:
1631         vmlinux_path__exit();
1632         return -1;
1633 }
1634
1635 static int kernel_maps__init(const struct symbol_conf *conf)
1636 {
1637         const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
1638
1639         symbol__priv_size = pconf->priv_size;
1640
1641         if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1642                 return -1;
1643
1644         if (kernel_maps__create_kernel_map(pconf) < 0) {
1645                 vmlinux_path__exit();
1646                 return -1;
1647         }
1648
1649         if (pconf->use_modules && kernel_maps__create_module_maps() < 0)
1650                 pr_debug("Failed to load list of modules in use, "
1651                          "continuing...\n");
1652         /*
1653          * Now that we have all the maps created, just set the ->end of them:
1654          */
1655         kernel_maps__fixup_end();
1656         return 0;
1657 }
1658
1659 int symbol__init(struct symbol_conf *conf)
1660 {
1661         elf_version(EV_CURRENT);
1662         return kernel_maps__init(conf);
1663 }