From 9966fd4eaea163439a63d63d044d0657df1908ea Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 16 Oct 2012 00:31:56 +0200 Subject: [PATCH] Only use blx if available Introduce ARM version for the target architecture in order to determine if blx instruction can be used or not. Availability of blx instruction allows for more scenarii supported in R_ARM_CALL relocation. It should also be useful when introducing support for the R_ARM_THM_CALL relocation. --- tcc.h | 8 ++++++++ tccelf.c | 19 +++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/tcc.h b/tcc.h index 8bca9ae8..4e88782c 100644 --- a/tcc.h +++ b/tcc.h @@ -105,6 +105,14 @@ #define TCC_TARGET_I386 #endif +#if defined (TCC_TARGET_ARM) && !defined(TCC_ARM_VERSION) + #ifdef TCC_ARM_HARDFLOAT + #define TCC_ARM_VERSION 7 + #else + #define TCC_ARM_VERSION 4 + #endif +#endif + #if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \ !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) #define CONFIG_TCC_BCHECK /* enable bound checking code */ diff --git a/tccelf.c b/tccelf.c index 79437632..f46a7423 100644 --- a/tccelf.c +++ b/tccelf.c @@ -601,27 +601,30 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) case R_ARM_JUMP24: case R_ARM_PLT32: { - int x, is_thumb, is_call, h; + int x, is_thumb, is_call, h, blx_avail; x = (*(int *)ptr)&0xffffff; (*(int *)ptr) &= 0xff000000; if (x & 0x800000) x -= 0x1000000; x <<= 2; + blx_avail = (TCC_ARM_VERSION >= 5); is_thumb = val & 1; is_call = (type == R_ARM_CALL); - x += (val & -2) - addr; + x += val - addr; h = x & 2; #ifndef TCC_TARGET_PE - if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) - if (s1->output_type == TCC_OUTPUT_MEMORY) - x += add_jmp_table(s1, val) - val; /* add veneer */ + if ((x & 3) || x >= 0x4000000 || x < -0x4000000) + if (!(x & 3) || !blx_avail || !is_call) + if (s1->output_type == TCC_OUTPUT_MEMORY) + x += add_jmp_table(s1, val) - val; /* add veneer */ #endif - if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) - if (!(h && is_call && is_thumb)) + if ((x & 3) || x >= 0x4000000 || x < -0x4000000) + if (!(x & 3) || !blx_avail || !is_call) tcc_error("can't relocate value at %x",addr); x >>= 2; x &= 0xffffff; - if (is_call && is_thumb) { + /* Only reached if blx is avail and it is a call */ + if (is_thumb) { x |= h << 24; (*(int *)ptr) = 0xfa << 24; /* bl -> blx */ } -- 2.11.4.GIT