Skip to content

Commit b865ea6

Browse files
sergey-senozhatskypmladek
authored andcommitted
sections: split dereference_function_descriptor()
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/[email protected] To: Fenghua Yu <[email protected]> To: Benjamin Herrenschmidt <[email protected]> To: Paul Mackerras <[email protected]> To: Michael Ellerman <[email protected]> To: James Bottomley <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Jessica Yu <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Sergey Senozhatsky <[email protected]> Tested-by: Tony Luck <[email protected]> #ia64 Tested-by: Santosh Sivaraj <[email protected]> #powerpc Tested-by: Helge Deller <[email protected]> #parisc64 Signed-off-by: Petr Mladek <[email protected]>
1 parent ce666d9 commit b865ea6

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

include/asm-generic/sections.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* __ctors_start, __ctors_end
3131
* __irqentry_text_start, __irqentry_text_end
3232
* __softirqentry_text_start, __softirqentry_text_end
33+
* __start_opd, __end_opd
3334
*/
3435
extern char _text[], _stext[], _etext[];
3536
extern char _data[], _sdata[], _edata[];
@@ -49,12 +50,15 @@ extern char __start_once[], __end_once[];
4950
/* Start and end of .ctors section - used for constructor calls. */
5051
extern char __ctors_start[], __ctors_end[];
5152

53+
/* Start and end of .opd section - used for function descriptors. */
54+
extern char __start_opd[], __end_opd[];
55+
5256
extern __visible const void __nosave_begin, __nosave_end;
5357

54-
/* function descriptor handling (if any). Override
55-
* in asm/sections.h */
58+
/* Function descriptor handling (if any). Override in asm/sections.h */
5659
#ifndef dereference_function_descriptor
5760
#define dereference_function_descriptor(p) (p)
61+
#define dereference_kernel_function_descriptor(p) (p)
5862
#endif
5963

6064
/* random extra sections (if any). Override

include/linux/module.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,9 @@ int ref_module(struct module *a, struct module *b);
606606
__mod ? __mod->name : "kernel"; \
607607
})
608608

609+
/* Dereference module function descriptor */
610+
void *dereference_module_function_descriptor(struct module *mod, void *ptr);
611+
609612
/* For kallsyms to ask for address resolution. namebuf should be at
610613
* least KSYM_NAME_LEN long: a pointer to namebuf is returned if
611614
* found, otherwise NULL. */
@@ -760,6 +763,13 @@ static inline bool is_module_sig_enforced(void)
760763
return false;
761764
}
762765

766+
/* Dereference module function descriptor */
767+
static inline
768+
void *dereference_module_function_descriptor(struct module *mod, void *ptr)
769+
{
770+
return ptr;
771+
}
772+
763773
#endif /* CONFIG_MODULES */
764774

765775
#ifdef CONFIG_SYSFS

kernel/module.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,6 +3938,12 @@ static const char *get_ksymbol(struct module *mod,
39383938
return symname(kallsyms, best);
39393939
}
39403940

3941+
void * __weak dereference_module_function_descriptor(struct module *mod,
3942+
void *ptr)
3943+
{
3944+
return ptr;
3945+
}
3946+
39413947
/* For kallsyms to ask for address resolution. NULL means not found. Careful
39423948
* not to lock to avoid deadlock on oopses, simply disable preemption. */
39433949
const char *module_address_lookup(unsigned long addr,

0 commit comments

Comments
 (0)