diff options
author | Bernd Schmidt <bernds_cb1@t-online.de> | 2009-01-07 10:14:39 -0500 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2009-01-07 10:14:39 -0500 |
commit | d1a853057a13e63c40c9b8715e585af15f1b141a (patch) | |
tree | cefd27448fa56585ad000417308b508a81c1f005 /arch/blackfin/kernel/module.c | |
parent | 2eddbadaebdf77a52d5cccc7cdd116656f1cf1f9 (diff) |
Blackfin arch: Remove all traces of the relocation stack
Remove all traces of the relocation stack. It's been removed from
binutils for years now.
Add a sanity overflow check to pcrel24 relocations to catch modules that
were built without -mlong-calls.
Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel/module.c')
-rw-r--r-- | arch/blackfin/kernel/module.c | 139 |
1 files changed, 7 insertions, 132 deletions
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 2e14cadd4302..1bd7f2d018a8 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c | |||
@@ -37,111 +37,6 @@ | |||
37 | #include <asm/dma.h> | 37 | #include <asm/dma.h> |
38 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
39 | 39 | ||
40 | /* | ||
41 | * handle arithmetic relocations. | ||
42 | * See binutils/bfd/elf32-bfin.c for more details | ||
43 | */ | ||
44 | #define RELOC_STACK_SIZE 100 | ||
45 | static uint32_t reloc_stack[RELOC_STACK_SIZE]; | ||
46 | static unsigned int reloc_stack_tos; | ||
47 | |||
48 | #define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1) | ||
49 | |||
50 | static void reloc_stack_push(uint32_t value) | ||
51 | { | ||
52 | reloc_stack[reloc_stack_tos++] = value; | ||
53 | } | ||
54 | |||
55 | static uint32_t reloc_stack_pop(void) | ||
56 | { | ||
57 | return reloc_stack[--reloc_stack_tos]; | ||
58 | } | ||
59 | |||
60 | static uint32_t reloc_stack_operate(unsigned int oper, struct module *mod) | ||
61 | { | ||
62 | uint32_t value; | ||
63 | |||
64 | switch (oper) { | ||
65 | case R_add: | ||
66 | value = reloc_stack[reloc_stack_tos - 2] + | ||
67 | reloc_stack[reloc_stack_tos - 1]; | ||
68 | reloc_stack_tos -= 2; | ||
69 | break; | ||
70 | case R_sub: | ||
71 | value = reloc_stack[reloc_stack_tos - 2] - | ||
72 | reloc_stack[reloc_stack_tos - 1]; | ||
73 | reloc_stack_tos -= 2; | ||
74 | break; | ||
75 | case R_mult: | ||
76 | value = reloc_stack[reloc_stack_tos - 2] * | ||
77 | reloc_stack[reloc_stack_tos - 1]; | ||
78 | reloc_stack_tos -= 2; | ||
79 | break; | ||
80 | case R_div: | ||
81 | value = reloc_stack[reloc_stack_tos - 2] / | ||
82 | reloc_stack[reloc_stack_tos - 1]; | ||
83 | reloc_stack_tos -= 2; | ||
84 | break; | ||
85 | case R_mod: | ||
86 | value = reloc_stack[reloc_stack_tos - 2] % | ||
87 | reloc_stack[reloc_stack_tos - 1]; | ||
88 | reloc_stack_tos -= 2; | ||
89 | break; | ||
90 | case R_lshift: | ||
91 | value = reloc_stack[reloc_stack_tos - 2] << | ||
92 | reloc_stack[reloc_stack_tos - 1]; | ||
93 | reloc_stack_tos -= 2; | ||
94 | break; | ||
95 | case R_rshift: | ||
96 | value = reloc_stack[reloc_stack_tos - 2] >> | ||
97 | reloc_stack[reloc_stack_tos - 1]; | ||
98 | reloc_stack_tos -= 2; | ||
99 | break; | ||
100 | case R_and: | ||
101 | value = reloc_stack[reloc_stack_tos - 2] & | ||
102 | reloc_stack[reloc_stack_tos - 1]; | ||
103 | reloc_stack_tos -= 2; | ||
104 | break; | ||
105 | case R_or: | ||
106 | value = reloc_stack[reloc_stack_tos - 2] | | ||
107 | reloc_stack[reloc_stack_tos - 1]; | ||
108 | reloc_stack_tos -= 2; | ||
109 | break; | ||
110 | case R_xor: | ||
111 | value = reloc_stack[reloc_stack_tos - 2] ^ | ||
112 | reloc_stack[reloc_stack_tos - 1]; | ||
113 | reloc_stack_tos -= 2; | ||
114 | break; | ||
115 | case R_land: | ||
116 | value = reloc_stack[reloc_stack_tos - 2] && | ||
117 | reloc_stack[reloc_stack_tos - 1]; | ||
118 | reloc_stack_tos -= 2; | ||
119 | break; | ||
120 | case R_lor: | ||
121 | value = reloc_stack[reloc_stack_tos - 2] || | ||
122 | reloc_stack[reloc_stack_tos - 1]; | ||
123 | reloc_stack_tos -= 2; | ||
124 | break; | ||
125 | case R_neg: | ||
126 | value = -reloc_stack[reloc_stack_tos - 1]; | ||
127 | reloc_stack_tos--; | ||
128 | break; | ||
129 | case R_comp: | ||
130 | value = ~reloc_stack[reloc_stack_tos - 1]; | ||
131 | reloc_stack_tos -= 1; | ||
132 | break; | ||
133 | default: | ||
134 | printk(KERN_WARNING "module %s: unhandled reloction\n", | ||
135 | mod->name); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | /* now push the new value back on stack */ | ||
140 | reloc_stack_push(value); | ||
141 | |||
142 | return value; | ||
143 | } | ||
144 | |||
145 | void *module_alloc(unsigned long size) | 40 | void *module_alloc(unsigned long size) |
146 | { | 41 | { |
147 | if (size == 0) | 42 | if (size == 0) |
@@ -334,11 +229,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
334 | undefined symbols have been resolved. */ | 229 | undefined symbols have been resolved. */ |
335 | sym = (Elf32_Sym *) sechdrs[symindex].sh_addr | 230 | sym = (Elf32_Sym *) sechdrs[symindex].sh_addr |
336 | + ELF32_R_SYM(rel[i].r_info); | 231 | + ELF32_R_SYM(rel[i].r_info); |
337 | if (is_reloc_stack_empty()) { | 232 | value = sym->st_value; |
338 | value = sym->st_value; | ||
339 | } else { | ||
340 | value = reloc_stack_pop(); | ||
341 | } | ||
342 | value += rel[i].r_addend; | 233 | value += rel[i].r_addend; |
343 | pr_debug("location is %x, value is %x type is %d \n", | 234 | pr_debug("location is %x, value is %x type is %d \n", |
344 | (unsigned int) location32, value, | 235 | (unsigned int) location32, value, |
@@ -361,6 +252,12 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
361 | location32 = (uint32_t *) location16; | 252 | location32 = (uint32_t *) location16; |
362 | value -= (uint32_t) location32; | 253 | value -= (uint32_t) location32; |
363 | value >>= 1; | 254 | value >>= 1; |
255 | if ((value & 0xFF000000) != 0 && | ||
256 | (value & 0xFF000000) != 0xFF000000) { | ||
257 | printk(KERN_ERR "module %s: relocation overflow\n", | ||
258 | mod->name); | ||
259 | return -ENOEXEC; | ||
260 | } | ||
364 | pr_debug("value is %x, before %x-%x after %x-%x\n", value, | 261 | pr_debug("value is %x, before %x-%x after %x-%x\n", value, |
365 | *location16, *(location16 + 1), | 262 | *location16, *(location16 + 1), |
366 | (*location16 & 0xff00) | (value >> 16 & 0x00ff), | 263 | (*location16 & 0xff00) | (value >> 16 & 0x00ff), |
@@ -405,28 +302,6 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
405 | pr_debug("before %x after %x\n", *location32, value); | 302 | pr_debug("before %x after %x\n", *location32, value); |
406 | *location32 = value; | 303 | *location32 = value; |
407 | break; | 304 | break; |
408 | case R_push: | ||
409 | reloc_stack_push(value); | ||
410 | break; | ||
411 | case R_const: | ||
412 | reloc_stack_push(rel[i].r_addend); | ||
413 | break; | ||
414 | case R_add: | ||
415 | case R_sub: | ||
416 | case R_mult: | ||
417 | case R_div: | ||
418 | case R_mod: | ||
419 | case R_lshift: | ||
420 | case R_rshift: | ||
421 | case R_and: | ||
422 | case R_or: | ||
423 | case R_xor: | ||
424 | case R_land: | ||
425 | case R_lor: | ||
426 | case R_neg: | ||
427 | case R_comp: | ||
428 | reloc_stack_operate(ELF32_R_TYPE(rel[i].r_info), mod); | ||
429 | break; | ||
430 | default: | 305 | default: |
431 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", | 306 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", |
432 | mod->name, ELF32_R_TYPE(rel[i].r_info)); | 307 | mod->name, ELF32_R_TYPE(rel[i].r_info)); |