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