net ipv4: Decouple ipv4 interface parameters from binary sysctl numbers
[safe/jmp/linux-2.6] / arch / s390 / kernel / module.c
index 607d506..639380a 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/moduleloader.h>
+#include <linux/bug.h>
 
 #if 0
 #define DEBUGP printk
 #define DEBUGP(fmt , ...)
 #endif
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 #define PLT_ENTRY_SIZE 12
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #define PLT_ENTRY_SIZE 20
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 void *module_alloc(unsigned long size)
 {
@@ -53,12 +55,12 @@ void *module_alloc(unsigned long size)
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
+       vfree(mod->arch.syminfo);
+       mod->arch.syminfo = NULL;
        vfree(module_region);
-       /* FIXME: If module_region == mod->init_region, trim exception
-           table entries. */
 }
 
-static inline void
+static void
 check_rela(Elf_Rela *rela, struct module *me)
 {
        struct mod_arch_syminfo *info;
@@ -119,7 +121,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
        int nrela, i, j;
 
        /* Find symbol table and string table. */
-       symtab = 0;
+       symtab = NULL;
        for (i = 0; i < hdr->e_shnum; i++)
                switch (sechdrs[i].sh_type) {
                case SHT_SYMTAB:
@@ -181,7 +183,7 @@ apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex,
        return -ENOEXEC;
 }
 
-static inline int
+static int
 apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, 
           struct module *me)
 {
@@ -294,29 +296,34 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
                        unsigned int *ip;
                        ip = me->module_core + me->arch.plt_offset +
                                info->plt_offset;
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
                        ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
                        ip[1] = 0x100607f1;
                        ip[2] = val;
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
                        ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
                        ip[1] = 0x100a0004;
                        ip[2] = 0x07f10000;
                        ip[3] = (unsigned int) (val >> 32);
                        ip[4] = (unsigned int) val;
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
                        info->plt_initialized = 1;
                }
                if (r_type == R_390_PLTOFF16 ||
-                   r_type == R_390_PLTOFF32
-                   || r_type == R_390_PLTOFF64
-                       )
+                   r_type == R_390_PLTOFF32 ||
+                   r_type == R_390_PLTOFF64)
                        val = me->arch.plt_offset - me->arch.got_offset +
                                info->plt_offset + rela->r_addend;
-               else
-                       val =  (Elf_Addr) me->module_core +
-                               me->arch.plt_offset + info->plt_offset + 
-                               rela->r_addend - loc;
+               else {
+                       if (!((r_type == R_390_PLT16DBL &&
+                              val - loc + 0xffffUL < 0x1ffffeUL) ||
+                             (r_type == R_390_PLT32DBL &&
+                              val - loc + 0xffffffffULL < 0x1fffffffeULL)))
+                               val = (Elf_Addr) me->module_core +
+                                       me->arch.plt_offset +
+                                       info->plt_offset;
+                       val += rela->r_addend - loc;
+               }
                if (r_type == R_390_PLT16DBL)
                        *(unsigned short *) loc = val >> 1;
                else if (r_type == R_390_PLTOFF16)
@@ -397,9 +404,11 @@ int module_finalize(const Elf_Ehdr *hdr,
                    struct module *me)
 {
        vfree(me->arch.syminfo);
-       return 0;
+       me->arch.syminfo = NULL;
+       return module_bug_finalize(hdr, sechdrs, me);
 }
 
 void module_arch_cleanup(struct module *mod)
 {
+       module_bug_cleanup(mod);
 }