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