linux/kernel/kallsyms.c
<<
>>
Prefs
   1/*
   2 * kallsyms.c: in-kernel printing of symbolic oopses and stack traces.
   3 *
   4 * Rewritten and vastly simplified by Rusty Russell for in-kernel
   5 * module loader:
   6 *   Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
   7 *
   8 * ChangeLog:
   9 *
  10 * (25/Aug/2004) Paulo Marques <pmarques@grupopie.com>
  11 *      Changed the compression method from stem compression to "table lookup"
  12 *      compression (see scripts/kallsyms.c for a more complete description)
  13 */
  14#include <linux/kallsyms.h>
  15#include <linux/init.h>
  16#include <linux/seq_file.h>
  17#include <linux/fs.h>
  18#include <linux/kdb.h>
  19#include <linux/err.h>
  20#include <linux/proc_fs.h>
  21#include <linux/sched.h>        /* for cond_resched */
  22#include <linux/ctype.h>
  23#include <linux/slab.h>
  24#include <linux/filter.h>
  25#include <linux/ftrace.h>
  26#include <linux/compiler.h>
  27
  28/*
  29 * These will be re-linked against their real values
  30 * during the second link stage.
  31 */
  32extern const unsigned long kallsyms_addresses[] __weak;
  33extern const int kallsyms_offsets[] __weak;
  34extern const u8 kallsyms_names[] __weak;
  35
  36/*
  37 * Tell the compiler that the count isn't in the small data section if the arch
  38 * has one (eg: FRV).
  39 */
  40extern const unsigned int kallsyms_num_syms
  41__attribute__((weak, section(".rodata")));
  42
  43extern const unsigned long kallsyms_relative_base
  44__attribute__((weak, section(".rodata")));
  45
  46extern const u8 kallsyms_token_table[] __weak;
  47extern const u16 kallsyms_token_index[] __weak;
  48
  49extern const unsigned int kallsyms_markers[] __weak;
  50
  51/*
  52 * Expand a compressed symbol data into the resulting uncompressed string,
  53 * if uncompressed string is too long (>= maxlen), it will be truncated,
  54 * given the offset to where the symbol is in the compressed stream.
  55 */
  56static unsigned int kallsyms_expand_symbol(unsigned int off,
  57                                           char *result, size_t maxlen)
  58{
  59        int len, skipped_first = 0;
  60        const u8 *tptr, *data;
  61
  62        /* Get the compressed symbol length from the first symbol byte. */
  63        data = &kallsyms_names[off];
  64        len = *data;
  65        data++;
  66
  67        /*
  68         * Update the offset to return the offset for the next symbol on
  69         * the compressed stream.
  70         */
  71        off += len + 1;
  72
  73        /*
  74         * For every byte on the compressed symbol data, copy the table
  75         * entry for that byte.
  76         */
  77        while (len) {
  78                tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
  79                data++;
  80                len--;
  81
  82                while (*tptr) {
  83                        if (skipped_first) {
  84                                if (maxlen <= 1)
  85                                        goto tail;
  86                                *result = *tptr;
  87                                result++;
  88                                maxlen--;
  89                        } else
  90                                skipped_first = 1;
  91                        tptr++;
  92                }
  93        }
  94
  95tail:
  96        if (maxlen)
  97                *result = '\0';
  98
  99        /* Return to offset to the next symbol. */
 100        return off;
 101}
 102
 103/*
 104 * Get symbol type information. This is encoded as a single char at the
 105 * beginning of the symbol name.
 106 */
 107static char kallsyms_get_symbol_type(unsigned int off)
 108{
 109        /*
 110         * Get just the first code, look it up in the token table,
 111         * and return the first char from this token.
 112         */
 113        return kallsyms_token_table[kallsyms_token_index[kallsyms_names[off + 1]]];
 114}
 115
 116
 117/*
 118 * Find the offset on the compressed stream given and index in the
 119 * kallsyms array.
 120 */
 121static unsigned int get_symbol_offset(unsigned long pos)
 122{
 123        const u8 *name;
 124        int i;
 125
 126        /*
 127         * Use the closest marker we have. We have markers every 256 positions,
 128         * so that should be close enough.
 129         */
 130        name = &kallsyms_names[kallsyms_markers[pos >> 8]];
 131
 132        /*
 133         * Sequentially scan all the symbols up to the point we're searching
 134         * for. Every symbol is stored in a [<len>][<len> bytes of data] format,
 135         * so we just need to add the len to the current pointer for every
 136         * symbol we wish to skip.
 137         */
 138        for (i = 0; i < (pos & 0xFF); i++)
 139                name = name + (*name) + 1;
 140
 141        return name - kallsyms_names;
 142}
 143
 144static unsigned long kallsyms_sym_address(int idx)
 145{
 146        if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE))
 147                return kallsyms_addresses[idx];
 148
 149        /* values are unsigned offsets if --absolute-percpu is not in effect */
 150        if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU))
 151                return kallsyms_relative_base + (u32)kallsyms_offsets[idx];
 152
 153        /* ...otherwise, positive offsets are absolute values */
 154        if (kallsyms_offsets[idx] >= 0)
 155                return kallsyms_offsets[idx];
 156
 157        /* ...and negative offsets are relative to kallsyms_relative_base - 1 */
 158        return kallsyms_relative_base - 1 - kallsyms_offsets[idx];
 159}
 160
 161/* Lookup the address for this symbol. Returns 0 if not found. */
 162unsigned long kallsyms_lookup_name(const char *name)
 163{
 164        char namebuf[KSYM_NAME_LEN];
 165        unsigned long i;
 166        unsigned int off;
 167
 168        for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
 169                off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
 170
 171                if (strcmp(namebuf, name) == 0)
 172                        return kallsyms_sym_address(i);
 173        }
 174        return module_kallsyms_lookup_name(name);
 175}
 176EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
 177
 178int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
 179                                      unsigned long),
 180                            void *data)
 181{
 182        char namebuf[KSYM_NAME_LEN];
 183        unsigned long i;
 184        unsigned int off;
 185        int ret;
 186
 187        for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
 188                off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
 189                ret = fn(data, namebuf, NULL, kallsyms_sym_address(i));
 190                if (ret != 0)
 191                        return ret;
 192        }
 193        return module_kallsyms_on_each_symbol(fn, data);
 194}
 195EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
 196
 197static unsigned long get_symbol_pos(unsigned long addr,
 198                                    unsigned long *symbolsize,
 199                                    unsigned long *offset)
 200{
 201        unsigned long symbol_start = 0, symbol_end = 0;
 202        unsigned long i, low, high, mid;
 203
 204        /* This kernel should never had been booted. */
 205        if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE))
 206                BUG_ON(!kallsyms_addresses);
 207        else
 208                BUG_ON(!kallsyms_offsets);
 209
 210        /* Do a binary search on the sorted kallsyms_addresses array. */
 211        low = 0;
 212        high = kallsyms_num_syms;
 213
 214        while (high - low > 1) {
 215                mid = low + (high - low) / 2;
 216                if (kallsyms_sym_address(mid) <= addr)
 217                        low = mid;
 218                else
 219                        high = mid;
 220        }
 221
 222        /*
 223         * Search for the first aliased symbol. Aliased
 224         * symbols are symbols with the same address.
 225         */
 226        while (low && kallsyms_sym_address(low-1) == kallsyms_sym_address(low))
 227                --low;
 228
 229        symbol_start = kallsyms_sym_address(low);
 230
 231        /* Search for next non-aliased symbol. */
 232        for (i = low + 1; i < kallsyms_num_syms; i++) {
 233                if (kallsyms_sym_address(i) > symbol_start) {
 234                        symbol_end = kallsyms_sym_address(i);
 235                        break;
 236                }
 237        }
 238
 239        /* If we found no next symbol, we use the end of the section. */
 240        if (!symbol_end) {
 241                if (is_kernel_inittext(addr))
 242                        symbol_end = (unsigned long)_einittext;
 243                else if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
 244                        symbol_end = (unsigned long)_end;
 245                else
 246                        symbol_end = (unsigned long)_etext;
 247        }
 248
 249        if (symbolsize)
 250                *symbolsize = symbol_end - symbol_start;
 251        if (offset)
 252                *offset = addr - symbol_start;
 253
 254        return low;
 255}
 256
 257/*
 258 * Lookup an address but don't bother to find any names.
 259 */
 260int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
 261                                unsigned long *offset)
 262{
 263        char namebuf[KSYM_NAME_LEN];
 264
 265        if (is_ksym_addr(addr))
 266                return !!get_symbol_pos(addr, symbolsize, offset);
 267        return !!module_address_lookup(addr, symbolsize, offset, NULL, namebuf) ||
 268               !!__bpf_address_lookup(addr, symbolsize, offset, namebuf);
 269}
 270
 271/*
 272 * Lookup an address
 273 * - modname is set to NULL if it's in the kernel.
 274 * - We guarantee that the returned name is valid until we reschedule even if.
 275 *   It resides in a module.
 276 * - We also guarantee that modname will be valid until rescheduled.
 277 */
 278const char *kallsyms_lookup(unsigned long addr,
 279                            unsigned long *symbolsize,
 280                            unsigned long *offset,
 281                            char **modname, char *namebuf)
 282{
 283        const char *ret;
 284
 285        namebuf[KSYM_NAME_LEN - 1] = 0;
 286        namebuf[0] = 0;
 287
 288        if (is_ksym_addr(addr)) {
 289                unsigned long pos;
 290
 291                pos = get_symbol_pos(addr, symbolsize, offset);
 292                /* Grab name */
 293                kallsyms_expand_symbol(get_symbol_offset(pos),
 294                                       namebuf, KSYM_NAME_LEN);
 295                if (modname)
 296                        *modname = NULL;
 297                return namebuf;
 298        }
 299
 300        /* See if it's in a module or a BPF JITed image. */
 301        ret = module_address_lookup(addr, symbolsize, offset,
 302                                    modname, namebuf);
 303        if (!ret)
 304                ret = bpf_address_lookup(addr, symbolsize,
 305                                         offset, modname, namebuf);
 306
 307        if (!ret)
 308                ret = ftrace_mod_address_lookup(addr, symbolsize,
 309                                                offset, modname, namebuf);
 310        return ret;
 311}
 312
 313int lookup_symbol_name(unsigned long addr, char *symname)
 314{
 315        symname[0] = '\0';
 316        symname[KSYM_NAME_LEN - 1] = '\0';
 317
 318        if (is_ksym_addr(addr)) {
 319                unsigned long pos;
 320
 321                pos = get_symbol_pos(addr, NULL, NULL);
 322                /* Grab name */
 323                kallsyms_expand_symbol(get_symbol_offset(pos),
 324                                       symname, KSYM_NAME_LEN);
 325                return 0;
 326        }
 327        /* See if it's in a module. */
 328        return lookup_module_symbol_name(addr, symname);
 329}
 330
 331int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
 332                        unsigned long *offset, char *modname, char *name)
 333{
 334        name[0] = '\0';
 335        name[KSYM_NAME_LEN - 1] = '\0';
 336
 337        if (is_ksym_addr(addr)) {
 338                unsigned long pos;
 339
 340                pos = get_symbol_pos(addr, size, offset);
 341                /* Grab name */
 342                kallsyms_expand_symbol(get_symbol_offset(pos),
 343                                       name, KSYM_NAME_LEN);
 344                modname[0] = '\0';
 345                return 0;
 346        }
 347        /* See if it's in a module. */
 348        return lookup_module_symbol_attrs(addr, size, offset, modname, name);
 349}
 350
 351/* Look up a kernel symbol and return it in a text buffer. */
 352static int __sprint_symbol(char *buffer, unsigned long address,
 353                           int symbol_offset, int add_offset)
 354{
 355        char *modname;
 356        const char *name;
 357        unsigned long offset, size;
 358        int len;
 359
 360        address += symbol_offset;
 361        name = kallsyms_lookup(address, &size, &offset, &modname, buffer);
 362        if (!name)
 363                return sprintf(buffer, "0x%lx", address - symbol_offset);
 364
 365        if (name != buffer)
 366                strcpy(buffer, name);
 367        len = strlen(buffer);
 368        offset -= symbol_offset;
 369
 370        if (add_offset)
 371                len += sprintf(buffer + len, "+%#lx/%#lx", offset, size);
 372
 373        if (modname)
 374                len += sprintf(buffer + len, " [%s]", modname);
 375
 376        return len;
 377}
 378
 379/**
 380 * sprint_symbol - Look up a kernel symbol and return it in a text buffer
 381 * @buffer: buffer to be stored
 382 * @address: address to lookup
 383 *
 384 * This function looks up a kernel symbol with @address and stores its name,
 385 * offset, size and module name to @buffer if possible. If no symbol was found,
 386 * just saves its @address as is.
 387 *
 388 * This function returns the number of bytes stored in @buffer.
 389 */
 390int sprint_symbol(char *buffer, unsigned long address)
 391{
 392        return __sprint_symbol(buffer, address, 0, 1);
 393}
 394EXPORT_SYMBOL_GPL(sprint_symbol);
 395
 396/**
 397 * sprint_symbol_no_offset - Look up a kernel symbol and return it in a text buffer
 398 * @buffer: buffer to be stored
 399 * @address: address to lookup
 400 *
 401 * This function looks up a kernel symbol with @address and stores its name
 402 * and module name to @buffer if possible. If no symbol was found, just saves
 403 * its @address as is.
 404 *
 405 * This function returns the number of bytes stored in @buffer.
 406 */
 407int sprint_symbol_no_offset(char *buffer, unsigned long address)
 408{
 409        return __sprint_symbol(buffer, address, 0, 0);
 410}
 411EXPORT_SYMBOL_GPL(sprint_symbol_no_offset);
 412
 413/**
 414 * sprint_backtrace - Look up a backtrace symbol and return it in a text buffer
 415 * @buffer: buffer to be stored
 416 * @address: address to lookup
 417 *
 418 * This function is for stack backtrace and does the same thing as
 419 * sprint_symbol() but with modified/decreased @address. If there is a
 420 * tail-call to the function marked "noreturn", gcc optimized out code after
 421 * the call so that the stack-saved return address could point outside of the
 422 * caller. This function ensures that kallsyms will find the original caller
 423 * by decreasing @address.
 424 *
 425 * This function returns the number of bytes stored in @buffer.
 426 */
 427int sprint_backtrace(char *buffer, unsigned long address)
 428{
 429        return __sprint_symbol(buffer, address, -1, 1);
 430}
 431
 432/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
 433struct kallsym_iter {
 434        loff_t pos;
 435        loff_t pos_arch_end;
 436        loff_t pos_mod_end;
 437        loff_t pos_ftrace_mod_end;
 438        unsigned long value;
 439        unsigned int nameoff; /* If iterating in core kernel symbols. */
 440        char type;
 441        char name[KSYM_NAME_LEN];
 442        char module_name[MODULE_NAME_LEN];
 443        int exported;
 444        int show_value;
 445};
 446
 447int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
 448                            char *type, char *name)
 449{
 450        return -EINVAL;
 451}
 452
 453static int get_ksymbol_arch(struct kallsym_iter *iter)
 454{
 455        int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
 456                                   &iter->value, &iter->type,
 457                                   iter->name);
 458
 459        if (ret < 0) {
 460                iter->pos_arch_end = iter->pos;
 461                return 0;
 462        }
 463
 464        return 1;
 465}
 466
 467static int get_ksymbol_mod(struct kallsym_iter *iter)
 468{
 469        int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
 470                                     &iter->value, &iter->type,
 471                                     iter->name, iter->module_name,
 472                                     &iter->exported);
 473        if (ret < 0) {
 474                iter->pos_mod_end = iter->pos;
 475                return 0;
 476        }
 477
 478        return 1;
 479}
 480
 481static int get_ksymbol_ftrace_mod(struct kallsym_iter *iter)
 482{
 483        int ret = ftrace_mod_get_kallsym(iter->pos - iter->pos_mod_end,
 484                                         &iter->value, &iter->type,
 485                                         iter->name, iter->module_name,
 486                                         &iter->exported);
 487        if (ret < 0) {
 488                iter->pos_ftrace_mod_end = iter->pos;
 489                return 0;
 490        }
 491
 492        return 1;
 493}
 494
 495static int get_ksymbol_bpf(struct kallsym_iter *iter)
 496{
 497        iter->module_name[0] = '\0';
 498        iter->exported = 0;
 499        return bpf_get_kallsym(iter->pos - iter->pos_ftrace_mod_end,
 500                               &iter->value, &iter->type,
 501                               iter->name) < 0 ? 0 : 1;
 502}
 503
 504/* Returns space to next name. */
 505static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
 506{
 507        unsigned off = iter->nameoff;
 508
 509        iter->module_name[0] = '\0';
 510        iter->value = kallsyms_sym_address(iter->pos);
 511
 512        iter->type = kallsyms_get_symbol_type(off);
 513
 514        off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name));
 515
 516        return off - iter->nameoff;
 517}
 518
 519static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
 520{
 521        iter->name[0] = '\0';
 522        iter->nameoff = get_symbol_offset(new_pos);
 523        iter->pos = new_pos;
 524        if (new_pos == 0) {
 525                iter->pos_arch_end = 0;
 526                iter->pos_mod_end = 0;
 527                iter->pos_ftrace_mod_end = 0;
 528        }
 529}
 530
 531/*
 532 * The end position (last + 1) of each additional kallsyms section is recorded
 533 * in iter->pos_..._end as each section is added, and so can be used to
 534 * determine which get_ksymbol_...() function to call next.
 535 */
 536static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
 537{
 538        iter->pos = pos;
 539
 540        if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
 541            get_ksymbol_arch(iter))
 542                return 1;
 543
 544        if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
 545            get_ksymbol_mod(iter))
 546                return 1;
 547
 548        if ((!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > pos) &&
 549            get_ksymbol_ftrace_mod(iter))
 550                return 1;
 551
 552        return get_ksymbol_bpf(iter);
 553}
 554
 555/* Returns false if pos at or past end of file. */
 556static int update_iter(struct kallsym_iter *iter, loff_t pos)
 557{
 558        /* Module symbols can be accessed randomly. */
 559        if (pos >= kallsyms_num_syms)
 560                return update_iter_mod(iter, pos);
 561
 562        /* If we're not on the desired position, reset to new position. */
 563        if (pos != iter->pos)
 564                reset_iter(iter, pos);
 565
 566        iter->nameoff += get_ksymbol_core(iter);
 567        iter->pos++;
 568
 569        return 1;
 570}
 571
 572static void *s_next(struct seq_file *m, void *p, loff_t *pos)
 573{
 574        (*pos)++;
 575
 576        if (!update_iter(m->private, *pos))
 577                return NULL;
 578        return p;
 579}
 580
 581static void *s_start(struct seq_file *m, loff_t *pos)
 582{
 583        if (!update_iter(m->private, *pos))
 584                return NULL;
 585        return m->private;
 586}
 587
 588static void s_stop(struct seq_file *m, void *p)
 589{
 590}
 591
 592static int s_show(struct seq_file *m, void *p)
 593{
 594        void *value;
 595        struct kallsym_iter *iter = m->private;
 596
 597        /* Some debugging symbols have no name.  Ignore them. */
 598        if (!iter->name[0])
 599                return 0;
 600
 601        value = iter->show_value ? (void *)iter->value : NULL;
 602
 603        if (iter->module_name[0]) {
 604                char type;
 605
 606                /*
 607                 * Label it "global" if it is exported,
 608                 * "local" if not exported.
 609                 */
 610                type = iter->exported ? toupper(iter->type) :
 611                                        tolower(iter->type);
 612                seq_printf(m, "%px %c %s\t[%s]\n", value,
 613                           type, iter->name, iter->module_name);
 614        } else
 615                seq_printf(m, "%px %c %s\n", value,
 616                           iter->type, iter->name);
 617        return 0;
 618}
 619
 620static const struct seq_operations kallsyms_op = {
 621        .start = s_start,
 622        .next = s_next,
 623        .stop = s_stop,
 624        .show = s_show
 625};
 626
 627static inline int kallsyms_for_perf(void)
 628{
 629#ifdef CONFIG_PERF_EVENTS
 630        extern int sysctl_perf_event_paranoid;
 631        if (sysctl_perf_event_paranoid <= 1)
 632                return 1;
 633#endif
 634        return 0;
 635}
 636
 637/*
 638 * We show kallsyms information even to normal users if we've enabled
 639 * kernel profiling and are explicitly not paranoid (so kptr_restrict
 640 * is clear, and sysctl_perf_event_paranoid isn't set).
 641 *
 642 * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
 643 * block even that).
 644 */
 645int kallsyms_show_value(void)
 646{
 647        switch (kptr_restrict) {
 648        case 0:
 649                if (kallsyms_for_perf())
 650                        return 1;
 651        /* fallthrough */
 652        case 1:
 653                if (has_capability_noaudit(current, CAP_SYSLOG))
 654                        return 1;
 655        /* fallthrough */
 656        default:
 657                return 0;
 658        }
 659}
 660
 661static int kallsyms_open(struct inode *inode, struct file *file)
 662{
 663        /*
 664         * We keep iterator in m->private, since normal case is to
 665         * s_start from where we left off, so we avoid doing
 666         * using get_symbol_offset for every symbol.
 667         */
 668        struct kallsym_iter *iter;
 669        iter = __seq_open_private(file, &kallsyms_op, sizeof(*iter));
 670        if (!iter)
 671                return -ENOMEM;
 672        reset_iter(iter, 0);
 673
 674        iter->show_value = kallsyms_show_value();
 675        return 0;
 676}
 677
 678#ifdef  CONFIG_KGDB_KDB
 679const char *kdb_walk_kallsyms(loff_t *pos)
 680{
 681        static struct kallsym_iter kdb_walk_kallsyms_iter;
 682        if (*pos == 0) {
 683                memset(&kdb_walk_kallsyms_iter, 0,
 684                       sizeof(kdb_walk_kallsyms_iter));
 685                reset_iter(&kdb_walk_kallsyms_iter, 0);
 686        }
 687        while (1) {
 688                if (!update_iter(&kdb_walk_kallsyms_iter, *pos))
 689                        return NULL;
 690                ++*pos;
 691                /* Some debugging symbols have no name.  Ignore them. */
 692                if (kdb_walk_kallsyms_iter.name[0])
 693                        return kdb_walk_kallsyms_iter.name;
 694        }
 695}
 696#endif  /* CONFIG_KGDB_KDB */
 697
 698static const struct file_operations kallsyms_operations = {
 699        .open = kallsyms_open,
 700        .read = seq_read,
 701        .llseek = seq_lseek,
 702        .release = seq_release_private,
 703};
 704
 705static int __init kallsyms_init(void)
 706{
 707        proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
 708        return 0;
 709}
 710device_initcall(kallsyms_init);
 711