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