diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2009-08-03 07:26:40 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-08-03 12:52:49 -0400 |
commit | 477c4b07406357ad93d0e32788dbf3ee814eadaa (patch) | |
tree | 42164d744d8cbd1c0c56550a6b993d643f2c29e2 /arch/mips/kernel/vpe.c | |
parent | e2a9cf96a0af24f33206b4bb98cc3a12242260c1 (diff) |
MIPS: VPE: Free relocation chain on error.
This may happen if a bad sequence of relocations is being encountered.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/vpe.c')
-rw-r--r-- | arch/mips/kernel/vpe.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 3d4ef841d829..245b03e88089 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -462,16 +462,15 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
462 | { | 462 | { |
463 | unsigned long insnlo = *location; | 463 | unsigned long insnlo = *location; |
464 | Elf32_Addr val, vallo; | 464 | Elf32_Addr val, vallo; |
465 | struct mips_hi16 *l, *next; | ||
465 | 466 | ||
466 | /* Sign extend the addend we extract from the lo insn. */ | 467 | /* Sign extend the addend we extract from the lo insn. */ |
467 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; | 468 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; |
468 | 469 | ||
469 | if (mips_hi16_list != NULL) { | 470 | if (mips_hi16_list != NULL) { |
470 | struct mips_hi16 *l; | ||
471 | 471 | ||
472 | l = mips_hi16_list; | 472 | l = mips_hi16_list; |
473 | while (l != NULL) { | 473 | while (l != NULL) { |
474 | struct mips_hi16 *next; | ||
475 | unsigned long insn; | 474 | unsigned long insn; |
476 | 475 | ||
477 | /* | 476 | /* |
@@ -481,7 +480,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
481 | printk(KERN_DEBUG "VPE loader: " | 480 | printk(KERN_DEBUG "VPE loader: " |
482 | "apply_r_mips_lo16/hi16: \t" | 481 | "apply_r_mips_lo16/hi16: \t" |
483 | "inconsistent value information\n"); | 482 | "inconsistent value information\n"); |
484 | return -ENOEXEC; | 483 | goto out_free; |
485 | } | 484 | } |
486 | 485 | ||
487 | /* | 486 | /* |
@@ -519,6 +518,16 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
519 | *location = insnlo; | 518 | *location = insnlo; |
520 | 519 | ||
521 | return 0; | 520 | return 0; |
521 | |||
522 | out_free: | ||
523 | while (l != NULL) { | ||
524 | next = l->next; | ||
525 | kfree(l); | ||
526 | l = next; | ||
527 | } | ||
528 | mips_hi16_list = NULL; | ||
529 | |||
530 | return -ENOEXEC; | ||
522 | } | 531 | } |
523 | 532 | ||
524 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, | 533 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, |