perf symbols: Introduce 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 int dso__load_sym(struct dso *self, struct map *map,
755                          struct map_groups *mg, const char *name, int fd,
756                          symbol_filter_t filter, int kernel, int kmodule)
757 {
758         struct map *curr_map = map;
759         struct dso *curr_dso = self;
760         size_t dso_name_len = strlen(self->short_name);
761         Elf_Data *symstrs, *secstrs;
762         uint32_t nr_syms;
763         int err = -1;
764         uint32_t idx;
765         GElf_Ehdr ehdr;
766         GElf_Shdr shdr;
767         Elf_Data *syms;
768         GElf_Sym sym;
769         Elf_Scn *sec, *sec_strndx;
770         Elf *elf;
771         int nr = 0;
772
773         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
774         if (elf == NULL) {
775                 pr_err("%s: cannot read %s ELF file.\n", __func__, name);
776                 goto out_close;
777         }
778
779         if (gelf_getehdr(elf, &ehdr) == NULL) {
780                 pr_err("%s: cannot get elf header.\n", __func__);
781                 goto out_elf_end;
782         }
783
784         sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
785         if (sec == NULL) {
786                 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
787                 if (sec == NULL)
788                         goto out_elf_end;
789         }
790
791         syms = elf_getdata(sec, NULL);
792         if (syms == NULL)
793                 goto out_elf_end;
794
795         sec = elf_getscn(elf, shdr.sh_link);
796         if (sec == NULL)
797                 goto out_elf_end;
798
799         symstrs = elf_getdata(sec, NULL);
800         if (symstrs == NULL)
801                 goto out_elf_end;
802
803         sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
804         if (sec_strndx == NULL)
805                 goto out_elf_end;
806
807         secstrs = elf_getdata(sec_strndx, NULL);
808         if (secstrs == NULL)
809                 goto out_elf_end;
810
811         nr_syms = shdr.sh_size / shdr.sh_entsize;
812
813         memset(&sym, 0, sizeof(sym));
814         if (!kernel) {
815                 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
816                                 elf_section_by_name(elf, &ehdr, &shdr,
817                                                      ".gnu.prelink_undo",
818                                                      NULL) != NULL);
819         } else self->adjust_symbols = 0;
820
821         elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
822                 struct symbol *f;
823                 const char *elf_name;
824                 char *demangled = NULL;
825                 int is_label = elf_sym__is_label(&sym);
826                 const char *section_name;
827
828                 if (!is_label && !elf_sym__is_function(&sym))
829                         continue;
830
831                 sec = elf_getscn(elf, sym.st_shndx);
832                 if (!sec)
833                         goto out_elf_end;
834
835                 gelf_getshdr(sec, &shdr);
836
837                 if (is_label && !elf_sec__is_text(&shdr, secstrs))
838                         continue;
839
840                 elf_name = elf_sym__name(&sym, symstrs);
841                 section_name = elf_sec__name(&shdr, secstrs);
842
843                 if (kernel || kmodule) {
844                         char dso_name[PATH_MAX];
845
846                         if (strcmp(section_name,
847                                    curr_dso->short_name + dso_name_len) == 0)
848                                 goto new_symbol;
849
850                         if (strcmp(section_name, ".text") == 0) {
851                                 curr_map = map;
852                                 curr_dso = self;
853                                 goto new_symbol;
854                         }
855
856                         snprintf(dso_name, sizeof(dso_name),
857                                  "%s%s", self->short_name, section_name);
858
859                         curr_map = map_groups__find_by_name(mg, dso_name);
860                         if (curr_map == NULL) {
861                                 u64 start = sym.st_value;
862
863                                 if (kmodule)
864                                         start += map->start + shdr.sh_offset;
865
866                                 curr_dso = dso__new(dso_name);
867                                 if (curr_dso == NULL)
868                                         goto out_elf_end;
869                                 curr_map = map__new2(start, curr_dso,
870                                                      MAP__FUNCTION);
871                                 if (curr_map == NULL) {
872                                         dso__delete(curr_dso);
873                                         goto out_elf_end;
874                                 }
875                                 curr_map->map_ip = identity__map_ip;
876                                 curr_map->unmap_ip = identity__map_ip;
877                                 curr_dso->origin = DSO__ORIG_KERNEL;
878                                 map_groups__insert(kmaps, curr_map);
879                                 dsos__add(&dsos__kernel, curr_dso);
880                         } else
881                                 curr_dso = curr_map->dso;
882
883                         goto new_symbol;
884                 }
885
886                 if (curr_dso->adjust_symbols) {
887                         pr_debug2("adjusting symbol: st_value: %Lx sh_addr: "
888                                   "%Lx sh_offset: %Lx\n", (u64)sym.st_value,
889                                   (u64)shdr.sh_addr, (u64)shdr.sh_offset);
890                         sym.st_value -= shdr.sh_addr - shdr.sh_offset;
891                 }
892                 /*
893                  * We need to figure out if the object was created from C++ sources
894                  * DWARF DW_compile_unit has this, but we don't always have access
895                  * to it...
896                  */
897                 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
898                 if (demangled != NULL)
899                         elf_name = demangled;
900 new_symbol:
901                 f = symbol__new(sym.st_value, sym.st_size, elf_name);
902                 free(demangled);
903                 if (!f)
904                         goto out_elf_end;
905
906                 if (filter && filter(curr_map, f))
907                         symbol__delete(f);
908                 else {
909                         symbols__insert(&curr_dso->symbols[curr_map->type], f);
910                         nr++;
911                 }
912         }
913
914         /*
915          * For misannotated, zeroed, ASM function sizes.
916          */
917         if (nr > 0)
918                 symbols__fixup_end(&self->symbols[map->type]);
919         err = nr;
920 out_elf_end:
921         elf_end(elf);
922 out_close:
923         return err;
924 }
925
926 static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
927 {
928         return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
929 }
930
931 static bool __dsos__read_build_ids(struct list_head *head)
932 {
933         bool have_build_id = false;
934         struct dso *pos;
935
936         list_for_each_entry(pos, head, node)
937                 if (filename__read_build_id(pos->long_name, pos->build_id,
938                                             sizeof(pos->build_id)) > 0) {
939                         have_build_id     = true;
940                         pos->has_build_id = true;
941                 }
942
943         return have_build_id;
944 }
945
946 bool dsos__read_build_ids(void)
947 {
948         bool kbuildids = __dsos__read_build_ids(&dsos__kernel),
949              ubuildids = __dsos__read_build_ids(&dsos__user);
950         return kbuildids || ubuildids;
951 }
952
953 /*
954  * Align offset to 4 bytes as needed for note name and descriptor data.
955  */
956 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
957
958 int filename__read_build_id(const char *filename, void *bf, size_t size)
959 {
960         int fd, err = -1;
961         GElf_Ehdr ehdr;
962         GElf_Shdr shdr;
963         Elf_Data *data;
964         Elf_Scn *sec;
965         Elf_Kind ek;
966         void *ptr;
967         Elf *elf;
968
969         if (size < BUILD_ID_SIZE)
970                 goto out;
971
972         fd = open(filename, O_RDONLY);
973         if (fd < 0)
974                 goto out;
975
976         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
977         if (elf == NULL) {
978                 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
979                 goto out_close;
980         }
981
982         ek = elf_kind(elf);
983         if (ek != ELF_K_ELF)
984                 goto out_elf_end;
985
986         if (gelf_getehdr(elf, &ehdr) == NULL) {
987                 pr_err("%s: cannot get elf header.\n", __func__);
988                 goto out_elf_end;
989         }
990
991         sec = elf_section_by_name(elf, &ehdr, &shdr,
992                                   ".note.gnu.build-id", NULL);
993         if (sec == NULL) {
994                 sec = elf_section_by_name(elf, &ehdr, &shdr,
995                                           ".notes", NULL);
996                 if (sec == NULL)
997                         goto out_elf_end;
998         }
999
1000         data = elf_getdata(sec, NULL);
1001         if (data == NULL)
1002                 goto out_elf_end;
1003
1004         ptr = data->d_buf;
1005         while (ptr < (data->d_buf + data->d_size)) {
1006                 GElf_Nhdr *nhdr = ptr;
1007                 int namesz = NOTE_ALIGN(nhdr->n_namesz),
1008                     descsz = NOTE_ALIGN(nhdr->n_descsz);
1009                 const char *name;
1010
1011                 ptr += sizeof(*nhdr);
1012                 name = ptr;
1013                 ptr += namesz;
1014                 if (nhdr->n_type == NT_GNU_BUILD_ID &&
1015                     nhdr->n_namesz == sizeof("GNU")) {
1016                         if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1017                                 memcpy(bf, ptr, BUILD_ID_SIZE);
1018                                 err = BUILD_ID_SIZE;
1019                                 break;
1020                         }
1021                 }
1022                 ptr += descsz;
1023         }
1024 out_elf_end:
1025         elf_end(elf);
1026 out_close:
1027         close(fd);
1028 out:
1029         return err;
1030 }
1031
1032 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1033 {
1034         int fd, err = -1;
1035
1036         if (size < BUILD_ID_SIZE)
1037                 goto out;
1038
1039         fd = open(filename, O_RDONLY);
1040         if (fd < 0)
1041                 goto out;
1042
1043         while (1) {
1044                 char bf[BUFSIZ];
1045                 GElf_Nhdr nhdr;
1046                 int namesz, descsz;
1047
1048                 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1049                         break;
1050
1051                 namesz = NOTE_ALIGN(nhdr.n_namesz);
1052                 descsz = NOTE_ALIGN(nhdr.n_descsz);
1053                 if (nhdr.n_type == NT_GNU_BUILD_ID &&
1054                     nhdr.n_namesz == sizeof("GNU")) {
1055                         if (read(fd, bf, namesz) != namesz)
1056                                 break;
1057                         if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1058                                 if (read(fd, build_id,
1059                                     BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1060                                         err = 0;
1061                                         break;
1062                                 }
1063                         } else if (read(fd, bf, descsz) != descsz)
1064                                 break;
1065                 } else {
1066                         int n = namesz + descsz;
1067                         if (read(fd, bf, n) != n)
1068                                 break;
1069                 }
1070         }
1071         close(fd);
1072 out:
1073         return err;
1074 }
1075
1076 char dso__symtab_origin(const struct dso *self)
1077 {
1078         static const char origin[] = {
1079                 [DSO__ORIG_KERNEL] =   'k',
1080                 [DSO__ORIG_JAVA_JIT] = 'j',
1081                 [DSO__ORIG_FEDORA] =   'f',
1082                 [DSO__ORIG_UBUNTU] =   'u',
1083                 [DSO__ORIG_BUILDID] =  'b',
1084                 [DSO__ORIG_DSO] =      'd',
1085                 [DSO__ORIG_KMODULE] =  'K',
1086         };
1087
1088         if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
1089                 return '!';
1090         return origin[self->origin];
1091 }
1092
1093 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1094 {
1095         int size = PATH_MAX;
1096         char *name;
1097         u8 build_id[BUILD_ID_SIZE];
1098         int ret = -1;
1099         int fd;
1100
1101         dso__set_loaded(self, map->type);
1102
1103         if (self->kernel)
1104                 return dso__load_kernel_sym(self, map, kmaps, filter);
1105
1106         name = malloc(size);
1107         if (!name)
1108                 return -1;
1109
1110         self->adjust_symbols = 0;
1111
1112         if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1113                 ret = dso__load_perf_map(self, map, filter);
1114                 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
1115                                          DSO__ORIG_NOT_FOUND;
1116                 return ret;
1117         }
1118
1119         self->origin = DSO__ORIG_FEDORA - 1;
1120
1121 more:
1122         do {
1123                 self->origin++;
1124                 switch (self->origin) {
1125                 case DSO__ORIG_FEDORA:
1126                         snprintf(name, size, "/usr/lib/debug%s.debug",
1127                                  self->long_name);
1128                         break;
1129                 case DSO__ORIG_UBUNTU:
1130                         snprintf(name, size, "/usr/lib/debug%s",
1131                                  self->long_name);
1132                         break;
1133                 case DSO__ORIG_BUILDID:
1134                         if (filename__read_build_id(self->long_name, build_id,
1135                                                     sizeof(build_id))) {
1136                                 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1137
1138                                 build_id__sprintf(build_id, sizeof(build_id),
1139                                                   build_id_hex);
1140                                 snprintf(name, size,
1141                                          "/usr/lib/debug/.build-id/%.2s/%s.debug",
1142                                         build_id_hex, build_id_hex + 2);
1143                                 if (self->has_build_id)
1144                                         goto compare_build_id;
1145                                 break;
1146                         }
1147                         self->origin++;
1148                         /* Fall thru */
1149                 case DSO__ORIG_DSO:
1150                         snprintf(name, size, "%s", self->long_name);
1151                         break;
1152
1153                 default:
1154                         goto out;
1155                 }
1156
1157                 if (self->has_build_id) {
1158                         if (filename__read_build_id(name, build_id,
1159                                                     sizeof(build_id)) < 0)
1160                                 goto more;
1161 compare_build_id:
1162                         if (!dso__build_id_equal(self, build_id))
1163                                 goto more;
1164                 }
1165
1166                 fd = open(name, O_RDONLY);
1167         } while (fd < 0);
1168
1169         ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0);
1170         close(fd);
1171
1172         /*
1173          * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1174          */
1175         if (!ret)
1176                 goto more;
1177
1178         if (ret > 0) {
1179                 int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1180                 if (nr_plt > 0)
1181                         ret += nr_plt;
1182         }
1183 out:
1184         free(name);
1185         if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1186                 return 0;
1187         return ret;
1188 }
1189
1190 static struct map *map_groups__find_by_name(struct map_groups *self, char *name)
1191 {
1192         struct rb_node *nd;
1193
1194         for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
1195                 struct map *map = rb_entry(nd, struct map, rb_node);
1196
1197                 if (map->dso && strcmp(map->dso->name, name) == 0)
1198                         return map;
1199         }
1200
1201         return NULL;
1202 }
1203
1204 static int dsos__set_modules_path_dir(char *dirname)
1205 {
1206         struct dirent *dent;
1207         DIR *dir = opendir(dirname);
1208
1209         if (!dir) {
1210                 pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1211                 return -1;
1212         }
1213
1214         while ((dent = readdir(dir)) != NULL) {
1215                 char path[PATH_MAX];
1216
1217                 if (dent->d_type == DT_DIR) {
1218                         if (!strcmp(dent->d_name, ".") ||
1219                             !strcmp(dent->d_name, ".."))
1220                                 continue;
1221
1222                         snprintf(path, sizeof(path), "%s/%s",
1223                                  dirname, dent->d_name);
1224                         if (dsos__set_modules_path_dir(path) < 0)
1225                                 goto failure;
1226                 } else {
1227                         char *dot = strrchr(dent->d_name, '.'),
1228                              dso_name[PATH_MAX];
1229                         struct map *map;
1230                         char *long_name;
1231
1232                         if (dot == NULL || strcmp(dot, ".ko"))
1233                                 continue;
1234                         snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1235                                  (int)(dot - dent->d_name), dent->d_name);
1236
1237                         strxfrchar(dso_name, '-', '_');
1238                         map = map_groups__find_by_name(kmaps, dso_name);
1239                         if (map == NULL)
1240                                 continue;
1241
1242                         snprintf(path, sizeof(path), "%s/%s",
1243                                  dirname, dent->d_name);
1244
1245                         long_name = strdup(path);
1246                         if (long_name == NULL)
1247                                 goto failure;
1248                         dso__set_long_name(map->dso, long_name);
1249                 }
1250         }
1251
1252         return 0;
1253 failure:
1254         closedir(dir);
1255         return -1;
1256 }
1257
1258 static int dsos__set_modules_path(void)
1259 {
1260         struct utsname uts;
1261         char modules_path[PATH_MAX];
1262
1263         if (uname(&uts) < 0)
1264                 return -1;
1265
1266         snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1267                  uts.release);
1268
1269         return dsos__set_modules_path_dir(modules_path);
1270 }
1271
1272 /*
1273  * Constructor variant for modules (where we know from /proc/modules where
1274  * they are loaded) and for vmlinux, where only after we load all the
1275  * symbols we'll know where it starts and ends.
1276  */
1277 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1278 {
1279         struct map *self = malloc(sizeof(*self));
1280
1281         if (self != NULL) {
1282                 /*
1283                  * ->end will be filled after we load all the symbols
1284                  */
1285                 map__init(self, type, start, 0, 0, dso);
1286         }
1287
1288         return self;
1289 }
1290
1291 static int map_groups__create_module_maps(struct map_groups *self)
1292 {
1293         char *line = NULL;
1294         size_t n;
1295         FILE *file = fopen("/proc/modules", "r");
1296         struct map *map;
1297
1298         if (file == NULL)
1299                 return -1;
1300
1301         while (!feof(file)) {
1302                 char name[PATH_MAX];
1303                 u64 start;
1304                 struct dso *dso;
1305                 char *sep;
1306                 int line_len;
1307
1308                 line_len = getline(&line, &n, file);
1309                 if (line_len < 0)
1310                         break;
1311
1312                 if (!line)
1313                         goto out_failure;
1314
1315                 line[--line_len] = '\0'; /* \n */
1316
1317                 sep = strrchr(line, 'x');
1318                 if (sep == NULL)
1319                         continue;
1320
1321                 hex2u64(sep + 1, &start);
1322
1323                 sep = strchr(line, ' ');
1324                 if (sep == NULL)
1325                         continue;
1326
1327                 *sep = '\0';
1328
1329                 snprintf(name, sizeof(name), "[%s]", line);
1330                 dso = dso__new(name);
1331
1332                 if (dso == NULL)
1333                         goto out_delete_line;
1334
1335                 map = map__new2(start, dso, MAP__FUNCTION);
1336                 if (map == NULL) {
1337                         dso__delete(dso);
1338                         goto out_delete_line;
1339                 }
1340
1341                 snprintf(name, sizeof(name),
1342                          "/sys/module/%s/notes/.note.gnu.build-id", line);
1343                 if (sysfs__read_build_id(name, dso->build_id,
1344                                          sizeof(dso->build_id)) == 0)
1345                         dso->has_build_id = true;
1346
1347                 dso->origin = DSO__ORIG_KMODULE;
1348                 map_groups__insert(self, map);
1349                 dsos__add(&dsos__kernel, dso);
1350         }
1351
1352         free(line);
1353         fclose(file);
1354
1355         return dsos__set_modules_path();
1356
1357 out_delete_line:
1358         free(line);
1359 out_failure:
1360         return -1;
1361 }
1362
1363 static int dso__load_vmlinux(struct dso *self, struct map *map,
1364                              struct map_groups *mg,
1365                              const char *vmlinux, symbol_filter_t filter)
1366 {
1367         int err = -1, fd;
1368
1369         if (self->has_build_id) {
1370                 u8 build_id[BUILD_ID_SIZE];
1371
1372                 if (filename__read_build_id(vmlinux, build_id,
1373                                             sizeof(build_id)) < 0) {
1374                         pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1375                         return -1;
1376                 }
1377                 if (!dso__build_id_equal(self, build_id)) {
1378                         char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1379                              vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1380
1381                         build_id__sprintf(self->build_id,
1382                                           sizeof(self->build_id),
1383                                           expected_build_id);
1384                         build_id__sprintf(build_id, sizeof(build_id),
1385                                           vmlinux_build_id);
1386                         pr_debug("build_id in %s is %s while expected is %s, "
1387                                  "ignoring it\n", vmlinux, vmlinux_build_id,
1388                                  expected_build_id);
1389                         return -1;
1390                 }
1391         }
1392
1393         fd = open(vmlinux, O_RDONLY);
1394         if (fd < 0)
1395                 return -1;
1396
1397         dso__set_loaded(self, map->type);
1398         err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0);
1399         close(fd);
1400
1401         return err;
1402 }
1403
1404 static int dso__load_kernel_sym(struct dso *self, struct map *map,
1405                                 struct map_groups *mg, symbol_filter_t filter)
1406 {
1407         int err;
1408         bool is_kallsyms;
1409
1410         if (vmlinux_path != NULL) {
1411                 int i;
1412                 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1413                          vmlinux_path__nr_entries);
1414                 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1415                         err = dso__load_vmlinux(self, map, mg,
1416                                                 vmlinux_path[i], filter);
1417                         if (err > 0) {
1418                                 pr_debug("Using %s for symbols\n",
1419                                          vmlinux_path[i]);
1420                                 dso__set_long_name(self,
1421                                                    strdup(vmlinux_path[i]));
1422                                 goto out_fixup;
1423                         }
1424                 }
1425         }
1426
1427         is_kallsyms = self->long_name[0] == '[';
1428         if (is_kallsyms)
1429                 goto do_kallsyms;
1430
1431         err = dso__load_vmlinux(self, map, mg, self->long_name, filter);
1432         if (err <= 0) {
1433                 pr_info("The file %s cannot be used, "
1434                         "trying to use /proc/kallsyms...", self->long_name);
1435 do_kallsyms:
1436                 err = dso__load_kallsyms(self, map, mg, filter);
1437                 if (err > 0 && !is_kallsyms)
1438                         dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1439         }
1440
1441         if (err > 0) {
1442 out_fixup:
1443                 map__fixup_start(map);
1444                 map__fixup_end(map);
1445         }
1446
1447         return err;
1448 }
1449
1450 LIST_HEAD(dsos__user);
1451 LIST_HEAD(dsos__kernel);
1452 struct dso *vdso;
1453
1454 static void dsos__add(struct list_head *head, struct dso *dso)
1455 {
1456         list_add_tail(&dso->node, head);
1457 }
1458
1459 static struct dso *dsos__find(struct list_head *head, const char *name)
1460 {
1461         struct dso *pos;
1462
1463         list_for_each_entry(pos, head, node)
1464                 if (strcmp(pos->name, name) == 0)
1465                         return pos;
1466         return NULL;
1467 }
1468
1469 struct dso *dsos__findnew(const char *name)
1470 {
1471         struct dso *dso = dsos__find(&dsos__user, name);
1472
1473         if (!dso) {
1474                 dso = dso__new(name);
1475                 if (dso != NULL) {
1476                         dsos__add(&dsos__user, dso);
1477                         dso__set_basename(dso);
1478                 }
1479         }
1480
1481         return dso;
1482 }
1483
1484 static void __dsos__fprintf(struct list_head *head, FILE *fp)
1485 {
1486         struct dso *pos;
1487
1488         list_for_each_entry(pos, head, node) {
1489                 int i;
1490                 for (i = 0; i < MAP__NR_TYPES; ++i)
1491                         dso__fprintf(pos, i, fp);
1492         }
1493 }
1494
1495 void dsos__fprintf(FILE *fp)
1496 {
1497         __dsos__fprintf(&dsos__kernel, fp);
1498         __dsos__fprintf(&dsos__user, fp);
1499 }
1500
1501 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp)
1502 {
1503         struct dso *pos;
1504         size_t ret = 0;
1505
1506         list_for_each_entry(pos, head, node) {
1507                 ret += dso__fprintf_buildid(pos, fp);
1508                 ret += fprintf(fp, " %s\n", pos->long_name);
1509         }
1510         return ret;
1511 }
1512
1513 size_t dsos__fprintf_buildid(FILE *fp)
1514 {
1515         return (__dsos__fprintf_buildid(&dsos__kernel, fp) +
1516                 __dsos__fprintf_buildid(&dsos__user, fp));
1517 }
1518
1519 static int map_groups__create_kernel_map(struct map_groups *self, const char *vmlinux)
1520 {
1521         struct map *kmap;
1522         struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]");
1523
1524         if (kernel == NULL)
1525                 return -1;
1526
1527         kmap = map__new2(0, kernel, MAP__FUNCTION);
1528         if (kmap == NULL)
1529                 goto out_delete_kernel_dso;
1530
1531         kmap->map_ip       = kmap->unmap_ip = identity__map_ip;
1532         kernel->short_name = "[kernel]";
1533         kernel->kernel     = 1;
1534
1535         vdso = dso__new("[vdso]");
1536         if (vdso == NULL)
1537                 goto out_delete_kernel_map;
1538         dso__set_loaded(vdso, MAP__FUNCTION);
1539
1540         if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
1541                                  sizeof(kernel->build_id)) == 0)
1542                 kernel->has_build_id = true;
1543
1544         map_groups__insert(self, kmap);
1545         dsos__add(&dsos__kernel, kernel);
1546         dsos__add(&dsos__user, vdso);
1547
1548         return 0;
1549
1550 out_delete_kernel_map:
1551         map__delete(kmap);
1552 out_delete_kernel_dso:
1553         dso__delete(kernel);
1554         return -1;
1555 }
1556
1557 static void vmlinux_path__exit(void)
1558 {
1559         while (--vmlinux_path__nr_entries >= 0) {
1560                 free(vmlinux_path[vmlinux_path__nr_entries]);
1561                 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1562         }
1563
1564         free(vmlinux_path);
1565         vmlinux_path = NULL;
1566 }
1567
1568 static int vmlinux_path__init(void)
1569 {
1570         struct utsname uts;
1571         char bf[PATH_MAX];
1572
1573         if (uname(&uts) < 0)
1574                 return -1;
1575
1576         vmlinux_path = malloc(sizeof(char *) * 5);
1577         if (vmlinux_path == NULL)
1578                 return -1;
1579
1580         vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1581         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1582                 goto out_fail;
1583         ++vmlinux_path__nr_entries;
1584         vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1585         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1586                 goto out_fail;
1587         ++vmlinux_path__nr_entries;
1588         snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1589         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1590         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1591                 goto out_fail;
1592         ++vmlinux_path__nr_entries;
1593         snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1594         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1595         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1596                 goto out_fail;
1597         ++vmlinux_path__nr_entries;
1598         snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1599                  uts.release);
1600         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1601         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1602                 goto out_fail;
1603         ++vmlinux_path__nr_entries;
1604
1605         return 0;
1606
1607 out_fail:
1608         vmlinux_path__exit();
1609         return -1;
1610 }
1611
1612 int symbol__init(struct symbol_conf *conf)
1613 {
1614         const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
1615
1616         elf_version(EV_CURRENT);
1617         symbol__priv_size = pconf->priv_size;
1618         map_groups__init(kmaps);
1619
1620         if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1621                 return -1;
1622
1623         if (map_groups__create_kernel_map(kmaps, pconf->vmlinux_name) < 0) {
1624                 vmlinux_path__exit();
1625                 return -1;
1626         }
1627
1628         kmaps->use_modules = pconf->use_modules;
1629         if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0)
1630                 pr_debug("Failed to load list of modules in use, "
1631                          "continuing...\n");
1632         /*
1633          * Now that we have all the maps created, just set the ->end of them:
1634          */
1635         map_groups__fixup_end(kmaps);
1636         return 0;
1637 }