public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* ARM stub sizing fix
@ 2010-01-14 11:55 Alan Modra
  2010-01-14 14:10 ` Daniel Jacobowitz
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Modra @ 2010-01-14 11:55 UTC (permalink / raw)
  To: binutils

This patch fixes a problem with stub sizing in the ARM backend.  I
started looking at this when I became curious about PR 10409, but I
now suspect that PR was fixed by Nathan's 2009-08-05 elf32-arm.c
patch.

The problem is due to the ARM backend creating stubs based only on the
destination symbol (also on input section stub group and reloc addend,
but within a single stub group you basically have only one stub per
destination);  We don't get multiple stubs if one branch to a
particular destination requires a different type of stub to that
required on another branch to the same destination.  However, the code
in arm_type_of_stub clearly returns stub types that depend on branch
offset and reloc type.  You could easily have both a
short_branch_v4t_thumb_arm and a long_branch_v4t_thumb_arm to the same
destination, with sorry results if the short version happened to be
created first.  Also, addition of stubs for one iteration of stub
sizing may cause a stub that was initially a
short_branch_v4t_thumb_arm to become a long_branch_v4t_thumb_arm on
the next iteration.  Fixed by updating existing stub_type for this
case.

I also add an assert that will trigger if there is a dependence on
reloc type.  I don't know enough about ARM code to know whether it's
possible to have, say, one branch to a function using R_ARM_THM_CALL
and another using R_ARM_THM_JUMP24 (possible tail call?).

OK to apply?

	* elf32-arm.c (arm_type_of_stub): Wrap overlong lines.
	(cortex_a8_erratum_scan): Fix uninitialised warning.
	(elf32_arm_size_stubs): Check and update stub_type in existing stubs.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.218
diff -u -p -r1.218 elf32-arm.c
--- bfd/elf32-arm.c	28 Dec 2009 18:55:16 -0000	1.218
+++ bfd/elf32-arm.c	14 Jan 2010 08:36:37 -0000
@@ -3075,7 +3075,9 @@ arm_type_of_stub (struct bfd_link_info *
   r_type = ELF32_R_TYPE (rel->r_info);
 
   /* Keep a simpler condition, for the sake of clarity.  */
-  if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)
+  if (globals->splt != NULL
+      && hash != NULL
+      && hash->root.plt.offset != (bfd_vma) -1)
     {
       use_plt = 1;
       /* Note when dealing with PLT entries: the main PLT stub is in
@@ -3181,7 +3183,9 @@ arm_type_of_stub (struct bfd_link_info *
 	    }
 	}
     }
-  else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
+  else if (r_type == R_ARM_CALL
+	   || r_type == R_ARM_JUMP24
+	   || r_type == R_ARM_PLT32)
     {
       if (st_type == STT_ARM_TFUNC)
 	{
@@ -4022,7 +4026,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
 		  && last_was_32bit
 		  && ! last_was_branch)
                 {
-                  bfd_signed_vma offset;
+                  bfd_signed_vma offset = 0;
                   bfd_boolean force_target_arm = FALSE;
 		  bfd_boolean force_target_thumb = FALSE;
                   bfd_vma target;
@@ -4528,6 +4532,16 @@ elf32_arm_size_stubs (bfd *output_bfd,
 			  /* The proper stub has already been created.  */
 			  free (stub_name);
 			  stub_entry->target_value = sym_value;
+			  if (stub_entry->stub_type
+			      == arm_stub_short_branch_v4t_thumb_arm
+			      && (stub_type
+				  == arm_stub_long_branch_v4t_thumb_arm))
+			    {
+			      stub_entry->stub_type = stub_type;
+			      stub_changed = TRUE;
+			    }
+			  else
+			    BFD_ASSERT (stub_entry->stub_type == stub_type);
 			  break;
 			}
 

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 11:55 ARM stub sizing fix Alan Modra
@ 2010-01-14 14:10 ` Daniel Jacobowitz
  2010-01-14 14:47   ` Alan Modra
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Jacobowitz @ 2010-01-14 14:10 UTC (permalink / raw)
  To: binutils

On Thu, Jan 14, 2010 at 10:25:28PM +1030, Alan Modra wrote:
> required on another branch to the same destination.  However, the code
> in arm_type_of_stub clearly returns stub types that depend on branch
> offset and reloc type.  You could easily have both a
> short_branch_v4t_thumb_arm and a long_branch_v4t_thumb_arm to the same
> destination, with sorry results if the short version happened to be
> created first.  Also, addition of stubs for one iteration of stub

I think this is a bug in arm_type_of_stub.  short_branch_v4t_thumb_arm
and long_branch_v4t_thumb_arm are the same type of stub, based on how
far the destination is from the stub.  So I think the branch_offset
check is the wrong thing.

We're picking the stub type before we know where the stub ends up.  I
think we have to give the two the same type, but distinguish in
find_stub_size_and_template.

> I also add an assert that will trigger if there is a dependence on
> reloc type.  I don't know enough about ARM code to know whether it's
> possible to have, say, one branch to a function using R_ARM_THM_CALL
> and another using R_ARM_THM_JUMP24 (possible tail call?).

You're right, that's just a normal and tail call to the same function.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 14:10 ` Daniel Jacobowitz
@ 2010-01-14 14:47   ` Alan Modra
  2010-01-14 15:11     ` Daniel Jacobowitz
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Modra @ 2010-01-14 14:47 UTC (permalink / raw)
  To: binutils

On Thu, Jan 14, 2010 at 09:10:19AM -0500, Daniel Jacobowitz wrote:
> On Thu, Jan 14, 2010 at 10:25:28PM +1030, Alan Modra wrote:
> > I also add an assert that will trigger if there is a dependence on
> > reloc type.  I don't know enough about ARM code to know whether it's
> > possible to have, say, one branch to a function using R_ARM_THM_CALL
> > and another using R_ARM_THM_JUMP24 (possible tail call?).
> 
> You're right, that's just a normal and tail call to the same function.

So the code is quite broken for thumb.  You'll end up using the same
stub for both the call and the tail call.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 14:47   ` Alan Modra
@ 2010-01-14 15:11     ` Daniel Jacobowitz
  2010-01-14 15:34       ` Alan Modra
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Jacobowitz @ 2010-01-14 15:11 UTC (permalink / raw)
  To: binutils

On Fri, Jan 15, 2010 at 01:17:08AM +1030, Alan Modra wrote:
> On Thu, Jan 14, 2010 at 09:10:19AM -0500, Daniel Jacobowitz wrote:
> > On Thu, Jan 14, 2010 at 10:25:28PM +1030, Alan Modra wrote:
> > > I also add an assert that will trigger if there is a dependence on
> > > reloc type.  I don't know enough about ARM code to know whether it's
> > > possible to have, say, one branch to a function using R_ARM_THM_CALL
> > > and another using R_ARM_THM_JUMP24 (possible tail call?).
> > 
> > You're right, that's just a normal and tail call to the same function.
> 
> So the code is quite broken for thumb.  You'll end up using the same
> stub for both the call and the tail call.

Why is that a problem?  The stubs are themselves tail calls.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 15:11     ` Daniel Jacobowitz
@ 2010-01-14 15:34       ` Alan Modra
  2010-01-14 19:48         ` Daniel Jacobowitz
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Modra @ 2010-01-14 15:34 UTC (permalink / raw)
  To: binutils

On Thu, Jan 14, 2010 at 10:11:47AM -0500, Daniel Jacobowitz wrote:
> Why is that a problem?  The stubs are themselves tail calls.

arm_type_of_stub wants to choose different stubs for the same
destination, depending on reloc type (see r_type ==R_ARM_THM_CALL) or
branch offset (arm_stub_long_branch_v4t_thumb_arm).  You don't get
different stubs.  You get just one stub per destination.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 15:34       ` Alan Modra
@ 2010-01-14 19:48         ` Daniel Jacobowitz
  2010-01-14 23:53           ` Alan Modra
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Jacobowitz @ 2010-01-14 19:48 UTC (permalink / raw)
  To: binutils

On Fri, Jan 15, 2010 at 02:03:42AM +1030, Alan Modra wrote:
> On Thu, Jan 14, 2010 at 10:11:47AM -0500, Daniel Jacobowitz wrote:
> > Why is that a problem?  The stubs are themselves tail calls.
> 
> arm_type_of_stub wants to choose different stubs for the same
> destination, depending on reloc type (see r_type ==R_ARM_THM_CALL) or
> branch offset (arm_stub_long_branch_v4t_thumb_arm).  You don't get
> different stubs.  You get just one stub per destination.

I see what you mean.  I guess there would have to be a little lattice;
we can't do bl/blx conversion on R_ARM_THM_JUMP24 since there's no
immediate bx to convert the branch to.  So the target of a tail call
must have a Thumb mode stub.

Yes, this is busted.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 19:48         ` Daniel Jacobowitz
@ 2010-01-14 23:53           ` Alan Modra
  2010-01-19 10:09             ` Christophe LYON
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Modra @ 2010-01-14 23:53 UTC (permalink / raw)
  To: binutils

On Thu, Jan 14, 2010 at 02:48:20PM -0500, Daniel Jacobowitz wrote:
> Yes, this is busted.

Easily fixed.  Breaks arm-call test due to different stub ordering,
but I'll leave fixing the testsuite to an ARM maintainer.

	* elf32-arm.c (arm_type_of_stub): Wrap overlong lines.
	(cortex_a8_erratum_scan): Fix uninitialised warning.
	(elf32_arm_stub_name): Add stub_type param.  Encode stub_type in name.
	Update all callers.
	(elf32_arm_get_stub_entry): Add stub_type param.  Update all callers.
	(elf32_arm_final_link_relocate): Call arm_type_of_stub to determine
	stub type, if any.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.218
diff -u -p -r1.218 elf32-arm.c
--- bfd/elf32-arm.c	28 Dec 2009 18:55:16 -0000	1.218
+++ bfd/elf32-arm.c	14 Jan 2010 23:33:09 -0000
@@ -3075,7 +3075,9 @@ arm_type_of_stub (struct bfd_link_info *
   r_type = ELF32_R_TYPE (rel->r_info);
 
   /* Keep a simpler condition, for the sake of clarity.  */
-  if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)
+  if (globals->splt != NULL
+      && hash != NULL
+      && hash->root.plt.offset != (bfd_vma) -1)
     {
       use_plt = 1;
       /* Note when dealing with PLT entries: the main PLT stub is in
@@ -3181,7 +3183,9 @@ arm_type_of_stub (struct bfd_link_info *
 	    }
 	}
     }
-  else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
+  else if (r_type == R_ARM_CALL
+	   || r_type == R_ARM_JUMP24
+	   || r_type == R_ARM_PLT32)
     {
       if (st_type == STT_ARM_TFUNC)
 	{
@@ -3245,31 +3249,34 @@ static char *
 elf32_arm_stub_name (const asection *input_section,
 		     const asection *sym_sec,
 		     const struct elf32_arm_link_hash_entry *hash,
-		     const Elf_Internal_Rela *rel)
+		     const Elf_Internal_Rela *rel,
+		     enum elf32_arm_stub_type stub_type)
 {
   char *stub_name;
   bfd_size_type len;
 
   if (hash)
     {
-      len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1;
+      len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1 + 2 + 1;
       stub_name = (char *) bfd_malloc (len);
       if (stub_name != NULL)
-	sprintf (stub_name, "%08x_%s+%x",
+	sprintf (stub_name, "%08x_%s+%x_%d",
 		 input_section->id & 0xffffffff,
 		 hash->root.root.root.string,
-		 (int) rel->r_addend & 0xffffffff);
+		 (int) rel->r_addend & 0xffffffff,
+		 (int) stub_type);
     }
   else
     {
-      len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
+      len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 2 + 1;
       stub_name = (char *) bfd_malloc (len);
       if (stub_name != NULL)
-	sprintf (stub_name, "%08x_%x:%x+%x",
+	sprintf (stub_name, "%08x_%x:%x+%x_%d",
 		 input_section->id & 0xffffffff,
 		 sym_sec->id & 0xffffffff,
 		 (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
-		 (int) rel->r_addend & 0xffffffff);
+		 (int) rel->r_addend & 0xffffffff,
+		 (int) stub_type);
     }
 
   return stub_name;
@@ -3283,7 +3290,8 @@ elf32_arm_get_stub_entry (const asection
 			  const asection *sym_sec,
 			  struct elf_link_hash_entry *hash,
 			  const Elf_Internal_Rela *rel,
-			  struct elf32_arm_link_hash_table *htab)
+			  struct elf32_arm_link_hash_table *htab,
+			  enum elf32_arm_stub_type stub_type)
 {
   struct elf32_arm_stub_hash_entry *stub_entry;
   struct elf32_arm_link_hash_entry *h = (struct elf32_arm_link_hash_entry *) hash;
@@ -3309,7 +3317,7 @@ elf32_arm_get_stub_entry (const asection
     {
       char *stub_name;
 
-      stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel);
+      stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel, stub_type);
       if (stub_name == NULL)
 	return NULL;
 
@@ -4022,7 +4030,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
 		  && last_was_32bit
 		  && ! last_was_branch)
                 {
-                  bfd_signed_vma offset;
+                  bfd_signed_vma offset = 0;
                   bfd_boolean force_target_arm = FALSE;
 		  bfd_boolean force_target_thumb = FALSE;
                   bfd_vma target;
@@ -4512,7 +4520,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 
 		      /* Get the name of this stub.  */
 		      stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
-						       irela);
+						       irela, stub_type);
 		      if (!stub_name)
 			goto error_ret_free_internal;
 
