aboutsummaryrefslogtreecommitdiffstats
path: root/arch/v850/kernel/module.c
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@kernel.org>2008-07-24 00:28:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:24 -0400
commitf606ddf42fd4edc558eeb48bfee66d2c591571d2 (patch)
tree193f00db121201255b2629fce43b99a53c4ec735 /arch/v850/kernel/module.c
parent99764fa4ceeecba8b9e0a8a5565b418a2e94f83b (diff)
remove the v850 port
Trying to compile the v850 port brings many compile errors, one of them exists since at least kernel 2.6.19. There also seems to be noone willing to bring this port back into a usable state. This patch therefore removes the v850 port. If anyone ever decides to revive the v850 port the code will still be available from older kernels, and it wouldn't be impossible for the port to reenter the kernel if it would become actively maintained again. Signed-off-by: Adrian Bunk <bunk@kernel.org> Acked-by: Greg Ungerer <gerg@uclinux.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/v850/kernel/module.c')
-rw-r--r--arch/v850/kernel/module.c237
1 files changed, 0 insertions, 237 deletions
diff --git a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c
deleted file mode 100644
index 64aeb3e37c52..000000000000
--- a/arch/v850/kernel/module.c
+++ /dev/null
@@ -1,237 +0,0 @@
1/*
2 * arch/v850/kernel/module.c -- Architecture-specific module functions
3 *
4 * Copyright (C) 2002,03 NEC Electronics Corporation
5 * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
6 * Copyright (C) 2001,03 Rusty Russell
7 *
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file COPYING in the main directory of this
10 * archive for more details.
11 *
12 * Written by Miles Bader <miles@gnu.org>
13 *
14 * Derived in part from arch/ppc/kernel/module.c
15 */
16
17#include <linux/kernel.h>
18#include <linux/vmalloc.h>
19#include <linux/moduleloader.h>
20#include <linux/elf.h>
21
22#if 0
23#define DEBUGP printk
24#else
25#define DEBUGP(fmt , ...)
26#endif
27
28void *module_alloc (unsigned long size)
29{
30 return size == 0 ? 0 : vmalloc (size);
31}
32
33void module_free (struct module *mod, void *module_region)
34{
35 vfree (module_region);
36 /* FIXME: If module_region == mod->init_region, trim exception
37 table entries. */
38}
39
40int module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
41 struct module *mod)
42{
43 return 0;
44}
45
46/* Count how many different relocations (different symbol, different
47 addend) */
48static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
49{
50 unsigned int i, j, ret = 0;
51
52 /* Sure, this is order(n^2), but it's usually short, and not
53 time critical */
54 for (i = 0; i < num; i++) {
55 for (j = 0; j < i; j++) {
56 /* If this addend appeared before, it's
57 already been counted */
58 if (ELF32_R_SYM(rela[i].r_info)
59 == ELF32_R_SYM(rela[j].r_info)
60 && rela[i].r_addend == rela[j].r_addend)
61 break;
62 }
63 if (j == i) ret++;
64 }
65 return ret;
66}
67
68/* Get the potential trampolines size required of the init and
69 non-init sections */
70static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
71 const Elf32_Shdr *sechdrs,
72 const char *secstrings,
73 int is_init)
74{
75 unsigned long ret = 0;
76 unsigned i;
77
78 /* Everything marked ALLOC (this includes the exported
79 symbols) */
80 for (i = 1; i < hdr->e_shnum; i++) {
81 /* If it's called *.init*, and we're not init, we're
82 not interested */
83 if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
84 != is_init)
85 continue;
86
87 if (sechdrs[i].sh_type == SHT_RELA) {
88 DEBUGP("Found relocations in section %u\n", i);
89 DEBUGP("Ptr: %p. Number: %u\n",
90 (void *)hdr + sechdrs[i].sh_offset,
91 sechdrs[i].sh_size / sizeof(Elf32_Rela));
92 ret += count_relocs((void *)hdr
93 + sechdrs[i].sh_offset,
94 sechdrs[i].sh_size
95 / sizeof(Elf32_Rela))
96 * sizeof(struct v850_plt_entry);
97 }
98 }
99
100 return ret;
101}
102
103int module_frob_arch_sections(Elf32_Ehdr *hdr,
104 Elf32_Shdr *sechdrs,
105 char *secstrings,
106 struct module *me)
107{
108 unsigned int i;
109
110 /* Find .plt and .pltinit sections */
111 for (i = 0; i < hdr->e_shnum; i++) {
112 if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0)
113 me->arch.init_plt_section = i;
114 else if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0)
115 me->arch.core_plt_section = i;
116 }
117 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
118 printk("Module doesn't contain .plt or .plt.init sections.\n");
119 return -ENOEXEC;
120 }
121
122 /* Override their sizes */
123 sechdrs[me->arch.core_plt_section].sh_size
124 = get_plt_size(hdr, sechdrs, secstrings, 0);
125 sechdrs[me->arch.init_plt_section].sh_size
126 = get_plt_size(hdr, sechdrs, secstrings, 1);
127 return 0;
128}
129
130int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab,
131 unsigned int symindex, unsigned int relsec,
132 struct module *mod)
133{
134 printk ("Barf\n");
135 return -ENOEXEC;
136}
137
138/* Set up a trampoline in the PLT to bounce us to the distant function */
139static uint32_t do_plt_call (void *location, Elf32_Addr val,
140 Elf32_Shdr *sechdrs, struct module *mod)
141{
142 struct v850_plt_entry *entry;
143 /* Instructions used to do the indirect jump. */
144 uint32_t tramp[2];
145
146 /* We have to trash a register, so we assume that any control
147 transfer more than 21-bits away must be a function call
148 (so we can use a call-clobbered register). */
149 tramp[0] = 0x0621 + ((val & 0xffff) << 16); /* mov sym, r1 ... */
150 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
151
152 /* Init, or core PLT? */
153 if (location >= mod->module_core
154 && location < mod->module_core + mod->core_size)
155 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
156 else
157 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
158
159 /* Find this entry, or if that fails, the next avail. entry */
160 while (entry->tramp[0])
161 if (entry->tramp[0] == tramp[0] && entry->tramp[1] == tramp[1])
162 return (uint32_t)entry;
163 else
164 entry++;
165
166 entry->tramp[0] = tramp[0];
167 entry->tramp[1] = tramp[1];
168
169 return (uint32_t)entry;
170}
171
172int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab,
173 unsigned int symindex, unsigned int relsec,
174 struct module *mod)
175{
176 unsigned int i;
177 Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
178
179 DEBUGP ("Applying relocate section %u to %u\n", relsec,
180 sechdrs[relsec].sh_info);
181
182 for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
183 /* This is where to make the change */
184 uint32_t *loc
185 = ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
186 + rela[i].r_offset);
187 /* This is the symbol it is referring to. Note that all
188 undefined symbols have been resolved. */
189 Elf32_Sym *sym
190 = ((Elf32_Sym *)sechdrs[symindex].sh_addr
191 + ELF32_R_SYM (rela[i].r_info));
192 uint32_t val = sym->st_value + rela[i].r_addend;
193
194 switch (ELF32_R_TYPE (rela[i].r_info)) {
195 case R_V850_32:
196 /* We write two shorts instead of a long because even
197 32-bit insns only need half-word alignment, but
198 32-bit data writes need to be long-word aligned. */
199 val += ((uint16_t *)loc)[0];
200 val += ((uint16_t *)loc)[1] << 16;
201 ((uint16_t *)loc)[0] = val & 0xffff;
202 ((uint16_t *)loc)[1] = (val >> 16) & 0xffff;
203 break;
204
205 case R_V850_22_PCREL:
206 /* Maybe jump indirectly via a PLT table entry. */
207 if ((int32_t)(val - (uint32_t)loc) > 0x1fffff
208 || (int32_t)(val - (uint32_t)loc) < -0x200000)
209 val = do_plt_call (loc, val, sechdrs, mod);
210
211 val -= (uint32_t)loc;
212
213 /* We write two shorts instead of a long because
214 even 32-bit insns only need half-word alignment,
215 but 32-bit data writes need to be long-word
216 aligned. */
217 ((uint16_t *)loc)[0] =
218 (*(uint16_t *)loc & 0xffc0) /* opcode + reg */
219 | ((val >> 16) & 0xffc03f); /* offs high */
220 ((uint16_t *)loc)[1] =
221 (val & 0xffff); /* offs low */
222 break;
223
224 default:
225 printk (KERN_ERR "module %s: Unknown reloc: %u\n",
226 mod->name, ELF32_R_TYPE (rela[i].r_info));
227 return -ENOEXEC;
228 }
229 }
230
231 return 0;
232}
233
234void
235module_arch_cleanup(struct module *mod)
236{
237}