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.
This commit is contained in:
Thomas Preud'homme 2012-10-16 00:31:56 +02:00
parent c6630ef92a
commit 9966fd4eae
2 changed files with 19 additions and 8 deletions

8
tcc.h
View File

@ -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 */

View File

@ -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 */
}