Root/tools/perf/util/symbol.c

1#include "util.h"
2#include "../perf.h"
3#include "sort.h"
4#include "string.h"
5#include "symbol.h"
6#include "thread.h"
7
8#include "debug.h"
9
10#include <asm/bug.h>
11#include <libelf.h>
12#include <gelf.h>
13#include <elf.h>
14#include <limits.h>
15#include <sys/utsname.h>
16
17#ifndef NT_GNU_BUILD_ID
18#define NT_GNU_BUILD_ID 3
19#endif
20
21enum dso_origin {
22    DSO__ORIG_KERNEL = 0,
23    DSO__ORIG_JAVA_JIT,
24    DSO__ORIG_BUILD_ID_CACHE,
25    DSO__ORIG_FEDORA,
26    DSO__ORIG_UBUNTU,
27    DSO__ORIG_BUILDID,
28    DSO__ORIG_DSO,
29    DSO__ORIG_KMODULE,
30    DSO__ORIG_NOT_FOUND,
31};
32
33static void dsos__add(struct list_head *head, struct dso *dso);
34static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
35static int dso__load_kernel_sym(struct dso *self, struct map *map,
36                symbol_filter_t filter);
37static int vmlinux_path__nr_entries;
38static char **vmlinux_path;
39
40struct symbol_conf symbol_conf = {
41    .exclude_other = true,
42    .use_modules = true,
43    .try_vmlinux_path = true,
44};
45
46bool dso__loaded(const struct dso *self, enum map_type type)
47{
48    return self->loaded & (1 << type);
49}
50
51bool dso__sorted_by_name(const struct dso *self, enum map_type type)
52{
53    return self->sorted_by_name & (1 << type);
54}
55
56static void dso__set_sorted_by_name(struct dso *self, enum map_type type)
57{
58    self->sorted_by_name |= (1 << type);
59}
60
61bool symbol_type__is_a(char symbol_type, enum map_type map_type)
62{
63    switch (map_type) {
64    case MAP__FUNCTION:
65        return symbol_type == 'T' || symbol_type == 'W';
66    case MAP__VARIABLE:
67        return symbol_type == 'D' || symbol_type == 'd';
68    default:
69        return false;
70    }
71}
72
73static void symbols__fixup_end(struct rb_root *self)
74{
75    struct rb_node *nd, *prevnd = rb_first(self);
76    struct symbol *curr, *prev;
77
78    if (prevnd == NULL)
79        return;
80
81    curr = rb_entry(prevnd, struct symbol, rb_node);
82
83    for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
84        prev = curr;
85        curr = rb_entry(nd, struct symbol, rb_node);
86
87        if (prev->end == prev->start)
88            prev->end = curr->start - 1;
89    }
90
91    /* Last entry */
92    if (curr->end == curr->start)
93        curr->end = roundup(curr->start, 4096);
94}
95
96static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
97{
98    struct map *prev, *curr;
99    struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
100
101    if (prevnd == NULL)
102        return;
103
104    curr = rb_entry(prevnd, struct map, rb_node);
105
106    for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
107        prev = curr;
108        curr = rb_entry(nd, struct map, rb_node);
109        prev->end = curr->start - 1;
110    }
111
112    /*
113     * We still haven't the actual symbols, so guess the
114     * last map final address.
115     */
116    curr->end = ~0UL;
117}
118
119static void map_groups__fixup_end(struct map_groups *self)
120{
121    int i;
122    for (i = 0; i < MAP__NR_TYPES; ++i)
123        __map_groups__fixup_end(self, i);
124}
125
126static struct symbol *symbol__new(u64 start, u64 len, const char *name)
127{
128    size_t namelen = strlen(name) + 1;
129    struct symbol *self = zalloc(symbol_conf.priv_size +
130                     sizeof(*self) + namelen);
131    if (self == NULL)
132        return NULL;
133
134    if (symbol_conf.priv_size)
135        self = ((void *)self) + symbol_conf.priv_size;
136
137    self->start = start;
138    self->end = len ? start + len - 1 : start;
139
140    pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
141
142    memcpy(self->name, name, namelen);
143
144    return self;
145}
146
147void symbol__delete(struct symbol *self)
148{
149    free(((void *)self) - symbol_conf.priv_size);
150}
151
152static size_t symbol__fprintf(struct symbol *self, FILE *fp)
153{
154    return fprintf(fp, " %llx-%llx %s\n",
155               self->start, self->end, self->name);
156}
157
158void dso__set_long_name(struct dso *self, char *name)
159{
160    if (name == NULL)
161        return;
162    self->long_name = name;
163    self->long_name_len = strlen(name);
164}
165
166static void dso__set_short_name(struct dso *self, const char *name)
167{
168    if (name == NULL)
169        return;
170    self->short_name = name;
171    self->short_name_len = strlen(name);
172}
173
174static void dso__set_basename(struct dso *self)
175{
176    dso__set_short_name(self, basename(self->long_name));
177}
178
179struct dso *dso__new(const char *name)
180{
181    struct dso *self = zalloc(sizeof(*self) + strlen(name) + 1);
182
183    if (self != NULL) {
184        int i;
185        strcpy(self->name, name);
186        dso__set_long_name(self, self->name);
187        dso__set_short_name(self, self->name);
188        for (i = 0; i < MAP__NR_TYPES; ++i)
189            self->symbols[i] = self->symbol_names[i] = RB_ROOT;
190        self->slen_calculated = 0;
191        self->origin = DSO__ORIG_NOT_FOUND;
192        self->loaded = 0;
193        self->sorted_by_name = 0;
194        self->has_build_id = 0;
195    }
196
197    return self;
198}
199
200static void symbols__delete(struct rb_root *self)
201{
202    struct symbol *pos;
203    struct rb_node *next = rb_first(self);
204
205    while (next) {
206        pos = rb_entry(next, struct symbol, rb_node);
207        next = rb_next(&pos->rb_node);
208        rb_erase(&pos->rb_node, self);
209        symbol__delete(pos);
210    }
211}
212
213void dso__delete(struct dso *self)
214{
215    int i;
216    for (i = 0; i < MAP__NR_TYPES; ++i)
217        symbols__delete(&self->symbols[i]);
218    if (self->long_name != self->name)
219        free(self->long_name);
220    free(self);
221}
222
223void dso__set_build_id(struct dso *self, void *build_id)
224{
225    memcpy(self->build_id, build_id, sizeof(self->build_id));
226    self->has_build_id = 1;
227}
228
229static void symbols__insert(struct rb_root *self, struct symbol *sym)
230{
231    struct rb_node **p = &self->rb_node;
232    struct rb_node *parent = NULL;
233    const u64 ip = sym->start;
234    struct symbol *s;
235
236    while (*p != NULL) {
237        parent = *p;
238        s = rb_entry(parent, struct symbol, rb_node);
239        if (ip < s->start)
240            p = &(*p)->rb_left;
241        else
242            p = &(*p)->rb_right;
243    }
244    rb_link_node(&sym->rb_node, parent, p);
245    rb_insert_color(&sym->rb_node, self);
246}
247
248static struct symbol *symbols__find(struct rb_root *self, u64 ip)
249{
250    struct rb_node *n;
251
252    if (self == NULL)
253        return NULL;
254
255    n = self->rb_node;
256
257    while (n) {
258        struct symbol *s = rb_entry(n, struct symbol, rb_node);
259
260        if (ip < s->start)
261            n = n->rb_left;
262        else if (ip > s->end)
263            n = n->rb_right;
264        else
265            return s;
266    }
267
268    return NULL;
269}
270
271struct symbol_name_rb_node {
272    struct rb_node rb_node;
273    struct symbol sym;
274};
275
276static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
277{
278    struct rb_node **p = &self->rb_node;
279    struct rb_node *parent = NULL;
280    struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s;
281
282    while (*p != NULL) {
283        parent = *p;
284        s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
285        if (strcmp(sym->name, s->sym.name) < 0)
286            p = &(*p)->rb_left;
287        else
288            p = &(*p)->rb_right;
289    }
290    rb_link_node(&symn->rb_node, parent, p);
291    rb_insert_color(&symn->rb_node, self);
292}
293
294static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source)
295{
296    struct rb_node *nd;
297
298    for (nd = rb_first(source); nd; nd = rb_next(nd)) {
299        struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
300        symbols__insert_by_name(self, pos);
301    }
302}
303
304static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name)
305{
306    struct rb_node *n;
307
308    if (self == NULL)
309        return NULL;
310
311    n = self->rb_node;
312
313    while (n) {
314        struct symbol_name_rb_node *s;
315        int cmp;
316
317        s = rb_entry(n, struct symbol_name_rb_node, rb_node);
318        cmp = strcmp(name, s->sym.name);
319
320        if (cmp < 0)
321            n = n->rb_left;
322        else if (cmp > 0)
323            n = n->rb_right;
324        else
325            return &s->sym;
326    }
327
328    return NULL;
329}
330
331struct symbol *dso__find_symbol(struct dso *self,
332                enum map_type type, u64 addr)
333{
334    return symbols__find(&self->symbols[type], addr);
335}
336
337struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
338                    const char *name)
339{
340    return symbols__find_by_name(&self->symbol_names[type], name);
341}
342
343void dso__sort_by_name(struct dso *self, enum map_type type)
344{
345    dso__set_sorted_by_name(self, type);
346    return symbols__sort_by_name(&self->symbol_names[type],
347                     &self->symbols[type]);
348}
349
350int build_id__sprintf(const u8 *self, int len, char *bf)
351{
352    char *bid = bf;
353    const u8 *raw = self;
354    int i;
355
356    for (i = 0; i < len; ++i) {
357        sprintf(bid, "%02x", *raw);
358        ++raw;
359        bid += 2;
360    }
361
362    return raw - self;
363}
364
365size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
366{
367    char sbuild_id[BUILD_ID_SIZE * 2 + 1];
368
369    build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
370    return fprintf(fp, "%s", sbuild_id);
371}
372
373size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
374{
375    struct rb_node *nd;
376    size_t ret = fprintf(fp, "dso: %s (", self->short_name);
377
378    if (self->short_name != self->long_name)
379        ret += fprintf(fp, "%s, ", self->long_name);
380    ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
381               self->loaded ? "" : "NOT ");
382    ret += dso__fprintf_buildid(self, fp);
383    ret += fprintf(fp, ")\n");
384    for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
385        struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
386        ret += symbol__fprintf(pos, fp);
387    }
388
389    return ret;
390}
391
392int kallsyms__parse(const char *filename, void *arg,
393            int (*process_symbol)(void *arg, const char *name,
394                             char type, u64 start))
395{
396    char *line = NULL;
397    size_t n;
398    int err = 0;
399    FILE *file = fopen(filename, "r");
400
401    if (file == NULL)
402        goto out_failure;
403
404    while (!feof(file)) {
405        u64 start;
406        int line_len, len;
407        char symbol_type;
408        char *symbol_name;
409
410        line_len = getline(&line, &n, file);
411        if (line_len < 0)
412            break;
413
414        if (!line)
415            goto out_failure;
416
417        line[--line_len] = '\0'; /* \n */
418
419        len = hex2u64(line, &start);
420
421        len++;
422        if (len + 2 >= line_len)
423            continue;
424
425        symbol_type = toupper(line[len]);
426        symbol_name = line + len + 2;
427
428        err = process_symbol(arg, symbol_name, symbol_type, start);
429        if (err)
430            break;
431    }
432
433    free(line);
434    fclose(file);
435    return err;
436
437out_failure:
438    return -1;
439}
440
441struct process_kallsyms_args {
442    struct map *map;
443    struct dso *dso;
444};
445
446static int map__process_kallsym_symbol(void *arg, const char *name,
447                       char type, u64 start)
448{
449    struct symbol *sym;
450    struct process_kallsyms_args *a = arg;
451    struct rb_root *root = &a->dso->symbols[a->map->type];
452
453    if (!symbol_type__is_a(type, a->map->type))
454        return 0;
455
456    /*
457     * Will fix up the end later, when we have all symbols sorted.
458     */
459    sym = symbol__new(start, 0, name);
460
461    if (sym == NULL)
462        return -ENOMEM;
463    /*
464     * We will pass the symbols to the filter later, in
465     * map__split_kallsyms, when we have split the maps per module
466     */
467    symbols__insert(root, sym);
468    return 0;
469}
470
471/*
472 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
473 * so that we can in the next step set the symbol ->end address and then
474 * call kernel_maps__split_kallsyms.
475 */
476static int dso__load_all_kallsyms(struct dso *self, const char *filename,
477                  struct map *map)
478{
479    struct process_kallsyms_args args = { .map = map, .dso = self, };
480    return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
481}
482
483/*
484 * Split the symbols into maps, making sure there are no overlaps, i.e. the
485 * kernel range is broken in several maps, named [kernel].N, as we don't have
486 * the original ELF section names vmlinux have.
487 */
488static int dso__split_kallsyms(struct dso *self, struct map *map,
489                   symbol_filter_t filter)
490{
491    struct map_groups *kmaps = map__kmap(map)->kmaps;
492    struct map *curr_map = map;
493    struct symbol *pos;
494    int count = 0;
495    struct rb_root *root = &self->symbols[map->type];
496    struct rb_node *next = rb_first(root);
497    int kernel_range = 0;
498
499    while (next) {
500        char *module;
501
502        pos = rb_entry(next, struct symbol, rb_node);
503        next = rb_next(&pos->rb_node);
504
505        module = strchr(pos->name, '\t');
506        if (module) {
507            if (!symbol_conf.use_modules)
508                goto discard_symbol;
509
510            *module++ = '\0';
511
512            if (strcmp(curr_map->dso->short_name, module)) {
513                curr_map = map_groups__find_by_name(kmaps, map->type, module);
514                if (curr_map == NULL) {
515                    pr_debug("/proc/{kallsyms,modules} "
516                             "inconsistency while looking "
517                         "for \"%s\" module!\n", module);
518                    return -1;
519                }
520
521                if (curr_map->dso->loaded)
522                    goto discard_symbol;
523            }
524            /*
525             * So that we look just like we get from .ko files,
526             * i.e. not prelinked, relative to map->start.
527             */
528            pos->start = curr_map->map_ip(curr_map, pos->start);
529            pos->end = curr_map->map_ip(curr_map, pos->end);
530        } else if (curr_map != map) {
531            char dso_name[PATH_MAX];
532            struct dso *dso;
533
534            snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
535                 kernel_range++);
536
537            dso = dso__new(dso_name);
538            if (dso == NULL)
539                return -1;
540
541            curr_map = map__new2(pos->start, dso, map->type);
542            if (curr_map == NULL) {
543                dso__delete(dso);
544                return -1;
545            }
546
547            curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
548            map_groups__insert(kmaps, curr_map);
549            ++kernel_range;
550        }
551
552        if (filter && filter(curr_map, pos)) {
553discard_symbol: rb_erase(&pos->rb_node, root);
554            symbol__delete(pos);
555        } else {
556            if (curr_map != map) {
557                rb_erase(&pos->rb_node, root);
558                symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
559            }
560            count++;
561        }
562    }
563
564    return count;
565}
566
567int dso__load_kallsyms(struct dso *self, const char *filename,
568               struct map *map, symbol_filter_t filter)
569{
570    if (dso__load_all_kallsyms(self, filename, map) < 0)
571        return -1;
572
573    symbols__fixup_end(&self->symbols[map->type]);
574    self->origin = DSO__ORIG_KERNEL;
575
576    return dso__split_kallsyms(self, map, filter);
577}
578
579static int dso__load_perf_map(struct dso *self, struct map *map,
580                  symbol_filter_t filter)
581{
582    char *line = NULL;
583    size_t n;
584    FILE *file;
585    int nr_syms = 0;
586
587    file = fopen(self->long_name, "r");
588    if (file == NULL)
589        goto out_failure;
590
591    while (!feof(file)) {
592        u64 start, size;
593        struct symbol *sym;
594        int line_len, len;
595
596        line_len = getline(&line, &n, file);
597        if (line_len < 0)
598            break;
599
600        if (!line)
601            goto out_failure;
602
603        line[--line_len] = '\0'; /* \n */
604
605        len = hex2u64(line, &start);
606
607        len++;
608        if (len + 2 >= line_len)
609            continue;
610
611        len += hex2u64(line + len, &size);
612
613        len++;
614        if (len + 2 >= line_len)
615            continue;
616
617        sym = symbol__new(start, size, line + len);
618
619        if (sym == NULL)
620            goto out_delete_line;
621
622        if (filter && filter(map, sym))
623            symbol__delete(sym);
624        else {
625            symbols__insert(&self->symbols[map->type], sym);
626            nr_syms++;
627        }
628    }
629
630    free(line);
631    fclose(file);
632
633    return nr_syms;
634
635out_delete_line:
636    free(line);
637out_failure:
638    return -1;
639}
640
641/**
642 * elf_symtab__for_each_symbol - iterate thru all the symbols
643 *
644 * @self: struct elf_symtab instance to iterate
645 * @idx: uint32_t idx
646 * @sym: GElf_Sym iterator
647 */
648#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
649    for (idx = 0, gelf_getsym(syms, idx, &sym);\
650         idx < nr_syms; \
651         idx++, gelf_getsym(syms, idx, &sym))
652
653static inline uint8_t elf_sym__type(const GElf_Sym *sym)
654{
655    return GELF_ST_TYPE(sym->st_info);
656}
657
658static inline int elf_sym__is_function(const GElf_Sym *sym)
659{
660    return elf_sym__type(sym) == STT_FUNC &&
661           sym->st_name != 0 &&
662           sym->st_shndx != SHN_UNDEF;
663}
664
665static inline bool elf_sym__is_object(const GElf_Sym *sym)
666{
667    return elf_sym__type(sym) == STT_OBJECT &&
668        sym->st_name != 0 &&
669        sym->st_shndx != SHN_UNDEF;
670}
671
672static inline int elf_sym__is_label(const GElf_Sym *sym)
673{
674    return elf_sym__type(sym) == STT_NOTYPE &&
675        sym->st_name != 0 &&
676        sym->st_shndx != SHN_UNDEF &&
677        sym->st_shndx != SHN_ABS;
678}
679
680static inline const char *elf_sec__name(const GElf_Shdr *shdr,
681                    const Elf_Data *secstrs)
682{
683    return secstrs->d_buf + shdr->sh_name;
684}
685
686static inline int elf_sec__is_text(const GElf_Shdr *shdr,
687                    const Elf_Data *secstrs)
688{
689    return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
690}
691
692static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
693                    const Elf_Data *secstrs)
694{
695    return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
696}
697
698static inline const char *elf_sym__name(const GElf_Sym *sym,
699                    const Elf_Data *symstrs)
700{
701    return symstrs->d_buf + sym->st_name;
702}
703
704static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
705                    GElf_Shdr *shp, const char *name,
706                    size_t *idx)
707{
708    Elf_Scn *sec = NULL;
709    size_t cnt = 1;
710
711    while ((sec = elf_nextscn(elf, sec)) != NULL) {
712        char *str;
713
714        gelf_getshdr(sec, shp);
715        str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
716        if (!strcmp(name, str)) {
717            if (idx)
718                *idx = cnt;
719            break;
720        }
721        ++cnt;
722    }
723
724    return sec;
725}
726
727#define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
728    for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
729         idx < nr_entries; \
730         ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
731
732#define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
733    for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
734         idx < nr_entries; \
735         ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
736
737/*
738 * We need to check if we have a .dynsym, so that we can handle the
739 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
740 * .dynsym or .symtab).
741 * And always look at the original dso, not at debuginfo packages, that
742 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
743 */
744static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
745                       symbol_filter_t filter)
746{
747    uint32_t nr_rel_entries, idx;
748    GElf_Sym sym;
749    u64 plt_offset;
750    GElf_Shdr shdr_plt;
751    struct symbol *f;
752    GElf_Shdr shdr_rel_plt, shdr_dynsym;
753    Elf_Data *reldata, *syms, *symstrs;
754    Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
755    size_t dynsym_idx;
756    GElf_Ehdr ehdr;
757    char sympltname[1024];
758    Elf *elf;
759    int nr = 0, symidx, fd, err = 0;
760
761    fd = open(self->long_name, O_RDONLY);
762    if (fd < 0)
763        goto out;
764
765    elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
766    if (elf == NULL)
767        goto out_close;
768
769    if (gelf_getehdr(elf, &ehdr) == NULL)
770        goto out_elf_end;
771
772    scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
773                     ".dynsym", &dynsym_idx);
774    if (scn_dynsym == NULL)
775        goto out_elf_end;
776
777    scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
778                      ".rela.plt", NULL);
779    if (scn_plt_rel == NULL) {
780        scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
781                          ".rel.plt", NULL);
782        if (scn_plt_rel == NULL)
783            goto out_elf_end;
784    }
785
786    err = -1;
787
788    if (shdr_rel_plt.sh_link != dynsym_idx)
789        goto out_elf_end;
790
791    if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
792        goto out_elf_end;
793
794    /*
795     * Fetch the relocation section to find the idxes to the GOT
796     * and the symbols in the .dynsym they refer to.
797     */
798    reldata = elf_getdata(scn_plt_rel, NULL);
799    if (reldata == NULL)
800        goto out_elf_end;
801
802    syms = elf_getdata(scn_dynsym, NULL);
803    if (syms == NULL)
804        goto out_elf_end;
805
806    scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
807    if (scn_symstrs == NULL)
808        goto out_elf_end;
809
810    symstrs = elf_getdata(scn_symstrs, NULL);
811    if (symstrs == NULL)
812        goto out_elf_end;
813
814    nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
815    plt_offset = shdr_plt.sh_offset;
816
817    if (shdr_rel_plt.sh_type == SHT_RELA) {
818        GElf_Rela pos_mem, *pos;
819
820        elf_section__for_each_rela(reldata, pos, pos_mem, idx,
821                       nr_rel_entries) {
822            symidx = GELF_R_SYM(pos->r_info);
823            plt_offset += shdr_plt.sh_entsize;
824            gelf_getsym(syms, symidx, &sym);
825            snprintf(sympltname, sizeof(sympltname),
826                 "%s@plt", elf_sym__name(&sym, symstrs));
827
828            f = symbol__new(plt_offset, shdr_plt.sh_entsize,
829                    sympltname);
830            if (!f)
831                goto out_elf_end;
832
833            if (filter && filter(map, f))
834                symbol__delete(f);
835            else {
836                symbols__insert(&self->symbols[map->type], f);
837                ++nr;
838            }
839        }
840    } else if (shdr_rel_plt.sh_type == SHT_REL) {
841        GElf_Rel pos_mem, *pos;
842        elf_section__for_each_rel(reldata, pos, pos_mem, idx,
843                      nr_rel_entries) {
844            symidx = GELF_R_SYM(pos->r_info);
845            plt_offset += shdr_plt.sh_entsize;
846            gelf_getsym(syms, symidx, &sym);
847            snprintf(sympltname, sizeof(sympltname),
848                 "%s@plt", elf_sym__name(&sym, symstrs));
849
850            f = symbol__new(plt_offset, shdr_plt.sh_entsize,
851                    sympltname);
852            if (!f)
853                goto out_elf_end;
854
855            if (filter && filter(map, f))
856                symbol__delete(f);
857            else {
858                symbols__insert(&self->symbols[map->type], f);
859                ++nr;
860            }
861        }
862    }
863
864    err = 0;
865out_elf_end:
866    elf_end(elf);
867out_close:
868    close(fd);
869
870    if (err == 0)
871        return nr;
872out:
873    pr_warning("%s: problems reading %s PLT info.\n",
874           __func__, self->long_name);
875    return 0;
876}
877
878static bool elf_sym__is_a(GElf_Sym *self, enum map_type type)
879{
880    switch (type) {
881    case MAP__FUNCTION:
882        return elf_sym__is_function(self);
883    case MAP__VARIABLE:
884        return elf_sym__is_object(self);
885    default:
886        return false;
887    }
888}
889
890static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type)
891{
892    switch (type) {
893    case MAP__FUNCTION:
894        return elf_sec__is_text(self, secstrs);
895    case MAP__VARIABLE:
896        return elf_sec__is_data(self, secstrs);
897    default:
898        return false;
899    }
900}
901
902static int dso__load_sym(struct dso *self, struct map *map, const char *name,
903             int fd, symbol_filter_t filter, int kmodule)
904{
905    struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
906    struct map *curr_map = map;
907    struct dso *curr_dso = self;
908    Elf_Data *symstrs, *secstrs;
909    uint32_t nr_syms;
910    int err = -1;
911    uint32_t idx;
912    GElf_Ehdr ehdr;
913    GElf_Shdr shdr;
914    Elf_Data *syms;
915    GElf_Sym sym;
916    Elf_Scn *sec, *sec_strndx;
917    Elf *elf;
918    int nr = 0;
919
920    elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
921    if (elf == NULL) {
922        pr_err("%s: cannot read %s ELF file.\n", __func__, name);
923        goto out_close;
924    }
925
926    if (gelf_getehdr(elf, &ehdr) == NULL) {
927        pr_err("%s: cannot get elf header.\n", __func__);
928        goto out_elf_end;
929    }
930
931    sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
932    if (sec == NULL) {
933        sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
934        if (sec == NULL)
935            goto out_elf_end;
936    }
937
938    syms = elf_getdata(sec, NULL);
939    if (syms == NULL)
940        goto out_elf_end;
941
942    sec = elf_getscn(elf, shdr.sh_link);
943    if (sec == NULL)
944        goto out_elf_end;
945
946    symstrs = elf_getdata(sec, NULL);
947    if (symstrs == NULL)
948        goto out_elf_end;
949
950    sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
951    if (sec_strndx == NULL)
952        goto out_elf_end;
953
954    secstrs = elf_getdata(sec_strndx, NULL);
955    if (secstrs == NULL)
956        goto out_elf_end;
957
958    nr_syms = shdr.sh_size / shdr.sh_entsize;
959
960    memset(&sym, 0, sizeof(sym));
961    if (!self->kernel) {
962        self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
963                elf_section_by_name(elf, &ehdr, &shdr,
964                             ".gnu.prelink_undo",
965                             NULL) != NULL);
966    } else self->adjust_symbols = 0;
967
968    elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
969        struct symbol *f;
970        const char *elf_name = elf_sym__name(&sym, symstrs);
971        char *demangled = NULL;
972        int is_label = elf_sym__is_label(&sym);
973        const char *section_name;
974
975        if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
976            strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
977            kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
978
979        if (!is_label && !elf_sym__is_a(&sym, map->type))
980            continue;
981
982        sec = elf_getscn(elf, sym.st_shndx);
983        if (!sec)
984            goto out_elf_end;
985
986        gelf_getshdr(sec, &shdr);
987
988        if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
989            continue;
990
991        section_name = elf_sec__name(&shdr, secstrs);
992
993        if (self->kernel || kmodule) {
994            char dso_name[PATH_MAX];
995
996            if (strcmp(section_name,
997                   (curr_dso->short_name +
998                    self->short_name_len)) == 0)
999                goto new_symbol;
1000
1001            if (strcmp(section_name, ".text") == 0) {
1002                curr_map = map;
1003                curr_dso = self;
1004                goto new_symbol;
1005            }
1006
1007            snprintf(dso_name, sizeof(dso_name),
1008                 "%s%s", self->short_name, section_name);
1009
1010            curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1011            if (curr_map == NULL) {
1012                u64 start = sym.st_value;
1013
1014                if (kmodule)
1015                    start += map->start + shdr.sh_offset;
1016
1017                curr_dso = dso__new(dso_name);
1018                if (curr_dso == NULL)
1019                    goto out_elf_end;
1020                curr_map = map__new2(start, curr_dso,
1021                             map->type);
1022                if (curr_map == NULL) {
1023                    dso__delete(curr_dso);
1024                    goto out_elf_end;
1025                }
1026                curr_map->map_ip = identity__map_ip;
1027                curr_map->unmap_ip = identity__map_ip;
1028                curr_dso->origin = DSO__ORIG_KERNEL;
1029                map_groups__insert(kmap->kmaps, curr_map);
1030                dsos__add(&dsos__kernel, curr_dso);
1031                dso__set_loaded(curr_dso, map->type);
1032            } else
1033                curr_dso = curr_map->dso;
1034
1035            goto new_symbol;
1036        }
1037
1038        if (curr_dso->adjust_symbols) {
1039            pr_debug4("%s: adjusting symbol: st_value: %#Lx "
1040                  "sh_addr: %#Lx sh_offset: %#Lx\n", __func__,
1041                  (u64)sym.st_value, (u64)shdr.sh_addr,
1042                  (u64)shdr.sh_offset);
1043            sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1044        }
1045        /*
1046         * We need to figure out if the object was created from C++ sources
1047         * DWARF DW_compile_unit has this, but we don't always have access
1048         * to it...
1049         */
1050        demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
1051        if (demangled != NULL)
1052            elf_name = demangled;
1053new_symbol:
1054        f = symbol__new(sym.st_value, sym.st_size, elf_name);
1055        free(demangled);
1056        if (!f)
1057            goto out_elf_end;
1058
1059        if (filter && filter(curr_map, f))
1060            symbol__delete(f);
1061        else {
1062            symbols__insert(&curr_dso->symbols[curr_map->type], f);
1063            nr++;
1064        }
1065    }
1066
1067    /*
1068     * For misannotated, zeroed, ASM function sizes.
1069     */
1070    if (nr > 0) {
1071        symbols__fixup_end(&self->symbols[map->type]);
1072        if (kmap) {
1073            /*
1074             * We need to fixup this here too because we create new
1075             * maps here, for things like vsyscall sections.
1076             */
1077            __map_groups__fixup_end(kmap->kmaps, map->type);
1078        }
1079    }
1080    err = nr;
1081out_elf_end:
1082    elf_end(elf);
1083out_close:
1084    return err;
1085}
1086
1087static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
1088{
1089    return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
1090}
1091
1092static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1093{
1094    bool have_build_id = false;
1095    struct dso *pos;
1096
1097    list_for_each_entry(pos, head, node) {
1098        if (with_hits && !pos->hit)
1099            continue;
1100        if (filename__read_build_id(pos->long_name, pos->build_id,
1101                        sizeof(pos->build_id)) > 0) {
1102            have_build_id = true;
1103            pos->has_build_id = true;
1104        }
1105    }
1106
1107    return have_build_id;
1108}
1109
1110bool dsos__read_build_ids(bool with_hits)
1111{
1112    bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
1113         ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
1114    return kbuildids || ubuildids;
1115}
1116
1117/*
1118 * Align offset to 4 bytes as needed for note name and descriptor data.
1119 */
1120#define NOTE_ALIGN(n) (((n) + 3) & -4U)
1121
1122int filename__read_build_id(const char *filename, void *bf, size_t size)
1123{
1124    int fd, err = -1;
1125    GElf_Ehdr ehdr;
1126    GElf_Shdr shdr;
1127    Elf_Data *data;
1128    Elf_Scn *sec;
1129    Elf_Kind ek;
1130    void *ptr;
1131    Elf *elf;
1132
1133    if (size < BUILD_ID_SIZE)
1134        goto out;
1135
1136    fd = open(filename, O_RDONLY);
1137    if (fd < 0)
1138        goto out;
1139
1140    elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1141    if (elf == NULL) {
1142        pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1143        goto out_close;
1144    }
1145
1146    ek = elf_kind(elf);
1147    if (ek != ELF_K_ELF)
1148        goto out_elf_end;
1149
1150    if (gelf_getehdr(elf, &ehdr) == NULL) {
1151        pr_err("%s: cannot get elf header.\n", __func__);
1152        goto out_elf_end;
1153    }
1154
1155    sec = elf_section_by_name(elf, &ehdr, &shdr,
1156                  ".note.gnu.build-id", NULL);
1157    if (sec == NULL) {
1158        sec = elf_section_by_name(elf, &ehdr, &shdr,
1159                      ".notes", NULL);
1160        if (sec == NULL)
1161            goto out_elf_end;
1162    }
1163
1164    data = elf_getdata(sec, NULL);
1165    if (data == NULL)
1166        goto out_elf_end;
1167
1168    ptr = data->d_buf;
1169    while (ptr < (data->d_buf + data->d_size)) {
1170        GElf_Nhdr *nhdr = ptr;
1171        int namesz = NOTE_ALIGN(nhdr->n_namesz),
1172            descsz = NOTE_ALIGN(nhdr->n_descsz);
1173        const char *name;
1174
1175        ptr += sizeof(*nhdr);
1176        name = ptr;
1177        ptr += namesz;
1178        if (nhdr->n_type == NT_GNU_BUILD_ID &&
1179            nhdr->n_namesz == sizeof("GNU")) {
1180            if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1181                memcpy(bf, ptr, BUILD_ID_SIZE);
1182                err = BUILD_ID_SIZE;
1183                break;
1184            }
1185        }
1186        ptr += descsz;
1187    }
1188out_elf_end:
1189    elf_end(elf);
1190out_close:
1191    close(fd);
1192out:
1193    return err;
1194}
1195
1196int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1197{
1198    int fd, err = -1;
1199
1200    if (size < BUILD_ID_SIZE)
1201        goto out;
1202
1203    fd = open(filename, O_RDONLY);
1204    if (fd < 0)
1205        goto out;
1206
1207    while (1) {
1208        char bf[BUFSIZ];
1209        GElf_Nhdr nhdr;
1210        int namesz, descsz;
1211
1212        if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1213            break;
1214
1215        namesz = NOTE_ALIGN(nhdr.n_namesz);
1216        descsz = NOTE_ALIGN(nhdr.n_descsz);
1217        if (nhdr.n_type == NT_GNU_BUILD_ID &&
1218            nhdr.n_namesz == sizeof("GNU")) {
1219            if (read(fd, bf, namesz) != namesz)
1220                break;
1221            if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1222                if (read(fd, build_id,
1223                    BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1224                    err = 0;
1225                    break;
1226                }
1227            } else if (read(fd, bf, descsz) != descsz)
1228                break;
1229        } else {
1230            int n = namesz + descsz;
1231            if (read(fd, bf, n) != n)
1232                break;
1233        }
1234    }
1235    close(fd);
1236out:
1237    return err;
1238}
1239
1240char dso__symtab_origin(const struct dso *self)
1241{
1242    static const char origin[] = {
1243        [DSO__ORIG_KERNEL] = 'k',
1244        [DSO__ORIG_JAVA_JIT] = 'j',
1245        [DSO__ORIG_BUILD_ID_CACHE] = 'B',
1246        [DSO__ORIG_FEDORA] = 'f',
1247        [DSO__ORIG_UBUNTU] = 'u',
1248        [DSO__ORIG_BUILDID] = 'b',
1249        [DSO__ORIG_DSO] = 'd',
1250        [DSO__ORIG_KMODULE] = 'K',
1251    };
1252
1253    if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
1254        return '!';
1255    return origin[self->origin];
1256}
1257
1258int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1259{
1260    int size = PATH_MAX;
1261    char *name;
1262    u8 build_id[BUILD_ID_SIZE];
1263    char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1264    int ret = -1;
1265    int fd;
1266
1267    dso__set_loaded(self, map->type);
1268
1269    if (self->kernel)
1270        return dso__load_kernel_sym(self, map, filter);
1271
1272    name = malloc(size);
1273    if (!name)
1274        return -1;
1275
1276    self->adjust_symbols = 0;
1277
1278    if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1279        ret = dso__load_perf_map(self, map, filter);
1280        self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
1281                     DSO__ORIG_NOT_FOUND;
1282        return ret;
1283    }
1284
1285    self->origin = DSO__ORIG_BUILD_ID_CACHE;
1286
1287    if (self->has_build_id) {
1288        build_id__sprintf(self->build_id, sizeof(self->build_id),
1289                  build_id_hex);
1290        snprintf(name, size, "%s/%s/.build-id/%.2s/%s",
1291             getenv("HOME"), DEBUG_CACHE_DIR,
1292             build_id_hex, build_id_hex + 2);
1293        goto open_file;
1294    }
1295more:
1296    do {
1297        self->origin++;
1298        switch (self->origin) {
1299        case DSO__ORIG_FEDORA:
1300            snprintf(name, size, "/usr/lib/debug%s.debug",
1301                 self->long_name);
1302            break;
1303        case DSO__ORIG_UBUNTU:
1304            snprintf(name, size, "/usr/lib/debug%s",
1305                 self->long_name);
1306            break;
1307        case DSO__ORIG_BUILDID:
1308            if (filename__read_build_id(self->long_name, build_id,
1309                            sizeof(build_id))) {
1310                build_id__sprintf(build_id, sizeof(build_id),
1311                          build_id_hex);
1312                snprintf(name, size,
1313                     "/usr/lib/debug/.build-id/%.2s/%s.debug",
1314                    build_id_hex, build_id_hex + 2);
1315                if (self->has_build_id)
1316                    goto compare_build_id;
1317                break;
1318            }
1319            self->origin++;
1320            /* Fall thru */
1321        case DSO__ORIG_DSO:
1322            snprintf(name, size, "%s", self->long_name);
1323            break;
1324
1325        default:
1326            goto out;
1327        }
1328
1329        if (self->has_build_id) {
1330            if (filename__read_build_id(name, build_id,
1331                            sizeof(build_id)) < 0)
1332                goto more;
1333compare_build_id:
1334            if (!dso__build_id_equal(self, build_id))
1335                goto more;
1336        }
1337open_file:
1338        fd = open(name, O_RDONLY);
1339    } while (fd < 0);
1340
1341    ret = dso__load_sym(self, map, name, fd, filter, 0);
1342    close(fd);
1343
1344    /*
1345     * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1346     */
1347    if (!ret)
1348        goto more;
1349
1350    if (ret > 0) {
1351        int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1352        if (nr_plt > 0)
1353            ret += nr_plt;
1354    }
1355out:
1356    free(name);
1357    if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1358        return 0;
1359    return ret;
1360}
1361
1362struct map *map_groups__find_by_name(struct map_groups *self,
1363                     enum map_type type, const char *name)
1364{
1365    struct rb_node *nd;
1366
1367    for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
1368        struct map *map = rb_entry(nd, struct map, rb_node);
1369
1370        if (map->dso && strcmp(map->dso->short_name, name) == 0)
1371            return map;
1372    }
1373
1374    return NULL;
1375}
1376
1377static int dso__kernel_module_get_build_id(struct dso *self)
1378{
1379    char filename[PATH_MAX];
1380    /*
1381     * kernel module short names are of the form "[module]" and
1382     * we need just "module" here.
1383     */
1384    const char *name = self->short_name + 1;
1385
1386    snprintf(filename, sizeof(filename),
1387         "/sys/module/%.*s/notes/.note.gnu.build-id",
1388         (int)strlen(name - 1), name);
1389
1390    if (sysfs__read_build_id(filename, self->build_id,
1391                 sizeof(self->build_id)) == 0)
1392        self->has_build_id = true;
1393
1394    return 0;
1395}
1396
1397static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirname)
1398{
1399    struct dirent *dent;
1400    DIR *dir = opendir(dirname);
1401
1402    if (!dir) {
1403        pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1404        return -1;
1405    }
1406
1407    while ((dent = readdir(dir)) != NULL) {
1408        char path[PATH_MAX];
1409
1410        if (dent->d_type == DT_DIR) {
1411            if (!strcmp(dent->d_name, ".") ||
1412                !strcmp(dent->d_name, ".."))
1413                continue;
1414
1415            snprintf(path, sizeof(path), "%s/%s",
1416                 dirname, dent->d_name);
1417            if (map_groups__set_modules_path_dir(self, path) < 0)
1418                goto failure;
1419        } else {
1420            char *dot = strrchr(dent->d_name, '.'),
1421                 dso_name[PATH_MAX];
1422            struct map *map;
1423            char *long_name;
1424
1425            if (dot == NULL || strcmp(dot, ".ko"))
1426                continue;
1427            snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1428                 (int)(dot - dent->d_name), dent->d_name);
1429
1430            strxfrchar(dso_name, '-', '_');
1431            map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name);
1432            if (map == NULL)
1433                continue;
1434
1435            snprintf(path, sizeof(path), "%s/%s",
1436                 dirname, dent->d_name);
1437
1438            long_name = strdup(path);
1439            if (long_name == NULL)
1440                goto failure;
1441            dso__set_long_name(map->dso, long_name);
1442            dso__kernel_module_get_build_id(map->dso);
1443        }
1444    }
1445
1446    return 0;
1447failure:
1448    closedir(dir);
1449    return -1;
1450}
1451
1452static int map_groups__set_modules_path(struct map_groups *self)
1453{
1454    struct utsname uts;
1455    char modules_path[PATH_MAX];
1456
1457    if (uname(&uts) < 0)
1458        return -1;
1459
1460    snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1461         uts.release);
1462
1463    return map_groups__set_modules_path_dir(self, modules_path);
1464}
1465
1466/*
1467 * Constructor variant for modules (where we know from /proc/modules where
1468 * they are loaded) and for vmlinux, where only after we load all the
1469 * symbols we'll know where it starts and ends.
1470 */
1471static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1472{
1473    struct map *self = zalloc(sizeof(*self) +
1474                  (dso->kernel ? sizeof(struct kmap) : 0));
1475    if (self != NULL) {
1476        /*
1477         * ->end will be filled after we load all the symbols
1478         */
1479        map__init(self, type, start, 0, 0, dso);
1480    }
1481
1482    return self;
1483}
1484
1485struct map *map_groups__new_module(struct map_groups *self, u64 start,
1486                   const char *filename)
1487{
1488    struct map *map;
1489    struct dso *dso = __dsos__findnew(&dsos__kernel, filename);
1490
1491    if (dso == NULL)
1492        return NULL;
1493
1494    map = map__new2(start, dso, MAP__FUNCTION);
1495    if (map == NULL)
1496        return NULL;
1497
1498    dso->origin = DSO__ORIG_KMODULE;
1499    map_groups__insert(self, map);
1500    return map;
1501}
1502
1503static int map_groups__create_modules(struct map_groups *self)
1504{
1505    char *line = NULL;
1506    size_t n;
1507    FILE *file = fopen("/proc/modules", "r");
1508    struct map *map;
1509
1510    if (file == NULL)
1511        return -1;
1512
1513    while (!feof(file)) {
1514        char name[PATH_MAX];
1515        u64 start;
1516        char *sep;
1517        int line_len;
1518
1519        line_len = getline(&line, &n, file);
1520        if (line_len < 0)
1521            break;
1522
1523        if (!line)
1524            goto out_failure;
1525
1526        line[--line_len] = '\0'; /* \n */
1527
1528        sep = strrchr(line, 'x');
1529        if (sep == NULL)
1530            continue;
1531
1532        hex2u64(sep + 1, &start);
1533
1534        sep = strchr(line, ' ');
1535        if (sep == NULL)
1536            continue;
1537
1538        *sep = '\0';
1539
1540        snprintf(name, sizeof(name), "[%s]", line);
1541        map = map_groups__new_module(self, start, name);
1542        if (map == NULL)
1543            goto out_delete_line;
1544        dso__kernel_module_get_build_id(map->dso);
1545    }
1546
1547    free(line);
1548    fclose(file);
1549
1550    return map_groups__set_modules_path(self);
1551
1552out_delete_line:
1553    free(line);
1554out_failure:
1555    return -1;
1556}
1557
1558static int dso__load_vmlinux(struct dso *self, struct map *map,
1559                 const char *vmlinux, symbol_filter_t filter)
1560{
1561    int err = -1, fd;
1562
1563    if (self->has_build_id) {
1564        u8 build_id[BUILD_ID_SIZE];
1565
1566        if (filename__read_build_id(vmlinux, build_id,
1567                        sizeof(build_id)) < 0) {
1568            pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1569            return -1;
1570        }
1571        if (!dso__build_id_equal(self, build_id)) {
1572            char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1573                 vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1574
1575            build_id__sprintf(self->build_id,
1576                      sizeof(self->build_id),
1577                      expected_build_id);
1578            build_id__sprintf(build_id, sizeof(build_id),
1579                      vmlinux_build_id);
1580            pr_debug("build_id in %s is %s while expected is %s, "
1581                 "ignoring it\n", vmlinux, vmlinux_build_id,
1582                 expected_build_id);
1583            return -1;
1584        }
1585    }
1586
1587    fd = open(vmlinux, O_RDONLY);
1588    if (fd < 0)
1589        return -1;
1590
1591    dso__set_loaded(self, map->type);
1592    err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
1593    close(fd);
1594
1595    if (err > 0)
1596        pr_debug("Using %s for symbols\n", vmlinux);
1597
1598    return err;
1599}
1600
1601int dso__load_vmlinux_path(struct dso *self, struct map *map,
1602               symbol_filter_t filter)
1603{
1604    int i, err = 0;
1605
1606    pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1607         vmlinux_path__nr_entries);
1608
1609    for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1610        err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
1611        if (err > 0) {
1612            dso__set_long_name(self, strdup(vmlinux_path[i]));
1613            break;
1614        }
1615    }
1616
1617    return err;
1618}
1619
1620static int dso__load_kernel_sym(struct dso *self, struct map *map,
1621                symbol_filter_t filter)
1622{
1623    int err;
1624    const char *kallsyms_filename = NULL;
1625    char *kallsyms_allocated_filename = NULL;
1626    /*
1627     * Step 1: if the user specified a vmlinux filename, use it and only
1628     * it, reporting errors to the user if it cannot be used.
1629     *
1630     * For instance, try to analyse an ARM perf.data file _without_ a
1631     * build-id, or if the user specifies the wrong path to the right
1632     * vmlinux file, obviously we can't fallback to another vmlinux (a
1633     * x86_86 one, on the machine where analysis is being performed, say),
1634     * or worse, /proc/kallsyms.
1635     *
1636     * If the specified file _has_ a build-id and there is a build-id
1637     * section in the perf.data file, we will still do the expected
1638     * validation in dso__load_vmlinux and will bail out if they don't
1639     * match.
1640     */
1641    if (symbol_conf.vmlinux_name != NULL) {
1642        err = dso__load_vmlinux(self, map,
1643                    symbol_conf.vmlinux_name, filter);
1644        goto out_try_fixup;
1645    }
1646
1647    if (vmlinux_path != NULL) {
1648        err = dso__load_vmlinux_path(self, map, filter);
1649        if (err > 0)
1650            goto out_fixup;
1651    }
1652
1653    /*
1654     * Say the kernel DSO was created when processing the build-id header table,
1655     * we have a build-id, so check if it is the same as the running kernel,
1656     * using it if it is.
1657     */
1658    if (self->has_build_id) {
1659        u8 kallsyms_build_id[BUILD_ID_SIZE];
1660        char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1661
1662        if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1663                     sizeof(kallsyms_build_id)) == 0) {
1664            if (dso__build_id_equal(self, kallsyms_build_id)) {
1665                kallsyms_filename = "/proc/kallsyms";
1666                goto do_kallsyms;
1667            }
1668        }
1669        /*
1670         * Now look if we have it on the build-id cache in
1671         * $HOME/.debug/[kernel.kallsyms].
1672         */
1673        build_id__sprintf(self->build_id, sizeof(self->build_id),
1674                  sbuild_id);
1675
1676        if (asprintf(&kallsyms_allocated_filename,
1677                 "%s/.debug/[kernel.kallsyms]/%s",
1678                 getenv("HOME"), sbuild_id) == -1) {
1679            pr_err("Not enough memory for kallsyms file lookup\n");
1680            return -1;
1681        }
1682
1683        kallsyms_filename = kallsyms_allocated_filename;
1684
1685        if (access(kallsyms_filename, F_OK)) {
1686            pr_err("No kallsyms or vmlinux with build-id %s "
1687                   "was found\n", sbuild_id);
1688            free(kallsyms_allocated_filename);
1689            return -1;
1690        }
1691    } else {
1692        /*
1693         * Last resort, if we don't have a build-id and couldn't find
1694         * any vmlinux file, try the running kernel kallsyms table.
1695         */
1696        kallsyms_filename = "/proc/kallsyms";
1697    }
1698
1699do_kallsyms:
1700    err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1701    if (err > 0)
1702        pr_debug("Using %s for symbols\n", kallsyms_filename);
1703    free(kallsyms_allocated_filename);
1704
1705out_try_fixup:
1706    if (err > 0) {
1707out_fixup:
1708        if (kallsyms_filename != NULL)
1709            dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1710        map__fixup_start(map);
1711        map__fixup_end(map);
1712    }
1713
1714    return err;
1715}
1716
1717LIST_HEAD(dsos__user);
1718LIST_HEAD(dsos__kernel);
1719
1720static void dsos__add(struct list_head *head, struct dso *dso)
1721{
1722    list_add_tail(&dso->node, head);
1723}
1724
1725static struct dso *dsos__find(struct list_head *head, const char *name)
1726{
1727    struct dso *pos;
1728
1729    list_for_each_entry(pos, head, node)
1730        if (strcmp(pos->long_name, name) == 0)
1731            return pos;
1732    return NULL;
1733}
1734
1735struct dso *__dsos__findnew(struct list_head *head, const char *name)
1736{
1737    struct dso *dso = dsos__find(head, name);
1738
1739    if (!dso) {
1740        dso = dso__new(name);
1741        if (dso != NULL) {
1742            dsos__add(head, dso);
1743            dso__set_basename(dso);
1744        }
1745    }
1746
1747    return dso;
1748}
1749
1750static void __dsos__fprintf(struct list_head *head, FILE *fp)
1751{
1752    struct dso *pos;
1753
1754    list_for_each_entry(pos, head, node) {
1755        int i;
1756        for (i = 0; i < MAP__NR_TYPES; ++i)
1757            dso__fprintf(pos, i, fp);
1758    }
1759}
1760
1761void dsos__fprintf(FILE *fp)
1762{
1763    __dsos__fprintf(&dsos__kernel, fp);
1764    __dsos__fprintf(&dsos__user, fp);
1765}
1766
1767static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1768                      bool with_hits)
1769{
1770    struct dso *pos;
1771    size_t ret = 0;
1772
1773    list_for_each_entry(pos, head, node) {
1774        if (with_hits && !pos->hit)
1775            continue;
1776        ret += dso__fprintf_buildid(pos, fp);
1777        ret += fprintf(fp, " %s\n", pos->long_name);
1778    }
1779    return ret;
1780}
1781
1782size_t dsos__fprintf_buildid(FILE *fp, bool with_hits)
1783{
1784    return (__dsos__fprintf_buildid(&dsos__kernel, fp, with_hits) +
1785        __dsos__fprintf_buildid(&dsos__user, fp, with_hits));
1786}
1787
1788struct dso *dso__new_kernel(const char *name)
1789{
1790    struct dso *self = dso__new(name ?: "[kernel.kallsyms]");
1791
1792    if (self != NULL) {
1793        dso__set_short_name(self, "[kernel]");
1794        self->kernel = 1;
1795    }
1796
1797    return self;
1798}
1799
1800void dso__read_running_kernel_build_id(struct dso *self)
1801{
1802    if (sysfs__read_build_id("/sys/kernel/notes", self->build_id,
1803                 sizeof(self->build_id)) == 0)
1804        self->has_build_id = true;
1805}
1806
1807static struct dso *dsos__create_kernel(const char *vmlinux)
1808{
1809    struct dso *kernel = dso__new_kernel(vmlinux);
1810
1811    if (kernel != NULL) {
1812        dso__read_running_kernel_build_id(kernel);
1813        dsos__add(&dsos__kernel, kernel);
1814    }
1815
1816    return kernel;
1817}
1818
1819int __map_groups__create_kernel_maps(struct map_groups *self,
1820                     struct map *vmlinux_maps[MAP__NR_TYPES],
1821                     struct dso *kernel)
1822{
1823    enum map_type type;
1824
1825    for (type = 0; type < MAP__NR_TYPES; ++type) {
1826        struct kmap *kmap;
1827
1828        vmlinux_maps[type] = map__new2(0, kernel, type);
1829        if (vmlinux_maps[type] == NULL)
1830            return -1;
1831
1832        vmlinux_maps[type]->map_ip =
1833            vmlinux_maps[type]->unmap_ip = identity__map_ip;
1834
1835        kmap = map__kmap(vmlinux_maps[type]);
1836        kmap->kmaps = self;
1837        map_groups__insert(self, vmlinux_maps[type]);
1838    }
1839
1840    return 0;
1841}
1842
1843static void vmlinux_path__exit(void)
1844{
1845    while (--vmlinux_path__nr_entries >= 0) {
1846        free(vmlinux_path[vmlinux_path__nr_entries]);
1847        vmlinux_path[vmlinux_path__nr_entries] = NULL;
1848    }
1849
1850    free(vmlinux_path);
1851    vmlinux_path = NULL;
1852}
1853
1854static int vmlinux_path__init(void)
1855{
1856    struct utsname uts;
1857    char bf[PATH_MAX];
1858
1859    if (uname(&uts) < 0)
1860        return -1;
1861
1862    vmlinux_path = malloc(sizeof(char *) * 5);
1863    if (vmlinux_path == NULL)
1864        return -1;
1865
1866    vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1867    if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1868        goto out_fail;
1869    ++vmlinux_path__nr_entries;
1870    vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1871    if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1872        goto out_fail;
1873    ++vmlinux_path__nr_entries;
1874    snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1875    vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1876    if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1877        goto out_fail;
1878    ++vmlinux_path__nr_entries;
1879    snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1880    vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1881    if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1882        goto out_fail;
1883    ++vmlinux_path__nr_entries;
1884    snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1885         uts.release);
1886    vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1887    if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1888        goto out_fail;
1889    ++vmlinux_path__nr_entries;
1890
1891    return 0;
1892
1893out_fail:
1894    vmlinux_path__exit();
1895    return -1;
1896}
1897
1898static int setup_list(struct strlist **list, const char *list_str,
1899              const char *list_name)
1900{
1901    if (list_str == NULL)
1902        return 0;
1903
1904    *list = strlist__new(true, list_str);
1905    if (!*list) {
1906        pr_err("problems parsing %s list\n", list_name);
1907        return -1;
1908    }
1909    return 0;
1910}
1911
1912int symbol__init(void)
1913{
1914    elf_version(EV_CURRENT);
1915    if (symbol_conf.sort_by_name)
1916        symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1917                      sizeof(struct symbol));
1918
1919    if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
1920        return -1;
1921
1922    if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
1923        pr_err("'.' is the only non valid --field-separator argument\n");
1924        return -1;
1925    }
1926
1927    if (setup_list(&symbol_conf.dso_list,
1928               symbol_conf.dso_list_str, "dso") < 0)
1929        return -1;
1930
1931    if (setup_list(&symbol_conf.comm_list,
1932               symbol_conf.comm_list_str, "comm") < 0)
1933        goto out_free_dso_list;
1934
1935    if (setup_list(&symbol_conf.sym_list,
1936               symbol_conf.sym_list_str, "symbol") < 0)
1937        goto out_free_comm_list;
1938
1939    return 0;
1940
1941out_free_dso_list:
1942    strlist__delete(symbol_conf.dso_list);
1943out_free_comm_list:
1944    strlist__delete(symbol_conf.comm_list);
1945    return -1;
1946}
1947
1948int map_groups__create_kernel_maps(struct map_groups *self,
1949                   struct map *vmlinux_maps[MAP__NR_TYPES])
1950{
1951    struct dso *kernel = dsos__create_kernel(symbol_conf.vmlinux_name);
1952
1953    if (kernel == NULL)
1954        return -1;
1955
1956    if (__map_groups__create_kernel_maps(self, vmlinux_maps, kernel) < 0)
1957        return -1;
1958
1959    if (symbol_conf.use_modules && map_groups__create_modules(self) < 0)
1960        pr_debug("Problems creating module maps, continuing anyway...\n");
1961    /*
1962     * Now that we have all the maps created, just set the ->end of them:
1963     */
1964    map_groups__fixup_end(self);
1965    return 0;
1966}
1967

Archive Download this file



interactive