From 2fe7fd9e875979d0947c17609b64799219485d2d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sun, 7 Oct 2012 17:48:46 +0200 Subject: [PATCH] Support for R_ARM_[THM_]MOV{W,T}_ABS[_NC} relocs Add support for relocations R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS as well as their Thumb2 counterpart R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS. These are encountered with gcc when compiling for armv7-a and a data is loaded in a register, either in arm or Thumb2 mode. The first half of the data is loaded with movw ; the second half is loaded with movt. --- elf.h | 4 ++++ tccelf.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/elf.h b/elf.h index 7b6d8636..2d15d31e 100644 --- a/elf.h +++ b/elf.h @@ -1692,6 +1692,10 @@ typedef Elf32_Addr Elf32_Conflict; #define R_ARM_JUMP24 29 #define R_ARM_V4BX 40 #define R_ARM_PREL31 42 +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 #define R_ARM_THM_PC11 102 /* thumb unconditional branch */ diff --git a/tccelf.c b/tccelf.c index a16499ba..5e1a64e7 100644 --- a/tccelf.c +++ b/tccelf.c @@ -620,6 +620,38 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) (*(int *)ptr) |= x; } break; + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_ABS_NC: + { + int x, imm4, imm12; + if (type == R_ARM_MOVT_ABS) + val >>= 16; + imm12 = val & 0xfff; + imm4 = (val >> 12) & 0xf; + x = (imm4 << 16) | imm12; + if (type == R_ARM_THM_MOVT_ABS) + *(int *)ptr |= x; + else + *(int *)ptr += x; + } + break; + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_ABS_NC: + { + int x, i, imm4, imm3, imm8; + if (type == R_ARM_THM_MOVT_ABS) + val >>= 16; + imm8 = val & 0xff; + imm3 = (val >> 8) & 0x7; + i = (val >> 11) & 1; + imm4 = (val >> 12) & 0xf; + x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4; + if (type == R_ARM_THM_MOVT_ABS) + *(int *)ptr |= x; + else + *(int *)ptr += x; + } + break; case R_ARM_PREL31: { int x;