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: ARM/thumb interworking confuses unwinder


Hi,

I have a question.  Have you tried any of the Thumb stubs on a
big-endian target?  I worry that your trick of using a 32-bit
word with two 16-bit Thumb instructions in it is going to leave them
in the wrong order.

No, I didn't try, and was worrying about this too.


 > Space before the *, not afterwards, please.
Here is an updated patch.

+ " first occurrence: %B: thumb call to arm"),
"Thumb", "ARM".
I changed this too. Note that I merely cut&pasted the error message from another part of elf32-arm.c :-)

I also removed the reformated comments (Thumb->(non-interworking aware) ARM), as they have been updated by Nick.

Otherwise OK; the big-endian question isn't new with this patch.


Can someone commit this for me? (as an only occasional contributor, I still don't dare to request an account)



Thanks,


Christophe.
2008-08-07  Christophe Lyon  <christophe.lyon@st.com>

	bfd/
	* elf32-arm.c (arm_thumb_arm_v4t_short_branch_stub): Define.
	(elf32_arm_stub_type): Add arm_thumb_arm_v4t_stub_short_branch.
	(arm_type_of_stub): Handle armv4t short branches. Update
	prototype.
	(arm_stub_is_thumb): Handle arm_thumb_arm_v4t_stub_short_branch.
	(arm_build_one_stub): Likewise.
	(arm_size_one_stub): Likewise.
	(elf32_arm_size_stubs): Use new arm_type_of_stub prototype.
	(arm_map_one_stub): Handle arm_thumb_arm_v4t_stub_short_branch.

	ld/testsuite/
	* ld-arm/arm-elf.exp: Add farcall-thumb-arm-short test.
	* ld-arm/farcall-group2.s: Fix comment.
	* ld-arm/farcall-thumb-arm-short.d: New test.
	* ld-arm/farcall-thumb-arm-short.s: New test.

diff --exclude=CVS --exclude='*~' -Naur binutils-cvs-ref/src/bfd/elf32-arm.c binutils-cvs/src/bfd/elf32-arm.c
--- binutils-cvs-ref/src/bfd/elf32-arm.c	2008-08-26 10:56:04.000000000 +0200
+++ binutils-cvs/src/bfd/elf32-arm.c	2008-08-26 10:51:51.000000000 +0200
@@ -2045,6 +2045,13 @@
     0x00000000,         /* dcd  R_ARM_ABS32(X) */
   };
 
+static const bfd_vma arm_thumb_arm_v4t_short_branch_stub[] =
+  {
+    0x46c04778,         /* bx   pc */
+                        /* nop   */
+    0xea000000,         /* b    (X) */
+  };
+
 static const bfd_vma arm_pic_long_branch_stub[] =
   {
     0xe59fc000,         /* ldr   r12, [pc] */
@@ -2063,6 +2070,7 @@
   arm_thumb_v4t_stub_long_branch,
   arm_thumb_thumb_stub_long_branch,
   arm_thumb_arm_v4t_stub_long_branch,
+  arm_thumb_arm_v4t_stub_short_branch,
   arm_stub_pic_long_branch,
 };
 
@@ -2738,6 +2746,7 @@
     {
     case arm_thumb_thumb_stub_long_branch:
     case arm_thumb_arm_v4t_stub_long_branch:
+    case arm_thumb_arm_v4t_stub_short_branch:
       return TRUE;
     case arm_stub_none:
       BFD_FAIL ();
@@ -2756,7 +2765,10 @@
 		  const Elf_Internal_Rela *rel,
 		  unsigned char st_type,
 		  struct elf32_arm_link_hash_entry *hash,
-		  bfd_vma destination)
+		  bfd_vma destination,
+		  asection *sym_sec,
+		  bfd *input_bfd,
+		  const char *name)
 {
   bfd_vma location;
   bfd_signed_vma branch_offset;
@@ -2826,6 +2838,16 @@
 	  else
 	    {
 	      /* Thumb to arm.  */
+	      if (sym_sec != NULL
+		  && sym_sec->owner != NULL
+		  && !INTERWORK_FLAG (sym_sec->owner))
+		{
+		  (*_bfd_error_handler)
+		    (_("%B(%s): warning: interworking not enabled.\n"
+		       "  first occurrence: %B: Thumb call to ARM"),
+		     sym_sec->owner, input_bfd, name);
+		}
+
 	      stub_type = (info->shared | globals->pic_veneer)
 		? ((globals->use_blx)
 		   ? arm_stub_pic_long_branch
@@ -2833,6 +2855,13 @@
 		: (globals->use_blx)
 		? arm_stub_long_branch
 		: arm_thumb_arm_v4t_stub_long_branch;
+
+	      /* Handle v4t short branches */
+	      if ( (stub_type == arm_thumb_arm_v4t_stub_long_branch)
+		   && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
+		   && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET)) {
+		stub_type = arm_thumb_arm_v4t_stub_short_branch;
+	      }
 	    }
 	}
     }
@@ -2841,6 +2870,17 @@
       if (st_type == STT_ARM_TFUNC)
 	{
 	  /* Arm to thumb.  */
+
+	  if (sym_sec != NULL
+	      && sym_sec->owner != NULL
+	      && !INTERWORK_FLAG (sym_sec->owner))
+	    {
+	      (*_bfd_error_handler)
+		(_("%B(%s): warning: interworking not enabled.\n"
+		   "  first occurrence: %B: Thumb call to ARM"),
+		 sym_sec->owner, input_bfd, name);
+	    }
+
 	  /* We have an extra 2-bytes reach because of the mode change
 	     (bit 24 (H) of BLX encoding).  */
 	  if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)
