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