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#include "intlist.h"
  19#include "header.h"
  20
  21#include <elf.h>
  22#include <limits.h>
  23#include <symbol/kallsyms.h>
  24#include <sys/utsname.h>
  25
  26static int dso__load_kernel_sym(struct dso *dso, struct map *map,
  27                                symbol_filter_t filter);
  28static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
  29                        symbol_filter_t filter);
  30int vmlinux_path__nr_entries;
  31char **vmlinux_path;
  32
  33struct symbol_conf symbol_conf = {
  34        .use_modules            = true,
  35        .try_vmlinux_path       = true,
  36        .annotate_src           = true,
  37        .demangle               = true,
  38        .demangle_kernel        = false,
  39        .cumulate_callchain     = true,
  40        .show_hist_headers      = true,
  41        .symfs                  = "",
  42};
  43
  44static enum dso_binary_type binary_type_symtab[] = {
  45        DSO_BINARY_TYPE__KALLSYMS,
  46        DSO_BINARY_TYPE__GUEST_KALLSYMS,
  47        DSO_BINARY_TYPE__JAVA_JIT,
  48        DSO_BINARY_TYPE__DEBUGLINK,
  49        DSO_BINARY_TYPE__BUILD_ID_CACHE,
  50        DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
  51        DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
  52        DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
  53        DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
  54        DSO_BINARY_TYPE__GUEST_KMODULE,
  55        DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
  56        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
  57        DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
  58        DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
  59        DSO_BINARY_TYPE__NOT_FOUND,
  60};
  61
  62#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
  63
  64bool symbol_type__is_a(char symbol_type, enum map_type map_type)
  65{
  66        symbol_type = toupper(symbol_type);
  67
  68        switch (map_type) {
  69        case MAP__FUNCTION:
  70                return symbol_type == 'T' || symbol_type == 'W';
  71        case MAP__VARIABLE:
  72                return symbol_type == 'D';
  73        default:
  74                return false;
  75        }
  76}
  77
  78static int prefix_underscores_count(const char *str)
  79{
  80        const char *tail = str;
  81
  82        while (*tail == '_')
  83                tail++;
  84
  85        return tail - str;
  86}
  87
  88#define SYMBOL_A 0
  89#define SYMBOL_B 1
  90
  91static int choose_best_symbol(struct symbol *syma, struct symbol *symb)
  92{
  93        s64 a;
  94        s64 b;
  95        size_t na, nb;
  96
  97        /* Prefer a symbol with non zero length */
  98        a = syma->end - syma->start;
  99        b = symb->end - symb->start;
 100        if ((b == 0) && (a > 0))
 101                return SYMBOL_A;
 102        else if ((a == 0) && (b > 0))
 103                return SYMBOL_B;
 104
 105        /* Prefer a non weak symbol over a weak one */
 106        a = syma->binding == STB_WEAK;
 107        b = symb->binding == STB_WEAK;
 108        if (b && !a)
 109                return SYMBOL_A;
 110        if (a && !b)
 111                return SYMBOL_B;
 112
 113        /* Prefer a global symbol over a non global one */
 114        a = syma->binding == STB_GLOBAL;
 115        b = symb->binding == STB_GLOBAL;
 116        if (a && !b)
 117                return SYMBOL_A;
 118        if (b && !a)
 119                return SYMBOL_B;
 120
 121        /* Prefer a symbol with less underscores */
 122        a = prefix_underscores_count(syma->name);
 123        b = prefix_underscores_count(symb->name);
 124        if (b > a)
 125                return SYMBOL_A;
 126        else if (a > b)
 127                return SYMBOL_B;
 128
 129        /* Choose the symbol with the longest name */
 130        na = strlen(syma->name);
 131        nb = strlen(symb->name);
 132        if (na > nb)
 133                return SYMBOL_A;
 134        else if (na < nb)
 135                return SYMBOL_B;
 136
 137        /* Avoid "SyS" kernel syscall aliases */
 138        if (na >= 3 && !strncmp(syma->name, "SyS", 3))
 139                return SYMBOL_B;
 140        if (na >= 10 && !strncmp(syma->name, "compat_SyS", 10))
 141                return SYMBOL_B;
 142
 143        return SYMBOL_A;
 144}
 145
 146void symbols__fixup_duplicate(struct rb_root *symbols)
 147{
 148        struct rb_node *nd;
 149        struct symbol *curr, *next;
 150
 151        nd = rb_first(symbols);
 152
 153        while (nd) {
 154                curr = rb_entry(nd, struct symbol, rb_node);
 155again:
 156                nd = rb_next(&curr->rb_node);
 157                next = rb_entry(nd, struct symbol, rb_node);
 158
 159                if (!nd)
 160                        break;
 161
 162                if (curr->start != next->start)
 163                        continue;
 164
 165                if (choose_best_symbol(curr, next) == SYMBOL_A) {
 166                        rb_erase(&next->rb_node, symbols);
 167                        symbol__delete(next);
 168                        goto again;
 169                } else {
 170                        nd = rb_next(&curr->rb_node);
 171                        rb_erase(&curr->rb_node, symbols);
 172                        symbol__delete(curr);
 173                }
 174        }
 175}
 176
 177void symbols__fixup_end(struct rb_root *symbols)
 178{
 179        struct rb_node *nd, *prevnd = rb_first(symbols);
 180        struct symbol *curr, *prev;
 181
 182        if (prevnd == NULL)
 183                return;
 184
 185        curr = rb_entry(prevnd, struct symbol, rb_node);
 186
 187        for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
 188                prev = curr;
 189                curr = rb_entry(nd, struct symbol, rb_node);
 190
 191                if (prev->end == prev->start && prev->end != curr->start)
 192                        prev->end = curr->start;
 193        }
 194
 195        /* Last entry */
 196        if (curr->end == curr->start)
 197                curr->end = roundup(curr->start, 4096);
 198}
 199
 200void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
 201{
 202        struct map *prev, *curr;
 203        struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
 204
 205        if (prevnd == NULL)
 206                return;
 207
 208        curr = rb_entry(prevnd, struct map, rb_node);
 209
 210        for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
 211                prev = curr;
 212                curr = rb_entry(nd, struct map, rb_node);
 213                prev->end = curr->start;
 214        }
 215
 216        /*
 217         * We still haven't the actual symbols, so guess the
 218         * last map final address.
 219         */
 220        curr->end = ~0ULL;
 221}
 222
 223struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
 224{
 225        size_t namelen = strlen(name) + 1;
 226        struct symbol *sym = calloc(1, (symbol_conf.priv_size +
 227                                        sizeof(*sym) + namelen));
 228        if (sym == NULL)
 229                return NULL;
 230
 231        if (symbol_conf.priv_size)
 232                sym = ((void *)sym) + symbol_conf.priv_size;
 233
 234        sym->start   = start;
 235        sym->end     = len ? start + len : start;
 236        sym->binding = binding;
 237        sym->namelen = namelen - 1;
 238
 239        pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
 240                  __func__, name, start, sym->end);
 241        memcpy(sym->name, name, namelen);
 242
 243        return sym;
 244}
 245
 246void symbol__delete(struct symbol *sym)
 247{
 248        free(((void *)sym) - symbol_conf.priv_size);
 249}
 250
 251size_t symbol__fprintf(struct symbol *sym, FILE *fp)
 252{
 253        return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
 254                       sym->start, sym->end,
 255                       sym->binding == STB_GLOBAL ? 'g' :
 256                       sym->binding == STB_LOCAL  ? 'l' : 'w',
 257                       sym->name);
 258}
 259
 260size_t symbol__fprintf_symname_offs(const struct symbol *sym,
 261                                    const struct addr_location *al, FILE *fp)
 262{
 263        unsigned long offset;
 264        size_t length;
 265
 266        if (sym && sym->name) {
 267                length = fprintf(fp, "%s", sym->name);
 268                if (al) {
 269                        if (al->addr < sym->end)
 270                                offset = al->addr - sym->start;
 271                        else
 272                                offset = al->addr - al->map->start - sym->start;
 273                        length += fprintf(fp, "+0x%lx", offset);
 274                }
 275                return length;
 276        } else
 277                return fprintf(fp, "[unknown]");
 278}
 279
 280size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
 281{
 282        return symbol__fprintf_symname_offs(sym, NULL, fp);
 283}
 284
 285void symbols__delete(struct rb_root *symbols)
 286{
 287        struct symbol *pos;
 288        struct rb_node *next = rb_first(symbols);
 289
 290        while (next) {
 291                pos = rb_entry(next, struct symbol, rb_node);
 292                next = rb_next(&pos->rb_node);
 293                rb_erase(&pos->rb_node, symbols);
 294                symbol__delete(pos);
 295        }
 296}
 297
 298void symbols__insert(struct rb_root *symbols, struct symbol *sym)
 299{
 300        struct rb_node **p = &symbols->rb_node;
 301        struct rb_node *parent = NULL;
 302        const u64 ip = sym->start;
 303        struct symbol *s;
 304
 305        while (*p != NULL) {
 306                parent = *p;
 307                s = rb_entry(parent, struct symbol, rb_node);
 308                if (ip < s->start)
 309                        p = &(*p)->rb_left;
 310                else
 311                        p = &(*p)->rb_right;
 312        }
 313        rb_link_node(&sym->rb_node, parent, p);
 314        rb_insert_color(&sym->rb_node, symbols);
 315}
 316
 317static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
 318{
 319        struct rb_node *n;
 320
 321        if (symbols == NULL)
 322                return NULL;
 323
 324        n = symbols->rb_node;
 325
 326        while (n) {
 327                struct symbol *s = rb_entry(n, struct symbol, rb_node);
 328
 329                if (ip < s->start)
 330                        n = n->rb_left;
 331                else if (ip >= s->end)
 332                        n = n->rb_right;
 333                else
 334                        return s;
 335        }
 336
 337        return NULL;
 338}
 339
 340static struct symbol *symbols__first(struct rb_root *symbols)
 341{
 342        struct rb_node *n = rb_first(symbols);
 343
 344        if (n)
 345                return rb_entry(n, struct symbol, rb_node);
 346
 347        return NULL;
 348}
 349
 350static struct symbol *symbols__next(struct symbol *sym)
 351{
 352        struct rb_node *n = rb_next(&sym->rb_node);
 353
 354        if (n)
 355                return rb_entry(n, struct symbol, rb_node);
 356
 357        return NULL;
 358}
 359
 360struct symbol_name_rb_node {
 361        struct rb_node  rb_node;
 362        struct symbol   sym;
 363};
 364
 365static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
 366{
 367        struct rb_node **p = &symbols->rb_node;
 368        struct rb_node *parent = NULL;
 369        struct symbol_name_rb_node *symn, *s;
 370
 371        symn = container_of(sym, struct symbol_name_rb_node, sym);
 372
 373        while (*p != NULL) {
 374                parent = *p;
 375                s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
 376                if (strcmp(sym->name, s->sym.name) < 0)
 377                        p = &(*p)->rb_left;
 378                else
 379                        p = &(*p)->rb_right;
 380        }
 381        rb_link_node(&symn->rb_node, parent, p);
 382        rb_insert_color(&symn->rb_node, symbols);
 383}
 384
 385static void symbols__sort_by_name(struct rb_root *symbols,
 386                                  struct rb_root *source)
 387{
 388        struct rb_node *nd;
 389
 390        for (nd = rb_first(source); nd; nd = rb_next(nd)) {
 391                struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
 392                symbols__insert_by_name(symbols, pos);
 393        }
 394}
 395
 396static struct symbol *symbols__find_by_name(struct rb_root *symbols,
 397                                            const char *name)
 398{
 399        struct rb_node *n;
 400        struct symbol_name_rb_node *s;
 401
 402        if (symbols == NULL)
 403                return NULL;
 404
 405        n = symbols->rb_node;
 406
 407        while (n) {
 408                int cmp;
 409
 410                s = rb_entry(n, struct symbol_name_rb_node, rb_node);
 411                cmp = strcmp(name, s->sym.name);
 412
 413                if (cmp < 0)
 414                        n = n->rb_left;
 415                else if (cmp > 0)
 416                        n = n->rb_right;
 417                else
 418                        break;
 419        }
 420
 421        if (n == NULL)
 422                return NULL;
 423
 424        /* return first symbol that has same name (if any) */
 425        for (n = rb_prev(n); n; n = rb_prev(n)) {
 426                struct symbol_name_rb_node *tmp;
 427
 428                tmp = rb_entry(n, struct symbol_name_rb_node, rb_node);
 429                if (strcmp(tmp->sym.name, s->sym.name))
 430                        break;
 431
 432                s = tmp;
 433        }
 434
 435        return &s->sym;
 436}
 437
 438struct symbol *dso__find_symbol(struct dso *dso,
 439                                enum map_type type, u64 addr)
 440{
 441        return symbols__find(&dso->symbols[type], addr);
 442}
 443
 444struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
 445{
 446        return symbols__first(&dso->symbols[type]);
 447}
 448
 449struct symbol *dso__next_symbol(struct symbol *sym)
 450{
 451        return symbols__next(sym);
 452}
 453
 454struct symbol *symbol__next_by_name(struct symbol *sym)
 455{
 456        struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym);
 457        struct rb_node *n = rb_next(&s->rb_node);
 458
 459        return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL;
 460}
 461
 462 /*
 463  * Teturns first symbol that matched with @name.
 464  */
 465struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 466                                        const char *name)
 467{
 468        return symbols__find_by_name(&dso->symbol_names[type], name);
 469}
 470
 471void dso__sort_by_name(struct dso *dso, enum map_type type)
 472{
 473        dso__set_sorted_by_name(dso, type);
 474        return symbols__sort_by_name(&dso->symbol_names[type],
 475                                     &dso->symbols[type]);
 476}
 477
 478size_t dso__fprintf_symbols_by_name(struct dso *dso,
 479                                    enum map_type type, FILE *fp)
 480{
 481        size_t ret = 0;
 482        struct rb_node *nd;
 483        struct symbol_name_rb_node *pos;
 484
 485        for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
 486                pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
 487                fprintf(fp, "%s\n", pos->sym.name);
 488        }
 489
 490        return ret;
 491}
 492
 493int modules__parse(const char *filename, void *arg,
 494                   int (*process_module)(void *arg, const char *name,
 495                                         u64 start))
 496{
 497        char *line = NULL;
 498        size_t n;
 499        FILE *file;
 500        int err = 0;
 501
 502        file = fopen(filename, "r");
 503        if (file == NULL)
 504                return -1;
 505
 506        while (1) {
 507                char name[PATH_MAX];
 508                u64 start;
 509                char *sep;
 510                ssize_t line_len;
 511
 512                line_len = getline(&line, &n, file);
 513                if (line_len < 0) {
 514                        if (feof(file))
 515                                break;
 516                        err = -1;
 517                        goto out;
 518                }
 519
 520                if (!line) {
 521                        err = -1;
 522                        goto out;
 523                }
 524
 525                line[--line_len] = '\0'; /* \n */
 526
 527                sep = strrchr(line, 'x');
 528                if (sep == NULL)
 529                        continue;
 530
 531                hex2u64(sep + 1, &start);
 532
 533                sep = strchr(line, ' ');
 534                if (sep == NULL)
 535                        continue;
 536
 537                *sep = '\0';
 538
 539                scnprintf(name, sizeof(name), "[%s]", line);
 540
 541                err = process_module(arg, name, start);
 542                if (err)
 543                        break;
 544        }
 545out:
 546        free(line);
 547        fclose(file);
 548        return err;
 549}
 550
 551struct process_kallsyms_args {
 552        struct map *map;
 553        struct dso *dso;
 554};
 555
 556/*
 557 * These are symbols in the kernel image, so make sure that
 558 * sym is from a kernel DSO.
 559 */
 560bool symbol__is_idle(struct symbol *sym)
 561{
 562        const char * const idle_symbols[] = {
 563                "cpu_idle",
 564                "cpu_startup_entry",
 565                "intel_idle",
 566                "default_idle",
 567                "native_safe_halt",
 568                "enter_idle",
 569                "exit_idle",
 570                "mwait_idle",
 571                "mwait_idle_with_hints",
 572                "poll_idle",
 573                "ppc64_runlatch_off",
 574                "pseries_dedicated_idle_sleep",
 575                NULL
 576        };
 577
 578        int i;
 579
 580        if (!sym)
 581                return false;
 582
 583        for (i = 0; idle_symbols[i]; i++) {
 584                if (!strcmp(idle_symbols[i], sym->name))
 585                        return true;
 586        }
 587
 588        return false;
 589}
 590
 591static int map__process_kallsym_symbol(void *arg, const char *name,
 592                                       char type, u64 start)
 593{
 594        struct symbol *sym;
 595        struct process_kallsyms_args *a = arg;
 596        struct rb_root *root = &a->dso->symbols[a->map->type];
 597
 598        if (!symbol_type__is_a(type, a->map->type))
 599                return 0;
 600
 601        /*
 602         * module symbols are not sorted so we add all
 603         * symbols, setting length to 0, and rely on
 604         * symbols__fixup_end() to fix it up.
 605         */
 606        sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
 607        if (sym == NULL)
 608                return -ENOMEM;
 609        /*
 610         * We will pass the symbols to the filter later, in
 611         * map__split_kallsyms, when we have split the maps per module
 612         */
 613        symbols__insert(root, sym);
 614
 615        return 0;
 616}
 617
 618/*
 619 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
 620 * so that we can in the next step set the symbol ->end address and then
 621 * call kernel_maps__split_kallsyms.
 622 */
 623static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
 624                                  struct map *map)
 625{
 626        struct process_kallsyms_args args = { .map = map, .dso = dso, };
 627        return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
 628}
 629
 630static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
 631                                         symbol_filter_t filter)
 632{
 633        struct map_groups *kmaps = map__kmaps(map);
 634        struct map *curr_map;
 635        struct symbol *pos;
 636        int count = 0, moved = 0;
 637        struct rb_root *root = &dso->symbols[map->type];
 638        struct rb_node *next = rb_first(root);
 639
 640        if (!kmaps)
 641                return -1;
 642
 643        while (next) {
 644                char *module;
 645
 646                pos = rb_entry(next, struct symbol, rb_node);
 647                next = rb_next(&pos->rb_node);
 648
 649                module = strchr(pos->name, '\t');
 650                if (module)
 651                        *module = '\0';
 652
 653                curr_map = map_groups__find(kmaps, map->type, pos->start);
 654
 655                if (!curr_map || (filter && filter(curr_map, pos))) {
 656                        rb_erase(&pos->rb_node, root);
 657                        symbol__delete(pos);
 658                } else {
 659                        pos->start -= curr_map->start - curr_map->pgoff;
 660                        if (pos->end)
 661                                pos->end -= curr_map->start - curr_map->pgoff;
 662                        if (curr_map != map) {
 663                                rb_erase(&pos->rb_node, root);
 664                                symbols__insert(
 665                                        &curr_map->dso->symbols[curr_map->type],
 666                                        pos);
 667                                ++moved;
 668                        } else {
 669                                ++count;
 670                        }
 671                }
 672        }
 673
 674        /* Symbols have been adjusted */
 675        dso->adjust_symbols = 1;
 676
 677        return count + moved;
 678}
 679
 680/*
 681 * Split the symbols into maps, making sure there are no overlaps, i.e. the
 682 * kernel range is broken in several maps, named [kernel].N, as we don't have
 683 * the original ELF section names vmlinux have.
 684 */
 685static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta,
 686                               symbol_filter_t filter)
 687{
 688        struct map_groups *kmaps = map__kmaps(map);
 689        struct machine *machine;
 690        struct map *curr_map = map;
 691        struct symbol *pos;
 692        int count = 0, moved = 0;
 693        struct rb_root *root = &dso->symbols[map->type];
 694        struct rb_node *next = rb_first(root);
 695        int kernel_range = 0;
 696
 697        if (!kmaps)
 698                return -1;
 699
 700        machine = kmaps->machine;
 701
 702        while (next) {
 703                char *module;
 704
 705                pos = rb_entry(next, struct symbol, rb_node);
 706                next = rb_next(&pos->rb_node);
 707
 708                module = strchr(pos->name, '\t');
 709                if (module) {
 710                        if (!symbol_conf.use_modules)
 711                                goto discard_symbol;
 712
 713                        *module++ = '\0';
 714
 715                        if (strcmp(curr_map->dso->short_name, module)) {
 716                                if (curr_map != map &&
 717                                    dso->kernel == DSO_TYPE_GUEST_KERNEL &&
 718                                    machine__is_default_guest(machine)) {
 719                                        /*
 720                                         * We assume all symbols of a module are
 721                                         * continuous in * kallsyms, so curr_map
 722                                         * points to a module and all its
 723                                         * symbols are in its kmap. Mark it as
 724                                         * loaded.
 725                                         */
 726                                        dso__set_loaded(curr_map->dso,
 727                                                        curr_map->type);
 728                                }
 729
 730                                curr_map = map_groups__find_by_name(kmaps,
 731                                                        map->type, module);
 732                                if (curr_map == NULL) {
 733                                        pr_debug("%s/proc/{kallsyms,modules} "
 734                                                 "inconsistency while looking "
 735                                                 "for \"%s\" module!\n",
 736                                                 machine->root_dir, module);
 737                                        curr_map = map;
 738                                        goto discard_symbol;
 739                                }
 740
 741                                if (curr_map->dso->loaded &&
 742                                    !machine__is_default_guest(machine))
 743                                        goto discard_symbol;
 744                        }
 745                        /*
 746                         * So that we look just like we get from .ko files,
 747                         * i.e. not prelinked, relative to map->start.
 748                         */
 749                        pos->start = curr_map->map_ip(curr_map, pos->start);
 750                        pos->end   = curr_map->map_ip(curr_map, pos->end);
 751                } else if (curr_map != map) {
 752                        char dso_name[PATH_MAX];
 753                        struct dso *ndso;
 754
 755                        if (delta) {
 756                                /* Kernel was relocated at boot time */
 757                                pos->start -= delta;
 758                                pos->end -= delta;
 759                        }
 760
 761                        if (count == 0) {
 762                                curr_map = map;
 763                                goto filter_symbol;
 764                        }
 765
 766                        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
 767                                snprintf(dso_name, sizeof(dso_name),
 768                                        "[guest.kernel].%d",
 769                                        kernel_range++);
 770                        else
 771                                snprintf(dso_name, sizeof(dso_name),
 772                                        "[kernel].%d",
 773                                        kernel_range++);
 774
 775                        ndso = dso__new(dso_name);
 776                        if (ndso == NULL)
 777                                return -1;
 778
 779                        ndso->kernel = dso->kernel;
 780
 781                        curr_map = map__new2(pos->start, ndso, map->type);
 782                        if (curr_map == NULL) {
 783                                dso__delete(ndso);
 784                                return -1;
 785                        }
 786
 787                        curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
 788                        map_groups__insert(kmaps, curr_map);
 789                        ++kernel_range;
 790                } else if (delta) {
 791                        /* Kernel was relocated at boot time */
 792                        pos->start -= delta;
 793                        pos->end -= delta;
 794                }
 795filter_symbol:
 796                if (filter && filter(curr_map, pos)) {
 797discard_symbol:         rb_erase(&pos->rb_node, root);
 798                        symbol__delete(pos);
 799                } else {
 800                        if (curr_map != map) {
 801                                rb_erase(&pos->rb_node, root);
 802                                symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
 803                                ++moved;
 804                        } else
 805                                ++count;
 806                }
 807        }
 808
 809        if (curr_map != map &&
 810            dso->kernel == DSO_TYPE_GUEST_KERNEL &&
 811            machine__is_default_guest(kmaps->machine)) {
 812                dso__set_loaded(curr_map->dso, curr_map->type);
 813        }
 814
 815        return count + moved;
 816}
 817
 818bool symbol__restricted_filename(const char *filename,
 819                                 const char *restricted_filename)
 820{
 821        bool restricted = false;
 822
 823        if (symbol_conf.kptr_restrict) {
 824                char *r = realpath(filename, NULL);
 825
 826                if (r != NULL) {
 827                        restricted = strcmp(r, restricted_filename) == 0;
 828                        free(r);
 829                        return restricted;
 830                }
 831        }
 832
 833        return restricted;
 834}
 835
 836struct module_info {
 837        struct rb_node rb_node;
 838        char *name;
 839        u64 start;
 840};
 841
 842static void add_module(struct module_info *mi, struct rb_root *modules)
 843{
 844        struct rb_node **p = &modules->rb_node;
 845        struct rb_node *parent = NULL;
 846        struct module_info *m;
 847
 848        while (*p != NULL) {
 849                parent = *p;
 850                m = rb_entry(parent, struct module_info, rb_node);
 851                if (strcmp(mi->name, m->name) < 0)
 852                        p = &(*p)->rb_left;
 853                else
 854                        p = &(*p)->rb_right;
 855        }
 856        rb_link_node(&mi->rb_node, parent, p);
 857        rb_insert_color(&mi->rb_node, modules);
 858}
 859
 860static void delete_modules(struct rb_root *modules)
 861{
 862        struct module_info *mi;
 863        struct rb_node *next = rb_first(modules);
 864
 865        while (next) {
 866                mi = rb_entry(next, struct module_info, rb_node);
 867                next = rb_next(&mi->rb_node);
 868                rb_erase(&mi->rb_node, modules);
 869                zfree(&mi->name);
 870                free(mi);
 871        }
 872}
 873
 874static struct module_info *find_module(const char *name,
 875                                       struct rb_root *modules)
 876{
 877        struct rb_node *n = modules->rb_node;
 878
 879        while (n) {
 880                struct module_info *m;
 881                int cmp;
 882
 883                m = rb_entry(n, struct module_info, rb_node);
 884                cmp = strcmp(name, m->name);
 885                if (cmp < 0)
 886                        n = n->rb_left;
 887                else if (cmp > 0)
 888                        n = n->rb_right;
 889                else
 890                        return m;
 891        }
 892
 893        return NULL;
 894}
 895
 896static int __read_proc_modules(void *arg, const char *name, u64 start)
 897{
 898        struct rb_root *modules = arg;
 899        struct module_info *mi;
 900
 901        mi = zalloc(sizeof(struct module_info));
 902        if (!mi)
 903                return -ENOMEM;
 904
 905        mi->name = strdup(name);
 906        mi->start = start;
 907
 908        if (!mi->name) {
 909                free(mi);
 910                return -ENOMEM;
 911        }
 912
 913        add_module(mi, modules);
 914
 915        return 0;
 916}
 917
 918static int read_proc_modules(const char *filename, struct rb_root *modules)
 919{
 920        if (symbol__restricted_filename(filename, "/proc/modules"))
 921                return -1;
 922
 923        if (modules__parse(filename, modules, __read_proc_modules)) {
 924                delete_modules(modules);
 925                return -1;
 926        }
 927
 928        return 0;
 929}
 930
 931int compare_proc_modules(const char *from, const char *to)
 932{
 933        struct rb_root from_modules = RB_ROOT;
 934        struct rb_root to_modules = RB_ROOT;
 935        struct rb_node *from_node, *to_node;
 936        struct module_info *from_m, *to_m;
 937        int ret = -1;
 938
 939        if (read_proc_modules(from, &from_modules))
 940                return -1;
 941
 942        if (read_proc_modules(to, &to_modules))
 943                goto out_delete_from;
 944
 945        from_node = rb_first(&from_modules);
 946        to_node = rb_first(&to_modules);
 947        while (from_node) {
 948                if (!to_node)
 949                        break;
 950
 951                from_m = rb_entry(from_node, struct module_info, rb_node);
 952                to_m = rb_entry(to_node, struct module_info, rb_node);
 953
 954                if (from_m->start != to_m->start ||
 955                    strcmp(from_m->name, to_m->name))
 956                        break;
 957
 958                from_node = rb_next(from_node);
 959                to_node = rb_next(to_node);
 960        }
 961
 962        if (!from_node && !to_node)
 963                ret = 0;
 964
 965        delete_modules(&to_modules);
 966out_delete_from:
 967        delete_modules(&from_modules);
 968
 969        return ret;
 970}
 971
 972static int do_validate_kcore_modules(const char *filename, struct map *map,
 973                                  struct map_groups *kmaps)
 974{
 975        struct rb_root modules = RB_ROOT;
 976        struct map *old_map;
 977        int err;
 978
 979        err = read_proc_modules(filename, &modules);
 980        if (err)
 981                return err;
 982
 983        old_map = map_groups__first(kmaps, map->type);
 984        while (old_map) {
 985                struct map *next = map_groups__next(old_map);
 986                struct module_info *mi;
 987
 988                if (old_map == map || old_map->start == map->start) {
 989                        /* The kernel map */
 990                        old_map = next;
 991                        continue;
 992                }
 993
 994                /* Module must be in memory at the same address */
 995                mi = find_module(old_map->dso->short_name, &modules);
 996                if (!mi || mi->start != old_map->start) {
 997                        err = -EINVAL;
 998                        goto out;
 999                }
1000
1001                old_map = next;
1002        }
1003out:
1004        delete_modules(&modules);
1005        return err;
1006}
1007
1008/*
1009 * If kallsyms is referenced by name then we look for filename in the same
1010 * directory.
1011 */
1012static bool filename_from_kallsyms_filename(char *filename,
1013                                            const char *base_name,
1014                                            const char *kallsyms_filename)
1015{
1016        char *name;
1017
1018        strcpy(filename, kallsyms_filename);
1019        name = strrchr(filename, '/');
1020        if (!name)
1021                return false;
1022
1023        name += 1;
1024
1025        if (!strcmp(name, "kallsyms")) {
1026                strcpy(name, base_name);
1027                return true;
1028        }
1029
1030        return false;
1031}
1032
1033static int validate_kcore_modules(const char *kallsyms_filename,
1034                                  struct map *map)
1035{
1036        struct map_groups *kmaps = map__kmaps(map);
1037        char modules_filename[PATH_MAX];
1038
1039        if (!kmaps)
1040                return -EINVAL;
1041
1042        if (!filename_from_kallsyms_filename(modules_filename, "modules",
1043                                             kallsyms_filename))
1044                return -EINVAL;
1045
1046        if (do_validate_kcore_modules(modules_filename, map, kmaps))
1047                return -EINVAL;
1048
1049        return 0;
1050}
1051
1052static int validate_kcore_addresses(const char *kallsyms_filename,
1053                                    struct map *map)
1054{
1055        struct kmap *kmap = map__kmap(map);
1056
1057        if (!kmap)
1058                return -EINVAL;
1059
1060        if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
1061                u64 start;
1062
1063                start = kallsyms__get_function_start(kallsyms_filename,
1064                                                     kmap->ref_reloc_sym->name);
1065                if (start != kmap->ref_reloc_sym->addr)
1066                        return -EINVAL;
1067        }
1068
1069        return validate_kcore_modules(kallsyms_filename, map);
1070}
1071
1072struct kcore_mapfn_data {
1073        struct dso *dso;
1074        enum map_type type;
1075        struct list_head maps;
1076};
1077
1078static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
1079{
1080        struct kcore_mapfn_data *md = data;
1081        struct map *map;
1082
1083        map = map__new2(start, md->dso, md->type);
1084        if (map == NULL)
1085                return -ENOMEM;
1086
1087        map->end = map->start + len;
1088        map->pgoff = pgoff;
1089
1090        list_add(&map->node, &md->maps);
1091
1092        return 0;
1093}
1094
1095static int dso__load_kcore(struct dso *dso, struct map *map,
1096                           const char *kallsyms_filename)
1097{
1098        struct map_groups *kmaps = map__kmaps(map);
1099        struct machine *machine;
1100        struct kcore_mapfn_data md;
1101        struct map *old_map, *new_map, *replacement_map = NULL;
1102        bool is_64_bit;
1103        int err, fd;
1104        char kcore_filename[PATH_MAX];
1105        struct symbol *sym;
1106
1107        if (!kmaps)
1108                return -EINVAL;
1109
1110        machine = kmaps->machine;
1111
1112        /* This function requires that the map is the kernel map */
1113        if (map != machine->vmlinux_maps[map->type])
1114                return -EINVAL;
1115
1116        if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
1117                                             kallsyms_filename))
1118                return -EINVAL;
1119
1120        /* Modules and kernel must be present at their original addresses */
1121        if (validate_kcore_addresses(kallsyms_filename, map))
1122                return -EINVAL;
1123
1124        md.dso = dso;
1125        md.type = map->type;
1126        INIT_LIST_HEAD(&md.maps);
1127
1128        fd = open(kcore_filename, O_RDONLY);
1129        if (fd < 0)
1130                return -EINVAL;
1131
1132        /* Read new maps into temporary lists */
1133        err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md,
1134                              &is_64_bit);
1135        if (err)
1136                goto out_err;
1137        dso->is_64_bit = is_64_bit;
1138
1139        if (list_empty(&md.maps)) {
1140                err = -EINVAL;
1141                goto out_err;
1142        }
1143
1144        /* Remove old maps */
1145        old_map = map_groups__first(kmaps, map->type);
1146        while (old_map) {
1147                struct map *next = map_groups__next(old_map);
1148
1149                if (old_map != map)
1150                        map_groups__remove(kmaps, old_map);
1151                old_map = next;
1152        }
1153
1154        /* Find the kernel map using the first symbol */
1155        sym = dso__first_symbol(dso, map->type);
1156        list_for_each_entry(new_map, &md.maps, node) {
1157                if (sym && sym->start >= new_map->start &&
1158                    sym->start < new_map->end) {
1159                        replacement_map = new_map;
1160                        break;
1161                }
1162        }
1163
1164        if (!replacement_map)
1165                replacement_map = list_entry(md.maps.next, struct map, node);
1166
1167        /* Add new maps */
1168        while (!list_empty(&md.maps)) {
1169                new_map = list_entry(md.maps.next, struct map, node);
1170                list_del(&new_map->node);
1171                if (new_map == replacement_map) {
1172                        map->start      = new_map->start;
1173                        map->end        = new_map->end;
1174                        map->pgoff      = new_map->pgoff;
1175                        map->map_ip     = new_map->map_ip;
1176                        map->unmap_ip   = new_map->unmap_ip;
1177                        map__delete(new_map);
1178                        /* Ensure maps are correctly ordered */
1179                        map_groups__remove(kmaps, map);
1180                        map_groups__insert(kmaps, map);
1181                } else {
1182                        map_groups__insert(kmaps, new_map);
1183                }
1184        }
1185
1186        /*
1187         * Set the data type and long name so that kcore can be read via
1188         * dso__data_read_addr().
1189         */
1190        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1191                dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE;
1192        else
1193                dso->binary_type = DSO_BINARY_TYPE__KCORE;
1194        dso__set_long_name(dso, strdup(kcore_filename), true);
1195
1196        close(fd);
1197
1198        if (map->type == MAP__FUNCTION)
1199                pr_debug("Using %s for kernel object code\n", kcore_filename);
1200        else
1201                pr_debug("Using %s for kernel data\n", kcore_filename);
1202
1203        return 0;
1204
1205out_err:
1206        while (!list_empty(&md.maps)) {
1207                map = list_entry(md.maps.next, struct map, node);
1208                list_del(&map->node);
1209                map__delete(map);
1210        }
1211        close(fd);
1212        return -EINVAL;
1213}
1214
1215/*
1216 * If the kernel is relocated at boot time, kallsyms won't match.  Compute the
1217 * delta based on the relocation reference symbol.
1218 */
1219static int kallsyms__delta(struct map *map, const char *filename, u64 *delta)
1220{
1221        struct kmap *kmap = map__kmap(map);
1222        u64 addr;
1223
1224        if (!kmap)
1225                return -1;
1226
1227        if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
1228                return 0;
1229
1230        addr = kallsyms__get_function_start(filename,
1231                                            kmap->ref_reloc_sym->name);
1232        if (!addr)
1233                return -1;
1234
1235        *delta = addr - kmap->ref_reloc_sym->addr;
1236        return 0;
1237}
1238
1239int dso__load_kallsyms(struct dso *dso, const char *filename,
1240                       struct map *map, symbol_filter_t filter)
1241{
1242        u64 delta = 0;
1243
1244        if (symbol__restricted_filename(filename, "/proc/kallsyms"))
1245                return -1;
1246
1247        if (dso__load_all_kallsyms(dso, filename, map) < 0)
1248                return -1;
1249
1250        if (kallsyms__delta(map, filename, &delta))
1251                return -1;
1252
1253        symbols__fixup_duplicate(&dso->symbols[map->type]);
1254        symbols__fixup_end(&dso->symbols[map->type]);
1255
1256        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1257                dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
1258        else
1259                dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
1260
1261        if (!dso__load_kcore(dso, map, filename))
1262                return dso__split_kallsyms_for_kcore(dso, map, filter);
1263        else
1264                return dso__split_kallsyms(dso, map, delta, filter);
1265}
1266
1267static int dso__load_perf_map(struct dso *dso, struct map *map,
1268                              symbol_filter_t filter)
1269{
1270        char *line = NULL;
1271        size_t n;
1272        FILE *file;
1273        int nr_syms = 0;
1274
1275        file = fopen(dso->long_name, "r");
1276        if (file == NULL)
1277                goto out_failure;
1278
1279        while (!feof(file)) {
1280                u64 start, size;
1281                struct symbol *sym;
1282                int line_len, len;
1283
1284                line_len = getline(&line, &n, file);
1285                if (line_len < 0)
1286                        break;
1287
1288                if (!line)
1289                        goto out_failure;
1290
1291                line[--line_len] = '\0'; /* \n */
1292
1293                len = hex2u64(line, &start);
1294
1295                len++;
1296                if (len + 2 >= line_len)
1297                        continue;
1298
1299                len += hex2u64(line + len, &size);
1300
1301                len++;
1302                if (len + 2 >= line_len)
1303                        continue;
1304
1305                sym = symbol__new(start, size, STB_GLOBAL, line + len);
1306
1307                if (sym == NULL)
1308                        goto out_delete_line;
1309
1310                if (filter && filter(map, sym))
1311                        symbol__delete(sym);
1312                else {
1313                        symbols__insert(&dso->symbols[map->type], sym);
1314                        nr_syms++;
1315                }
1316        }
1317
1318        free(line);
1319        fclose(file);
1320
1321        return nr_syms;
1322
1323out_delete_line:
1324        free(line);
1325out_failure:
1326        return -1;
1327}
1328
1329static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
1330                                           enum dso_binary_type type)
1331{
1332        switch (type) {
1333        case DSO_BINARY_TYPE__JAVA_JIT:
1334        case DSO_BINARY_TYPE__DEBUGLINK:
1335        case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
1336        case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
1337        case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
1338        case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
1339        case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
1340                return !kmod && dso->kernel == DSO_TYPE_USER;
1341
1342        case DSO_BINARY_TYPE__KALLSYMS:
1343        case DSO_BINARY_TYPE__VMLINUX:
1344        case DSO_BINARY_TYPE__KCORE:
1345                return dso->kernel == DSO_TYPE_KERNEL;
1346
1347        case DSO_BINARY_TYPE__GUEST_KALLSYMS:
1348        case DSO_BINARY_TYPE__GUEST_VMLINUX:
1349        case DSO_BINARY_TYPE__GUEST_KCORE:
1350                return dso->kernel == DSO_TYPE_GUEST_KERNEL;
1351
1352        case DSO_BINARY_TYPE__GUEST_KMODULE:
1353        case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
1354        case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
1355        case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
1356                /*
1357                 * kernel modules know their symtab type - it's set when
1358                 * creating a module dso in machine__new_module().
1359                 */
1360                return kmod && dso->symtab_type == type;
1361
1362        case DSO_BINARY_TYPE__BUILD_ID_CACHE:
1363                return true;
1364
1365        case DSO_BINARY_TYPE__NOT_FOUND:
1366        default:
1367                return false;
1368        }
1369}
1370
1371int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1372{
1373        char *name;
1374        int ret = -1;
1375        u_int i;
1376        struct machine *machine;
1377        char *root_dir = (char *) "";
1378        int ss_pos = 0;
1379        struct symsrc ss_[2];
1380        struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
1381        bool kmod;
1382
1383        dso__set_loaded(dso, map->type);
1384
1385        if (dso->kernel == DSO_TYPE_KERNEL)
1386                return dso__load_kernel_sym(dso, map, filter);
1387        else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1388                return dso__load_guest_kernel_sym(dso, map, filter);
1389
1390        if (map->groups && map->groups->machine)
1391                machine = map->groups->machine;
1392        else
1393                machine = NULL;
1394
1395        dso->adjust_symbols = 0;
1396
1397        if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1398                struct stat st;
1399
1400                if (lstat(dso->name, &st) < 0)
1401                        return -1;
1402
1403                if (st.st_uid && (st.st_uid != geteuid())) {
1404                        pr_warning("File %s not owned by current user or root, "
1405                                "ignoring it.\n", dso->name);
1406                        return -1;
1407                }
1408
1409                ret = dso__load_perf_map(dso, map, filter);
1410                dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
1411                                             DSO_BINARY_TYPE__NOT_FOUND;
1412                return ret;
1413        }
1414
1415        if (machine)
1416                root_dir = machine->root_dir;
1417
1418        name = malloc(PATH_MAX);
1419        if (!name)
1420                return -1;
1421
1422        kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
1423                dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
1424                dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
1425                dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
1426
1427        /*
1428         * Iterate over candidate debug images.
1429         * Keep track of "interesting" ones (those which have a symtab, dynsym,
1430         * and/or opd section) for processing.
1431         */
1432        for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
1433                struct symsrc *ss = &ss_[ss_pos];
1434                bool next_slot = false;
1435
1436                enum dso_binary_type symtab_type = binary_type_symtab[i];
1437
1438                if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
1439                        continue;
1440
1441                if (dso__read_binary_type_filename(dso, symtab_type,
1442                                                   root_dir, name, PATH_MAX))
1443                        continue;
1444
1445                /* Name is now the name of the next image to try */
1446                if (symsrc__init(ss, dso, name, symtab_type) < 0)
1447                        continue;
1448
1449                if (!syms_ss && symsrc__has_symtab(ss)) {
1450                        syms_ss = ss;
1451                        next_slot = true;
1452                        if (!dso->symsrc_filename)
1453                                dso->symsrc_filename = strdup(name);
1454                }
1455
1456                if (!runtime_ss && symsrc__possibly_runtime(ss)) {
1457                        runtime_ss = ss;
1458                        next_slot = true;
1459                }
1460
1461                if (next_slot) {
1462                        ss_pos++;
1463
1464                        if (syms_ss && runtime_ss)
1465                                break;
1466                } else {
1467                        symsrc__destroy(ss);
1468                }
1469
1470        }
1471
1472        if (!runtime_ss && !syms_ss)
1473                goto out_free;
1474
1475        if (runtime_ss && !syms_ss) {
1476                syms_ss = runtime_ss;
1477        }
1478
1479        /* We'll have to hope for the best */
1480        if (!runtime_ss && syms_ss)
1481                runtime_ss = syms_ss;
1482
1483        if (syms_ss)
1484                ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod);
1485        else
1486                ret = -1;
1487
1488        if (ret > 0) {
1489                int nr_plt;
1490
1491                nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter);
1492                if (nr_plt > 0)
1493                        ret += nr_plt;
1494        }
1495
1496        for (; ss_pos > 0; ss_pos--)
1497                symsrc__destroy(&ss_[ss_pos - 1]);
1498out_free:
1499        free(name);
1500        if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1501                return 0;
1502        return ret;
1503}
1504
1505struct map *map_groups__find_by_name(struct map_groups *mg,
1506                                     enum map_type type, const char *name)
1507{
1508        struct rb_node *nd;
1509
1510        for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1511                struct map *map = rb_entry(nd, struct map, rb_node);
1512
1513                if (map->dso && strcmp(map->dso->short_name, name) == 0)
1514                        return map;
1515        }
1516
1517        return NULL;
1518}
1519
1520int dso__load_vmlinux(struct dso *dso, struct map *map,
1521                      const char *vmlinux, bool vmlinux_allocated,
1522                      symbol_filter_t filter)
1523{
1524        int err = -1;
1525        struct symsrc ss;
1526        char symfs_vmlinux[PATH_MAX];
1527        enum dso_binary_type symtab_type;
1528
1529        if (vmlinux[0] == '/')
1530                snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux);
1531        else
1532                symbol__join_symfs(symfs_vmlinux, vmlinux);
1533
1534        if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1535                symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1536        else
1537                symtab_type = DSO_BINARY_TYPE__VMLINUX;
1538
1539        if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
1540                return -1;
1541
1542        err = dso__load_sym(dso, map, &ss, &ss, filter, 0);
1543        symsrc__destroy(&ss);
1544
1545        if (err > 0) {
1546                if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1547                        dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1548                else
1549                        dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
1550                dso__set_long_name(dso, vmlinux, vmlinux_allocated);
1551                dso__set_loaded(dso, map->type);
1552                pr_debug("Using %s for symbols\n", symfs_vmlinux);
1553        }
1554
1555        return err;
1556}
1557
1558int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1559                           symbol_filter_t filter)
1560{
1561        int i, err = 0;
1562        char *filename = NULL;
1563
1564        if (!symbol_conf.ignore_vmlinux_buildid)
1565                filename = dso__build_id_filename(dso, NULL, 0);
1566        if (filename != NULL) {
1567                err = dso__load_vmlinux(dso, map, filename, true, filter);
1568                if (err > 0)
1569                        goto out;
1570                free(filename);
1571        }
1572
1573        pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1574                 vmlinux_path__nr_entries + 1);
1575
1576        for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1577                err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
1578                if (err > 0)
1579                        break;
1580        }
1581out:
1582        return err;
1583}
1584
1585static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1586{
1587        char kallsyms_filename[PATH_MAX];
1588        struct dirent *dent;
1589        int ret = -1;
1590        DIR *d;
1591
1592        d = opendir(dir);
1593        if (!d)
1594                return -1;
1595
1596        while (1) {
1597                dent = readdir(d);
1598                if (!dent)
1599                        break;
1600                if (dent->d_type != DT_DIR)
1601                        continue;
1602                scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1603                          "%s/%s/kallsyms", dir, dent->d_name);
1604                if (!validate_kcore_addresses(kallsyms_filename, map)) {
1605                        strlcpy(dir, kallsyms_filename, dir_sz);
1606                        ret = 0;
1607                        break;
1608                }
1609        }
1610
1611        closedir(d);
1612
1613        return ret;
1614}
1615
1616static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1617{
1618        u8 host_build_id[BUILD_ID_SIZE];
1619        char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1620        bool is_host = false;
1621        char path[PATH_MAX];
1622
1623        if (!dso->has_build_id) {
1624                /*
1625                 * Last resort, if we don't have a build-id and couldn't find
1626                 * any vmlinux file, try the running kernel kallsyms table.
1627                 */
1628                goto proc_kallsyms;
1629        }
1630
1631        if (sysfs__read_build_id("/sys/kernel/notes", host_build_id,
1632                                 sizeof(host_build_id)) == 0)
1633                is_host = dso__build_id_equal(dso, host_build_id);
1634
1635        build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1636
1637        scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir,
1638                  sbuild_id);
1639
1640        /* Use /proc/kallsyms if possible */
1641        if (is_host) {
1642                DIR *d;
1643                int fd;
1644
1645                /* If no cached kcore go with /proc/kallsyms */
1646                d = opendir(path);
1647                if (!d)
1648                        goto proc_kallsyms;
1649                closedir(d);
1650
1651                /*
1652                 * Do not check the build-id cache, until we know we cannot use
1653                 * /proc/kcore.
1654                 */
1655                fd = open("/proc/kcore", O_RDONLY);
1656                if (fd != -1) {
1657                        close(fd);
1658                        /* If module maps match go with /proc/kallsyms */
1659                        if (!validate_kcore_addresses("/proc/kallsyms", map))
1660                                goto proc_kallsyms;
1661                }
1662
1663                /* Find kallsyms in build-id cache with kcore */
1664                if (!find_matching_kcore(map, path, sizeof(path)))
1665                        return strdup(path);
1666
1667                goto proc_kallsyms;
1668        }
1669
1670        /* Find kallsyms in build-id cache with kcore */
1671        if (!find_matching_kcore(map, path, sizeof(path)))
1672                return strdup(path);
1673
1674        scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s",
1675                  buildid_dir, sbuild_id);
1676
1677        if (access(path, F_OK)) {
1678                pr_err("No kallsyms or vmlinux with build-id %s was found\n",
1679                       sbuild_id);
1680                return NULL;
1681        }
1682
1683        return strdup(path);
1684
1685proc_kallsyms:
1686        return strdup("/proc/kallsyms");
1687}
1688
1689static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1690                                symbol_filter_t filter)
1691{
1692        int err;
1693        const char *kallsyms_filename = NULL;
1694        char *kallsyms_allocated_filename = NULL;
1695        /*
1696         * Step 1: if the user specified a kallsyms or vmlinux filename, use
1697         * it and only it, reporting errors to the user if it cannot be used.
1698         *
1699         * For instance, try to analyse an ARM perf.data file _without_ a
1700         * build-id, or if the user specifies the wrong path to the right
1701         * vmlinux file, obviously we can't fallback to another vmlinux (a
1702         * x86_86 one, on the machine where analysis is being performed, say),
1703         * or worse, /proc/kallsyms.
1704         *
1705         * If the specified file _has_ a build-id and there is a build-id
1706         * section in the perf.data file, we will still do the expected
1707         * validation in dso__load_vmlinux and will bail out if they don't
1708         * match.
1709         */
1710        if (symbol_conf.kallsyms_name != NULL) {
1711                kallsyms_filename = symbol_conf.kallsyms_name;
1712                goto do_kallsyms;
1713        }
1714
1715        if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
1716                return dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name,
1717                                         false, filter);
1718        }
1719
1720        if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
1721                err = dso__load_vmlinux_path(dso, map, filter);
1722                if (err > 0)
1723                        return err;
1724        }
1725
1726        /* do not try local files if a symfs was given */
1727        if (symbol_conf.symfs[0] != 0)
1728                return -1;
1729
1730        kallsyms_allocated_filename = dso__find_kallsyms(dso, map);
1731        if (!kallsyms_allocated_filename)
1732                return -1;
1733
1734        kallsyms_filename = kallsyms_allocated_filename;
1735
1736do_kallsyms:
1737        err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1738        if (err > 0)
1739                pr_debug("Using %s for symbols\n", kallsyms_filename);
1740        free(kallsyms_allocated_filename);
1741
1742        if (err > 0 && !dso__is_kcore(dso)) {
1743                dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
1744                dso__set_long_name(dso, "[kernel.kallsyms]", false);
1745                map__fixup_start(map);
1746                map__fixup_end(map);
1747        }
1748
1749        return err;
1750}
1751
1752static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1753                                      symbol_filter_t filter)
1754{
1755        int err;
1756        const char *kallsyms_filename = NULL;
1757        struct machine *machine;
1758        char path[PATH_MAX];
1759
1760        if (!map->groups) {
1761                pr_debug("Guest kernel map hasn't the point to groups\n");
1762                return -1;
1763        }
1764        machine = map->groups->machine;
1765
1766        if (machine__is_default_guest(machine)) {
1767                /*
1768                 * if the user specified a vmlinux filename, use it and only
1769                 * it, reporting errors to the user if it cannot be used.
1770                 * Or use file guest_kallsyms inputted by user on commandline
1771                 */
1772                if (symbol_conf.default_guest_vmlinux_name != NULL) {
1773                        err = dso__load_vmlinux(dso, map,
1774                                                symbol_conf.default_guest_vmlinux_name,
1775                                                false, filter);
1776                        return err;
1777                }
1778
1779                kallsyms_filename = symbol_conf.default_guest_kallsyms;
1780                if (!kallsyms_filename)
1781                        return -1;
1782        } else {
1783                sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1784                kallsyms_filename = path;
1785        }
1786
1787        err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1788        if (err > 0)
1789                pr_debug("Using %s for symbols\n", kallsyms_filename);
1790        if (err > 0 && !dso__is_kcore(dso)) {
1791                dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
1792                machine__mmap_name(machine, path, sizeof(path));
1793                dso__set_long_name(dso, strdup(path), true);
1794                map__fixup_start(map);
1795                map__fixup_end(map);
1796        }
1797
1798        return err;
1799}
1800
1801static void vmlinux_path__exit(void)
1802{
1803        while (--vmlinux_path__nr_entries >= 0)
1804                zfree(&vmlinux_path[vmlinux_path__nr_entries]);
1805
1806        zfree(&vmlinux_path);
1807}
1808
1809static int vmlinux_path__init(struct perf_session_env *env)
1810{
1811        struct utsname uts;
1812        char bf[PATH_MAX];
1813        char *kernel_version;
1814
1815        vmlinux_path = malloc(sizeof(char *) * 6);
1816        if (vmlinux_path == NULL)
1817                return -1;
1818
1819        vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1820        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1821                goto out_fail;
1822        ++vmlinux_path__nr_entries;
1823        vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1824        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1825                goto out_fail;
1826        ++vmlinux_path__nr_entries;
1827
1828        /* only try kernel version if no symfs was given */
1829        if (symbol_conf.symfs[0] != 0)
1830                return 0;
1831
1832        if (env) {
1833                kernel_version = env->os_release;
1834        } else {
1835                if (uname(&uts) < 0)
1836                        goto out_fail;
1837
1838                kernel_version = uts.release;
1839        }
1840
1841        snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version);
1842        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1843        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1844                goto out_fail;
1845        ++vmlinux_path__nr_entries;
1846        snprintf(bf, sizeof(bf), "/usr/lib/debug/boot/vmlinux-%s",
1847                 kernel_version);
1848        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1849        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1850                goto out_fail;
1851        ++vmlinux_path__nr_entries;
1852        snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version);
1853        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1854        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1855                goto out_fail;
1856        ++vmlinux_path__nr_entries;
1857        snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1858                 kernel_version);
1859        vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1860        if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1861                goto out_fail;
1862        ++vmlinux_path__nr_entries;
1863
1864        return 0;
1865
1866out_fail:
1867        vmlinux_path__exit();
1868        return -1;
1869}
1870
1871int setup_list(struct strlist **list, const char *list_str,
1872                      const char *list_name)
1873{
1874        if (list_str == NULL)
1875                return 0;
1876
1877        *list = strlist__new(true, list_str);
1878        if (!*list) {
1879                pr_err("problems parsing %s list\n", list_name);
1880                return -1;
1881        }
1882        return 0;
1883}
1884
1885int setup_intlist(struct intlist **list, const char *list_str,
1886                  const char *list_name)
1887{
1888        if (list_str == NULL)
1889                return 0;
1890
1891        *list = intlist__new(list_str);
1892        if (!*list) {
1893                pr_err("problems parsing %s list\n", list_name);
1894                return -1;
1895        }
1896        return 0;
1897}
1898
1899static bool symbol__read_kptr_restrict(void)
1900{
1901        bool value = false;
1902
1903        if (geteuid() != 0) {
1904                FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
1905                if (fp != NULL) {
1906                        char line[8];
1907
1908                        if (fgets(line, sizeof(line), fp) != NULL)
1909                                value = atoi(line) != 0;
1910
1911                        fclose(fp);
1912                }
1913        }
1914
1915        return value;
1916}
1917
1918int symbol__init(struct perf_session_env *env)
1919{
1920        const char *symfs;
1921
1922        if (symbol_conf.initialized)
1923                return 0;
1924
1925        symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
1926
1927        symbol__elf_init();
1928
1929        if (symbol_conf.sort_by_name)
1930                symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1931                                          sizeof(struct symbol));
1932
1933        if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0)
1934                return -1;
1935
1936        if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
1937                pr_err("'.' is the only non valid --field-separator argument\n");
1938                return -1;
1939        }
1940
1941        if (setup_list(&symbol_conf.dso_list,
1942                       symbol_conf.dso_list_str, "dso") < 0)
1943                return -1;
1944
1945        if (setup_list(&symbol_conf.comm_list,
1946                       symbol_conf.comm_list_str, "comm") < 0)
1947                goto out_free_dso_list;
1948
1949        if (setup_intlist(&symbol_conf.pid_list,
1950                       symbol_conf.pid_list_str, "pid") < 0)
1951                goto out_free_comm_list;
1952
1953        if (setup_intlist(&symbol_conf.tid_list,
1954                       symbol_conf.tid_list_str, "tid") < 0)
1955                goto out_free_pid_list;
1956
1957        if (setup_list(&symbol_conf.sym_list,
1958                       symbol_conf.sym_list_str, "symbol") < 0)
1959                goto out_free_tid_list;
1960
1961        /*
1962         * A path to symbols of "/" is identical to ""
1963         * reset here for simplicity.
1964         */
1965        symfs = realpath(symbol_conf.symfs, NULL);
1966        if (symfs == NULL)
1967                symfs = symbol_conf.symfs;
1968        if (strcmp(symfs, "/") == 0)
1969                symbol_conf.symfs = "";
1970        if (symfs != symbol_conf.symfs)
1971                free((void *)symfs);
1972
1973        symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
1974
1975        symbol_conf.initialized = true;
1976        return 0;
1977
1978out_free_tid_list:
1979        intlist__delete(symbol_conf.tid_list);
1980out_free_pid_list:
1981        intlist__delete(symbol_conf.pid_list);
1982out_free_comm_list:
1983        strlist__delete(symbol_conf.comm_list);
1984out_free_dso_list:
1985        strlist__delete(symbol_conf.dso_list);
1986        return -1;
1987}
1988
1989void symbol__exit(void)
1990{
1991        if (!symbol_conf.initialized)
1992                return;
1993        strlist__delete(symbol_conf.sym_list);
1994        strlist__delete(symbol_conf.dso_list);
1995        strlist__delete(symbol_conf.comm_list);
1996        intlist__delete(symbol_conf.tid_list);
1997        intlist__delete(symbol_conf.pid_list);
1998        vmlinux_path__exit();
1999        symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
2000        symbol_conf.initialized = false;
2001}
2002