source: trunk/target/linux/cobalt/patches-2.6.39/001-no_module_reloc.patch @ 27175

Last change on this file since 27175 was 27175, checked in by florian, 5 years ago

[cobalt] switch to 2.6.39

File size: 9.2 KB
  • arch/mips/include/asm/module.h

    a b struct mod_arch_specific { 
    99        struct list_head dbe_list; 
    1010        const struct exception_table_entry *dbe_start; 
    1111        const struct exception_table_entry *dbe_end; 
    12  
    13         void *phys_plt_tbl; 
    14         void *virt_plt_tbl; 
    15         unsigned int phys_plt_offset; 
    16         unsigned int virt_plt_offset; 
    1712}; 
    1813 
    1914typedef uint8_t Elf64_Byte;             /* Type for a 8-bit quantity.  */ 
  • arch/mips/kernel/module.c

    a b static struct mips_hi16 *mips_hi16_list; 
    4545static LIST_HEAD(dbe_list); 
    4646static DEFINE_SPINLOCK(dbe_lock); 
    4747 
    48 /* 
    49  * Get the potential max trampolines size required of the init and 
    50  * non-init sections. Only used if we cannot find enough contiguous 
    51  * physically mapped memory to put the module into. 
    52  */ 
    53 static unsigned int 
    54 get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, 
    55              const char *secstrings, unsigned int symindex, bool is_init) 
    56 { 
    57         unsigned long ret = 0; 
    58         unsigned int i, j; 
    59         Elf_Sym *syms; 
    60  
    61         /* Everything marked ALLOC (this includes the exported symbols) */ 
    62         for (i = 1; i < hdr->e_shnum; ++i) { 
    63                 unsigned int info = sechdrs[i].sh_info; 
    64  
    65                 if (sechdrs[i].sh_type != SHT_REL 
    66                     && sechdrs[i].sh_type != SHT_RELA) 
    67                         continue; 
    68  
    69                 /* Not a valid relocation section? */ 
    70                 if (info >= hdr->e_shnum) 
    71                         continue; 
    72  
    73                 /* Don't bother with non-allocated sections */ 
    74                 if (!(sechdrs[info].sh_flags & SHF_ALLOC)) 
    75                         continue; 
    76  
    77                 /* If it's called *.init*, and we're not init, we're 
    78                    not interested */ 
    79                 if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) 
    80                     != is_init) 
    81                         continue; 
    82  
    83                 syms = (Elf_Sym *) sechdrs[symindex].sh_addr; 
    84                 if (sechdrs[i].sh_type == SHT_REL) { 
    85                         Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; 
    86                         unsigned int size = sechdrs[i].sh_size / sizeof(*rel); 
    87  
    88                         for (j = 0; j < size; ++j) { 
    89                                 Elf_Sym *sym; 
    90  
    91                                 if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) 
    92                                         continue; 
    93  
    94                                 sym = syms + ELF_MIPS_R_SYM(rel[j]); 
    95                                 if (!is_init && sym->st_shndx != SHN_UNDEF) 
    96                                         continue; 
    97  
    98                                 ret += 4 * sizeof(int); 
    99                         } 
    100                 } else { 
    101                         Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; 
    102                         unsigned int size = sechdrs[i].sh_size / sizeof(*rela); 
    103  
    104                         for (j = 0; j < size; ++j) { 
    105                                 Elf_Sym *sym; 
    106  
    107                                 if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) 
    108                                         continue; 
    109  
    110                                 sym = syms + ELF_MIPS_R_SYM(rela[j]); 
    111                                 if (!is_init && sym->st_shndx != SHN_UNDEF) 
    112                                         continue; 
    113  
    114                                 ret += 4 * sizeof(int); 
    115                         } 
    116                 } 
    117         } 
    118  
    119         return ret; 
    120 } 
    121  
    122 #ifndef MODULE_START 
    123 static void *alloc_phys(unsigned long size) 
    124 { 
    125         unsigned order; 
    126         struct page *page; 
    127         struct page *p; 
    128  
    129         size = PAGE_ALIGN(size); 
    130         order = get_order(size); 
    131  
    132         page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | 
    133                         __GFP_THISNODE, order); 
    134         if (!page) 
    135                 return NULL; 
    136  
    137         split_page(page, order); 
    138  
    139         for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) 
    140                 __free_page(p); 
    141  
    142         return page_address(page); 
    143 } 
    144 #endif 
    145  
    146 static void free_phys(void *ptr, unsigned long size) 
    147 { 
    148         struct page *page; 
    149         struct page *end; 
    150  
    151         page = virt_to_page(ptr); 
    152         end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT); 
    153  
    154         for (; page < end; ++page) 
    155                 __free_page(page); 
    156 } 
    157  
    158  
    15948void *module_alloc(unsigned long size) 
    16049{ 
    16150#ifdef MODULE_START 
    void *module_alloc(unsigned long size) 
    16352                                GFP_KERNEL, PAGE_KERNEL, -1, 
    16453                                __builtin_return_address(0)); 
    16554#else 
    166         void *ptr; 
    167  
    16855        if (size == 0) 
    16956                return NULL; 
    170  
    171         ptr = alloc_phys(size); 
    172  
    173         /* If we failed to allocate physically contiguous memory, 
    174          * fall back to regular vmalloc. The module loader code will 
    175          * create jump tables to handle long jumps */ 
    176         if (!ptr) 
    177                 return vmalloc(size); 
    178  
    179         return ptr; 
    180 #endif 
    181 } 
    182  
    183 static inline bool is_phys_addr(void *ptr) 
    184 { 
    185 #ifdef CONFIG_64BIT 
    186         return (KSEGX((unsigned long)ptr) == CKSEG0); 
    187 #else 
    188         return (KSEGX(ptr) == KSEG0); 
     57        return vmalloc(size); 
    18958#endif 
    19059} 
    19160 
    19261/* Free memory returned from module_alloc */ 
    19362void module_free(struct module *mod, void *module_region) 
    19463{ 
    195         if (is_phys_addr(module_region)) { 
    196                 if (mod->module_init == module_region) 
    197                         free_phys(module_region, mod->init_size); 
    198                 else if (mod->module_core == module_region) 
    199                         free_phys(module_region, mod->core_size); 
    200                 else 
    201                         BUG(); 
    202         } else { 
    203                 vfree(module_region); 
    204         } 
    205 } 
    206  
    207 static void *__module_alloc(int size, bool phys) 
    208 { 
    209         void *ptr; 
    210  
    211         if (phys) 
    212                 ptr = kmalloc(size, GFP_KERNEL); 
    213         else 
    214                 ptr = vmalloc(size); 
    215         return ptr; 
    216 } 
    217  
    218 static void __module_free(void *ptr) 
    219 { 
    220         if (is_phys_addr(ptr)) 
    221                 kfree(ptr); 
    222         else 
    223                 vfree(ptr); 
     64        vfree(module_region); 
    22465} 
    22566 
    22667int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, 
    22768                              char *secstrings, struct module *mod) 
    22869{ 
    229         unsigned int symindex = 0; 
    230         unsigned int core_size, init_size; 
    231         int i; 
    232  
    233         for (i = 1; i < hdr->e_shnum; i++) 
    234                 if (sechdrs[i].sh_type == SHT_SYMTAB) 
    235                         symindex = i; 
    236  
    237         core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); 
    238         init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); 
    239  
    240         mod->arch.phys_plt_offset = 0; 
    241         mod->arch.virt_plt_offset = 0; 
    242         mod->arch.phys_plt_tbl = NULL; 
    243         mod->arch.virt_plt_tbl = NULL; 
    244  
    245         if ((core_size + init_size) == 0) 
    246                 return 0; 
    247  
    248         mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); 
    249         if (!mod->arch.phys_plt_tbl) 
    250                 return -ENOMEM; 
    251  
    252         mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); 
    253         if (!mod->arch.virt_plt_tbl) { 
    254                 __module_free(mod->arch.phys_plt_tbl); 
    255                 mod->arch.phys_plt_tbl = NULL; 
    256                 return -ENOMEM; 
    257         } 
    258  
    25970        return 0; 
    26071} 
    26172 
    static int apply_r_mips_32_rela(struct m 
    27889        return 0; 
    27990} 
    28091 
    281 static Elf_Addr add_plt_entry_to(unsigned *plt_offset, 
    282                                  void *start, Elf_Addr v) 
     92static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) 
    28393{ 
    284         unsigned *tramp = start + *plt_offset; 
    285         *plt_offset += 4 * sizeof(int); 
    286  
    287         /* adjust carry for addiu */ 
    288         if (v & 0x00008000) 
    289                 v += 0x10000; 
    290  
    291         tramp[0] = 0x3c190000 | (v >> 16);      /* lui t9, hi16 */ 
    292         tramp[1] = 0x27390000 | (v & 0xffff);   /* addiu t9, t9, lo16 */ 
    293         tramp[2] = 0x03200008;                  /* jr t9 */ 
    294         tramp[3] = 0x00000000;                  /* nop */ 
     94        if (v % 4) { 
     95                pr_err("module %s: dangerous R_MIPS_26 REL relocation\n", 
     96                       me->name); 
     97                return -ENOEXEC; 
     98        } 
    29599 
    296         return (Elf_Addr) tramp; 
    297 } 
     100        if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 
     101                printk(KERN_ERR 
     102                       "module %s: relocation overflow\n", 
     103                       me->name); 
     104                return -ENOEXEC; 
     105        } 
    298106 
    299 static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) 
    300 { 
    301         if (is_phys_addr(location)) 
    302                 return add_plt_entry_to(&me->arch.phys_plt_offset, 
    303                                 me->arch.phys_plt_tbl, v); 
    304         else 
    305                 return add_plt_entry_to(&me->arch.virt_plt_offset, 
    306                                 me->arch.virt_plt_tbl, v); 
     107        *location = (*location & ~0x03ffffff) | 
     108                    ((*location + (v >> 2)) & 0x03ffffff); 
    307109 
     110        return 0; 
    308111} 
    309112 
    310 static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v) 
     113static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) 
    311114{ 
    312115        if (v % 4) { 
    313116                pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", 
    static int set_r_mips_26(struct module * 
    316119        } 
    317120 
    318121        if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 
    319             v = add_plt_entry(me, location, v + (ofs << 2)); 
    320                 if (!v) { 
    321                         printk(KERN_ERR 
     122                printk(KERN_ERR 
    322123                       "module %s: relocation overflow\n", 
    323124                       me->name); 
    324                         return -ENOEXEC; 
    325                 } 
    326                 ofs = 0; 
     125                return -ENOEXEC; 
    327126        } 
    328127 
    329         *location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff); 
     128        *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); 
    330129 
    331130        return 0; 
    332131} 
    333132 
    334 static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) 
    335 { 
    336         return set_r_mips_26(me, location, *location & 0x03ffffff, v); 
    337 } 
    338  
    339 static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) 
    340 { 
    341         return set_r_mips_26(me, location, 0, v); 
    342 } 
    343  
    344133static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) 
    345134{ 
    346135        struct mips_hi16 *n; 
    int module_finalize(const Elf_Ehdr *hdr, 
    608397                list_add(&me->arch.dbe_list, &dbe_list); 
    609398                spin_unlock_irq(&dbe_lock); 
    610399        } 
    611  
    612         /* Get rid of the fixup trampoline if we're running the module 
    613          * from physically mapped address space */ 
    614         if (me->arch.phys_plt_offset == 0) { 
    615                 __module_free(me->arch.phys_plt_tbl); 
    616                 me->arch.phys_plt_tbl = NULL; 
    617         } 
    618         if (me->arch.virt_plt_offset == 0) { 
    619                 __module_free(me->arch.virt_plt_tbl); 
    620                 me->arch.virt_plt_tbl = NULL; 
    621         } 
    622  
    623400        return 0; 
    624401} 
    625402 
    626403void module_arch_cleanup(struct module *mod) 
    627404{ 
    628         if (mod->arch.phys_plt_tbl) { 
    629                 __module_free(mod->arch.phys_plt_tbl); 
    630                 mod->arch.phys_plt_tbl = NULL; 
    631         } 
    632         if (mod->arch.virt_plt_tbl) { 
    633                 __module_free(mod->arch.virt_plt_tbl); 
    634                 mod->arch.virt_plt_tbl = NULL; 
    635         } 
    636  
    637405        spin_lock_irq(&dbe_lock); 
    638406        list_del(&mod->arch.dbe_list); 
    639407        spin_unlock_irq(&dbe_lock); 
  • arch/mips/Makefile

    a b all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin 
    9090cflags-y                        += -G 0 -mno-abicalls -fno-pic -pipe 
    9191cflags-y                        += -msoft-float 
    9292LDFLAGS_vmlinux                 += -G 0 -static -n -nostdlib 
    93 KBUILD_AFLAGS_MODULE            += -mno-long-calls 
    94 KBUILD_CFLAGS_MODULE            += -mno-long-calls 
     93KBUILD_AFLAGS_MODULE            += -mlong-calls 
     94KBUILD_CFLAGS_MODULE            += -mlong-calls 
    9595 
    9696cflags-y += -ffreestanding 
    9797 
Note: See TracBrowser for help on using the repository browser.