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: PR9743 / ARM: long branch stubs to PLT


On 06.02.2009 15:58, Daniel Jacobowitz wrote:
On Fri, Feb 06, 2009 at 09:45:53AM +0100, Christophe LYON wrote:
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' ./bfd/elf32-arm.c ../../binutils-cvs-ref/src/bfd/elf32-arm.c

Which one of these is the new version? I think this one's switched.


For diffs, it is most helpful to have the old version on the left, the
new version on the right, and both with the same number of pathname
components (either bfd/elf32-arm.c.orig vs bfd/elf32-arm.c or
ref/bfd/elf32-arm.c vs new/bfd/elf32-arm.c).

OK, here is a new attempt, hopefully right this time ;-)

Christophe.

diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/bfd/elf32-arm.c binutils-cvs/src/bfd/elf32-arm.c
--- binutils-cvs-ref/src/bfd/elf32-arm.c	2009-02-05 11:10:54.000000000 +0100
+++ binutils-cvs/src/bfd/elf32-arm.c	2009-02-05 16:27:28.000000000 +0100
@@ -2010,31 +2010,40 @@
 #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
 #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
 
-static const bfd_vma arm_long_branch_stub[] =
+/* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx
+   to reach the stub if necessary.  */
+static const bfd_vma elf32_arm_stub_long_branch_any_any[] =
   {
     0xe51ff004,         /* ldr   pc, [pc, #-4] */
     0x00000000,         /* dcd   R_ARM_ABS32(X) */
   };
 
-static const bfd_vma arm_thumb_v4t_long_branch_stub[] =
+/* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not
+   available.  */
+static const bfd_vma elf32_arm_stub_long_branch_v4t_arm_thumb[] =
   {
     0xe59fc000,         /* ldr   ip, [pc, #0] */
     0xe12fff1c,         /* bx    ip */
     0x00000000,         /* dcd   R_ARM_ABS32(X) */
   };
 
-static const bfd_vma arm_thumb_thumb_long_branch_stub[] =
+/* Thumb -> Thumb long branch stub. Used on architectures which
+   support only this mode, or on V4T where it is expensive to switch
+   to ARM.  */
+static const bfd_vma elf32_arm_stub_long_branch_thumb_only[] =
   {
     0x4e02b540,         /* push {r6, lr} */
                         /* ldr  r6, [pc, #8] */
-    0x473046fe,         /* mov  lr, pc */
-                        /* bx   r6 */
+    0x46b746fe,         /* mov  lr, pc */
+                        /* mov  pc, r6 */
     0xbf00bd40,         /* pop  {r6, pc} */
                         /* nop */
     0x00000000,         /* dcd  R_ARM_ABS32(X) */
   };
 
-static const bfd_vma arm_thumb_arm_v4t_long_branch_stub[] =
+/* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not
+   available.  */
+static const bfd_vma elf32_arm_stub_long_branch_v4t_thumb_arm[] =
   {
     0x4e03b540,         /* push {r6, lr} */
                         /* ldr  r6, [pc, #12] */
@@ -2045,20 +2054,59 @@
     0x00000000,         /* dcd  R_ARM_ABS32(X) */
   };
 
-static const bfd_vma arm_thumb_arm_v4t_short_branch_stub[] =
+/* V4T Thumb -> ARM short branch stub. Shorter variant of the above
+   one, when the destination is close enough.  */
+static const bfd_vma elf32_arm_stub_short_branch_v4t_thumb_arm[] =
   {
     0x46c04778,         /* bx   pc */
                         /* nop   */
     0xea000000,         /* b    (X) */
   };
 
-static const bfd_vma arm_pic_long_branch_stub[] =
+/* ARM/Thumb -> ARM/Thumb long branch stub, PIC. On V5T and above, use
+   blx to reach the stub if necessary.  */
+static const bfd_vma elf32_arm_stub_long_branch_any_any_pic[] =
   {
     0xe59fc000,         /* ldr   r12, [pc] */
     0xe08ff00c,         /* add   pc, pc, ip */
     0x00000000,         /* dcd   R_ARM_REL32(X) */
   };
 
+/* V4T ARM -> ARM long branch stub, PIC.  */
+static const bfd_vma elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] =
+  {
+    0xe59fc004,         /* ldr   r12, [pc, #4] */
+    0xe08cc00f,         /* add   r12, r12, pc */
+    0xe12fff1c,         /* bx    r12 */
+    0x00000000,         /* dcd   R_ARM_REL32(X) */
+  };
+
+/* V4T Thumb -> ARM long branch stub, PIC.  */
+static const bfd_vma elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
+  {
+    0x46c04778,         /* bx   pc */
+                        /* nop   */
+    0xe59fc004,         /* ldr   r12, [pc, #4] */
+    0xe08cc00f,         /* add   r12, r12, pc */
+    0xe1a0f00c,         /* mov   pc, r12 */
+    0x00000000,         /* dcd   R_ARM_REL32(X) */
+  };
+
+/* Thumb -> Thumb long branch stub, PIC. Used on architectures which
+   support only this mode, or on V4T where it is expensive to switch
+   to ARM.  */
+static const bfd_vma elf32_arm_stub_long_branch_thumb_only_pic[] =
+  {
+    0x4e02b540,         /* push {r6, lr} */
+                        /* ldr  r6, [pc, #8] */
+    0x44b746fe,         /* mov  lr, pc */
+                        /* add  pc, r6 */
+    0xbf00bd40,         /* pop  {r6, pc} */
+                        /* nop */
+    0x00000000,         /* dcd  R_ARM_REL32(X) */
+  };
+
+
 /* Section name for stubs is the associated section name plus this
    string.  */
 #define STUB_SUFFIX ".stub"
@@ -2066,12 +2114,15 @@
 enum elf32_arm_stub_type
 {
   arm_stub_none,
-  arm_stub_long_branch,
-  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,
+  arm_stub_long_branch_any_any,
+  arm_stub_long_branch_v4t_arm_thumb,
+  arm_stub_long_branch_thumb_only,
+  arm_stub_long_branch_v4t_thumb_arm,
+  arm_stub_short_branch_v4t_thumb_arm,
+  arm_stub_long_branch_any_any_pic,
+  arm_stub_long_branch_v4t_arm_thumb_pic,
+  arm_stub_long_branch_v4t_thumb_arm_pic,
+  arm_stub_long_branch_thumb_only_pic,
 };
 
 struct elf32_arm_stub_hash_entry
@@ -2731,9 +2782,11 @@
 {
   switch (stub_type)
     {
-    case arm_thumb_thumb_stub_long_branch:
-    case arm_thumb_arm_v4t_stub_long_branch:
-    case arm_thumb_arm_v4t_stub_short_branch:
+    case arm_stub_long_branch_thumb_only:
+    case arm_stub_long_branch_v4t_thumb_arm:
+    case arm_stub_short_branch_v4t_thumb_arm:
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+    case arm_stub_long_branch_thumb_only_pic:
       return TRUE;
     case arm_stub_none:
       BFD_FAIL ();
@@ -2752,10 +2805,7 @@
 		  const Elf_Internal_Rela *rel,
 		  unsigned char st_type,
 		  struct elf32_arm_link_hash_entry *hash,
-		  bfd_vma destination,
-		  asection *sym_sec,
-		  bfd *input_bfd,
-		  const char *name)
+		  bfd_vma destination)
 {
   bfd_vma location;
   bfd_signed_vma branch_offset;
@@ -2764,6 +2814,7 @@
   int thumb2;
   int thumb_only;
   enum elf32_arm_stub_type stub_type = arm_stub_none;
+  int use_plt = 0;
 
   /* We don't know the actual type of destination in case it is of
      type STT_SECTION: give up.  */
@@ -2785,20 +2836,37 @@
 
   r_type = ELF32_R_TYPE (rel->r_info);
 
-  /* If the call will go through a PLT entry then we do not need
-     glue.  */
+  /* Keep a simpler condition, for the sake of clarity.  */
   if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)
