1 /* Kernel module help for PPC. 2 Copyright (C) 2001 Rusty Russell. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 #include <linux/module.h> 19 #include <linux/moduleloader.h> 20 #include <linux/elf.h> 21 #include <linux/vmalloc.h> 22 #include <linux/fs.h> 23 #include <linux/string.h> 24 #include <linux/kernel.h> 25 #include <linux/cache.h> 26 27 #if 0 28 #define DEBUGP printk 29 #else 30 #define DEBUGP(fmt , ...) 31 #endif 32 33 LIST_HEAD(module_bug_list); 34 35 void *module_alloc(unsigned long size) 36 { 37 if (size == 0) 38 return NULL; 39 return vmalloc(size); 40 } 41 42 /* Free memory returned from module_alloc */ 43 void module_free(struct module *mod, void *module_region) 44 { 45 vfree(module_region); 46 /* FIXME: If module_region == mod->init_region, trim exception 47 table entries. */ 48 } 49 50 /* Count how many different relocations (different symbol, different 51 addend) */ 52 static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) 53 { 54 unsigned int i, j, ret = 0; 55 56 /* Sure, this is order(n^2), but it's usually short, and not 57 time critical */ 58 for (i = 0; i < num; i++) { 59 for (j = 0; j < i; j++) { 60 /* If this addend appeared before, it's 61 already been counted */ 62 if (ELF32_R_SYM(rela[i].r_info) 63 == ELF32_R_SYM(rela[j].r_info) 64 && rela[i].r_addend == rela[j].r_addend) 65 break; 66 } 67 if (j == i) ret++; 68 } 69 return ret; 70 } 71 72 /* Get the potential trampolines size required of the init and 73 non-init sections */ 74 static unsigned long get_plt_size(const Elf32_Ehdr *hdr, 75 const Elf32_Shdr *sechdrs, 76 const char *secstrings, 77 int is_init) 78 { 79 unsigned long ret = 0; 80 unsigned i; 81 82 /* Everything marked ALLOC (this includes the exported 83 symbols) */ 84 for (i = 1; i < hdr->e_shnum; i++) { 85 /* If it's called *.init*, and we're not init, we're 86 not interested */ 87 if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) 88 != is_init) 89 continue; 90 91 /* We don't want to look at debug sections. */ 92 if (strstr(secstrings + sechdrs[i].sh_name, ".debug") != 0) 93 continue; 94 95 if (sechdrs[i].sh_type == SHT_RELA) { 96 DEBUGP("Found relocations in section %u\n", i); 97 DEBUGP("Ptr: %p. Number: %u\n", 98 (void *)hdr + sechdrs[i].sh_offset, 99 sechdrs[i].sh_size / sizeof(Elf32_Rela)); 100 ret += count_relocs((void *)hdr 101 + sechdrs[i].sh_offset, 102 sechdrs[i].sh_size 103 / sizeof(Elf32_Rela)) 104 * sizeof(struct ppc_plt_entry); 105 } 106 } 107 108 return ret; 109 } 110 111 int module_frob_arch_sections(Elf32_Ehdr *hdr, 112 Elf32_Shdr *sechdrs, 113 char *secstrings, 114 struct module *me) 115 { 116 unsigned int i; 117 118 /* Find .plt and .init.plt sections */ 119 for (i = 0; i < hdr->e_shnum; i++) { 120 if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0) 121 me->arch.init_plt_section = i; 122 else if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0) 123 me->arch.core_plt_section = i; 124 } 125 if (!me->arch.core_plt_section || !me->arch.init_plt_section) { 126 printk("Module doesn't contain .plt or .init.plt sections.\n"); 127 return -ENOEXEC; 128 } 129 130 /* Override their sizes */ 131 sechdrs[me->arch.core_plt_section].sh_size 132 = get_plt_size(hdr, sechdrs, secstrings, 0); 133 sechdrs[me->arch.init_plt_section].sh_size 134 = get_plt_size(hdr, sechdrs, secstrings, 1); 135 return 0; 136 } 137 138 int apply_relocate(Elf32_Shdr *sechdrs, 139 const char *strtab, 140 unsigned int symindex, 141 unsigned int relsec, 142 struct module *module) 143 { 144 printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n", 145 module->name); 146 return -ENOEXEC; 147 } 148 149 static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) 150 { 151 if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16) 152 && entry->jump[1] == 0x396b0000 + (val & 0xffff)) 153 return 1; 154 return 0; 155 } 156 157 /* Set up a trampoline in the PLT to bounce us to the distant function */ 158 static uint32_t do_plt_call(void *location, 159 Elf32_Addr val, 160 Elf32_Shdr *sechdrs, 161 struct module *mod) 162 { 163 struct ppc_plt_entry *entry; 164 165 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); 166 /* Init, or core PLT? */ 167 if (location >= mod->module_core 168 && location < mod->module_core + mod->core_size) 169 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; 170 else 171 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; 172 173 /* Find this entry, or if that fails, the next avail. entry */ 174 while (entry->jump[0]) { 175 if (entry_matches(entry, val)) return (uint32_t)entry; 176 entry++; 177 } 178 179 /* Stolen from Paul Mackerras as well... */ 180 entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */ 181 entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/ 182 entry->jump[2] = 0x7d6903a6; /* mtctr r11 */ 183 entry->jump[3] = 0x4e800420; /* bctr */ 184 185 DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); 186 return (uint32_t)entry; 187 } 188 189 int apply_relocate_add(Elf32_Shdr *sechdrs, 190 const char *strtab, 191 unsigned int symindex, 192 unsigned int relsec, 193 struct module *module) 194 { 195 unsigned int i; 196 Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; 197 Elf32_Sym *sym; 198 uint32_t *location; 199 uint32_t value; 200 201 DEBUGP("Applying ADD relocate section %u to %u\n", relsec, 202 sechdrs[relsec].sh_info); 203 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { 204 /* This is where to make the change */ 205 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 206 + rela[i].r_offset; 207 /* This is the symbol it is referring to. Note that all 208 undefined symbols have been resolved. */ 209 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 210 + ELF32_R_SYM(rela[i].r_info); 211 /* `Everything is relative'. */ 212 value = sym->st_value + rela[i].r_addend; 213 214 switch (ELF32_R_TYPE(rela[i].r_info)) { 215 case R_PPC_ADDR32: 216 /* Simply set it */ 217 *(uint32_t *)location = value; 218 break; 219 220 case R_PPC_ADDR16_LO: 221 /* Low half of the symbol */ 222 *(uint16_t *)location = value; 223 break; 224 225 case R_PPC_ADDR16_HA: 226 /* Sign-adjusted lower 16 bits: PPC ELF ABI says: 227 (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF. 228 This is the same, only sane. 229 */ 230 *(uint16_t *)location = (value + 0x8000) >> 16; 231 break; 232 233 case R_PPC_REL24: 234 if ((int)(value - (uint32_t)location) < -0x02000000 235 || (int)(value - (uint32_t)location) >= 0x02000000) 236 value = do_plt_call(location, value, 237 sechdrs, module); 238 239 /* Only replace bits 2 through 26 */ 240 DEBUGP("REL24 value = %08X. location = %08X\n", 241 value, (uint32_t)location); 242 DEBUGP("Location before: %08X.\n", 243 *(uint32_t *)location); 244 *(uint32_t *)location 245 = (*(uint32_t *)location & ~0x03fffffc) 246 | ((value - (uint32_t)location) 247 & 0x03fffffc); 248 DEBUGP("Location after: %08X.\n", 249 *(uint32_t *)location); 250 DEBUGP("ie. jump to %08X+%08X = %08X\n", 251 *(uint32_t *)location & 0x03fffffc, 252 (uint32_t)location, 253 (*(uint32_t *)location & 0x03fffffc) 254 + (uint32_t)location); 255 break; 256 257 case R_PPC_REL32: 258 /* 32-bit relative jump. */ 259 *(uint32_t *)location = value - (uint32_t)location; 260 break; 261 262 default: 263 printk("%s: unknown ADD relocation: %u\n", 264 module->name, 265 ELF32_R_TYPE(rela[i].r_info)); 266 return -ENOEXEC; 267 } 268 } 269 return 0; 270 } 271 272 int module_finalize(const Elf_Ehdr *hdr, 273 const Elf_Shdr *sechdrs, 274 struct module *me) 275 { 276 char *secstrings; 277 unsigned int i; 278 279 me->arch.bug_table = NULL; 280 me->arch.num_bugs = 0; 281 282 /* Find the __bug_table section, if present */ 283 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 284 for (i = 1; i < hdr->e_shnum; i++) { 285 if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) 286 continue; 287 me->arch.bug_table = (void *) sechdrs[i].sh_addr; 288 me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); 289 break; 290 } 291 292 /* 293 * Strictly speaking this should have a spinlock to protect against 294 * traversals, but since we only traverse on BUG()s, a spinlock 295 * could potentially lead to deadlock and thus be counter-productive. 296 */ 297 list_add(&me->arch.bug_list, &module_bug_list); 298 299 return 0; 300 } 301 302 void module_arch_cleanup(struct module *mod) 303 { 304 list_del(&mod->arch.bug_list); 305 } 306 307 struct bug_entry *module_find_bug(unsigned long bugaddr) 308 { 309 struct mod_arch_specific *mod; 310 unsigned int i; 311 struct bug_entry *bug; 312 313 list_for_each_entry(mod, &module_bug_list, bug_list) { 314 bug = mod->bug_table; 315 for (i = 0; i < mod->num_bugs; ++i, ++bug) 316 if (bugaddr == bug->bug_addr) 317 return bug; 318 } 319 return NULL; 320 } 321