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