1 /* 2 * arch/xtensa/kernel/module.c 3 * 4 * Module support. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 * 10 * Copyright (C) 2001 - 2006 Tensilica Inc. 11 * 12 * Chris Zankel <chris@zankel.net> 13 * 14 */ 15 16 #include <linux/module.h> 17 #include <linux/moduleloader.h> 18 #include <linux/elf.h> 19 #include <linux/vmalloc.h> 20 #include <linux/fs.h> 21 #include <linux/string.h> 22 #include <linux/kernel.h> 23 #include <linux/cache.h> 24 25 #undef DEBUG_RELOCATE 26 27 void *module_alloc(unsigned long size) 28 { 29 if (size == 0) 30 return NULL; 31 return vmalloc_exec(size); 32 } 33 34 void module_free(struct module *mod, void *module_region) 35 { 36 vfree(module_region); 37 } 38 39 int module_frob_arch_sections(Elf32_Ehdr *hdr, 40 Elf32_Shdr *sechdrs, 41 char *secstrings, 42 struct module *mod) 43 { 44 return 0; 45 } 46 47 static int 48 decode_calln_opcode (unsigned char *location) 49 { 50 #ifdef __XTENSA_EB__ 51 return (location[0] & 0xf0) == 0x50; 52 #endif 53 #ifdef __XTENSA_EL__ 54 return (location[0] & 0xf) == 0x5; 55 #endif 56 } 57 58 static int 59 decode_l32r_opcode (unsigned char *location) 60 { 61 #ifdef __XTENSA_EB__ 62 return (location[0] & 0xf0) == 0x10; 63 #endif 64 #ifdef __XTENSA_EL__ 65 return (location[0] & 0xf) == 0x1; 66 #endif 67 } 68 69 int apply_relocate(Elf32_Shdr *sechdrs, 70 const char *strtab, 71 unsigned int symindex, 72 unsigned int relsec, 73 struct module *mod) 74 { 75 printk(KERN_ERR "module %s: REL RELOCATION unsupported\n", 76 mod->name); 77 return -ENOEXEC; 78 79 } 80 81 int apply_relocate_add(Elf32_Shdr *sechdrs, 82 const char *strtab, 83 unsigned int symindex, 84 unsigned int relsec, 85 struct module *mod) 86 { 87 unsigned int i; 88 Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; 89 Elf32_Sym *sym; 90 unsigned char *location; 91 uint32_t value; 92 93 #ifdef DEBUG_RELOCATE 94 printk("Applying relocate section %u to %u\n", relsec, 95 sechdrs[relsec].sh_info); 96 #endif 97 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { 98 location = (char *)sechdrs[sechdrs[relsec].sh_info].sh_addr 99 + rela[i].r_offset; 100 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 101 + ELF32_R_SYM(rela[i].r_info); 102 value = sym->st_value + rela[i].r_addend; 103 104 switch (ELF32_R_TYPE(rela[i].r_info)) { 105 case R_XTENSA_NONE: 106 case R_XTENSA_DIFF8: 107 case R_XTENSA_DIFF16: 108 case R_XTENSA_DIFF32: 109 case R_XTENSA_ASM_EXPAND: 110 break; 111 112 case R_XTENSA_32: 113 case R_XTENSA_PLT: 114 *(uint32_t *)location += value; 115 break; 116 117 case R_XTENSA_SLOT0_OP: 118 if (decode_calln_opcode(location)) { 119 value -= ((unsigned long)location & -4) + 4; 120 if ((value & 3) != 0 || 121 ((value + (1 << 19)) >> 20) != 0) { 122 printk("%s: relocation out of range, " 123 "section %d reloc %d " 124 "sym '%s'\n", 125 mod->name, relsec, i, 126 strtab + sym->st_name); 127 return -ENOEXEC; 128 } 129 value = (signed int)value >> 2; 130 #ifdef __XTENSA_EB__ 131 location[0] = ((location[0] & ~0x3) | 132 ((value >> 16) & 0x3)); 133 location[1] = (value >> 8) & 0xff; 134 location[2] = value & 0xff; 135 #endif 136 #ifdef __XTENSA_EL__ 137 location[0] = ((location[0] & ~0xc0) | 138 ((value << 6) & 0xc0)); 139 location[1] = (value >> 2) & 0xff; 140 location[2] = (value >> 10) & 0xff; 141 #endif 142 } else if (decode_l32r_opcode(location)) { 143 value -= (((unsigned long)location + 3) & -4); 144 if ((value & 3) != 0 || 145 (signed int)value >> 18 != -1) { 146 printk("%s: relocation out of range, " 147 "section %d reloc %d " 148 "sym '%s'\n", 149 mod->name, relsec, i, 150 strtab + sym->st_name); 151 return -ENOEXEC; 152 } 153 value = (signed int)value >> 2; 154 155 #ifdef __XTENSA_EB__ 156 location[1] = (value >> 8) & 0xff; 157 location[2] = value & 0xff; 158 #endif 159 #ifdef __XTENSA_EL__ 160 location[1] = value & 0xff; 161 location[2] = (value >> 8) & 0xff; 162 #endif 163 } 164 /* FIXME: Ignore any other opcodes. The Xtensa 165 assembler currently assumes that the linker will 166 always do relaxation and so all PC-relative 167 operands need relocations. (The assembler also 168 writes out the tentative PC-relative values, 169 assuming no link-time relaxation, so it is usually 170 safe to ignore the relocations.) If the 171 assembler's "--no-link-relax" flag can be made to 172 work, and if all kernel modules can be assembled 173 with that flag, then unexpected relocations could 174 be detected here. */ 175 break; 176 177 case R_XTENSA_SLOT1_OP: 178 case R_XTENSA_SLOT2_OP: 179 case R_XTENSA_SLOT3_OP: 180 case R_XTENSA_SLOT4_OP: 181 case R_XTENSA_SLOT5_OP: 182 case R_XTENSA_SLOT6_OP: 183 case R_XTENSA_SLOT7_OP: 184 case R_XTENSA_SLOT8_OP: 185 case R_XTENSA_SLOT9_OP: 186 case R_XTENSA_SLOT10_OP: 187 case R_XTENSA_SLOT11_OP: 188 case R_XTENSA_SLOT12_OP: 189 case R_XTENSA_SLOT13_OP: 190 case R_XTENSA_SLOT14_OP: 191 printk("%s: unexpected FLIX relocation: %u\n", 192 mod->name, 193 ELF32_R_TYPE(rela[i].r_info)); 194 return -ENOEXEC; 195 196 case R_XTENSA_SLOT0_ALT: 197 case R_XTENSA_SLOT1_ALT: 198 case R_XTENSA_SLOT2_ALT: 199 case R_XTENSA_SLOT3_ALT: 200 case R_XTENSA_SLOT4_ALT: 201 case R_XTENSA_SLOT5_ALT: 202 case R_XTENSA_SLOT6_ALT: 203 case R_XTENSA_SLOT7_ALT: 204 case R_XTENSA_SLOT8_ALT: 205 case R_XTENSA_SLOT9_ALT: 206 case R_XTENSA_SLOT10_ALT: 207 case R_XTENSA_SLOT11_ALT: 208 case R_XTENSA_SLOT12_ALT: 209 case R_XTENSA_SLOT13_ALT: 210 case R_XTENSA_SLOT14_ALT: 211 printk("%s: unexpected ALT relocation: %u\n", 212 mod->name, 213 ELF32_R_TYPE(rela[i].r_info)); 214 return -ENOEXEC; 215 216 default: 217 printk("%s: unexpected relocation: %u\n", 218 mod->name, 219 ELF32_R_TYPE(rela[i].r_info)); 220 return -ENOEXEC; 221 } 222 } 223 return 0; 224 } 225 226 int module_finalize(const Elf_Ehdr *hdr, 227 const Elf_Shdr *sechdrs, 228 struct module *mod) 229 { 230 return 0; 231 } 232 233 void module_arch_cleanup(struct module *mod) 234 { 235 } 236