diff options
Diffstat (limited to 'arch/mips/kernel/module.c')
-rw-r--r-- | arch/mips/kernel/module.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 1833f5171ccd..f9b2936d598d 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c | |||
@@ -197,9 +197,10 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | |||
197 | struct module *me) | 197 | struct module *me) |
198 | { | 198 | { |
199 | Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr; | 199 | Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr; |
200 | int (*handler)(struct module *me, u32 *location, Elf_Addr v); | ||
200 | Elf_Sym *sym; | 201 | Elf_Sym *sym; |
201 | u32 *location; | 202 | u32 *location; |
202 | unsigned int i; | 203 | unsigned int i, type; |
203 | Elf_Addr v; | 204 | Elf_Addr v; |
204 | int res; | 205 | int res; |
205 | 206 | ||
@@ -223,9 +224,21 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | |||
223 | return -ENOENT; | 224 | return -ENOENT; |
224 | } | 225 | } |
225 | 226 | ||
226 | v = sym->st_value; | 227 | type = ELF_MIPS_R_TYPE(rel[i]); |
228 | |||
229 | if (type < ARRAY_SIZE(reloc_handlers_rel)) | ||
230 | handler = reloc_handlers_rel[type]; | ||
231 | else | ||
232 | handler = NULL; | ||
227 | 233 | ||
228 | res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v); | 234 | if (!handler) { |
235 | pr_err("%s: Unknown relocation type %u\n", | ||
236 | me->name, type); | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | |||
240 | v = sym->st_value; | ||
241 | res = handler(me, location, v); | ||
229 | if (res) | 242 | if (res) |
230 | return res; | 243 | return res; |
231 | } | 244 | } |