1/*  Kernel module help for i386.
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/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
25#define DEBUGP(fmt , ...)
26
27void *module_alloc(unsigned long size)
28{
29	if (size == 0)
30		return NULL;
31	return vmalloc_exec(size);
32}
33
34
35/* Free memory returned from module_alloc */
36void module_free(struct module *mod, void *module_region)
37{
38	vfree(module_region);
39}
40
41/* We don't need anything special. */
42int module_frob_arch_sections(Elf_Ehdr *hdr,
43			      Elf_Shdr *sechdrs,
44			      char *secstrings,
45			      struct module *mod)
46{
47	return 0;
48}
49
50int apply_relocate(Elf32_Shdr *sechdrs,
51		   const char *strtab,
52		   unsigned int symindex,
53		   unsigned int relsec,
54		   struct module *me)
55{
56	printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
57	return -ENOEXEC;
58}
59
60int apply_relocate_add(Elf32_Shdr *sechdrs,
61		       const char *strtab,
62		       unsigned int symindex,
63		       unsigned int relsec,
64		       struct module *me)
65{
66  	unsigned int i;
67	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
68
69	DEBUGP ("Applying add relocate section %u to %u\n", relsec,
70		sechdrs[relsec].sh_info);
71
72	for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
73		/* This is where to make the change */
74		uint32_t *loc
75			= ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
76			   + rela[i].r_offset);
77		/* This is the symbol it is referring to.  Note that all
78		   undefined symbols have been resolved.  */
79		Elf32_Sym *sym
80			= ((Elf32_Sym *)sechdrs[symindex].sh_addr
81			   + ELF32_R_SYM (rela[i].r_info));
82		switch (ELF32_R_TYPE(rela[i].r_info)) {
83		case R_CRIS_32:
84			*loc = sym->st_value + rela[i].r_addend;
85			break;
86		case R_CRIS_32_PCREL:
87			*loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4;
88			 break;
89		default:
90			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
91			       me->name, ELF32_R_TYPE(rela[i].r_info));
92			return -ENOEXEC;
93		}
94	}
95
96	return 0;
97}
98
99int module_finalize(const Elf_Ehdr *hdr,
100		    const Elf_Shdr *sechdrs,
101		    struct module *me)
102{
103 	return 0;
104}
105
106void module_arch_cleanup(struct module *mod)
107{
108}
109