Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / kernel / module.c
index f9a5987..893ec57 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/* Rewritten by Rusty Russell, on the backs of many others...
    Copyright (C) 2002 Richard Henderson
    Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
 
    Copyright (C) 2002 Richard Henderson
    Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
 
@@ -16,6 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
-#include <linux/unwind.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
-#include <linux/license.h>
 #include "module-verify.h"
 
 #if 0
 #include "module-verify.h"
 
 #if 0
@@ -122,17 +121,9 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
 extern const struct kernel_symbol __stop___ksymtab_gpl[];
 extern const struct kernel_symbol __start___ksymtab_gpl_future[];
 extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
 extern const struct kernel_symbol __stop___ksymtab_gpl[];
 extern const struct kernel_symbol __start___ksymtab_gpl_future[];
 extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
-extern const struct kernel_symbol __start___ksymtab_unused[];
-extern const struct kernel_symbol __stop___ksymtab_unused[];
-extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
-extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
-extern const struct kernel_symbol __start___ksymtab_gpl_future[];
-extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
 extern const unsigned long __start___kcrctab[];
 extern const unsigned long __start___kcrctab_gpl[];
 extern const unsigned long __start___kcrctab_gpl_future[];
 extern const unsigned long __start___kcrctab[];
 extern const unsigned long __start___kcrctab_gpl[];
 extern const unsigned long __start___kcrctab_gpl_future[];
-extern const unsigned long __start___kcrctab_unused[];
-extern const unsigned long __start___kcrctab_unused_gpl[];
 
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
 
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
@@ -152,17 +143,6 @@ static const struct kernel_symbol *lookup_symbol(const char *name,
        return NULL;
 }
 
        return NULL;
 }
 
-static void printk_unused_warning(const char *name)
-{
-       printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
-               "however this module is using it.\n", name);
-       printk(KERN_WARNING "This symbol will go away in the future.\n");
-       printk(KERN_WARNING "Please evalute if this is the right api to use, "
-               "and if it really is, submit a report the linux kernel "
-               "mailinglist together with submitting your code for "
-               "inclusion.\n");
-}
-
 /* Find a symbol, return value, crc and module which owns it */
 static unsigned long __find_symbol(const char *name,
                                   struct module **owner,
 /* Find a symbol, return value, crc and module which owns it */
 static unsigned long __find_symbol(const char *name,
                                   struct module **owner,
@@ -205,25 +185,6 @@ static unsigned long __find_symbol(const char *name,
                return ks->value;
        }
 
                return ks->value;
        }
 
-       ks = lookup_symbol(name, __start___ksymtab_unused,
-                                __stop___ksymtab_unused);
-       if (ks) {
-               printk_unused_warning(name);
-               *crc = symversion(__start___kcrctab_unused,
-                                 (ks - __start___ksymtab_unused));
-               return ks->value;
-       }
-
-       if (gplok)
-               ks = lookup_symbol(name, __start___ksymtab_unused_gpl,
-                                __stop___ksymtab_unused_gpl);
-       if (ks) {
-               printk_unused_warning(name);
-               *crc = symversion(__start___kcrctab_unused_gpl,
-                                 (ks - __start___ksymtab_unused_gpl));
-               return ks->value;
-       }
-
        /* Now try modules. */ 
        list_for_each_entry(mod, &modules, list) {
                *owner = mod;
        /* Now try modules. */ 
        list_for_each_entry(mod, &modules, list) {
                *owner = mod;
@@ -242,23 +203,6 @@ static unsigned long __find_symbol(const char *name,
                                return ks->value;
                        }
                }
                                return ks->value;
                        }
                }
-               ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);
-               if (ks) {
-                       printk_unused_warning(name);
-                       *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
-                       return ks->value;
-               }
-
-               if (gplok) {
-                       ks = lookup_symbol(name, mod->unused_gpl_syms,
-                                          mod->unused_gpl_syms + mod->num_unused_gpl_syms);
-                       if (ks) {
-                               printk_unused_warning(name);
-                               *crc = symversion(mod->unused_gpl_crcs,
-                                                 (ks - mod->unused_gpl_syms));
-                               return ks->value;
-                       }
-               }
                ks = lookup_symbol(name, mod->gpl_future_syms,
                                   (mod->gpl_future_syms +
                                    mod->num_gpl_future_syms));
                ks = lookup_symbol(name, mod->gpl_future_syms,
                                   (mod->gpl_future_syms +
                                    mod->num_gpl_future_syms));
