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 */ 40 extern const unsigned long kallsyms_addresses[] __weak; 41 extern 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 */ 47 extern const unsigned long kallsyms_num_syms 48 __attribute__((weak, section(".rodata"))); 49 50 extern const u8 kallsyms_token_table[] __weak; 51 extern const u16 kallsyms_token_index[] __weak; 52 53 extern const unsigned long kallsyms_markers[] __weak; 54 55 static 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 63 static 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 71 static 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 78 static 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 */ 91 static 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 130 tail: 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 */ 142 static 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 */ 156 static 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. */ 180 unsigned 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 } 194 EXPORT_SYMBOL_GPL(kallsyms_lookup_name); 195 196 int 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 } 213 EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol); 214 215 static 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 */ 275 int 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 */ 292 const 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 317 int 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 335 int 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. */ 356 static 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 */ 394 int sprint_symbol(char *buffer, unsigned long address) 395 { 396 return __sprint_symbol(buffer, address, 0, 1); 397 } 398 EXPORT_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 */ 411 int sprint_symbol_no_offset(char *buffer, unsigned long address) 412 { 413 return __sprint_symbol(buffer, address, 0, 0); 414 } 415 EXPORT_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 */ 431 int 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. */ 437 void __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 } 445 EXPORT_SYMBOL(__print_symbol); 446 447 /* To avoid using get_symbol_offset for every symbol, we carry prefix along. */ 448 struct 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 458 static 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. */ 468 static 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 482 static 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. */ 490 static 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 508 static 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 517 static 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 524 static void s_stop(struct seq_file *m, void *p) 525 { 526 } 527 528 static 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 553 static const struct seq_operations kallsyms_op = { 554 .start = s_start, 555 .next = s_next, 556 .stop = s_stop, 557 .show = s_show 558 }; 559 560 static 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 577 const 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 596 static 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 603 static int __init kallsyms_init(void) 604 { 605 proc_create("kallsyms", 0444, NULL, &kallsyms_operations); 606 return 0; 607 } 608 device_initcall(kallsyms_init); 609