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