linux/tools/perf/util/symbol.c
<<
>>
Prefs
   1#define _GNU_SOURCE
   2#include <ctype.h>
   3#include <dirent.h>
   4#include <errno.h>
   5#include <libgen.h>
   6#include <stdlib.h>
   7#include <stdio.h>
   8#include <string.h>
   9#include <sys/types.h>
  10#include <sys/stat.h>
  11#include <sys/param.h>
  12#include <fcntl.h>
  13#include <unistd.h>
  14#include "build-id.h"
  15#include "symbol.h"
  16#include "strlist.h"
  17
  18#include <libelf.h>
  19#include <gelf.h>
  20#include <elf.h>
  21#include <limits.h>
  22#include <sys/utsname.h>
  23
  24#ifndef NT_GNU_BUILD_ID
  25#define NT_GNU_BUILD_ID 3
  26#endif
  27
  28static void dsos__add(struct list_head *head, struct dso *dso);
  29static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
  30static int dso__load_kernel_sym(struct dso *self, struct map *map,
  31                                symbol_filter_t filter);
  32static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
  33                        symbol_filter_t filter);
  34static int vmlinux_path__nr_entries;
  35static char **vmlinux_path;
  36
  37struct symbol_conf symbol_conf = {
  38        .exclude_other    = true,
  39        .use_modules      = true,
  40        .try_vmlinux_path = true,
  41};
  42
  43bool dso__loaded(const struct dso *self, enum map_type type)
  44{
  45        return self->loaded & (1 << type);
  46}
  47
  48bool dso__sorted_by_name(const struct dso *self, enum map_type type)
  49{
  50        return self->sorted_by_name & (1 << type);
  51}
  52
  53static void dso__set_sorted_by_name(struct dso *self, enum map_type type)
  54{
  55        self->sorted_by_name |= (1 << type);
  56}
  57
  58bool symbol_type__is_a(char symbol_type, enum map_type map_type)
  59{
  60        switch (map_type) {
  61        case MAP__FUNCTION:
  62                return symbol_type == 'T' || symbol_type == 'W';
  63        case MAP__VARIABLE:
  64                return symbol_type == 'D' || symbol_type == 'd';
  65        default:
  66                return false;
  67        }
  68}
  69
  70static void symbols__fixup_end(struct rb_root *self)
  71{
  72        struct rb_node *nd, *prevnd = rb_first(self);
  73        struct symbol *curr, *prev;
  74
  75        if (prevnd == NULL)
  76                return;
  77
  78        curr = rb_entry(prevnd, struct symbol, rb_node);
  79
  80        for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
  81                prev = curr;
  82                curr = rb_entry(nd, struct symbol, rb_node);
  83
  84                if (prev->end == prev->start)
  85                        prev->end = curr->start - 1;
  86        }
  87
  88        /* Last entry */
  89        if (curr->end == curr->start)
  90                curr->end = roundup(curr->start, 4096);
  91}
  92
  93static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
  94{
  95        struct map *prev, *curr;
  96        struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
  97
  98        if (prevnd == NULL)
  99                return;
 100
 101        curr = rb_entry(prevnd, struct map, rb_node);
 102
 103        for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
 104                prev = curr;
 105                curr = rb_entry(nd, struct map, rb_node);
 106                prev->end = curr->start - 1;
 107        }
 108
 109        /*
 110         * We still haven't the actual symbols, so guess the
 111         * last map final address.
 112         */
 113        curr->end = ~0UL;
 114}
 115
 116static void map_groups__fixup_end(struct map_groups *self)
 117{
 118        int i;
 119        for (i = 0; i < MAP__NR_TYPES; ++i)
 120                __map_groups__fixup_end(self, i);
 121}
 122
 123static struct symbol *symbol__new(u64 start, u64 len, const char *name)
 124{
 125        size_t namelen = strlen(name) + 1;
 126        struct symbol *self = calloc(1, (symbol_conf.priv_size +
 127                                         sizeof(*self) + namelen));
 128        if (self == NULL)
 129                return NULL;
 130
 131        if (symbol_conf.priv_size)
 132                self = ((void *)self) + symbol_conf.priv_size;
 133
 134        self->start   = start;
 135        self->end     = len ? start + len - 1 : start;
 136        self->namelen = namelen - 1;
 137
 138        pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
 139
 140        memcpy(self->name, name, namelen);
 141
 142        return self;
 143}
 144
 145void symbol__delete(struct symbol *self)
 146{
 147        free(((void *)self) - symbol_conf.priv_size);
 148}
 149
 150static size_t symbol__fprintf(struct symbol *self, FILE *fp)
 151{
 152        return fprintf(fp, " %llx-%llx %s\n",
 153                       self->start, self->end, self->name);
 154}
 155
 156void dso__set_long_name(struct dso *self, char *name)
 157{
 158        if (name == NULL)
 159                return;
 160        self->long_name = name;
 161        self->long_name_len = strlen(name);
 162}
 163
 164static void dso__set_short_name(struct dso *self, const char *name)
 165{
 166        if (name == NULL)
 167                return;
 168        self->short_name = name;
 169        self->short_name_len = strlen(name);
 170}
 171
 172static void dso__set_basename(struct dso *self)
 173{
 174        dso__set_short_name(self, basename(self->long_name));
 175}
 176
 177struct dso *dso__new(const char *name)
 178{
 179        struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1);
 180
 181        if (self != NULL) {
 182                int i;
 183                strcpy(self->name, name);
 184                dso__set_long_name(self, self->name);
 185                dso__set_short_name(self, self->name);
 186                for (i = 0; i < MAP__NR_TYPES; ++i)
 187                        self->symbols[i] = self->symbol_names[i] = RB_ROOT;
 188                self->slen_calculated = 0;
 189                self->origin = DSO__ORIG_NOT_FOUND;
 190                self->loaded = 0;
 191                self->sorted_by_name = 0;
 192                self->has_build_id = 0;
 193                self->kernel = DSO_TYPE_USER;
 194                INIT_LIST_HEAD(&self->node);
 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 || !line)
 412                        break;
 413
 414                line[--line_len] = '\0'; /* \n */
 415
 416                len = hex2u64(line, &start);
 417
 418                len++;
 419                if (len + 2 >= line_len)
 420                        continue;
 421
 422                symbol_type = toupper(line[len]);
 423                symbol_name = line + len + 2;
 424
 425                err = process_symbol(arg, symbol_name, symbol_type, start);
 426                if (err)
 427                        break;
 428        }
 429
 430        free(line);
 431        fclose(file);
 432        return err;
 433
 434out_failure:
 435        return -1;
 436}
 437
 438struct process_kallsyms_args {
 439        struct map *map;
 440        struct dso *dso;
 441};
 442
 443static int map__process_kallsym_symbol(void *arg, const char *name,
 444                                       char type, u64 start)
 445{
 446        struct symbol *sym;
 447        struct process_kallsyms_args *a = arg;
 448        struct rb_root *root = &a->dso->symbols[a->map->type];
 449
 450        if (!symbol_type__is_a(type, a->map->type))
 451                return 0;
 452
 453        /*
 454         * Will fix up the end later, when we have all symbols sorted.
 455         */
 456        sym = symbol__new(start, 0, name);
 457
 458        if (sym == NULL)
 459                return -ENOMEM;
 460        /*
 461         * We will pass the symbols to the filter later, in
 462         * map__split_kallsyms, when we have split the maps per module
 463         */
 464        symbols__insert(root, sym);
 465
 466        return 0;
 467}
 468
 469/*
 470 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
 471 * so that we can in the next step set the symbol ->end address and then
 472 * call kernel_maps__split_kallsyms.
 473 */
 474static int dso__load_all_kallsyms(struct dso *self, const char *filename,
 475                                  struct map *map)
 476{
 477        struct process_kallsyms_args args = { .map = map, .dso = self, };
 478        return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
 479}
 480
 481/*
 482 * Split the symbols into maps, making sure there are no overlaps, i.e. the
 483 * kernel range is broken in several maps, named [kernel].N, as we don't have
 484 * the original ELF section names vmlinux have.
 485 */
 486static int dso__split_kallsyms(struct dso *self, struct map *map,
 487                               symbol_filter_t filter)
 488{
 489        struct map_groups *kmaps = map__kmap(map)->kmaps;
 490        struct machine *machine = kmaps->machine;
 491        struct map *curr_map = map;
 492        struct symbol *pos;
 493        int count = 0;
 494        struct rb_root *root = &self->symbols[map->type];
 495        struct rb_node *next = rb_first(root);
 496        int kernel_range = 0;
 497
 498        while (next) {
 499                char *module;
 500
 501                pos = rb_entry(next, struct symbol, rb_node);
 502                next = rb_next(&pos->rb_node);
 503
 504                module = strchr(pos->name, '\t');
 505                if (module) {
 506                        if (!symbol_conf.use_modules)
 507                                goto discard_symbol;
 508
 509                        *module++ = '\0';
 510
 511                        if (strcmp(curr_map->dso->short_name, module)) {
 512                                if (curr_map != map &&
 513                                    self->kernel == DSO_TYPE_GUEST_KERNEL &&
 514                                    machine__is_default_guest(machine)) {
 515                                        /*
 516                                         * We assume all symbols of a module are
 517                                         * continuous in * kallsyms, so curr_map
 518                                         * points to a module and all its
 519                                         * symbols are in its kmap. Mark it as
 520                                         * loaded.
 521                                         */
 522                                        dso__set_loaded(curr_map->dso,
 523                                                        curr_map->type);
 524                                }
 525
 526                                curr_map = map_groups__find_by_name(kmaps,
 527                                                        map->type, module);
 528                                if (curr_map == NULL) {
 529                                        pr_debug("%s/proc/{kallsyms,modules} "
 530                                                 "inconsistency while looking "
 531                                                 "for \"%s\" module!\n",
 532                                                 machine->root_dir, module);
 533                                        curr_map = map;
 534                                        goto discard_symbol;
 535                                }
 536
 537                                if (curr_map->dso->loaded &&
 538                                    !machine__is_default_guest(machine))
 539                                        goto discard_symbol;
 540                        }
 541                        /*
 542                         * So that we look just like we get from .ko files,
 543                         * i.e. not prelinked, relative to map->start.
 544                         */
 545                        pos->start = curr_map->map_ip(curr_map, pos->start);
 546                        pos->end   = curr_map->map_ip(curr_map, pos->end);
 547                } else if (curr_map != map) {
 548                        char dso_name[PATH_MAX];
 549                        struct dso *dso;
 550
 551                        if (self->kernel == DSO_TYPE_GUEST_KERNEL)
 552                                snprintf(dso_name, sizeof(dso_name),
 553                                        "[guest.kernel].%d",
 554                                        kernel_range++);
 555                        else
 556                                snprintf(dso_name, sizeof(dso_name),
 557                                        "[kernel].%d",
 558                                        kernel_range++);
 559
 560                        dso = dso__new(dso_name);
 561                        if (dso == NULL)
 562                                return -1;
 563
 564                        dso->kernel = self->kernel;
 565
 566                        curr_map = map__new2(pos->start, dso, map->type);
 567                        if (curr_map == NULL) {
 568                                dso__delete(dso);
 569                                return -1;
 570                        }
 571
 572                        curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
 573                        map_groups__insert(kmaps, curr_map);
 574                        ++kernel_range;
 575                }
 576
 577                if (filter && filter(curr_map, pos)) {
 578discard_symbol:         rb_erase(&pos->rb_node, root);
 579                        symbol__delete(pos);
 580                } else {
 581                        if (curr_map != map) {
 582                                rb_erase(&pos->rb_node, root);
 583                                symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
 584                        }
 585                        count++;
 586                }
 587        }
 588
 589        if (curr_map != map &&
 590            self->kernel == DSO_TYPE_GUEST_KERNEL &&
 591            machine__is_default_guest(kmaps->machine)) {
 592                dso__set_loaded(curr_map->dso, curr_map->type);
 593        }
 594
 595        return count;
 596}
 597
 598int dso__load_kallsyms(struct dso *self, const char *filename,
 599                       struct map *map, symbol_filter_t filter)
 600{
 601        if (dso__load_all_kallsyms(self, filename, map) < 0)
 602                return -1;
 603
 604        symbols__fixup_end(&self->symbols[map->type]);
 605        if (self->kernel == DSO_TYPE_GUEST_KERNEL)
 606                self->origin = DSO__ORIG_GUEST_KERNEL;
 607        else
 608                self->origin = DSO__ORIG_KERNEL;
 609
 610        return dso__split_kallsyms(self, map, filter);
 611}
 612
 613static int dso__load_perf_map(struct dso *self, struct map *map,
 614                              symbol_filter_t filter)
 615{
 616        char *line = NULL;
 617        size_t n;
 618        FILE *file;
 619        int nr_syms = 0;
 620
 621        file = fopen(self->long_name, "r");
 622        if (file == NULL)
 623                goto out_failure;
 624
 625        while (!feof(file)) {
 626                u64 start, size;
 627                struct symbol *sym;
 628                int line_len, len;
 629
 630                line_len = getline(&line, &n, file);
 631                if (line_len < 0)
 632                        break;
 633
 634                if (!line)
 635                        goto out_failure;
 636
 637                line[--line_len] = '\0'; /* \n */
 638
 639                len = hex2u64(line, &start);
 640
 641                len++;
 642                if (len + 2 >= line_len)
 643                        continue;
 644
 645                len += hex2u64(line + len, &size);
 646
 647                len++;
 648                if (len + 2 >= line_len)
 649                        continue;
 650
 651                sym = symbol__new(start, size, line + len);
 652
 653                if (sym == NULL)
 654                        goto out_delete_line;
 655
 656                if (filter && filter(map, sym))
 657                        symbol__delete(sym);
 658                else {
 659                        symbols__insert(&self->symbols[map->type], sym);
 660                        nr_syms++;
 661                }
 662        }
 663
 664        free(line);
 665        fclose(file);
 666
 667        return nr_syms;
 668
 669out_delete_line:
 670        free(line);
 671out_failure:
 672        return -1;
 673}
 674
 675/**
 676 * elf_symtab__for_each_symbol - iterate thru all the symbols
 677 *
 678 * @self: struct elf_symtab instance to iterate
 679 * @idx: uint32_t idx
 680 * @sym: GElf_Sym iterator
 681 */
 682#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
 683        for (idx = 0, gelf_getsym(syms, idx, &sym);\
 684             idx < nr_syms; \
 685             idx++, gelf_getsym(syms, idx, &sym))
 686
 687static inline uint8_t elf_sym__type(const GElf_Sym *sym)
 688{
 689        return GELF_ST_TYPE(sym->st_info);
 690}
 691
 692static inline int elf_sym__is_function(const GElf_Sym *sym)
 693{
 694        return elf_sym__type(sym) == STT_FUNC &&
 695               sym->st_name != 0 &&
 696               sym->st_shndx != SHN_UNDEF;
 697}
 698
 699static inline bool elf_sym__is_object(const GElf_Sym *sym)
 700{
 701        return elf_sym__type(sym) == STT_OBJECT &&
 702                sym->st_name != 0 &&
 703                sym->st_shndx != SHN_UNDEF;
 704}
 705
 706static inline int elf_sym__is_label(const GElf_Sym *sym)
 707{
 708        return elf_sym__type(sym) == STT_NOTYPE &&
 709                sym->st_name != 0 &&
 710                sym->st_shndx != SHN_UNDEF &&
 711                sym->st_shndx != SHN_ABS;
 712}
 713
 714static inline const char *elf_sec__name(const GElf_Shdr *shdr,
 715                                        const Elf_Data *secstrs)
 716{
 717        return secstrs->d_buf + shdr->sh_name;
 718}
 719
 720static inline int elf_sec__is_text(const GElf_Shdr *shdr,
 721                                        const Elf_Data *secstrs)
 722{
 723        return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
 724}
 725
 726static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
 727                                    const Elf_Data *secstrs)
 728{
 729        return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
 730}
 731
 732static inline const char *elf_sym__name(const GElf_Sym *sym,
 733                                        const Elf_Data *symstrs)
 734{
 735        return symstrs->d_buf + sym->st_name;
 736}
 737
 738static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
 739                                    GElf_Shdr *shp, const char *name,
 740                                    size_t *idx)
 741{
 742        Elf_Scn *sec = NULL;
 743        size_t cnt = 1;
 744
 745        while ((sec = elf_nextscn(elf, sec)) != NULL) {
 746                char *str;
 747
 748                gelf_getshdr(sec, shp);
 749                str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
 750                if (!strcmp(name, str)) {
 751                        if (idx)
 752                                *idx = cnt;
 753                        break;
 754                }
 755                ++cnt;
 756        }
 757
 758        return sec;
 759}
 760
 761#define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
 762        for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
 763             idx < nr_entries; \
 764             ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
 765
 766#define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
 767        for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
 768             idx < nr_entries; \
 769             ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
 770
 771/*
 772 * We need to check if we have a .dynsym, so that we can handle the
 773 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
 774 * .dynsym or .symtab).
 775 * And always look at the original dso, not at debuginfo packages, that
 776 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
 777 */
 778static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
 779                                       symbol_filter_t filter)
 780{
 781        uint32_t nr_rel_entries, idx;
 782        GElf_Sym sym;
 783        u64 plt_offset;
 784        GElf_Shdr shdr_plt;
 785        struct symbol *f;
 786        GElf_Shdr shdr_rel_plt, shdr_dynsym;
 787        Elf_Data *reldata, *syms, *symstrs;
 788        Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
 789        size_t dynsym_idx;
 790        GElf_Ehdr ehdr;
 791        char sympltname[1024];
 792        Elf *elf;
 793        int nr = 0, symidx, fd, err = 0;
 794
 795        fd = open(self->long_name, O_RDONLY);
 796        if (fd < 0)
 797                goto out;
 798
 799        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 800        if (elf == NULL)
 801                goto out_close;
 802
 803        if (gelf_getehdr(elf, &ehdr) == NULL)
 804                goto out_elf_end;
 805
 806        scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
 807                                         ".dynsym", &dynsym_idx);
 808        if (scn_dynsym == NULL)
 809                goto out_elf_end;
 810
 811        scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
 812                                          ".rela.plt", NULL);
 813        if (scn_plt_rel == NULL) {
 814                scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
 815                                                  ".rel.plt", NULL);
 816                if (scn_plt_rel == NULL)
 817                        goto out_elf_end;
 818        }
 819
 820        err = -1;
 821
 822        if (shdr_rel_plt.sh_link != dynsym_idx)
 823                goto out_elf_end;
 824
 825        if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
 826                goto out_elf_end;
 827
 828        /*
 829         * Fetch the relocation section to find the idxes to the GOT
 830         * and the symbols in the .dynsym they refer to.
 831         */
 832        reldata = elf_getdata(scn_plt_rel, NULL);
 833        if (reldata == NULL)
 834                goto out_elf_end;
 835
 836        syms = elf_getdata(scn_dynsym, NULL);
 837        if (syms == NULL)
 838                goto out_elf_end;
 839
 840        scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
 841        if (scn_symstrs == NULL)
 842                goto out_elf_end;
 843
 844        symstrs = elf_getdata(scn_symstrs, NULL);
 845        if (symstrs == NULL)
 846                goto out_elf_end;
 847
 848        nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
 849        plt_offset = shdr_plt.sh_offset;
 850
 851        if (shdr_rel_plt.sh_type == SHT_RELA) {
 852                GElf_Rela pos_mem, *pos;
 853
 854                elf_section__for_each_rela(reldata, pos, pos_mem, idx,
 855                                           nr_rel_entries) {
 856                        symidx = GELF_R_SYM(pos->r_info);
 857                        plt_offset += shdr_plt.sh_entsize;
 858                        gelf_getsym(syms, symidx, &sym);
 859                        snprintf(sympltname, sizeof(sympltname),
 860                                 "%s@plt", elf_sym__name(&sym, symstrs));
 861
 862                        f = symbol__new(plt_offset, shdr_plt.sh_entsize,
 863                                        sympltname);
 864                        if (!f)
 865                                goto out_elf_end;
 866
 867                        if (filter && filter(map, f))
 868                                symbol__delete(f);
 869                        else {
 870                                symbols__insert(&self->symbols[map->type], f);
 871                                ++nr;
 872                        }
 873                }
 874        } else if (shdr_rel_plt.sh_type == SHT_REL) {
 875                GElf_Rel pos_mem, *pos;
 876                elf_section__for_each_rel(reldata, pos, pos_mem, idx,
 877                                          nr_rel_entries) {
 878                        symidx = GELF_R_SYM(pos->r_info);
 879                        plt_offset += shdr_plt.sh_entsize;
 880                        gelf_getsym(syms, symidx, &sym);
 881                        snprintf(sympltname, sizeof(sympltname),
 882                                 "%s@plt", elf_sym__name(&sym, symstrs));
 883
 884                        f = symbol__new(plt_offset, shdr_plt.sh_entsize,
 885                                        sympltname);
 886                        if (!f)
 887                                goto out_elf_end;
 888
 889                        if (filter && filter(map, f))
 890                                symbol__delete(f);
 891                        else {
 892                                symbols__insert(&self->symbols[map->type], f);
 893                                ++nr;
 894                        }
 895                }
 896        }
 897
 898        err = 0;
 899out_elf_end:
 900        elf_end(elf);
 901out_close:
 902        close(fd);
 903
 904        if (err == 0)
 905                return nr;
 906out:
 907        pr_debug("%s: problems reading %s PLT info.\n",
 908                 __func__, self->long_name);
 909        return 0;
 910}
 911
 912static bool elf_sym__is_a(GElf_Sym *self, enum map_type type)
 913{
 914        switch (type) {
 915        case MAP__FUNCTION:
 916                return elf_sym__is_function(self);
 917        case MAP__VARIABLE:
 918                return elf_sym__is_object(self);
 919        default:
 920                return false;
 921        }
 922}
 923
 924static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type)
 925{
 926        switch (type) {
 927        case MAP__FUNCTION:
 928                return elf_sec__is_text(self, secstrs);
 929        case MAP__VARIABLE:
 930                return elf_sec__is_data(self, secstrs);
 931        default:
 932                return false;
 933        }
 934}
 935
 936static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 937                         int fd, symbol_filter_t filter, int kmodule)
 938{
 939        struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
 940        struct map *curr_map = map;
 941        struct dso *curr_dso = self;
 942        Elf_Data *symstrs, *secstrs;
 943        uint32_t nr_syms;
 944        int err = -1;
 945        uint32_t idx;
 946        GElf_Ehdr ehdr;
 947        GElf_Shdr shdr;
 948        Elf_Data *syms;
 949        GElf_Sym sym;
 950        Elf_Scn *sec, *sec_strndx;
 951        Elf *elf;
 952        int nr = 0;
 953
 954        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 955        if (elf == NULL) {
 956                pr_err("%s: cannot read %s ELF file.\n", __func__, name);
 957                goto out_close;
 958        }
 959
 960        if (gelf_getehdr(elf, &ehdr) == NULL) {
 961                pr_err("%s: cannot get elf header.\n", __func__);
 962                goto out_elf_end;
 963        }
 964
 965        sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
 966        if (sec == NULL) {
 967                sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
 968                if (sec == NULL)
 969                        goto out_elf_end;
 970        }
 971
 972        syms = elf_getdata(sec, NULL);
 973        if (syms == NULL)
 974                goto out_elf_end;
 975
 976        sec = elf_getscn(elf, shdr.sh_link);
 977        if (sec == NULL)
 978                goto out_elf_end;
 979
 980        symstrs = elf_getdata(sec, NULL);
 981        if (symstrs == NULL)
 982                goto out_elf_end;
 983
 984        sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
 985        if (sec_strndx == NULL)
 986                goto out_elf_end;
 987
 988        secstrs = elf_getdata(sec_strndx, NULL);
 989        if (secstrs == NULL)
 990                goto out_elf_end;
 991
 992        nr_syms = shdr.sh_size / shdr.sh_entsize;
 993
 994        memset(&sym, 0, sizeof(sym));
 995        if (self->kernel == DSO_TYPE_USER) {
 996                self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
 997                                elf_section_by_name(elf, &ehdr, &shdr,
 998                                                     ".gnu.prelink_undo",
 999                                                     NULL) != NULL);
1000        } else self->adjust_symbols = 0;
1001
1002        elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1003                struct symbol *f;
1004                const char *elf_name = elf_sym__name(&sym, symstrs);
1005                char *demangled = NULL;
1006                int is_label = elf_sym__is_label(&sym);
1007                const char *section_name;
1008
1009                if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
1010                    strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
1011                        kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
1012
1013                if (!is_label && !elf_sym__is_a(&sym, map->type))
1014                        continue;
1015
1016                sec = elf_getscn(elf, sym.st_shndx);
1017                if (!sec)
1018                        goto out_elf_end;
1019
1020                gelf_getshdr(sec, &shdr);
1021
1022                if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
1023                        continue;
1024
1025                section_name = elf_sec__name(&shdr, secstrs);
1026
1027                if (self->kernel != DSO_TYPE_USER || kmodule) {
1028                        char dso_name[PATH_MAX];
1029
1030                        if (strcmp(section_name,
1031                                   (curr_dso->short_name +
1032                                    self->short_name_len)) == 0)
1033                                goto new_symbol;
1034
1035                        if (strcmp(section_name, ".text") == 0) {
1036                                curr_map = map;
1037                                curr_dso = self;
1038                                goto new_symbol;
1039                        }
1040
1041                        snprintf(dso_name, sizeof(dso_name),
1042                                 "%s%s", self->short_name, section_name);
1043
1044                        curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1045                        if (curr_map == NULL) {
1046                                u64 start = sym.st_value;
1047
1048                                if (kmodule)
1049                                        start += map->start + shdr.sh_offset;
1050
1051                                curr_dso = dso__new(dso_name);
1052                                if (curr_dso == NULL)
1053                                        goto out_elf_end;
1054                                curr_dso->kernel = self->kernel;
1055                                curr_map = map__new2(start, curr_dso,
1056                                                     map->type);
1057                                if (curr_map == NULL) {
1058                                        dso__delete(curr_dso);
1059                                        goto out_elf_end;
1060                                }
1061                                curr_map->map_ip = identity__map_ip;
1062                                curr_map->unmap_ip = identity__map_ip;
1063                                curr_dso->origin = self->origin;
1064                                map_groups__insert(kmap->kmaps, curr_map);
1065                                dsos__add(&self->node, curr_dso);
1066                                dso__set_loaded(curr_dso, map->type);
1067                        } else
1068                                curr_dso = curr_map->dso;
1069
1070                        goto new_symbol;
1071                }
1072
1073                if (curr_dso->adjust_symbols) {
1074                        pr_debug4("%s: adjusting symbol: st_value: %#Lx "
1075                                  "sh_addr: %#Lx sh_offset: %#Lx\n", __func__,
1076                                  (u64)sym.st_value, (u64)shdr.sh_addr,
1077                                  (u64)shdr.sh_offset);
1078                        sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1079                }
1080                /*
1081                 * We need to figure out if the object was created from C++ sources
1082                 * DWARF DW_compile_unit has this, but we don't always have access
1083                 * to it...
1084                 */
1085                demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
1086                if (demangled != NULL)
1087                        elf_name = demangled;
1088new_symbol:
1089                f = symbol__new(sym.st_value, sym.st_size, elf_name);
1090                free(demangled);
1091                if (!f)
1092                        goto out_elf_end;
1093
1094                if (filter && filter(curr_map, f))
1095                        symbol__delete(f);
1096                else {
1097                        symbols__insert(&curr_dso->symbols[curr_map->type], f);
1098                        nr++;
1099                }
1100        }
1101
1102        /*
1103         * For misannotated, zeroed, ASM function sizes.
1104         */
1105        if (nr > 0) {
1106                symbols__fixup_end(&self->symbols[map->type]);
1107                if (kmap) {
1108                        /*
1109                         * We need to fixup this here too because we create new
1110                         * maps here, for things like vsyscall sections.
1111                         */
1112                        __map_groups__fixup_end(kmap->kmaps, map->type);
1113                }
1114        }
1115        err = nr;
1116out_elf_end:
1117        elf_end(elf);
1118out_close:
1119        return err;
1120}
1121
1122static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
1123{
1124        return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
1125}
1126
1127bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1128{
1129        bool have_build_id = false;
1130        struct dso *pos;
1131
1132        list_for_each_entry(pos, head, node) {
1133                if (with_hits && !pos->hit)
1134                        continue;
1135                if (pos->has_build_id) {
1136                        have_build_id = true;
1137                        continue;
1138                }
1139                if (filename__read_build_id(pos->long_name, pos->build_id,
1140                                            sizeof(pos->build_id)) > 0) {
1141                        have_build_id     = true;
1142                        pos->has_build_id = true;
1143                }
1144        }
1145
1146        return have_build_id;
1147}
1148
1149/*
1150 * Align offset to 4 bytes as needed for note name and descriptor data.
1151 */
1152#define NOTE_ALIGN(n) (((n) + 3) & -4U)
1153
1154int filename__read_build_id(const char *filename, void *bf, size_t size)
1155{
1156        int fd, err = -1;
1157        GElf_Ehdr ehdr;
1158        GElf_Shdr shdr;
1159        Elf_Data *data;
1160        Elf_Scn *sec;
1161        Elf_Kind ek;
1162        void *ptr;
1163        Elf *elf;
1164
1165        if (size < BUILD_ID_SIZE)
1166                goto out;
1167
1168        fd = open(filename, O_RDONLY);
1169        if (fd < 0)
1170                goto out;
1171
1172        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1173        if (elf == NULL) {
1174                pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1175                goto out_close;
1176        }
1177
1178        ek = elf_kind(elf);
1179        if (ek != ELF_K_ELF)
1180                goto out_elf_end;
1181
1182        if (gelf_getehdr(elf, &ehdr) == NULL) {
1183                pr_err("%s: cannot get elf header.\n", __func__);
1184                goto out_elf_end;
1185        }
1186
1187        sec = elf_section_by_name(elf, &ehdr, &shdr,
1188                                  ".note.gnu.build-id", NULL);
1189        if (sec == NULL) {
1190                sec = elf_section_by_name(elf, &ehdr, &shdr,
1191                                          ".notes", NULL);
1192                if (sec == NULL)
1193                        goto out_elf_end;
1194        }
1195
1196        data = elf_getdata(sec, NULL);
1197        if (data == NULL)
1198                goto out_elf_end;
1199
1200        ptr = data->d_buf;
1201        while (ptr < (data->d_buf + data->d_size)) {
1202                GElf_Nhdr *nhdr = ptr;
1203                int namesz = NOTE_ALIGN(nhdr->n_namesz),
1204                    descsz = NOTE_ALIGN(nhdr->n_descsz);
1205                const char *name;
1206
1207                ptr += sizeof(*nhdr);
1208                name = ptr;
1209                ptr += namesz;
1210                if (nhdr->n_type == NT_GNU_BUILD_ID &&
1211                    nhdr->n_namesz == sizeof("GNU")) {
1212                        if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1213                                memcpy(bf, ptr, BUILD_ID_SIZE);
1214                                err = BUILD_ID_SIZE;
1215                                break;
1216                        }
1217                }
1218                ptr += descsz;
1219        }
1220out_elf_end:
1221        elf_end(elf);
1222out_close:
1223        close(fd);
1224out:
1225        return err;
1226}
1227
1228int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1229{
1230        int fd, err = -1;
1231
1232        if (size < BUILD_ID_SIZE)
1233                goto out;
1234
1235        fd = open(filename, O_RDONLY);
1236        if (fd < 0)
1237                goto out;
1238
1239        while (1) {
1240                char bf[BUFSIZ];
1241                GElf_Nhdr nhdr;
1242                int namesz, descsz;
1243
1244                if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1245                        break;
1246
1247                namesz = NOTE_ALIGN(nhdr.n_namesz);
1248                descsz = NOTE_ALIGN(nhdr.n_descsz);
1249                if (nhdr.n_type == NT_GNU_BUILD_ID &&
1250                    nhdr.n_namesz == sizeof("GNU")) {
1251                        if (read(fd, bf, namesz) != namesz)
1252                                break;
1253                        if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1254                                if (read(fd, build_id,
1255                                    BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1256                                        err = 0;
1257                                        break;
1258                                }
1259                        } else if (read(fd, bf, descsz) != descsz)
1260                                break;
1261                } else {
1262                        int n = namesz + descsz;
1263                        if (read(fd, bf, n) != n)
1264                                break;
1265                }
1266        }
1267        close(fd);
1268out:
1269        return err;
1270}
1271
1272char dso__symtab_origin(const struct dso *self)
1273{
1274        static const char origin[] = {
1275                [DSO__ORIG_KERNEL] =   'k',
1276                [DSO__ORIG_JAVA_JIT] = 'j',
1277                [DSO__ORIG_BUILD_ID_CACHE] = 'B',
1278                [DSO__ORIG_FEDORA] =   'f',
1279                [DSO__ORIG_UBUNTU] =   'u',
1280                [DSO__ORIG_BUILDID] =  'b',
1281                [DSO__ORIG_DSO] =      'd',
1282                [DSO__ORIG_KMODULE] =  'K',
1283                [DSO__ORIG_GUEST_KERNEL] =  'g',
1284                [DSO__ORIG_GUEST_KMODULE] =  'G',
1285        };
1286
1287        if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
1288                return '!';
1289        return origin[self->origin];
1290}
1291
1292int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1293{
1294        int size = PATH_MAX;
1295        char *name;
1296        u8 build_id[BUILD_ID_SIZE];
1297        int ret = -1;
1298        int fd;
1299        struct machine *machine;
1300        const char *root_dir;
1301
1302        dso__set_loaded(self, map->type);
1303
1304        if (self->kernel == DSO_TYPE_KERNEL)
1305                return dso__load_kernel_sym(self, map, filter);
1306        else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
1307                return dso__load_guest_kernel_sym(self, map, filter);
1308
1309        if (map->groups && map->groups->machine)
1310                machine = map->groups->machine;
1311        else
1312                machine = NULL;
1313
1314        name = malloc(size);
1315        if (!name)
1316                return -1;
1317
1318        self->adjust_symbols = 0;
1319
1320        if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1321                ret = dso__load_perf_map(self, map, filter);
1322                self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
1323                                         DSO__ORIG_NOT_FOUND;
1324                return ret;
1325        }
1326
1327        self->origin = DSO__ORIG_BUILD_ID_CACHE;
1328        if (dso__build_id_filename(self, name, size) != NULL)
1329                goto open_file;
1330more:
1331        do {
1332                self->origin++;
1333                switch (self->origin) {
1334                case DSO__ORIG_FEDORA:
1335                        snprintf(name, size, "/usr/lib/debug%s.debug",
1336                                 self->long_name);
1337                        break;
1338                case DSO__ORIG_UBUNTU:
1339                        snprintf(name, size, "/usr/lib/debug%s",
1340                                 self->long_name);
1341                        break;
1342                case DSO__ORIG_BUILDID:
1343                        if (filename__read_build_id(self->long_name, build_id,
1344                                                    sizeof(build_id))) {
1345                                char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1346                                build_id__sprintf(build_id, sizeof(build_id),
1347                                                  build_id_hex);
1348                                snprintf(name, size,
1349                                         "/usr/lib/debug/.build-id/%.2s/%s.debug",
1350                                        build_id_hex, build_id_hex + 2);
1351                                if (self->has_build_id)
1352                                        goto compare_build_id;
1353                                break;
1354                        }
1355                        self->origin++;
1356                        /* Fall thru */
1357                case DSO__ORIG_DSO:
1358                        snprintf(name, size, "%s", self->long_name);
1359                        break;
1360                case DSO__ORIG_GUEST_KMODULE:
1361                        if (map->groups && map->groups->machine)
1362                                root_dir = map->groups->machine->root_dir;
1363                        else
1364                                root_dir = "";
1365                        snprintf(name, size, "%s%s", root_dir, self->long_name);
1366                        break;
1367
1368                default:
1369                        goto out;
1370                }
1371
1372                if (self->has_build_id) {
1373                        if (filename__read_build_id(name, build_id,
1374                                                    sizeof(build_id)) < 0)
1375                                goto more;
1376compare_build_id:
1377                        if (!dso__build_id_equal(self, build_id))
1378                                goto more;
1379                }
1380open_file:
1381                fd = open(name, O_RDONLY);
1382        } while (fd < 0);
1383
1384        ret = dso__load_sym(self, map, name, fd, filter, 0);
1385        close(fd);
1386
1387        /*
1388         * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
1389         */
1390        if (!ret)
1391                goto more;
1392
1393        if (ret > 0) {
1394                int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1395                if (nr_plt > 0)
1396                        ret += nr_plt;
1397        }
1398out:
1399        free(name);
1400        if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1401                return 0;
1402        return ret;
1403}
1404
1405struct map *map_groups__find_by_name(struct map_groups *self,
1406                                     enum map_type type, const char *name)
1407{
1408        struct rb_node *nd;
1409
1410        for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
1411                struct map *map = rb_entry(nd, struct map, rb_node);
1412
1413                if (map->dso && strcmp(map->dso->short_name, name) == 0)
1414                        return map;
1415        }
1416
1417        return NULL;
1418}
1419
1420static int dso__kernel_module_get_build_id(struct dso *self,
1421                                const char *root_dir)
1422{
1423        char filename[PATH_MAX];
1424        /*
1425         * kernel module short names are of the form "[module]" and
1426         * we need just "module" here.
1427         */
1428        const char *name = self->short_name + 1;
1429
1430        snprintf(filename, sizeof(filename),
1431                 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1432                 root_dir, (int)strlen(name) - 1, name);
1433
1434        if (sysfs__read_build_id(filename, self->build_id,
1435                                 sizeof(self->build_id)) == 0)
1436                self->has_build_id = true;
1437
1438        return 0;
1439}
1440
1441static int map_groups__set_modules_path_dir(struct map_groups *self,
1442                                const char *dir_name)
1443{
1444        struct dirent *dent;
1445        DIR *dir = opendir(dir_name);
1446        int ret = 0;
1447
1448        if (!dir) {
1449                pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
1450                return -1;
1451        }
1452
1453        while ((dent = readdir(dir)) != NULL) {
1454                char path[PATH_MAX];
1455                struct stat st;
1456
1457                /*sshfs might return bad dent->d_type, so we have to stat*/
1458                sprintf(path, "%s/%s", dir_name, dent->d_name);
1459                if (stat(path, &st))
1460                        continue;
1461
1462                if (S_ISDIR(st.st_mode)) {
1463                        if (!strcmp(dent->d_name, ".") ||
1464                            !strcmp(dent->d_name, ".."))
1465                                continue;
1466
1467                        snprintf(path, sizeof(path), "%s/%s",
1468                                 dir_name, dent->d_name);
1469                        ret = map_groups__set_modules_path_dir(self, path);
1470                        if (ret < 0)
1471                                goto out;
1472                } else {
1473                        char *dot = strrchr(dent->d_name, '.'),
1474                             dso_name[PATH_MAX];
1475                        struct map *map;
1476                        char *long_name;
1477
1478                        if (dot == NULL || strcmp(dot, ".ko"))
1479                                continue;
1480                        snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1481                                 (int)(dot - dent->d_name), dent->d_name);
1482
1483                        strxfrchar(dso_name, '-', '_');
1484                        map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name);
1485                        if (map == NULL)
1486                                continue;
1487
1488                        snprintf(path, sizeof(path), "%s/%s",
1489                                 dir_name, dent->d_name);
1490
1491                        long_name = strdup(path);
1492                        if (long_name == NULL) {
1493                                ret = -1;
1494                                goto out;
1495                        }
1496                        dso__set_long_name(map->dso, long_name);
1497                        dso__kernel_module_get_build_id(map->dso, "");
1498                }
1499        }
1500
1501out:
1502        closedir(dir);
1503        return ret;
1504}
1505
1506static char *get_kernel_version(const char *root_dir)
1507{
1508        char version[PATH_MAX];
1509        FILE *file;
1510        char *name, *tmp;
1511        const char *prefix = "Linux version ";
1512
1513        sprintf(version, "%s/proc/version", root_dir);
1514        file = fopen(version, "r");
1515        if (!file)
1516                return NULL;
1517
1518        version[0] = '\0';
1519        tmp = fgets(version, sizeof(version), file);
1520        fclose(file);
1521
1522        name = strstr(version, prefix);
1523        if (!name)
1524                return NULL;
1525        name += strlen(prefix);
1526        tmp = strchr(name, ' ');
1527        if (tmp)
1528                *tmp = '\0';
1529
1530        return strdup(name);
1531}
1532
1533static int machine__set_modules_path(struct machine *self)
1534{
1535        char *version;
1536        char modules_path[PATH_MAX];
1537
1538        version = get_kernel_version(self->root_dir);
1539        if (!version)
1540                return -1;
1541
1542        snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1543                 self->root_dir, version);
1544        free(version);
1545
1546        return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
1547}
1548
1549/*
1550 * Constructor variant for modules (where we know from /proc/modules where
1551 * they are loaded) and for vmlinux, where only after we load all the
1552 * symbols we'll know where it starts and ends.
1553 */
1554static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1555{
1556        struct map *self = calloc(1, (sizeof(*self) +
1557                                      (dso->kernel ? sizeof(struct kmap) : 0)));
1558        if (self != NULL) {
1559                /*
1560                 * ->end will be filled after we load all the symbols
1561                 */
1562                map__init(self, type, start, 0, 0, dso);
1563        }
1564
1565        return self;
1566}
1567
1568struct map *machine__new_module(struct machine *self, u64 start,
1569                                const char *filename)
1570{
1571        struct map *map;
1572        struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
1573
1574        if (dso == NULL)
1575                return NULL;
1576
1577        map = map__new2(start, dso, MAP__FUNCTION);
1578        if (map == NULL)
1579                return NULL;
1580
1581        if (machine__is_host(self))
1582                dso->origin = DSO__ORIG_KMODULE;
1583        else
1584                dso->origin = DSO__ORIG_GUEST_KMODULE;
1585        map_groups__insert(&self->kmaps, map);
1586        return map;
1587}
1588
1589static int machine__create_modules(struct machine *self)
1590{
1591        char *line = NULL;
1592        size_t n;
1593        FILE *file;
1594        struct map *map;
1595        const char *modules;
1596        char path[PATH_MAX];
1597
1598        if (machine__is_default_guest(self))
1599                modules = symbol_conf.default_guest_modules;
1600        else {
1601                sprintf(path, "%s/proc/modules", self->root_dir);
1602                modules = path;
1603        }
1604
1605        file = fopen(modules, "r");
1606        if (file == NULL)
1607                return -1;
1608
1609        while (!feof(file)) {
1610                char name[PATH_MAX];
1611                u64 start;
1612                char *sep;
1613                int line_len;
1614
1615                line_len = getline(&line, &n, file);
1616                if (line_len < 0)
1617                        break;
1618
1619                if (!line)
1620                        goto out_failure;
1621
1622                line[--line_len] = '\0'; /* \n */
1623
1624                sep = strrchr(line, 'x');
1625                if (sep == NULL)
1626                        continue;
1627
1628                hex2u64(sep + 1, &start);
1629
1630                sep = strchr(line, ' ');
1631                if (sep == NULL)
1632                        continue;
1633
1634                *sep = '\0';
1635
1636                snprintf(name, sizeof(name), "[%s]", line);
1637                map = machine__new_module(self, start, name);
1638                if (map == NULL)
1639                        goto out_delete_line;
1640                dso__kernel_module_get_build_id(map->dso, self->root_dir);
1641        }
1642
1643        free(line);
1644        fclose(file);
1645
1646        return machine__set_modules_path(self);
1647
1648out_delete_line:
1649        free(line);
1650out_failure:
1651        return -1;
1652}
1653
1654static int dso__load_vmlinux(struct dso *self, struct map *map,
1655                             const char *vmlinux, symbol_filter_t filter)
1656{
1657        int err = -1, fd;
1658
1659        if (self->has_build_id) {
1660                u8 build_id[BUILD_ID_SIZE];
1661
1662                if (filename__read_build_id(vmlinux, build_id,
1663                                            sizeof(build_id)) < 0) {
1664                        pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1665                        return -1;
1666                }
1667                if (!dso__build_id_equal(self, build_id)) {
1668                        char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1669                             vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1670
1671                        build_id__sprintf(self->build_id,
1672                                          sizeof(self->build_id),
1673                                          expected_build_id);
1674                        build_id__sprintf(build_id, sizeof(build_id),
1675                                          vmlinux_build_id);
1676                        pr_debug("build_id in %s is %s while expected is %s, "
1677                                 "ignoring it\n", vmlinux, vmlinux_build_id,
1678                                 expected_build_id);
1679                        return -1;
1680                }
1681        }
1682
1683        fd = open(vmlinux, O_RDONLY);
1684        if (fd < 0)
1685                return -1;
1686
1687        dso__set_loaded(self, map->type);
1688        err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
1689        close(fd);
1690
1691        if (err > 0)
1692                pr_debug("Using %s for symbols\n", vmlinux);
1693
1694        return err;
1695}
1696
1697int dso__load_vmlinux_path(struct dso *self, struct map *map,
1698                           symbol_filter_t filter)
1699{
1700        int i, err = 0;
1701        char *filename;
1702
1703        pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1704                 vmlinux_path__nr_entries + 1);
1705
1706        filename = dso__build_id_filename(self, NULL, 0);
1707        if (filename != NULL) {
1708                err = dso__load_vmlinux(self, map, filename, filter);
1709                if (err > 0) {
1710                        dso__set_long_name(self, filename);
1711                        goto out;
1712                }
1713                free(filename);
1714        }
1715
1716        for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1717                err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
1718                if (err > 0) {
1719                        dso__set_long_name(self, strdup(vmlinux_path[i]));
1720                        break;
1721                }
1722        }
1723out:
1724        return err;
1725}
1726
1727static int dso__load_kernel_sym(struct dso *self, struct map *map,
1728                                symbol_filter_t filter)
1729{
1730        int err;
1731        const char *kallsyms_filename = NULL;
1732        char *kallsyms_allocated_filename = NULL;
1733        /*
1734         * Step 1: if the user specified a vmlinux filename, use it and only
1735         * it, reporting errors to the user if it cannot be used.
1736         *
1737         * For instance, try to analyse an ARM perf.data file _without_ a
1738         * build-id, or if the user specifies the wrong path to the right
1739         * vmlinux file, obviously we can't fallback to another vmlinux (a
1740         * x86_86 one, on the machine where analysis is being performed, say),
1741         * or worse, /proc/kallsyms.
1742         *
1743         * If the specified file _has_ a build-id and there is a build-id
1744         * section in the perf.data file, we will still do the expected
1745         * validation in dso__load_vmlinux and will bail out if they don't
1746         * match.
1747         */
1748        if (symbol_conf.vmlinux_name != NULL) {
1749                err = dso__load_vmlinux(self, map,
1750                                        symbol_conf.vmlinux_name, filter);
1751                if (err > 0) {
1752                        dso__set_long_name(self,
1753                                           strdup(symbol_conf.vmlinux_name));
1754                        goto out_fixup;
1755                }
1756                return err;
1757        }
1758
1759        if (vmlinux_path != NULL) {
1760                err = dso__load_vmlinux_path(self, map, filter);
1761                if (err > 0)
1762                        goto out_fixup;
1763        }
1764
1765        /*
1766         * Say the kernel DSO was created when processing the build-id header table,
1767         * we have a build-id, so check if it is the same as the running kernel,
1768         * using it if it is.
1769         */
1770        if (self->has_build_id) {
1771                u8 kallsyms_build_id[BUILD_ID_SIZE];
1772                char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1773
1774                if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1775                                         sizeof(kallsyms_build_id)) == 0) {
1776                        if (dso__build_id_equal(self, kallsyms_build_id)) {
1777                                kallsyms_filename = "/proc/kallsyms";
1778                                goto do_kallsyms;
1779                        }
1780                }
1781                /*
1782                 * Now look if we have it on the build-id cache in
1783                 * $HOME/.debug/[kernel.kallsyms].
1784                 */
1785                build_id__sprintf(self->build_id, sizeof(self->build_id),
1786                                  sbuild_id);
1787
1788                if (asprintf(&kallsyms_allocated_filename,
1789                             "%s/.debug/[kernel.kallsyms]/%s",
1790                             getenv("HOME"), sbuild_id) == -1) {
1791                        pr_err("Not enough memory for kallsyms file lookup\n");
1792                        return -1;
1793                }
1794
1795                kallsyms_filename = kallsyms_allocated_filename;
1796
1797                if (access(kallsyms_filename, F_OK)) {
1798                        pr_err("No kallsyms or vmlinux with build-id %s "
1799                               "was found\n", sbuild_id);
1800                        free(kallsyms_allocated_filename);
1801                        return -1;
1802                }
1803        } else {
1804                /*
1805                 * Last resort, if we don't have a build-id and couldn't find
1806                 * any vmlinux file, try the running kernel kallsyms table.
1807                 */
1808                kallsyms_filename = "/proc/kallsyms";
1809        }
1810
1811do_kallsyms:
1812        err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1813        if (err > 0)
1814                pr_debug("Using %s for symbols\n", kallsyms_filename);
1815        free(kallsyms_allocated_filename);
1816
1817        if (err > 0) {
1818out_fixup:
1819                if (kallsyms_filename != NULL)
1820                        dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1821                map__fixup_start(map);
1822                map__fixup_end(map);
1823        }
1824
1825        return err;
1826}
1827
1828static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
1829                                symbol_filter_t filter)
1830{
1831        int err;
1832        const char *kallsyms_filename = NULL;
1833        struct machine *machine;
1834        char path[PATH_MAX];
1835
1836        if (!map->groups) {
1837                pr_debug("Guest kernel map hasn't the point to groups\n");
1838                return -1;
1839        }
1840        machine = map->groups->machine;
1841
1842        if (machine__is_default_guest(machine)) {
1843                /*
1844                 * if the user specified a vmlinux filename, use it and only
1845                 * it, reporting errors to the user if it cannot be used.
1846                 * Or use file guest_kallsyms inputted by user on commandline
1847                 */
1848                if (symbol_conf.default_guest_vmlinux_name != NULL) {
1849                        err = dso__load_vmlinux(self, map,
1850                                symbol_conf.default_guest_vmlinux_name, filter);
1851                        goto out_try_fixup;
1852                }
1853
1854                kallsyms_filename = symbol_conf.default_guest_kallsyms;
1855                if (!kallsyms_filename)
1856                        return -1;
1857        } else {
1858                sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1859                kallsyms_filename = path;
1860        }
1861
1862        err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1863        if (err > 0)
1864                pr_debug("Using %s for symbols\n", kallsyms_filename);
1865
1866out_try_fixup:
1867        if (err > 0) {
1868                if (kallsyms_filename != NULL) {
1869                        machine__mmap_name(machine, path, sizeof(path));
1870                        dso__set_long_name(self, strdup(path));
1871                }
1872                map__fixup_start(map);
1873                map__fixup_end(map);
1874        }
1875
1876        return err;
1877}
1878
1879static void dsos__add(struct list_head *head, struct dso *dso)
1880{
1881        list_add_tail(&dso->node, head);
1882}
1883
1884static struct dso *dsos__find(struct list_head *head, const char *name)
1885{
1886        struct dso *pos;
1887
1888        list_for_each_entry(pos, head, node)
1889                if (strcmp(pos->long_name, name) == 0)
1890                        return pos;
1891        return NULL;
1892}
1893
1894struct dso *__dsos__findnew(struct list_head *head, const char *name)
1895{
1896        struct dso *dso = dsos__find(head, name);
1897
1898        if (!dso) {
1899                dso = dso__new(name);
1900                if (dso != NULL) {
1901                        dsos__add(head, dso);
1902                        dso__set_basename(dso);
1903                }
1904        }
1905
1906        return dso;
1907}
1908
1909size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1910{
1911        struct dso *pos;
1912        size_t ret = 0;
1913
1914        list_for_each_entry(pos, head, node) {
1915                int i;
1916                for (i = 0; i < MAP__NR_TYPES; ++i)
1917                        ret += dso__fprintf(pos, i, fp);
1918        }
1919
1920        return ret;
1921}
1922
1923size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
1924{
1925        struct rb_node *nd;
1926        size_t ret = 0;
1927
1928        for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1929                struct machine *pos = rb_entry(nd, struct machine, rb_node);
1930                ret += __dsos__fprintf(&pos->kernel_dsos, fp);
1931                ret += __dsos__fprintf(&pos->user_dsos, fp);
1932        }
1933
1934        return ret;
1935}
1936
1937static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1938                                      bool with_hits)
1939{
1940        struct dso *pos;
1941        size_t ret = 0;
1942
1943        list_for_each_entry(pos, head, node) {
1944                if (with_hits && !pos->hit)
1945                        continue;
1946                ret += dso__fprintf_buildid(pos, fp);
1947                ret += fprintf(fp, " %s\n", pos->long_name);
1948        }
1949        return ret;
1950}
1951
1952size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits)
1953{
1954        return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) +
1955               __dsos__fprintf_buildid(&self->user_dsos, fp, with_hits);
1956}
1957
1958size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
1959{
1960        struct rb_node *nd;
1961        size_t ret = 0;
1962
1963        for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1964                struct machine *pos = rb_entry(nd, struct machine, rb_node);
1965                ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
1966        }
1967        return ret;
1968}
1969
1970struct dso *dso__new_kernel(const char *name)
1971{
1972        struct dso *self = dso__new(name ?: "[kernel.kallsyms]");
1973
1974        if (self != NULL) {
1975                dso__set_short_name(self, "[kernel]");
1976                self->kernel = DSO_TYPE_KERNEL;
1977        }
1978
1979        return self;
1980}
1981
1982static struct dso *dso__new_guest_kernel(struct machine *machine,
1983                                        const char *name)
1984{
1985        char bf[PATH_MAX];
1986        struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
1987
1988        if (self != NULL) {
1989                dso__set_short_name(self, "[guest.kernel]");
1990                self->kernel = DSO_TYPE_GUEST_KERNEL;
1991        }
1992
1993        return self;
1994}
1995
1996void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
1997{
1998        char path[PATH_MAX];
1999
2000        if (machine__is_default_guest(machine))
2001                return;
2002        sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
2003        if (sysfs__read_build_id(path, self->build_id,
2004                                 sizeof(self->build_id)) == 0)
2005                self->has_build_id = true;
2006}
2007
2008static struct dso *machine__create_kernel(struct machine *self)
2009{
2010        const char *vmlinux_name = NULL;
2011        struct dso *kernel;
2012
2013        if (machine__is_host(self)) {
2014                vmlinux_name = symbol_conf.vmlinux_name;
2015                kernel = dso__new_kernel(vmlinux_name);
2016        } else {
2017                if (machine__is_default_guest(self))
2018                        vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2019                kernel = dso__new_guest_kernel(self, vmlinux_name);
2020        }
2021
2022        if (kernel != NULL) {
2023                dso__read_running_kernel_build_id(kernel, self);
2024                dsos__add(&self->kernel_dsos, kernel);
2025        }
2026        return kernel;
2027}
2028
2029int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2030{
2031        enum map_type type;
2032
2033        for (type = 0; type < MAP__NR_TYPES; ++type) {
2034                struct kmap *kmap;
2035
2036                self->vmlinux_maps[type] = map__new2(0, kernel, type);
2037                if (self->vmlinux_maps[type] == NULL)
2038                        return -1;
2039
2040                self->vmlinux_maps[type]->map_ip =
2041                        self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
2042
2043                kmap = map__kmap(self->vmlinux_maps[type]);
2044                kmap->kmaps = &self->kmaps;
2045                map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
2046        }
2047
2048        return 0;
2049}
2050
2051int machine__create_kernel_maps(struct machine *self)
2052{
2053        struct dso *kernel = machine__create_kernel(self);
2054
2055        if (kernel == NULL ||
2056            __machine__create_kernel_maps(self, kernel) < 0)
2057                return -1;
2058
2059        if (symbol_conf.use_modules && machine__create_modules(self) < 0)
2060                pr_debug("Problems creating module maps, continuing anyway...\n");
2061        /*
2062         * Now that we have all the maps created, just set the ->end of them:
2063         */
2064        map_groups__fixup_end(&self->kmaps);
2065        return 0;
2066}
2067
2068static void vmlinux_path__exit(void)
2069{
2070        while (--vmlinux_path__nr_entries >= 0) {
2071                free(vmlinux_path[vmlinux_path__nr_entries]);
2072                vmlinux_path[vmlinux_path__nr_entries] = NULL;
2073        }
2074
2075        free(vmlinux_path);
2076        vmlinux_path = NULL;
2077}
2078
2079static int vmlinux_path__init(void)
2080{
2081        struct utsname uts;
2082        char bf[PATH_MAX];
2083
2084        if (uname(&uts) < 0)
2085                return -1;
2086
2087        vmlinux_path = malloc(sizeof(char *) * 5);
2088        if (vmlinux_path == NULL)
2089                return -1;
2090
2091        vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
2092        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2093                goto out_fail;
2094        ++vmlinux_path__nr_entries;
2095        vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
2096        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2097                goto out_fail;
2098        ++vmlinux_path__nr_entries;
2099        snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
2100        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2101        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2102                goto out_fail;
2103        ++vmlinux_path__nr_entries;
2104        snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
2105        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2106        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2107                goto out_fail;
2108        ++vmlinux_path__nr_entries;
2109        snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
2110                 uts.release);
2111        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2112        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2113                goto out_fail;
2114        ++vmlinux_path__nr_entries;
2115
2116        return 0;
2117
2118out_fail:
2119        vmlinux_path__exit();
2120        return -1;
2121}
2122
2123size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp)
2124{
2125        int i;
2126        size_t printed = 0;
2127        struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso;
2128
2129        if (kdso->has_build_id) {
2130                char filename[PATH_MAX];
2131                if (dso__build_id_filename(kdso, filename, sizeof(filename)))
2132                        printed += fprintf(fp, "[0] %s\n", filename);
2133        }
2134
2135        for (i = 0; i < vmlinux_path__nr_entries; ++i)
2136                printed += fprintf(fp, "[%d] %s\n",
2137                                   i + kdso->has_build_id, vmlinux_path[i]);
2138
2139        return printed;
2140}
2141
2142static int setup_list(struct strlist **list, const char *list_str,
2143                      const char *list_name)
2144{
2145        if (list_str == NULL)
2146                return 0;
2147
2148        *list = strlist__new(true, list_str);
2149        if (!*list) {
2150                pr_err("problems parsing %s list\n", list_name);
2151                return -1;
2152        }
2153        return 0;
2154}
2155
2156int symbol__init(void)
2157{
2158        elf_version(EV_CURRENT);
2159        if (symbol_conf.sort_by_name)
2160                symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
2161                                          sizeof(struct symbol));
2162
2163        if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
2164                return -1;
2165
2166        if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
2167                pr_err("'.' is the only non valid --field-separator argument\n");
2168                return -1;
2169        }
2170
2171        if (setup_list(&symbol_conf.dso_list,
2172                       symbol_conf.dso_list_str, "dso") < 0)
2173                return -1;
2174
2175        if (setup_list(&symbol_conf.comm_list,
2176                       symbol_conf.comm_list_str, "comm") < 0)
2177                goto out_free_dso_list;
2178
2179        if (setup_list(&symbol_conf.sym_list,
2180                       symbol_conf.sym_list_str, "symbol") < 0)
2181                goto out_free_comm_list;
2182
2183        return 0;
2184
2185out_free_dso_list:
2186        strlist__delete(symbol_conf.dso_list);
2187out_free_comm_list:
2188        strlist__delete(symbol_conf.comm_list);
2189        return -1;
2190}
2191
2192int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
2193{
2194        struct machine *machine = machines__findnew(self, pid);
2195
2196        if (machine == NULL)
2197                return -1;
2198
2199        return machine__create_kernel_maps(machine);
2200}
2201
2202static int hex(char ch)
2203{
2204        if ((ch >= '0') && (ch <= '9'))
2205                return ch - '0';
2206        if ((ch >= 'a') && (ch <= 'f'))
2207                return ch - 'a' + 10;
2208        if ((ch >= 'A') && (ch <= 'F'))
2209                return ch - 'A' + 10;
2210        return -1;
2211}
2212
2213/*
2214 * While we find nice hex chars, build a long_val.
2215 * Return number of chars processed.
2216 */
2217int hex2u64(const char *ptr, u64 *long_val)
2218{
2219        const char *p = ptr;
2220        *long_val = 0;
2221
2222        while (*p) {
2223                const int hex_val = hex(*p);
2224
2225                if (hex_val < 0)
2226                        break;
2227
2228                *long_val = (*long_val << 4) | hex_val;
2229                p++;
2230        }
2231
2232        return p - ptr;
2233}
2234
2235char *strxfrchar(char *s, char from, char to)
2236{
2237        char *p = s;
2238
2239        while ((p = strchr(p, from)) != NULL)
2240                *p++ = to;
2241
2242        return s;
2243}
2244
2245int machines__create_guest_kernel_maps(struct rb_root *self)
2246{
2247        int ret = 0;
2248        struct dirent **namelist = NULL;
2249        int i, items = 0;
2250        char path[PATH_MAX];
2251        pid_t pid;
2252
2253        if (symbol_conf.default_guest_vmlinux_name ||
2254            symbol_conf.default_guest_modules ||
2255            symbol_conf.default_guest_kallsyms) {
2256                machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
2257        }
2258
2259        if (symbol_conf.guestmount) {
2260                items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
2261                if (items <= 0)
2262                        return -ENOENT;
2263                for (i = 0; i < items; i++) {
2264                        if (!isdigit(namelist[i]->d_name[0])) {
2265                                /* Filter out . and .. */
2266                                continue;
2267                        }
2268                        pid = atoi(namelist[i]->d_name);
2269                        sprintf(path, "%s/%s/proc/kallsyms",
2270                                symbol_conf.guestmount,
2271                                namelist[i]->d_name);
2272                        ret = access(path, R_OK);
2273                        if (ret) {
2274                                pr_debug("Can't access file %s\n", path);
2275                                goto failure;
2276                        }
2277                        machines__create_kernel_maps(self, pid);
2278                }
2279failure:
2280                free(namelist);
2281        }
2282
2283        return ret;
2284}
2285
2286int machine__load_kallsyms(struct machine *self, const char *filename,
2287                           enum map_type type, symbol_filter_t filter)
2288{
2289        struct map *map = self->vmlinux_maps[type];
2290        int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2291
2292        if (ret > 0) {
2293                dso__set_loaded(map->dso, type);
2294                /*
2295                 * Since /proc/kallsyms will have multiple sessions for the
2296                 * kernel, with modules between them, fixup the end of all
2297                 * sections.
2298                 */
2299                __map_groups__fixup_end(&self->kmaps, type);
2300        }
2301
2302        return ret;
2303}
2304
2305int machine__load_vmlinux_path(struct machine *self, enum map_type type,
2306                               symbol_filter_t filter)
2307{
2308        struct map *map = self->vmlinux_maps[type];
2309        int ret = dso__load_vmlinux_path(map->dso, map, filter);
2310
2311        if (ret > 0) {
2312                dso__set_loaded(map->dso, type);
2313                map__reloc_vmlinux(map);
2314        }
2315
2316        return ret;
2317}
2318
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.