mfd: Fix for the TWL4030 PM sleep/wakeup sequence
[linux-2.6.git] / kernel / kallsyms.c
index b9d0fd1..079f1d3 100644 (file)
@@ -342,13 +342,15 @@ int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
 }
 
 /* Look up a kernel symbol and return it in a text buffer. */
-int sprint_symbol(char *buffer, unsigned long address)
+static int __sprint_symbol(char *buffer, unsigned long address,
+                          int symbol_offset)
 {
        char *modname;
        const char *name;
        unsigned long offset, size;
        int len;
 
+       address += symbol_offset;
        name = kallsyms_lookup(address, &size, &offset, &modname, buffer);
        if (!name)
                return sprintf(buffer, "0x%lx", address);
@@ -357,17 +359,53 @@ int sprint_symbol(char *buffer, unsigned long address)
                strcpy(buffer, name);
        len = strlen(buffer);
        buffer += len;
+       offset -= symbol_offset;
 
        if (modname)
-               len += sprintf(buffer, "+%#lx/%#lx [%s]",
-                                               offset, size, modname);
+               len += sprintf(buffer, "+%#lx/%#lx [%s]", offset, size, modname);
        else
                len += sprintf(buffer, "+%#lx/%#lx", offset, size);
 
        return len;
 }
+
+/**
+ * sprint_symbol - Look up a kernel symbol and return it in a text buffer
+ * @buffer: buffer to be stored
+ * @address: address to lookup
+ *
+ * This function looks up a kernel symbol with @address and stores its name,
+ * offset, size and module name to @buffer if possible. If no symbol was found,
+ * just saves its @address as is.
+ *
+ * This function returns the number of bytes stored in @buffer.
+ */
+int sprint_symbol(char *buffer, unsigned long address)
+{
+       return __sprint_symbol(buffer, address, 0);
+}
+
 EXPORT_SYMBOL_GPL(sprint_symbol);
 
+/**
+ * sprint_backtrace - Look up a backtrace symbol and return it in a text buffer
+ * @buffer: buffer to be stored
+ * @address: address to lookup
+ *
+ * This function is for stack backtrace and does the same thing as
+ * sprint_symbol() but with modified/decreased @address. If there is a
+ * tail-call to the function marked "noreturn", gcc optimized out code after
+ * the call so that the stack-saved return address could point outside of the
+ * caller. This function ensures that kallsyms will find the original caller
+ * by decreasing @address.
+ *
+ * This function returns the number of bytes stored in @buffer.
+ */
+int sprint_backtrace(char *buffer, unsigned long address)
+{
+       return __sprint_symbol(buffer, address, -1);
+}
+
 /* Look up a kernel symbol and print it to the kernel messages. */
 void __print_symbol(const char *fmt, unsigned long address)
 {
@@ -477,13 +515,11 @@ static int s_show(struct seq_file *m, void *p)
                 */
                type = iter->exported ? toupper(iter->type) :
                                        tolower(iter->type);
-               seq_printf(m, "%0*lx %c %s\t[%s]\n",
-                          (int)(2 * sizeof(void *)),
-                          iter->value, type, iter->name, iter->module_name);
+               seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
+                          type, iter->name, iter->module_name);
        } else
-               seq_printf(m, "%0*lx %c %s\n",
-                          (int)(2 * sizeof(void *)),
-                          iter->value, iter->type, iter->name);
+               seq_printf(m, "%pK %c %s\n", (void *)iter->value,
+                          iter->type, iter->name);
        return 0;
 }