From 1b606d18840f8d0abe43ea80c0675c0639f84c51 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Mon, 18 Nov 2013 00:03:38 +0800 Subject: [PATCH] Allow thumb transition for R_ARM_PC24 Allow bl -> blx conversion in the case of R_ARM_PC24 relocation with instruction being an unconditional bl. Also make spacing more uniform. --- tccelf.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tccelf.c b/tccelf.c index 8af4bb63..91155e3f 100644 --- a/tccelf.c +++ b/tccelf.c @@ -603,29 +603,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, blx_avail; - x = (*(int *)ptr)&0xffffff; + int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; + 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); + is_bl = (*(unsigned *) ptr) >> 24 == 0xeb; + is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); x += val - addr; h = x & 2; + th_ko = (x & 3) && (!blx_avail || !is_call); #ifdef TCC_HAS_RUNTIME_PLTGOT if (s1->output_type == TCC_OUTPUT_MEMORY) { - if ((x & 3) || x >= 0x2000000 || x < -0x2000000) - if (!(x & 3) || !blx_avail || !is_call) { - x += add_jmp_table(s1, val) - val; /* add veneer */ - is_thumb = 0; /* Veneer uses ARM instructions */ - } + if (th_ko || x >= 0x2000000 || x < -0x2000000) { + x += add_jmp_table(s1, val) - val; /* add veneer */ + th_ko = (x & 3) && (!blx_avail || !is_call); + is_thumb = 0; /* Veneer uses ARM instructions */ + } } #endif - if ((x & 3) || x >= 0x2000000 || x < -0x2000000) - if (!(x & 3) || !blx_avail || !is_call) - tcc_error("can't relocate value at %x",addr); + if (th_ko || x >= 0x2000000 || x < -0x2000000) + tcc_error("can't relocate value at %x",addr); x >>= 2; x &= 0xffffff; /* Only reached if blx is avail and it is a call */ @@ -633,7 +634,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) x |= h << 24; (*(int *)ptr) = 0xfa << 24; /* bl -> blx */ } - (*(int *)ptr) |= x; + (*(int *) ptr) |= x; } break; /* Since these relocations only concern Thumb-2 and blx instruction was