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