From 9966fd4eaea163439a63d63d044d0657df1908ea Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 16 Oct 2012 00:31:56 +0200 Subject: 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. --- tccelf.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'tccelf.c') diff --git a/tccelf.c b/tccelf.c index 7943763..f46a742 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 */ } -- cgit v1.3.1