mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-04 06:30:10 +08:00
Fix R_ARM_CALL when target fonction is Thumb
With R_ARM_CALL, if target function is to be entered in Thumb mode, the relocation is supposed to transform bl in blx. This is not the case actually so this commit is there to fix it.
This commit is contained in:
parent
2fe7fd9e87
commit
c6630ef92a
16
tccelf.c
16
tccelf.c
@ -601,22 +601,30 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
|||||||
case R_ARM_JUMP24:
|
case R_ARM_JUMP24:
|
||||||
case R_ARM_PLT32:
|
case R_ARM_PLT32:
|
||||||
{
|
{
|
||||||
int x;
|
int x, is_thumb, is_call, h;
|
||||||
x = (*(int *)ptr)&0xffffff;
|
x = (*(int *)ptr)&0xffffff;
|
||||||
(*(int *)ptr) &= 0xff000000;
|
(*(int *)ptr) &= 0xff000000;
|
||||||
if (x & 0x800000)
|
if (x & 0x800000)
|
||||||
x -= 0x1000000;
|
x -= 0x1000000;
|
||||||
x *= 4;
|
x <<= 2;
|
||||||
x += val - addr;
|
is_thumb = val & 1;
|
||||||
|
is_call = (type == R_ARM_CALL);
|
||||||
|
x += (val & -2) - addr;
|
||||||
|
h = x & 2;
|
||||||
#ifndef TCC_TARGET_PE
|
#ifndef TCC_TARGET_PE
|
||||||
if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
|
if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
|
||||||
if (s1->output_type == TCC_OUTPUT_MEMORY)
|
if (s1->output_type == TCC_OUTPUT_MEMORY)
|
||||||
x += add_jmp_table(s1, val) - val; /* add veneer */
|
x += add_jmp_table(s1, val) - val; /* add veneer */
|
||||||
#endif
|
#endif
|
||||||
if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
|
if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
|
||||||
tcc_error("can't relocate value at %x",addr);
|
if (!(h && is_call && is_thumb))
|
||||||
|
tcc_error("can't relocate value at %x",addr);
|
||||||
x >>= 2;
|
x >>= 2;
|
||||||
x &= 0xffffff;
|
x &= 0xffffff;
|
||||||
|
if (is_call && is_thumb) {
|
||||||
|
x |= h << 24;
|
||||||
|
(*(int *)ptr) = 0xfa << 24; /* bl -> blx */
|
||||||
|
}
|
||||||
(*(int *)ptr) |= x;
|
(*(int *)ptr) |= x;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user