diff options
Diffstat (limited to 'kernel/kallsyms.c')
| -rw-r--r-- | kernel/kallsyms.c | 44 | 
1 files changed, 41 insertions, 3 deletions
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 6f6d091b575..59e879929b1 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -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)  {  |