From 2fe7fd9e875979d0947c17609b64799219485d2d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sun, 7 Oct 2012 17:48:46 +0200 Subject: 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. --- tccelf.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'tccelf.c') diff --git a/tccelf.c b/tccelf.c index a16499b..5e1a64e 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; -- cgit v1.3.1