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