aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Glöckner <daniel-gl@gmx.net>2010-05-15 01:23:34 +0200
committerDaniel Glöckner <daniel-gl@gmx.net>2010-05-15 01:23:34 +0200
commit128e46f91bc07a1c609726c3a79b9546572573cd (patch)
treed2a53dacc11ee74ed371d7f2c63e62658d01b67c
parent20a1cba286eb333443e55c6aba5aa73e85964455 (diff)
downloadtinycc-128e46f91bc07a1c609726c3a79b9546572573cd.tar.gz
tinycc-128e46f91bc07a1c609726c3a79b9546572573cd.tar.bz2
ARM: add support for R_ARM_V4BX
-rw-r--r--elf.h1
-rw-r--r--tccelf.c11
2 files changed, 11 insertions, 1 deletions
diff --git a/elf.h b/elf.h
index 8ecadd1..d6b1c6a 100644
--- a/elf.h
+++ b/elf.h
@@ -1673,6 +1673,7 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_ARM_PLT32 27 /* 32 bit PLT address */
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
+#define R_ARM_V4BX 40
#define R_ARM_PREL31 42
#define R_ARM_GNU_VTENTRY 100
#define R_ARM_GNU_VTINHERIT 101
diff --git a/tccelf.c b/tccelf.c
index 037615a..526c513 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -660,6 +660,11 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
break;
case R_ARM_COPY:
break;
+ case R_ARM_V4BX:
+ /* trade Thumb support for ARMv4 support */
+ if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
+ *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
+ break;
default:
fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
type,addr,(unsigned int)(long)ptr,val);
@@ -2474,7 +2479,11 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
goto invalid_reloc;
sym_index = old_to_new_syms[sym_index];
/* ignore link_once in rel section. */
- if (!sym_index && !sm->link_once) {
+ if (!sym_index && !sm->link_once
+#ifdef TCC_TARGET_ARM
+ && type != R_ARM_V4BX
+#endif
+ ) {
invalid_reloc:
error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
i, strsec + sh->sh_name, rel->r_offset);