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