| From 22823ab419d8ed884195cfa75483fd3a99bb1462 Mon Sep 17 00:00:00 2001 |
| From: Al Viro <viro@zeniv.linux.org.uk> |
| Date: Mon, 11 Jan 2016 10:54:54 -0500 |
| Subject: [PATCH] EXPORT_SYMBOL() for asm |
| |
| commit 22823ab419d8ed884195cfa75483fd3a99bb1462 upstream. |
| |
| Add asm-usable variants of EXPORT_SYMBOL/EXPORT_SYMBOL_GPL. This |
| commit just adds the default implementation; most of the architectures |
| can simply add export.h to asm/Kbuild and start using <asm/export.h> |
| from assembler. The rest needs to have their <asm/export.h> define |
| everal macros and then explicitly include <asm-generic/export.h> |
| |
| One area where the things might diverge from default is the alignment; |
| normally it's 8 bytes on 64bit targets and 4 on 32bit ones, both for |
| unsigned long and for struct kernel_symbol. Unfortunately, amd64 and |
| m68k are unusual - m68k aligns to 2 bytes (for both) and amd64 aligns |
| struct kernel_symbol to 16 bytes. For those we'll need asm/export.h to |
| override the constants used by generic version - KSYM_ALIGN and KCRC_ALIGN |
| for kernel_symbol and unsigned long resp. And no, __alignof__ would not |
| do the trick - on amd64 __alignof__ of struct kernel_symbol is 8, not 16. |
| |
| More serious source of unpleasantness is treatment of function |
| descriptors on architectures that have those. Things like ppc64, |
| parisc, ia64, etc. need more than the address of the first insn to |
| call an arbitrary function. As the result, their representation of |
| pointers to functions is not the typical "address of the entry point" - |
| it's an address of a small static structure containing all the required |
| information (including the entry point, of course). Sadly, the asm-side |
| conventions differ in what the function name refers to - entry point or |
| the function descriptor. On ppc64 we do the latter; |
| bar: .quad foo |
| is what void (*bar)(void) = foo; turns into and the rare places where |
| we need to explicitly work with the label of entry point are dealt with |
| as DOTSYM(foo). For our purposes it's ideal - generic macros are usable. |
| However, parisc would have foo and P%foo used for label of entry point |
| and address of the function descriptor and |
| bar: .long P%foo |
| woudl be used instead. ia64 goes similar to parisc in that respect, |
| except that there it's @fptr(foo) rather than P%foo. Such architectures |
| need to define KSYM_FUNC that would turn a function name into whatever |
| is needed to refer to function descriptor. |
| |
| What's more, on such architectures we need to know whether we are exporting |
| a function or an object - in assembler we have to tell that explicitly, to |
| decide whether we want EXPORT_SYMBOL(foo) produce e.g. |
| __ksymtab_foo: .quad foo |
| or |
| __ksymtab_foo: .quad @fptr(foo) |
| |
| For that reason we introduce EXPORT_DATA_SYMBOL{,_GPL}(), to be used for |
| exports of data objects. On normal architectures it's the same thing |
| as EXPORT_SYMBOL{,_GPL}(), but on parisc-like ones they differ and the |
| right one needs to be used. Most of the exports are functions, so we |
| keep EXPORT_SYMBOL for those... |
| |
| Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> |
| |
| diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h |
| new file mode 100644 |
| index 000000000000..43199a049da5 |
| --- /dev/null |
| +++ b/include/asm-generic/export.h |
| @@ -0,0 +1,94 @@ |
| +#ifndef __ASM_GENERIC_EXPORT_H |
| +#define __ASM_GENERIC_EXPORT_H |
| + |
| +#ifndef KSYM_FUNC |
| +#define KSYM_FUNC(x) x |
| +#endif |
| +#ifdef CONFIG_64BIT |
| +#define __put .quad |
| +#ifndef KSYM_ALIGN |
| +#define KSYM_ALIGN 8 |
| +#endif |
| +#ifndef KCRC_ALIGN |
| +#define KCRC_ALIGN 8 |
| +#endif |
| +#else |
| +#define __put .long |
| +#ifndef KSYM_ALIGN |
| +#define KSYM_ALIGN 4 |
| +#endif |
| +#ifndef KCRC_ALIGN |
| +#define KCRC_ALIGN 4 |
| +#endif |
| +#endif |
| + |
| +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX |
| +#define KSYM(name) _##name |
| +#else |
| +#define KSYM(name) name |
| +#endif |
| + |
| +/* |
| + * note on .section use: @progbits vs %progbits nastiness doesn't matter, |
| + * since we immediately emit into those sections anyway. |
| + */ |
| +.macro ___EXPORT_SYMBOL name,val,sec |
| +#ifdef CONFIG_MODULES |
| + .globl KSYM(__ksymtab_\name) |
| + .section ___ksymtab\sec+\name,"a" |
| + .balign KSYM_ALIGN |
| +KSYM(__ksymtab_\name): |
| + __put \val, KSYM(__kstrtab_\name) |
| + .previous |
| + .section __ksymtab_strings,"a" |
| +KSYM(__kstrtab_\name): |
| +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX |
| + .asciz "_\name" |
| +#else |
| + .asciz "\name" |
| +#endif |
| + .previous |
| +#ifdef CONFIG_MODVERSIONS |
| + .section ___kcrctab\sec+\name,"a" |
| + .balign KCRC_ALIGN |
| +KSYM(__kcrctab_\name): |
| + __put KSYM(__crc_\name) |
| + .weak KSYM(__crc_\name) |
| + .previous |
| +#endif |
| +#endif |
| +.endm |
| +#undef __put |
| + |
| +#if defined(__KSYM_DEPS__) |
| + |
| +#define __EXPORT_SYMBOL(sym, val, sec) === __KSYM_##sym === |
| + |
| +#elif defined(CONFIG_TRIM_UNUSED_KSYMS) |
| + |
| +#include <linux/kconfig.h> |
| +#include <generated/autoksyms.h> |
| + |
| +#define __EXPORT_SYMBOL(sym, val, sec) \ |
| + __cond_export_sym(sym, val, sec, config_enabled(__KSYM_##sym)) |
| +#define __cond_export_sym(sym, val, sec, conf) \ |
| + ___cond_export_sym(sym, val, sec, conf) |
| +#define ___cond_export_sym(sym, val, sec, enabled) \ |
| + __cond_export_sym_##enabled(sym, val, sec) |
| +#define __cond_export_sym_1(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec |
| +#define __cond_export_sym_0(sym, val, sec) /* nothing */ |
| + |
| +#else |
| +#define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec |
| +#endif |
| + |
| +#define EXPORT_SYMBOL(name) \ |
| + __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)),) |
| +#define EXPORT_SYMBOL_GPL(name) \ |
| + __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)), _gpl) |
| +#define EXPORT_DATA_SYMBOL(name) \ |
| + __EXPORT_SYMBOL(name, KSYM(name),) |
| +#define EXPORT_DATA_SYMBOL_GPL(name) \ |
| + __EXPORT_SYMBOL(name, KSYM(name),_gpl) |
| + |
| +#endif |
| -- |
| 2.15.0 |
| |