perf annotate: Allocate history size correctly
[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
6 #include "debug.h"
7
8 #include <libelf.h>
9 #include <gelf.h>
10 #include <elf.h>
11
12 const char *sym_hist_filter;
13
14 enum dso_origin {
15         DSO__ORIG_KERNEL = 0,
16         DSO__ORIG_JAVA_JIT,
17         DSO__ORIG_FEDORA,
18         DSO__ORIG_UBUNTU,
19         DSO__ORIG_BUILDID,
20         DSO__ORIG_DSO,
21         DSO__ORIG_NOT_FOUND,
22 };
23
24 static struct symbol *symbol__new(u64 start, u64 len,
25                                   const char *name, unsigned int priv_size,
26                                   u64 obj_start, int v)
27 {
28         size_t namelen = strlen(name) + 1;
29         struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen);
30
31         if (!self)
32                 return NULL;
33
34         if (v >= 2)
35                 printf("new symbol: %016Lx [%08lx]: %s, hist: %p, obj_start: %p\n",
36                         (u64)start, (unsigned long)len, name, self->hist, (void *)(unsigned long)obj_start);
37
38         self->obj_start= obj_start;
39         self->hist = NULL;
40         self->hist_sum = 0;
41
42         if (sym_hist_filter && !strcmp(name, sym_hist_filter))
43                 self->hist = calloc(sizeof(u64), len);
44
45         if (priv_size) {
46                 memset(self, 0, priv_size);
47                 self = ((void *)self) + priv_size;
48         }
49         self->start = start;
50         self->end   = len ? start + len - 1 : start;
51         memcpy(self->name, name, namelen);
52
53         return self;
54 }
55
56 static void symbol__delete(struct symbol *self, unsigned int priv_size)
57 {
58         free(((void *)self) - priv_size);
59 }
60
61 static size_t symbol__fprintf(struct symbol *self, FILE *fp)
62 {
63         if (!self->module)
64                 return fprintf(fp, " %llx-%llx %s\n",
65                        self->start, self->end, self->name);
66         else
67                 return fprintf(fp, " %llx-%llx %s \t[%s]\n",
68                        self->start, self->end, self->name, self->module->name);
69 }
70
71 struct dso *dso__new(const char *name, unsigned int sym_priv_size)
72 {
73         struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
74
75         if (self != NULL) {
76                 strcpy(self->name, name);
77                 self->syms = RB_ROOT;
78                 self->sym_priv_size = sym_priv_size;
79                 self->find_symbol = dso__find_symbol;
80                 self->slen_calculated = 0;
81                 self->origin = DSO__ORIG_NOT_FOUND;
82         }
83
84         return self;
85 }
86
87 static void dso__delete_symbols(struct dso *self)
88 {
89         struct symbol *pos;
90         struct rb_node *next = rb_first(&self->syms);
91
92         while (next) {
93                 pos = rb_entry(next, struct symbol, rb_node);
94                 next = rb_next(&pos->rb_node);
95                 rb_erase(&pos->rb_node, &self->syms);
96                 symbol__delete(pos, self->sym_priv_size);
97         }
98 }
99
100 void dso__delete(struct dso *self)
101 {
102         dso__delete_symbols(self);
103         free(self);
104 }
105
106 static void dso__insert_symbol(struct dso *self, struct symbol *sym)
107 {
108         struct rb_node **p = &self->syms.rb_node;
109         struct rb_node *parent = NULL;
110         const u64 ip = sym->start;
111         struct symbol *s;
112
113         while (*p != NULL) {
114                 parent = *p;
115                 s = rb_entry(parent, struct symbol, rb_node);
116                 if (ip < s->start)
117                         p = &(*p)->rb_left;
118                 else
119                         p = &(*p)->rb_right;
120         }
121         rb_link_node(&sym->rb_node, parent, p);
122         rb_insert_color(&sym->rb_node, &self->syms);
123 }
124
125 struct symbol *dso__find_symbol(struct dso *self, u64 ip)
126 {
127         struct rb_node *n;
128
129         if (self == NULL)
130                 return NULL;
131
132         n = self->syms.rb_node;
133
134         while (n) {
135                 struct symbol *s = rb_entry(n, struct symbol, rb_node);
136
137                 if (ip < s->start)
138                         n = n->rb_left;
139                 else if (ip > s->end)
140                         n = n->rb_right;
141                 else
142                         return s;
143         }
144
145         return NULL;
146 }
147
148 size_t dso__fprintf(struct dso *self, FILE *fp)
149 {
150         size_t ret = fprintf(fp, "dso: %s\n", self->name);
151
152         struct rb_node *nd;
153         for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) {
154                 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
155                 ret += symbol__fprintf(pos, fp);
156         }
157
158         return ret;
159 }
160
161 static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v)
162 {
163         struct rb_node *nd, *prevnd;
164         char *line = NULL;
165         size_t n;
166         FILE *file = fopen("/proc/kallsyms", "r");
167         int count = 0;
168
169         if (file == NULL)
170                 goto out_failure;
171
172         while (!feof(file)) {
173                 u64 start;
174                 struct symbol *sym;
175                 int line_len, len;
176                 char symbol_type;
177
178                 line_len = getline(&line, &n, file);
179                 if (line_len < 0)
180                         break;
181
182                 if (!line)
183                         goto out_failure;
184
185                 line[--line_len] = '\0'; /* \n */
186
187                 len = hex2u64(line, &start);
188
189                 len++;
190                 if (len + 2 >= line_len)
191                         continue;
192
193                 symbol_type = toupper(line[len]);
194                 /*
195                  * We're interested only in code ('T'ext)
196                  */
197                 if (symbol_type != 'T' && symbol_type != 'W')
198                         continue;
199                 /*
200                  * Well fix up the end later, when we have all sorted.
201                  */
202                 sym = symbol__new(start, 0xdead, line + len + 2,
203                                   self->sym_priv_size, 0, v);
204
205                 if (sym == NULL)
206                         goto out_delete_line;
207
208                 if (filter && filter(self, sym))
209                         symbol__delete(sym, self->sym_priv_size);
210                 else {
211                         dso__insert_symbol(self, sym);
212                         count++;
213                 }
214         }
215
216         /*
217          * Now that we have all sorted out, just set the ->end of all
218          * symbols
219          */
220         prevnd = rb_first(&self->syms);
221
222         if (prevnd == NULL)
223                 goto out_delete_line;
224
225         for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
226                 struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node),
227                               *curr = rb_entry(nd, struct symbol, rb_node);
228
229                 prev->end = curr->start - 1;
230                 if (prev->hist) {
231                         free(prev->hist);
232                         prev->hist = calloc(sizeof(u64), prev->end - prev->start);
233                 }
234                 prevnd = nd;
235         }
236
237         free(line);
238         fclose(file);
239
240         return count;
241
242 out_delete_line:
243         free(line);
244 out_failure:
245         return -1;
246 }
247
248 static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v)
249 {
250         char *line = NULL;
251         size_t n;
252         FILE *file;
253         int nr_syms = 0;
254
255         file = fopen(self->name, "r");
256         if (file == NULL)
257                 goto out_failure;
258
259         while (!feof(file)) {
260                 u64 start, size;
261                 struct symbol *sym;
262                 int line_len, len;
263
264                 line_len = getline(&line, &n, file);
265                 if (line_len < 0)
266                         break;
267
268                 if (!line)
269                         goto out_failure;
270
271                 line[--line_len] = '\0'; /* \n */
272
273                 len = hex2u64(line, &start);
274
275                 len++;
276                 if (len + 2 >= line_len)
277                         continue;
278
279                 len += hex2u64(line + len, &size);
280
281                 len++;
282                 if (len + 2 >= line_len)
283                         continue;
284
285                 sym = symbol__new(start, size, line + len,
286                                   self->sym_priv_size, start, v);
287
288                 if (sym == NULL)
289                         goto out_delete_line;
290
291                 if (filter && filter(self, sym))
292                         symbol__delete(sym, self->sym_priv_size);
293                 else {
294                         dso__insert_symbol(self, sym);
295                         nr_syms++;
296                 }
297         }
298
299         free(line);
300         fclose(file);
301
302         return nr_syms;
303
304 out_delete_line:
305         free(line);
306 out_failure:
307         return -1;
308 }
309
310 /**
311  * elf_symtab__for_each_symbol - iterate thru all the symbols
312  *
313  * @self: struct elf_symtab instance to iterate
314  * @idx: uint32_t idx
315  * @sym: GElf_Sym iterator
316  */
317 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
318         for (idx = 0, gelf_getsym(syms, idx, &sym);\
319              idx < nr_syms; \
320              idx++, gelf_getsym(syms, idx, &sym))
321
322 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
323 {
324         return GELF_ST_TYPE(sym->st_info);
325 }
326
327 static inline int elf_sym__is_function(const GElf_Sym *sym)
328 {
329         return elf_sym__type(sym) == STT_FUNC &&
330                sym->st_name != 0 &&
331                sym->st_shndx != SHN_UNDEF;
332 }
333
334 static inline int elf_sym__is_label(const GElf_Sym *sym)
335 {
336         return elf_sym__type(sym) == STT_NOTYPE &&
337                 sym->st_name != 0 &&
338                 sym->st_shndx != SHN_UNDEF &&
339                 sym->st_shndx != SHN_ABS;
340 }
341
342 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
343                                         const Elf_Data *secstrs)
344 {
345         return secstrs->d_buf + shdr->sh_name;
346 }
347
348 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
349                                         const Elf_Data *secstrs)
350 {
351         return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
352 }
353
354 static inline const char *elf_sym__name(const GElf_Sym *sym,
355                                         const Elf_Data *symstrs)
356 {
357         return symstrs->d_buf + sym->st_name;
358 }
359
360 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
361                                     GElf_Shdr *shp, const char *name,
362                                     size_t *idx)
363 {
364         Elf_Scn *sec = NULL;
365         size_t cnt = 1;
366
367         while ((sec = elf_nextscn(elf, sec)) != NULL) {
368                 char *str;
369
370                 gelf_getshdr(sec, shp);
371                 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
372                 if (!strcmp(name, str)) {
373                         if (idx)
374                                 *idx = cnt;
375                         break;
376                 }
377                 ++cnt;
378         }
379
380         return sec;
381 }
382
383 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
384         for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
385              idx < nr_entries; \
386              ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
387
388 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
389         for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
390              idx < nr_entries; \
391              ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
392
393 /*
394  * We need to check if we have a .dynsym, so that we can handle the
395  * .plt, synthesizing its symbols, that aren't on the symtabs (be it
396  * .dynsym or .symtab).
397  * And always look at the original dso, not at debuginfo packages, that
398  * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
399  */
400 static int dso__synthesize_plt_symbols(struct  dso *self, int v)
401 {
402         uint32_t nr_rel_entries, idx;
403         GElf_Sym sym;
404         u64 plt_offset;
405         GElf_Shdr shdr_plt;
406         struct symbol *f;
407         GElf_Shdr shdr_rel_plt, shdr_dynsym;
408         Elf_Data *reldata, *syms, *symstrs;
409         Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
410         size_t dynsym_idx;
411         GElf_Ehdr ehdr;
412         char sympltname[1024];
413         Elf *elf;
414         int nr = 0, symidx, fd, err = 0;
415
416         fd = open(self->name, O_RDONLY);
417         if (fd < 0)
418                 goto out;
419
420         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
421         if (elf == NULL)
422                 goto out_close;
423
424         if (gelf_getehdr(elf, &ehdr) == NULL)
425                 goto out_elf_end;
426
427         scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
428                                          ".dynsym", &dynsym_idx);
429         if (scn_dynsym == NULL)
430                 goto out_elf_end;
431
432         scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
433                                           ".rela.plt", NULL);
434         if (scn_plt_rel == NULL) {
435                 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
436                                                   ".rel.plt", NULL);
437                 if (scn_plt_rel == NULL)
438                         goto out_elf_end;
439         }
440
441         err = -1;
442
443         if (shdr_rel_plt.sh_link != dynsym_idx)
444                 goto out_elf_end;
445
446         if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
447                 goto out_elf_end;
448
449         /*
450          * Fetch the relocation section to find the idxes to the GOT
451          * and the symbols in the .dynsym they refer to.
452          */
453         reldata = elf_getdata(scn_plt_rel, NULL);
454         if (reldata == NULL)
455                 goto out_elf_end;
456
457         syms = elf_getdata(scn_dynsym, NULL);
458         if (syms == NULL)
459                 goto out_elf_end;
460
461         scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
462         if (scn_symstrs == NULL)
463                 goto out_elf_end;
464
465         symstrs = elf_getdata(scn_symstrs, NULL);
466         if (symstrs == NULL)
467                 goto out_elf_end;
468
469         nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
470         plt_offset = shdr_plt.sh_offset;
471
472         if (shdr_rel_plt.sh_type == SHT_RELA) {
473                 GElf_Rela pos_mem, *pos;
474
475                 elf_section__for_each_rela(reldata, pos, pos_mem, idx,
476                                            nr_rel_entries) {
477                         symidx = GELF_R_SYM(pos->r_info);
478                         plt_offset += shdr_plt.sh_entsize;
479                         gelf_getsym(syms, symidx, &sym);
480                         snprintf(sympltname, sizeof(sympltname),
481                                  "%s@plt", elf_sym__name(&sym, symstrs));
482
483                         f = symbol__new(plt_offset, shdr_plt.sh_entsize,
484                                         sympltname, self->sym_priv_size, 0, v);
485                         if (!f)
486                                 goto out_elf_end;
487
488                         dso__insert_symbol(self, f);
489                         ++nr;
490                 }
491         } else if (shdr_rel_plt.sh_type == SHT_REL) {
492                 GElf_Rel pos_mem, *pos;
493                 elf_section__for_each_rel(reldata, pos, pos_mem, idx,
494                                           nr_rel_entries) {
495                         symidx = GELF_R_SYM(pos->r_info);
496                         plt_offset += shdr_plt.sh_entsize;
497                         gelf_getsym(syms, symidx, &sym);
498                         snprintf(sympltname, sizeof(sympltname),
499                                  "%s@plt", elf_sym__name(&sym, symstrs));
500
501                         f = symbol__new(plt_offset, shdr_plt.sh_entsize,
502                                         sympltname, self->sym_priv_size, 0, v);
503                         if (!f)
504                                 goto out_elf_end;
505
506                         dso__insert_symbol(self, f);
507                         ++nr;
508                 }
509         }
510
511         err = 0;
512 out_elf_end:
513         elf_end(elf);
514 out_close:
515         close(fd);
516
517         if (err == 0)
518                 return nr;
519 out:
520         fprintf(stderr, "%s: problems reading %s PLT info.\n",
521                 __func__, self->name);
522         return 0;
523 }
524
525 static int dso__load_sym(struct dso *self, int fd, const char *name,
526                          symbol_filter_t filter, int v, struct module *mod)
527 {
528         Elf_Data *symstrs, *secstrs;
529         uint32_t nr_syms;
530         int err = -1;
531         uint32_t idx;
532         GElf_Ehdr ehdr;
533         GElf_Shdr shdr;
534         Elf_Data *syms;
535         GElf_Sym sym;
536         Elf_Scn *sec, *sec_strndx;
537         Elf *elf;
538         int nr = 0, kernel = !strcmp("[kernel]", self->name);
539
540         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
541         if (elf == NULL) {
542                 if (v)
543                         fprintf(stderr, "%s: cannot read %s ELF file.\n",
544                                 __func__, name);
545                 goto out_close;
546         }
547
548         if (gelf_getehdr(elf, &ehdr) == NULL) {
549                 if (v)
550                         fprintf(stderr, "%s: cannot get elf header.\n", __func__);
551                 goto out_elf_end;
552         }
553
554         sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
555         if (sec == NULL) {
556                 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
557                 if (sec == NULL)
558                         goto out_elf_end;
559         }
560
561         syms = elf_getdata(sec, NULL);
562         if (syms == NULL)
563                 goto out_elf_end;
564
565         sec = elf_getscn(elf, shdr.sh_link);
566         if (sec == NULL)
567                 goto out_elf_end;
568
569         symstrs = elf_getdata(sec, NULL);
570         if (symstrs == NULL)
571                 goto out_elf_end;
572
573         sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
574         if (sec_strndx == NULL)
575                 goto out_elf_end;
576
577         secstrs = elf_getdata(sec_strndx, NULL);
578         if (secstrs == NULL)
579                 goto out_elf_end;
580
581         nr_syms = shdr.sh_size / shdr.sh_entsize;
582
583         memset(&sym, 0, sizeof(sym));
584         if (!kernel) {
585                 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
586                                 elf_section_by_name(elf, &ehdr, &shdr,
587                                                      ".gnu.prelink_undo",
588                                                      NULL) != NULL);
589         } else self->adjust_symbols = 0;
590
591         elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
592                 struct symbol *f;
593                 const char *elf_name;
594                 char *demangled;
595                 u64 obj_start;
596                 struct section *section = NULL;
597                 int is_label = elf_sym__is_label(&sym);
598                 const char *section_name;
599
600                 if (!is_label && !elf_sym__is_function(&sym))
601                         continue;
602
603                 sec = elf_getscn(elf, sym.st_shndx);
604                 if (!sec)
605                         goto out_elf_end;
606
607                 gelf_getshdr(sec, &shdr);
608
609                 if (is_label && !elf_sec__is_text(&shdr, secstrs))
610                         continue;
611
612                 section_name = elf_sec__name(&shdr, secstrs);
613                 obj_start = sym.st_value;
614
615                 if (self->adjust_symbols) {
616                         if (v >= 2)
617                                 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
618                                         (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
619
620                         sym.st_value -= shdr.sh_addr - shdr.sh_offset;
621                 }
622
623                 if (mod) {
624                         section = mod->sections->find_section(mod->sections, section_name);
625                         if (section)
626                                 sym.st_value += section->vma;
627                         else {
628                                 fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n",
629                                         mod->name, section_name);
630                                 goto out_elf_end;
631                         }
632                 }
633                 /*
634                  * We need to figure out if the object was created from C++ sources
635                  * DWARF DW_compile_unit has this, but we don't always have access
636                  * to it...
637                  */
638                 elf_name = elf_sym__name(&sym, symstrs);
639                 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
640                 if (demangled != NULL)
641                         elf_name = demangled;
642
643                 f = symbol__new(sym.st_value, sym.st_size, elf_name,
644                                 self->sym_priv_size, obj_start, v);
645                 free(demangled);
646                 if (!f)
647                         goto out_elf_end;
648
649                 if (filter && filter(self, f))
650                         symbol__delete(f, self->sym_priv_size);
651                 else {
652                         f->module = mod;
653                         dso__insert_symbol(self, f);
654                         nr++;
655                 }
656         }
657
658         err = nr;
659 out_elf_end:
660         elf_end(elf);
661 out_close:
662         return err;
663 }
664
665 #define BUILD_ID_SIZE 128
666
667 static char *dso__read_build_id(struct dso *self, int v)
668 {
669         int i;
670         GElf_Ehdr ehdr;
671         GElf_Shdr shdr;
672         Elf_Data *build_id_data;
673         Elf_Scn *sec;
674         char *build_id = NULL, *bid;
675         unsigned char *raw;
676         Elf *elf;
677         int fd = open(self->name, O_RDONLY);
678
679         if (fd < 0)
680                 goto out;
681
682         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
683         if (elf == NULL) {
684                 if (v)
685                         fprintf(stderr, "%s: cannot read %s ELF file.\n",
686                                 __func__, self->name);
687                 goto out_close;
688         }
689
690         if (gelf_getehdr(elf, &ehdr) == NULL) {
691                 if (v)
692                         fprintf(stderr, "%s: cannot get elf header.\n", __func__);
693                 goto out_elf_end;
694         }
695
696         sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL);
697         if (sec == NULL)
698                 goto out_elf_end;
699
700         build_id_data = elf_getdata(sec, NULL);
701         if (build_id_data == NULL)
702                 goto out_elf_end;
703         build_id = malloc(BUILD_ID_SIZE);
704         if (build_id == NULL)
705                 goto out_elf_end;
706         raw = build_id_data->d_buf + 16;
707         bid = build_id;
708
709         for (i = 0; i < 20; ++i) {
710                 sprintf(bid, "%02x", *raw);
711                 ++raw;
712                 bid += 2;
713         }
714         if (v >= 2)
715                 printf("%s(%s): %s\n", __func__, self->name, build_id);
716 out_elf_end:
717         elf_end(elf);
718 out_close:
719         close(fd);
720 out:
721         return build_id;
722 }
723
724 char dso__symtab_origin(const struct dso *self)
725 {
726         static const char origin[] = {
727                 [DSO__ORIG_KERNEL] =   'k',
728                 [DSO__ORIG_JAVA_JIT] = 'j',
729                 [DSO__ORIG_FEDORA] =   'f',
730                 [DSO__ORIG_UBUNTU] =   'u',
731                 [DSO__ORIG_BUILDID] =  'b',
732                 [DSO__ORIG_DSO] =      'd',
733         };
734
735         if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
736                 return '!';
737         return origin[self->origin];
738 }
739
740 int dso__load(struct dso *self, symbol_filter_t filter, int v)
741 {
742         int size = PATH_MAX;
743         char *name = malloc(size), *build_id = NULL;
744         int ret = -1;
745         int fd;
746
747         if (!name)
748                 return -1;
749
750         self->adjust_symbols = 0;
751
752         if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
753                 ret = dso__load_perf_map(self, filter, v);
754                 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
755                                          DSO__ORIG_NOT_FOUND;
756                 return ret;
757         }
758
759         self->origin = DSO__ORIG_FEDORA - 1;
760
761 more:
762         do {
763                 self->origin++;
764                 switch (self->origin) {
765                 case DSO__ORIG_FEDORA:
766                         snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
767                         break;
768                 case DSO__ORIG_UBUNTU:
769                         snprintf(name, size, "/usr/lib/debug%s", self->name);
770                         break;
771                 case DSO__ORIG_BUILDID:
772                         build_id = dso__read_build_id(self, v);
773                         if (build_id != NULL) {
774                                 snprintf(name, size,
775                                          "/usr/lib/debug/.build-id/%.2s/%s.debug",
776                                         build_id, build_id + 2);
777                                 free(build_id);
778                                 break;
779                         }
780                         self->origin++;
781                         /* Fall thru */
782                 case DSO__ORIG_DSO:
783                         snprintf(name, size, "%s", self->name);
784                         break;
785
786                 default:
787                         goto out;
788                 }
789
790                 fd = open(name, O_RDONLY);
791         } while (fd < 0);
792
793         ret = dso__load_sym(self, fd, name, filter, v, NULL);
794         close(fd);
795
796         /*
797          * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
798          */
799         if (!ret)
800                 goto more;
801
802         if (ret > 0) {
803                 int nr_plt = dso__synthesize_plt_symbols(self, v);
804                 if (nr_plt > 0)
805                         ret += nr_plt;
806         }
807 out:
808         free(name);
809         if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
810                 return 0;
811         return ret;
812 }
813
814 static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name,
815                              symbol_filter_t filter, int v)
816 {
817         struct module *mod = mod_dso__find_module(mods, name);
818         int err = 0, fd;
819
820         if (mod == NULL || !mod->active)
821                 return err;
822
823         fd = open(mod->path, O_RDONLY);
824
825         if (fd < 0)
826                 return err;
827
828         err = dso__load_sym(self, fd, name, filter, v, mod);
829         close(fd);
830
831         return err;
832 }
833
834 int dso__load_modules(struct dso *self, symbol_filter_t filter, int v)
835 {
836         struct mod_dso *mods = mod_dso__new_dso("modules");
837         struct module *pos;
838         struct rb_node *next;
839         int err, count = 0;
840
841         err = mod_dso__load_modules(mods);
842
843         if (err <= 0)
844                 return err;
845
846         /*
847          * Iterate over modules, and load active symbols.
848          */
849         next = rb_first(&mods->mods);
850         while (next) {
851                 pos = rb_entry(next, struct module, rb_node);
852                 err = dso__load_module(self, mods, pos->name, filter, v);
853
854                 if (err < 0)
855                         break;
856
857                 next = rb_next(&pos->rb_node);
858                 count += err;
859         }
860
861         if (err < 0) {
862                 mod_dso__delete_modules(mods);
863                 mod_dso__delete_self(mods);
864                 return err;
865         }
866
867         return count;
868 }
869
870 static inline void dso__fill_symbol_holes(struct dso *self)
871 {
872         struct symbol *prev = NULL;
873         struct rb_node *nd;
874
875         for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) {
876                 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
877
878                 if (prev) {
879                         u64 hole = 0;
880                         int alias = pos->start == prev->start;
881
882                         if (!alias)
883                                 hole = prev->start - pos->end - 1;
884
885                         if (hole || alias) {
886                                 if (alias)
887                                         pos->end = prev->end;
888                                 else if (hole)
889                                         pos->end = prev->start - 1;
890                                 if (pos->hist) {
891                                         free(pos->hist);
892                                         pos->hist = calloc(sizeof(u64), pos->end - pos->start);
893                                 }
894                         }
895                 }
896                 prev = pos;
897         }
898 }
899
900 static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
901                              symbol_filter_t filter, int v)
902 {
903         int err, fd = open(vmlinux, O_RDONLY);
904
905         if (fd < 0)
906                 return -1;
907
908         err = dso__load_sym(self, fd, vmlinux, filter, v, NULL);
909
910         if (err > 0)
911                 dso__fill_symbol_holes(self);
912
913         close(fd);
914
915         return err;
916 }
917
918 int dso__load_kernel(struct dso *self, const char *vmlinux,
919                      symbol_filter_t filter, int v, int use_modules)
920 {
921         int err = -1;
922
923         if (vmlinux) {
924                 err = dso__load_vmlinux(self, vmlinux, filter, v);
925                 if (err > 0 && use_modules) {
926                         int syms = dso__load_modules(self, filter, v);
927
928                         if (syms < 0) {
929                                 fprintf(stderr, "dso__load_modules failed!\n");
930                                 return syms;
931                         }
932                         err += syms;
933                 }
934         }
935
936         if (err <= 0)
937                 err = dso__load_kallsyms(self, filter, v);
938
939         if (err > 0)
940                 self->origin = DSO__ORIG_KERNEL;
941
942         return err;
943 }
944
945 LIST_HEAD(dsos);
946 struct dso      *kernel_dso;
947 struct dso      *vdso;
948 struct dso      *hypervisor_dso;
949
950 const char      *vmlinux_name = "vmlinux";
951 int             modules;
952
953 static void dsos__add(struct dso *dso)
954 {
955         list_add_tail(&dso->node, &dsos);
956 }
957
958 static struct dso *dsos__find(const char *name)
959 {
960         struct dso *pos;
961
962         list_for_each_entry(pos, &dsos, node)
963                 if (strcmp(pos->name, name) == 0)
964                         return pos;
965         return NULL;
966 }
967
968 struct dso *dsos__findnew(const char *name)
969 {
970         struct dso *dso = dsos__find(name);
971         int nr;
972
973         if (dso)
974                 return dso;
975
976         dso = dso__new(name, 0);
977         if (!dso)
978                 goto out_delete_dso;
979
980         nr = dso__load(dso, NULL, verbose);
981         if (nr < 0) {
982                 eprintf("Failed to open: %s\n", name);
983                 goto out_delete_dso;
984         }
985         if (!nr)
986                 eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
987
988         dsos__add(dso);
989
990         return dso;
991
992 out_delete_dso:
993         dso__delete(dso);
994         return NULL;
995 }
996
997 void dsos__fprintf(FILE *fp)
998 {
999         struct dso *pos;
1000
1001         list_for_each_entry(pos, &dsos, node)
1002                 dso__fprintf(pos, fp);
1003 }
1004
1005 static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
1006 {
1007         return dso__find_symbol(dso, ip);
1008 }
1009
1010 int load_kernel(void)
1011 {
1012         int err;
1013
1014         kernel_dso = dso__new("[kernel]", 0);
1015         if (!kernel_dso)
1016                 return -1;
1017
1018         err = dso__load_kernel(kernel_dso, vmlinux_name, NULL, verbose, modules);
1019         if (err <= 0) {
1020                 dso__delete(kernel_dso);
1021                 kernel_dso = NULL;
1022         } else
1023                 dsos__add(kernel_dso);
1024
1025         vdso = dso__new("[vdso]", 0);
1026         if (!vdso)
1027                 return -1;
1028
1029         vdso->find_symbol = vdso__find_symbol;
1030
1031         dsos__add(vdso);
1032
1033         hypervisor_dso = dso__new("[hypervisor]", 0);
1034         if (!hypervisor_dso)
1035                 return -1;
1036         dsos__add(hypervisor_dso);
1037
1038         return err;
1039 }
1040
1041
1042 void symbol__init(void)
1043 {
1044         elf_version(EV_CURRENT);
1045 }