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