aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elf.h4
-rw-r--r--tccelf.c32
2 files changed, 36 insertions, 0 deletions
diff --git a/elf.h b/elf.h
index 7b6d863..2d15d31 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 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;