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