@@ -1055,12 +999,6 @@ static int mod_sysfs_setup(struct module *mod,
 {
        int err;
 
 {
        int err;
 
-       if (!module_subsys.kset.subsys) {
-               printk(KERN_ERR "%s: module_subsys not initialized\n",
-                      mod->name);
-               err = -EINVAL;
-               goto out;
-       }
        memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
        err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
        if (err)
        memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
        err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
        if (err)
@@ -1114,8 +1052,6 @@ static void free_module(struct module *mod)
        remove_sect_attrs(mod);
        mod_kobject_remove(mod);
 
        remove_sect_attrs(mod);
        mod_kobject_remove(mod);
 
-       unwind_remove_table(mod->unwind_info, 0);
-
        /* Arch-specific cleanup. */
        module_arch_cleanup(mod);
 
        /* Arch-specific cleanup. */
        module_arch_cleanup(mod);
 
@@ -1128,9 +1064,6 @@ static void free_module(struct module *mod)
        if (mod->percpu)
                percpu_modfree(mod->percpu);
 
        if (mod->percpu)
                percpu_modfree(mod->percpu);
 
-       /* Free lock-classes: */
-       lockdep_free_key_range(mod->module_core, mod->core_size);
-
        /* Finally, free the core (containing the module structure) */
        module_free(mod, mod->module_core);
 }
        /* Finally, free the core (containing the module structure) */
        module_free(mod, mod->module_core);
 }
@@ -1316,6 +1249,16 @@ static void layout_sections(struct module *mod,
        }
 }
 
        }
 }
 
