diff options
| author | Chris Metcalf <cmetcalf@tilera.com> | 2010-08-13 19:59:15 -0400 |
|---|---|---|
| committer | Chris Metcalf <cmetcalf@tilera.com> | 2010-08-13 19:59:15 -0400 |
| commit | 7d72e6fa56c4100b9669efe0044f77ed9eb785a1 (patch) | |
| tree | 5e90bf4969809a1ab20b97432b85be20ccfaa1f4 /arch/arm/kernel/module.c | |
| parent | ba00376b0b13f234d839541a7b36a5bf5c2a4036 (diff) | |
| parent | 2be1f3a73dd02e38e181cf5abacb3d45a6a2d6b8 (diff) | |
Merge branch 'master' into for-linus
Diffstat (limited to 'arch/arm/kernel/module.c')
| -rw-r--r-- | arch/arm/kernel/module.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index c628bdf6c430..6b4605893f1e 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
| @@ -102,7 +102,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
| 102 | unsigned long loc; | 102 | unsigned long loc; |
| 103 | Elf32_Sym *sym; | 103 | Elf32_Sym *sym; |
| 104 | s32 offset; | 104 | s32 offset; |
| 105 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 105 | u32 upper, lower, sign, j1, j2; | 106 | u32 upper, lower, sign, j1, j2; |
| 107 | #endif | ||
| 106 | 108 | ||
| 107 | offset = ELF32_R_SYM(rel->r_info); | 109 | offset = ELF32_R_SYM(rel->r_info); |
| 108 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { | 110 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { |
| @@ -185,6 +187,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
| 185 | (offset & 0x0fff); | 187 | (offset & 0x0fff); |
| 186 | break; | 188 | break; |
| 187 | 189 | ||
| 190 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 188 | case R_ARM_THM_CALL: | 191 | case R_ARM_THM_CALL: |
| 189 | case R_ARM_THM_JUMP24: | 192 | case R_ARM_THM_JUMP24: |
| 190 | upper = *(u16 *)loc; | 193 | upper = *(u16 *)loc; |
| @@ -233,9 +236,40 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
| 233 | *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | | 236 | *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | |
| 234 | (j1 << 13) | (j2 << 11) | | 237 | (j1 << 13) | (j2 << 11) | |
| 235 | ((offset >> 1) & 0x07ff)); | 238 | ((offset >> 1) & 0x07ff)); |
| 239 | break; | ||
| 240 | |||
| 241 | case R_ARM_THM_MOVW_ABS_NC: | ||
| 242 | case R_ARM_THM_MOVT_ABS: | ||
| 236 | upper = *(u16 *)loc; | 243 | upper = *(u16 *)loc; |
| 237 | lower = *(u16 *)(loc + 2); | 244 | lower = *(u16 *)(loc + 2); |
| 245 | |||
| 246 | /* | ||
| 247 | * MOVT/MOVW instructions encoding in Thumb-2: | ||
| 248 | * | ||
| 249 | * i = upper[10] | ||
| 250 | * imm4 = upper[3:0] | ||
| 251 | * imm3 = lower[14:12] | ||
| 252 | * imm8 = lower[7:0] | ||
| 253 | * | ||
| 254 | * imm16 = imm4:i:imm3:imm8 | ||
| 255 | */ | ||
| 256 | offset = ((upper & 0x000f) << 12) | | ||
| 257 | ((upper & 0x0400) << 1) | | ||
| 258 | ((lower & 0x7000) >> 4) | (lower & 0x00ff); | ||
| 259 | offset = (offset ^ 0x8000) - 0x8000; | ||
| 260 | offset += sym->st_value; | ||
| 261 | |||
| 262 | if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) | ||
| 263 | offset >>= 16; | ||
| 264 | |||
| 265 | *(u16 *)loc = (u16)((upper & 0xfbf0) | | ||
| 266 | ((offset & 0xf000) >> 12) | | ||
| 267 | ((offset & 0x0800) >> 1)); | ||
| 268 | *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | | ||
| 269 | ((offset & 0x0700) << 4) | | ||
| 270 | (offset & 0x00ff)); | ||
| 238 | break; | 271 | break; |
| 272 | #endif | ||
| 239 | 273 | ||
| 240 | default: | 274 | default: |
| 241 | printk(KERN_ERR "%s: unknown relocation: %u\n", | 275 | printk(KERN_ERR "%s: unknown relocation: %u\n", |
