History

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.

Thomas Preud'homme committed 14 years ago

Commit 9966fd41 parent c6630ef2 files · +19 −8Browse files

Unified · Split

2 files
  1. tcc.h +8 −0
  2. tccelf.c +11 −8
tcc.h+8−0
@@ -105,6 +105,14 @@ · 104 unmodified lines
105#define TCC_TARGET_I386105#define TCC_TARGET_I386
106#endif106#endif
107 107
108#if defined (TCC_TARGET_ARM) && !defined(TCC_ARM_VERSION)
109 #ifdef TCC_ARM_HARDFLOAT
110 #define TCC_ARM_VERSION 7
111 #else
112 #define TCC_ARM_VERSION 4
113 #endif
114#endif
115
108#if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \116#if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
109 !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)117 !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
110#define CONFIG_TCC_BCHECK /* enable bound checking code */118#define CONFIG_TCC_BCHECK /* enable bound checking code */
tccelf.c+11−8
@@ -601,27 +601,30 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 600 unmodified lines
601 case R_ARM_JUMP24:601 case R_ARM_JUMP24:
602 case R_ARM_PLT32:602 case R_ARM_PLT32:
603 {603 {
604 int x, is_thumb, is_call, h;604 int x, is_thumb, is_call, h, blx_avail;
605 x = (*(int *)ptr)&0xffffff;605 x = (*(int *)ptr)&0xffffff;
606 (*(int *)ptr) &= 0xff000000;606 (*(int *)ptr) &= 0xff000000;
607 if (x & 0x800000)607 if (x & 0x800000)
608 x -= 0x1000000;608 x -= 0x1000000;
609 x <<= 2;609 x <<= 2;
610 blx_avail = (TCC_ARM_VERSION >= 5);
610 is_thumb = val & 1;611 is_thumb = val & 1;
611 is_call = (type == R_ARM_CALL);612 is_call = (type == R_ARM_CALL);
612 x += (val & -2) - addr;613 x += val - addr;
613 h = x & 2;614 h = x & 2;
614#ifndef TCC_TARGET_PE615#ifndef TCC_TARGET_PE
615 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)616 if ((x & 3) || x >= 0x4000000 || x < -0x4000000)
616 if (s1->output_type == TCC_OUTPUT_MEMORY)617 if (!(x & 3) || !blx_avail || !is_call)
617 x += add_jmp_table(s1, val) - val; /* add veneer */618 if (s1->output_type == TCC_OUTPUT_MEMORY)
619 x += add_jmp_table(s1, val) - val; /* add veneer */
618#endif620#endif
619 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)621 if ((x & 3) || x >= 0x4000000 || x < -0x4000000)
620 if (!(h && is_call && is_thumb))622 if (!(x & 3) || !blx_avail || !is_call)
621 tcc_error("can't relocate value at %x",addr);623 tcc_error("can't relocate value at %x",addr);
622 x >>= 2;624 x >>= 2;
623 x &= 0xffffff;625 x &= 0xffffff;
624 if (is_call && is_thumb) {626 /* Only reached if blx is avail and it is a call */
627 if (is_thumb) {
625 x |= h << 24;628 x |= h << 24;
626 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */629 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
627 }630 }