@@ -7004,7 +7012,6 @@ elf32_arm_final_link_relocate (reloc_how
 	case R_ARM_PC24:	  /* Arm B/BL instruction.  */
 	case R_ARM_PLT32:
 	  {
-	  bfd_signed_vma branch_offset;
 	  struct elf32_arm_stub_hash_entry *stub_entry = NULL;
 
 	  if (r_type == R_ARM_XPC25)
@@ -7040,8 +7047,9 @@ elf32_arm_final_link_relocate (reloc_how
 	      || r_type == R_ARM_JUMP24
 	      || r_type == R_ARM_PLT32)
 	    {
-	      bfd_vma from;
-	      
+	      enum elf32_arm_stub_type stub_type;
+	      struct elf32_arm_link_hash_entry *hash;
+
 	      /* If the call goes through a PLT entry, make sure to
 		 check distance to the right destination address.  */
 	      if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
@@ -7055,25 +7063,21 @@ elf32_arm_final_link_relocate (reloc_how
 		  sym_flags = STT_FUNC;
 		}
 
-	      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)
-		      && (((r_type == R_ARM_CALL) && !globals->use_blx)
-			  || (r_type == R_ARM_JUMP24)
-			  || (r_type == R_ARM_PLT32) ))
-		  )
+	      hash = (struct elf32_arm_link_hash_entry *) h;
+	      stub_type = arm_type_of_stub (info, input_section, rel,
+					    sym_flags, hash,
+					    value, sym_sec,
+					    input_bfd, sym_name);
+
+	      if (stub_type != arm_stub_none)
 		{
 		  /* The target is out of reach, so redirect the
 		     branch to the local stub for this function.  */
 
 		  stub_entry = elf32_arm_get_stub_entry (input_section,
 							 sym_sec, h,
-							 rel, globals);
+							 rel, globals,
+							 stub_type);
 		  if (stub_entry != NULL)
 		    value = (stub_entry->stub_offset
 			     + stub_entry->stub_sec->output_offset
@@ -7489,32 +7493,24 @@ elf32_arm_final_link_relocate (reloc_how
 	  {
 	    /* Check if a stub has to be inserted because the destination
 	       is too far.  */
-	    bfd_vma from;
-	    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 ((!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)))
-		|| ((sym_flags != STT_ARM_TFUNC)
-		    && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
-			|| r_type == R_ARM_THM_JUMP24)))
+	    enum elf32_arm_stub_type stub_type;
+	    struct elf32_arm_stub_hash_entry *stub_entry;
+	    struct elf32_arm_link_hash_entry *hash;
+
+	    hash = (struct elf32_arm_link_hash_entry *) h;
+	    stub_type = arm_type_of_stub (info, input_section, rel,
+					  sym_flags, hash, value, sym_sec,
+					  input_bfd, sym_name);
+
+	    if (stub_type != arm_stub_none)
 	      {
 		/* The target is out of reach or we are changing modes, so
 		   redirect the branch to the local stub for this
 		   function.  */
 		stub_entry = elf32_arm_get_stub_entry (input_section,
 						       sym_sec, h,
-						       rel, globals);
+						       rel, globals,
+						       stub_type);
 		if (stub_entry != NULL)
 		  value = (stub_entry->stub_offset
 			   + stub_entry->stub_sec->output_offset

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-14 23:53           ` Alan Modra
@ 2010-01-19 10:09             ` Christophe LYON
  2010-02-04 16:26               ` Matthew Gretton-Dann
  0 siblings, 1 reply; 15+ messages in thread
From: Christophe LYON @ 2010-01-19 10:09 UTC (permalink / raw)
  To: binutils

On 15.01.2010 00:53, Alan Modra wrote:
> On Thu, Jan 14, 2010 at 02:48:20PM -0500, Daniel Jacobowitz wrote:
>> Yes, this is busted.
>
> Easily fixed.  Breaks arm-call test due to different stub ordering,
> but I'll leave fixing the testsuite to an ARM maintainer.
>

I have tried your patch, and it breaks a few other tests too, mainly due 
to different stub ordering as you say, but farcall-mixed-app and 
farcall-mixed-lib.so also fail to link.

I am looking at why they now fail (using CVS trunk, target arm-none-eabi).

Christophe.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-01-19 10:09             ` Christophe LYON
@ 2010-02-04 16:26               ` Matthew Gretton-Dann
  2010-02-04 16:37                 ` Christophe LYON
                                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Matthew Gretton-Dann @ 2010-02-04 16:26 UTC (permalink / raw)
  To: Christophe LYON; +Cc: binutils, amodra

On Tue, 2010-01-19 at 11:09 +0100, Christophe LYON wrote:
> On 15.01.2010 00:53, Alan Modra wrote:
> > On Thu, Jan 14, 2010 at 02:48:20PM -0500, Daniel Jacobowitz wrote:
> >> Yes, this is busted.
> >
> > Easily fixed.  Breaks arm-call test due to different stub ordering,
> > but I'll leave fixing the testsuite to an ARM maintainer.
> >
> 
> I have tried your patch, and it breaks a few other tests too, mainly due 
> to different stub ordering as you say, but farcall-mixed-app and 
> farcall-mixed-lib.so also fail to link.
> 
> I am looking at why they now fail (using CVS trunk, target arm-none-eabi).

I've also seen these failures on CVS trunk, target arm-none-eabi.

For example: farcall-mixed-app is failing with the following error:

tmpdir/farcall-mixed-app.o: In function `app_tfunc':
(.far_thumb+0x2): relocation truncated to fit: R_ARM_THM_CALL against symbol `lib_func2' defined in .plt section in tmpdir/mixed-lib.so

This seems to be because after applying the patch the call to
elf32_arm_get_stub_entry() at about line 7510 of elf32-arm.c returns
NULL for this relocation.  Before the patch was applied it returned
non-NULL.

The 'obvious' fix of changing the call to arm_stub_hash_lookup() made by
elf32_arm_get_stub_entry() to pass TRUE for the create parameter (around
elf32-arm.c:3324) causes the tests to 'pass' (they still fail - but only
due to stub ordering changes).  However, I do not know what other
effects it has and whether that is a safe change.  Could someone with
more knowledge of this area take a look please, and make some comments?

Thanks,

Matt

-- 
Matthew Gretton-Dann
Principal Engineer - Tools, PD Software
ARM Limited

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-02-04 16:26               ` Matthew Gretton-Dann
@ 2010-02-04 16:37                 ` Christophe LYON
  2010-02-05  2:15                 ` Alan Modra
  2010-02-05  5:32                 ` Alan Modra
  2 siblings, 0 replies; 15+ messages in thread
From: Christophe LYON @ 2010-02-04 16:37 UTC (permalink / raw)
  To: Matthew Gretton-Dann; +Cc: binutils, amodra

Hi,

> The 'obvious' fix of changing the call to arm_stub_hash_lookup() made by
> elf32_arm_get_stub_entry() to pass TRUE for the create parameter (around
> elf32-arm.c:3324) causes the tests to 'pass' (they still fail - but only
> due to stub ordering changes).  However, I do not know what other
> effects it has and whether that is a safe change.  Could someone with
> more knowledge of this area take a look please, and make some comments?
>

As I mentioned in another thread, I am currently looking at this, as 
Alan's patch actually triggered several bugs. In this process, I have 
encountered issues with an earlier patch from one of your colleagues, 
for which I am about to propose a patch.

Christophe.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-02-04 16:26               ` Matthew Gretton-Dann
  2010-02-04 16:37                 ` Christophe LYON
@ 2010-02-05  2:15                 ` Alan Modra
  2010-02-05  5:32                 ` Alan Modra
  2 siblings, 0 replies; 15+ messages in thread
From: Alan Modra @ 2010-02-05  2:15 UTC (permalink / raw)
  To: Matthew Gretton-Dann; +Cc: Christophe LYON, binutils

> > On 15.01.2010 00:53, Alan Modra wrote:
> > > Easily fixed.

That statement was too hasty.  I see that stub_cache takes no notice
of the stub type, so that needs fixing too.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-02-04 16:26               ` Matthew Gretton-Dann
  2010-02-04 16:37                 ` Christophe LYON
  2010-02-05  2:15                 ` Alan Modra
@ 2010-02-05  5:32                 ` Alan Modra
  2010-02-24 18:45                   ` Christophe LYON
  2 siblings, 1 reply; 15+ messages in thread
From: Alan Modra @ 2010-02-05  5:32 UTC (permalink / raw)
  To: Matthew Gretton-Dann; +Cc: Christophe LYON, binutils

On Thu, Feb 04, 2010 at 04:26:38PM +0000, Matthew Gretton-Dann wrote:
> tmpdir/farcall-mixed-app.o: In function `app_tfunc':
> (.far_thumb+0x2): relocation truncated to fit: R_ARM_THM_CALL against symbol `lib_func2' defined in .plt section in tmpdir/mixed-lib.so
> 
> This seems to be because after applying the patch the call to
> elf32_arm_get_stub_entry() at about line 7510 of elf32-arm.c returns
> NULL for this relocation.  Before the patch was applied it returned
> non-NULL.

This is because the arm_type_of_stub call in elf32_arm_size_stubs
returns arm_stub_long_branch_v4t_thumb_arm but when called in
elf32_arm_final_link_relocate you get
arm_stub_long_branch_v4t_thumb_thumb.  st_type differs in the two
calls.  I think the changes to sym_flags for plt calls in 
elf32_arm_final_link_relocate should be moved into arm_type_of_stub,
but I don't understand the arm back end well enough to fix this
without spending quite some time on it.  I don't have the time to
continue with this patch.  Sorry.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-02-05  5:32                 ` Alan Modra
@ 2010-02-24 18:45                   ` Christophe LYON
  2010-03-01 17:45                     ` Nick Clifton
  0 siblings, 1 reply; 15+ messages in thread
From: Christophe LYON @ 2010-02-24 18:45 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 2216 bytes --]

