diff options
author | Joe Perches <joe@perches.com> | 2012-12-12 13:18:50 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-04-30 16:31:16 -0400 |
commit | b0d33c2bd77bcf2d7c9427d2361ac57fe5b33aa1 (patch) | |
tree | 2acb72d0e39aee019cf8aecc917685b120e506a3 /lib/vsprintf.c | |
parent | 071361d3473ebb8142907470ff12d59c59f6be72 (diff) |
vsprintf: Add extension %pSR - print_symbol replacement
print_symbol takes a long and converts it to a function
name and offset. %pS does something similar, but doesn't
translate the address via __builtin_extract_return_addr.
%pSR does the translation.
This will enable replacing multiple calls like
printk(...);
printk_symbol(addr);
printk("\n");
with a single non-interleavable in dmesg
printk("... %pSR\n", (void *)addr);
Update documentation too.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 0d62fd700f68..e149c6416384 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -534,14 +534,21 @@ char *string(char *buf, char *end, const char *s, struct printf_spec spec) | |||
534 | 534 | ||
535 | static noinline_for_stack | 535 | static noinline_for_stack |
536 | char *symbol_string(char *buf, char *end, void *ptr, | 536 | char *symbol_string(char *buf, char *end, void *ptr, |
537 | struct printf_spec spec, char ext) | 537 | struct printf_spec spec, const char *fmt) |
538 | { | 538 | { |
539 | unsigned long value = (unsigned long) ptr; | 539 | unsigned long value; |
540 | #ifdef CONFIG_KALLSYMS | 540 | #ifdef CONFIG_KALLSYMS |
541 | char sym[KSYM_SYMBOL_LEN]; | 541 | char sym[KSYM_SYMBOL_LEN]; |
542 | if (ext == 'B') | 542 | #endif |
543 | |||
544 | if (fmt[1] == 'R') | ||
545 | ptr = __builtin_extract_return_addr(ptr); | ||
546 | value = (unsigned long)ptr; | ||
547 | |||
548 | #ifdef CONFIG_KALLSYMS | ||
549 | if (*fmt == 'B') | ||
543 | sprint_backtrace(sym, value); | 550 | sprint_backtrace(sym, value); |
544 | else if (ext != 'f' && ext != 's') | 551 | else if (*fmt != 'f' && *fmt != 's') |
545 | sprint_symbol(sym, value); | 552 | sprint_symbol(sym, value); |
546 | else | 553 | else |
547 | sprint_symbol_no_offset(sym, value); | 554 | sprint_symbol_no_offset(sym, value); |
@@ -987,6 +994,7 @@ int kptr_restrict __read_mostly; | |||
987 | * - 'f' For simple symbolic function names without offset | 994 | * - 'f' For simple symbolic function names without offset |
988 | * - 'S' For symbolic direct pointers with offset | 995 | * - 'S' For symbolic direct pointers with offset |
989 | * - 's' For symbolic direct pointers without offset | 996 | * - 's' For symbolic direct pointers without offset |
997 | * - '[FfSs]R' as above with __builtin_extract_return_addr() translation | ||
990 | * - 'B' For backtraced symbolic direct pointers with offset | 998 | * - 'B' For backtraced symbolic direct pointers with offset |
991 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] | 999 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
992 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] | 1000 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
@@ -1060,7 +1068,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1060 | case 'S': | 1068 | case 'S': |
1061 | case 's': | 1069 | case 's': |
1062 | case 'B': | 1070 | case 'B': |
1063 | return symbol_string(buf, end, ptr, spec, *fmt); | 1071 | return symbol_string(buf, end, ptr, spec, fmt); |
1064 | case 'R': | 1072 | case 'R': |
1065 | case 'r': | 1073 | case 'r': |
1066 | return resource_string(buf, end, ptr, spec, fmt); | 1074 | return resource_string(buf, end, ptr, spec, fmt); |