11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Kernel module help for i386. 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright (C) 2001 Rusty Russell. 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is free software; you can redistribute it and/or modify 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it under the terms of the GNU General Public License as published by 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the Free Software Foundation; either version 2 of the License, or 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (at your option) any later version. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is distributed in the hope that it will be useful, 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GNU General Public License for more details. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds You should have received a copy of the GNU General Public License 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds along with this program; if not, write to the Free Software 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/moduleloader.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/elf.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vmalloc.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 245a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUGP printk 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUGP(fmt , ...) 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3208cfeacb6bcb37c5cf1a9bc0c930243634631f09Jesper Nilsson#ifdef CONFIG_ETRAX_KMALLOCED_MODULES 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid *module_alloc(unsigned long size) 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3566574cc05438dd0907029075d7e6ec5ac0036fbcJonas Bonn return kmalloc(size, GFP_KERNEL); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Free memory returned from module_alloc */ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid module_free(struct module *mod, void *module_region) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4166574cc05438dd0907029075d7e6ec5ac0036fbcJonas Bonn kfree(module_region); 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4366574cc05438dd0907029075d7e6ec5ac0036fbcJonas Bonn#endif 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint apply_relocate_add(Elf32_Shdr *sechdrs, 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *strtab, 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int symindex, 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int relsec, 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct module *me) 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 545d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik DEBUGP ("Applying add relocate section %u to %u\n", relsec, 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sechdrs[relsec].sh_info); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) { 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This is where to make the change */ 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uint32_t *loc 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + rela[i].r_offset); 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This is the symbol it is referring to. Note that all 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds undefined symbols have been resolved. */ 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Elf32_Sym *sym 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds = ((Elf32_Sym *)sechdrs[symindex].sh_addr 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + ELF32_R_SYM (rela[i].r_info)); 675d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik switch (ELF32_R_TYPE(rela[i].r_info)) { 685d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik case R_CRIS_32: 695d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik *loc = sym->st_value + rela[i].r_addend; 705d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik break; 715d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik case R_CRIS_32_PCREL: 725d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik *loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4; 735d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik break; 745d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik default: 755d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik printk(KERN_ERR "module %s: Unknown relocation: %u\n", 765d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik me->name, ELF32_R_TYPE(rela[i].r_info)); 775d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik return -ENOEXEC; 785d01e6ce785884a5db5792cd2e5bb36fa82fe23cMikael Starvik } 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 83