mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
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:
parent
c6630ef92a
commit
9966fd4eae
8
tcc.h
8
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 */
|
||||
|
19
tccelf.c
19
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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user