Commit ae51e609 authored by Paul Gortmaker's avatar Paul Gortmaker Committed by Russell King

[ARM] 5507/1: support R_ARM_MOVW_ABS_NC and MOVT_ABS relocation types

From: Bruce Ashfield <bruce.ashfield@windriver.com>

To fully support the armv7-a instruction set/optimizations, support
for the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocation types is
required.

The MOVW and MOVT are both load-immediate instructions, MOVW loads 16
bits into the bottom half of a register, and MOVT loads 16 bits into the
top half of a register.

The relocation information for these instructions has a full 32 bit
value, plus an addend which is stored in the 16 immediate bits in the
instruction itself.  The immediate bits in the instruction are not
contiguous (the register # splits it into a 4 bit and 12 bit value),
so the addend has to be extracted accordingly and added to the value.
The value is then split and put into the instruction; a MOVW uses the
bottom 16 bits of the value, and a MOVT uses the top 16 bits.
Signed-off-by: default avatarDavid Borman <david.borman@windriver.com>
Signed-off-by: default avatarBruce Ashfield <bruce.ashfield@windriver.com>
Signed-off-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent a029b706
...@@ -52,6 +52,8 @@ typedef struct user_fp elf_fpregset_t; ...@@ -52,6 +52,8 @@ typedef struct user_fp elf_fpregset_t;
#define R_ARM_JUMP24 29 #define R_ARM_JUMP24 29
#define R_ARM_V4BX 40 #define R_ARM_V4BX 40
#define R_ARM_PREL31 42 #define R_ARM_PREL31 42
#define R_ARM_MOVW_ABS_NC 43
#define R_ARM_MOVT_ABS 44
/* /*
* These are used to set parameters in the core dumps. * These are used to set parameters in the core dumps.
......
...@@ -169,6 +169,21 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, ...@@ -169,6 +169,21 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
*(u32 *)loc = offset & 0x7fffffff; *(u32 *)loc = offset & 0x7fffffff;
break; break;
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
offset = *(u32 *)loc;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
offset = (offset ^ 0x8000) - 0x8000;
offset += sym->st_value;
if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
offset >>= 16;
*(u32 *)loc &= 0xfff0f000;
*(u32 *)loc |= ((offset & 0xf000) << 4) |
(offset & 0x0fff);
break;
default: default:
printk(KERN_ERR "%s: unknown relocation: %u\n", printk(KERN_ERR "%s: unknown relocation: %u\n",
module->name, ELF32_R_TYPE(rel->r_info)); module->name, ELF32_R_TYPE(rel->r_info));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment