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