Merge branch 'old_next' into next
[pandora-kernel.git] / arch / arm / kernel / module.c
index 6d4105e..fee7c36 100644 (file)
@@ -76,6 +76,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
        for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
                unsigned long loc;
                Elf32_Sym *sym;
+               const char *symname;
                s32 offset;
 #ifdef CONFIG_THUMB2_KERNEL
                u32 upper, lower, sign, j1, j2;
@@ -83,18 +84,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 
                offset = ELF32_R_SYM(rel->r_info);
                if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
-                       printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n",
+                       pr_err("%s: section %u reloc %u: bad relocation sym offset\n",
                                module->name, relindex, i);
                        return -ENOEXEC;
                }
 
                sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
+               symname = strtab + sym->st_name;
 
                if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
-                       printk(KERN_ERR "%s: out of bounds relocation, "
-                               "section %d reloc %d offset %d size %d\n",
-                               module->name, relindex, i, rel->r_offset,
-                               dstsec->sh_size);
+                       pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n",
+                              module->name, relindex, i, symname,
+                              rel->r_offset, dstsec->sh_size);
                        return -ENOEXEC;
                }
 
@@ -120,10 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
                        if (offset & 3 ||
                            offset <= (s32)0xfe000000 ||
                            offset >= (s32)0x02000000) {
-                               printk(KERN_ERR
-                                      "%s: relocation out of range, section "
-                                      "%d reloc %d sym '%s'\n", module->name,
-                                      relindex, i, strtab + sym->st_name);
+                               pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+                                      module->name, relindex, i, symname,
+                                      ELF32_R_TYPE(rel->r_info), loc,
+                                      sym->st_value);
                                return -ENOEXEC;
                        }
 
@@ -196,10 +197,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
                        if (!(offset & 1) ||
                            offset <= (s32)0xff000000 ||
                            offset >= (s32)0x01000000) {
-                               printk(KERN_ERR
-                                      "%s: relocation out of range, section "
-                                      "%d reloc %d sym '%s'\n", module->name,
-                                      relindex, i, strtab + sym->st_name);
+                               pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+                                      module->name, relindex, i, symname,
+                                      ELF32_R_TYPE(rel->r_info), loc,
+                                      sym->st_value);
                                return -ENOEXEC;
                        }
 
@@ -282,12 +283,13 @@ static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr,
        return NULL;
 }
 
+extern void fixup_pv_table(const void *, unsigned long);
 extern void fixup_smp(const void *, unsigned long);
 
 int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
                    struct module *mod)
 {
-       const Elf_Shdr * __maybe_unused s = NULL;
+       const Elf_Shdr *s = NULL;
 #ifdef CONFIG_ARM_UNWIND
        const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
        const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
@@ -331,6 +333,11 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
                                                 maps[i].unw_sec->sh_size,
                                                 maps[i].txt_sec->sh_addr,
                                                 maps[i].txt_sec->sh_size);
+#endif
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+       s = find_mod_section(hdr, sechdrs, ".pv_table");
+       if (s)
+               fixup_pv_table((void *)s->sh_addr, s->sh_size);
 #endif
        s = find_mod_section(hdr, sechdrs, ".alt.smp.init");
        if (s && !is_smp())