diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 1cebcbc28b474d9f7af1d4061f0e30ba60347aa8..3e3b92dabe3bb08783df230036c2f2069a784317 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -7,6 +7,8 @@ #define KSYM_NAME_LEN 127 +#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + \ + 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1) #ifdef CONFIG_KALLSYMS /* Lookup the address for a symbol. Returns 0 if not found. */ @@ -22,7 +24,10 @@ const char *kallsyms_lookup(unsigned long addr, unsigned long *offset, char **modname, char *namebuf); -/* Replace "%s" in format with address, if found */ +/* Look up a kernel symbol and return it in a text buffer. */ +extern int sprint_symbol(char *buffer, unsigned long address); + +/* Look up a kernel symbol and print it to the kernel messages. */ extern void __print_symbol(const char *fmt, unsigned long address); #else /* !CONFIG_KALLSYMS */ @@ -47,6 +52,12 @@ static inline const char *kallsyms_lookup(unsigned long addr, return NULL; } +static inline int sprint_symbol(char *buffer, unsigned long addr) +{ + *buffer = '\0'; + return 0; +} + /* Stupid that this does nothing, but I didn't create this mess. */ #define __print_symbol(fmt, addr) #endif /*CONFIG_KALLSYMS*/ diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 6f294ff4f9eec46f448dd9eb30fcb0b2ed47e6dc..5a0de8409739588a0710cb46f204d8cb262f77a9 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -267,27 +267,33 @@ const char *kallsyms_lookup(unsigned long addr, return NULL; } -/* Replace "%s" in format with address, or returns -errno. */ -void __print_symbol(const char *fmt, unsigned long address) +/* Look up a kernel symbol and return it in a text buffer. */ +int sprint_symbol(char *buffer, unsigned long address) { char *modname; const char *name; unsigned long offset, size; char namebuf[KSYM_NAME_LEN+1]; - char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + - 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1]; name = kallsyms_lookup(address, &size, &offset, &modname, namebuf); - if (!name) - sprintf(buffer, "0x%lx", address); + return sprintf(buffer, "0x%lx", address); else { if (modname) - sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset, + return sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset, size, modname); else - sprintf(buffer, "%s+%#lx/%#lx", name, offset, size); + return sprintf(buffer, "%s+%#lx/%#lx", name, offset, size); } +} + +/* Look up a kernel symbol and print it to the kernel messages. */ +void __print_symbol(const char *fmt, unsigned long address) +{ + char buffer[KSYM_SYMBOL_LEN]; + + sprint_symbol(buffer, address); + printk(fmt, buffer); } @@ -452,3 +458,4 @@ static int __init kallsyms_init(void) __initcall(kallsyms_init); EXPORT_SYMBOL(__print_symbol); +EXPORT_SYMBOL_GPL(sprint_symbol);