-    return stub_type;
-
-  if (r_type == R_ARM_THM_CALL)
     {
+      use_plt = 1;
+      /* Note when dealing with PLT entries: the main PLT stub is in
+	 ARM mode, so if we are in Thumb mode, another Thumb->ARM stub
+	 will be inserted just before the ARM PLT stub. We don't take
+	 this extra distance into account here, because if a long
+	 branch stub is needed, we'll add a Thumb->Arm one and branch
+	 directly to the ARM PLT entry because it avoids spreading
+	 offset corrections in several places.  */
+    }
+
+  if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
+    {
+      /* Check cases where:
+	 - this call goes too far (different Thumb/Thumb2 distance)
+	 - it's a Thumb->Arm call and blx is not available. A stub is
+           needed in this case, but only if this call is not through a
+           PLT entry. Indeed, PLT stubs handle mode switching already.
+      */
       if ((!thumb2
 	    && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET
 		|| (branch_offset < THM_MAX_BWD_BRANCH_OFFSET)))
 	  || (thumb2
 	      && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
 		  || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
-	  || ((st_type != STT_ARM_TFUNC) && !globals->use_blx))
+	  || ((st_type != STT_ARM_TFUNC)
+	      && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
+		  || (r_type == R_ARM_THM_JUMP24))
+	      && !use_plt))
 	{
 	  if (st_type == STT_ARM_TFUNC)
 	    {
@@ -2807,77 +2875,58 @@
 		{
 		  stub_type = (info->shared | globals->pic_veneer)
 		    ? ((globals->use_blx)
-		       ? arm_stub_pic_long_branch
-		       : arm_stub_none)
-		    : (globals->use_blx)
-		    ? arm_stub_long_branch
-		    : arm_stub_none;
+		       ? arm_stub_long_branch_any_any_pic
+		       : arm_stub_long_branch_thumb_only_pic)
+		    : ((globals->use_blx)
+		       ? arm_stub_long_branch_any_any
+		       : arm_stub_long_branch_thumb_only);
 		}
 	      else
 		{
 		  stub_type = (info->shared | globals->pic_veneer)
-		    ? arm_stub_none
-		    : (globals->use_blx)
-		    ? arm_thumb_thumb_stub_long_branch
-		    : arm_stub_none;
+		    ? arm_stub_long_branch_thumb_only_pic
+		    : arm_stub_long_branch_thumb_only;
 		}
 	    }
 	  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
-		   : arm_stub_none)
-		: (globals->use_blx)
-		? arm_stub_long_branch
-		: arm_thumb_arm_v4t_stub_long_branch;
+		   ? arm_stub_long_branch_any_any_pic
+		   : arm_stub_long_branch_v4t_thumb_arm_pic)
+		: ((globals->use_blx)
+		   ? arm_stub_long_branch_any_any
+		   : arm_stub_long_branch_v4t_thumb_arm);
 
 	      /* Handle v4t short branches.  */
-	      if ((stub_type == arm_thumb_arm_v4t_stub_long_branch)
+	      if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
 		  && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
 		  && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))
-		stub_type = arm_thumb_arm_v4t_stub_short_branch;
+		stub_type = arm_stub_short_branch_v4t_thumb_arm;
 	    }
 	}
     }
-  else if (r_type == R_ARM_CALL)
+  else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
     {
       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)
 	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)
-	      || !globals->use_blx)
+	      || ((r_type == R_ARM_CALL) && !globals->use_blx)
+	      || (r_type == R_ARM_JUMP24) || r_type == R_ARM_PLT32)
 	    {
 	      stub_type = (info->shared | globals->pic_veneer)
-		? arm_stub_pic_long_branch
-		: (globals->use_blx)
-		? arm_stub_long_branch
-		: arm_thumb_v4t_stub_long_branch;
+		? ((globals->use_blx)
+		   ? arm_stub_long_branch_any_any_pic
+		   : arm_stub_long_branch_v4t_arm_thumb_pic)
+		: ((globals->use_blx)
+		   ? arm_stub_long_branch_any_any
+		   : arm_stub_long_branch_v4t_arm_thumb);
 	    }
 	}
       else
@@ -2887,8 +2936,8 @@
 	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
 	    {
 	      stub_type = (info->shared | globals->pic_veneer)
-		? arm_stub_pic_long_branch
-		: arm_stub_long_branch;
+		? arm_stub_long_branch_any_any_pic
+		: arm_stub_long_branch_any_any;
 	    }
 	}
     }
@@ -3108,29 +3157,41 @@
 
   switch (stub_entry->stub_type)
     {
-    case arm_stub_long_branch:
-      template = arm_long_branch_stub;
-      template_size = (sizeof (arm_long_branch_stub) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_thumb_v4t_stub_long_branch:
-      template =  arm_thumb_v4t_long_branch_stub;
-      template_size = (sizeof (arm_thumb_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_thumb_thumb_stub_long_branch:
-      template =  arm_thumb_thumb_long_branch_stub;
-      template_size = (sizeof (arm_thumb_thumb_long_branch_stub) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_thumb_arm_v4t_stub_long_branch:
-      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;
+    case arm_stub_long_branch_any_any:
+      template = elf32_arm_stub_long_branch_any_any;
+      template_size = (sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_arm_thumb:
+      template =  elf32_arm_stub_long_branch_v4t_arm_thumb;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_thumb_only:
+      template =  elf32_arm_stub_long_branch_thumb_only;
+      template_size = (sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm:
+      template =  elf32_arm_stub_long_branch_v4t_thumb_arm;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_short_branch_v4t_thumb_arm:
+      template =  elf32_arm_stub_short_branch_v4t_thumb_arm;
+      template_size = (sizeof(elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_any_any_pic:
+      template = elf32_arm_stub_long_branch_any_any_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_any_any_pic) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_arm_thumb_pic:
+      template = elf32_arm_stub_long_branch_v4t_arm_thumb_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb_pic) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+      template = elf32_arm_stub_long_branch_v4t_thumb_arm_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm_pic) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_thumb_only_pic:
+      template = elf32_arm_stub_long_branch_thumb_only_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_thumb_only_pic) / sizeof (bfd_vma)) * 4;
       break;
     default:
       BFD_FAIL ();
@@ -3157,27 +3218,27 @@
 
   switch (stub_entry->stub_type)
     {
-    case arm_stub_long_branch:
+    case arm_stub_long_branch_any_any:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
 				stub_bfd, stub_sec, stub_sec->contents,
 				stub_entry->stub_offset + 4, sym_value, 0);
       break;
-    case arm_thumb_v4t_stub_long_branch:
+    case arm_stub_long_branch_v4t_arm_thumb:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
 				stub_bfd, stub_sec, stub_sec->contents,
 				stub_entry->stub_offset + 8, sym_value, 0);
       break;
-    case arm_thumb_thumb_stub_long_branch:
+    case arm_stub_long_branch_thumb_only:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
 				stub_bfd, stub_sec, stub_sec->contents,
 				stub_entry->stub_offset + 12, sym_value, 0);
       break;
-    case arm_thumb_arm_v4t_stub_long_branch:
+    case arm_stub_long_branch_v4t_thumb_arm:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
 				stub_bfd, stub_sec, stub_sec->contents,
 				stub_entry->stub_offset + 16, sym_value, 0);
       break;
-    case arm_thumb_arm_v4t_stub_short_branch:
+    case arm_stub_short_branch_v4t_thumb_arm:
       {
 	long int rel_offset;
 	static const insn32 t2a3_b_insn = 0xea000000;
@@ -3190,14 +3251,36 @@
       }
       break;
 
-    case arm_stub_pic_long_branch:
+    case arm_stub_long_branch_any_any_pic:
       /* We want the value relative to the address 8 bytes from the
 	 start of the stub.  */
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),
 				stub_bfd, stub_sec, stub_sec->contents,
-				stub_entry->stub_offset + 8, sym_value, 0);
+				stub_entry->stub_offset + 8, sym_value, -4);
+      break;
+    case arm_stub_long_branch_v4t_arm_thumb_pic:
+      /* We want the value relative to the address 12 bytes from the
+	 start of the stub.  */
+      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),
+				stub_bfd, stub_sec, stub_sec->contents,
+				stub_entry->stub_offset + 12, sym_value, 0);
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+      /* We want the value relative to the address 16 bytes from the
+	 start of the stub.  */
+      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),
+				stub_bfd, stub_sec, stub_sec->contents,
+				stub_entry->stub_offset + 16, sym_value, 0);
+      break;
+    case arm_stub_long_branch_thumb_only_pic:
+      /* We want the value relative to the address 12 bytes from the
+	 start of the stub.  */
+      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),
+				stub_bfd, stub_sec, stub_sec->contents,
+				stub_entry->stub_offset + 12, sym_value, 2);
       break;
     default:
+      BFD_FAIL ();
       break;
     }
 
