Add 'discard' request handling
[linux-2.6.git] / arch / cris / kernel / module.c
index f1d3e784f30c7ae366073e5f63b2245d0cf9ba66..a187833febc8b0cfd582a39b84aaefdabe54a205 100644 (file)
 #define DEBUGP(fmt , ...)
 #endif
 
+#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
+#define MALLOC_MODULE(size) kmalloc(size, GFP_KERNEL)
+#define FREE_MODULE(region) kfree(region)
+#else
+#define MALLOC_MODULE(size) vmalloc_exec(size)
+#define FREE_MODULE(region) vfree(region)
+#endif
+
 void *module_alloc(unsigned long size)
 {
        if (size == 0)
                return NULL;
-       return vmalloc(size);
+       return MALLOC_MODULE(size);
 }
 
 
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
-       vfree(module_region);
+       FREE_MODULE(module_region);
        /* FIXME: If module_region == mod->init_region, trim exception
-           table entries. */
+          table entries. */
 }
 
 /* We don't need anything special. */
@@ -59,26 +67,8 @@ int apply_relocate(Elf32_Shdr *sechdrs,
                   unsigned int relsec,
                   struct module *me)
 {
-       unsigned int i;
-       Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
-       Elf32_Sym *sym;
-       uint32_t *location;
-
-       DEBUGP("Applying relocate section %u to %u\n", relsec,
-              sechdrs[relsec].sh_info);
-       for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
-               /* This is where to make the change */
-               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset
-                       + rel[i].r_offset;
-               /* This is the symbol it is referring to.  Note that all
-                  undefined symbols have been resolved.  */
-               sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
-                       + ELF32_R_SYM(rel[i].r_info);
-
-                /* We add the value into the location given */
-                *location += sym->st_value;
-       }
-       return 0;
+       printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
+       return -ENOEXEC;
 }
 
 int apply_relocate_add(Elf32_Shdr *sechdrs,
@@ -90,7 +80,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
        unsigned int i;
        Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
 
-       DEBUGP ("Applying relocate section %u to %u\n", relsec,
+       DEBUGP ("Applying add relocate section %u to %u\n", relsec,
                sechdrs[relsec].sh_info);
 
        for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
@@ -103,7 +93,18 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
                Elf32_Sym *sym
                        = ((Elf32_Sym *)sechdrs[symindex].sh_addr
                           + ELF32_R_SYM (rela[i].r_info));
-               *loc = sym->st_value + rela[i].r_addend;
+               switch (ELF32_R_TYPE(rela[i].r_info)) {
+               case R_CRIS_32:
+                       *loc = sym->st_value + rela[i].r_addend;
+                       break;
+               case R_CRIS_32_PCREL:
+                       *loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4;
+                        break;
+               default:
+                       printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+                              me->name, ELF32_R_TYPE(rela[i].r_info));
+                       return -ENOEXEC;
+               }
        }
 
        return 0;