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
105105 #define TCC_TARGET_I386
106106 #endif
107107
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+
108116 #if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
109117 !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
110118 #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
601601 case R_ARM_JUMP24:
602602 case R_ARM_PLT32:
603603 {
604− int x, is_thumb, is_call, h;
604+ int x, is_thumb, is_call, h, blx_avail;
605605 x = (*(int *)ptr)&0xffffff;
606606 (*(int *)ptr) &= 0xff000000;
607607 if (x & 0x800000)
608608 x -= 0x1000000;
609609 x <<= 2;
610+ blx_avail = (TCC_ARM_VERSION >= 5);
610611 is_thumb = val & 1;
611612 is_call = (type == R_ARM_CALL);
612− x += (val & -2) - addr;
613+ x += val - addr;
613614 h = x & 2;
614615 #ifndef TCC_TARGET_PE
615− if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
616− if (s1->output_type == TCC_OUTPUT_MEMORY)
617− x += add_jmp_table(s1, val) - val; /* add veneer */
616+ if ((x & 3) || x >= 0x4000000 || x < -0x4000000)
617+ if (!(x & 3) || !blx_avail || !is_call)
618+ if (s1->output_type == TCC_OUTPUT_MEMORY)
619+ x += add_jmp_table(s1, val) - val; /* add veneer */
618620 #endif
619− if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
620− if (!(h && is_call && is_thumb))
621+ if ((x & 3) || x >= 0x4000000 || x < -0x4000000)
622+ if (!(x & 3) || !blx_avail || !is_call)
621623 tcc_error("can't relocate value at %x",addr);
622624 x >>= 2;
623625 x &= 0xffffff;
624− if (is_call && is_thumb) {
626+ /* Only reached if blx is avail and it is a call */
627+ if (is_thumb) {
625628 x |= h << 24;
626629 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
627630 }