diff options
| -rw-r--r-- | include/asm-generic/export.h | 6 | ||||
| -rw-r--r-- | include/linux/export.h | 91 | ||||
| -rw-r--r-- | include/linux/module.h | 2 | ||||
| -rw-r--r-- | kernel/module.c | 43 |
4 files changed, 123 insertions, 19 deletions
diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 63f54907317b..e2b5d0f569d3 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h | |||
| @@ -17,11 +17,11 @@ | |||
| 17 | 17 | ||
| 18 | .macro __put, val, name | 18 | .macro __put, val, name |
| 19 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | 19 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS |
| 20 | .long \val - ., \name - . | 20 | .long \val - ., \name - ., 0 - . |
| 21 | #elif defined(CONFIG_64BIT) | 21 | #elif defined(CONFIG_64BIT) |
| 22 | .quad \val, \name | 22 | .quad \val, \name, 0 |
| 23 | #else | 23 | #else |
| 24 | .long \val, \name | 24 | .long \val, \name, 0 |
| 25 | #endif | 25 | #endif |
| 26 | .endm | 26 | .endm |
| 27 | 27 | ||
diff --git a/include/linux/export.h b/include/linux/export.h index 28a4d2150689..d59461e71478 100644 --- a/include/linux/export.h +++ b/include/linux/export.h | |||
| @@ -20,6 +20,8 @@ extern struct module __this_module; | |||
| 20 | 20 | ||
| 21 | #ifdef CONFIG_MODULES | 21 | #ifdef CONFIG_MODULES |
| 22 | 22 | ||
| 23 | #define NS_SEPARATOR "." | ||
| 24 | |||
| 23 | #if defined(__KERNEL__) && !defined(__GENKSYMS__) | 25 | #if defined(__KERNEL__) && !defined(__GENKSYMS__) |
| 24 | #ifdef CONFIG_MODVERSIONS | 26 | #ifdef CONFIG_MODVERSIONS |
| 25 | /* Mark the CRC weak since genksyms apparently decides not to | 27 | /* Mark the CRC weak since genksyms apparently decides not to |
| @@ -29,13 +31,13 @@ extern struct module __this_module; | |||
| 29 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ | 31 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ |
| 30 | " .weak __crc_" #sym " \n" \ | 32 | " .weak __crc_" #sym " \n" \ |
| 31 | " .long __crc_" #sym " - . \n" \ | 33 | " .long __crc_" #sym " - . \n" \ |
| 32 | " .previous \n"); | 34 | " .previous \n") |
| 33 | #else | 35 | #else |
| 34 | #define __CRC_SYMBOL(sym, sec) \ | 36 | #define __CRC_SYMBOL(sym, sec) \ |
| 35 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ | 37 | asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ |
| 36 | " .weak __crc_" #sym " \n" \ | 38 | " .weak __crc_" #sym " \n" \ |
| 37 | " .long __crc_" #sym " \n" \ | 39 | " .long __crc_" #sym " \n" \ |
| 38 | " .previous \n"); | 40 | " .previous \n") |
| 39 | #endif | 41 | #endif |
| 40 | #else | 42 | #else |
| 41 | #define __CRC_SYMBOL(sym, sec) | 43 | #define __CRC_SYMBOL(sym, sec) |
| @@ -49,6 +51,16 @@ extern struct module __this_module; | |||
| 49 | * absolute relocations that require runtime processing on relocatable | 51 | * absolute relocations that require runtime processing on relocatable |
| 50 | * kernels. | 52 | * kernels. |
| 51 | */ | 53 | */ |
| 54 | #define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ | ||
| 55 | __ADDRESSABLE(sym) \ | ||
| 56 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ | ||
| 57 | " .balign 4 \n" \ | ||
| 58 | "__ksymtab_" #sym NS_SEPARATOR #ns ": \n" \ | ||
| 59 | " .long " #sym "- . \n" \ | ||
| 60 | " .long __kstrtab_" #sym "- . \n" \ | ||
| 61 | " .long __kstrtab_ns_" #sym "- . \n" \ | ||
| 62 | " .previous \n") | ||
| 63 | |||
| 52 | #define __KSYMTAB_ENTRY(sym, sec) \ | 64 | #define __KSYMTAB_ENTRY(sym, sec) \ |
| 53 | __ADDRESSABLE(sym) \ | 65 | __ADDRESSABLE(sym) \ |
| 54 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ | 66 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ |
| @@ -56,32 +68,53 @@ extern struct module __this_module; | |||
| 56 | "__ksymtab_" #sym ": \n" \ | 68 | "__ksymtab_" #sym ": \n" \ |
| 57 | " .long " #sym "- . \n" \ | 69 | " .long " #sym "- . \n" \ |
| 58 | " .long __kstrtab_" #sym "- . \n" \ | 70 | " .long __kstrtab_" #sym "- . \n" \ |
| 71 | " .long 0 - . \n" \ | ||
| 59 | " .previous \n") | 72 | " .previous \n") |
| 60 | 73 | ||
| 61 | struct kernel_symbol { | 74 | struct kernel_symbol { |
| 62 | int value_offset; | 75 | int value_offset; |
| 63 | int name_offset; | 76 | int name_offset; |
| 77 | int namespace_offset; | ||
| 64 | }; | 78 | }; |
| 65 | #else | 79 | #else |
| 80 | #define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ | ||
| 81 | static const struct kernel_symbol __ksymtab_##sym##__##ns \ | ||
| 82 | asm("__ksymtab_" #sym NS_SEPARATOR #ns) \ | ||
| 83 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ | ||
| 84 | __aligned(sizeof(void *)) \ | ||
| 85 | = { (unsigned long)&sym, __kstrtab_##sym, __kstrtab_ns_##sym } | ||
| 86 | |||
| 66 | #define __KSYMTAB_ENTRY(sym, sec) \ | 87 | #define __KSYMTAB_ENTRY(sym, sec) \ |
| 67 | static const struct kernel_symbol __ksymtab_##sym \ | 88 | static const struct kernel_symbol __ksymtab_##sym \ |
| 89 | asm("__ksymtab_" #sym) \ | ||
| 68 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ | 90 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ |
| 69 | __aligned(sizeof(void *)) \ | 91 | __aligned(sizeof(void *)) \ |
| 70 | = { (unsigned long)&sym, __kstrtab_##sym } | 92 | = { (unsigned long)&sym, __kstrtab_##sym, NULL } |
| 71 | 93 | ||
| 72 | struct kernel_symbol { | 94 | struct kernel_symbol { |
| 73 | unsigned long value; | 95 | unsigned long value; |
| 74 | const char *name; | 96 | const char *name; |
| 97 | const char *namespace; | ||
| 75 | }; | 98 | }; |
| 76 | #endif | 99 | #endif |
| 77 | 100 | ||
| 78 | /* For every exported symbol, place a struct in the __ksymtab section */ | 101 | #define ___export_symbol_common(sym, sec) \ |
| 79 | #define ___EXPORT_SYMBOL(sym, sec) \ | ||
| 80 | extern typeof(sym) sym; \ | 102 | extern typeof(sym) sym; \ |
| 81 | __CRC_SYMBOL(sym, sec) \ | 103 | __CRC_SYMBOL(sym, sec); \ |
| 82 | static const char __kstrtab_##sym[] \ | 104 | static const char __kstrtab_##sym[] \ |
| 83 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ | 105 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ |
| 84 | = #sym; \ | 106 | = #sym \ |
| 107 | |||
| 108 | /* For every exported symbol, place a struct in the __ksymtab section */ | ||
| 109 | #define ___EXPORT_SYMBOL_NS(sym, sec, ns) \ | ||
| 110 | ___export_symbol_common(sym, sec); \ | ||
| 111 | static const char __kstrtab_ns_##sym[] \ | ||
| 112 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ | ||
| 113 | = #ns; \ | ||
| 114 | __KSYMTAB_ENTRY_NS(sym, sec, ns) | ||
| 115 | |||
| 116 | #define ___EXPORT_SYMBOL(sym, sec) \ | ||
| 117 | ___export_symbol_common(sym, sec); \ | ||
| 85 | __KSYMTAB_ENTRY(sym, sec) | 118 | __KSYMTAB_ENTRY(sym, sec) |
| 86 | 119 | ||
| 87 | #if defined(__DISABLE_EXPORTS) | 120 | #if defined(__DISABLE_EXPORTS) |
| @@ -91,6 +124,7 @@ struct kernel_symbol { | |||
| 91 | * be reused in other execution contexts such as the UEFI stub or the | 124 | * be reused in other execution contexts such as the UEFI stub or the |
| 92 | * decompressor. | 125 | * decompressor. |
| 93 | */ | 126 | */ |
| 127 | #define __EXPORT_SYMBOL_NS(sym, sec, ns) | ||
| 94 | #define __EXPORT_SYMBOL(sym, sec) | 128 | #define __EXPORT_SYMBOL(sym, sec) |
| 95 | 129 | ||
| 96 | #elif defined(CONFIG_TRIM_UNUSED_KSYMS) | 130 | #elif defined(CONFIG_TRIM_UNUSED_KSYMS) |
| @@ -117,18 +151,26 @@ struct kernel_symbol { | |||
| 117 | #define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec) | 151 | #define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec) |
| 118 | #define __cond_export_sym_0(sym, sec) /* nothing */ | 152 | #define __cond_export_sym_0(sym, sec) /* nothing */ |
| 119 | 153 | ||
| 154 | #define __EXPORT_SYMBOL_NS(sym, sec, ns) \ | ||
| 155 | __ksym_marker(sym); \ | ||
| 156 | __cond_export_ns_sym(sym, sec, ns, __is_defined(__KSYM_##sym)) | ||
| 157 | #define __cond_export_ns_sym(sym, sec, ns, conf) \ | ||
| 158 | ___cond_export_ns_sym(sym, sec, ns, conf) | ||
| 159 | #define ___cond_export_ns_sym(sym, sec, ns, enabled) \ | ||
| 160 | __cond_export_ns_sym_##enabled(sym, sec, ns) | ||
| 161 | #define __cond_export_ns_sym_1(sym, sec, ns) ___EXPORT_SYMBOL_NS(sym, sec, ns) | ||
| 162 | #define __cond_export_ns_sym_0(sym, sec, ns) /* nothing */ | ||
| 163 | |||
| 120 | #else | 164 | #else |
| 165 | #define __EXPORT_SYMBOL_NS ___EXPORT_SYMBOL_NS | ||
| 121 | #define __EXPORT_SYMBOL ___EXPORT_SYMBOL | 166 | #define __EXPORT_SYMBOL ___EXPORT_SYMBOL |
| 122 | #endif | 167 | #endif |
| 123 | 168 | ||
| 124 | #define EXPORT_SYMBOL(sym) \ | 169 | #define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") |
| 125 | __EXPORT_SYMBOL(sym, "") | 170 | #define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") |
| 126 | 171 | #define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future") | |
| 127 | #define EXPORT_SYMBOL_GPL(sym) \ | 172 | #define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL_NS(sym, "", ns) |
| 128 | __EXPORT_SYMBOL(sym, "_gpl") | 173 | #define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL_NS(sym, "_gpl", ns) |
| 129 | |||
| 130 | #define EXPORT_SYMBOL_GPL_FUTURE(sym) \ | ||
| 131 | __EXPORT_SYMBOL(sym, "_gpl_future") | ||
| 132 | 174 | ||
| 133 | #ifdef CONFIG_UNUSED_SYMBOLS | 175 | #ifdef CONFIG_UNUSED_SYMBOLS |
| 134 | #define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") | 176 | #define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") |
| @@ -138,11 +180,28 @@ struct kernel_symbol { | |||
| 138 | #define EXPORT_UNUSED_SYMBOL_GPL(sym) | 180 | #define EXPORT_UNUSED_SYMBOL_GPL(sym) |
| 139 | #endif | 181 | #endif |
| 140 | 182 | ||
| 141 | #endif /* __GENKSYMS__ */ | 183 | #endif /* __KERNEL__ && !__GENKSYMS__ */ |
| 184 | |||
| 185 | #if defined(__GENKSYMS__) | ||
| 186 | /* | ||
| 187 | * When we're running genksyms, ignore the namespace and make the _NS | ||
| 188 | * variants look like the normal ones. There are two reasons for this: | ||
| 189 | * 1) In the normal definition of EXPORT_SYMBOL_NS, the 'ns' macro | ||
