diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-28 23:27:48 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-28 23:27:48 -0400 |
| commit | 9f2fa466383ce100b90fe52cb4489d7a26bf72a9 (patch) | |
| tree | 7b72b1fae85137435d5b98f4614df2195f612acc /kernel/module.c | |
| parent | 607f31e80b6f982d7c0dd7a5045377fc368fe507 (diff) | |
| parent | 0a6047eef1c465c38aacfbdab193161b3f0cd144 (diff) | |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 101 |
1 files changed, 95 insertions, 6 deletions
diff --git a/kernel/module.c b/kernel/module.c index 10e5b872adf6..99c022ac3d21 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)); |
| @@ -1403,10 +1458,27 @@ static struct module *load_module(void __user *umod, | |||
| 1403 | Elf_Ehdr *hdr; | 1458 | Elf_Ehdr *hdr; |
| 1404 | Elf_Shdr *sechdrs; | 1459 | Elf_Shdr *sechdrs; |
| 1405 | char *secstrings, *args, *modmagic, *strtab = NULL; | 1460 | char *secstrings, *args, *modmagic, *strtab = NULL; |
| 1406 | unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, | 1461 | unsigned int i; |
| 1407 | exportindex, modindex, obsparmindex, infoindex, gplindex, | 1462 | unsigned int symindex = 0; |
| 1408 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, | 1463 | unsigned int strindex = 0; |
| 1409 | gplfuturecrcindex, unwindex = 0; | 1464 | unsigned int setupindex; |
| 1465 | unsigned int exindex; | ||
| 1466 | unsigned int exportindex; | ||
| 1467 | unsigned int modindex; | ||
| 1468 | unsigned int obsparmindex; | ||
| 1469 | unsigned int infoindex; | ||
| 1470 | unsigned int gplindex; | ||
| 1471 | unsigned int crcindex; | ||
| 1472 | unsigned int gplcrcindex; | ||
| 1473 | unsigned int versindex; | ||
| 1474 | unsigned int pcpuindex; | ||
| 1475 | unsigned int gplfutureindex; | ||
| 1476 | unsigned int gplfuturecrcindex; | ||
| 1477 | unsigned int unwindex = 0; | ||
| 1478 | unsigned int unusedindex; | ||
| 1479 | unsigned int unusedcrcindex; | ||
| 1480 | unsigned int unusedgplindex; | ||
| 1481 | unsigned int unusedgplcrcindex; | ||
| 1410 | struct module *mod; | 1482 | struct module *mod; |
| 1411 | long err = 0; | 1483 | long err = 0; |
| 1412 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1484 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
| @@ -1487,9 +1559,13 @@ static struct module *load_module(void __user *umod, | |||
| 1487 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); | 1559 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); |
| 1488 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); | 1560 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); |
| 1489 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); | 1561 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); |
| 1562 | unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused"); | ||
| 1563 | unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl"); | ||
| 1490 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); | 1564 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); |
| 1491 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | 1565 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); |
| 1492 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); | 1566 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); |
| 1567 | unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused"); | ||
| 1568 | unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl"); | ||
| 1493 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); | 1569 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); |
| 1494 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); | 1570 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); |
| 1495 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); | 1571 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); |
| @@ -1638,14 +1714,27 @@ static struct module *load_module(void __user *umod, | |||
| 1638 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; | 1714 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; |
| 1639 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / | 1715 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / |
| 1640 | sizeof(*mod->gpl_future_syms); | 1716 | sizeof(*mod->gpl_future_syms); |
| 1717 | mod->num_unused_syms = sechdrs[unusedindex].sh_size / | ||
| 1718 | sizeof(*mod->unused_syms); | ||
| 1719 | mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size / | ||
| 1720 | sizeof(*mod->unused_gpl_syms); | ||
| 1641 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; | 1721 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; |
| 1642 | if (gplfuturecrcindex) | 1722 | if (gplfuturecrcindex) |
| 1643 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; | 1723 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; |
| 1644 | 1724 | ||
| 1725 | mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr; | ||
| 1726 | if (unusedcrcindex) | ||
| 1727 | mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr; | ||
| 1728 | mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr; | ||
| 1729 | if (unusedgplcrcindex) | ||
| 1730 | mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr; | ||
| 1731 | |||
| 1645 | #ifdef CONFIG_MODVERSIONS | 1732 | #ifdef CONFIG_MODVERSIONS |
| 1646 | if ((mod->num_syms && !crcindex) || | 1733 | if ((mod->num_syms && !crcindex) || |
| 1647 | (mod->num_gpl_syms && !gplcrcindex) || | 1734 | (mod->num_gpl_syms && !gplcrcindex) || |
| 1648 | (mod->num_gpl_future_syms && !gplfuturecrcindex)) { | 1735 | (mod->num_gpl_future_syms && !gplfuturecrcindex) || |
| 1736 | (mod->num_unused_syms && !unusedcrcindex) || | ||
| 1737 | (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { | ||
| 1649 | printk(KERN_WARNING "%s: No versions for exported symbols." | 1738 | printk(KERN_WARNING "%s: No versions for exported symbols." |
| 1650 | " Tainting kernel.\n", mod->name); | 1739 | " Tainting kernel.\n", mod->name); |
| 1651 | add_taint(TAINT_FORCED_MODULE); | 1740 | add_taint(TAINT_FORCED_MODULE); |
