]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Allocate struct module using special allocator
authorRusty Russell <rusty@rustcorp.com.au>
Sun, 17 Nov 2002 03:21:55 +0000 (19:21 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 17 Nov 2002 03:21:55 +0000 (19:21 -0800)
Sparc64 (and probably others) need all the kernel symbols within
32-bits, which includes the manufactured "__this_module" which refers
to the struct module *.

This changes the interface back to its old style: the arch-specific code
manipulates the init and core sizes, and we call module_alloc() ourselves.

arch/i386/kernel/module.c
include/linux/moduleloader.h
kernel/module.c

index 500723e0305158bafddf3ec96134f4c022abbf05..2a9f3da0f7cd63104b900e73c77048ce1d7bad4d 100644 (file)
 #define DEBUGP(fmt , ...)
 #endif
 
-static void *alloc_and_zero(unsigned long size)
+void *module_alloc(unsigned long size)
 {
-       void *ret;
-
-       /* We handle the zero case fine, unlike vmalloc */
        if (size == 0)
                return NULL;
-
-       ret = vmalloc(size);
-       if (!ret) ret = ERR_PTR(-ENOMEM);
-       else memset(ret, 0, size);
-
-       return ret;
+       return vmalloc(size);
 }
 
-/* Free memory returned from module_core_alloc/module_init_alloc */
+
+/* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
        vfree(module_region);
@@ -51,20 +44,21 @@ void module_free(struct module *mod, void *module_region)
            table entries. */
 }
 
-void *module_core_alloc(const Elf32_Ehdr *hdr,
-                       const Elf32_Shdr *sechdrs,
-                       const char *secstrings,
-                       struct module *module)
+/* We don't need anything special. */
+long module_core_size(const Elf32_Ehdr *hdr,
+                     const Elf32_Shdr *sechdrs,
+                     const char *secstrings,
+                     struct module *module)
 {
-       return alloc_and_zero(module->core_size);
+       return module->core_size;
 }
 
-void *module_init_alloc(const Elf32_Ehdr *hdr,
-                       const Elf32_Shdr *sechdrs,
-                       const char *secstrings,
-                       struct module *module)
+long module_init_size(const Elf32_Ehdr *hdr,
+                     const Elf32_Shdr *sechdrs,
+                     const char *secstrings,
+                     struct module *module)
 {
-       return alloc_and_zero(module->init_size);
+       return module->init_size;
 }
 
 int apply_relocate(Elf32_Shdr *sechdrs,
index a74960440032700d68309d4d7e97db52246b6400..928ae553ca3744cadd25d11090ca628f331e5e29 100644 (file)
@@ -15,20 +15,26 @@ unsigned long find_symbol_internal(Elf_Shdr *sechdrs,
 
 /* These must be implemented by the specific architecture */
 
-/* vmalloc AND zero for the non-releasable code; return ERR_PTR() on error. */
-void *module_core_alloc(const Elf_Ehdr *hdr,
-                       const Elf_Shdr *sechdrs,
-                       const char *secstrings,
-                       struct module *mod);
-
-/* vmalloc and zero (if any) for sections to be freed after init.
-   Return ERR_PTR() on error. */
-void *module_init_alloc(const Elf_Ehdr *hdr,
-                       const Elf_Shdr *sechdrs,
-                       const char *secstrings,
-                       struct module *mod);
-
-/* Free memory returned from module_core_alloc/module_init_alloc */
+/* Total size to allocate for the non-releasable code; return len or
+   -error.  mod->core_size is the current generic tally. */
+long module_core_size(const Elf_Ehdr *hdr,
+                     const Elf_Shdr *sechdrs,
+                     const char *secstrings,
+                     struct module *mod);
+
+/* Total size of (if any) sections to be freed after init.  Return 0
+   for none, len, or -error. mod->init_size is the current generic
+   tally. */
+long module_init_size(const Elf_Ehdr *hdr,
+                     const Elf_Shdr *sechdrs,
+                     const char *secstrings,
+                     struct module *mod);
+
+/* Allocator used for allocating struct module, core sections and init
+   sections.  Returns NULL on failure. */
+void *module_alloc(unsigned long size);
+
+/* Free memory returned from module_alloc. */
 void module_free(struct module *mod, void *module_region);
 
 /* Apply the given relocation to the (simplified) ELF.  Return -error
index c92e6b7ca6bfc464a1a1ce7cb883389033c68ba2..728e8698422cba3a32ac76c51603262e50e6aa07 100644 (file)
@@ -557,7 +557,7 @@ static void free_module(struct module *mod)
        module_unload_free(mod);
 
        /* Finally, free the module structure */
-       kfree(mod);
+       module_free(mod, mod);
 }
 
 void *__symbol_get(const char *symbol)
@@ -805,7 +805,7 @@ static struct module *load_module(void *umod,
        unsigned long common_length;
        struct sizes sizes, used;
        struct module *mod;
-       int err = 0;
+       long err = 0;
        void *ptr = NULL; /* Stops spurious gcc uninitialized warning */
 
        DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -894,7 +894,7 @@ static struct module *load_module(void *umod,
                goto free_hdr;
        arglen = err;
 
-       mod = kmalloc(sizeof(*mod) + arglen+1, GFP_KERNEL);
+       mod = module_alloc(sizeof(*mod) + arglen+1);
        if (!mod) {
                err = -ENOMEM;
                goto free_hdr;
@@ -925,20 +925,36 @@ static struct module *load_module(void *umod,
        common_length = read_commons(hdr, &sechdrs[symindex]);
        sizes.core_size += common_length;
 
-       /* Set these up: arch's can add to them */
+       /* Set these up, and allow archs to manipulate them. */
        mod->core_size = sizes.core_size;
        mod->init_size = sizes.init_size;
 
-       /* Allocate (this is arch specific) */
-       ptr = module_core_alloc(hdr, sechdrs, secstrings, mod);
-       if (IS_ERR(ptr))
+       /* Allow archs to add to them. */
+       err = module_init_size(hdr, sechdrs, secstrings, mod);
+       if (err < 0)
                goto free_mod;
+       mod->init_size = err;
 
+       err = module_core_size(hdr, sechdrs, secstrings, mod);
+       if (err < 0)
+               goto free_mod;
+       mod->core_size = err;
+
+       /* Do the allocs. */
+       ptr = module_alloc(mod->core_size);
+       if (!ptr) {
+               err = -ENOMEM;
+               goto free_mod;
+       }
+       memset(ptr, 0, mod->core_size);
        mod->module_core = ptr;
 
-       ptr = module_init_alloc(hdr, sechdrs, secstrings, mod);
-       if (IS_ERR(ptr))
+       ptr = module_alloc(mod->init_size);
+       if (!ptr) {
+               err = -ENOMEM;
                goto free_core;
+       }
+       memset(ptr, 0, mod->init_size);
        mod->module_init = ptr;
 
        /* Transfer each section which requires ALLOC, and set sh_offset
@@ -1015,7 +1031,7 @@ static struct module *load_module(void *umod,
  free_core:
        module_free(mod, mod->module_core);
  free_mod:
-       kfree(mod);
+       module_free(mod, mod);
  free_hdr:
        vfree(hdr);
        if (err < 0) return ERR_PTR(err);