From 19b3b6033adfe740038a5cd483f05b7c9273a148 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 18 Jul 2013 11:33:55 +0800 Subject: ARM Support Signed-off-by: Peng Fan --- libbsd/include/arch/arm/machine/elf_machdep.h | 20 +- rtl-mdreloc-arm.c | 291 ++++++++++++++++++++------ testcase/1.c | 106 ++++++++++ testcase/2.c | 14 ++ testcase/Readme | 11 + testcase/wscript | 32 +++ wscript | 8 +- 7 files changed, 408 insertions(+), 74 deletions(-) create mode 100644 testcase/1.c create mode 100644 testcase/2.c create mode 100644 testcase/Readme create mode 100644 testcase/wscript diff --git a/libbsd/include/arch/arm/machine/elf_machdep.h b/libbsd/include/arch/arm/machine/elf_machdep.h index 963ff64..78c88b5 100644 --- a/libbsd/include/arch/arm/machine/elf_machdep.h +++ b/libbsd/include/arch/arm/machine/elf_machdep.h @@ -46,7 +46,7 @@ #define R_ARM_THM_ABS5 7 #define R_ARM_ABS8 8 #define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 +#define R_ARM_THM_CALL 10 #define R_ARM_THM_PC8 11 #define R_ARM_AMP_VCALL9 12 #define R_ARM_SWI24 13 @@ -68,6 +68,10 @@ #define R_ARM_GOTPC 25 #define R_ARM_GOT32 26 #define R_ARM_PLT32 27 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_THM_JUMP24 30 +#define R_ARM_BASE_ABS 31 #define R_ARM_ALU_PCREL_7_0 32 #define R_ARM_ALU_PCREL_15_8 33 @@ -75,12 +79,22 @@ #define R_ARM_ALU_SBREL_11_0 35 #define R_ARM_ALU_SBREL_19_12 36 #define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_V4BX 40 +#define R_ARM_PREL31 41 + +#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_THM_JUMP19 51 /* 96-111 are reserved to G++. */ #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_PC11 102 -#define R_ARM_THM_PC9 103 +#define R_ARM_THM_JUMP11 102 +#define R_ARM_THM_JUMP8 103 /* More TLS relocations */ #define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic */ diff --git a/rtl-mdreloc-arm.c b/rtl-mdreloc-arm.c index e55da1f..d1bfd5a 100644 --- a/rtl-mdreloc-arm.c +++ b/rtl-mdreloc-arm.c @@ -40,6 +40,18 @@ store_ptr(void *where, Elf_Addr val) memcpy(where, &val, sizeof(val)); } +/* + * The address of Thumb function symbols is it's real address plus one. + * This is done by compiler, thus do not consider symtype here. + */ +static inline int +isThumb(Elf_Word symvalue) +{ + if ((symvalue & 0x1) == 0x1) + return true; + else return false; +} + bool rtems_rtl_elf_rel_resolve_sym (Elf_Word type) { @@ -67,7 +79,10 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, const Elf_Word symvalue) { Elf_Addr *where; - Elf_Addr tmp; + Elf_Addr tmp; + Elf_Word insn, addend; + Elf_Word sign, i1, i2; + uint16_t lower_insn, upper_insn; where = (Elf_Addr *)(sect->base + rel->r_offset); @@ -75,81 +90,221 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, case R_TYPE(NONE): break; -#if 1 /* XXX should not occur */ - case R_TYPE(PC24): { /* word32 S - P + A */ - Elf32_Sword addend; - - /* - * Extract addend and sign-extend if needed. - */ - addend = *where; - if (addend & 0x00800000) - addend |= 0xff000000; - - tmp = (Elf_Addr)sect->base + symvalue - - (Elf_Addr)where + (addend << 2); - - if ((tmp & 0xfe000000) != 0xfe000000 && - (tmp & 0xfe000000) != 0) { - rtems_rtl_set_error (EINVAL, - "R_ARM_PC24 in %s relocation @ %p failed " \ - "(displacement %ld (%#lx) out of range)", - rtems_rtl_obj_oname (obj), where, (long) tmp, (long) tmp); - return false; - } - - tmp >>= 2; - *where = (*where & 0xff000000) | (tmp & 0x00ffffff); + case R_TYPE(CALL): /* BL/BLX */ + case R_TYPE(JUMP24): /* B/BL */ + insn = *where; + + if (insn & 0x00800000) + addend = insn | 0xff000000; + else addend = insn & 0x00ffffff; + + if (isThumb(symvalue)) { + if ((insn & 0xfe000000) == 0xfa000000); /* Already blx */ + else { + if ((insn & 0xff000000) == 0xeb000000) { /* BL