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