+static inline int license_is_gpl_compatible(const char *license)
+{
+       return (strcmp(license, "GPL") == 0
+               || strcmp(license, "GPL v2") == 0
+               || strcmp(license, "GPL and additional rights") == 0
+               || strcmp(license, "Dual BSD/GPL") == 0
+               || strcmp(license, "Dual MIT/GPL") == 0
+               || strcmp(license, "Dual MPL/GPL") == 0);
+}
+
 static void set_license(struct module *mod, const char *license)
 {
        if (!license)
 static void set_license(struct module *mod, const char *license)
 {
        if (!license)
@@ -1384,7 +1327,7 @@ int is_exported(const char *name, const struct module *mod)
        if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
                return 1;
        else
        if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
                return 1;
        else
-               if (mod && lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
+               if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
                        return 1;
                else
                        return 0;
                        return 1;
                else
                        return 0;
@@ -1467,27 +1410,10 @@ static struct module *load_module(void __user *umod,
        Elf_Ehdr *hdr;
        Elf_Shdr *sechdrs;
        char *secstrings, *args, *modmagic, *strtab = NULL;
        Elf_Ehdr *hdr;
        Elf_Shdr *sechdrs;
        char *secstrings, *args, *modmagic, *strtab = NULL;
-       unsigned int i;
-       unsigned int symindex = 0;
-       unsigned int strindex = 0;
-       unsigned int setupindex;
-       unsigned int exindex;
-       unsigned int exportindex;
-       unsigned int modindex;
-       unsigned int obsparmindex;
-       unsigned int infoindex;
-       unsigned int gplindex;
-       unsigned int crcindex;
-       unsigned int gplcrcindex;
-       unsigned int versindex;
-       unsigned int pcpuindex;
-       unsigned int gplfutureindex;
-       unsigned int gplfuturecrcindex;
-       unsigned int unwindex = 0;
-       unsigned int unusedindex;
-       unsigned int unusedcrcindex;
-       unsigned int unusedgplindex;
-       unsigned int unusedgplcrcindex;
+       unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
+               exportindex, modindex, obsparmindex, infoindex, gplindex,
+               crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
+               gplfuturecrcindex;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1575,22 +1501,15 @@ static struct module *load_module(void __user *umod,
        exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
        gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
        gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
        exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
        gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
        gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
-       unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
-       unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
        crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
        gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
        gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
        crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
        gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
        gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
-       unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
-       unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
        setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
        exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
        obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
        versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
        infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
        pcpuindex = find_pcpusec(hdr, sechdrs, secstrings);
        setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
        exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
        obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
        versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
        infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
        pcpuindex = find_pcpusec(hdr, sechdrs, secstrings);
-#ifdef ARCH_UNWIND_SECTION_NAME
-       unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME);
-#endif
 
        /* Don't keep modinfo section */
        sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
 
        /* Don't keep modinfo section */
        sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
@@ -1599,8 +1518,6 @@ static struct module *load_module(void __user *umod,
        sechdrs[symindex].sh_flags |= SHF_ALLOC;
        sechdrs[strindex].sh_flags |= SHF_ALLOC;
 #endif
        sechdrs[symindex].sh_flags |= SHF_ALLOC;
        sechdrs[strindex].sh_flags |= SHF_ALLOC;
 #endif
-       if (unwindex)
-               sechdrs[unwindex].sh_flags |= SHF_ALLOC;
 
        /* Check module struct version now, before we try to use module. */
        if (!check_modstruct_version(sechdrs, versindex, mod)) {
 
        /* Check module struct version now, before we try to use module. */
        if (!check_modstruct_version(sechdrs, versindex, mod)) {
@@ -1730,27 +1647,14 @@ static struct module *load_module(void __user *umod,
                mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
        mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
                                        sizeof(*mod->gpl_future_syms);
                mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
        mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
                                        sizeof(*mod->gpl_future_syms);
-       mod->num_unused_syms = sechdrs[unusedindex].sh_size /
-                                       sizeof(*mod->unused_syms);
-       mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
-                                       sizeof(*mod->unused_gpl_syms);
        mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
        if (gplfuturecrcindex)
                mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
 
        mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
        if (gplfuturecrcindex)
                mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
 
-       mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
-       if (unusedcrcindex)
-               mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
-       mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
-       if (unusedgplcrcindex)
-               mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
-
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !crcindex) || 
            (mod->num_gpl_syms && !gplcrcindex) ||
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !crcindex) || 
            (mod->num_gpl_syms && !gplcrcindex) ||
-           (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
-           (mod->num_unused_syms && !unusedcrcindex) ||
-           (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
+           (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
                printk(KERN_WARNING "%s: No versions for exported symbols."
                       " Tainting kernel.\n", mod->name);
                add_taint(TAINT_FORCED_MODULE);
                printk(KERN_WARNING "%s: No versions for exported symbols."
                       " Tainting kernel.\n", mod->name);
                add_taint(TAINT_FORCED_MODULE);
@@ -1842,11 +1746,6 @@ static struct module *load_module(void __user *umod,
                goto arch_cleanup;
        add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
 
                goto arch_cleanup;
        add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
 
-       /* Size of section 0 is 0, so this works well if no unwind info. */
-       mod->unwind_info = unwind_add_table(mod,
-                                           (void *)sechdrs[unwindex].sh_addr,
-                                           sechdrs[unwindex].sh_size);
-
        /* Get rid of temporary copy */
        vfree(hdr);
 
        /* Get rid of temporary copy */
        vfree(hdr);
 
@@ -1945,7 +1844,6 @@ sys_init_module(void __user *umod,
        mod->state = MODULE_STATE_LIVE;
        /* Drop initial reference. */
        module_put(mod);
        mod->state = MODULE_STATE_LIVE;
        /* Drop initial reference. */
        module_put(mod);
-       unwind_remove_table(mod->unwind_info, 1);
        module_free(mod, mod->module_init);
        mod->module_init = NULL;
        mod->init_size = 0;
        module_free(mod, mod->module_init);
        mod->module_init = NULL;
        mod->init_size = 0;
@@ -2033,8 +1931,10 @@ const char *module_address_lookup(unsigned long addr,
        return NULL;
 }
 
        return NULL;
 }
 
-struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
-                               char *type, char *name, size_t namelen)
+struct module *module_get_kallsym(unsigned int symnum,
+                                 unsigned long *value,
+                                 char *type,
+                                 char namebuf[128])
 {
        struct module *mod;
 
 {
        struct module *mod;
 
@@ -2043,8 +1943,9 @@ struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
-                       strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
-                               namelen);
+                       strncpy(namebuf,
+                               mod->strtab + mod->symtab[symnum].st_name,
+                               127);
                        mutex_unlock(&module_mutex);
                        return mod;
                }
                        mutex_unlock(&module_mutex);
                        return mod;
                }
@@ -2173,29 +2074,6 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
        return e;
 }
 
        return e;
 }
 
-/*
- * Is this a valid module address?
- */
-int is_module_address(unsigned long addr)
-{
-       unsigned long flags;
-       struct module *mod;
-
-       spin_lock_irqsave(&modlist_lock, flags);
-
-       list_for_each_entry(mod, &modules, list) {
-               if (within(addr, mod->module_core, mod->core_size)) {
-                       spin_unlock_irqrestore(&modlist_lock, flags);
-                       return 1;
-               }
-       }
-
-       spin_unlock_irqrestore(&modlist_lock, flags);
-
-       return 0;
-}
-
-
 /* Is this a valid kernel address?  We don't grab the lock: we are oopsing. */
 struct module *__module_text_address(unsigned long addr)
 {
 /* Is this a valid kernel address?  We don't grab the lock: we are oopsing. */
 struct module *__module_text_address(unsigned long addr)
 {