diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-06-25 06:32:01 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-06-25 06:32:01 -0400 |
| commit | da7878d75b8520c9ae00d27dfbbce546a7bfdfbb (patch) | |
| tree | 547fd497a80818a60ac36831377d5df97868173c /arch/sh/kernel/module.c | |
| parent | 0e50a4c6ab94ffe7e5515b86b5df9e5abc8c6b13 (diff) | |
| parent | 543cf4cb3fe6f6cae3651ba918b9c56200b257d0 (diff) | |
Merge branch 'linus' into x86/pebs
Diffstat (limited to 'arch/sh/kernel/module.c')
| -rw-r--r-- | arch/sh/kernel/module.c | 39 |
1 files changed, 5 insertions, 34 deletions
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index b3d0a03b4c76..5482e65375a9 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
| 31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
| 32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
| 33 | #include <asm/unaligned.h> | ||
| 33 | 34 | ||
| 34 | void *module_alloc(unsigned long size) | 35 | void *module_alloc(unsigned long size) |
| 35 | { | 36 | { |
| @@ -56,34 +57,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, | |||
| 56 | return 0; | 57 | return 0; |
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | #ifdef CONFIG_SUPERH32 | ||
| 60 | #define COPY_UNALIGNED_WORD(sw, tw, align) \ | ||
| 61 | { \ | ||
| 62 | void *__s = &(sw), *__t = &(tw); \ | ||
| 63 | unsigned short *__s2 = __s, *__t2 = __t; \ | ||
| 64 | unsigned char *__s1 = __s, *__t1 = __t; \ | ||
| 65 | switch ((align)) \ | ||
| 66 | { \ | ||
| 67 | case 0: \ | ||
| 68 | *(unsigned long *) __t = *(unsigned long *) __s; \ | ||
| 69 | break; \ | ||
| 70 | case 2: \ | ||
| 71 | *__t2++ = *__s2++; \ | ||
| 72 | *__t2 = *__s2; \ | ||
| 73 | break; \ | ||
| 74 | default: \ | ||
| 75 | *__t1++ = *__s1++; \ | ||
| 76 | *__t1++ = *__s1++; \ | ||
| 77 | *__t1++ = *__s1++; \ | ||
| 78 | *__t1 = *__s1; \ | ||
| 79 | break; \ | ||
| 80 | } \ | ||
| 81 | } | ||
| 82 | #else | ||
| 83 | /* One thing SHmedia doesn't screw up! */ | ||
| 84 | #define COPY_UNALIGNED_WORD(sw, tw, align) { (tw) = (sw); } | ||
| 85 | #endif | ||
| 86 | |||
| 87 | int apply_relocate_add(Elf32_Shdr *sechdrs, | 60 | int apply_relocate_add(Elf32_Shdr *sechdrs, |
| 88 | const char *strtab, | 61 | const char *strtab, |
| 89 | unsigned int symindex, | 62 | unsigned int symindex, |
| @@ -96,7 +69,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
| 96 | Elf32_Addr relocation; | 69 | Elf32_Addr relocation; |
| 97 | uint32_t *location; | 70 | uint32_t *location; |
| 98 | uint32_t value; | 71 | uint32_t value; |
| 99 | int align; | ||
| 100 | 72 | ||
| 101 | pr_debug("Applying relocate section %u to %u\n", relsec, | 73 | pr_debug("Applying relocate section %u to %u\n", relsec, |
| 102 | sechdrs[relsec].sh_info); | 74 | sechdrs[relsec].sh_info); |
| @@ -109,7 +81,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
| 109 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr | 81 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr |
| 110 | + ELF32_R_SYM(rel[i].r_info); | 82 | + ELF32_R_SYM(rel[i].r_info); |
| 111 | relocation = sym->st_value + rel[i].r_addend; | 83 | relocation = sym->st_value + rel[i].r_addend; |
| 112 | align = (int)location & 3; | ||
| 113 | 84 | ||
| 114 | #ifdef CONFIG_SUPERH64 | 85 | #ifdef CONFIG_SUPERH64 |
| 115 | /* For text addresses, bit2 of the st_other field indicates | 86 | /* For text addresses, bit2 of the st_other field indicates |
| @@ -122,15 +93,15 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
| 122 | 93 | ||
| 123 | switch (ELF32_R_TYPE(rel[i].r_info)) { | 94 | switch (ELF32_R_TYPE(rel[i].r_info)) { |
| 124 | case R_SH_DIR32: | 95 | case R_SH_DIR32: |
| 125 | COPY_UNALIGNED_WORD (*location, value, align); | 96 | value = get_unaligned(location); |
| 126 | value += relocation; | 97 | value += relocation; |
| 127 | COPY_UNALIGNED_WORD (value, *location, align); | 98 | put_unaligned(value, location); |
| 128 | break; | 99 | break; |
| 129 | case R_SH_REL32: | 100 | case R_SH_REL32: |
| 130 | relocation = (relocation - (Elf32_Addr) location); | 101 | relocation = (relocation - (Elf32_Addr) location); |
| 131 | COPY_UNALIGNED_WORD (*location, value, align); | 102 | value = get_unaligned(location); |
| 132 | value += relocation; | 103 | value += relocation; |
| 133 | COPY_UNALIGNED_WORD (value, *location, align); | 104 | put_unaligned(value, location); |
| 134 | break; | 105 | break; |
| 135 | case R_SH_IMM_LOW16: | 106 | case R_SH_IMM_LOW16: |
| 136 | *location = (*location & ~0x3fffc00) | | 107 | *location = (*location & ~0x3fffc00) | |