Hi all,

On 05.02.2010 06:32, Alan Modra wrote:
> On Thu, Feb 04, 2010 at 04:26:38PM +0000, Matthew Gretton-Dann wrote:
>> tmpdir/farcall-mixed-app.o: In function `app_tfunc':
>> (.far_thumb+0x2): relocation truncated to fit: R_ARM_THM_CALL against symbol `lib_func2' defined in .plt section in tmpdir/mixed-lib.so
>>
>> This seems to be because after applying the patch the call to
>> elf32_arm_get_stub_entry() at about line 7510 of elf32-arm.c returns
>> NULL for this relocation.  Before the patch was applied it returned
>> non-NULL.
>
> This is because the arm_type_of_stub call in elf32_arm_size_stubs
> returns arm_stub_long_branch_v4t_thumb_arm but when called in
> elf32_arm_final_link_relocate you get
> arm_stub_long_branch_v4t_thumb_thumb.  st_type differs in the two
> calls.  I think the changes to sym_flags for plt calls in
> elf32_arm_final_link_relocate should be moved into arm_type_of_stub,
> but I don't understand the arm back end well enough to fix this
> without spending quite some time on it.  I don't have the time to
> continue with this patch.  Sorry.
>

After quite some time and a few headaches, I am able to propose the 
attached patch, which is an updated version of Alan's initial proposal 
along with the associated testsuite updates.

I have factorized a bit of the logic about long branches offsets 
computation into arm_type_of_stub, hopefully making 
elf32_arm_final_link_relocate a bit easier to read (it would still 
deserve a bit of cleanup).

In arm_build_one_stub, we now always call elf32_arm_final_link_relocate, 
but it two places: it leaves room for a cleanup patch. (but I am unsure 
about the magic around A8 stubs, so some parts of this function are 
still a bit obscure, so if someone volunteers for this part, I'd be 
happy ;-)

Most testsuite updates are due to a change in the order of stubs 
emission. However, note that I have updated the farcall-thumb-arm test, 
so that it can lead to the generation of 2 different stubs for the same 
destination, depending on the branch start address (and architecture 
features).

Sorry for the long patch, I did not find an easy way to split it.

Validated on arm-none-eabi, arm-linux-gnueabi and arm-elf.

Christophe.

