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