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