diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/module.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c index 10e5b872adf6..03b738172a8c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Rewritten by Rusty Russell, on the backs of many others... | 1 | /* |
| 2 | Copyright (C) 2002 Richard Henderson | 2 | Copyright (C) 2002 Richard Henderson |
| 3 | Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM. | 3 | Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM. |
| 4 | 4 | ||
| @@ -122,9 +122,17 @@ extern const struct kernel_symbol __start___ksymtab_gpl[]; | |||
| 122 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; | 122 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; |
| 123 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | 123 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; |
| 124 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | 124 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; |
| 125 | extern const struct kernel_symbol __start___ksymtab_unused[]; | ||
| 126 | extern const struct kernel_symbol __stop___ksymtab_unused[]; | ||
| 127 | extern const struct kernel_symbol __start___ksymtab_unused_gpl[]; | ||
| 128 | extern const struct kernel_symbol __stop___ksymtab_unused_gpl[]; | ||
| 129 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | ||
| 130 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | ||
| 125 | extern const unsigned long __start___kcrctab[]; | 131 | extern const unsigned long __start___kcrctab[]; |
| 126 | extern const unsigned long __start___kcrctab_gpl[]; | 132 | extern const unsigned long __start___kcrctab_gpl[]; |
| 127 | extern const unsigned long __start___kcrctab_gpl_future[]; | 133 | extern const unsigned long __start___kcrctab_gpl_future[]; |
| 134 | extern const unsigned long __start___kcrctab_unused[]; | ||
| 135 | extern const unsigned long __start___kcrctab_unused_gpl[]; | ||
| 128 | 136 | ||
| 129 | #ifndef CONFIG_MODVERSIONS | 137 | #ifndef CONFIG_MODVERSIONS |
| 130 | #define symversion(base, idx) NULL | 138 | #define symversion(base, idx) NULL |
| @@ -144,6 +152,17 @@ static const struct kernel_symbol *lookup_symbol(const char *name, | |||
| 144 | return NULL; | 152 | return NULL; |
| 145 | } | 153 | } |
| 146 | 154 | ||
| 155 | static void printk_unused_warning(const char *name) | ||
| 156 | { | ||
| 157 | printk(KERN_WARNING "Symbol %s is marked as UNUSED, " | ||
| 158 | "however this module is using it.\n", name); | ||
| 159 | printk(KERN_WARNING "This symbol will go away in the future.\n"); | ||
| 160 | printk(KERN_WARNING "Please evalute if this is the right api to use, " | ||
| 161 | "and if it really is, submit a report the linux kernel " | ||
| 162 | "mailinglist together with submitting your code for " | ||
| 163 | "inclusion.\n"); | ||
| 164 | } | ||
| 165 | |||
| 147 | /* Find a symbol, return value, crc and module which owns it */ | 166 | /* Find a symbol, return value, crc and module which owns it */ |
| 148 | static unsigned long __find_symbol(const char *name, | 167 | static unsigned long __find_symbol(const char *name, |
| 149 | struct module **owner, | 168 | struct module **owner, |
| @@ -186,6 +205,25 @@ static unsigned long __find_symbol(const char *name, | |||
| 186 | return ks->value; | 205 | return ks->value; |
| 187 | } | 206 | } |
| 188 | 207 | ||
| 208 | ks = lookup_symbol(name, __start___ksymtab_unused, | ||
| 209 | __stop___ksymtab_unused); | ||
| 210 | if (ks) { | ||
| 211 | printk_unused_warning(name); | ||
| 212 | *crc = symversion(__start___kcrctab_unused, | ||
| 213 | (ks - __start___ksymtab_unused)); | ||
| 214 | return ks->value; | ||
| 215 | } | ||
| 216 | |||
| 217 | if (gplok) | ||
| 218 | ks = lookup_symbol(name, __start___ksymtab_unused_gpl, | ||
| 219 | __stop___ksymtab_unused_gpl); | ||
| 220 | if (ks) { | ||
| 221 | printk_unused_warning(name); | ||
| 222 | *crc = symversion(__start___kcrctab_unused_gpl, | ||
| 223 | (ks - __start___ksymtab_unused_gpl)); | ||
| 224 | return ks->value; | ||
| 225 | } | ||
| 226 | |||
| 189 | /* Now try modules. */ | 227 | /* Now try modules. */ |
| 190 | list_for_each_entry(mod, &modules, list) { | 228 | list_for_each_entry(mod, &modules, list) { |
| 191 | *owner = mod; | 229 | *owner = mod; |
| @@ -204,6 +242,23 @@ static unsigned long __find_symbol(const char *name, | |||
| 204 | return ks->value; | 242 | return ks->value; |
| 205 | } | 243 | } |
| 206 | } | 244 | } |
| 245 | ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms); | ||
| 246 | if (ks) { | ||
| 247 | printk_unused_warning(name); | ||
| 248 | *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms)); | ||
| 249 | return ks->value; | ||
| 250 | } | ||
| 251 | |||
| 252 | if (gplok) { | ||
| 253 | ks = lookup_symbol(name, mod->unused_gpl_syms, | ||
| 254 | mod->unused_gpl_syms + mod->num_unused_gpl_syms); | ||
| 255 | if (ks) { | ||
| 256 | printk_unused_warning(name); | ||
| 257 | *crc = symversion(mod->unused_gpl_crcs, | ||
| 258 | (ks - mod->unused_gpl_syms)); | ||
| 259 | return ks->value; | ||
| 260 | } | ||
| 261 | } | ||
| 207 | ks = lookup_symbol(name, mod->gpl_future_syms, | 262 | ks = lookup_symbol(name, mod->gpl_future_syms, |
| 208 | (mod->gpl_future_syms + | 263 | (mod->gpl_future_syms + |
| 209 | mod->num_gpl_future_syms)); | 264 | mod->num_gpl_future_syms)); |
| @@ -1407,6 +1462,8 @@ static struct module *load_module(void __user *umod, | |||
| 1407 | exportindex, modindex, obsparmindex, infoindex, gplindex, | 1462 | exportindex, modindex, obsparmindex, infoindex, gplindex, |
| 1408 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, | 1463 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, |
| 1409 | gplfuturecrcindex, unwindex = 0; | 1464 | gplfuturecrcindex, unwindex = 0; |
| 1465 | unsigned int unusedindex, unusedcrcindex, unusedgplindex, | ||
| 1466 | unusedgplcrcindex; | ||
| 1410 | struct module *mod; | 1467 | struct module *mod; |
| 1411 | long err = 0; | 1468 | long err = 0; |
| 1412 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1469 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
| @@ -1487,9 +1544,13 @@ static struct module *load_module(void __user *umod, | |||
| 1487 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); | 1544 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); |
| 1488 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); | 1545 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); |
| 1489 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); | 1546 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); |
| 1547 | unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused"); | ||
| 1548 | unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl"); | ||
| 1490 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); | 1549 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); |
| 1491 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | 1550 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); |
| 1492 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); | 1551 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); |
| 1552 | unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused"); | ||
| 1553 | unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl"); | ||
| 1493 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); | 1554 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); |
| 1494 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); | 1555 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); |
| 1495 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); | 1556 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); |
| @@ -1638,14 +1699,27 @@ static struct module *load_module(void __user *umod, | |||
| 1638 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; | 1699 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; |
| 1639 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / | 1700 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / |
| 1640 | sizeof(*mod->gpl_future_syms); | 1701 | sizeof(*mod->gpl_future_syms); |
| 1702 | mod->num_unused_syms = sechdrs[unusedindex].sh_size / | ||
| 1703 | sizeof(*mod->unused_syms); | ||
| 1704 | mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size / | ||
| 1705 | sizeof(*mod->unused_gpl_syms); | ||
| 1641 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; | 1706 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; |
| 1642 | if (gplfuturecrcindex) | 1707 | if (gplfuturecrcindex) |
| 1643 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; | 1708 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; |
| 1644 | 1709 | ||
| 1710 | mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr; | ||
| 1711 | if (unusedcrcindex) | ||
| 1712 | mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr; | ||
| 1713 | mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr; | ||
| 1714 | if (unusedgplcrcindex) | ||
| 1715 | mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr; | ||
| 1716 | |||
| 1645 | #ifdef CONFIG_MODVERSIONS | 1717 | #ifdef CONFIG_MODVERSIONS |
| 1646 | if ((mod->num_syms && !crcindex) || | 1718 | if ((mod->num_syms && !crcindex) || |
| 1647 | (mod->num_gpl_syms && !gplcrcindex) || | 1719 | (mod->num_gpl_syms && !gplcrcindex) || |
| 1648 | (mod->num_gpl_future_syms && !gplfuturecrcindex)) { | 1720 | (mod->num_gpl_future_syms && !gplfuturecrcindex) || |
| 1721 | (mod->num_unused_syms && !unusedcrcindex) || | ||
| 1722 | (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { | ||
| 1649 | printk(KERN_WARNING "%s: No versions for exported symbols." | 1723 | printk(KERN_WARNING "%s: No versions for exported symbols." |
| 1650 | " Tainting kernel.\n", mod->name); | 1724 | " Tainting kernel.\n", mod->name); |
| 1651 | add_taint(TAINT_FORCED_MODULE); | 1725 | add_taint(TAINT_FORCED_MODULE); |