@@ -3224,29 +3307,41 @@
 
   switch (stub_entry->stub_type)
     {
-    case arm_stub_long_branch:
-      template =  arm_long_branch_stub;
-      template_size = (sizeof (arm_long_branch_stub) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_thumb_v4t_stub_long_branch:
-      template =  arm_thumb_v4t_long_branch_stub;
-      template_size = (sizeof (arm_thumb_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_thumb_thumb_stub_long_branch:
-      template =  arm_thumb_thumb_long_branch_stub;
-      template_size = (sizeof (arm_thumb_thumb_long_branch_stub) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_thumb_arm_v4t_stub_long_branch:
-      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;
+    case arm_stub_long_branch_any_any:
+      template =  elf32_arm_stub_long_branch_any_any;
+      template_size = (sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_arm_thumb:
+      template =  elf32_arm_stub_long_branch_v4t_arm_thumb;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_thumb_only:
+      template =  elf32_arm_stub_long_branch_thumb_only;
+      template_size = (sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm:
+      template =  elf32_arm_stub_long_branch_v4t_thumb_arm;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_short_branch_v4t_thumb_arm:
+      template =  elf32_arm_stub_short_branch_v4t_thumb_arm;
+      template_size = (sizeof(elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_any_any_pic:
+      template = elf32_arm_stub_long_branch_any_any_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_any_any_pic) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_arm_thumb_pic:
+      template = elf32_arm_stub_long_branch_v4t_arm_thumb_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb_pic) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+      template = elf32_arm_stub_long_branch_v4t_thumb_arm_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm_pic) / sizeof (bfd_vma)) * 4;
+      break;
+    case arm_stub_long_branch_thumb_only_pic:
+      template = elf32_arm_stub_long_branch_thumb_only_pic;
+      template_size = (sizeof (elf32_arm_stub_long_branch_thumb_only_pic) / sizeof (bfd_vma)) * 4;
       break;
     default:
       BFD_FAIL ();
@@ -3564,9 +3659,12 @@
 		      goto error_ret_free_local;
 		    }
 
-		  /* Only look for stubs on call instructions.  */
+		  /* Only look for stubs on branch instructions.  */
 		  if ((r_type != (unsigned int) R_ARM_CALL)
-		      && (r_type != (unsigned int) R_ARM_THM_CALL))
+		      && (r_type != (unsigned int) R_ARM_THM_CALL)
+		      && (r_type != (unsigned int) R_ARM_JUMP24)
+		      && (r_type != (unsigned int) R_ARM_THM_JUMP24)
+		      && (r_type != (unsigned int) R_ARM_PLT32))
 		    continue;
 
 		  /* Now determine the call target, its name, value,
@@ -3650,8 +3748,7 @@
 
 		  /* Determine what (if any) linker stub is needed.  */
 		  stub_type = arm_type_of_stub (info, section, irela, st_type,
-						hash, destination, sym_sec,
-						input_bfd, sym_name);
+						hash, destination);
 		  if (stub_type == arm_stub_none)
 		    continue;
 
@@ -4039,86 +4136,6 @@
   return myh;
 }
 
-static void
-record_thumb_to_arm_glue (struct bfd_link_info *link_info,
-			  struct elf_link_hash_entry *h)
-{
-  const char *name = h->root.root.string;
-  asection *s;
-  char *tmp_name;
-  struct elf_link_hash_entry *myh;
-  struct bfd_link_hash_entry *bh;
-  struct elf32_arm_link_hash_table *hash_table;
-  bfd_vma val;
-
-  hash_table = elf32_arm_hash_table (link_info);
-
-  BFD_ASSERT (hash_table != NULL);
-  BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
-
-  s = bfd_get_section_by_name
-    (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
-
-  BFD_ASSERT (s != NULL);
-
-  tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
-			 + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
-
-  BFD_ASSERT (tmp_name);
-
-  sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
-
-  myh = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
-
-  if (myh != NULL)
-    {
-      /* We've already seen this guy.  */
-      free (tmp_name);
-      return;
-    }
-
-  /* The only trick here is using hash_table->thumb_glue_size as the value.
-     Even though the section isn't allocated yet, this is where we will be
-     putting it.  The +1 on the value marks that the stub has not been
-     output yet - not that it is a Thumb function.  */
-  bh = NULL;
-  val = hash_table->thumb_glue_size + 1;
-  _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
-				    tmp_name, BSF_GLOBAL, s, val,
-				    NULL, TRUE, FALSE, &bh);
-
-  /* If we mark it 'Thumb', the disassembler will do a better job.  */
-  myh = (struct elf_link_hash_entry *) bh;
-  myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC);
-  myh->forced_local = 1;
-
-  free (tmp_name);
-
-#define CHANGE_TO_ARM "__%s_change_to_arm"
-#define BACK_FROM_ARM "__%s_back_from_arm"
-
-  /* Allocate another symbol to mark where we switch to Arm mode.  */
-  tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
-			 + strlen (CHANGE_TO_ARM) + 1);
-
-  BFD_ASSERT (tmp_name);
-
-  sprintf (tmp_name, CHANGE_TO_ARM, name);
-
-  bh = NULL;
-  val = hash_table->thumb_glue_size + 4,
-  _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
-				    tmp_name, BSF_LOCAL, s, val,
-				    NULL, TRUE, FALSE, &bh);
-
-  free (tmp_name);
-
-  s->size += THUMB2ARM_GLUE_SIZE;
-  hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
-}
-
-
 /* Allocate space for ARMv4 BX veneers.  */
 
 static void
@@ -4493,10 +4510,7 @@
 	  r_index = ELF32_R_SYM (irel->r_info);
 
 	  /* These are the only relocation types we care about.  */
-	  if (   r_type != R_ARM_PC24
-	      && r_type != R_ARM_PLT32
-	      && r_type != R_ARM_JUMP24
-	      && r_type != R_ARM_THM_JUMP24
+	  if (r_type != R_ARM_PC24
 	      && (r_type != R_ARM_V4BX || globals->fix_v4bx < 2))
 	    continue;
 
@@ -4548,26 +4562,13 @@
 	  switch (r_type)
 	    {
 	    case R_ARM_PC24:
-	    case R_ARM_PLT32:
-	    case R_ARM_JUMP24:
 	      /* This one is a call from arm code.  We need to look up
 	         the target of the call.  If it is a thumb target, we
 	         insert glue.  */
-	      if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC
-		  && !(r_type == R_ARM_CALL && globals->use_blx))
+	      if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
 		record_arm_to_thumb_glue (link_info, h);
 	      break;
 
-	    case R_ARM_THM_JUMP24:
-	      /* This one is a call from thumb code.  We look
-	         up the target of the call.  If it is not a thumb
-                 target, we insert glue.  */
-	      if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC
-		  && !(globals->use_blx && r_type == R_ARM_THM_CALL)
-		  && h->root.type != bfd_link_hash_undefweak)
-		record_thumb_to_arm_glue (link_info, h);
-	      break;
-
 	    default:
 	      abort ();
 	    }
@@ -5909,9 +5910,11 @@
       /* Handle relocations which should use the PLT entry.  ABS32/REL32
 	 will use the symbol's value, which may point to a PLT entry, but we
 	 don't need to handle that here.  If we created a PLT entry, all
-	 branches in this object should go to it.  */
+	 branches in this object should go to it, except if the PLT is too
+	 far away, in which case a long branch stub should be inserted.  */
       if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
-           && r_type != R_ARM_ABS32_NOI && r_type != R_ARM_REL32_NOI)
+           && r_type != R_ARM_ABS32_NOI && r_type != R_ARM_REL32_NOI
+	   && r_type != R_ARM_CALL && r_type != R_ARM_JUMP24 && r_type != R_ARM_PLT32)
 	  && h != NULL
 	  && splt != NULL
 	  && h->plt.offset != (bfd_vma) -1)
@@ -6068,11 +6071,6 @@
 	  bfd_signed_vma branch_offset;
 	  struct elf32_arm_stub_hash_entry *stub_entry = NULL;
 
-	  from = (input_section->output_section->vma
-		  + input_section->output_offset
-		  + rel->r_offset);
-	  branch_offset = (bfd_signed_vma)(value - from);
-
 	  if (r_type == R_ARM_XPC25)
 	    {
 	      /* Check for Arm calling Arm function.  */
@@ -6084,7 +6082,7 @@
 		   input_bfd,
 		   h ? h->root.root.string : "(local)");
 	    }
