diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-09-07 08:19:51 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-09-07 08:19:51 +0200 |
| commit | a1922ed661ab2c1637d0b10cde933bd9cd33d965 (patch) | |
| tree | 0f1777542b385ebefd30b3586d830fd8ed6fda5b /arch/mn10300/kernel/module.c | |
| parent | 75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (diff) | |
| parent | d28daf923ac5e4a0d7cecebae56f3e339189366b (diff) | |
Merge branch 'tracing/core' into tracing/hw-breakpoints
Conflicts:
arch/Kconfig
kernel/trace/trace.h
Merge reason: resolve the conflicts, plus adopt to the new
ring-buffer APIs.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/mn10300/kernel/module.c')
| -rw-r--r-- | arch/mn10300/kernel/module.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c index 4fa0e3648d8e..6aea7fd76993 100644 --- a/arch/mn10300/kernel/module.c +++ b/arch/mn10300/kernel/module.c @@ -1,6 +1,6 @@ /* MN10300 Kernel module helper routines * - * Copyright (C) 2007, 2008 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All Rights Reserved. * Written by Mark Salter (msalter@redhat.com) * - Derived from arch/i386/kernel/module.c * @@ -103,10 +103,10 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, unsigned int relsec, struct module *me) { - unsigned int i; + unsigned int i, sym_diff_seen = 0; Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; - Elf32_Addr relocation; + Elf32_Addr relocation, sym_diff_val = 0; uint8_t *location; uint32_t value; @@ -126,6 +126,22 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, /* this is the adjustment to be made */ relocation = sym->st_value + rel[i].r_addend; + if (sym_diff_seen) { + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_MN10300_32: + case R_MN10300_24: + case R_MN10300_16: + case R_MN10300_8: + relocation -= sym_diff_val; + sym_diff_seen = 0; + break; + default: + printk(KERN_ERR "module %s: Unexpected SYM_DIFF relocation: %u\n", + me->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } + } + switch (ELF32_R_TYPE(rel[i].r_info)) { /* for the first four relocation types, we simply * store the adjustment at the location given */ @@ -157,12 +173,29 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, *location = relocation - (uint32_t) location; break; + case R_MN10300_SYM_DIFF: + /* This is used to adjust the next reloc as required + * by relaxation. */ + sym_diff_seen = 1; + sym_diff_val = sym->st_value; + break; + + case R_MN10300_ALIGN: + /* Just ignore the ALIGN relocs. + * Only interesting if kernel performed relaxation. */ + continue; + default: printk(KERN_ERR "module %s: Unknown relocation: %u\n", me->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } } + if (sym_diff_seen) { + printk(KERN_ERR "module %s: Nothing follows SYM_DIFF relocation: %u\n", + me->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } return 0; } |
