1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/moduleloader.h>
19#include <linux/elf.h>
20#include <linux/vmalloc.h>
21#include <linux/fs.h>
22#include <linux/string.h>
23#include <linux/kernel.h>
24#include <linux/slab.h>
25
26#if 0
27#define DEBUGP printk
28#else
29#define DEBUGP(fmt , ...)
30#endif
31
32#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
33void *module_alloc(unsigned long size)
34{
35 return kmalloc(size, GFP_KERNEL);
36}
37
38
39void module_free(struct module *mod, void *module_region)
40{
41 kfree(module_region);
42}
43#endif
44
45int apply_relocate_add(Elf32_Shdr *sechdrs,
46 const char *strtab,
47 unsigned int symindex,
48 unsigned int relsec,
49 struct module *me)
50{
51 unsigned int i;
52 Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
53
54 DEBUGP ("Applying add relocate section %u to %u\n", relsec,
55 sechdrs[relsec].sh_info);
56
57 for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
58
59 uint32_t *loc
60 = ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
61 + rela[i].r_offset);
62
63
64 Elf32_Sym *sym
65 = ((Elf32_Sym *)sechdrs[symindex].sh_addr
66 + ELF32_R_SYM (rela[i].r_info));
67 switch (ELF32_R_TYPE(rela[i].r_info)) {
68 case R_CRIS_32:
69 *loc = sym->st_value + rela[i].r_addend;
70 break;
71 case R_CRIS_32_PCREL:
72 *loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4;
73 break;
74 default:
75 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
76 me->name, ELF32_R_TYPE(rela[i].r_info));
77 return -ENOEXEC;
78 }
79 }
80
81 return 0;
82}
83