aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c198
1 files changed, 167 insertions, 31 deletions
diff --git a/kernel/module.c b/kernel/module.c
index bbe04862e1b0..05625d5dc758 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
@@ -16,7 +16,6 @@
16 along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/ 18*/
19#include <linux/config.h>
20#include <linux/module.h> 19#include <linux/module.h>
21#include <linux/moduleloader.h> 20#include <linux/moduleloader.h>
22#include <linux/init.h> 21#include <linux/init.h>
@@ -40,9 +39,11 @@
40#include <linux/string.h> 39#include <linux/string.h>
41#include <linux/sched.h> 40#include <linux/sched.h>
42#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/unwind.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/semaphore.h> 44#include <asm/semaphore.h>
45#include <asm/cacheflush.h> 45#include <asm/cacheflush.h>
46#include <linux/license.h>
46 47
47#if 0 48#if 0
48#define DEBUGP printk 49#define DEBUGP printk
@@ -120,9 +121,17 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
120extern const struct kernel_symbol __stop___ksymtab_gpl[]; 121extern const struct kernel_symbol __stop___ksymtab_gpl[];
121extern const struct kernel_symbol __start___ksymtab_gpl_future[]; 122extern const struct kernel_symbol __start___ksymtab_gpl_future[];
122extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; 123extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
124extern const struct kernel_symbol __start___ksymtab_unused[];
125extern const struct kernel_symbol __stop___ksymtab_unused[];
126extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
127extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
128extern const struct kernel_symbol __start___ksymtab_gpl_future[];
129extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
123extern const unsigned long __start___kcrctab[]; 130extern const unsigned long __start___kcrctab[];
124extern const unsigned long __start___kcrctab_gpl[]; 131extern const unsigned long __start___kcrctab_gpl[];
125extern const unsigned long __start___kcrctab_gpl_future[]; 132extern const unsigned long __start___kcrctab_gpl_future[];
133extern const unsigned long __start___kcrctab_unused[];
134extern const unsigned long __start___kcrctab_unused_gpl[];
126 135
127#ifndef CONFIG_MODVERSIONS 136#ifndef CONFIG_MODVERSIONS
128#define symversion(base, idx) NULL 137#define symversion(base, idx) NULL
@@ -142,6 +151,17 @@ static const struct kernel_symbol *lookup_symbol(const char *name,
142 return NULL; 151 return NULL;
143} 152}
144 153
154static void printk_unused_warning(const char *name)
155{
156 printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
157 "however this module is using it.\n", name);
158 printk(KERN_WARNING "This symbol will go away in the future.\n");
159 printk(KERN_WARNING "Please evalute if this is the right api to use, "
160 "and if it really is, submit a report the linux kernel "
161 "mailinglist together with submitting your code for "
162 "inclusion.\n");
163}
164
145/* Find a symbol, return value, crc and module which owns it */ 165/* Find a symbol, return value, crc and module which owns it */
146static unsigned long __find_symbol(const char *name, 166static unsigned long __find_symbol(const char *name,
147 struct module **owner, 167 struct module **owner,
@@ -184,6 +204,25 @@ static unsigned long __find_symbol(const char *name,
184 return ks->value; 204 return ks->value;
185 } 205 }
186 206
207 ks = lookup_symbol(name, __start___ksymtab_unused,
208 __stop___ksymtab_unused);
209 if (ks) {
210 printk_unused_warning(name);
211 *crc = symversion(__start___kcrctab_unused,
212 (ks - __start___ksymtab_unused));
213 return ks->value;
214 }
215
216 if (gplok)
217 ks = lookup_symbol(name, __start___ksymtab_unused_gpl,
218 __stop___ksymtab_unused_gpl);
219 if (ks) {
220 printk_unused_warning(name);
221 *crc = symversion(__start___kcrctab_unused_gpl,
222 (ks - __start___ksymtab_unused_gpl));
223 return ks->value;
224 }
225
187 /* Now try modules. */ 226 /* Now try modules. */
188 list_for_each_entry(mod, &modules, list) { 227 list_for_each_entry(mod, &modules, list) {
189 *owner = mod; 228 *owner = mod;
@@ -202,6 +241,23 @@ static unsigned long __find_symbol(const char *name,
202 return ks->value; 241 return ks->value;
203 } 242 }
204 } 243 }
244 ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);
245 if (ks) {
246 printk_unused_warning(name);
247 *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
248 return ks->value;
249 }
250
251 if (gplok) {
252 ks = lookup_symbol(name, mod->unused_gpl_syms,
253 mod->unused_gpl_syms + mod->num_unused_gpl_syms);
254 if (ks) {
255 printk_unused_warning(name);
256 *crc = symversion(mod->unused_gpl_crcs,
257 (ks - mod->unused_gpl_syms));
258 return ks->value;
259 }
260 }
205 ks = lookup_symbol(name, mod->gpl_future_syms, 261 ks = lookup_symbol(name, mod->gpl_future_syms,
206 (mod->gpl_future_syms + 262 (mod->gpl_future_syms +
207 mod->num_gpl_future_syms)); 263 mod->num_gpl_future_syms));
@@ -877,6 +933,15 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
877 return sprintf(buf, "0x%lx\n", sattr->address); 933 return sprintf(buf, "0x%lx\n", sattr->address);
878} 934}
879 935
936static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
937{
938 int section;
939
940 for (section = 0; section < sect_attrs->nsections; section++)
941 kfree(sect_attrs->attrs[section].name);
942 kfree(sect_attrs);
943}
944
880static void add_sect_attrs(struct module *mod, unsigned int nsect, 945static void add_sect_attrs(struct module *mod, unsigned int nsect,
881 char *secstrings, Elf_Shdr *sechdrs) 946 char *secstrings, Elf_Shdr *sechdrs)
882{ 947{
@@ -893,21 +958,26 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
893 + nloaded * sizeof(sect_attrs->attrs[0]), 958 + nloaded * sizeof(sect_attrs->attrs[0]),
894 sizeof(sect_attrs->grp.attrs[0])); 959 sizeof(sect_attrs->grp.attrs[0]));
895 size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); 960 size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
896 if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL))) 961 sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
962 if (sect_attrs == NULL)
897 return; 963 return;
898 964
899 /* Setup section attributes. */ 965 /* Setup section attributes. */
900 sect_attrs->grp.name = "sections"; 966 sect_attrs->grp.name = "sections";
901 sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; 967 sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
902 968
969 sect_attrs->nsections = 0;
903 sattr = &sect_attrs->attrs[0]; 970 sattr = &sect_attrs->attrs[0];
904 gattr = &sect_attrs->grp.attrs[0]; 971 gattr = &sect_attrs->grp.attrs[0];
905 for (i = 0; i < nsect; i++) { 972 for (i = 0; i < nsect; i++) {
906 if (! (sechdrs[i].sh_flags & SHF_ALLOC)) 973 if (! (sechdrs[i].sh_flags & SHF_ALLOC))
907 continue; 974 continue;
908 sattr->address = sechdrs[i].sh_addr; 975 sattr->address = sechdrs[i].sh_addr;
909 strlcpy(sattr->name, secstrings + sechdrs[i].sh_name, 976 sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
910 MODULE_SECT_NAME_LEN); 977 GFP_KERNEL);
978 if (sattr->name == NULL)
979 goto out;
980 sect_attrs->nsections++;
911 sattr->mattr.show = module_sect_show; 981 sattr->mattr.show = module_sect_show;
912 sattr->mattr.store = NULL; 982 sattr->mattr.store = NULL;
913 sattr->mattr.attr.name = sattr->name; 983 sattr->mattr.attr.name = sattr->name;
@@ -923,7 +993,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
923 mod->sect_attrs = sect_attrs; 993 mod->sect_attrs = sect_attrs;
924 return; 994 return;
925 out: 995 out:
926 kfree(sect_attrs); 996 free_sect_attrs(sect_attrs);
927} 997}
928 998
929static void remove_sect_attrs(struct module *mod) 999static void remove_sect_attrs(struct module *mod)
@@ -933,13 +1003,13 @@ static void remove_sect_attrs(struct module *mod)
933 &mod->sect_attrs->grp); 1003 &mod->sect_attrs->grp);
934 /* We are positive that no one is using any sect attrs 1004 /* We are positive that no one is using any sect attrs
935 * at this point. Deallocate immediately. */ 1005 * at this point. Deallocate immediately. */
936 kfree(mod->sect_attrs); 1006 free_sect_attrs(mod->sect_attrs);
937 mod->sect_attrs = NULL; 1007 mod->sect_attrs = NULL;
938 } 1008 }
939} 1009}
940 1010
941
942#else 1011#else
1012
943static inline void add_sect_attrs(struct module *mod, unsigned int nsect, 1013static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
944 char *sectstrings, Elf_Shdr *sechdrs) 1014 char *sectstrings, Elf_Shdr *sechdrs)
945{ 1015{
@@ -998,6 +1068,12 @@ static int mod_sysfs_setup(struct module *mod,
998{ 1068{
999 int err; 1069 int err;
1000 1070
1071 if (!module_subsys.kset.subsys) {
1072 printk(KERN_ERR "%s: module_subsys not initialized\n",
1073 mod->name);
1074 err = -EINVAL;
1075 goto out;
1076 }
1001 memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); 1077 memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
1002 err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name); 1078 err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
1003 if (err) 1079 if (err)
@@ -1051,6 +1127,8 @@ static void free_module(struct module *mod)
1051 remove_sect_attrs(mod); 1127 remove_sect_attrs(mod);
1052 mod_kobject_remove(mod); 1128 mod_kobject_remove(mod);
1053 1129
1130 unwind_remove_table(mod->unwind_info, 0);
1131
1054 /* Arch-specific cleanup. */ 1132 /* Arch-specific cleanup. */
1055 module_arch_cleanup(mod); 1133 module_arch_cleanup(mod);
1056 1134
@@ -1063,6 +1141,9 @@ static void free_module(struct module *mod)
1063 if (mod->percpu) 1141 if (mod->percpu)
1064 percpu_modfree(mod->percpu); 1142 percpu_modfree(mod->percpu);
1065 1143
1144 /* Free lock-classes: */
1145 lockdep_free_key_range(mod->module_core, mod->core_size);
1146
1066 /* Finally, free the core (containing the module structure) */ 1147 /* Finally, free the core (containing the module structure) */
1067 module_free(mod, mod->module_core); 1148 module_free(mod, mod->module_core);
1068} 1149}
@@ -1248,16 +1329,6 @@ static void layout_sections(struct module *mod,
1248 } 1329 }
1249} 1330}
1250 1331
1251static inline int license_is_gpl_compatible(const char *license)
1252{
1253 return (strcmp(license, "GPL") == 0
1254 || strcmp(license, "GPL v2") == 0
1255 || strcmp(license, "GPL and additional rights") == 0
1256 || strcmp(license, "Dual BSD/GPL") == 0
1257 || strcmp(license, "Dual MIT/GPL") == 0
1258 || strcmp(license, "Dual MPL/GPL") == 0);
1259}
1260
1261static void set_license(struct module *mod, const char *license) 1332static void set_license(struct module *mod, const char *license)
1262{ 1333{
1263 if (!license) 1334 if (!license)
@@ -1326,7 +1397,7 @@ int is_exported(const char *name, const struct module *mod)
1326 if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab)) 1397 if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
1327 return 1; 1398 return 1;
1328 else 1399 else
1329 if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms)) 1400 if (mod && lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
1330 return 1; 1401 return 1;
1331 else 1402 else
1332 return 0; 1403 return 0;
@@ -1409,10 +1480,27 @@ static struct module *load_module(void __user *umod,
1409 Elf_Ehdr *hdr; 1480 Elf_Ehdr *hdr;
1410 Elf_Shdr *sechdrs; 1481 Elf_Shdr *sechdrs;
1411 char *secstrings, *args, *modmagic, *strtab = NULL; 1482 char *secstrings, *args, *modmagic, *strtab = NULL;
1412 unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, 1483 unsigned int i;
1413 exportindex, modindex, obsparmindex, infoindex, gplindex, 1484 unsigned int symindex = 0;
1414 crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, 1485 unsigned int strindex = 0;
1415 gplfuturecrcindex; 1486 unsigned int setupindex;
1487 unsigned int exindex;
1488 unsigned int exportindex;
1489 unsigned int modindex;
1490 unsigned int obsparmindex;
1491 unsigned int infoindex;
1492 unsigned int gplindex;
1493 unsigned int crcindex;
1494 unsigned int gplcrcindex;
1495 unsigned int versindex;
1496 unsigned int pcpuindex;
1497 unsigned int gplfutureindex;
1498 unsigned int gplfuturecrcindex;
1499 unsigned int unwindex = 0;
1500 unsigned int unusedindex;
1501 unsigned int unusedcrcindex;
1502 unsigned int unusedgplindex;
1503 unsigned int unusedgplcrcindex;
1416 struct module *mod; 1504 struct module *mod;
1417 long err = 0; 1505 long err = 0;
1418 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ 1506 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1493,15 +1581,22 @@ static struct module *load_module(void __user *umod,
1493 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); 1581 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
1494 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); 1582 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
1495 gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); 1583 gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
1584 unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
1585 unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
1496 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); 1586 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
1497 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); 1587 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
1498 gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); 1588 gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
1589 unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
1590 unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
1499 setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); 1591 setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
1500 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); 1592 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
1501 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); 1593 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
1502 versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); 1594 versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
1503 infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); 1595 infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
1504 pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); 1596 pcpuindex = find_pcpusec(hdr, sechdrs, secstrings);
1597#ifdef ARCH_UNWIND_SECTION_NAME
1598 unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME);
1599#endif
1505 1600
1506 /* Don't keep modinfo section */ 1601 /* Don't keep modinfo section */
1507 sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; 1602 sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
@@ -1510,6 +1605,8 @@ static struct module *load_module(void __user *umod,
1510 sechdrs[symindex].sh_flags |= SHF_ALLOC; 1605 sechdrs[symindex].sh_flags |= SHF_ALLOC;
1511 sechdrs[strindex].sh_flags |= SHF_ALLOC; 1606 sechdrs[strindex].sh_flags |= SHF_ALLOC;
1512#endif 1607#endif
1608 if (unwindex)
1609 sechdrs[unwindex].sh_flags |= SHF_ALLOC;
1513 1610
1514 /* Check module struct version now, before we try to use module. */ 1611 /* Check module struct version now, before we try to use module. */
1515 if (!check_modstruct_version(sechdrs, versindex, mod)) { 1612 if (!check_modstruct_version(sechdrs, versindex, mod)) {
@@ -1639,14 +1736,27 @@ static struct module *load_module(void __user *umod,
1639 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; 1736 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
1640 mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / 1737 mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
1641 sizeof(*mod->gpl_future_syms); 1738 sizeof(*mod->gpl_future_syms);
1739 mod->num_unused_syms = sechdrs[unusedindex].sh_size /
1740 sizeof(*mod->unused_syms);
1741 mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
1742 sizeof(*mod->unused_gpl_syms);
1642 mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; 1743 mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
1643 if (gplfuturecrcindex) 1744 if (gplfuturecrcindex)
1644 mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; 1745 mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
1645 1746
1747 mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
1748 if (unusedcrcindex)
1749 mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
1750 mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
1751 if (unusedgplcrcindex)
1752 mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
1753
1646#ifdef CONFIG_MODVERSIONS 1754#ifdef CONFIG_MODVERSIONS
1647 if ((mod->num_syms && !crcindex) || 1755 if ((mod->num_syms && !crcindex) ||
1648 (mod->num_gpl_syms && !gplcrcindex) || 1756 (mod->num_gpl_syms && !gplcrcindex) ||
1649 (mod->num_gpl_future_syms && !gplfuturecrcindex)) { 1757 (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
1758 (mod->num_unused_syms && !unusedcrcindex) ||
1759 (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
1650 printk(KERN_WARNING "%s: No versions for exported symbols." 1760 printk(KERN_WARNING "%s: No versions for exported symbols."
1651 " Tainting kernel.\n", mod->name); 1761 " Tainting kernel.\n", mod->name);
1652 add_taint(TAINT_FORCED_MODULE); 1762 add_taint(TAINT_FORCED_MODULE);
@@ -1738,6 +1848,11 @@ static struct module *load_module(void __user *umod,
1738 goto arch_cleanup; 1848 goto arch_cleanup;
1739 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); 1849 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
1740 1850
1851 /* Size of section 0 is 0, so this works well if no unwind info. */
1852 mod->unwind_info = unwind_add_table(mod,
1853 (void *)sechdrs[unwindex].sh_addr,
1854 sechdrs[unwindex].sh_size);
1855
1741 /* Get rid of temporary copy */ 1856 /* Get rid of temporary copy */
1742 vfree(hdr); 1857 vfree(hdr);
1743 1858
@@ -1836,6 +1951,7 @@ sys_init_module(void __user *umod,
1836 mod->state = MODULE_STATE_LIVE; 1951 mod->state = MODULE_STATE_LIVE;
1837 /* Drop initial reference. */ 1952 /* Drop initial reference. */
1838 module_put(mod); 1953 module_put(mod);
1954 unwind_remove_table(mod->unwind_info, 1);
1839 module_free(mod, mod->module_init); 1955 module_free(mod, mod->module_init);
1840 mod->module_init = NULL; 1956 mod->module_init = NULL;
1841 mod->init_size = 0; 1957 mod->init_size = 0;
@@ -1923,10 +2039,8 @@ const char *module_address_lookup(unsigned long addr,
1923 return NULL; 2039 return NULL;
1924} 2040}
1925 2041
1926struct module *module_get_kallsym(unsigned int symnum, 2042struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
1927 unsigned long *value, 2043 char *type, char *name, size_t namelen)
1928 char *type,
1929 char namebuf[128])
1930{ 2044{
1931 struct module *mod; 2045 struct module *mod;
1932 2046
@@ -1935,9 +2049,8 @@ struct module *module_get_kallsym(unsigned int symnum,
1935 if (symnum < mod->num_symtab) { 2049 if (symnum < mod->num_symtab) {
1936 *value = mod->symtab[symnum].st_value; 2050 *value = mod->symtab[symnum].st_value;
1937 *type = mod->symtab[symnum].st_info; 2051 *type = mod->symtab[symnum].st_info;
1938 strncpy(namebuf, 2052 strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
1939 mod->strtab + mod->symtab[symnum].st_name, 2053 namelen);
1940 127);
1941 mutex_unlock(&module_mutex); 2054 mutex_unlock(&module_mutex);
1942 return mod; 2055 return mod;
1943 } 2056 }
@@ -2066,6 +2179,29 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
2066 return e; 2179 return e;
2067} 2180}
2068 2181
2182/*
2183 * Is this a valid module address?
2184 */
2185int is_module_address(unsigned long addr)
2186{
2187 unsigned long flags;
2188 struct module *mod;
2189
2190 spin_lock_irqsave(&modlist_lock, flags);
2191
2192 list_for_each_entry(mod, &modules, list) {
2193 if (within(addr, mod->module_core, mod->core_size)) {
2194 spin_unlock_irqrestore(&modlist_lock, flags);
2195 return 1;
2196 }
2197 }
2198
2199 spin_unlock_irqrestore(&modlist_lock, flags);
2200
2201 return 0;
2202}
2203
2204
2069/* Is this a valid kernel address? We don't grab the lock: we are oopsing. */ 2205/* Is this a valid kernel address? We don't grab the lock: we are oopsing. */
2070struct module *__module_text_address(unsigned long addr) 2206struct module *__module_text_address(unsigned long addr)
2071{ 2207{