Commit 4796dd200db943e36f876e7029552212e5bbdf33

Authored by Stephen Boyd
Committed by Linus Torvalds
1 parent 05a6c8a922

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;
... ... @@ -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. */
... ... @@ -436,7 +436,7 @@
436 436 else if (ext != 'f' && ext != 's')
437 437 sprint_symbol(sym, value);
438 438 else
439   - kallsyms_lookup(value, NULL, NULL, NULL, sym);
  439 + sprint_symbol_no_offset(sym, value);
440 440  
441 441 return string(buf, end, sym, spec);
442 442 #else