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