diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/kernel/module.c b/kernel/module.c index d75275de1c28..10e5b872adf6 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -40,9 +40,11 @@ | |||
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/unwind.h> | ||
43 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
44 | #include <asm/semaphore.h> | 45 | #include <asm/semaphore.h> |
45 | #include <asm/cacheflush.h> | 46 | #include <asm/cacheflush.h> |
47 | #include <linux/license.h> | ||
46 | 48 | ||
47 | #if 0 | 49 | #if 0 |
48 | #define DEBUGP printk | 50 | #define DEBUGP printk |
@@ -1051,6 +1053,8 @@ static void free_module(struct module *mod) | |||
1051 | remove_sect_attrs(mod); | 1053 | remove_sect_attrs(mod); |
1052 | mod_kobject_remove(mod); | 1054 | mod_kobject_remove(mod); |
1053 | 1055 | ||
1056 | unwind_remove_table(mod->unwind_info, 0); | ||
1057 | |||
1054 | /* Arch-specific cleanup. */ | 1058 | /* Arch-specific cleanup. */ |
1055 | module_arch_cleanup(mod); | 1059 | module_arch_cleanup(mod); |
1056 | 1060 | ||
@@ -1248,16 +1252,6 @@ static void layout_sections(struct module *mod, | |||
1248 | } | 1252 | } |
1249 | } | 1253 | } |
1250 | 1254 | ||
1251 | static 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 | |||
1261 | static void set_license(struct module *mod, const char *license) | 1255 | static void set_license(struct module *mod, const char *license) |
1262 | { | 1256 | { |
1263 | if (!license) | 1257 | if (!license) |
@@ -1412,7 +1406,7 @@ static struct module *load_module(void __user *umod, | |||
1412 | unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, | 1406 | unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, |
1413 | exportindex, modindex, obsparmindex, infoindex, gplindex, | 1407 | exportindex, modindex, obsparmindex, infoindex, gplindex, |
1414 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, | 1408 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, |
1415 | gplfuturecrcindex; | 1409 | gplfuturecrcindex, unwindex = 0; |
1416 | struct module *mod; | 1410 | struct module *mod; |
1417 | long err = 0; | 1411 | long err = 0; |
1418 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1412 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
@@ -1502,6 +1496,9 @@ static struct module *load_module(void __user *umod, | |||
1502 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); | 1496 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); |
1503 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); | 1497 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); |
1504 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); | 1498 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); |
1499 | #ifdef ARCH_UNWIND_SECTION_NAME | ||
1500 | unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME); | ||
1501 | #endif | ||
1505 | 1502 | ||
1506 | /* Don't keep modinfo section */ | 1503 | /* Don't keep modinfo section */ |
1507 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 1504 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
@@ -1510,6 +1507,8 @@ static struct module *load_module(void __user *umod, | |||
1510 | sechdrs[symindex].sh_flags |= SHF_ALLOC; | 1507 | sechdrs[symindex].sh_flags |= SHF_ALLOC; |
1511 | sechdrs[strindex].sh_flags |= SHF_ALLOC; | 1508 | sechdrs[strindex].sh_flags |= SHF_ALLOC; |
1512 | #endif | 1509 | #endif |
1510 | if (unwindex) | ||
1511 | sechdrs[unwindex].sh_flags |= SHF_ALLOC; | ||
1513 | 1512 | ||
1514 | /* Check module struct version now, before we try to use module. */ | 1513 | /* Check module struct version now, before we try to use module. */ |
1515 | if (!check_modstruct_version(sechdrs, versindex, mod)) { | 1514 | if (!check_modstruct_version(sechdrs, versindex, mod)) { |
@@ -1738,6 +1737,11 @@ static struct module *load_module(void __user *umod, | |||
1738 | goto arch_cleanup; | 1737 | goto arch_cleanup; |
1739 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 1738 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
1740 | 1739 | ||
1740 | /* Size of section 0 is 0, so this works well if no unwind info. */ | ||
1741 | mod->unwind_info = unwind_add_table(mod, | ||
1742 | (void *)sechdrs[unwindex].sh_addr, | ||
1743 | sechdrs[unwindex].sh_size); | ||
1744 | |||
1741 | /* Get rid of temporary copy */ | 1745 | /* Get rid of temporary copy */ |
1742 | vfree(hdr); | 1746 | vfree(hdr); |
1743 | 1747 | ||
@@ -1836,6 +1840,7 @@ sys_init_module(void __user *umod, | |||
1836 | mod->state = MODULE_STATE_LIVE; | 1840 | mod->state = MODULE_STATE_LIVE; |
1837 | /* Drop initial reference. */ | 1841 | /* Drop initial reference. */ |
1838 | module_put(mod); | 1842 | module_put(mod); |
1843 | unwind_remove_table(mod->unwind_info, 1); | ||
1839 | module_free(mod, mod->module_init); | 1844 | module_free(mod, mod->module_init); |
1840 | mod->module_init = NULL; | 1845 | mod->module_init = NULL; |
1841 | mod->init_size = 0; | 1846 | mod->init_size = 0; |