linux/tools/perf/util/symbol.c
<<
>>
Prefs
   1#include <dirent.h>
   2#include <errno.h>
   3#include <stdlib.h>
   4#include <stdio.h>
   5#include <string.h>
   6#include <sys/types.h>
   7#include <sys/stat.h>
   8#include <sys/param.h>
   9#include <fcntl.h>
  10#include <unistd.h>
  11#include <inttypes.h>
  12#include "build-id.h"
  13#include "util.h"
  14#include "debug.h"
  15#include "machine.h"
  16#include "symbol.h"
  17#include "strlist.h"
  18
  19#include <elf.h>
  20#include <limits.h>
  21#include <sys/utsname.h>
  22
  23#ifndef KSYM_NAME_LEN
  24#define KSYM_NAME_LEN 256
  25#endif
  26
  27static int dso__load_kernel_sym(struct dso *dso, struct map *map,
  28                                symbol_filter_t filter);
  29static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
  30                        symbol_filter_t filter);
  31int vmlinux_path__nr_entries;
  32char **vmlinux_path;
  33
  34struct symbol_conf symbol_conf = {
  35        .use_modules      = true,
  36        .try_vmlinux_path = true,
  37        .annotate_src     = true,
  38        .demangle         = true,
  39        .symfs            = "",
  40};
  41
  42static enum dso_binary_type binary_type_symtab[] = {
  43        DSO_BINARY_TYPE__KALLSYMS,
  44        DSO_BINARY_TYPE__GUEST_KALLSYMS,
  45        DSO_BINARY_TYPE__JAVA_JIT,
  46        DSO_BINARY_TYPE__DEBUGLINK,
  47        DSO_BINARY_TYPE__BUILD_ID_CACHE,
  48        DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
  49        DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
  50        DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
  51        DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
  52        DSO_BINARY_TYPE__GUEST_KMODULE,
  53        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
  54        DSO_BINARY_TYPE__NOT_FOUND,
  55};
  56
  57#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
  58
  59bool symbol_type__is_a(char symbol_type, enum map_type map_type)
  60{
  61        symbol_type = toupper(symbol_type);
  62
  63        switch (map_type) {
  64        case MAP__FUNCTION:
  65                return symbol_type == 'T' || symbol_type == 'W';
  66        case MAP__VARIABLE:
  67                return symbol_type == 'D';
  68        default:
  69                return false;
  70        }
  71}
  72
  73static int prefix_underscores_count(const char *str)
  74{
  75        const char *tail = str;
  76
  77        while (*tail == '_')
  78                tail++;
  79
  80        return tail - str;
  81}
  82
  83#define SYMBOL_A 0
  84#define SYMBOL_B 1
  85
  86static int choose_best_symbol(struct symbol *syma, struct symbol *symb)
  87{
  88        s64 a;
  89        s64 b;
  90
  91        /* Prefer a symbol with non zero length */
  92        a = syma->end - syma->start;
  93        b = symb->end - symb->start;
  94        if ((b == 0) && (a > 0))
  95                return SYMBOL_A;
  96        else if ((a == 0) && (b > 0))
  97                return SYMBOL_B;
  98
  99        /* Prefer a non weak symbol over a weak one */
 100        a = syma->binding == STB_WEAK;
 101        b = symb->binding == STB_WEAK;
 102        if (b && !a)
 103                return SYMBOL_A;
 104        if (a && !b)
 105                return SYMBOL_B;
 106
 107        /* Prefer a global symbol over a non global one */
 108        a = syma->binding == STB_GLOBAL;
 109        b = symb->binding == STB_GLOBAL;
 110        if (a && !b)
 111                return SYMBOL_A;
 112        if (b && !a)
 113                return SYMBOL_B;
 114
 115        /* Prefer a symbol with less underscores */
 116        a = prefix_underscores_count(syma->name);
 117        b = prefix_underscores_count(symb->name);
 118        if (b > a)
 119                return SYMBOL_A;
 120        else if (a > b)
 121                return SYMBOL_B;
 122
 123        /* If all else fails, choose the symbol with the longest name */
 124        if (strlen(syma->name) >= strlen(symb->name))
 125                return SYMBOL_A;
 126        else
 127                return SYMBOL_B;
 128}
 129
 130void symbols__fixup_duplicate(struct rb_root *symbols)
 131{
 132        struct rb_node *nd;
 133        struct symbol *curr, *next;
 134
 135        nd = rb_first(symbols);
 136
 137        while (nd) {
 138                curr = rb_entry(nd, struct symbol, rb_node);
 139again:
 140                nd = rb_next(&curr->rb_node);
 141                next = rb_entry(nd, struct symbol, rb_node);
 142
 143                if (!nd)
 144                        break;
 145
 146                if (curr->start != next->start)
 147                        continue;
 148
 149                if (choose_best_symbol(curr, next) == SYMBOL_A) {
 150                        rb_erase(&next->rb_node, symbols);
 151                        goto again;
 152                } else {
 153                        nd = rb_next(&curr->rb_node);
 154                        rb_erase(&curr->rb_node, symbols);
 155                }
 156        }
 157}
 158
 159void symbols__fixup_end(struct rb_root *symbols)
 160{
 161        struct rb_node *nd, *prevnd = rb_first(symbols);
 162        struct symbol *curr, *prev;
 163
 164        if (prevnd == NULL)
 165                return;
 166
 167        curr = rb_entry(prevnd, struct symbol, rb_node);
 168
 169        for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
 170                prev = curr;
 171                curr = rb_entry(nd, struct symbol, rb_node);
 172
 173                if (prev->end == prev->start && prev->end != curr->start)
 174                        prev->end = curr->start - 1;
 175        }
 176
 177        /* Last entry */
 178        if (curr->end == curr->start)
 179                curr->end = roundup(curr->start, 4096);
 180}
 181
 182void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
 183{
 184        struct map *prev, *curr;
 185        struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
 186
 187        if (prevnd == NULL)
 188                return;
 189
 190        curr = rb_entry(prevnd, struct map, rb_node);
 191
 192        for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
 193                prev = curr;
 194                curr = rb_entry(nd, struct map, rb_node);
 195                prev->end = curr->start - 1;
 196        }
 197
 198        /*
 199         * We still haven't the actual symbols, so guess the
 200         * last map final address.
 201         */
 202        curr->end = ~0ULL;
 203}
 204
 205struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
 206{
 207        size_t namelen = strlen(name) + 1;
 208        struct symbol *sym = calloc(1, (symbol_conf.priv_size +
 209                                        sizeof(*sym) + namelen));
 210        if (sym == NULL)
 211                return NULL;
 212
 213        if (symbol_conf.priv_size)
 214                sym = ((void *)sym) + symbol_conf.priv_size;
 215
 216        sym->start   = start;
 217        sym->end     = len ? start + len - 1 : start;
 218        sym->binding = binding;
 219        sym->namelen = namelen - 1;
 220
 221        pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
 222                  __func__, name, start, sym->end);
 223        memcpy(sym->name, name, namelen);
 224
 225        return sym;
 226}
 227
 228void symbol__delete(struct symbol *sym)
 229{
 230        free(((void *)sym) - symbol_conf.priv_size);
 231}
 232
 233size_t symbol__fprintf(struct symbol *sym, FILE *fp)
 234{
 235        return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
 236                       sym->start, sym->end,
 237                       sym->binding == STB_GLOBAL ? 'g' :
 238                       sym->binding == STB_LOCAL  ? 'l' : 'w',
 239                       sym->name);
 240}
 241
 242size_t symbol__fprintf_symname_offs(const struct symbol *sym,
 243                                    const struct addr_location *al, FILE *fp)
 244{
 245        unsigned long offset;
 246        size_t length;
 247
 248        if (sym && sym->name) {
 249                length = fprintf(fp, "%s", sym->name);
 250                if (al) {
 251                        offset = al->addr - sym->start;
 252                        length += fprintf(fp, "+0x%lx", offset);
 253                }
 254                return length;
 255        } else
 256                return fprintf(fp, "[unknown]");
 257}
 258
 259size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
 260{
 261        return symbol__fprintf_symname_offs(sym, NULL, fp);
 262}
 263
 264void symbols__delete(struct rb_root *symbols)
 265{
 266        struct symbol *pos;
 267        struct rb_node *next = rb_first(symbols);
 268
 269        while (next) {
 270                pos = rb_entry(next, struct symbol, rb_node);
 271                next = rb_next(&pos->rb_node);
 272                rb_erase(&pos->rb_node, symbols);
 273                symbol__delete(pos);
 274        }
 275}
 276
 277void symbols__insert(struct rb_root *symbols, struct symbol *sym)
 278{
 279        struct rb_node **p = &symbols->rb_node;
 280        struct rb_node *parent = NULL;
 281        const u64 ip = sym->start;
 282        struct symbol *s;
 283
 284        while (*p != NULL) {
 285                parent = *p;
 286                s = rb_entry(parent, struct symbol, rb_node);
 287                if (ip < s->start)
 288                        p = &(*p)->rb_left;
 289                else
 290                        p = &(*p)->rb_right;
 291        }
 292        rb_link_node(&sym->rb_node, parent, p);
 293        rb_insert_color(&sym->rb_node, symbols);
 294}
 295
 296static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
 297{
 298        struct rb_node *n;
 299
 300        if (symbols == NULL)
 301                return NULL;
 302
 303        n = symbols->rb_node;
 304
 305        while (n) {
 306                struct symbol *s = rb_entry(n, struct symbol, rb_node);
 307
 308                if (ip < s->start)
 309                        n = n->rb_left;
 310                else if (ip > s->end)
 311                        n = n->rb_right;
 312                else
 313                        return s;
 314        }
 315
 316        return NULL;
 317}
 318
 319struct symbol_name_rb_node {
 320        struct rb_node  rb_node;
 321        struct symbol   sym;
 322};
 323
 324static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
 325{
 326        struct rb_node **p = &symbols->rb_node;
 327        struct rb_node *parent = NULL;
 328        struct symbol_name_rb_node *symn, *s;
 329
 330        symn = container_of(sym, struct symbol_name_rb_node, sym);
 331
 332        while (*p != NULL) {
 333                parent = *p;
 334                s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
 335                if (strcmp(sym->name, s->sym.name) < 0)
 336                        p = &(*p)->rb_left;
 337                else
 338                        p = &(*p)->rb_right;
 339        }
 340        rb_link_node(&symn->rb_node, parent, p);
 341        rb_insert_color(&symn->rb_node, symbols);
 342}
 343
 344static void symbols__sort_by_name(struct rb_root *symbols,
 345                                  struct rb_root *source)
 346{
 347        struct rb_node *nd;
 348
 349        for (nd = rb_first(source); nd; nd = rb_next(nd)) {
 350                struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
 351                symbols__insert_by_name(symbols, pos);
 352        }
 353}
 354
 355static struct symbol *symbols__find_by_name(struct rb_root *symbols,
 356                                            const char *name)
 357{
 358        struct rb_node *n;
 359
 360        if (symbols == NULL)
 361                return NULL;
 362
 363        n = symbols->rb_node;
 364
 365        while (n) {
 366                struct symbol_name_rb_node *s;
 367                int cmp;
 368
 369                s = rb_entry(n, struct symbol_name_rb_node, rb_node);
 370                cmp = strcmp(name, s->sym.name);
 371
 372                if (cmp < 0)
 373                        n = n->rb_left;
 374                else if (cmp > 0)
 375                        n = n->rb_right;
 376                else
 377                        return &s->sym;
 378        }
 379
 380        return NULL;
 381}
 382
 383struct symbol *dso__find_symbol(struct dso *dso,
 384                                enum map_type type, u64 addr)
 385{
 386        return symbols__find(&dso->symbols[type], addr);
 387}
 388
 389struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 390                                        const char *name)
 391{
 392        return symbols__find_by_name(&dso->symbol_names[type], name);
 393}
 394
 395void dso__sort_by_name(struct dso *dso, enum map_type type)
 396{
 397        dso__set_sorted_by_name(dso, type);
 398        return symbols__sort_by_name(&dso->symbol_names[type],
 399                                     &dso->symbols[type]);
 400}
 401
 402size_t dso__fprintf_symbols_by_name(struct dso *dso,
 403                                    enum map_type type, FILE *fp)
 404{
 405        size_t ret = 0;
 406        struct rb_node *nd;
 407        struct symbol_name_rb_node *pos;
 408
 409        for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
 410                pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
 411                fprintf(fp, "%s\n", pos->sym.name);
 412        }
 413
 414        return ret;
 415}
 416
 417int kallsyms__parse(const char *filename, void *arg,
 418                    int (*process_symbol)(void *arg, const char *name,
 419                                          char type, u64 start))
 420{
 421        char *line = NULL;
 422        size_t n;
 423        int err = -1;
 424        FILE *file = fopen(filename, "r");
 425
 426        if (file == NULL)
 427                goto out_failure;
 428
 429        err = 0;
 430
 431        while (!feof(file)) {
 432                u64 start;
 433                int line_len, len;
 434                char symbol_type;
 435                char *symbol_name;
 436
 437                line_len = getline(&line, &n, file);
 438                if (line_len < 0 || !line)
 439                        break;
 440
 441                line[--line_len] = '\0'; /* \n */
 442
 443                len = hex2u64(line, &start);
 444
 445                len++;
 446                if (len + 2 >= line_len)
 447                        continue;
 448
 449                symbol_type = line[len];
 450                len += 2;
 451                symbol_name = line + len;
 452                len = line_len - len;
 453
 454                if (len >= KSYM_NAME_LEN) {
 455                        err = -1;
 456                        break;
 457                }
 458
 459                err = process_symbol(arg, symbol_name,
 460                                     symbol_type, start);
 461                if (err)
 462                        break;
 463        }
 464
 465        free(line);
 466        fclose(file);
 467        return err;
 468
 469out_failure:
 470        return -1;
 471}
 472
 473struct process_kallsyms_args {
 474        struct map *map;
 475        struct dso *dso;
 476};
 477
 478static u8 kallsyms2elf_type(char type)
 479{
 480        if (type == 'W')
 481                return STB_WEAK;
 482
 483        return isupper(type) ? STB_GLOBAL : STB_LOCAL;
 484}
 485
 486static int map__process_kallsym_symbol(void *arg, const char *name,
 487                                       char type, u64 start)
 488{
 489        struct symbol *sym;
 490        struct process_kallsyms_args *a = arg;
 491        struct rb_root *root = &a->dso->symbols[a->map->type];
 492
 493        if (!symbol_type__is_a(type, a->map->type))
 494                return 0;
 495
 496        /*
 497         * module symbols are not sorted so we add all
 498         * symbols, setting length to 0, and rely on
 499         * symbols__fixup_end() to fix it up.
 500         */
 501        sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
 502        if (sym == NULL)
 503                return -ENOMEM;
 504        /*
 505         * We will pass the symbols to the filter later, in
 506         * map__split_kallsyms, when we have split the maps per module
 507         */
 508        symbols__insert(root, sym);
 509
 510        return 0;
 511}
 512
 513/*
 514 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
 515 * so that we can in the next step set the symbol ->end address and then
 516 * call kernel_maps__split_kallsyms.
 517 */
 518static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
 519                                  struct map *map)
 520{
 521        struct process_kallsyms_args args = { .map = map, .dso = dso, };
 522        return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
 523}
 524
 525/*
 526 * Split the symbols into maps, making sure there are no overlaps, i.e. the
 527 * kernel range is broken in several maps, named [kernel].N, as we don't have
 528 * the original ELF section names vmlinux have.
 529 */
 530static int dso__split_kallsyms(struct dso *dso, struct map *map,
 531                               symbol_filter_t filter)
 532{
 533        struct map_groups *kmaps = map__kmap(map)->kmaps;
 534        struct machine *machine = kmaps->machine;
 535        struct map *curr_map = map;
 536        struct symbol *pos;
 537        int count = 0, moved = 0;       
 538        struct rb_root *root = &dso->symbols[map->type];
 539        struct rb_node *next = rb_first(root);
 540        int kernel_range = 0;
 541
 542        while (next) {
 543                char *module;
 544
 545                pos = rb_entry(next, struct symbol, rb_node);
 546                next = rb_next(&pos->rb_node);
 547
 548                module = strchr(pos->name, '\t');
 549                if (module) {
 550                        if (!symbol_conf.use_modules)
 551                                goto discard_symbol;
 552
 553                        *module++ = '\0';
 554
 555                        if (strcmp(curr_map->dso->short_name, module)) {
 556                                if (curr_map != map &&
 557                                    dso->kernel == DSO_TYPE_GUEST_KERNEL &&
 558                                    machine__is_default_guest(machine)) {
 559                                        /*
 560                                         * We assume all symbols of a module are
 561                                         * continuous in * kallsyms, so curr_map
 562                                         * points to a module and all its
 563                                         * symbols are in its kmap. Mark it as
 564                                         * loaded.
 565                                         */
 566                                        dso__set_loaded(curr_map->dso,
 567                                                        curr_map->type);
 568                                }
 569
 570                                curr_map = map_groups__find_by_name(kmaps,
 571                                                        map->type, module);
 572                                if (curr_map == NULL) {
 573                                        pr_debug("%s/proc/{kallsyms,modules} "
 574                                                 "inconsistency while looking "
 575                                                 "for \"%s\" module!\n",
 576                                                 machine->root_dir, module);
 577                                        curr_map = map;
 578                                        goto discard_symbol;
 579                                }
 580
 581                                if (curr_map->dso->loaded &&
 582                                    !machine__is_default_guest(machine))
 583                                        goto discard_symbol;
 584                        }
 585                        /*
 586                         * So that we look just like we get from .ko files,
 587                         * i.e. not prelinked, relative to map->start.
 588                         */
 589                        pos->start = curr_map->map_ip(curr_map, pos->start);
 590                        pos->end   = curr_map->map_ip(curr_map, pos->end);
 591                } else if (curr_map != map) {
 592                        char dso_name[PATH_MAX];
 593                        struct dso *ndso;
 594
 595                        if (count == 0) {
 596                                curr_map = map;
 597                                goto filter_symbol;
 598                        }
 599
 600                        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
 601                                snprintf(dso_name, sizeof(dso_name),
 602                                        "[guest.kernel].%d",
 603                                        kernel_range++);
 604                        else
 605                                snprintf(dso_name, sizeof(dso_name),
 606                                        "[kernel].%d",
 607                                        kernel_range++);
 608
 609                        ndso = dso__new(dso_name);
 610                        if (ndso == NULL)
 611                                return -1;
 612
 613                        ndso->kernel = dso->kernel;
 614
 615                        curr_map = map__new2(pos->start, ndso, map->type);
 616                        if (curr_map == NULL) {
 617                                dso__delete(ndso);
 618                                return -1;
 619                        }
 620
 621                        curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
 622                        map_groups__insert(kmaps, curr_map);
 623                        ++kernel_range;
 624                }
 625filter_symbol:
 626                if (filter && filter(curr_map, pos)) {
 627discard_symbol:         rb_erase(&pos->rb_node, root);
 628                        symbol__delete(pos);
 629                } else {
 630                        if (curr_map != map) {
 631                                rb_erase(&pos->rb_node, root);
 632                                symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
 633                                ++moved;
 634                        } else
 635                                ++count;
 636                }
 637        }
 638
 639        if (curr_map != map &&
 640            dso->kernel == DSO_TYPE_GUEST_KERNEL &&
 641            machine__is_default_guest(kmaps->machine)) {
 642                dso__set_loaded(curr_map->dso, curr_map->type);
 643        }
 644
 645        return count + moved;
 646}
 647
 648bool symbol__restricted_filename(const char *filename,
 649                                 const char *restricted_filename)
 650{
 651        bool restricted = false;
 652
 653        if (symbol_conf.kptr_restrict) {
 654                char *r = realpath(filename, NULL);
 655
 656                if (r != NULL) {
 657                        restricted = strcmp(r, restricted_filename) == 0;
 658                        free(r);
 659                        return restricted;
 660                }
 661        }
 662
 663        return restricted;
 664}
 665
 666int dso__load_kallsyms(struct dso *dso, const char *filename,
 667                       struct map *map, symbol_filter_t filter)
 668{
 669        if (symbol__restricted_filename(filename, "/proc/kallsyms"))
 670                return -1;
 671
 672        if (dso__load_all_kallsyms(dso, filename, map) < 0)
 673                return -1;
 674
 675        symbols__fixup_duplicate(&dso->symbols[map->type]);
 676        symbols__fixup_end(&dso->symbols[map->type]);
 677
 678        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
 679                dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
 680        else
 681                dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
 682
 683        return dso__split_kallsyms(dso, map, filter);
 684}
 685
 686static int dso__load_perf_map(struct dso *dso, struct map *map,
 687                              symbol_filter_t filter)
 688{
 689        char *line = NULL;
 690        size_t n;
 691        FILE *file;
 692        int nr_syms = 0;
 693
 694        file = fopen(dso->long_name, "r");
 695        if (file == NULL)
 696                goto out_failure;
 697
 698        while (!feof(file)) {
 699                u64 start, size;
 700                struct symbol *sym;
 701                int line_len, len;
 702
 703                line_len = getline(&line, &n, file);
 704                if (line_len < 0)
 705                        break;
 706
 707                if (!line)
 708                        goto out_failure;
 709
 710                line[--line_len] = '\0'; /* \n */
 711
 712                len = hex2u64(line, &start);
 713
 714                len++;
 715                if (len + 2 >= line_len)
 716                        continue;
 717
 718                len += hex2u64(line + len, &size);
 719
 720                len++;
 721                if (len + 2 >= line_len)
 722                        continue;
 723
 724                sym = symbol__new(start, size, STB_GLOBAL, line + len);
 725
 726                if (sym == NULL)
 727                        goto out_delete_line;
 728
 729                if (filter && filter(map, sym))
 730                        symbol__delete(sym);
 731                else {
 732                        symbols__insert(&dso->symbols[map->type], sym);
 733                        nr_syms++;
 734                }
 735        }
 736
 737        free(line);
 738        fclose(file);
 739
 740        return nr_syms;
 741
 742out_delete_line:
 743        free(line);
 744out_failure:
 745        return -1;
 746}
 747
 748int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
 749{
 750        char *name;
 751        int ret = -1;
 752        u_int i;
 753        struct machine *machine;
 754        char *root_dir = (char *) "";
 755        int ss_pos = 0;
 756        struct symsrc ss_[2];
 757        struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
 758
 759        dso__set_loaded(dso, map->type);
 760
 761        if (dso->kernel == DSO_TYPE_KERNEL)
 762                return dso__load_kernel_sym(dso, map, filter);
 763        else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
 764                return dso__load_guest_kernel_sym(dso, map, filter);
 765
 766        if (map->groups && map->groups->machine)
 767                machine = map->groups->machine;
 768        else
 769                machine = NULL;
 770
 771        dso->adjust_symbols = 0;
 772
 773        if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
 774                struct stat st;
 775
 776                if (lstat(dso->name, &st) < 0)
 777                        return -1;
 778
 779                if (st.st_uid && (st.st_uid != geteuid())) {
 780                        pr_warning("File %s not owned by current user or root, "
 781                                "ignoring it.\n", dso->name);
 782                        return -1;
 783                }
 784
 785                ret = dso__load_perf_map(dso, map, filter);
 786                dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
 787                                             DSO_BINARY_TYPE__NOT_FOUND;
 788                return ret;
 789        }
 790
 791        if (machine)
 792                root_dir = machine->root_dir;
 793
 794        name = malloc(PATH_MAX);
 795        if (!name)
 796                return -1;
 797
 798        /* Iterate over candidate debug images.
 799         * Keep track of "interesting" ones (those which have a symtab, dynsym,
 800         * and/or opd section) for processing.
 801         */
 802        for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
 803                struct symsrc *ss = &ss_[ss_pos];
 804                bool next_slot = false;
 805
 806                enum dso_binary_type symtab_type = binary_type_symtab[i];
 807
 808                if (dso__binary_type_file(dso, symtab_type,
 809                                          root_dir, name, PATH_MAX))
 810                        continue;
 811
 812                /* Name is now the name of the next image to try */
 813                if (symsrc__init(ss, dso, name, symtab_type) < 0)
 814                        continue;
 815
 816                if (!syms_ss && symsrc__has_symtab(ss)) {
 817                        syms_ss = ss;
 818                        next_slot = true;
 819                }
 820
 821                if (!runtime_ss && symsrc__possibly_runtime(ss)) {
 822                        runtime_ss = ss;
 823                        next_slot = true;
 824                }
 825
 826                if (next_slot) {
 827                        ss_pos++;
 828
 829                        if (syms_ss && runtime_ss)
 830                                break;
 831                }
 832
 833        }
 834
 835        if (!runtime_ss && !syms_ss)
 836                goto out_free;
 837
 838        if (runtime_ss && !syms_ss) {
 839                syms_ss = runtime_ss;
 840        }
 841
 842        /* We'll have to hope for the best */
 843        if (!runtime_ss && syms_ss)
 844                runtime_ss = syms_ss;
 845
 846        if (syms_ss)
 847                ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, 0);
 848        else
 849                ret = -1;
 850
 851        if (ret > 0) {
 852                int nr_plt;
 853
 854                nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter);
 855                if (nr_plt > 0)
 856                        ret += nr_plt;
 857        }
 858
 859        for (; ss_pos > 0; ss_pos--)
 860                symsrc__destroy(&ss_[ss_pos - 1]);
 861out_free:
 862        free(name);
 863        if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
 864                return 0;
 865        return ret;
 866}
 867
 868struct map *map_groups__find_by_name(struct map_groups *mg,
 869                                     enum map_type type, const char *name)
 870{
 871        struct rb_node *nd;
 872
 873        for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
 874                struct map *map = rb_entry(nd, struct map, rb_node);
 875
 876                if (map->dso && strcmp(map->dso->short_name, name) == 0)
 877                        return map;
 878        }
 879
 880        return NULL;
 881}
 882
 883int dso__load_vmlinux(struct dso *dso, struct map *map,
 884                      const char *vmlinux, symbol_filter_t filter)
 885{
 886        int err = -1;
 887        struct symsrc ss;
 888        char symfs_vmlinux[PATH_MAX];
 889        enum dso_binary_type symtab_type;
 890
 891        snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s",
 892                 symbol_conf.symfs, vmlinux);
 893
 894        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
 895                symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
 896        else
 897                symtab_type = DSO_BINARY_TYPE__VMLINUX;
 898
 899        if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
 900                return -1;
 901
 902        err = dso__load_sym(dso, map, &ss, &ss, filter, 0);
 903        symsrc__destroy(&ss);
 904
 905        if (err > 0) {
 906                dso__set_long_name(dso, (char *)vmlinux);
 907                dso__set_loaded(dso, map->type);
 908                pr_debug("Using %s for symbols\n", symfs_vmlinux);
 909        }
 910
 911        return err;
 912}
 913
 914int dso__load_vmlinux_path(struct dso *dso, struct map *map,
 915                           symbol_filter_t filter)
 916{
 917        int i, err = 0;
 918        char *filename;
 919
 920        pr_debug("Looking at the vmlinux_path (%d entries long)\n",
 921                 vmlinux_path__nr_entries + 1);
 922
 923        filename = dso__build_id_filename(dso, NULL, 0);
 924        if (filename != NULL) {
 925                err = dso__load_vmlinux(dso, map, filename, filter);
 926                if (err > 0) {
 927                        dso->lname_alloc = 1;
 928                        goto out;
 929                }
 930                free(filename);
 931        }
 932
 933        for (i = 0; i < vmlinux_path__nr_entries; ++i) {
 934                err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
 935                if (err > 0) {
 936                        dso__set_long_name(dso, strdup(vmlinux_path[i]));
 937                        dso->lname_alloc = 1;
 938                        break;
 939                }
 940        }
 941out:
 942        return err;
 943}
 944
 945static int dso__load_kernel_sym(struct dso *dso, struct map *map,
 946                                symbol_filter_t filter)
 947{
 948        int err;
 949        const char *kallsyms_filename = NULL;
 950        char *kallsyms_allocated_filename = NULL;
 951        /*
 952         * Step 1: if the user specified a kallsyms or vmlinux filename, use
 953         * it and only it, reporting errors to the user if it cannot be used.
 954         *
 955         * For instance, try to analyse an ARM perf.data file _without_ a
 956         * build-id, or if the user specifies the wrong path to the right
 957         * vmlinux file, obviously we can't fallback to another vmlinux (a
 958         * x86_86 one, on the machine where analysis is being performed, say),
 959         * or worse, /proc/kallsyms.
 960         *
 961         * If the specified file _has_ a build-id and there is a build-id
 962         * section in the perf.data file, we will still do the expected
 963         * validation in dso__load_vmlinux and will bail out if they don't
 964         * match.
 965         */
 966        if (symbol_conf.kallsyms_name != NULL) {
 967                kallsyms_filename = symbol_conf.kallsyms_name;
 968                goto do_kallsyms;
 969        }
 970
 971        if (symbol_conf.vmlinux_name != NULL) {
 972                err = dso__load_vmlinux(dso, map,
 973                                        symbol_conf.vmlinux_name, filter);
 974                if (err > 0) {
 975                        dso__set_long_name(dso,
 976                                           strdup(symbol_conf.vmlinux_name));
 977                        dso->lname_alloc = 1;
 978                        goto out_fixup;
 979                }
 980                return err;
 981        }
 982
 983        if (vmlinux_path != NULL) {
 984                err = dso__load_vmlinux_path(dso, map, filter);
 985                if (err > 0)
 986                        goto out_fixup;
 987        }
 988
 989        /* do not try local files if a symfs was given */
 990        if (symbol_conf.symfs[0] != 0)
 991                return -1;
 992
 993        /*
 994         * Say the kernel DSO was created when processing the build-id header table,
 995         * we have a build-id, so check if it is the same as the running kernel,
 996         * using it if it is.
 997         */
 998        if (dso->has_build_id) {
 999                u8 kallsyms_build_id[BUILD_ID_SIZE];
1000                char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1001
1002                if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1003                                         sizeof(kallsyms_build_id)) == 0) {
1004                        if (dso__build_id_equal(dso, kallsyms_build_id)) {
1005                                kallsyms_filename = "/proc/kallsyms";
1006                                goto do_kallsyms;
1007                        }
1008                }
1009                /*
1010                 * Now look if we have it on the build-id cache in
1011                 * $HOME/.debug/[kernel.kallsyms].
1012                 */
1013                build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1014                                  sbuild_id);
1015
1016                if (asprintf(&kallsyms_allocated_filename,
1017                             "%s/.debug/[kernel.kallsyms]/%s",
1018                             getenv("HOME"), sbuild_id) == -1) {
1019                        pr_err("Not enough memory for kallsyms file lookup\n");
1020                        return -1;
1021                }
1022
1023                kallsyms_filename = kallsyms_allocated_filename;
1024
1025                if (access(kallsyms_filename, F_OK)) {
1026                        pr_err("No kallsyms or vmlinux with build-id %s "
1027                               "was found\n", sbuild_id);
1028                        free(kallsyms_allocated_filename);
1029                        return -1;
1030                }
1031        } else {
1032                /*
1033                 * Last resort, if we don't have a build-id and couldn't find
1034                 * any vmlinux file, try the running kernel kallsyms table.
1035                 */
1036                kallsyms_filename = "/proc/kallsyms";
1037        }
1038
1039do_kallsyms:
1040        err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1041        if (err > 0)
1042                pr_debug("Using %s for symbols\n", kallsyms_filename);
1043        free(kallsyms_allocated_filename);
1044
1045        if (err > 0) {
1046                dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
1047out_fixup:
1048                map__fixup_start(map);
1049                map__fixup_end(map);
1050        }
1051
1052        return err;
1053}
1054
1055static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1056                                      symbol_filter_t filter)
1057{
1058        int err;
1059        const char *kallsyms_filename = NULL;
1060        struct machine *machine;
1061        char path[PATH_MAX];
1062
1063        if (!map->groups) {
1064                pr_debug("Guest kernel map hasn't the point to groups\n");
1065                return -1;
1066        }
1067        machine = map->groups->machine;
1068
1069        if (machine__is_default_guest(machine)) {
1070                /*
1071                 * if the user specified a vmlinux filename, use it and only
1072                 * it, reporting errors to the user if it cannot be used.
1073                 * Or use file guest_kallsyms inputted by user on commandline
1074                 */
1075                if (symbol_conf.default_guest_vmlinux_name != NULL) {
1076                        err = dso__load_vmlinux(dso, map,
1077                                symbol_conf.default_guest_vmlinux_name, filter);
1078                        goto out_try_fixup;
1079                }
1080
1081                kallsyms_filename = symbol_conf.default_guest_kallsyms;
1082                if (!kallsyms_filename)
1083                        return -1;
1084        } else {
1085                sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1086                kallsyms_filename = path;
1087        }
1088
1089        err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1090        if (err > 0)
1091                pr_debug("Using %s for symbols\n", kallsyms_filename);
1092
1093out_try_fixup:
1094        if (err > 0) {
1095                if (kallsyms_filename != NULL) {
1096                        machine__mmap_name(machine, path, sizeof(path));
1097                        dso__set_long_name(dso, strdup(path));
1098                }
1099                map__fixup_start(map);
1100                map__fixup_end(map);
1101        }
1102
1103        return err;
1104}
1105
1106static void vmlinux_path__exit(void)
1107{
1108        while (--vmlinux_path__nr_entries >= 0) {
1109                free(vmlinux_path[vmlinux_path__nr_entries]);
1110                vmlinux_path[vmlinux_path__nr_entries] = NULL;
1111        }
1112
1113        free(vmlinux_path);
1114        vmlinux_path = NULL;
1115}
1116
1117static int vmlinux_path__init(void)
1118{
1119        struct utsname uts;
1120        char bf[PATH_MAX];
1121
1122        vmlinux_path = malloc(sizeof(char *) * 5);
1123        if (vmlinux_path == NULL)
1124                return -1;
1125
1126        vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1127        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1128                goto out_fail;
1129        ++vmlinux_path__nr_entries;
1130        vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1131        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1132                goto out_fail;
1133        ++vmlinux_path__nr_entries;
1134
1135        /* only try running kernel version if no symfs was given */
1136        if (symbol_conf.symfs[0] != 0)
1137                return 0;
1138
1139        if (uname(&uts) < 0)
1140                return -1;
1141
1142        snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1143        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1144        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1145                goto out_fail;
1146        ++vmlinux_path__nr_entries;
1147        snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1148        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1149        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1150                goto out_fail;
1151        ++vmlinux_path__nr_entries;
1152        snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1153                 uts.release);
1154        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1155        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1156                goto out_fail;
1157        ++vmlinux_path__nr_entries;
1158
1159        return 0;
1160
1161out_fail:
1162        vmlinux_path__exit();
1163        return -1;
1164}
1165
1166static int setup_list(struct strlist **list, const char *list_str,
1167                      const char *list_name)
1168{
1169        if (list_str == NULL)
1170                return 0;
1171
1172        *list = strlist__new(true, list_str);
1173        if (!*list) {
1174                pr_err("problems parsing %s list\n", list_name);
1175                return -1;
1176        }
1177        return 0;
1178}
1179
1180static bool symbol__read_kptr_restrict(void)
1181{
1182        bool value = false;
1183
1184        if (geteuid() != 0) {
1185                FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
1186                if (fp != NULL) {
1187                        char line[8];
1188
1189                        if (fgets(line, sizeof(line), fp) != NULL)
1190                                value = atoi(line) != 0;
1191
1192                        fclose(fp);
1193                }
1194        }
1195
1196        return value;
1197}
1198
1199int symbol__init(void)
1200{
1201        const char *symfs;
1202
1203        if (symbol_conf.initialized)
1204                return 0;
1205
1206        symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
1207
1208        symbol__elf_init();
1209
1210        if (symbol_conf.sort_by_name)
1211                symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1212                                          sizeof(struct symbol));
1213
1214        if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
1215                return -1;
1216
1217        if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
1218                pr_err("'.' is the only non valid --field-separator argument\n");
1219                return -1;
1220        }
1221
1222        if (setup_list(&symbol_conf.dso_list,
1223                       symbol_conf.dso_list_str, "dso") < 0)
1224                return -1;
1225
1226        if (setup_list(&symbol_conf.comm_list,
1227                       symbol_conf.comm_list_str, "comm") < 0)
1228                goto out_free_dso_list;
1229
1230        if (setup_list(&symbol_conf.sym_list,
1231                       symbol_conf.sym_list_str, "symbol") < 0)
1232                goto out_free_comm_list;
1233
1234        /*
1235         * A path to symbols of "/" is identical to ""
1236         * reset here for simplicity.
1237         */
1238        symfs = realpath(symbol_conf.symfs, NULL);
1239        if (symfs == NULL)
1240                symfs = symbol_conf.symfs;
1241        if (strcmp(symfs, "/") == 0)
1242                symbol_conf.symfs = "";
1243        if (symfs != symbol_conf.symfs)
1244                free((void *)symfs);
1245
1246        symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
1247
1248        symbol_conf.initialized = true;
1249        return 0;
1250
1251out_free_comm_list:
1252        strlist__delete(symbol_conf.comm_list);
1253out_free_dso_list:
1254        strlist__delete(symbol_conf.dso_list);
1255        return -1;
1256}
1257
1258void symbol__exit(void)
1259{
1260        if (!symbol_conf.initialized)
1261                return;
1262        strlist__delete(symbol_conf.sym_list);
1263        strlist__delete(symbol_conf.dso_list);
1264        strlist__delete(symbol_conf.comm_list);
1265        vmlinux_path__exit();
1266        symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
1267        symbol_conf.initialized = false;
1268}
1269