@@ -3098,6 +3138,10 @@
       template =  arm_thumb_arm_v4t_long_branch_stub;
       template_size = (sizeof (arm_thumb_arm_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
       break;
+    case arm_thumb_arm_v4t_stub_short_branch:
+      template =  arm_thumb_arm_v4t_short_branch_stub;
+      template_size = (sizeof(arm_thumb_arm_v4t_short_branch_stub) / sizeof (bfd_vma)) * 4;
+      break;
     case arm_stub_pic_long_branch:
       template = arm_pic_long_branch_stub;
       template_size = (sizeof (arm_pic_long_branch_stub) / sizeof (bfd_vma)) * 4;
@@ -3147,6 +3191,19 @@
 				stub_bfd, stub_sec, stub_sec->contents,
 				stub_entry->stub_offset + 16, sym_value, 0);
       break;
+    case arm_thumb_arm_v4t_stub_short_branch:
+      {
+	long int rel_offset;
+	static const insn32 t2a3_b_insn = 0xea000000;
+
+	rel_offset = sym_value - (stub_addr + 8 + 4);
+
+	put_arm_insn (globals, stub_bfd,
+		      (bfd_vma) t2a3_b_insn | ((rel_offset >> 2) & 0x00FFFFFF),
+		      loc + 4);
+      }
+      break;
+
     case arm_stub_pic_long_branch:
       /* We want the value relative to the address 8 bytes from the
 	 start of the stub.  */
@@ -3197,6 +3254,10 @@
       template =  arm_thumb_arm_v4t_long_branch_stub;
       template_size = (sizeof (arm_thumb_arm_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
       break;
+    case arm_thumb_arm_v4t_stub_short_branch:
+      template =  arm_thumb_arm_v4t_short_branch_stub;
+      template_size = (sizeof(arm_thumb_arm_v4t_short_branch_stub) / sizeof (bfd_vma)) * 4;
+      break;
     case arm_stub_pic_long_branch:
       template = arm_pic_long_branch_stub;
       template_size = (sizeof (arm_pic_long_branch_stub) / sizeof (bfd_vma)) * 4;
@@ -3603,7 +3664,8 @@
 
 		  /* Determine what (if any) linker stub is needed.  */
 		  stub_type = arm_type_of_stub (info, section, irela, st_type,
-						hash, destination);
+						hash, destination, sym_sec,
+						input_bfd, sym_name);
 		  if (stub_type == arm_stub_none)
 		    continue;
 
@@ -11205,6 +11267,12 @@
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
 	return FALSE;
       break;
+    case arm_thumb_arm_v4t_stub_short_branch:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 8))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 4))
+	return FALSE;
+      break;
     case arm_stub_pic_long_branch:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
 	return FALSE;
diff --exclude=CVS --exclude='*~' -Naur binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-elf.exp binutils-cvs/src/ld/testsuite/ld-arm/arm-elf.exp
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-elf.exp	2008-07-18 22:49:12.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/arm-elf.exp	2008-08-07 14:46:24.000000000 +0200
@@ -207,7 +207,7 @@
      {"Thumb-2 BL" "-Ttext 0x1000 --section-start .foo=0x1001000" "" {thumb2-bl.s}
       {{objdump -dr thumb2-bl.d}}
       "thumb2-bl"}
-    
+
     {"ARMv4 interworking" "-static -T arm.ld --fix-v4bx-interworking" "--fix-v4bx -meabi=4" {armv4-bx.s}
      {{objdump -d armv4-bx.d}}
      "armv4-bx"}
@@ -260,6 +260,9 @@
     {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
      "farcall-thumb-arm"}
+    {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
+     {{objdump -d farcall-thumb-arm-short.d}}
+     "farcall-thumb-arm-short"}
     {"Thumb-ARM farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx.d}}
      "farcall-thumb-arm-blx"}
diff --exclude=CVS --exclude='*~' -Naur binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-group2.s binutils-cvs/src/ld/testsuite/ld-arm/farcall-group2.s
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-group2.s	2008-05-23 16:16:16.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-group2.s	2008-08-07 10:48:15.000000000 +0200
@@ -1,10 +1,7 @@
-
 @ Test to ensure that ARM calls exceeding 32Mb generate stubs.
 
-@ We will place the section .foo at 0x2000.
-
 	.text
-myfunc:	
+myfunc:
 	bl bar3
 	bl bar4
 	bl bar5
diff --exclude=CVS --exclude='*~' -Naur binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.d	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.d	2008-08-06 13:48:05.000000000 +0200
@@ -0,0 +1,14 @@
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <__bar_from_thumb>:
+    1000:	4778      	bx	pc
+    1002:	46c0      	nop			\(mov r8, r8\)
+    1004:	ea000402 	b	2014 <bar>
+00001008 <_start>:
+    1008:	f7ff fffa 	bl	1000 <__bar_from_thumb>
+Disassembly of section .foo:
+
+00002014 <bar>:
+    2014:	e12fff1e 	bx	lr
diff --exclude=CVS --exclude='*~' -Naur binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.s binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.s
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.s	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-short.s	2008-08-06 13:38:48.000000000 +0200
@@ -0,0 +1,21 @@
+@ Test to ensure that a Thumb to ARM call within 4Mb does not generate a stub.
+
+	.global _start
+	.syntax unified
+
+@ We will place the section .text at 0x1000.
+
+	.text
+	.thumb_func
+_start:
+	bl bar
+
+@ We will place the section .foo at 0x2014.
+
+	.section .foo, "xa"
+
+	.arm
+	.type bar, %function
+bar:
+	bx lr
+

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