-	  else if (r_type != R_ARM_CALL)
+	  else if (r_type != R_ARM_CALL && r_type != R_ARM_JUMP24 && r_type != R_ARM_PLT32)
 	    {
 	      /* Check for Arm calling Thumb function.  */
 	      if (sym_flags == STT_ARM_TFUNC)
@@ -6102,11 +6100,30 @@
 
 	  /* Check if a stub has to be inserted because the
 	     destination is too far or we are changing mode.  */
-	  if (r_type == R_ARM_CALL)
+	  if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
 	    {
+	      /* If the call goes through a PLT entry, make sure to
+		 use the right destination address.  */
+	      if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
+		{
+		  value = (splt->output_section->vma
+			   + splt->output_offset
+			   + h->plt.offset);
+		  *unresolved_reloc_p = FALSE;
+		}
+
+	      from = (input_section->output_section->vma
+		      + input_section->output_offset
+		      + rel->r_offset);
+	      branch_offset = (bfd_signed_vma)(value - from);
+
 	      if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
 		  || branch_offset < ARM_MAX_BWD_BRANCH_OFFSET
-		  || sym_flags == STT_ARM_TFUNC)
+		  || ((sym_flags == STT_ARM_TFUNC)
+		      && (((r_type == R_ARM_CALL) && !globals->use_blx)
+			  || (r_type == R_ARM_JUMP24)
+			  || (r_type == R_ARM_PLT32) ))
+		      )
 		{
 		  /* The target is out of reach, so redirect the
 		     branch to the local stub for this function.  */
@@ -6172,15 +6189,16 @@
 		| (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
 
 	      /* Set the H bit in the BLX instruction.  */
-	      if (sym_flags == STT_ARM_TFUNC)
-		{
-		  if (addend)
-		    value |= (1 << 24);
-		  else
-		    value &= ~(bfd_vma)(1 << 24);
-		}
 	      if (r_type == R_ARM_CALL)
 		{
+		  if (sym_flags == STT_ARM_TFUNC)
+		    {
+		      if (addend)
+			value |= (1 << 24);
+		      else
+			value &= ~(bfd_vma)(1 << 24);
+		    }
+
 		  /* Select the correct instruction (BL or BLX).  */
 		  /* Only if we are not handling a BL to a stub. In this
 		     case, mode switching is performed by the stub.  */
@@ -6424,7 +6442,7 @@
 		    /* Convert BL to BLX.  */
 		    lower_insn = (lower_insn & ~0x1000) | 0x0800;
 		  }
-		else if (r_type != R_ARM_THM_CALL)
+		else if (r_type != R_ARM_THM_CALL && r_type != R_ARM_THM_JUMP24)
 		  {
 		    if (elf32_thumb_to_arm_stub
 			(info, sym_name, input_bfd, output_bfd, input_section,
@@ -6461,7 +6479,7 @@
 	    *unresolved_reloc_p = FALSE;
 	  }
 
-	if (r_type == R_ARM_THM_CALL)
+	if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
 	  {
 	    /* Check if a stub has to be inserted because the destination
 	       is too far.  */
@@ -6481,7 +6499,9 @@
 		(thumb2
 		 && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
 		     || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
-		|| ((sym_flags != STT_ARM_TFUNC) && !globals->use_blx))
+		|| ((sym_flags != STT_ARM_TFUNC)
+		    && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
+			|| r_type == R_ARM_THM_JUMP24)))
 	      {
 		/* The target is out of reach or we are changing modes, so
 		   redirect the branch to the local stub for this
@@ -6495,7 +6515,7 @@
 			   + stub_entry->stub_sec->output_section->vma);
 
 		/* If this call becomes a call to Arm, force BLX.  */
-		if (globals->use_blx)
+		if (globals->use_blx && (r_type == R_ARM_THM_CALL))
 		  {
 		    if ((stub_entry
 			 && !arm_stub_is_thumb (stub_entry->stub_type))
@@ -11654,7 +11674,7 @@
 
   switch (stub_entry->stub_type)
     {
-    case arm_stub_long_branch:
+    case arm_stub_long_branch_any_any:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 8))
 	return FALSE;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
@@ -11662,7 +11682,7 @@
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
 	return FALSE;
       break;
-    case arm_thumb_v4t_stub_long_branch:
+    case arm_stub_long_branch_v4t_arm_thumb:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
 	return FALSE;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
@@ -11670,7 +11690,7 @@
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
 	return FALSE;
       break;
-    case arm_thumb_thumb_stub_long_branch:
+    case arm_stub_long_branch_thumb_only:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 16))
 	return FALSE;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
@@ -11678,7 +11698,7 @@
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
 	return FALSE;
       break;
-    case arm_thumb_arm_v4t_stub_long_branch:
+    case arm_stub_long_branch_v4t_thumb_arm:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 20))
 	return FALSE;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
@@ -11688,13 +11708,15 @@
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
 	return FALSE;
       break;
-    case arm_thumb_arm_v4t_stub_short_branch:
+    case arm_stub_short_branch_v4t_thumb_arm:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 8))
 	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
+	return FALSE;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 4))
 	return FALSE;
       break;
-    case arm_stub_pic_long_branch:
+    case arm_stub_long_branch_any_any_pic:
       if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
 	return FALSE;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
@@ -11702,6 +11724,32 @@
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
 	return FALSE;
       break;
+    case arm_stub_long_branch_v4t_arm_thumb_pic:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 16))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
+	return FALSE;
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 20))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 4))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
+	return FALSE;
+      break;
+    case arm_stub_long_branch_thumb_only_pic:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 16))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
+	return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
+	return FALSE;
+      break;
     default:
       BFD_FAIL ();
     }
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-call.d binutils-cvs/src/ld/testsuite/ld-arm/arm-call.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-call.d	2007-05-22 19:17:53.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/arm-call.d	2009-02-02 15:21:10.000000000 +0100
@@ -3,54 +3,54 @@
 
 Disassembly of section .text:
 
