kallsyms.c 15 KB

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