[-- Attachment #2: stubs.changelog --]
[-- Type: text/plain, Size: 2281 bytes --]

2010-02-24  Christophe Lyon  <christophe.lyon@st.com>
	Alan Modra  <amodra@gmail.com>

	bfd/
	* elf32-arm.c (a8_erratum_fix): Add st_type field to record the
	destination mode of the a8 stub.
	(elf32_arm_link_hash_table): Add top_id field.
	(elf32_arm_link_hash_table_create): Initialize top_id.
	(arm_type_of_stub): Update prototype, st_type can now be updated
	by this function. Actual destination address in case of PLT is
	computed here, to help factorizing code.
	(elf32_arm_stub_name): Update prototype, use stub_type additional
	parameter to build stub name.
	(elf32_arm_get_stub_entry): Update prototype, use stub_type
	additional parameter to build stub entry.
	(arm_build_one_stub): Use bfd_put_16/bfd_put_32 instead of
	put_thumb_insn/put_arm_insn as BE8 encoding is now handled later.
	Call elf32_arm_final_link_relocate to process all in-stub
	relocations.
	(elf32_arm_setup_section_lists): Update top_id.
	(cortex_a8_erratum_scan): Record stub destination mode.
	(elf32_arm_size_stubs): Update call to arm_type_of_stub according
	to new prototype.
	(elf32_arm_final_link_relocate): Enable processing of in-stub
	REL32 relocations. Rely on arm_type_of_stub to detect if a stub is
	needed, enabling code factorization.
	(elf32_arm_final_link): Process stub sections.
	(elf32_arm_output_map_sym): Add entry to code/data map.

	ld/testsuite/
	* ld-arm/arm-elf.exp: Change .text start address for
	farcall-thumb-arm tests. Add v4t variant for farcall-mixed-lib
	test.
	* ld-arm/farcall-mixed-lib-v4t.d: New test.
	* ld-arm/farcall-mixed-lib1.s: Don't force armv5t.
	* ld-arm/farcall-mixed-lib2.s: Likewise.
	* ld-arm/arm-call.d: Update expected results.
	* ld-arm/cortex-a8-far.d: Likewise.
	* ld-arm/farcall-group-size2.d: Likewise.
	* ld-arm/farcall-group.d: Likewise.
	* ld-arm/farcall-mix.d: Likewise.
	* ld-arm/farcall-mix2.d: Likewise.
	* ld-arm/farcall-mixed-app-v5.d: Likewise.
	* ld-arm/farcall-mixed-app.d: Likewise.
	* ld-arm/farcall-mixed-lib.d: Likewise.
	* ld-arm/farcall-thumb-arm.d: Likewise.
	* ld-arm/farcall-thumb-arm-blx.d: Likewise.
	* ld-arm/farcall-thumb-arm-pic-veneer.d: Likewise.
	* ld-arm/farcall-thumb-arm-blx-pic-veneer.d: Likewise.
	* ld-arm/farcall-thumb-arm.s: Update test. Add a new call to
	potentially generate different types of stubs.

[-- Attachment #3: stubs.patch --]
[-- Type: text/x-patch, Size: 52299 bytes --]

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.223
diff -u -p -r1.223 elf32-arm.c
--- bfd/elf32-arm.c	18 Feb 2010 10:56:26 -0000	1.223
+++ bfd/elf32-arm.c	24 Feb 2010 17:31:41 -0000
@@ -2399,6 +2399,7 @@ struct a8_erratum_fix {
   unsigned long orig_insn;
   char *stub_name;
   enum elf32_arm_stub_type stub_type;
+  int st_type;
 };
 
 /* A table of relocs applied to branches which might trigger Cortex-A8
@@ -2650,6 +2651,9 @@ struct elf32_arm_link_hash_table
      information on stub grouping.  */
   struct map_stub *stub_group;
 
+  /* Number of elements in stub_group.  */
+  int top_id;
+
   /* Assorted information used by elf32_arm_size_stubs.  */
   unsigned int bfd_count;
   int top_index;
@@ -2944,6 +2948,7 @@ elf32_arm_link_hash_table_create (bfd *a
   ret->add_stub_section = NULL;
   ret->layout_sections_again = NULL;
   ret->stub_group = NULL;
+  ret->top_id = 0;
   ret->bfd_count = 0;
   ret->top_index = 0;
   ret->input_list = NULL;
@@ -3046,7 +3051,7 @@ static enum elf32_arm_stub_type
 arm_type_of_stub (struct bfd_link_info *info,
 		  asection *input_sec,
 		  const Elf_Internal_Rela *rel,
-		  unsigned char st_type,
+		  int *actual_st_type,
 		  struct elf32_arm_link_hash_entry *hash,
 		  bfd_vma destination,
 		  asection *sym_sec,
@@ -3061,6 +3066,7 @@ arm_type_of_stub (struct bfd_link_info *
   int thumb_only;
   enum elf32_arm_stub_type stub_type = arm_stub_none;
   int use_plt = 0;
+  int st_type = *actual_st_type;
 
   /* We don't know the actual type of destination in case it is of
      type STT_SECTION: give up.  */
@@ -3080,14 +3086,15 @@ arm_type_of_stub (struct bfd_link_info *
 	      + input_sec->output_section->vma
 	      + rel->r_offset);
 
-  branch_offset = (bfd_signed_vma)(destination - location);
-
   r_type = ELF32_R_TYPE (rel->r_info);
 
   /* Keep a simpler condition, for the sake of clarity.  */
-  if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)
+  if (globals->splt != NULL
+      && hash != NULL
+      && hash->root.plt.offset != (bfd_vma) -1)
     {
       use_plt = 1;
+
       /* Note when dealing with PLT entries: the main PLT stub is in
 	 ARM mode, so if the branch is in Thumb mode, another
 	 Thumb->ARM stub will be inserted later just before the ARM
@@ -3096,8 +3103,15 @@ arm_type_of_stub (struct bfd_link_info *
 	 Thumb->Arm one and branch directly to the ARM PLT entry
 	 because it avoids spreading offset corrections in several
 	 places.  */
+
+      destination = (globals->splt->output_section->vma
+		     + globals->splt->output_offset
+		     + hash->root.plt.offset);
+      st_type = STT_FUNC;
     }
 
+  branch_offset = (bfd_signed_vma)(destination - location);
+
   if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
     {
       /* Handle cases where:
@@ -3191,7 +3205,9 @@ arm_type_of_stub (struct bfd_link_info *
 	    }
 	}
     }
-  else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
+  else if (r_type == R_ARM_CALL
+	   || r_type == R_ARM_JUMP24
+	   || r_type == R_ARM_PLT32)
     {
       if (st_type == STT_ARM_TFUNC)
 	{
@@ -3246,6 +3262,12 @@ arm_type_of_stub (struct bfd_link_info *
 	}
     }
 
+  /* If a stub is needed, record the actual destination type.  */
+  if (stub_type != arm_stub_none)
+    {
+      *actual_st_type = st_type;
+    }
+
   return stub_type;
 }
 
@@ -3255,31 +3277,34 @@ static char *
 elf32_arm_stub_name (const asection *input_section,
 		     const asection *sym_sec,
 		     const struct elf32_arm_link_hash_entry *hash,
-		     const Elf_Internal_Rela *rel)
+		     const Elf_Internal_Rela *rel,
+		     enum elf32_arm_stub_type stub_type)
 {
   char *stub_name;
   bfd_size_type len;
 
   if (hash)
     {
-      len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1;
+      len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1 + 2 + 1;
       stub_name = (char *) bfd_malloc (len);
       if (stub_name != NULL)
-	sprintf (stub_name, "%08x_%s+%x",
+	sprintf (stub_name, "%08x_%s+%x_%d",
 		 input_section->id & 0xffffffff,
 		 hash->root.root.root.string,
-		 (int) rel->r_addend & 0xffffffff);
+		 (int) rel->r_addend & 0xffffffff,
+		 (int) stub_type);
     }
   else
     {
-      len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
+      len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 2 + 1;
       stub_name = (char *) bfd_malloc (len);
       if (stub_name != NULL)
-	sprintf (stub_name, "%08x_%x:%x+%x",
+	sprintf (stub_name, "%08x_%x:%x+%x_%d",
 		 input_section->id & 0xffffffff,
 		 sym_sec->id & 0xffffffff,
 		 (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
-		 (int) rel->r_addend & 0xffffffff);
+		 (int) rel->r_addend & 0xffffffff,
+		 (int) stub_type);
     }
 
   return stub_name;
@@ -3293,7 +3318,8 @@ elf32_arm_get_stub_entry (const asection
 			  const asection *sym_sec,
 			  struct elf_link_hash_entry *hash,
 			  const Elf_Internal_Rela *rel,
-			  struct elf32_arm_link_hash_table *htab)
+			  struct elf32_arm_link_hash_table *htab,
+			  enum elf32_arm_stub_type stub_type)
 {
   struct elf32_arm_stub_hash_entry *stub_entry;
   struct elf32_arm_link_hash_entry *h = (struct elf32_arm_link_hash_entry *) hash;
@@ -3311,7 +3337,8 @@ elf32_arm_get_stub_entry (const asection
 
   if (h != NULL && h->stub_cache != NULL
       && h->stub_cache->h == h
-      && h->stub_cache->id_sec == id_sec)
+      && h->stub_cache->id_sec == id_sec
+      && h->stub_cache->stub_type == stub_type)
     {
       stub_entry = h->stub_cache;
     }
@@ -3319,7 +3346,7 @@ elf32_arm_get_stub_entry (const asection
     {
       char *stub_name;
 
-      stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel);
+      stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel, stub_type);
       if (stub_name == NULL)
 	return NULL;
 
@@ -3479,7 +3506,7 @@ arm_build_one_stub (struct bfd_hash_entr
     /* We have to do the a8 fixes last, as they are less aligned than
        the other veneers.  */
     return TRUE;
-  
+
   /* Make a note of the offset within the stubs for this entry.  */
   stub_entry->stub_offset = stub_sec->size;
   loc = stub_sec->contents + stub_entry->stub_offset;
@@ -3514,17 +3541,17 @@ arm_build_one_stub (struct bfd_hash_entr
                 BFD_ASSERT ((data & 0xff00) == 0xd000);
                 data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8;
 	      }
-	    put_thumb_insn (globals, stub_bfd, data, loc + size);
+	    bfd_put_16 (stub_bfd, data, loc + size);
 	    size += 2;
 	  }
 	  break;
 
 	case THUMB32_TYPE:
-          put_thumb_insn (globals, stub_bfd,
-                          (template_sequence[i].data >> 16) & 0xffff,
-                          loc + size);
-          put_thumb_insn (globals, stub_bfd, template_sequence[i].data & 0xffff,
-                          loc + size + 2);
+	  bfd_put_16 (stub_bfd,
+		      (template_sequence[i].data >> 16) & 0xffff,
+		      loc + size);
+	  bfd_put_16 (stub_bfd, template_sequence[i].data & 0xffff,
+		      loc + size + 2);
           if (template_sequence[i].r_type != R_ARM_NONE)
             {
               stub_reloc_idx[nrelocs] = i;
@@ -3534,8 +3561,8 @@ arm_build_one_stub (struct bfd_hash_entr
           break;
 
 	case ARM_TYPE:
-	  put_arm_insn (globals, stub_bfd, template_sequence[i].data,
-                        loc + size);
+	  bfd_put_32 (stub_bfd, template_sequence[i].data,
+		      loc + size);
 	  /* Handle cases where the target is encoded within the
 	     instruction.  */
 	  if (template_sequence[i].r_type == R_ARM_JUMP24)
@@ -3614,11 +3641,23 @@ arm_build_one_stub (struct bfd_hash_entr
       }
     else
       {
-	_bfd_final_link_relocate (elf32_arm_howto_from_type
-	    (template_sequence[stub_reloc_idx[i]].r_type), stub_bfd, stub_sec,
-	  stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset[i],
-	  sym_value + stub_entry->target_addend,
-	  template_sequence[stub_reloc_idx[i]].reloc_addend);
+	Elf_Internal_Rela rel;
+	bfd_boolean unresolved_reloc;
+	char *error_message;
+	bfd_vma points_to = sym_value + stub_entry->target_addend
+	  + template_sequence[stub_reloc_idx[i]].reloc_addend;
+
+	rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
+	rel.r_info = ELF32_R_INFO (0,
+                                   template_sequence[stub_reloc_idx[i]].r_type);
+	rel.r_addend = 0;
+
+	elf32_arm_final_link_relocate (elf32_arm_howto_from_type
+	    (template_sequence[stub_reloc_idx[i]].r_type),
+	  stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
+	  points_to, info, stub_entry->target_section, "", stub_entry->st_type,
+	  (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc,
+	  &error_message);
       }
 
   return TRUE;
@@ -3745,6 +3784,7 @@ elf32_arm_setup_section_lists (bfd *outp
   htab->stub_group = (struct map_stub *) bfd_zmalloc (amt);
   if (htab->stub_group == NULL)
     return -1;
+  htab->top_id = top_id;
 
   /* We can't use output_bfd->section_count here to find the top output
      section index as some sections may have been removed, and
@@ -4033,7 +4073,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
 		}
 
 	      is_32bit_branch = is_b || is_bl || is_blx || is_bcc;
-			   
+
               if (((base_vma + i) & 0xfff) == 0xffe
 		  && insn_32bit
 		  && is_32bit_branch
@@ -4204,6 +4244,8 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                           a8_fixes[num_a8_fixes].orig_insn = insn;
                           a8_fixes[num_a8_fixes].stub_name = stub_name;
                           a8_fixes[num_a8_fixes].stub_type = stub_type;
+                          a8_fixes[num_a8_fixes].st_type =
+			    is_blx ? STT_FUNC : STT_ARM_TFUNC;
 
                           num_a8_fixes++;
                         }
@@ -4219,11 +4261,11 @@ cortex_a8_erratum_scan (bfd *input_bfd,
       if (elf_section_data (section)->this_hdr.contents == NULL)
         free (contents);
     }
-  
+
   *a8_fixes_p = a8_fixes;
   *num_a8_fixes_p = num_a8_fixes;
   *a8_fix_table_size_p = a8_fix_table_size;
-  
+
   return FALSE;
 }
 
@@ -4374,7 +4416,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 		  const char *sym_name;
 		  char *stub_name;
 		  const asection *id_sec;
-		  unsigned char st_type;
+		  int st_type;
 		  bfd_boolean created_stub = FALSE;
 
 		  r_type = ELF32_R_TYPE (irela->r_info);
@@ -4432,7 +4474,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 			/* This is an undefined symbol.  It can never
 			   be resolved. */
 			continue;
-		  
+
 		      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
 			sym_value = sym->st_value;
 		      destination = (sym_value + irela->r_addend
@@ -4526,7 +4568,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 		    {
 		      /* Determine what (if any) linker stub is needed.  */
 		      stub_type = arm_type_of_stub (info, section, irela,
-						    st_type, hash,
+						    &st_type, hash,
 						    destination, sym_sec,
 						    input_bfd, sym_name);
 		      if (stub_type == arm_stub_none)
@@ -4537,7 +4579,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 
 		      /* Get the name of this stub.  */
 		      stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
-						       irela);
+						       irela, stub_type);
 		      if (!stub_name)
 			goto error_ret_free_internal;
 
@@ -4737,7 +4779,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
           stub_entry->target_value = a8_fixes[i].offset;
           stub_entry->target_addend = a8_fixes[i].addend;
           stub_entry->orig_insn = a8_fixes[i].orig_insn;
-          stub_entry->st_type = STT_ARM_TFUNC;
+	  stub_entry->st_type = a8_fixes[i].st_type;
 
           size = find_stub_size_and_template (a8_fixes[i].stub_type,
                                               &template_sequence,
@@ -6918,6 +6960,7 @@ elf32_arm_final_link_relocate (reloc_how
 			  ".tls_vars") == 0)
 	  && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
 	      || !SYMBOL_CALLS_LOCAL (info, h))
+	  && (!strstr (input_section->name, STUB_SUFFIX))
 	  && (h == NULL
 	      || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 	      || h->root.type != bfd_link_hash_undefweak)
@@ -7042,7 +7085,6 @@ elf32_arm_final_link_relocate (reloc_how
 	case R_ARM_PC24:	  /* Arm B/BL instruction.  */
 	case R_ARM_PLT32:
 	  {
-	  bfd_signed_vma branch_offset;
 	  struct elf32_arm_stub_hash_entry *stub_entry = NULL;
 
 	  if (r_type == R_ARM_XPC25)
@@ -7078,45 +7120,46 @@ elf32_arm_final_link_relocate (reloc_how
 	      || r_type == R_ARM_JUMP24
 	      || r_type == R_ARM_PLT32)
 	    {
-	      bfd_vma from;
-	      
-	      /* If the call goes through a PLT entry, make sure to
-		 check distance to 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;
-		  /* The PLT entry is in ARM mode, regardless of the
-		     target function.  */
-		  sym_flags = STT_FUNC;
-		}
-
-	      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)
-		      && (((r_type == R_ARM_CALL) && !globals->use_blx)
-			  || (r_type == R_ARM_JUMP24)
-			  || (r_type == R_ARM_PLT32) ))
-		  )
+	      enum elf32_arm_stub_type stub_type = arm_stub_none;
+	      struct elf32_arm_link_hash_entry *hash;
+
+	      hash = (struct elf32_arm_link_hash_entry *) h;
+	      stub_type = arm_type_of_stub (info, input_section, rel,
+					    &sym_flags, hash,
+					    value, sym_sec,
+					    input_bfd, sym_name);
+
+	      if (stub_type != arm_stub_none)
 		{
 		  /* The target is out of reach, so redirect the
 		     branch to the local stub for this function.  */
 
 		  stub_entry = elf32_arm_get_stub_entry (input_section,
 							 sym_sec, h,
-							 rel, globals);
+							 rel, globals,
+							 stub_type);
 		  if (stub_entry != NULL)
 		    value = (stub_entry->stub_offset
 			     + stub_entry->stub_sec->output_offset
 			     + stub_entry->stub_sec->output_section->vma);
 		}
+	      else
+		{
+		  /* If the call goes through a PLT entry, make sure to
+		     check distance to 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;
+		      /* The PLT entry is in ARM mode, regardless of the
+			 target function.  */
+		      sym_flags = STT_FUNC;
+		    }
+		}
 	    }
 
 	  /* The ARM ELF ABI says that this reloc is computed as: S - P + A
@@ -7501,58 +7544,29 @@ elf32_arm_final_link_relocate (reloc_how
 	      }
 	  }
 
-	/* Handle calls via the PLT.  */
-	if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
-	  {
-	    value = (splt->output_section->vma
-		     + splt->output_offset
-		     + h->plt.offset);
- 	    if (globals->use_blx && r_type == R_ARM_THM_CALL)
- 	      {
- 		/* If the Thumb BLX instruction is available, convert the
-		   BL to a BLX instruction to call the ARM-mode PLT entry.  */
-		lower_insn = (lower_insn & ~0x1000) | 0x0800;
-		sym_flags = STT_FUNC;
- 	      }
- 	    else
-	      {
-		/* Target the Thumb stub before the ARM PLT entry.  */
-		value -= PLT_THUMB_STUB_SIZE;
-		sym_flags = STT_ARM_TFUNC;
-	      }
-	    *unresolved_reloc_p = FALSE;
-	  }
-
+	enum elf32_arm_stub_type stub_type = arm_stub_none;
 	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.  */
-	    bfd_vma from;
-	    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 ((!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)))
-		|| ((sym_flags != STT_ARM_TFUNC)
-		    && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
-			|| r_type == R_ARM_THM_JUMP24)))
+	    struct elf32_arm_stub_hash_entry *stub_entry;
+	    struct elf32_arm_link_hash_entry *hash;
+
+	    hash = (struct elf32_arm_link_hash_entry *) h;
+
+	    stub_type = arm_type_of_stub (info, input_section, rel,
+					  &sym_flags, hash, value, sym_sec,
+					  input_bfd, sym_name);
+
+	    if (stub_type != arm_stub_none)
 	      {
 		/* The target is out of reach or we are changing modes, so
 		   redirect the branch to the local stub for this
 		   function.  */
 		stub_entry = elf32_arm_get_stub_entry (input_section,
 						       sym_sec, h,
-						       rel, globals);
+						       rel, globals,
+						       stub_type);
 		if (stub_entry != NULL)
 		  value = (stub_entry->stub_offset
 			   + stub_entry->stub_sec->output_offset
@@ -7569,6 +7583,33 @@ elf32_arm_final_link_relocate (reloc_how
 	      }
 	  }
 
+	/* Handle calls via the PLT.  */
+	if (stub_type == arm_stub_none
+	    && h != NULL
+	    && splt != NULL
+	    && h->plt.offset != (bfd_vma) -1)
+	  {
+	    value = (splt->output_section->vma
+		     + splt->output_offset
+		     + h->plt.offset);
+
+	    if (globals->use_blx && r_type == R_ARM_THM_CALL)
+	      {
+		/* If the Thumb BLX instruction is available, convert
+		   the BL to a BLX instruction to call the ARM-mode
+		   PLT entry.  */
+		lower_insn = (lower_insn & ~0x1000) | 0x0800;
+		sym_flags = STT_FUNC;
+	      }
+	    else
+	      {
+		/* Target the Thumb stub before the ARM PLT entry.  */
+		value -= PLT_THUMB_STUB_SIZE;
+		sym_flags = STT_ARM_TFUNC;
+	      }
+	    *unresolved_reloc_p = FALSE;
+	  }
+
 	relocation = value + signed_addend;
 
 	relocation -= (input_section->output_section->vma
@@ -9357,6 +9398,7 @@ static bfd_boolean
 elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
+  asection *sec, *osec;
 
   if (globals == NULL)
     return FALSE;
@@ -9365,6 +9407,20 @@ elf32_arm_final_link (bfd *abfd, struct 
   if (!bfd_elf_final_link (abfd, info))
     return FALSE;
 
+  /* Process stub sections (eg BE8 encoding, ...).  */
+  struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+  int i;
+  for(i=0; i<htab->top_id; i++) {
+    sec = htab->stub_group[i].stub_sec;
+    if (sec) {
+      osec = sec->output_section;
+      elf32_arm_write_section (abfd, info, sec, sec->contents);
+      if (! bfd_set_section_contents (abfd, osec, sec->contents,
+				      sec->output_offset, sec->size))
+	return FALSE;
+    }
+  }
+
   /* Write out any glue sections now that we have created all the
      stubs.  */
   if (globals->bfd_of_glue_owner != NULL)
@@ -12866,6 +12922,7 @@ elf32_arm_output_map_sym (output_arch_sy
   sym.st_other = 0;
   sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
   sym.st_shndx = osi->sec_shndx;
+  elf32_arm_section_map_add (osi->sec, names[type][1], offset);
   return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
 }
 
Index: ld/testsuite/ld-arm/arm-call.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-call.d,v
retrieving revision 1.5
diff -u -p -r1.5 arm-call.d
--- ld/testsuite/ld-arm/arm-call.d	30 Jun 2009 11:57:05 -0000	1.5
+++ ld/testsuite/ld-arm/arm-call.d	24 Feb 2010 17:31:44 -0000
@@ -10,10 +10,10 @@ Disassembly of section .text:
     800c:	fb00000d 	blx	804a <t5>
     8010:	fa00000a 	blx	8040 <t1>
     8014:	fb000009 	blx	8042 <t2>
-    8018:	ea000012 	b	8068 <__t1_from_arm>
-    801c:	ea00000f 	b	8060 <__t2_from_arm>
-    8020:	1b000010 	blne	8068 <__t1_from_arm>
-    8024:	1b00000d 	blne	8060 <__t2_from_arm>
+    8018:	ea000010 	b	8060 <__t1_from_arm>
+    801c:	ea000011 	b	8068 <__t2_from_arm>
+    8020:	1b00000e 	blne	8060 <__t1_from_arm>
+    8024:	1b00000f 	blne	8068 <__t2_from_arm>
     8028:	1b000003 	blne	803c <arm>
     802c:	eb000002 	bl	803c <arm>
     8030:	faffffff 	blx	8034 <thumblocal>
@@ -49,10 +49,10 @@ Disassembly of section .text:
     805c:	0000      	lsls	r0, r0, #0
 	...
 
-00008060 <__t2_from_arm>:
-    8060:	e51ff004 	ldr	pc, \[pc, #-4\]	; 8064 <__t2_from_arm\+0x4>
-    8064:	00008043 	.word	0x00008043
-
-00008068 <__t1_from_arm>:
-    8068:	e51ff004 	ldr	pc, \[pc, #-4\]	; 806c <__t1_from_arm\+0x4>
-    806c:	00008041 	.word	0x00008041
+00008060 <__t1_from_arm>:
+    8060:	e51ff004 	ldr	pc, \[pc, #-4\]	; 8064 <__t1_from_arm\+0x4>
+    8064:	00008041 	.word	0x00008041
+
+00008068 <__t2_from_arm>:
+    8068:	e51ff004 	ldr	pc, \[pc, #-4\]	; 806c <__t2_from_arm\+0x4>
+    806c:	00008043 	.word	0x00008043
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.72
diff -u -p -r1.72 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	24 Feb 2010 11:15:11 -0000	1.72
+++ ld/testsuite/ld-arm/arm-elf.exp	24 Feb 2010 17:31:45 -0000
@@ -387,25 +387,25 @@ set armeabitests {
      {{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}
+    {"Thumb-ARM farcall" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
      "farcall-thumb-arm"}
-    {"Thumb-ARM farcall (BE8)" "-Ttext 0x1000 --section-start .foo=0x2001014 -EB --be8" "-W -EB" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall (BE8)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 -EB --be8" "-W -EB" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
      "farcall-thumb-arm-be8"}
-    {"Thumb-ARM farcall (BE)" "-Ttext 0x1000 --section-start .foo=0x2001014 -EB" "-W -EB" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall (BE)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 -EB" "-W -EB" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
      "farcall-thumb-arm-be"}
     {"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}
+    {"Thumb-ARM farcall with BLX" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx.d}}
      "farcall-thumb-arm-blx"}
-    {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1c01010 --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}
+    {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-pic-veneer.d}}
      "farcall-thumb-arm-pic-veneer"}
 
@@ -437,7 +437,12 @@ set armeabitests {
       {readelf -Ds farcall-mixed-app.sym}}
      "farcall-mixed-app-v5"}
 
-    {"Mixed ARM/Thumb shared library with long branches" "-shared -T arm-lib.ld" ""
+    {"Mixed ARM/Thumb shared library with long branches (v4t)" "-shared -T arm-lib.ld" "-march=armv4t"
+     {farcall-mixed-lib1.s farcall-mixed-lib2.s}
+     {{objdump -fdw farcall-mixed-lib-v4t.d}}
+     "farcall-mixed-lib.so"}
+
+    {"Mixed ARM/Thumb shared library with long branches (v5t)" "-shared -T arm-lib.ld" "-march=armv5t"
      {farcall-mixed-lib1.s farcall-mixed-lib2.s}
      {{objdump -fdw farcall-mixed-lib.d}}
      "farcall-mixed-lib.so"}
Index: ld/testsuite/ld-arm/cortex-a8-far.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/cortex-a8-far.d,v
retrieving revision 1.1
diff -u -p -r1.1 cortex-a8-far.d
--- ld/testsuite/ld-arm/cortex-a8-far.d	5 Aug 2009 12:36:14 -0000	1.1
+++ ld/testsuite/ld-arm/cortex-a8-far.d	24 Feb 2010 17:31:45 -0000
@@ -13,14 +13,14 @@ Disassembly of section \.text:
   80000c:	7fff0000 	.word	0x7fff0000
 
 00800010 <three>:
-  800010:	f001 e806 	blx	801020 <__far_fn1_from_thumb>
-  800014:	f001 e800 	blx	801018 <__far_fn2_from_thumb>
+  800010:	f001 e802 	blx	801018 <__far_fn1_from_thumb>
+  800014:	f001 e804 	blx	801020 <__far_fn2_from_thumb>
 	...
   800ff8:	bf00      	nop
 
 00800ffa <label1>:
   800ffa:	ea81 0002 	eor.w	r0, r1, r2
-  800ffe:	f000 b813 	b.w	801028 <__far_fn1_from_thumb\+0x8>
+  800ffe:	f000 b813 	b.w	801028 <__far_fn2_from_thumb\+0x8>
   801002:	ea81 0002 	eor.w	r0, r1, r2
   801006:	ea81 0002 	eor.w	r0, r1, r2
   80100a:	f7ff bff6 	b.w	800ffa <label1>
@@ -28,13 +28,13 @@ Disassembly of section \.text:
   801012:	ea81 0002 	eor.w	r0, r1, r2
 	...
 
-00801018 <__far_fn2_from_thumb>:
-  801018:	e51ff004 	ldr	pc, \[pc, #-4\]	; 80101c <__far_fn2_from_thumb\+0x4>
-  80101c:	80000004 	.word	0x80000004
+00801018 <__far_fn1_from_thumb>:
+  801018:	e51ff004 	ldr	pc, \[pc, #-4\]	; 80101c <__far_fn1_from_thumb\+0x4>
+  80101c:	80000000 	.word	0x80000000
 
-00801020 <__far_fn1_from_thumb>:
-  801020:	e51ff004 	ldr	pc, \[pc, #-4\]	; 801024 <__far_fn1_from_thumb\+0x4>
-  801024:	80000000 	.word	0x80000000
-  801028:	d001      	beq.n	80102e <__far_fn1_from_thumb\+0xe>
+00801020 <__far_fn2_from_thumb>:
+  801020:	e51ff004 	ldr	pc, \[pc, #-4\]	; 801024 <__far_fn2_from_thumb\+0x4>
+  801024:	80000004 	.word	0x80000004
+  801028:	d001      	beq.n	80102e <__far_fn2_from_thumb\+0xe>
   80102a:	f7ff bfea 	b.w	801002 <label1\+0x8>
   80102e:	f7ff bfe4 	b.w	800ffa <label1>
Index: ld/testsuite/ld-arm/farcall-group-size2.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-group-size2.d,v
retrieving revision 1.4
diff -u -p -r1.4 farcall-group-size2.d
--- ld/testsuite/ld-arm/farcall-group-size2.d	21 Apr 2009 22:05:04 -0000	1.4
+++ ld/testsuite/ld-arm/farcall-group-size2.d	24 Feb 2010 17:31:45 -0000
@@ -6,27 +6,33 @@ Disassembly of section .text:
 00001000 <_start>:
     1000:	eb000000 	bl	1008 <__bar_from_arm>
     1004:	eb000002 	bl	1014 <__bar2_veneer>
+
 00001008 <__bar_from_arm>:
     1008:	e59fc000 	ldr	ip, \[pc, #0\]	; 1010 <__bar_from_arm\+0x8>
     100c:	e12fff1c 	bx	ip
     1010:	02003021 	.word	0x02003021
+
 00001014 <__bar2_veneer>:
     1014:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1018 <__bar2_veneer\+0x4>
     1018:	02003024 	.word	0x02003024
     101c:	00000000 	.word	0x00000000
+
 00001020 <myfunc>:
     1020:	eb000008 	bl	1048 <__bar3_veneer>
-    1024:	eb000004 	bl	103c <__bar4_from_arm>
-    1028:	eb000000 	bl	1030 <__bar5_from_arm>
+    1024:	eb000001 	bl	1030 <__bar4_from_arm>
+    1028:	eb000003 	bl	103c <__bar5_from_arm>
     102c:	00000000 	andeq	r0, r0, r0
-00001030 <__bar5_from_arm>:
-    1030:	e59fc000 	ldr	ip, \[pc, #0\]	; 1038 <__bar5_from_arm\+0x8>
+
+00001030 <__bar4_from_arm>:
+    1030:	e59fc000 	ldr	ip, \[pc, #0\]	; 1038 <__bar4_from_arm\+0x8>
     1034:	e12fff1c 	bx	ip
-    1038:	0200302f 	.word	0x0200302f
-0000103c <__bar4_from_arm>:
-    103c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1044 <__bar4_from_arm\+0x8>
+    1038:	0200302d 	.word	0x0200302d
+
+0000103c <__bar5_from_arm>:
+    103c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1044 <__bar5_from_arm\+0x8>
     1040:	e12fff1c 	bx	ip
-    1044:	0200302d 	.word	0x0200302d
+    1044:	0200302f 	.word	0x0200302f
+
 00001048 <__bar3_veneer>:
     1048:	e51ff004 	ldr	pc, \[pc, #-4\]	; 104c <__bar3_veneer\+0x4>
     104c:	02003028 	.word	0x02003028
Index: ld/testsuite/ld-arm/farcall-group.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-group.d,v
retrieving revision 1.4
diff -u -p -r1.4 farcall-group.d
--- ld/testsuite/ld-arm/farcall-group.d	21 Apr 2009 22:05:04 -0000	1.4
+++ ld/testsuite/ld-arm/farcall-group.d	24 Feb 2010 17:31:45 -0000
@@ -4,34 +4,39 @@
 Disassembly of section .text:
 
 00001000 <_start>:
-    1000:	eb00000c 	bl	1038 <__bar_from_arm>
-    1004:	eb00000e 	bl	1044 <__bar2_veneer>
+    1000:	eb000009 	bl	102c <__bar_from_arm>
+    1004:	eb000006 	bl	1024 <__bar2_veneer>
 
 00001008 <myfunc>:
-    1008:	eb000008 	bl	1030 <__bar3_veneer>
-    100c:	eb000004 	bl	1024 <__bar4_from_arm>
-    1010:	eb000000 	bl	1018 <__bar5_from_arm>
+    1008:	eb00000d 	bl	1044 <__bar3_veneer>
+    100c:	eb000001 	bl	1018 <__bar4_from_arm>
+    1010:	eb000008 	bl	1038 <__bar5_from_arm>
     1014:	00000000 	andeq	r0, r0, r0
 
-00001018 <__bar5_from_arm>:
-    1018:	e59fc000 	ldr	ip, \[pc, #0\]	; 1020 <__bar5_from_arm\+0x8>
+00001018 <__bar4_from_arm>:
+    1018:	e59fc000 	ldr	ip, \[pc, #0\]	; 1020 <__bar4_from_arm\+0x8>
     101c:	e12fff1c 	bx	ip
-    1020:	0200302f 	.word	0x0200302f
-00001024 <__bar4_from_arm>:
-    1024:	e59fc000 	ldr	ip, \[pc, #0\]	; 102c <__bar4_from_arm\+0x8>
-    1028:	e12fff1c 	bx	ip
-    102c:	0200302d 	.word	0x0200302d
-00001030 <__bar3_veneer>:
-    1030:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1034 <__bar3_veneer\+0x4>
-    1034:	02003028 	.word	0x02003028
-00001038 <__bar_from_arm>:
-    1038:	e59fc000 	ldr	ip, \[pc, #0\]	; 1040 <__bar_from_arm\+0x8>
+    1020:	0200302d 	.word	0x0200302d
+
+00001024 <__bar2_veneer>:
+    1024:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1028 <__bar2_veneer\+0x4>
+    1028:	02003024 	.word	0x02003024
+
+0000102c <__bar_from_arm>:
+    102c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1034 <__bar_from_arm\+0x8>
+    1030:	e12fff1c 	bx	ip
+    1034:	02003021 	.word	0x02003021
+
+00001038 <__bar5_from_arm>:
+    1038:	e59fc000 	ldr	ip, \[pc, #0\]	; 1040 <__bar5_from_arm\+0x8>
     103c:	e12fff1c 	bx	ip
-    1040:	02003021 	.word	0x02003021
-00001044 <__bar2_veneer>:
-    1044:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1048 <__bar2_veneer\+0x4>
-    1048:	02003024 	.word	0x02003024
+    1040:	0200302f 	.word	0x0200302f
+
+00001044 <__bar3_veneer>:
+    1044:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1048 <__bar3_veneer\+0x4>
+    1048:	02003028 	.word	0x02003028
 	...
+
 Disassembly of section .foo:
 
 02003020 <bar>:
Index: ld/testsuite/ld-arm/farcall-mix.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mix.d,v
retrieving revision 1.4
diff -u -p -r1.4 farcall-mix.d
--- ld/testsuite/ld-arm/farcall-mix.d	21 Apr 2009 22:05:04 -0000	1.4
+++ ld/testsuite/ld-arm/farcall-mix.d	24 Feb 2010 17:31:45 -0000
@@ -4,32 +4,34 @@
 Disassembly of section .text:
 
 00001000 <_start>:
-    1000:	eb000009 	bl	102c <__bar_from_arm>
-    1004:	eb00000b 	bl	1038 <__bar2_veneer>
+    1000:	eb000004 	bl	1018 <__bar_from_arm>
+    1004:	eb00000e 	bl	1044 <__bar2_veneer>
     1008:	eb000005 	bl	1024 <__bar3_veneer>
-    100c:	eb00000b 	bl	1040 <__bar4_from_arm>
-    1010:	eb000000 	bl	1018 <__bar5_from_arm>
+    100c:	eb000009 	bl	1038 <__bar4_from_arm>
+    1010:	eb000005 	bl	102c <__bar5_from_arm>
     1014:	00000000 	andeq	r0, r0, r0
 
-00001018 <__bar5_from_arm>:
-    1018:	e59fc000 	ldr	ip, \[pc, #0\]	; 1020 <__bar5_from_arm\+0x8>
+00001018 <__bar_from_arm>:
+    1018:	e59fc000 	ldr	ip, \[pc, #0\]	; 1020 <__bar_from_arm\+0x8>
     101c:	e12fff1c 	bx	ip
-    1020:	0200202f 	.word	0x0200202f
+    1020:	02002021 	.word	0x02002021
 00001024 <__bar3_veneer>:
     1024:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1028 <__bar3_veneer\+0x4>
     1028:	02002028 	.word	0x02002028
-0000102c <__bar_from_arm>:
-    102c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1034 <__bar_from_arm\+0x8>
+0000102c <__bar5_from_arm>:
+    102c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1034 <__bar5_from_arm\+0x8>
     1030:	e12fff1c 	bx	ip
-    1034:	02002021 	.word	0x02002021
-00001038 <__bar2_veneer>:
-    1038:	e51ff004 	ldr	pc, \[pc, #-4\]	; 103c <__bar2_veneer\+0x4>
-    103c:	02002024 	.word	0x02002024
-00001040 <__bar4_from_arm>:
-    1040:	e59fc000 	ldr	ip, \[pc, #0\]	; 1048 <__bar4_from_arm\+0x8>
-    1044:	e12fff1c 	bx	ip
-    1048:	0200202d 	.word	0x0200202d
+    1034:	0200202f 	.word	0x0200202f
+00001038 <__bar4_from_arm>:
+    1038:	e59fc000 	ldr	ip, \[pc, #0\]	; 1040 <__bar4_from_arm\+0x8>
+    103c:	e12fff1c 	bx	ip
+    1040:	0200202d 	.word	0x0200202d
+
+00001044 <__bar2_veneer>:
+    1044:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1048 <__bar2_veneer\+0x4>
+    1048:	02002024 	.word	0x02002024
 	...
+
 Disassembly of section .foo:
 
 02002020 <bar>:
Index: ld/testsuite/ld-arm/farcall-mix2.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mix2.d,v
retrieving revision 1.4
diff -u -p -r1.4 farcall-mix2.d
--- ld/testsuite/ld-arm/farcall-mix2.d	21 Apr 2009 22:05:04 -0000	1.4
+++ ld/testsuite/ld-arm/farcall-mix2.d	24 Feb 2010 17:31:45 -0000
@@ -17,22 +17,25 @@ Disassembly of section .text:
     101c:	00000000 	.word	0x00000000
 Disassembly of section .mytext:
 
-00002000 <__bar5_from_arm-0x10>:
-    2000:	eb000008 	bl	2028 <__bar3_veneer>
-    2004:	eb000004 	bl	201c <__bar4_from_arm>
-    2008:	eb000000 	bl	2010 <__bar5_from_arm>
+00002000 <__bar3_veneer-0x10>:
+    2000:	eb000002 	bl	2010 <__bar3_veneer>
+    2004:	eb000003 	bl	2018 <__bar4_from_arm>
+    2008:	eb000005 	bl	2024 <__bar5_from_arm>
     200c:	00000000 	andeq	r0, r0, r0
-00002010 <__bar5_from_arm>:
-    2010:	e59fc000 	ldr	ip, \[pc, #0\]	; 2018 <__bar5_from_arm\+0x8>
-    2014:	e12fff1c 	bx	ip
-    2018:	0200302f 	.word	0x0200302f
-0000201c <__bar4_from_arm>:
-    201c:	e59fc000 	ldr	ip, \[pc, #0\]	; 2024 <__bar4_from_arm\+0x8>
-    2020:	e12fff1c 	bx	ip
-    2024:	0200302d 	.word	0x0200302d
-00002028 <__bar3_veneer>:
-    2028:	e51ff004 	ldr	pc, \[pc, #-4\]	; 202c <__bar3_veneer\+0x4>
-    202c:	02003028 	.word	0x02003028
+
+00002010 <__bar3_veneer>:
+    2010:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2014 <__bar3_veneer\+0x4>
+    2014:	02003028 	.word	0x02003028
+
+00002018 <__bar4_from_arm>:
+    2018:	e59fc000 	ldr	ip, \[pc, #0\]	; 2020 <__bar4_from_arm\+0x8>
+    201c:	e12fff1c 	bx	ip
+    2020:	0200302d 	.word	0x0200302d
+
+00002024 <__bar5_from_arm>:
+    2024:	e59fc000 	ldr	ip, \[pc, #0\]	; 202c <__bar5_from_arm\+0x8>
+    2028:	e12fff1c 	bx	ip
+    202c:	0200302f 	.word	0x0200302f
 	...
 Disassembly of section .foo:
 
Index: ld/testsuite/ld-arm/farcall-mixed-app-v5.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mixed-app-v5.d,v
retrieving revision 1.5
diff -u -p -r1.5 farcall-mixed-app-v5.d
--- ld/testsuite/ld-arm/farcall-mixed-app-v5.d	20 Nov 2009 15:04:51 -0000	1.5
+++ ld/testsuite/ld-arm/farcall-mixed-app-v5.d	24 Feb 2010 17:31:45 -0000
@@ -49,8 +49,8 @@ Disassembly of section .far_arm:
 .* <app_func>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	push	{fp, ip, lr, pc}
- .*:	eb00000a 	bl	.* <__lib_func1_veneer>
- .*:	eb000007 	bl	.* <__lib_func2_veneer>
+ .*:	eb000008 	bl	.* <__lib_func1_veneer>
+ .*:	eb000009 	bl	.* <__lib_func2_veneer>
  .*:	e89d6800 	ldm	sp, {fp, sp, lr}
  .*:	e12fff1e 	bx	lr
  .*:	e1a00000 	nop			; \(mov r0, r0\)
@@ -62,12 +62,12 @@ Disassembly of section .far_arm:
  .*:	e1a00000 	nop			; \(mov r0, r0\)
  .*:	e1a00000 	nop			; \(mov r0, r0\)
 
-.* <__lib_func2_veneer>:
- .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2100034 <__lib_func2_veneer\+0x4>
- .*:	000081dc 	.word	0x000081dc
 .* <__lib_func1_veneer>:
- .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 210003c <__lib_func1_veneer\+0x4>
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2100034 <__lib_func1_veneer\+0x4>
  .*:	000081e8 	.word	0x000081e8
+.* <__lib_func2_veneer>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 210003c <__lib_func2_veneer\+0x4>
+ .*:	000081dc 	.word	0x000081dc
 
 Disassembly of section .far_thumb:
 
Index: ld/testsuite/ld-arm/farcall-mixed-app.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mixed-app.d,v
retrieving revision 1.5
diff -u -p -r1.5 farcall-mixed-app.d
--- ld/testsuite/ld-arm/farcall-mixed-app.d	20 Nov 2009 15:04:51 -0000	1.5
+++ ld/testsuite/ld-arm/farcall-mixed-app.d	24 Feb 2010 17:31:45 -0000
@@ -51,8 +51,8 @@ Disassembly of section .far_arm:
 .* <app_func>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	push	{fp, ip, lr, pc}
- .*:	eb00000a 	bl	.* <__lib_func1_veneer>
- .*:	eb000007 	bl	.* <__lib_func2_veneer>
+ .*:	eb000008 	bl	.* <__lib_func1_veneer>
+ .*:	eb000009 	bl	.* <__lib_func2_veneer>
  .*:	e89d6800 	ldm	sp, {fp, sp, lr}
  .*:	e12fff1e 	bx	lr
  .*:	e1a00000 	nop			; \(mov r0, r0\)
@@ -64,12 +64,12 @@ Disassembly of section .far_arm:
  .*:	e1a00000 	nop			; \(mov r0, r0\)
  .*:	e1a00000 	nop			; \(mov r0, r0\)
 
-.* <__lib_func2_veneer>:
- .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2100034 <__lib_func2_veneer\+0x4>
- .*:	000081e0 	.word	0x000081e0
 .* <__lib_func1_veneer>:
- .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 210003c <__lib_func1_veneer\+0x4>
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2100034 <__lib_func1_veneer\+0x4>
  .*:	000081ec 	.word	0x000081ec
+.* <__lib_func2_veneer>:
+ .*:	e51ff004 	ldr	pc, \[pc, #-4\]	; 210003c <__lib_func2_veneer\+0x4>
+ .*:	000081e0 	.word	0x000081e0
 
 Disassembly of section .far_thumb:
 
Index: ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d
===================================================================
RCS file: ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d
diff -N ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d	24 Feb 2010 17:31:45 -0000
@@ -0,0 +1,123 @@
+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\]!
+ .*:	.* 	.word	.*
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e28fc6.* 	add	ip, pc, #.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!	; .*
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e28fc6.* 	add	ip, pc, #.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!	; 0x.*
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e28fc6.* 	add	ip, pc, #.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!	; 0x.*
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e28fc6.* 	add	ip, pc, #.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!	; 0x.*
+
+Disassembly of section .text:
+
+.* <lib_func1>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	push	{fp, ip, lr, pc}
+ .*:	ebffff.. 	bl	.* <lib_func1-0x.*>
+ .*:	ebffff.. 	bl	.* <lib_func1-0x.*>
+ .*:	ebffff.. 	bl	.* <lib_func1-0x.*>
+ .*:	ebffff.. 	bl	.* <lib_func1-0x.*>
+ .*:	e89d6800 	ldm	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+	...
+
+.* <__real_lib_func2>:
+ .*:	f000 f80e 	bl	1000330 <__app_func_from_thumb>
+ .*:	f000 f81c 	bl	1000350 <__app_func_weak_from_thumb>
+ .*:	f000 f822 	bl	1000360 <__lib_func3_from_thumb>
+ .*:	f000 f810 	bl	1000340 <__lib_func4_from_thumb>
+ .*:	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\)
+
+.* <__app_func_from_thumb>:
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 100033c <__app_func_from_thumb\+0xc>
+ .*:	e08cf00f 	add	pc, ip, pc
+ .*:	feffff68 	.word	0xfeffff68
+
+.* <__lib_func4_from_thumb>:
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 100034c <__lib_func4_from_thumb\+0xc>
+ .*:	e08cf00f 	add	pc, ip, pc
+ .*:	feffff88 	.word	0xfeffff88
+
+.* <__app_func_weak_from_thumb>:
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 100035c <__app_func_weak_from_thumb\+0xc>
+ .*:	e08cf00f 	add	pc, ip, pc
+ .*:	feffff58 	.word	0xfeffff58
+
+.* <__lib_func3_from_thumb>:
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 100036c <__lib_func3_from_thumb\+0xc>
+ .*:	e08cf00f 	add	pc, ip, pc
+ .*:	feffff58 	.word	0xfeffff58
+	...
+
+.* <__real_lib_func3>:
+ .*:	f000 f806 	bl	2000380 <__app_func_from_thumb>
+ .*:	f000 f80c 	bl	2000390 <__app_func_weak_from_thumb>
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	46c0      	nop			; \(mov r8, r8\)
+
+.* <__app_func_from_thumb>:
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 200038c <__app_func_from_thumb\+0xc>
+ .*:	e08cf00f 	add	pc, ip, pc
+ .*:	fdffff18 	.word	0xfdffff18
+
+.* <__app_func_weak_from_thumb>:
+ .*:	4778      	bx	pc
+ .*:	46c0      	nop			; \(mov r8, r8\)
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 200039c <__app_func_weak_from_thumb\+0xc>
+ .*:	e08cf00f 	add	pc, ip, pc
+ .*:	fdffff18 	.word	0xfdffff18
+
+.* <lib_func3>:
+ .*:	e59fc004 	ldr	ip, \[pc, #4\]	; 20003ac <lib_func3\+0xc>
+ .*:	e08cc00f 	add	ip, ip, pc
+ .*:	e12fff1c 	bx	ip
+ .*:	ffffffc5 	.word	0xffffffc5
+
+.* <lib_func2>:
+ .*:	e59fc004 	ldr	ip, \[pc, #4\]	; 20003bc <lib_func2\+0xc>
+ .*:	e08cc00f 	add	ip, ip, pc
+ .*:	e12fff1c 	bx	ip
+ .*:	feffff55 	.word	0xfeffff55
Index: ld/testsuite/ld-arm/farcall-mixed-lib.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mixed-lib.d,v
retrieving revision 1.8
diff -u -p -r1.8 farcall-mixed-lib.d
--- ld/testsuite/ld-arm/farcall-mixed-lib.d	20 Nov 2009 15:04:51 -0000	1.8
+++ ld/testsuite/ld-arm/farcall-mixed-lib.d	24 Feb 2010 17:31:45 -0000
@@ -38,10 +38,10 @@ Disassembly of section .text:
 	...
 
 .* <lib_func2>:
- .*:	f000 e80e 	blx	1000320 <__app_func_from_thumb>
- .*:	f000 e81a 	blx	100033c <__app_func_weak_from_thumb>
- .*:	f000 e810 	blx	100032c <__lib_func3_veneer>
- .*:	f000 e81c 	blx	1000348 <__lib_func4_from_thumb>
+ .*:	f000 e820 	blx	1000344 <__app_func_from_thumb>
+ .*:	f000 e812 	blx	100032c <__app_func_weak_from_thumb>
+ .*:	f000 e80a 	blx	1000320 <__lib_func3_from_thumb>
+ .*:	f000 e814 	blx	1000338 <__lib_func4_from_thumb>
  .*:	4770      	bx	lr
  .*:	46c0      	nop			; \(mov r8, r8\)
  .*:	46c0      	nop			; \(mov r8, r8\)
@@ -51,43 +51,42 @@ Disassembly of section .text:
  .*:	46c0      	nop			; \(mov r8, r8\)
  .*:	46c0      	nop			; \(mov r8, r8\)
 
-.* <__app_func_from_thumb>:
- .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000328 <__app_func_from_thumb\+0x8>
+.* <__lib_func3_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000328 <__lib_func3_from_thumb\+0x8>
  .*:	e08ff00c 	add	pc, pc, ip
- .*:	feffff78 	.word	0xfeffff78
-
-.* <__lib_func3_veneer>:
- .*:	e59fc004 	ldr	ip, \[pc, #4\]	; 1000338 <__lib_func3_veneer\+0xc>
- .*:	e08fc00c 	add	ip, pc, ip
- .*:	e12fff1c 	bx	ip
- .*:	feffff85 	.word	0xfeffff85
+ .*:	feffff90 	.word	0xfeffff90
 
 .* <__app_func_weak_from_thumb>:
- .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000344 <__app_func_weak_from_thumb\+0x8>
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000334 <__app_func_weak_from_thumb\+0x8>
  .*:	e08ff00c 	add	pc, pc, ip
- .*:	feffff68 	.word	0xfeffff68
+ .*:	feffff78 	.word	0xfeffff78
 
 .* <__lib_func4_from_thumb>:
- .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000350 <__lib_func4_from_thumb\+0x8>
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000340 <__lib_func4_from_thumb\+0x8>
  .*:	e08ff00c 	add	pc, pc, ip
- .*:	feffff74 	.word	0xfeffff74
+ .*:	feffff84 	.word	0xfeffff84
+
+.* <__app_func_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 100034c <__app_func_from_thumb\+0x8>
+ .*:	e08ff00c 	add	pc, pc, ip
+ .*:	feffff54 	.word	0xfeffff54
 	...
 
 .* <lib_func3>:
- .*:	f000 e80c 	blx	200037c <__app_func_from_thumb>
- .*:	f000 e804 	blx	2000370 <__app_func_weak_from_thumb>
+ .*:	f000 e806 	blx	2000370 <__app_func_from_thumb>
+ .*:	f000 e80a 	blx	200037c <__app_func_weak_from_thumb>
  .*:	4770      	bx	lr
  .*:	46c0      	nop			; \(mov r8, r8\)
  .*:	46c0      	nop			; \(mov r8, r8\)
  .*:	46c0      	nop			; \(mov r8, r8\)
 
-.* <__app_func_weak_from_thumb>:
- .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 2000378 <__app_func_weak_from_thumb\+0x8>
+.* <__app_func_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 2000378 <__app_func_from_thumb\+0x8>
  .*:	e08ff00c 	add	pc, pc, ip
- .*:	fdffff34 	.word	0xfdffff34
+ .*:	fdffff28 	.word	0xfdffff28
 
-.* <__app_func_from_thumb>:
- .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 2000384 <__app_func_from_thumb\+0x8>
+.* <__app_func_weak_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 2000384 <__app_func_weak_from_thumb\+0x8>
  .*:	e08ff00c 	add	pc, pc, ip
- .*:	fdffff1c 	.word	0xfdffff1c
+ .*:	fdffff28 	.word	0xfdffff28
 	...
Index: ld/testsuite/ld-arm/farcall-mixed-lib1.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mixed-lib1.s,v
retrieving revision 1.2
diff -u -p -r1.2 farcall-mixed-lib1.s
--- ld/testsuite/ld-arm/farcall-mixed-lib1.s	22 Jun 2009 10:55:33 -0000	1.2
+++ ld/testsuite/ld-arm/farcall-mixed-lib1.s	24 Feb 2010 17:31:45 -0000
@@ -3,7 +3,6 @@
 @ Check also calls to an undef weak symbol.
 
 	.text
-	.arch armv5t
 
 	.p2align 4
 	.globl lib_func1
Index: ld/testsuite/ld-arm/farcall-mixed-lib2.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mixed-lib2.s,v
retrieving revision 1.1
diff -u -p -r1.1 farcall-mixed-lib2.s
--- ld/testsuite/ld-arm/farcall-mixed-lib2.s	17 Apr 2009 13:04:41 -0000	1.1
+++ ld/testsuite/ld-arm/farcall-mixed-lib2.s	24 Feb 2010 17:31:45 -0000
@@ -3,7 +3,6 @@
 @ Check also calls to an undef weak symbol.
 
 	.text
-	.arch armv5t
 
 	.space 0x1000000
 	.p2align 4
Index: ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d,v
retrieving revision 1.5
diff -u -p -r1.5 farcall-thumb-arm-blx-pic-veneer.d
--- ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d	24 Feb 2009 22:43:10 -0000	1.5
+++ ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d	24 Feb 2010 17:31:45 -0000
@@ -2,16 +2,16 @@
 
 Disassembly of section .text:
 
-00001000 <_start>:
-    1000:	f000 e802 	blx	1008 <__bar_from_thumb>
-    1004:	0000      	lsls	r0, r0, #0
+01c01010 <_start>:
+ 1c01010:	f300 e802 	blx	1f01018 <__bar_from_thumb>
 	\.\.\.
+ 1f01014:	f0ff effe 	blx	2001014 <bar>
 
-00001008 <__bar_from_thumb>:
-    1008:	e59fc000 	ldr	ip, \[pc, #0\]	; 1010 <__bar_from_thumb\+0x8>
-    100c:	e08ff00c 	add	pc, pc, ip
-    1010:	02000000 	.word	0x02000000
-    1014:	00000000 	.word	0x00000000
+01f01018 <__bar_from_thumb>:
+ 1f01018:	e59fc000 	ldr	ip, \[pc, #0\]	; 1f01020 <__bar_from_thumb\+0x8>
+ 1f0101c:	e08ff00c 	add	pc, pc, ip
+ 1f01020:	000ffff0 	.word	0x000ffff0
+ 1f01024:	00000000 	.word	0x00000000
 Disassembly of section .foo:
 
 02001014 <bar>:
Index: ld/testsuite/ld-arm/farcall-thumb-arm-blx.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm-blx.d,v
retrieving revision 1.4
diff -u -p -r1.4 farcall-thumb-arm-blx.d
--- ld/testsuite/ld-arm/farcall-thumb-arm-blx.d	24 Feb 2009 22:43:10 -0000	1.4
+++ ld/testsuite/ld-arm/farcall-thumb-arm-blx.d	24 Feb 2010 17:31:45 -0000
@@ -2,14 +2,14 @@
 
 Disassembly of section .text:
 
-00001000 <_start>:
-    1000:	f000 e802 	blx	1008 <__bar_from_thumb>
-    1004:	0000      	lsls	r0, r0, #0
+01c01010 <_start>:
+ 1c01010:	f300 e802 	blx	1f01018 <__bar_from_thumb>
 	\.\.\.
+ 1f01014:	f0ff effe 	blx	2001014 <bar>
 
-00001008 <__bar_from_thumb>:
-    1008:	e51ff004 	ldr	pc, \[pc, #-4\]	; 100c <__bar_from_thumb\+0x4>
-    100c:	02001014 	.word	0x02001014
+01f01018 <__bar_from_thumb>:
+ 1f01018:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1f0101c <__bar_from_thumb\+0x4>
+ 1f0101c:	02001014 	.word	0x02001014
 Disassembly of section .foo:
 
 02001014 <bar>:
Index: ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d,v
retrieving revision 1.4
diff -u -p -r1.4 farcall-thumb-arm-pic-veneer.d
--- ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d	30 Jun 2009 11:57:05 -0000	1.4
+++ ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d	24 Feb 2010 17:31:45 -0000
@@ -2,17 +2,17 @@
 
 Disassembly of section .text:
 
-00001000 <_start>:
-    1000:	f000 f802 	bl	1008 <__bar_from_thumb>
-    1004:	0000      	lsls	r0, r0, #0
+01c01010 <_start>:
+ 1c01010:	f300 f802 	bl	1f01018 <__bar_from_thumb>
 	...
+ 1f01014:	f000 f800 	bl	1f01018 <__bar_from_thumb>
 
-00001008 <__bar_from_thumb>:
-    1008:	4778      	bx	pc
-    100a:	46c0      	nop			; \(mov r8, r8\)
-    100c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1014 <__bar_from_thumb\+0xc>
-    1010:	e08cf00f 	add	pc, ip, pc
-    1014:	01fffffc 	.word	0x01fffffc
+01f01018 <__bar_from_thumb>:
+ 1f01018:	4778      	bx	pc
+ 1f0101a:	46c0      	nop			; \(mov r8, r8\)
+ 1f0101c:	e59fc000 	ldr	ip, \[pc, #0\]	; 1f01024 <__bar_from_thumb\+0xc>
+ 1f01020:	e08cf00f 	add	pc, ip, pc
+ 1f01024:	000fffec 	.word	0x000fffec
 
 Disassembly of section .foo:
 
Index: ld/testsuite/ld-arm/farcall-thumb-arm.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm.d,v
retrieving revision 1.7
diff -u -p -r1.7 farcall-thumb-arm.d
--- ld/testsuite/ld-arm/farcall-thumb-arm.d	30 Jun 2009 11:57:05 -0000	1.7
+++ ld/testsuite/ld-arm/farcall-thumb-arm.d	24 Feb 2010 17:31:45 -0000
@@ -2,17 +2,23 @@
 
 Disassembly of section .text:
 
-00001000 <_start>:
-    1000:	f000 f802 	bl	1008 <__bar_from_thumb>
-    1004:	0000      	lsls	r0, r0, #0
+01c01010 <_start>:
+ 1c01010:	f300 f802 	bl	1f01018 <__bar_from_thumb>
 	\.\.\.
+ 1f01014:	f000 f806 	bl	1f01024 <__bar_from_thumb>
+
+01f01018 <__bar_from_thumb>:
+ 1f01018:	4778      	bx	pc
+ 1f0101a:	46c0      	nop			; \(mov r8, r8\)
+ 1f0101c:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1f01020 <__bar_from_thumb\+0x8>
+ 1f01020:	02001014 	.word	0x02001014
+
+01f01024 <__bar_from_thumb>:
+ 1f01024:	4778      	bx	pc
+ 1f01026:	46c0      	nop			; \(mov r8, r8\)
+ 1f01028:	ea03fff9 	b	2001014 <bar>
+ 1f0102c:	00000000 	andeq	r0, r0, r0
 
-00001008 <__bar_from_thumb>:
-    1008:	4778      	bx	pc
-    100a:	46c0      	nop			; \(mov r8, r8\)
-    100c:	e51ff004 	ldr	pc, \[pc, #-4\]	; 1010 <__bar_from_thumb\+0x8>
-    1010:	02001014 	.word	0x02001014
-    1014:	00000000 	.word	0x00000000
 Disassembly of section .foo:
 
 02001014 <bar>:
Index: ld/testsuite/ld-arm/farcall-thumb-arm.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm.s,v
retrieving revision 1.2
diff -u -p -r1.2 farcall-thumb-arm.s
--- ld/testsuite/ld-arm/farcall-thumb-arm.s	23 May 2008 13:53:27 -0000	1.2
+++ ld/testsuite/ld-arm/farcall-thumb-arm.s	24 Feb 2010 17:31:45 -0000
@@ -1,13 +1,19 @@
 @ Test to ensure that a Thumb to ARM call exceeding 4Mb generates a stub.
+@ Check that we can generate two types of stub in the same section.
 
 	.global _start
 	.syntax unified
 
-@ We will place the section .text at 0x1000.
+@ We will place the section .text at 0x1c01010.
 
 	.text
 	.thumb_func
 _start:
+	.global bar
+	bl bar
+@ This call is close enough to generate a "short branch" stub
+@ or no stub if blx is available.
+	.space 0x0300000
 	bl bar
 
 @ We will place the section .foo at 0x2001014.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-02-24 18:45                   ` Christophe LYON
@ 2010-03-01 17:45                     ` Nick Clifton
  2010-03-02  9:15                       ` Christophe LYON
  0 siblings, 1 reply; 15+ messages in thread
From: Nick Clifton @ 2010-03-01 17:45 UTC (permalink / raw)
  To: Christophe LYON; +Cc: binutils

Hi Christophe,

> 2010-02-24  Christophe Lyon  <christophe.lyon@st.com>
> 	Alan Modra  <amodra@gmail.com>
>
> 	bfd/
> 	* elf32-arm.c (a8_erratum_fix): Add st_type field to record the
> 	destination mode of the a8 stub.
> 	(elf32_arm_link_hash_table): Add top_id field.
> 	(elf32_arm_link_hash_table_create): Initialize top_id.
> 	(arm_type_of_stub): Update prototype, st_type can now be updated
> 	by this function. Actual destination address in case of PLT is
> 	computed here, to help factorizing code.
> 	(elf32_arm_stub_name): Update prototype, use stub_type additional
> 	parameter to build stub name.
> 	(elf32_arm_get_stub_entry): Update prototype, use stub_type
> 	additional parameter to build stub entry.
> 	(arm_build_one_stub): Use bfd_put_16/bfd_put_32 instead of
> 	put_thumb_insn/put_arm_insn as BE8 encoding is now handled later.
> 	Call elf32_arm_final_link_relocate to process all in-stub
> 	relocations.
> 	(elf32_arm_setup_section_lists): Update top_id.
> 	(cortex_a8_erratum_scan): Record stub destination mode.
> 	(elf32_arm_size_stubs): Update call to arm_type_of_stub according
> 	to new prototype.
> 	(elf32_arm_final_link_relocate): Enable processing of in-stub
> 	REL32 relocations. Rely on arm_type_of_stub to detect if a stub is
> 	needed, enabling code factorization.
> 	(elf32_arm_final_link): Process stub sections.
> 	(elf32_arm_output_map_sym): Add entry to code/data map.
>
> 	ld/testsuite/
> 	* ld-arm/arm-elf.exp: Change .text start address for
> 	farcall-thumb-arm tests. Add v4t variant for farcall-mixed-lib
> 	test.
> 	* ld-arm/farcall-mixed-lib-v4t.d: New test.
> 	* ld-arm/farcall-mixed-lib1.s: Don't force armv5t.
> 	* ld-arm/farcall-mixed-lib2.s: Likewise.
> 	* ld-arm/arm-call.d: Update expected results.
> 	* ld-arm/cortex-a8-far.d: Likewise.
> 	* ld-arm/farcall-group-size2.d: Likewise.
> 	* ld-arm/farcall-group.d: Likewise.
> 	* ld-arm/farcall-mix.d: Likewise.
> 	* ld-arm/farcall-mix2.d: Likewise.
> 	* ld-arm/farcall-mixed-app-v5.d: Likewise.
> 	* ld-arm/farcall-mixed-app.d: Likewise.
> 	* ld-arm/farcall-mixed-lib.d: Likewise.
> 	* ld-arm/farcall-thumb-arm.d: Likewise.
> 	* ld-arm/farcall-thumb-arm-blx.d: Likewise.
> 	* ld-arm/farcall-thumb-arm-pic-veneer.d: Likewise.
> 	* ld-arm/farcall-thumb-arm-blx-pic-veneer.d: Likewise.
> 	* ld-arm/farcall-thumb-arm.s: Update test. Add a new call to
> 	potentially generate different types of stubs.


Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: ARM stub sizing fix
  2010-03-01 17:45                     ` Nick Clifton
@ 2010-03-02  9:15                       ` Christophe LYON
  0 siblings, 0 replies; 15+ messages in thread
From: Christophe LYON @ 2010-03-02  9:15 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils


>
> Approved - please apply.
>

Thanks, committed.

Christophe.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2010-03-02  9:15 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-14 11:55 ARM stub sizing fix Alan Modra
2010-01-14 14:10 ` Daniel Jacobowitz
2010-01-14 14:47   ` Alan Modra
2010-01-14 15:11     ` Daniel Jacobowitz
2010-01-14 15:34       ` Alan Modra
2010-01-14 19:48         ` Daniel Jacobowitz
2010-01-14 23:53           ` Alan Modra
2010-01-19 10:09             ` Christophe LYON
2010-02-04 16:26               ` Matthew Gretton-Dann
2010-02-04 16:37                 ` Christophe LYON
2010-02-05  2:15                 ` Alan Modra
2010-02-05  5:32                 ` Alan Modra
2010-02-24 18:45                   ` Christophe LYON
2010-03-01 17:45                     ` Nick Clifton
2010-03-02  9:15                       ` Christophe LYON

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).