-00008000 <_start>:
-    8000:	eb00000d 	bl	803c <arm>
-    8004:	fa00000d 	blx	8040 <t1>
-    8008:	fb00000c 	blx	8042 <t2>
-    800c:	fb00000d 	blx	804a <t5>
-    8010:	fa00000a 	blx	8040 <t1>
-    8014:	fb000009 	blx	8042 <t2>
-    8018:	ea00000f 	b	805c <__t1_from_arm>
-    801c:	ea000010 	b	8064 <__t2_from_arm>
-    8020:	1b00000d 	blne	805c <__t1_from_arm>
-    8024:	1b00000e 	blne	8064 <__t2_from_arm>
-    8028:	1b000003 	blne	803c <arm>
-    802c:	eb000002 	bl	803c <arm>
-    8030:	faffffff 	blx	8034 <thumblocal>
-
-00008034 <thumblocal>:
-    8034:	4770      	bx	lr
-
-00008036 <t3>:
-    8036:	4770      	bx	lr
-
-00008038 <t4>:
-    8038:	4770      	bx	lr
-    803a:	46c0      	nop			\(mov r8, r8\)
-
-0000803c <arm>:
-    803c:	e12fff1e 	bx	lr
-
-00008040 <t1>:
-    8040:	4770      	bx	lr
-
-00008042 <t2>:
-    8042:	f7ff fff8 	bl	8036 <t3>
-    8046:	f7ff fff7 	bl	8038 <t4>
-
-0000804a <t5>:
-    804a:	f000 f801 	bl	8050 <local_thumb>
-    804e:	46c0      	nop			\(mov r8, r8\)
-
-00008050 <local_thumb>:
-    8050:	f7ff fff1 	bl	8036 <t3>
-    8054:	f7ff efd4 	blx	8000 <_start>
-    8058:	f7ff efd2 	blx	8000 <_start>
-
-0000805c <__t1_from_arm>:
-    805c:	e51ff004 	ldr	pc, \[pc, #-4\]	; 8060 <__t1_from_arm\+0x4>
-    8060:	00008041 	.word	0x00008041
-
-00008064 <__t2_from_arm>:
-    8064:	e51ff004 	ldr	pc, \[pc, #-4\]	; 8068 <__t2_from_arm\+0x4>
-    8068:	00008043 	.word	0x00008043
+00008000 <__t1_veneer>:
+    8000:	e51ff004 	ldr	pc, \[pc, #-4\]	; 8004 <__t1_veneer\+0x4>
+    8004:	00008051 	.word	0x00008051
+
+00008008 <__t2_veneer>:
+    8008:	e51ff004 	ldr	pc, \[pc, #-4\]	; 800c <__t2_veneer\+0x4>
+    800c:	00008053 	.word	0x00008053
+
+00008010 <_start>:
+    8010:	eb00000d 	bl	804c <arm>
+    8014:	fa00000d 	blx	8050 <t1>
+    8018:	fb00000c 	blx	8052 <t2>
+    801c:	fb00000d 	blx	805a <t5>
+    8020:	fa00000a 	blx	8050 <t1>
+    8024:	fb000009 	blx	8052 <t2>
+    8028:	eafffff4 	b	8000 <__t1_veneer>
+    802c:	eafffff5 	b	8008 <__t2_veneer>
+    8030:	1bfffff2 	blne	8000 <__t1_veneer>
+    8034:	1bfffff3 	blne	8008 <__t2_veneer>
+    8038:	1b000003 	blne	804c <arm>
+    803c:	eb000002 	bl	804c <arm>
+    8040:	faffffff 	blx	8044 <thumblocal>
+
+00008044 <thumblocal>:
+    8044:	4770      	bx	lr
+
+00008046 <t3>:
+    8046:	4770      	bx	lr
+
+00008048 <t4>:
+    8048:	4770      	bx	lr
+    804a:	46c0      	nop			\(mov r8, r8\)
+
+0000804c <arm>:
+    804c:	e12fff1e 	bx	lr
+
+00008050 <t1>:
+    8050:	4770      	bx	lr
+
+00008052 <t2>:
+    8052:	f7ff fff8 	bl	8046 <t3>
+    8056:	f7ff fff7 	bl	8048 <t4>
+
+0000805a <t5>:
+    805a:	f000 f801 	bl	8060 <local_thumb>
+    805e:	46c0      	nop			\(mov r8, r8\)
+
+00008060 <local_thumb>:
+    8060:	f7ff fff1 	bl	8046 <t3>
+    8064:	f7ff efd4 	blx	8010 <_start>
+    8068:	f7ff efd2 	blx	8010 <_start>
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' 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	2009-01-23 14:13:45.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/arm-elf.exp	2009-02-05 16:04:43.000000000 +0100
@@ -190,10 +190,6 @@
 # Exclude non-ARM-EABI targets.
 
 if { ![istarget "arm*-*-*eabi"] } {
-    # Special variants of these tests, as no farcall stub is generated
-    # for a non-ARM-EABI target
-    run_dump_test "thumb2-bl-as-thumb1-bad-noeabi"
-    run_dump_test "thumb2-bl-bad-noeabi"
     return
 }
 
@@ -265,7 +261,7 @@
     {"ARM-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb-pic-veneer.d}}
      "farcall-arm-thumb-pic-veneer"}
-    {"ARM-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-arm-thumb.s}
+    {"ARM-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2002014 --pic-veneer" "-march=armv5t" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb-blx-pic-veneer.d}}
      "farcall-arm-thumb-blx-pic-veneer"}
 
@@ -275,9 +271,18 @@
     {"Thumb-Thumb farcall M profile" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv7m" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-m.d}}
      "farcall-thumb-thumb-m"}
+    {"Thumb-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv4t" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb.d}}
+     "farcall-thumb-thumb"}
     {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
      "farcall-thumb-thumb-blx-pic-veneer"}
+    {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7m" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb-m-pic-veneer.d}}
+     "farcall-thumb-thumb-m-pic-veneer"}
+    {"Thumb-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv4t" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb-pic-veneer.d}}
+     "farcall-thumb-thumb-pic-veneer"}
 
     {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
@@ -291,6 +296,9 @@
     {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
      "farcall-thumb-arm-blx-pic-veneer"}
+    {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
+     {{objdump -d farcall-thumb-arm-pic-veneer.d}}
+     "farcall-thumb-arm-pic-veneer"}
 
     {"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" {farcall-mix.s}
      {{objdump -d farcall-mix.d}}
@@ -305,6 +313,28 @@
     {"Group size=2" "-Ttext 0x1000 --section-start .foo=0x2003020 --stub-group-size=2" "" {farcall-group.s farcall-group2.s}
      {{objdump -d farcall-group-size2.d}}
      "farcall-group-size2"}
+
+    {"Thumb shared library with ARM entry points and farcalls" "-shared -T farcall-arm-lib.ld" "-mthumb-interwork"
+     {farcall-mixed-lib.s}
+     {{objdump -fdw farcall-armthumb-lib.d} {readelf -Ds farcall-armthumb-lib.sym}}
+     "farcall-armthumb-lib.so"}
+    {"Mixed ARM/Thumb dynamic application with farcalls" "tmpdir/farcall-mixed-lib.so -T farcall-arm-dyn.ld --section-start .far_arm=0x2100000 --section-start .far_thumb=0x2200000" ""
+     {farcall-mixed-app.s}
+     {{objdump -fdw farcall-mixed-app.d} {objdump -Rw farcall-mixed-app.r}
+      {readelf -Ds farcall-mixed-app.sym}}
+     "farcall-mixed-app"}
+
+    {"Mixed ARM/Thumb shared library and farcalls" "-shared -T farcall-arm-lib.ld -use-blx" ""
+     {farcall-mixed-lib.s}
+     {{objdump -fdw farcall-mixed-lib.d} {objdump -Rw farcall-mixed-lib.r}
+      {readelf -Ds farcall-mixed-lib.sym}}
+     "farcall-mixed-lib.so"}
+    {"Mixed ARM/Thumb arch5 dynamic application with farcalls" "tmpdir/farcall-mixed-lib.so -T farcall-arm-dyn.ld --use-blx --section-start .far_arm=0x2100000 --section-start .far_thumb=0x2200000" ""
+     {farcall-mixed-app.s}
+     {{objdump -fdw farcall-mixed-app-v5.d} {objdump -Rw farcall-mixed-app.r}
+      {readelf -Ds farcall-mixed-app.sym}}
+     "farcall-mixed-app-v5"}
+
 }
 
 run_ld_link_tests $armeabitests
@@ -326,10 +356,6 @@
 run_dump_test "attr-merge-wchar-40-nowarn"
 run_dump_test "attr-merge-wchar-42-nowarn"
 run_dump_test "attr-merge-wchar-44-nowarn"
-run_dump_test "farcall-thumb-thumb"
-run_dump_test "farcall-thumb-thumb-pic-veneer"
-run_dump_test "farcall-thumb-thumb-m-pic-veneer"
-run_dump_test "farcall-thumb-arm-pic-veneer"
 run_dump_test "farcall-section"
 run_dump_test "attr-merge-unknown-1"
 run_dump_test "attr-merge-unknown-2"
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/arm-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-pic-veneer.d	2007-05-22 19:17:53.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/arm-pic-veneer.d	2009-02-02 15:27:05.000000000 +0100
@@ -3,15 +3,15 @@
 
 Disassembly of section .text:
 
-00008000 <_start>:
-    8000:	ea000000 	b	8008 <__foo_from_arm>
+00008000 <__foo_veneer>:
+    8000:	e59fc004 	ldr	ip, \[pc, #4\]	; 800c <__foo_veneer\+0xc>
+    8004:	e08cc00f 	add	ip, ip, pc
+    8008:	e12fff1c 	bx	ip
+    800c:	00000009 	.word	0x00000009
 
-00008004 <foo>:
-    8004:	46c0      	nop			\(mov r8, r8\)
-    8006:	4770      	bx	lr
+00008010 <_start>:
+    8010:	eafffffa 	b	8000 <__foo_veneer>
 
-00008008 <__foo_from_arm>:
-    8008:	e59fc004 	ldr	ip, \[pc, #4\]	; 8014 <__foo_from_arm\+0xc>
-    800c:	e08cc00f 	add	ip, ip, pc
-    8010:	e12fff1c 	bx	ip
-    8014:	fffffff1 	.word	0xfffffff1
+00008014 <foo>:
+    8014:	46c0      	nop			\(mov r8, r8\)
+    8016:	4770      	bx	lr
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-pic-veneer.s binutils-cvs/src/ld/testsuite/ld-arm/arm-pic-veneer.s
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/arm-pic-veneer.s	2007-03-20 21:19:07.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/arm-pic-veneer.s	2009-02-02 14:42:28.000000000 +0100
@@ -1,14 +1,14 @@
-.text
-.arm
-.global _start
-.type _start, %function
+	.text
+	.arm
+	.global _start
+	.type _start, %function
 _start:
-b foo
+	b foo
 
-.thumb
-.global foo
-.type foo, %function
+	.thumb
+	.global foo
+	.type foo, %function
 foo:
-nop
-bx lr
+	nop
+	bx lr
 
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-arm-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-arm-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-arm-pic-veneer.d	2008-06-25 16:28:48.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-arm-pic-veneer.d	2009-02-04 11:42:59.000000000 +0100
@@ -5,7 +5,7 @@
 00001000 <__bar_veneer>:
     1000:	e59fc000 	ldr	ip, \[pc, #0\]	; 1008 <__bar_veneer\+0x8>
     1004:	e08ff00c 	add	pc, pc, ip
-    1008:	02000018 	.word	0x02000018
+    1008:	02000014 	.word	0x02000014
     100c:	00000000 	.word	0x00000000
 
 00001010 <_start>:
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-dyn.ld binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-dyn.ld
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-dyn.ld	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-dyn.ld	2009-01-28 10:51:14.000000000 +0100
@@ -0,0 +1,194 @@
+/* Script for -z combreloc: combine and sort reloc sections */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = 0x8000); . = 0x8000;
+  .interp         : { *(.interp) }
+  .hash           : { *(.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.dyn        :
+    {
+      *(.rel.init)
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+      *(.rel.fini)
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+      *(.rel.data.rel.ro*)
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+      *(.rel.ctors)
+      *(.rel.dtors)
+      *(.rel.got)
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+    }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+    }
+  .rel.plt        : { *(.rel.plt) }
+  .rela.plt       : { *(.rela.plt) }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0
+  .plt            : { *(.plt) }
+  .text           :
+  {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    KEEP (*(.text.*personality*))
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7)
+  } =0
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+   __exidx_start = .;
+  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+   __exidx_end = .;
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN (0x8000) - ((0x8000 - .) & (0x8000 - 1)); . = DATA_SEGMENT_ALIGN (0x8000, 0x1000);
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+  /* Thread Local Storage sections  */
+  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  /* Ensure the __preinit_array_start label is properly aligned.  We
+     could instead move the label definition inside the section, but
+     the linker would then create the section even if it turns out to
+     be empty, which isn't pretty.  */
+  . = ALIGN(32 / 8);
+  PROVIDE (__preinit_array_start = .);
+  .preinit_array     : { KEEP (*(.preinit_array)) }
+  PROVIDE (__preinit_array_end = .);
+  PROVIDE (__init_array_start = .);
+  .init_array     : { KEEP (*(.init_array)) }
+  PROVIDE (__init_array_end = .);
+  PROVIDE (__fini_array_start = .);
+  .fini_array     : { KEEP (*(.fini_array)) }
+  PROVIDE (__fini_array_end = .);
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin*.o(.ctors))
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin*.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got.plt) *(.got) }
+  .data           :
+  {
+    __data_start = . ;
+    *(.data .data.* .gnu.linkonce.d.*)
+    KEEP (*(.gnu.linkonce.d.*personality*))
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  _edata = .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  __bss_start__ = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.  */
+   . = ALIGN(32 / 8);
+  }
+  . = ALIGN(32 / 8);
+  _end = .;
+  _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+  PROVIDE (end = .);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  /DISCARD/ : { *(.note.GNU-stack) }
+}
+
+
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-lib.ld binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-lib.ld
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-lib.ld	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-lib.ld	2009-01-28 10:48:14.000000000 +0100
@@ -0,0 +1,187 @@
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0 + SIZEOF_HEADERS;
+  .hash           : { *(.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.dyn        :
+    {
+      *(.rel.init)
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+      *(.rel.fini)
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+      *(.rel.data.rel.ro*)
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+      *(.rel.ctors)
+      *(.rel.dtors)
+      *(.rel.got)
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+    }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+    }
+  .rel.plt        : { *(.rel.plt) }
+  .rela.plt       : { *(.rela.plt) }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0
+  .plt            : { *(.plt) }
+  .text           :
+  {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    KEEP (*(.text.*personality*))
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7)
+  } =0
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+   __exidx_start = .;
+  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+   __exidx_end = .;
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN (0x8000) - ((0x8000 - .) & (0x8000 - 1)); . = DATA_SEGMENT_ALIGN (0x8000, 0x1000);
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+  /* Thread Local Storage sections  */
+  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  /* Ensure the __preinit_array_start label is properly aligned.  We
+     could instead move the label definition inside the section, but
+     the linker would then create the section even if it turns out to
+     be empty, which isn't pretty.  */
+  . = ALIGN(32 / 8);
+  .preinit_array     : { KEEP (*(.preinit_array)) }
+  .init_array     : { KEEP (*(.init_array)) }
+  .fini_array     : { KEEP (*(.fini_array)) }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin*.o(.ctors))
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin*.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got.plt) *(.got) }
+  .data           :
+  {
+    __data_start = . ;
+    *(.data .data.* .gnu.linkonce.d.*)
+    KEEP (*(.gnu.linkonce.d.*personality*))
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  _edata = .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  __bss_start__ = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.  */
+   . = ALIGN(32 / 8);
+  }
+  . = ALIGN(32 / 8);
+  _end = .;
+  _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+  PROVIDE (end = .);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  /DISCARD/ : { *(.note.GNU-stack) }
+}
+
+
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-thumb-blx-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-thumb-blx-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-thumb-blx-pic-veneer.d	2008-06-25 16:28:48.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-thumb-blx-pic-veneer.d	2009-02-04 11:44:52.000000000 +0100
@@ -5,12 +5,12 @@
 00001000 <__bar_from_arm>:
     1000:	e59fc000 	ldr	ip, \[pc, #0\]	; 1008 <__bar_from_arm\+0x8>
     1004:	e08ff00c 	add	pc, pc, ip
-    1008:	0200000d 	.word	0x0200000d
+    1008:	02001009 	.word	0x02001009
     100c:	00000000 	.word	0x00000000
 
 00001010 <_start>:
     1010:	ebfffffa 	bl	1000 <__bar_from_arm>
 Disassembly of section .foo:
 
-02001014 <bar>:
- 2001014:	4770      	bx	lr
+02002014 <bar>:
+ 2002014:	4770      	bx	lr
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-thumb-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-thumb-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-arm-thumb-pic-veneer.d	2008-06-25 16:28:48.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-arm-thumb-pic-veneer.d	2009-02-02 15:40:05.000000000 +0100
@@ -3,10 +3,10 @@
 Disassembly of section .text:
 
 00001000 <__bar_from_arm>:
-    1000:	e59fc000 	ldr	ip, \[pc, #0\]	; 1008 <__bar_from_arm\+0x8>
-    1004:	e08ff00c 	add	pc, pc, ip
-    1008:	0200000d 	.word	0x0200000d
-    100c:	00000000 	.word	0x00000000
+    1000:	e59fc004 	ldr	ip, \[pc, #4\]	; 100c <__bar_from_arm\+0xc>
+    1004:	e08cc00f 	add	ip, ip, pc
+    1008:	e12fff1c 	bx	ip
+    100c:	02000009 	.word	0x02000009
 
 00001010 <_start>:
     1010:	ebfffffa 	bl	1000 <__bar_from_arm>
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-armthumb-lib.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-armthumb-lib.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-armthumb-lib.d	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-armthumb-lib.d	2009-01-28 14:48:39.000000000 +0100
@@ -0,0 +1,44 @@
+
+tmpdir/farcall-armthumb-lib.so:     file format elf32-(little|big)arm
+architecture: arm, flags 0x00000150:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*:	e52de004 	push	{lr}		; \(str lr, \[sp, #-4\]!\)
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <lib_func1-0x1.>
+ .*:	e08fe00e 	add	lr, pc, lr
+ .*:	e5bef008 	ldr	pc, \[lr, #8\]!
+ .*:	.*
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+Disassembly of section .text:
+
+.* <lib_func1>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebfffff. 	bl	.* <lib_func1-0x..?>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <__real_lib_func2>:
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+
+.* <lib_func2>:
+ .*:	e59fc004 	ldr	ip, \[pc, #4\]	; .* <lib_func2\+0xc>
+ .*:	e08cc00f 	add	ip, ip, pc
+ .*:	e12fff1c 	bx	ip
+ .*:	ffffffe5 	.*
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-armthumb-lib.sym binutils-cvs/src/ld/testsuite/ld-arm/farcall-armthumb-lib.sym
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-armthumb-lib.sym	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-armthumb-lib.sym	2009-01-28 10:47:47.000000000 +0100
@@ -0,0 +1,17 @@
+
+Symbol table for image:
+  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _edata
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_start__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _end
+   ..  ..: ........     4  OBJECT GLOBAL DEFAULT   9 data_obj
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_end__
+   ..  ..: .......0    20    FUNC GLOBAL DEFAULT   6 lib_func1
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __exidx_start
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT   9 __data_start
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __end__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_start
+   ..  ..: 00000000     0  NOTYPE GLOBAL DEFAULT UND app_func2
+   ..  ..: .......0     2    FUNC GLOBAL DEFAULT   6 lib_func2
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _bss_end__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __exidx_end
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app-v5.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app-v5.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app-v5.d	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app-v5.d	2009-01-28 17:52:27.000000000 +0100
@@ -0,0 +1,85 @@
+
+tmpdir/farcall-mixed-app-v5:     file format elf32-(little|big)arm
+architecture: arm, flags 0x00000112:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*:	e52de004 	push	{lr}		; \(str lr, \[sp, #-4\]!\)
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <__app_func_veneer-0x24>
+ .*:	e08fe00e 	add	lr, pc, lr
+ .*:	e5bef008 	ldr	pc, \[lr, #8\]!
+ .*:	.*
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+
+Disassembly of section .text:
+
+.* <__app_func_veneer>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; .* <__app_func_veneer\+0x4>
+ .*:	02100010 	.word	0x02100010
+	...
+
+.* <_start>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebfffff8 	bl	.* <__app_func_veneer>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_tfunc_close>:
+ .*:	b500      	push	{lr}
+ .*:	f7ff efd6 	blx	.* <__app_func_veneer-0x20>
+ .*:	bd00      	pop	{pc}
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+
+Disassembly of section .far_arm:
+
+.* <__lib_func1_veneer>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2100004 <__lib_func1_veneer\+0x4>
+ .*:	0000822c 	.word	0x0000822c
+	...
+
+.* <app_func>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebfffff. 	bl	.* <__lib_func1_veneer>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_func2>:
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+Disassembly of section .far_thumb:
+
+.* <__lib_func2_from_thumb>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2200004 <__lib_func2_from_thumb\+0x4>
+ .*:	00008220 	.word	0x00008220
+	...
+
+.* <app_tfunc>:
+ .*:	b500      	push	{lr}
+ .*:	f7ff eff6 	blx	.* <__lib_func2_from_thumb>
+ .*:	bd00      	pop	{pc}
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.d	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.d	2009-01-28 17:36:18.000000000 +0100
@@ -0,0 +1,92 @@
+
+tmpdir/farcall-mixed-app:     file format elf32-(little|big)arm
+architecture: arm, flags 0x00000112:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*:	e52de004 	push	{lr}		; \(str lr, \[sp, #-4\]!\)
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <__app_func_veneer-0x24>
+ .*:	e08fe00e 	add	lr, pc, lr
+ .*:	e5bef008 	ldr	pc, \[lr, #8\]!
+ .*:	.*
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+
+Disassembly of section .text:
+
+.* <__app_func_veneer>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 8244 <__app_func_veneer\+0x4>
+ .*:	02100010 	.word	0x02100010
+	...
+
+.* <_start>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebfffff8 	bl	.* <__app_func_veneer>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_tfunc_close>:
+ .*:	b500      	push	{lr}
+ .*:	f7ff ffd5 	bl	8220 <__app_func_veneer-0x20>
+ .*:	bd00      	pop	{pc}
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+
+Disassembly of section .far_arm:
+
+.* <__lib_func1_veneer>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2100004 <__lib_func1_veneer\+0x4>
+ .*:	00008230 	.word	0x00008230
+	...
+
+.* <app_func>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebffff.. 	bl	.* <__lib_func1_veneer>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_func2>:
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+Disassembly of section .far_thumb:
+
+.* <__lib_func2_from_thumb>:
+ .*:	b540      	push	{r6, lr}
+ .*:	4e03      	ldr	r6, \[pc, #12\]	\(2200010 <__lib_func2_from_thumb\+0x10>\)
+ .*:	46fe      	mov	lr, pc
+ .*:	4730      	bx	r6
+ .*:	e8bd4040 	pop	{r6, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	00008224 	.word	0x00008224
+	...
+
+.* <app_tfunc>:
+ .*:	b500      	push	{lr}
+ .*:	f7ff ffed 	bl	.* <__lib_func2_from_thumb>
+ .*:	bd00      	pop	{pc}
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.r binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.r
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.r	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.r	2009-01-28 17:37:42.000000000 +0100
@@ -0,0 +1,10 @@
+
+tmpdir/farcall-mixed-app.*:     file format elf32-(little|big)arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+.* R_ARM_COPY        data_obj
+.* R_ARM_JUMP_SLOT   lib_func2
+.* R_ARM_JUMP_SLOT   lib_func1
+
+
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.s binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.s
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.s	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.s	2009-02-02 15:42:30.000000000 +0100
@@ -0,0 +1,61 @@
+	.text
+	.p2align 4
+	.globl _start
+_start:
+	mov	ip, sp
+	stmdb	sp!, {r11, ip, lr, pc}
+	bl	app_func
+	ldmia	sp, {r11, sp, lr}
+	bx lr
+
+	.p2align 4
+	.globl app_tfunc_close
+	.type app_tfunc_close,%function
+	.thumb_func
+	.code 16
+app_tfunc_close:
+	push	{lr}
+	bl	lib_func2
+	pop	{pc}
+	bx	lr
+
+@ We will place the section .far_arm at 0x2100000.
+	.section .far_arm, "xa"
+
+	.arm
+	.p2align 4
+	.globl app_func
+	.type app_func,%function
+app_func:
+	mov	ip, sp
+	stmdb	sp!, {r11, ip, lr, pc}
+	bl	lib_func1
+	ldmia	sp, {r11, sp, lr}
+	bx lr
+
+	.arm
+	.p2align 4
+	.globl app_func2
+	.type app_func2,%function
+app_func2:
+	bx	lr
+	nop
+	nop
+	nop
+
+@ We will place the section .far_thumb at 0x2200000.
+	.section .far_thumb, "xa"
+
+	.p2align 4
+	.globl app_tfunc
+	.type app_tfunc,%function
+	.thumb_func
+	.code 16
+app_tfunc:
+	push	{lr}
+	bl	lib_func2
+	pop	{pc}
+	bx	lr
+
+	.data
+	.long data_obj
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.sym binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.sym
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-app.sym	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-app.sym	2009-01-28 17:40:06.000000000 +0100
@@ -0,0 +1,17 @@
+
+Symbol table for image:
+  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _edata
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_start__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _end
+   ..  ..: ........     4  OBJECT GLOBAL DEFAULT  12 data_obj
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_end__
+   ..  ..: 0*[^0]*.*    0    FUNC GLOBAL DEFAULT UND lib_func1
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __exidx_start
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT  11 __data_start
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __end__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_start
+   ..  ..: .......0     0    FUNC GLOBAL DEFAULT  14 app_func2
+   ..  ..: 0*[^0]*.*    0    FUNC GLOBAL DEFAULT UND lib_func2
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _bss_end__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __exidx_end
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.d	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.d	2009-01-28 11:17:59.000000000 +0100
@@ -0,0 +1,38 @@
+
+tmpdir/farcall-mixed-lib.so:     file format elf32-(little|big)arm
+architecture: arm, flags 0x00000150:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*:	e52de004 	push	{lr}		; \(str lr, \[sp, #-4\]!\)
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <lib_func1-0x.*>
+ .*:	e08fe00e 	add	lr, pc, lr
+ .*:	e5bef008 	ldr	pc, \[lr, #8\]!
+ .*:	.*
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+Disassembly of section .text:
+
+.* <lib_func1>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebfffff. 	bl	.* <lib_func1-0x..?>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <lib_func2>:
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.r binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.r
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.r	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.r	2009-01-28 13:45:09.000000000 +0100
@@ -0,0 +1,8 @@
+
+tmpdir/farcall-mixed-lib.so:     file format elf32-(little|big)arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+.* R_ARM_JUMP_SLOT   app_func2
+
+
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.s binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.s
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.s	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.s	2009-01-28 10:43:44.000000000 +0100
@@ -0,0 +1,28 @@
+	.text
+
+	.p2align 4
+	.globl lib_func1
+	.type lib_func1, %function
+lib_func1:
+	mov	ip, sp
+	stmdb	sp!, {r11, ip, lr, pc}
+	bl	app_func2
+	ldmia	sp, {r11, sp, lr}
+	bx lr
+	.size lib_func1, . - lib_func1
+
+	.p2align 4
+	.globl lib_func2
+	.type lib_func2, %function
+	.thumb_func
+	.code 16
+lib_func2:
+	bx lr
+	.size lib_func2, . - lib_func2
+
+	.data
+	.globl data_obj
+	.type data_obj, %object
+data_obj:
+	.long 0
+	.size data_obj, . - data_obj
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.sym binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.sym
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-mixed-lib.sym	1970-01-01 01:00:00.000000000 +0100
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-mixed-lib.sym	2009-01-28 10:53:43.000000000 +0100
@@ -0,0 +1,17 @@
+
+Symbol table for image:
+  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _edata
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_start__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _end
+   ..  ..: ........     4  OBJECT GLOBAL DEFAULT   9 data_obj
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_end__
+   ..  ..: .......0    20    FUNC GLOBAL DEFAULT   6 lib_func1
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __exidx_start
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT   9 __data_start
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __end__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __bss_start
+   ..  ..: 00000000     0  NOTYPE GLOBAL DEFAULT UND app_func2
+   ..  ..: .......1     2    FUNC GLOBAL DEFAULT   6 lib_func2
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS _bss_end__
+   ..  ..: ........     0  NOTYPE GLOBAL DEFAULT ABS __exidx_end
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d	2008-06-25 16:28:48.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d	2009-02-04 11:49:42.000000000 +0100
@@ -5,7 +5,7 @@
 00001000 <__bar_from_thumb>:
     1000:	e59fc000 	ldr	ip, \[pc, #0\]	; 1008 <__bar_from_thumb\+0x8>
     1004:	e08ff00c 	add	pc, pc, ip
-    1008:	0200000c 	.word	0x0200000c
+    1008:	02000008 	.word	0x02000008
     100c:	00000000 	.word	0x00000000
 
 00001010 <_start>:
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d	2008-05-15 19:00:15.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d	2009-02-04 13:24:45.000000000 +0100
@@ -1,5 +1,19 @@
-#name: Thumb-Thumb farcall without BLX
-#source: farcall-thumb-thumb.s
-#as: -march=armv4t
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <__bar_from_thumb>:
+    1000:	4778      	bx	pc
+    1002:	46c0      	nop			\(mov r8, r8\)
+    1004:	e59fc004 	ldr	ip, \[pc, #4\]	; 1010 <__bar_from_thumb\+0x10>
+    1008:	e08cc00f 	add	ip, ip, pc
+    100c:	e1a0f00c 	mov	pc, ip
+    1010:	02000004 	.word	0x02000004
+    1014:	00000000 	.word	0x00000000
+
+00001018 <_start>:
+    1018:	f7ff fff2 	bl	1000 <__bar_from_thumb>
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:	e12fff1e 	bx	lr
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-blx-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-blx-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-blx-pic-veneer.d	2008-06-25 16:28:48.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-blx-pic-veneer.d	2009-02-04 11:45:31.000000000 +0100
@@ -5,7 +5,7 @@
 00001000 <__bar_veneer>:
     1000:	e59fc000 	ldr	ip, \[pc, #0\]	; 1008 <__bar_veneer\+0x8>
     1004:	e08ff00c 	add	pc, pc, ip
-    1008:	0200000d 	.word	0x0200000d
+    1008:	02000009 	.word	0x02000009
     100c:	00000000 	.word	0x00000000
 
 00001010 <_start>:
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d	2008-05-15 19:00:15.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d	2009-02-04 11:57:49.000000000 +0100
@@ -1,5 +1,19 @@
-#name: Thumb-Thumb farcall without BLX
-#source: farcall-thumb-thumb.s
-#as: -march=armv4t
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <__bar_veneer>:
+    1000:	b540      	push	{r6, lr}
+    1002:	4e02      	ldr	r6, \[pc, #8\]	\(100c <__bar_veneer\+0xc>\)
+    1004:	46fe      	mov	lr, pc
+    1006:	44b7      	add	pc, r6
+    1008:	bd40      	pop	{r6, pc}
+    100a:	bf00      	nop
+    100c:	0200000b 	.word	0x0200000b
+
+00001010 <_start>:
+    1010:	f7ff fff6 	bl	1000 <__bar_veneer>
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:	4770      	bx	lr
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d	2008-06-25 16:28:48.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d	2009-02-03 10:08:52.000000000 +0100
@@ -6,7 +6,7 @@
     1000:	b540      	push	{r6, lr}
     1002:	4e02      	ldr	r6, \[pc, #8\]	\(100c <__bar_veneer\+0xc>\)
     1004:	46fe      	mov	lr, pc
-    1006:	4730      	bx	r6
+    1006:	46b7      	mov	pc, r6
     1008:	bd40      	pop	{r6, pc}
     100a:	bf00      	nop
     100c:	02001015 	.word	0x02001015
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d	2008-05-15 19:00:15.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d	2009-02-04 12:01:03.000000000 +0100
@@ -1,5 +1,19 @@
-#name: Thumb-Thumb farcall without BLX
-#source: farcall-thumb-thumb.s
-#as: -march=armv4t
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <__bar_veneer>:
+    1000:	b540      	push	{r6, lr}
+    1002:	4e02      	ldr	r6, \[pc, #8\]	\(100c <__bar_veneer\+0xc>\)
+    1004:	46fe      	mov	lr, pc
+    1006:	44b7      	add	pc, r6
+    1008:	bd40      	pop	{r6, pc}
+    100a:	bf00      	nop
+    100c:	0200000b 	.word	0x0200000b
+
+00001010 <_start>:
+    1010:	f7ff fff6 	bl	1000 <__bar_veneer>
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:	4770      	bx	lr
diff -uN -r --exclude=CVS --exclude='*~' --exclude='.#*' binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb.d binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb.d
--- binutils-cvs-ref/src/ld/testsuite/ld-arm/farcall-thumb-thumb.d	2008-05-15 19:00:15.000000000 +0200
+++ binutils-cvs/src/ld/testsuite/ld-arm/farcall-thumb-thumb.d	2009-02-03 10:09:19.000000000 +0100
@@ -1,5 +1,19 @@
-#name: Thumb-Thumb farcall without BLX
-#source: farcall-thumb-thumb.s
-#as: -march=armv4t
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <__bar_veneer>:
+    1000:	b540      	push	{r6, lr}
+    1002:	4e02      	ldr	r6, \[pc, #8\]	\(100c <__bar_veneer\+0xc>\)
+    1004:	46fe      	mov	lr, pc
+    1006:	46b7      	mov	pc, r6
+    1008:	bd40      	pop	{r6, pc}
+    100a:	bf00      	nop
+    100c:	02001015 	.word	0x02001015
+
+00001010 <_start>:
+    1010:	f7ff fff6 	bl	1000 <__bar_veneer>
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:	4770      	bx	lr
2009-02-04  Christophe Lyon  <christophe.lyon@st.com>

	PR 9743
	* ld-arm/arm-elf.exp (thumb2-bl-as-thumb1-bad-noeabi,
	thumb2-bl-bad-noeabi): Removed tests on non-EABI
	targets. (farcall-thumb-thumb, farcall-thumb-thumb-pic-veneer,
	farcall-thumb-thumb-m-pic-veneer, farcall-thumb-arm-pic-veneer):
	Updated as they now pass. (farcall-arm-thumb-blx-pic-veneer):
	Fixed. (farcall-armthumb-lib.so, farcall-mixed-app,
	farcall-mixed-lib.so, farcall-mixed-app-v5): New tests.
	* ld-arm/arm-call.d: Updated to expect new stub.
	* ld-arm/arm-pic-veneer.d: Likewise.
	* ld-arm/arm-pic-veneer.s: Fixed formatting.
	* ld-arm/farcall-arm-arm-pic-veneer.d: Fixed.
	* ld-arm/farcall-arm-dyn.ld: New file.
	* ld-arm/farcall-arm-lib.ld: New file.
	* ld-arm/farcall-arm-thumb-blx-pic-veneer.d: Fixed.
	* ld-arm/farcall-arm-thumb-pic-veneer.d: Fixed.
	* ld-arm/farcall-armthumb-lib.d: New file.
	* ld-arm/farcall-armthumb-lib.sym: New file.
	* ld-arm/farcall-mixed-app-v5.d: New file.
	* ld-arm/farcall-mixed-app.d: New file.
	* ld-arm/farcall-mixed-app.r: New file.
	* ld-arm/farcall-mixed-app.s: New file.
	* ld-arm/farcall-mixed-app.sym: New file.
	* ld-arm/farcall-mixed-lib.d: New file.
	* ld-arm/farcall-mixed-lib.r: New file.
	* ld-arm/farcall-mixed-lib.s: New file.
	* ld-arm/farcall-mixed-lib.sym: New file.
	* ld-arm/farcall-thumb-arm-blx-pic-veneer.d: Fixed.
	* ld-arm/farcall-thumb-arm-pic-veneer.d: Updated to expect new stub.
	* ld-arm/farcall-thumb-thumb-blx-pic-veneer.d: Fixed.
	* ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Updated to expect new stub.
	* ld-arm/farcall-thumb-thumb-m.d: Fixed.
	* ld-arm/farcall-thumb-thumb-pic-veneer.d: Updated to expect new stub.
	* ld-arm/farcall-thumb-thumb.d: Updated to expect new stub.
2009-02-04  Christophe Lyon  <christophe.lyon@st.com>

	PR 9743
	* elf32-arm.c (arm_long_branch_stub,
	arm_thumb_v4t_long_branch_stub,
	arm_thumb_thumb_long_branch_stub,
	arm_thumb_arm_v4t_long_branch_stub,
	arm_thumb_arm_v4t_short_branch_stub,
	arm_pic_long_branch_stub):
	Renamed to elf32_arm_stub_long_branch_any_any,
	elf32_arm_stub_long_branch_v4t_arm_thumb,
	elf32_arm_stub_long_branch_thumb_only,
	elf32_arm_stub_long_branch_v4t_thumb_arm,
	elf32_arm_stub_short_branch_v4t_thumb_arm,
	elf32_arm_stub_long_branch_any_any_pic.
	(elf32_arm_stub_long_branch_v4t_arm_thumb_pic,
	elf32_arm_stub_long_branch_v4t_thumb_arm_pic,
	elf32_arm_stub_long_branch_thumb_only_pic): Define new stubs.
	(arm_stub_long_branch, 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):
	Renamed to arm_stub_long_branch_any_any,
	arm_stub_long_branch_v4t_arm_thumb,
	arm_stub_long_branch_thumb_only,
	arm_stub_long_branch_v4t_thumb_arm,
	arm_stub_short_branch_v4t_thumb_arm,
	arm_stub_long_branch_any_any_pic.
	(arm_stub_long_branch_v4t_arm_thumb_pic,
	arm_stub_long_branch_v4t_thumb_arm_pic,
	arm_stub_long_branch_thumb_only_pic): Define.
	(elf32_arm_stub_long_branch_thumb_only): Fixed stub code.
	(arm_stub_is_thumb): Handle new cases.
	(arm_type_of_stub): Handle R_ARM_THM_JUMP24, R_ARM_JUMP24,
	R_ARM_PLT32 relocations and calls through PLT.
	(arm_build_one_stub): Handle new stubs. Fix handling of
	arm_stub_long_branch_any_any_pic.
	(elf32_arm_size_stubs): Handle R_ARM_THM_JUMP24, R_ARM_JUMP24,
	R_ARM_PLT32 relocations. Use new arm_type_of_stub prototype.
	(record_thumb_to_arm_glue): Remove now unused function.
	(bfd_elf32_arm_process_before_allocation): Stop handling
	R_ARM_THM_JUMP24, R_ARM_JUMP24, R_ARM_PLT32 relocations.
	(elf32_arm_final_link_relocate): Handle calls through PLT too far away.
	(arm_map_one_stub): Added missing Thumb map symbol in
	arm_stub_short_branch_v4t_thumb_arm stub. Handle new stubs.

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