From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
To: Tony Luck <tony.luck@intel.com>,
Fenghua Yu <fenghua.yu@intel.com>, Helge Deller <deller@gmx.de>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Paul Mackerras <paulus@samba.org>,
Michael Ellerman <mpe@ellerman.id.au>,
James Bottomley <jejb@parisc-linux.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Jessica Yu <jeyu@kernel.org>, Petr Mladek <pmladek@suse.com>,
Steven Rostedt <rostedt@goodmis.org>,
linux-ia64@vger.kernel.org, linux-parisc@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Subject: [PATCHv4 5/6] symbol lookup: introduce dereference_symbol_descriptor()
Date: Fri, 10 Nov 2017 08:48:29 +0900 [thread overview]
Message-ID: <20171109234830.5067-6-sergey.senozhatsky@gmail.com> (raw)
In-Reply-To: <20171109234830.5067-1-sergey.senozhatsky@gmail.com>
dereference_symbol_descriptor() invokes appropriate ARCH specific
function descriptor dereference callbacks:
- dereference_kernel_function_descriptor() if the pointer is a
kernel symbol;
- dereference_module_function_descriptor() if the pointer is a
module symbol.
This is the last step needed to make '%pS/%ps' smart enough to
handle function descriptor dereference on affected ARCHs and
to retire '%pF/%pf'.
To refresh it:
Some architectures (ia64, ppc64, parisc64) use an indirect pointer
for C function pointers - the function pointer points to a function
descriptor and we need to dereference it to get the actual function
pointer.
Function descriptors live in .opd elf section and all affected
ARCHs (ia64, ppc64, parisc64) handle it properly for kernel and
modules. So we, technically, can decide if the dereference is
needed by simply looking at the pointer: if it belongs to .opd
section then we need to dereference it.
The kernel and modules have their own .opd sections, obviously,
that's why we need to split dereference_function_descriptor()
and use separate kernel and module dereference arch callbacks.
Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
Documentation/printk-formats.txt | 49 ++++++++++++++++------------------------
include/linux/kallsyms.h | 2 ++
kernel/kallsyms.c | 19 ++++++++++++++++
lib/vsprintf.c | 5 ++--
4 files changed, 42 insertions(+), 33 deletions(-)
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index 361789df51ec..2f17e684b72e 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -50,42 +50,31 @@ Symbols/Function Pointers
::
- %pF versatile_init+0x0/0x110
- %pf versatile_init
- %pS versatile_init+0x0/0x110
- %pSR versatile_init+0x9/0x110
- (with __builtin_extract_return_addr() translation)
- %ps versatile_init
- %pB prev_fn_of_versatile_init+0x88/0x88
-
-The ``F`` and ``f`` specifiers are for printing function pointers,
-for example, f->func, &gettimeofday. They have the same result as
-``S`` and ``s`` specifiers. But they do an extra conversion on
-ia64, ppc64 and parisc64 architectures where the function pointers
-are actually function descriptors.
-
-The ``S`` and ``s`` specifiers can be used for printing symbols
-from direct addresses, for example, __builtin_return_address(0),
-(void *)regs->ip. They result in the symbol name with (``S``) or
-without (``s``) offsets. If KALLSYMS are disabled then the symbol
-address is printed instead.
+ %pS versatile_init+0x0/0x110
+ %ps versatile_init
+ %pF versatile_init+0x0/0x110
+ %pf versatile_init
+ %pSR versatile_init+0x9/0x110
+ (with __builtin_extract_return_addr() translation)
+ %pB prev_fn_of_versatile_init+0x88/0x88
+
+The ``S`` and ``s`` specifiers are used for printing a pointer in symbolic
+format. They result in the symbol name with (``S``) or without (``s``)
+offsets. If KALLSYMS are disabled then the symbol address is printed instead.
+
+Note, that the ``F`` and ``f`` specifiers are identical to ``S`` (``s``)
+and thus deprecated. We have ``F`` and ``f`` because on ia64, ppc64 and
+parisc64 function pointers are indirect and, in fact, are function
+descriptors, which require additional dereferencing before we can lookup
+the symbol. As of now, ``S`` and ``s`` perform dereferencing on those
+platforms (when needed), so ``F`` and ``f`` exist for compatibility
+reasons only.
The ``B`` specifier results in the symbol name with offsets and should be
used when printing stack backtraces. The specifier takes into
consideration the effect of compiler optimisations which may occur
when tail-call``s are used and marked with the noreturn GCC attribute.
-Examples::
-
- printk("Going to call: %pF\n", gettimeofday);
- printk("Going to call: %pF\n", p->func);
- printk("%s: called from %pS\n", __func__, (void *)_RET_IP_);
- printk("%s: called from %pS\n", __func__,
- (void *)__builtin_return_address(0));
- printk("Faulted at %pS\n", (void *)regs->ip);
- printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack);
-
-
Kernel Pointers
===============
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 11dd93e42580..73f7e874c3e1 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -16,6 +16,8 @@
struct module;
+void *dereference_symbol_descriptor(void *ptr);
+
#ifdef CONFIG_KALLSYMS
/* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name);
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 1966fe1c2b57..18b3dffc4b84 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -411,6 +411,25 @@ static int __sprint_symbol(char *buffer, unsigned long address,
return len;
}
+void *dereference_symbol_descriptor(void *ptr)
+{
+#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
+ struct module *mod;
+
+ ptr = dereference_kernel_function_descriptor(ptr);
+ if (is_ksym_addr((unsigned long)ptr))
+ return ptr;
+
+ preempt_disable();
+ mod = __module_address((unsigned long)ptr);
+ preempt_enable();
+
+ if (mod)
+ ptr = dereference_module_function_descriptor(mod, ptr);
+#endif
+ return ptr;
+}
+
/**
* sprint_symbol - Look up a kernel symbol and return it in a text buffer
* @buffer: buffer to be stored
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 1746bae94d41..16e2eefb0f79 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -40,7 +40,6 @@
#include "../mm/internal.h" /* For the trace_print_flags arrays */
#include <asm/page.h> /* for PAGE_SIZE */
-#include <asm/sections.h> /* for dereference_function_descriptor() */
#include <asm/byteorder.h> /* cpu_to_le16 */
#include <linux/string_helpers.h>
@@ -1723,10 +1722,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
switch (*fmt) {
case 'F':
case 'f':
- ptr = dereference_function_descriptor(ptr);
- /* Fallthrough */
case 'S':
case 's':
+ ptr = dereference_symbol_descriptor(ptr);
+ /* Fallthrough */
case 'B':
return symbol_string(buf, end, ptr, spec, fmt);
case 'R':
--
2.15.0
next prev parent reply other threads:[~2017-11-09 23:50 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-09 23:48 [PATCHv4 0/6] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers Sergey Senozhatsky
2017-11-09 23:48 ` [PATCHv4 1/6] sections: split dereference_function_descriptor() Sergey Senozhatsky
2017-11-09 23:48 ` [PATCHv4 2/6] ia64: Add .opd based function descriptor dereference Sergey Senozhatsky
2017-11-09 23:48 ` [PATCHv4 3/6] powerpc64: " Sergey Senozhatsky
2017-11-13 7:11 ` Santosh Sivaraj
2017-11-13 9:35 ` Sergey Senozhatsky
2017-11-09 23:48 ` [PATCHv4 4/6] parisc64: " Sergey Senozhatsky
2017-11-09 23:48 ` Sergey Senozhatsky [this message]
2017-11-10 18:09 ` [PATCHv4 5/6] symbol lookup: introduce dereference_symbol_descriptor() Luck, Tony
2017-11-11 4:49 ` Sergey Senozhatsky
2017-11-28 15:44 ` Petr Mladek
2017-12-06 4:36 ` Sergey Senozhatsky
2017-12-06 10:32 ` Petr Mladek
2017-12-06 10:46 ` Sergey Senozhatsky
2017-11-09 23:48 ` [PATCHv4 6/6] checkpatch: add pF/pf deprecation warning Sergey Senozhatsky
2017-11-10 18:11 ` [PATCHv4 0/6] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers Luck, Tony
2017-11-11 4:41 ` Sergey Senozhatsky
2017-11-13 17:17 ` Helge Deller
2017-11-14 1:29 ` Sergey Senozhatsky
2017-11-28 15:47 ` Petr Mladek
2017-11-29 7:24 ` Sergey Senozhatsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171109234830.5067-6-sergey.senozhatsky@gmail.com \
--to=sergey.senozhatsky@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=benh@kernel.crashing.org \
--cc=deller@gmx.de \
--cc=fenghua.yu@intel.com \
--cc=jejb@parisc-linux.org \
--cc=jeyu@kernel.org \
--cc=linux-ia64@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-parisc@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=paulus@samba.org \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.org \
--cc=sergey.senozhatsky.work@gmail.com \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®