1#include <linux/moduleloader.h> 2#include <linux/elf.h> 3#include <linux/vmalloc.h> 4#include <linux/fs.h> 5#include <linux/string.h> 6#include <linux/kernel.h> 7 8#define DEBUGP(fmt...) 9 10void *module_alloc(unsigned long size) 11{ 12 if (size == 0) 13 return NULL; 14 return vmalloc(size); 15} 16 17 18/* Free memory returned from module_alloc */ 19void module_free(struct module *mod, void *module_region) 20{ 21 vfree(module_region); 22} 23 24/* We don't need anything special. */ 25int module_frob_arch_sections(Elf_Ehdr *hdr, 26 Elf_Shdr *sechdrs, 27 char *secstrings, 28 struct module *mod) 29{ 30 return 0; 31} 32 33int apply_relocate(Elf32_Shdr *sechdrs, 34 const char *strtab, 35 unsigned int symindex, 36 unsigned int relsec, 37 struct module *me) 38{ 39 unsigned int i; 40 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; 41 Elf32_Sym *sym; 42 uint32_t *location; 43 44 DEBUGP("Applying relocate section %u to %u\n", relsec, 45 sechdrs[relsec].sh_info); 46 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 47 /* This is where to make the change */ 48 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 49 + rel[i].r_offset; 50 /* This is the symbol it is referring to. Note that all 51 undefined symbols have been resolved. */ 52 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 53 + ELF32_R_SYM(rel[i].r_info); 54 55 switch (ELF32_R_TYPE(rel[i].r_info)) { 56 case R_68K_32: 57 /* We add the value into the location given */ 58 *location += sym->st_value; 59 break; 60 case R_68K_PC32: 61 /* Add the value, subtract its postition */ 62 *location += sym->st_value - (uint32_t)location; 63 break; 64 default: 65 printk(KERN_ERR "module %s: Unknown relocation: %u\n", 66 me->name, ELF32_R_TYPE(rel[i].r_info)); 67 return -ENOEXEC; 68 } 69 } 70 return 0; 71} 72 73int apply_relocate_add(Elf32_Shdr *sechdrs, 74 const char *strtab, 75 unsigned int symindex, 76 unsigned int relsec, 77 struct module *me) 78{ 79 unsigned int i; 80 Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; 81 Elf32_Sym *sym; 82 uint32_t *location; 83 84 DEBUGP("Applying relocate_add section %u to %u\n", relsec, 85 sechdrs[relsec].sh_info); 86 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 87 /* This is where to make the change */ 88 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 89 + rel[i].r_offset; 90 /* This is the symbol it is referring to. Note that all 91 undefined symbols have been resolved. */ 92 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 93 + ELF32_R_SYM(rel[i].r_info); 94 95 switch (ELF32_R_TYPE(rel[i].r_info)) { 96 case R_68K_32: 97 /* We add the value into the location given */ 98 *location = rel[i].r_addend + sym->st_value; 99 break; 100 case R_68K_PC32: 101 /* Add the value, subtract its postition */ 102 *location = rel[i].r_addend + sym->st_value - (uint32_t)location; 103 break; 104 default: 105 printk(KERN_ERR "module %s: Unknown relocation: %u\n", 106 me->name, ELF32_R_TYPE(rel[i].r_info)); 107 return -ENOEXEC; 108 } 109 } 110 return 0; 111} 112 113int module_finalize(const Elf_Ehdr *hdr, 114 const Elf_Shdr *sechdrs, 115 struct module *me) 116{ 117 return 0; 118} 119 120void module_arch_cleanup(struct module *mod) 121{ 122} 123