aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/module.h2
-rw-r--r--init/Kconfig4
-rw-r--r--kernel/module.c49
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
862config MODULE_FORCE_UNLOAD 862config 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[];
134extern const struct kernel_symbol __stop___ksymtab_gpl[]; 134extern const struct kernel_symbol __stop___ksymtab_gpl[];
135extern const struct kernel_symbol __start___ksymtab_gpl_future[]; 135extern const struct kernel_symbol __start___ksymtab_gpl_future[];
136extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; 136extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
137extern const struct kernel_symbol __start___ksymtab_unused[];
138extern const struct kernel_symbol __stop___ksymtab_unused[];
139extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
140extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
141extern const struct kernel_symbol __start___ksymtab_gpl_future[]; 137extern const struct kernel_symbol __start___ksymtab_gpl_future[];
142extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; 138extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
143extern const unsigned long __start___kcrctab[]; 139extern const unsigned long __start___kcrctab[];
144extern const unsigned long __start___kcrctab_gpl[]; 140extern const unsigned long __start___kcrctab_gpl[];
145extern const unsigned long __start___kcrctab_gpl_future[]; 141extern const unsigned long __start___kcrctab_gpl_future[];
142#ifdef CONFIG_UNUSED_SYMBOLS
143extern const struct kernel_symbol __start___ksymtab_unused[];
144extern const struct kernel_symbol __stop___ksymtab_unused[];
145extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
146extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
146extern const unsigned long __start___kcrctab_unused[]; 147extern const unsigned long __start___kcrctab_unused[];
147extern const unsigned long __start___kcrctab_unused_gpl[]; 148extern 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)