This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Long call support broke Thumb veneers


Daniel,


On 03.06.2008 15:54, Daniel Jacobowitz wrote:


Christophe, you removed handling of two relocation types from
bfd_elf32_arm_process_before_allocation, which is responsible for
inserting these stubs.  How do you intend they be handled?
record_arm_to_thumb_glue is now never called for them.

In general, handling long call stubs differently from mode-changing
stubs seems like asking for trouble.


Well,
While taking into account Paul's remarks, it seemed clearer to me to handle mode-switching stubs in the same place as long calls (ie a call which involves mode-switching is handled by the stubs I added, whatever the distance).


Unfortunately I forgot to handle this case in elf32_arm_final_link_relocate.

I propose the attached patch, which also fixes another issue (BLX was still used in cases where it shouldn't). I ran the testsuite with arm-none-eabi and arm-elf targets.

I checked with the code fragment you mentioned (using Code Sourcery 2008q1-126 release), it seems OK to me but I am worrying about your generic-hosted.ld linker script: indeed, the long call stubs are generated before __cs3_interrupt_vector, and I suspect this is problem, isn't it?

Christophe.
2008-06-03  Christophe Lyon  <christophe.lyon@st.com>

	bfd/
	* elf32-arm.c (arm_stub_is_thumb): Define.
	(elf32_arm_final_link_relocate): Handle near mode switching stubs.

	ld/testsuite/
	* ld-arm/farcall-thumb-thumb-m.d: Fix branch type.
	* ld-arm/farcall-thumb-arm.d: Likewise.
Index: ld/testsuite/ld-arm/farcall-thumb-thumb-m.d
===================================================================
--- ld/testsuite/ld-arm/farcall-thumb-thumb-m.d	(revision 680)
+++ ld/testsuite/ld-arm/farcall-thumb-thumb-m.d	(working copy)
@@ -12,7 +12,7 @@ Disassembly of section .text:
     100c:	02001015 	.word	0x02001015
 
 00001010 <_start>:
-    1010:	f7ff eff6 	blx	1000 <_start-0x10>
+    1010:	f7ff fff6 	bl	1000 <_start-0x10>
 Disassembly of section .foo:
 
 02001014 <bar>:
Index: ld/testsuite/ld-arm/farcall-thumb-arm.d
===================================================================
--- ld/testsuite/ld-arm/farcall-thumb-arm.d	(revision 747)
+++ ld/testsuite/ld-arm/farcall-thumb-arm.d	(working copy)
@@ -12,7 +12,7 @@ Disassembly of section .text:
 	...
 
 00001018 <_start>:
-    1018:	f7ff eff2 	blx	1000 <_start-0x18>
+    1018:	f7ff fff2 	bl	1000 <_start-0x18>
 Disassembly of section .foo:
 
 02001014 <bar>:
Index: bfd/elf32-arm.c
===================================================================
--- bfd/elf32-arm.c	(revision 747)
+++ bfd/elf32-arm.c	(working copy)
@@ -2680,6 +2680,21 @@ elf32_arm_hash_table_free (struct bfd_li
 static int using_thumb2 (struct elf32_arm_link_hash_table *globals);
 static int using_thumb_only (struct elf32_arm_link_hash_table *globals);
 
+static bfd_boolean arm_stub_is_thumb(enum elf32_arm_stub_type stub_type)
+{
+  switch(stub_type) {
+  case arm_thumb_thumb_stub_long_branch:
+  case arm_thumb_arm_v4t_stub_long_branch:
+    return TRUE;
+  case arm_stub_none:
+    BFD_FAIL ();
+    return FALSE;
+    break;
+  default:
+    return FALSE;
+  }
+}
+
 static enum elf32_arm_stub_type
 arm_type_of_stub (struct bfd_link_info *info,
 		  asection *input_sec,
@@ -6306,6 +6321,7 @@ elf32_arm_final_link_relocate (reloc_how
 	       (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
 		|| (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET))
 	       )
+	     || ((sym_flags != STT_ARM_TFUNC) && !globals->use_blx)
 	    )
 	  {
 	    /* The target is out of reach or we are changing modes, so
@@ -6320,10 +6336,14 @@ elf32_arm_final_link_relocate (reloc_how
 		       + stub_entry->stub_sec->output_offset
 		       + stub_entry->stub_sec->output_section->vma);
 
-	    /* This call becomes a call to Arm for sure. Force BLX */
+	    /* If this call becomes a call to Arm, force BLX */
+	    if (globals->use_blx) {
+	      if ( (stub_entry && !arm_stub_is_thumb(stub_entry->stub_type))
+		   || (sym_flags != STT_ARM_TFUNC) )
 	    lower_insn = (lower_insn & ~0x1000) | 0x0800;
 	  }
 	}
+	}
 
 	relocation = value + signed_addend;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]