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