Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242505
b: refs/heads/master
c: 0f77a8d
h: refs/heads/master
i:
  242503: 102a54d
v: v3
  • Loading branch information
Namhyung Kim authored and Ingo Molnar committed Mar 24, 2011
1 parent 8855f73 commit 01a1c63
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dec2960827c85253d76938dbfa909df3be34958b
refs/heads/master: 0f77a8d378254f27df4a114a5da67223af1fe93f
7 changes: 7 additions & 0 deletions trunk/include/linux/kallsyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const char *kallsyms_lookup(unsigned long addr,

/* Look up a kernel symbol and return it in a text buffer. */
extern int sprint_symbol(char *buffer, unsigned long address);
extern int sprint_backtrace(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);
Expand Down Expand Up @@ -79,6 +80,12 @@ static inline int sprint_symbol(char *buffer, unsigned long addr)
return 0;
}

static inline int sprint_backtrace(char *buffer, unsigned long addr)
{
*buffer = '\0';
return 0;
}

static inline int lookup_symbol_name(unsigned long addr, char *symname)
{
return -ERANGE;
Expand Down
44 changes: 41 additions & 3 deletions trunk/kernel/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down
7 changes: 6 additions & 1 deletion trunk/lib/vsprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,9 @@ char *symbol_string(char *buf, char *end, void *ptr,
unsigned long value = (unsigned long) ptr;
#ifdef CONFIG_KALLSYMS
char sym[KSYM_SYMBOL_LEN];
if (ext != 'f' && ext != 's')
if (ext == 'B')
sprint_backtrace(sym, value);
else if (ext != 'f' && ext != 's')
sprint_symbol(sym, value);
else
kallsyms_lookup(value, NULL, NULL, NULL, sym);
Expand Down Expand Up @@ -949,6 +951,7 @@ int kptr_restrict = 1;
* - 'f' For simple symbolic function names without offset
* - 'S' For symbolic direct pointers with offset
* - 's' For symbolic direct pointers without offset
* - 'B' For backtraced symbolic direct pointers with offset
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
* - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
* - 'M' For a 6-byte MAC address, it prints the address in the
Expand Down Expand Up @@ -1008,6 +1011,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
/* Fallthrough */
case 'S':
case 's':
case 'B':
return symbol_string(buf, end, ptr, spec, *fmt);
case 'R':
case 'r':
Expand Down Expand Up @@ -1279,6 +1283,7 @@ int format_decode(const char *fmt, struct printf_spec *spec)
* %ps output the name of a text symbol without offset
* %pF output the name of a function pointer with its offset
* %pf output the name of a function pointer without its offset
* %pB output the name of a backtrace symbol with its offset
* %pR output the address range in a struct resource with decoded flags
* %pr output the address range in a struct resource with raw flags
* %pM output a 6-byte MAC address with colons
Expand Down

0 comments on commit 01a1c63

Please sign in to comment.