Commit 4796dd200db943e36f876e7029552212e5bbdf33
Committed by
Linus Torvalds
1 parent
05a6c8a922
Exists in
master
and in
20 other branches
vsprintf: fix %ps on non symbols when using kallsyms
Using %ps in a printk format will sometimes fail silently and print the empty string if the address passed in does not match a symbol that kallsyms knows about. But using %pS will fall back to printing the full address if kallsyms can't find the symbol. Make %ps act the same as %pS by falling back to printing the address. While we're here also make %ps print the module that a symbol comes from so that it matches what %pS already does. Take this simple function for example (in a module): static void test_printk(void) { int test; pr_info("with pS: %pS\n", &test); pr_info("with ps: %ps\n", &test); } Before this patch: with pS: 0xdff7df44 with ps: After this patch: with pS: 0xdff7df44 with ps: 0xdff7df44 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 32 additions and 9 deletions Side-by-side Diff
include/linux/kallsyms.h
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | |
37 | 37 | /* Look up a kernel symbol and return it in a text buffer. */ |
38 | 38 | extern int sprint_symbol(char *buffer, unsigned long address); |
39 | +extern int sprint_symbol_no_offset(char *buffer, unsigned long address); | |
39 | 40 | extern int sprint_backtrace(char *buffer, unsigned long address); |
40 | 41 | |
41 | 42 | /* Look up a kernel symbol and print it to the kernel messages. */ |
... | ... | @@ -75,6 +76,12 @@ |
75 | 76 | } |
76 | 77 | |
77 | 78 | static inline int sprint_symbol(char *buffer, unsigned long addr) |
79 | +{ | |
80 | + *buffer = '\0'; | |
81 | + return 0; | |
82 | +} | |
83 | + | |
84 | +static inline int sprint_symbol_no_offset(char *buffer, unsigned long addr) | |
78 | 85 | { |
79 | 86 | *buffer = '\0'; |
80 | 87 | return 0; |
kernel/kallsyms.c
... | ... | @@ -343,7 +343,7 @@ |
343 | 343 | |
344 | 344 | /* Look up a kernel symbol and return it in a text buffer. */ |
345 | 345 | static int __sprint_symbol(char *buffer, unsigned long address, |
346 | - int symbol_offset) | |
346 | + int symbol_offset, int add_offset) | |
347 | 347 | { |
348 | 348 | char *modname; |
349 | 349 | const char *name; |
350 | 350 | |
351 | 351 | |
... | ... | @@ -358,13 +358,13 @@ |
358 | 358 | if (name != buffer) |
359 | 359 | strcpy(buffer, name); |
360 | 360 | len = strlen(buffer); |
361 | - buffer += len; | |
362 | 361 | offset -= symbol_offset; |
363 | 362 | |
363 | + if (add_offset) | |
364 | + len += sprintf(buffer + len, "+%#lx/%#lx", offset, size); | |
365 | + | |
364 | 366 | if (modname) |
365 | - len += sprintf(buffer, "+%#lx/%#lx [%s]", offset, size, modname); | |
366 | - else | |
367 | - len += sprintf(buffer, "+%#lx/%#lx", offset, size); | |
367 | + len += sprintf(buffer + len, " [%s]", modname); | |
368 | 368 | |
369 | 369 | return len; |
370 | 370 | } |
371 | 371 | |
372 | 372 | |
... | ... | @@ -382,12 +382,28 @@ |
382 | 382 | */ |
383 | 383 | int sprint_symbol(char *buffer, unsigned long address) |
384 | 384 | { |
385 | - return __sprint_symbol(buffer, address, 0); | |
385 | + return __sprint_symbol(buffer, address, 0, 1); | |
386 | 386 | } |
387 | - | |
388 | 387 | EXPORT_SYMBOL_GPL(sprint_symbol); |
389 | 388 | |
390 | 389 | /** |
390 | + * sprint_symbol_no_offset - Look up a kernel symbol and return it in a text buffer | |
391 | + * @buffer: buffer to be stored | |
392 | + * @address: address to lookup | |
393 | + * | |
394 | + * This function looks up a kernel symbol with @address and stores its name | |
395 | + * and module name to @buffer if possible. If no symbol was found, just saves | |
396 | + * its @address as is. | |
397 | + * | |
398 | + * This function returns the number of bytes stored in @buffer. | |
399 | + */ | |
400 | +int sprint_symbol_no_offset(char *buffer, unsigned long address) | |
401 | +{ | |
402 | + return __sprint_symbol(buffer, address, 0, 0); | |
403 | +} | |
404 | +EXPORT_SYMBOL_GPL(sprint_symbol_no_offset); | |
405 | + | |
406 | +/** | |
391 | 407 | * sprint_backtrace - Look up a backtrace symbol and return it in a text buffer |
392 | 408 | * @buffer: buffer to be stored |
393 | 409 | * @address: address to lookup |
... | ... | @@ -403,7 +419,7 @@ |
403 | 419 | */ |
404 | 420 | int sprint_backtrace(char *buffer, unsigned long address) |
405 | 421 | { |
406 | - return __sprint_symbol(buffer, address, -1); | |
422 | + return __sprint_symbol(buffer, address, -1, 1); | |
407 | 423 | } |
408 | 424 | |
409 | 425 | /* Look up a kernel symbol and print it to the kernel messages. */ |
lib/vsprintf.c