Skip to content
  • Sergey Senozhatsky's avatar
    sections: split dereference_function_descriptor() · b865ea64
    Sergey Senozhatsky authored
    There are two format specifiers to print out a pointer in symbolic
    format: '%pS/%ps' and '%pF/%pf'. On most architectures, the two
    mean exactly the same thing, but some architectures (ia64, ppc64,
    parisc64) use an indirect pointer for C function pointers, where
    the function pointer points to a function descriptor (which in
    turn contains the actual pointer to the code). The '%pF/%pf, when
    used appropriately, automatically does the appropriate function
    descriptor dereference on such architectures.
    
    The "when used appropriately" part is tricky. Basically this is
    a subtle ABI detail, specific to some platforms, that made it to
    the API level and people can be unaware of it and miss the whole
    "we need to dereference the function" business out. [1] proves
    that point (note that it fixes only '%pF' and '%pS', there might
    be '%pf' and '%ps' cases as well).
    
    It appears that we can handle everything within the affected
    arches and make '%pS/%ps' smart enough to retire '%pF/%pf'.
    Function descriptors live in .opd elf section and all affected
    arches (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.
    
    This patch does the first step, it
    a) adds dereference_kernel_function_descriptor() function.
    b) adds a weak alias to dereference_module_function_descriptor()
       function.
    
    So, for the time being, we will have:
    1) dereference_function_descriptor()
       A generic function, that simply dereferences the pointer. There is
       bunch of places that call it: kgdbts, init/main.c, extable, etc.
    
    2) dereference_kernel_function_descriptor()
       A function to call on kernel symbols that does kernel .opd section
       address range test.
    
    3) dereference_module_function_descriptor()
       A function to call on modules' symbols that does modules' .opd
       section address range test.
    
    [1] https://marc.info/?l=linux-kernel&m=150472969730573
    
    Link: http://lkml.kernel.org/r/20171109234830.5067-2-sergey.senozhatsky@gmail.com
    
    
    To: Fenghua Yu <fenghua.yu@intel.com>
    To: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    To: Paul Mackerras <paulus@samba.org>
    To: Michael Ellerman <mpe@ellerman.id.au>
    To: James Bottomley <jejb@parisc-linux.org>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Jessica Yu <jeyu@kernel.org>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: linux-ia64@vger.kernel.org
    Cc: linux-parisc@vger.kernel.org
    Cc: linuxppc-dev@lists.ozlabs.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
    Tested-by: Tony Luck <tony.luck@intel.com> #ia64
    Tested-by: Santosh Sivaraj <santosh@fossix.org> #powerpc
    Tested-by: Helge Deller <deller@gmx.de> #parisc64
    Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
    b865ea64