aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/module.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2012-08-14 11:13:45 -0400
committerRusty Russell <rusty@rustcorp.com.au>2012-09-28 01:01:02 -0400
commit6ede81239e31cfacbb1e2d260530cd80d13cf0db (patch)
treef31b3750b611b3d580864dbe9f8444cc1173d396 /arch/mips/kernel/module.c
parentc99af3752bb52ba3aece5315279a57a477edfaf1 (diff)
MIPS: Fix module.c build for 32 bit
Fixes build failure introduced by "Make most arch asm/module.h files use asm-generic/module.h" by moving all the RELA processing code to a separate file to be used only for RELA processing on 64-bit kernels. CC arch/mips/kernel/module.o arch/mips/kernel/module.c:250:14: error: 'reloc_handlers_rela' defined but not used [-Werror=unused-variable] cc1: all warnings being treated as errors make[6]: *** [arch/mips/kernel/module.o] Error 1 Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'arch/mips/kernel/module.c')
-rw-r--r--arch/mips/kernel/module.c121
1 files changed, 1 insertions, 120 deletions
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 4f8c3cba8c0c..07ff5812ffaf 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -51,7 +51,7 @@ void *module_alloc(unsigned long size)
51} 51}
52#endif 52#endif
53 53
54static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) 54int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
55{ 55{
56 return 0; 56 return 0;
57} 57}
@@ -63,13 +63,6 @@ static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v)
63 return 0; 63 return 0;
64} 64}
65 65
66static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
67{
68 *location = v;
69
70 return 0;
71}
72
73static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) 66static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
74{ 67{
75 if (v % 4) { 68 if (v % 4) {
@@ -91,26 +84,6 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
91 return 0; 84 return 0;
92} 85}
93 86
94static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
95{
96 if (v % 4) {
97 pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
98 me->name);
99 return -ENOEXEC;
100 }
101
102 if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
103 printk(KERN_ERR
104 "module %s: relocation overflow\n",
105 me->name);
106 return -ENOEXEC;
107 }
108
109 *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
110
111 return 0;
112}
113
114static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) 87static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
115{ 88{
116 struct mips_hi16 *n; 89 struct mips_hi16 *n;
@@ -132,14 +105,6 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
132 return 0; 105 return 0;
133} 106}
134 107
135static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
136{
137 *location = (*location & 0xffff0000) |
138 ((((long long) v + 0x8000LL) >> 16) & 0xffff);
139
140 return 0;
141}
142
143static void free_relocation_chain(struct mips_hi16 *l) 108static void free_relocation_chain(struct mips_hi16 *l)
144{ 109{
145 struct mips_hi16 *next; 110 struct mips_hi16 *next;
@@ -217,38 +182,6 @@ out_danger:
217 return -ENOEXEC; 182 return -ENOEXEC;
218} 183}
219 184
220static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
221{
222 *location = (*location & 0xffff0000) | (v & 0xffff);
223
224 return 0;
225}
226
227static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
228{
229 *(Elf_Addr *)location = v;
230
231 return 0;
232}
233
234static int apply_r_mips_higher_rela(struct module *me, u32 *location,
235 Elf_Addr v)
236{
237 *location = (*location & 0xffff0000) |
238 ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
239
240 return 0;
241}
242
243static int apply_r_mips_highest_rela(struct module *me, u32 *location,
244 Elf_Addr v)
245{
246 *location = (*location & 0xffff0000) |
247 ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
248
249 return 0;
250}
251
252static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, 185static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
253 Elf_Addr v) = { 186 Elf_Addr v) = {
254 [R_MIPS_NONE] = apply_r_mips_none, 187 [R_MIPS_NONE] = apply_r_mips_none,
@@ -258,18 +191,6 @@ static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
258 [R_MIPS_LO16] = apply_r_mips_lo16_rel 191 [R_MIPS_LO16] = apply_r_mips_lo16_rel
259}; 192};
260 193
261static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
262 Elf_Addr v) = {
263 [R_MIPS_NONE] = apply_r_mips_none,
264 [R_MIPS_32] = apply_r_mips_32_rela,
265 [R_MIPS_26] = apply_r_mips_26_rela,
266 [R_MIPS_HI16] = apply_r_mips_hi16_rela,
267 [R_MIPS_LO16] = apply_r_mips_lo16_rela,
268 [R_MIPS_64] = apply_r_mips_64_rela,
269 [R_MIPS_HIGHER] = apply_r_mips_higher_rela,
270 [R_MIPS_HIGHEST] = apply_r_mips_highest_rela
271};
272
273int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, 194int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
274 unsigned int symindex, unsigned int relsec, 195 unsigned int symindex, unsigned int relsec,
275 struct module *me) 196 struct module *me)
@@ -324,46 +245,6 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
324 return 0; 245 return 0;
325} 246}
326 247
327int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
328 unsigned int symindex, unsigned int relsec,
329 struct module *me)
330{
331 Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
332 Elf_Sym *sym;
333 u32 *location;
334 unsigned int i;
335 Elf_Addr v;
336 int res;
337
338 pr_debug("Applying relocate section %u to %u\n", relsec,
339 sechdrs[relsec].sh_info);
340
341 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
342 /* This is where to make the change */
343 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
344 + rel[i].r_offset;
345 /* This is the symbol it is referring to */
346 sym = (Elf_Sym *)sechdrs[symindex].sh_addr
347 + ELF_MIPS_R_SYM(rel[i]);
348 if (IS_ERR_VALUE(sym->st_value)) {
349 /* Ignore unresolved weak symbol */
350 if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
351 continue;
352 printk(KERN_WARNING "%s: Unknown symbol %s\n",
353 me->name, strtab + sym->st_name);
354 return -ENOENT;
355 }
356
357 v = sym->st_value + rel[i].r_addend;
358
359 res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
360 if (res)
361 return res;
362 }
363
364 return 0;
365}
366
367/* Given an address, look for it in the module exception tables. */ 248/* Given an address, look for it in the module exception tables. */
368const struct exception_table_entry *search_module_dbetables(unsigned long addr) 249const struct exception_table_entry *search_module_dbetables(unsigned long addr)
369{ 250{