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