diff options
-rw-r--r-- | include/linux/module.h | 2 | ||||
-rw-r--r-- | init/Kconfig | 4 | ||||
-rw-r--r-- | kernel/module.c | 49 |
3 files changed, 38 insertions, 17 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 63f0eb69e214..a860a2c1f379 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -257,6 +257,7 @@ struct module | |||
257 | const struct kernel_symbol *gpl_syms; | 257 | const struct kernel_symbol *gpl_syms; |
258 | const unsigned long *gpl_crcs; | 258 | const unsigned long *gpl_crcs; |
259 | 259 | ||
260 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
260 | /* unused exported symbols. */ | 261 | /* unused exported symbols. */ |
261 | const struct kernel_symbol *unused_syms; | 262 | const struct kernel_symbol *unused_syms; |
262 | const unsigned long *unused_crcs; | 263 | const unsigned long *unused_crcs; |
@@ -266,6 +267,7 @@ struct module | |||
266 | unsigned int num_unused_gpl_syms; | 267 | unsigned int num_unused_gpl_syms; |
267 | const struct kernel_symbol *unused_gpl_syms; | 268 | const struct kernel_symbol *unused_gpl_syms; |
268 | const unsigned long *unused_gpl_crcs; | 269 | const unsigned long *unused_gpl_crcs; |
270 | #endif | ||
269 | 271 | ||
270 | /* symbols that will be GPL-only in the near future. */ | 272 | /* symbols that will be GPL-only in the near future. */ |
271 | const struct kernel_symbol *gpl_future_syms; | 273 | const struct kernel_symbol *gpl_future_syms; |
diff --git a/init/Kconfig b/init/Kconfig index 6199d1120900..c8578f9ee31d 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -856,8 +856,8 @@ config MODULE_UNLOAD | |||
856 | help | 856 | help |
857 | Without this option you will not be able to unload any | 857 | Without this option you will not be able to unload any |
858 | modules (note that some modules may not be unloadable | 858 | modules (note that some modules may not be unloadable |
859 | anyway), which makes your kernel slightly smaller and | 859 | anyway), which makes your kernel smaller, faster |
860 | simpler. If unsure, say Y. | 860 | and simpler. If unsure, say Y. |
861 | 861 | ||
862 | config MODULE_FORCE_UNLOAD | 862 | config MODULE_FORCE_UNLOAD |
863 | bool "Forced module unloading" | 863 | bool "Forced module unloading" |
diff --git a/kernel/module.c b/kernel/module.c index c51c089c666e..ea9580521eb1 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -134,17 +134,19 @@ extern const struct kernel_symbol __start___ksymtab_gpl[]; | |||
134 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; | 134 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; |
135 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | 135 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; |
136 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | 136 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; |
137 | extern const struct kernel_symbol __start___ksymtab_unused[]; | ||
138 | extern const struct kernel_symbol __stop___ksymtab_unused[]; | ||
139 | extern const struct kernel_symbol __start___ksymtab_unused_gpl[]; | ||
140 | extern const struct kernel_symbol __stop___ksymtab_unused_gpl[]; | ||
141 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | 137 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; |
142 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | 138 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; |
143 | extern const unsigned long __start___kcrctab[]; | 139 | extern const unsigned long __start___kcrctab[]; |
144 | extern const unsigned long __start___kcrctab_gpl[]; | 140 | extern const unsigned long __start___kcrctab_gpl[]; |
145 | extern const unsigned long __start___kcrctab_gpl_future[]; | 141 | extern const unsigned long __start___kcrctab_gpl_future[]; |
142 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
143 | extern const struct kernel_symbol __start___ksymtab_unused[]; | ||
144 | extern const struct kernel_symbol __stop___ksymtab_unused[]; | ||
145 | extern const struct kernel_symbol __start___ksymtab_unused_gpl[]; | ||
146 | extern const struct kernel_symbol __stop___ksymtab_unused_gpl[]; | ||
146 | extern const unsigned long __start___kcrctab_unused[]; | 147 | extern const unsigned long __start___kcrctab_unused[]; |
147 | extern const unsigned long __start___kcrctab_unused_gpl[]; | 148 | extern const unsigned long __start___kcrctab_unused_gpl[]; |
149 | #endif | ||
148 | 150 | ||
149 | #ifndef CONFIG_MODVERSIONS | 151 | #ifndef CONFIG_MODVERSIONS |
150 | #define symversion(base, idx) NULL | 152 | #define symversion(base, idx) NULL |
@@ -198,12 +200,14 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr, | |||
198 | { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future, | 200 | { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future, |
199 | __start___kcrctab_gpl_future, | 201 | __start___kcrctab_gpl_future, |
200 | WILL_BE_GPL_ONLY, false }, | 202 | WILL_BE_GPL_ONLY, false }, |
203 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
201 | { __start___ksymtab_unused, __stop___ksymtab_unused, | 204 | { __start___ksymtab_unused, __stop___ksymtab_unused, |
202 | __start___kcrctab_unused, | 205 | __start___kcrctab_unused, |
203 | NOT_GPL_ONLY, true }, | 206 | NOT_GPL_ONLY, true }, |
204 | { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl, | 207 | { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl, |
205 | __start___kcrctab_unused_gpl, | 208 | __start___kcrctab_unused_gpl, |
206 | GPL_ONLY, true }, | 209 | GPL_ONLY, true }, |
210 | #endif | ||
207 | }; | 211 | }; |
208 | 212 | ||
209 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) | 213 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) |
@@ -220,6 +224,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr, | |||
220 | mod->gpl_future_syms + mod->num_gpl_future_syms, | 224 | mod->gpl_future_syms + mod->num_gpl_future_syms, |
221 | mod->gpl_future_crcs, | 225 | mod->gpl_future_crcs, |
222 | WILL_BE_GPL_ONLY, false }, | 226 | WILL_BE_GPL_ONLY, false }, |
227 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
223 | { mod->unused_syms, | 228 | { mod->unused_syms, |
224 | mod->unused_syms + mod->num_unused_syms, | 229 | mod->unused_syms + mod->num_unused_syms, |
225 | mod->unused_crcs, | 230 | mod->unused_crcs, |
@@ -228,6 +233,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr, | |||
228 | mod->unused_gpl_syms + mod->num_unused_gpl_syms, | 233 | mod->unused_gpl_syms + mod->num_unused_gpl_syms, |
229 | mod->unused_gpl_crcs, | 234 | mod->unused_gpl_crcs, |
230 | GPL_ONLY, true }, | 235 | GPL_ONLY, true }, |
236 | #endif | ||
231 | }; | 237 | }; |
232 | 238 | ||
233 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data)) | 239 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data)) |
@@ -270,6 +276,7 @@ static bool find_symbol_in_section(const struct symsearch *syms, | |||
270 | } | 276 | } |
271 | } | 277 | } |
272 | 278 | ||
279 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
273 | if (syms->unused && fsa->warn) { | 280 | if (syms->unused && fsa->warn) { |
274 | printk(KERN_WARNING "Symbol %s is marked as UNUSED, " | 281 | printk(KERN_WARNING "Symbol %s is marked as UNUSED, " |
275 | "however this module is using it.\n", fsa->name); | 282 | "however this module is using it.\n", fsa->name); |
@@ -281,6 +288,7 @@ static bool find_symbol_in_section(const struct symsearch *syms, | |||
281 | "mailinglist together with submitting your code for " | 288 | "mailinglist together with submitting your code for " |
282 | "inclusion.\n"); | 289 | "inclusion.\n"); |
283 | } | 290 | } |
291 | #endif | ||
284 | 292 | ||
285 | fsa->owner = owner; | 293 | fsa->owner = owner; |
286 | fsa->crc = symversion(syms->crcs, symnum); | 294 | fsa->crc = symversion(syms->crcs, symnum); |
@@ -1476,8 +1484,10 @@ static int verify_export_symbols(struct module *mod) | |||
1476 | { mod->syms, mod->num_syms }, | 1484 | { mod->syms, mod->num_syms }, |
1477 | { mod->gpl_syms, mod->num_gpl_syms }, | 1485 | { mod->gpl_syms, mod->num_gpl_syms }, |
1478 | { mod->gpl_future_syms, mod->num_gpl_future_syms }, | 1486 | { mod->gpl_future_syms, mod->num_gpl_future_syms }, |
1487 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
1479 | { mod->unused_syms, mod->num_unused_syms }, | 1488 | { mod->unused_syms, mod->num_unused_syms }, |
1480 | { mod->unused_gpl_syms, mod->num_unused_gpl_syms }, | 1489 | { mod->unused_gpl_syms, mod->num_unused_gpl_syms }, |
1490 | #endif | ||
1481 | }; | 1491 | }; |
1482 | 1492 | ||
1483 | for (i = 0; i < ARRAY_SIZE(arr); i++) { | 1493 | for (i = 0; i < ARRAY_SIZE(arr); i++) { |
@@ -1795,10 +1805,12 @@ static struct module *load_module(void __user *umod, | |||
1795 | unsigned int gplfutureindex; | 1805 | unsigned int gplfutureindex; |
1796 | unsigned int gplfuturecrcindex; | 1806 | unsigned int gplfuturecrcindex; |
1797 | unsigned int unwindex = 0; | 1807 | unsigned int unwindex = 0; |
1808 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
1798 | unsigned int unusedindex; | 1809 | unsigned int unusedindex; |
1799 | unsigned int unusedcrcindex; | 1810 | unsigned int unusedcrcindex; |
1800 | unsigned int unusedgplindex; | 1811 | unsigned int unusedgplindex; |
1801 | unsigned int unusedgplcrcindex; | 1812 | unsigned int unusedgplcrcindex; |
1813 | #endif | ||
1802 | unsigned int markersindex; | 1814 | unsigned int markersindex; |
1803 | unsigned int markersstringsindex; | 1815 | unsigned int markersstringsindex; |
1804 | struct module *mod; | 1816 | struct module *mod; |
@@ -1881,13 +1893,15 @@ static struct module *load_module(void __user *umod, | |||
1881 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); | 1893 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); |
1882 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); | 1894 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); |
1883 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); | 1895 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); |
1884 | unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused"); | ||
1885 | unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl"); | ||
1886 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); | 1896 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); |
1887 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | 1897 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); |
1888 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); | 1898 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); |
1899 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
1900 | unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused"); | ||
1901 | unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl"); | ||
1889 | unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused"); | 1902 | unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused"); |
1890 | unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl"); | 1903 | unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl"); |
1904 | #endif | ||
1891 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); | 1905 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); |
1892 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); | 1906 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); |
1893 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); | 1907 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); |
@@ -2049,14 +2063,15 @@ static struct module *load_module(void __user *umod, | |||
2049 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; | 2063 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; |
2050 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / | 2064 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / |
2051 | sizeof(*mod->gpl_future_syms); | 2065 | sizeof(*mod->gpl_future_syms); |
2052 | mod->num_unused_syms = sechdrs[unusedindex].sh_size / | ||
2053 | sizeof(*mod->unused_syms); | ||
2054 | mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size / | ||
2055 | sizeof(*mod->unused_gpl_syms); | ||
2056 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; | 2066 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; |
2057 | if (gplfuturecrcindex) | 2067 | if (gplfuturecrcindex) |
2058 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; | 2068 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; |
2059 | 2069 | ||
2070 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
2071 | mod->num_unused_syms = sechdrs[unusedindex].sh_size / | ||
2072 | sizeof(*mod->unused_syms); | ||
2073 | mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size / | ||
2074 | sizeof(*mod->unused_gpl_syms); | ||
2060 | mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr; | 2075 | mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr; |
2061 | if (unusedcrcindex) | 2076 | if (unusedcrcindex) |
2062 | mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr; | 2077 | mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr; |
@@ -2064,13 +2079,17 @@ static struct module *load_module(void __user *umod, | |||
2064 | if (unusedgplcrcindex) | 2079 | if (unusedgplcrcindex) |
2065 | mod->unused_gpl_crcs | 2080 | mod->unused_gpl_crcs |
2066 | = (void *)sechdrs[unusedgplcrcindex].sh_addr; | 2081 | = (void *)sechdrs[unusedgplcrcindex].sh_addr; |
2082 | #endif | ||
2067 | 2083 | ||
2068 | #ifdef CONFIG_MODVERSIONS | 2084 | #ifdef CONFIG_MODVERSIONS |
2069 | if ((mod->num_syms && !crcindex) || | 2085 | if ((mod->num_syms && !crcindex) |
2070 | (mod->num_gpl_syms && !gplcrcindex) || | 2086 | || (mod->num_gpl_syms && !gplcrcindex) |
2071 | (mod->num_gpl_future_syms && !gplfuturecrcindex) || | 2087 | || (mod->num_gpl_future_syms && !gplfuturecrcindex) |
2072 | (mod->num_unused_syms && !unusedcrcindex) || | 2088 | #ifdef CONFIG_UNUSED_SYMBOLS |
2073 | (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { | 2089 | || (mod->num_unused_syms && !unusedcrcindex) |
2090 | || (mod->num_unused_gpl_syms && !unusedgplcrcindex) | ||
2091 | #endif | ||
2092 | ) { | ||
2074 | printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name); | 2093 | printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name); |
2075 | err = try_to_force_load(mod, "nocrc"); | 2094 | err = try_to_force_load(mod, "nocrc"); |
2076 | if (err) | 2095 | if (err) |