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: [PATCH, ARM] Work around Cortex-A8 erratum in linker


On Thu, 21 May 2009 15:46:19 +0100
Richard Earnshaw <rearnsha@arm.com> wrote:

> OK.

This is the version I've committed, since the underlying code shifted
around a bit in the last couple of weeks and the submitted version
didn't apply cleanly any more.

Julian
? bfd/elf32-arm.c-partially-fixed
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.143
diff -c -p -r1.143 bfd-in.h
*** bfd/bfd-in.h	5 May 2009 14:18:29 -0000	1.143
--- bfd/bfd-in.h	22 May 2009 11:42:39 -0000
*************** extern void bfd_elf32_arm_init_maps
*** 825,830 ****
--- 825,833 ----
  extern void bfd_elf32_arm_set_vfp11_fix
    (bfd *, struct bfd_link_info *);
  
+ extern void bfd_elf32_arm_set_cortex_a8_fix
+   (bfd *, struct bfd_link_info *);
+ 
  extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan
    (bfd *, struct bfd_link_info *);
  
*************** extern bfd_boolean bfd_elf32_arm_process
*** 860,866 ****
  
  void bfd_elf32_arm_set_target_relocs
    (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
!    int, int, int);
  
  extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
    (bfd *, struct bfd_link_info *);
--- 863,869 ----
  
  void bfd_elf32_arm_set_target_relocs
    (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
!    int, int, int, int);
  
  extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
    (bfd *, struct bfd_link_info *);
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.479
diff -c -p -r1.479 bfd-in2.h
*** bfd/bfd-in2.h	5 May 2009 14:18:29 -0000	1.479
--- bfd/bfd-in2.h	22 May 2009 11:42:39 -0000
*************** extern void bfd_elf32_arm_init_maps
*** 832,837 ****
--- 832,840 ----
  extern void bfd_elf32_arm_set_vfp11_fix
    (bfd *, struct bfd_link_info *);
  
+ extern void bfd_elf32_arm_set_cortex_a8_fix
+   (bfd *, struct bfd_link_info *);
+ 
  extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan
    (bfd *, struct bfd_link_info *);
  
*************** extern bfd_boolean bfd_elf32_arm_process
*** 867,873 ****
  
  void bfd_elf32_arm_set_target_relocs
    (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
!    int, int, int);
  
  extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
    (bfd *, struct bfd_link_info *);
--- 870,876 ----
  
  void bfd_elf32_arm_set_target_relocs
    (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
!    int, int, int, int);
  
  extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
    (bfd *, struct bfd_link_info *);
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.195
diff -c -p -r1.195 elf32-arm.c
*** bfd/elf32-arm.c	21 May 2009 14:15:48 -0000	1.195
--- bfd/elf32-arm.c	22 May 2009 11:42:39 -0000
*************** enum stub_insn_type
*** 2026,2036 ****
      DATA_TYPE
    };
  
! #define THUMB16_INSN(X)    {(X), THUMB16_TYPE, R_ARM_NONE, 0}
! #define THUMB32_INSN(X)    {(X), THUMB32_TYPE, R_ARM_NONE, 0}
! #define ARM_INSN(X)        {(X), ARM_TYPE, R_ARM_NONE, 0}
! #define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)}
! #define DATA_WORD(X,Y,Z)   {(X), DATA_TYPE, (Y), (Z)}
  
  typedef struct
  {
--- 2026,2040 ----
      DATA_TYPE
    };
  
! #define THUMB16_INSN(X)		{(X), THUMB16_TYPE, R_ARM_NONE, 0}
! /* A bit of a hack.  A Thumb conditional branch, in which the proper condition
!    is inserted in arm_build_one_stub().  */
! #define THUMB16_BCOND_INSN(X)	{(X), THUMB16_TYPE, R_ARM_NONE, 1}
! #define THUMB32_INSN(X)		{(X), THUMB32_TYPE, R_ARM_NONE, 0}
! #define THUMB32_B_INSN(X, Z)	{(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)}
! #define ARM_INSN(X)		{(X), ARM_TYPE, R_ARM_NONE, 0}
! #define ARM_REL_INSN(X, Z)	{(X), ARM_TYPE, R_ARM_JUMP24, (Z)}
! #define DATA_WORD(X,Y,Z)	{(X), DATA_TYPE, (Y), (Z)}
  
  typedef struct
  {
*************** static const insn_sequence elf32_arm_stu
*** 2164,2169 ****
--- 2168,2206 ----
      DATA_WORD(0, R_ARM_REL32, 0),     /* dcd  R_ARM_REL32(X) */
    };
  
+ /* Cortex-A8 erratum-workaround stubs.  */
+ 
+ /* Stub used for conditional branches (which may be beyond +/-1MB away, so we
+    can't use a conditional branch to reach this stub).  */
+ 
+ static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] =
+   {
+     THUMB16_BCOND_INSN(0xd001),         /* b<cond>.n true.  */
+     THUMB32_B_INSN(0xf000b800, -4),     /* b.w insn_after_original_branch.  */
+     THUMB32_B_INSN(0xf000b800, -4)      /* true: b.w original_branch_dest.  */
+   };
+ 
+ /* Stub used for b.w and bl.w instructions.  */
+ 
+ static const insn_sequence elf32_arm_stub_a8_veneer_b[] =
+   {
+     THUMB32_B_INSN(0xf000b800, -4)	/* b.w original_branch_dest.  */
+   };
+ 
+ static const insn_sequence elf32_arm_stub_a8_veneer_bl[] =
+   {
+     THUMB32_B_INSN(0xf000b800, -4)	/* b.w original_branch_dest.  */
+   };
+ 
+ /* Stub used for Thumb-2 blx.w instructions.  We modified the original blx.w
+    instruction (which switches to ARM mode) to point to this stub.  Jump to the
+    real destination using an ARM-mode branch.  */
+ 
+ static const insn_sequence elf32_arm_stub_a8_veneer_blx[] =
+   {
+     ARM_REL_INSN(0xea000000, -8)	/* b original_branch_dest.  */
+   };
+ 
  /* Section name for stubs is the associated section name plus this
     string.  */
  #define STUB_SUFFIX ".stub"
*************** static const insn_sequence elf32_arm_stu
*** 2181,2187 ****
    DEF_STUB(long_branch_v4t_thumb_thumb_pic) \
    DEF_STUB(long_branch_v4t_arm_thumb_pic) \
    DEF_STUB(long_branch_v4t_thumb_arm_pic) \
!   DEF_STUB(long_branch_thumb_only_pic)
  
  #define DEF_STUB(x) arm_stub_##x,
  enum elf32_arm_stub_type {
--- 2218,2228 ----
    DEF_STUB(long_branch_v4t_thumb_thumb_pic) \
    DEF_STUB(long_branch_v4t_arm_thumb_pic) \
    DEF_STUB(long_branch_v4t_thumb_arm_pic) \
!   DEF_STUB(long_branch_thumb_only_pic) \
!   DEF_STUB(a8_veneer_b_cond) \
!   DEF_STUB(a8_veneer_b) \
!   DEF_STUB(a8_veneer_bl) \
!   DEF_STUB(a8_veneer_blx)
  
  #define DEF_STUB(x) arm_stub_##x,
  enum elf32_arm_stub_type {
*************** struct elf32_arm_stub_hash_entry
*** 2218,2223 ****
--- 2259,2271 ----
    bfd_vma target_value;
    asection *target_section;
  
+   /* Offset to apply to relocation referencing target_value.  */
+   bfd_vma target_addend;
+ 
+   /* The instruction which caused this stub to be generated (only valid for
+      Cortex-A8 erratum workaround stubs at present).  */
+   unsigned long orig_insn;
+ 
    /* The stub type.  */
    enum elf32_arm_stub_type stub_type;
    /* Its encoding size in bytes.  */
*************** _arm_elf_section_data;
*** 2337,2342 ****
--- 2385,2418 ----
  #define elf32_arm_section_data(sec) \
    ((_arm_elf_section_data *) elf_section_data (sec))
  
+ /* A fix which might be required for Cortex-A8 Thumb-2 branch/TLB erratum.
+    These fixes are subject to a relaxation procedure (in elf32_arm_size_stubs),
+    so may be created multiple times: we use an array of these entries whilst
+    relaxing which we can refresh easily, then create stubs for each potentially
+    erratum-triggering instruction once we've settled on a solution.  */
+ 
+ struct a8_erratum_fix {
+   bfd *input_bfd;
+   asection *section;
+   bfd_vma offset;
+   bfd_vma addend;
+   unsigned long orig_insn;
+   char *stub_name;
+   enum elf32_arm_stub_type stub_type;
+ };
+ 
+ /* A table of relocs applied to branches which might trigger Cortex-A8
+    erratum.  */
+ 
+ struct a8_erratum_reloc {
+   bfd_vma from;
+   bfd_vma destination;
+   unsigned int r_type;
+   unsigned char st_type;
+   const char *sym_name;
+   bfd_boolean non_a8_stub;
+ };
+ 
  /* The size of the thread control block.  */
  #define TCB_SIZE	8
  
*************** struct elf32_arm_link_hash_table
*** 2468,2473 ****
--- 2544,2555 ----
       veneers.  */
    bfd_size_type vfp11_erratum_glue_size;
  
+   /* A table of fix locations for Cortex-A8 Thumb-2 branch/TLB erratum.  This
+      holds Cortex-A8 erratum fix locations between elf32_arm_size_stubs() and
+      elf32_arm_write_section().  */
+   struct a8_erratum_fix *a8_erratum_fixes;
+   unsigned int num_a8_erratum_fixes;
+ 
    /* An arbitrary input BFD chosen to hold the glue sections.  */
    bfd * bfd_of_glue_owner;
  
*************** struct elf32_arm_link_hash_table
*** 2486,2491 ****
--- 2568,2576 ----
       2 = Generate v4 interworing stubs.  */
    int fix_v4bx;
  
+   /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum.  */
+   int fix_cortex_a8;
+ 
    /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
    int use_blx;
  
*************** elf32_arm_link_hash_table_create (bfd *a
*** 2825,2830 ****
--- 2910,2916 ----
    ret->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
    ret->vfp11_erratum_glue_size = 0;
    ret->num_vfp11_fixes = 0;
+   ret->fix_cortex_a8 = 0;
    ret->bfd_of_glue_owner = NULL;
    ret->byteswap_code = 0;
    ret->target1_is_rel = 0;
*************** elf32_arm_get_stub_entry (const asection
*** 3214,3230 ****
    return stub_entry;
  }
  
! /* Add a new stub entry to the stub hash.  Not all fields of the new
!    stub entry are initialised.  */
  
! static struct elf32_arm_stub_hash_entry *
! elf32_arm_add_stub (const char *stub_name,
! 		    asection *section,
! 		    struct elf32_arm_link_hash_table *htab)
  {
    asection *link_sec;
    asection *stub_sec;
-   struct elf32_arm_stub_hash_entry *stub_entry;
  
    link_sec = htab->stub_group[section->id].link_sec;
    stub_sec = htab->stub_group[section->id].stub_sec;
--- 3300,3315 ----
    return stub_entry;
  }
  
! /* Find or create a stub section.  Returns a pointer to the stub section, and
!    the section to which the stub section will be attached (in *LINK_SEC_P). 
!    LINK_SEC_P may be NULL.  */
  
! static asection *
! elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
! 				   struct elf32_arm_link_hash_table *htab)
  {
    asection *link_sec;
    asection *stub_sec;
  
    link_sec = htab->stub_group[section->id].link_sec;
    stub_sec = htab->stub_group[section->id].stub_sec;
*************** elf32_arm_add_stub (const char *stub_nam
*** 3252,3257 ****
--- 3337,3364 ----
  	}
        htab->stub_group[section->id].stub_sec = stub_sec;
      }
+   
+   if (link_sec_p)
+     *link_sec_p = link_sec;
+   
+   return stub_sec;
+ }
+ 
+ /* Add a new stub entry to the stub hash.  Not all fields of the new
+    stub entry are initialised.  */
+ 
+ static struct elf32_arm_stub_hash_entry *
+ elf32_arm_add_stub (const char *stub_name,
+ 		    asection *section,
+ 		    struct elf32_arm_link_hash_table *htab)
+ {
+   asection *link_sec;
+   asection *stub_sec;
+   struct elf32_arm_stub_hash_entry *stub_entry;
+ 
+   stub_sec = elf32_arm_create_or_find_stub_sec (&link_sec, section, htab);
+   if (stub_sec == NULL)
+     return NULL;
  
    /* Enter this entry into the linker stub hash table.  */
    stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
*************** put_thumb_insn (struct elf32_arm_link_ha
*** 3297,3306 ****
--- 3404,3419 ----
      bfd_putb16 (val, ptr);
  }
  
+ static bfd_reloc_status_type elf32_arm_final_link_relocate
+   (reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
+    Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,
+    const char *, int, struct elf_link_hash_entry *, bfd_boolean *, char **);
+ 
  static bfd_boolean
  arm_build_one_stub (struct bfd_hash_entry *gen_entry,
  		    void * in_arg)
  {
+ #define MAXRELOCS 2
    struct elf32_arm_stub_hash_entry *stub_entry;
    struct bfd_link_info *info;
    struct elf32_arm_link_hash_table *htab;
*************** arm_build_one_stub (struct bfd_hash_entr
*** 3314,3321 ****
    const insn_sequence *template;
    int i;
    struct elf32_arm_link_hash_table * globals;
!   int stub_reloc_idx = -1;
!   int stub_reloc_offset = 0;
  
    /* Massage our args to the form they really have.  */
    stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
--- 3427,3435 ----
    const insn_sequence *template;
    int i;
    struct elf32_arm_link_hash_table * globals;
!   int stub_reloc_idx[MAXRELOCS] = {-1, -1};
!   int stub_reloc_offset[MAXRELOCS] = {0, 0};
!   int nrelocs = 0;
  
    /* Massage our args to the form they really have.  */
    stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
*************** arm_build_one_stub (struct bfd_hash_entr
*** 3350,3375 ****
        switch (template[i].type)
  	{
  	case THUMB16_TYPE:
! 	  put_thumb_insn (globals, stub_bfd, template[i].data, loc + size);
! 	  size += 2;
  	  break;
  
  	case ARM_TYPE:
  	  put_arm_insn (globals, stub_bfd, template[i].data, loc + size);
  	  /* Handle cases where the target is encoded within the
  	     instruction.  */
  	  if (template[i].r_type == R_ARM_JUMP24)
  	    {
! 	      stub_reloc_idx = i;
! 	      stub_reloc_offset = size;
  	    }
  	  size += 4;
  	  break;
  
  	case DATA_TYPE:
  	  bfd_put_32 (stub_bfd, template[i].data, loc + size);
! 	  stub_reloc_idx = i;
! 	  stub_reloc_offset = size;
  	  size += 4;
  	  break;
  
--- 3464,3513 ----
        switch (template[i].type)
  	{
  	case THUMB16_TYPE:
! 	  {
! 	    bfd_vma data = template[i].data;
! 	    if (template[i].reloc_addend != 0)
! 	      {
!                 /* We've borrowed the reloc_addend field to mean we should
!                    insert a condition code into this (Thumb-1 branch)
!                    instruction.  See THUMB16_BCOND_INSN.  */
!                 BFD_ASSERT ((data & 0xff00) == 0xd000);
!                 data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8;
! 	      }
! 	    put_thumb_insn (globals, stub_bfd, data, loc + size);
! 	    size += 2;
! 	  }
  	  break;
  
+ 	case THUMB32_TYPE:
+           put_thumb_insn (globals, stub_bfd, (template[i].data >> 16) & 0xffff,
+                           loc + size);
+           put_thumb_insn (globals, stub_bfd, template[i].data & 0xffff,
+                           loc + size + 2);
+           if (template[i].r_type != R_ARM_NONE)
+             {
+               stub_reloc_idx[nrelocs] = i;
+               stub_reloc_offset[nrelocs++] = size;
+             }
+           size += 4;
+           break;
+ 
  	case ARM_TYPE:
  	  put_arm_insn (globals, stub_bfd, template[i].data, loc + size);
  	  /* Handle cases where the target is encoded within the
  	     instruction.  */
  	  if (template[i].r_type == R_ARM_JUMP24)
  	    {
! 	      stub_reloc_idx[nrelocs] = i;
! 	      stub_reloc_offset[nrelocs++] = size;
  	    }
  	  size += 4;
  	  break;
  
  	case DATA_TYPE:
  	  bfd_put_32 (stub_bfd, template[i].data, loc + size);
! 	  stub_reloc_idx[nrelocs] = i;
! 	  stub_reloc_offset[nrelocs++] = size;
  	  size += 4;
  	  break;
  
*************** arm_build_one_stub (struct bfd_hash_entr
*** 3389,3428 ****
    if (stub_entry->st_type == STT_ARM_TFUNC)
      sym_value |= 1;
  
!   /* Assume there is one and only one entry to relocate in each stub.  */
!   BFD_ASSERT (stub_reloc_idx != -1);
! 
!   _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].r_type),
! 			    stub_bfd, stub_sec, stub_sec->contents,
! 			    stub_entry->stub_offset + stub_reloc_offset,
! 			    sym_value, template[stub_reloc_idx].reloc_addend);
  
    return TRUE;
  }
  
! /* As above, but don't actually build the stub.  Just bump offset so
!    we know stub section sizes.  */
! 
! static bfd_boolean
! arm_size_one_stub (struct bfd_hash_entry *gen_entry,
! 		   void * in_arg)
! {
!   struct elf32_arm_stub_hash_entry *stub_entry;
!   struct elf32_arm_link_hash_table *htab;
!   const insn_sequence *template;
!   int template_size;
!   int size;
!   int i;
! 
!   /* Massage our args to the form they really have.  */
!   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
!   htab = (struct elf32_arm_link_hash_table *) in_arg;
  
!   BFD_ASSERT((stub_entry->stub_type > arm_stub_none)
! 	     && stub_entry->stub_type < ARRAY_SIZE(stub_definitions));
  
!   template = stub_definitions[stub_entry->stub_type].template;
!   template_size = stub_definitions[stub_entry->stub_type].template_size;
  
    size = 0;
    for (i = 0; i < template_size; i++)
--- 3527,3598 ----
    if (stub_entry->st_type == STT_ARM_TFUNC)
      sym_value |= 1;
  
!   /* Assume there is at least one and at most MAXRELOCS entries to relocate
!      in each stub.  */
!   BFD_ASSERT (nrelocs != 0 && nrelocs <= MAXRELOCS);
! 
!   for (i = 0; i < nrelocs; i++)
!     if (template[stub_reloc_idx[i]].r_type == R_ARM_THM_JUMP24
! 	|| template[stub_reloc_idx[i]].r_type == R_ARM_THM_JUMP19
! 	|| template[stub_reloc_idx[i]].r_type == R_ARM_THM_CALL
! 	|| template[stub_reloc_idx[i]].r_type == R_ARM_THM_XPC22)
!       {
! 	Elf_Internal_Rela rel;
! 	bfd_boolean unresolved_reloc;
! 	char *error_message;
! 	int sym_flags
! 	  = (template[stub_reloc_idx[i]].r_type != R_ARM_THM_XPC22)
! 	    ? STT_ARM_TFUNC : 0;
! 	bfd_vma points_to = sym_value + stub_entry->target_addend;
! 
! 	rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
! 	rel.r_info = ELF32_R_INFO (0, template[stub_reloc_idx[i]].r_type);
! 	rel.r_addend = template[stub_reloc_idx[i]].reloc_addend;
! 
! 	if (stub_entry->stub_type == arm_stub_a8_veneer_b_cond && i == 0)
! 	  /* The first relocation in the elf32_arm_stub_a8_veneer_b_cond[]
! 	     template should refer back to the instruction after the original
! 	     branch.  */
! 	  points_to = sym_value;
! 
! 	/* Note: _bfd_final_link_relocate doesn't handle these relocations
! 	   properly.  We should probably use this function unconditionally,
! 	   rather than only for certain relocations listed in the enclosing
! 	   conditional, for the sake of consistency.  */
! 	elf32_arm_final_link_relocate (elf32_arm_howto_from_type
! 	    (template[stub_reloc_idx[i]].r_type),
! 	  stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
! 	  points_to, info, stub_entry->target_section, "", sym_flags,
! 	  (struct elf_link_hash_entry *) stub_entry, &unresolved_reloc,
! 	  &error_message);
!       }
!     else
!       {
! 	_bfd_final_link_relocate (elf32_arm_howto_from_type
! 	    (template[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[stub_reloc_idx[i]].reloc_addend);
!       }
  
    return TRUE;
+ #undef MAXRELOCS
  }
  
! /* Calculate the template, template size and instruction size for a stub.
!    Return value is the instruction size.  */
  
! static unsigned int
! find_stub_size_and_template (enum elf32_arm_stub_type stub_type,
! 			     const insn_sequence **stub_template,
! 			     int *stub_template_size)
! {
!   const insn_sequence *template = NULL;
!   int template_size = 0, i;
!   unsigned int size;
  
!   template = stub_definitions[stub_type].template;
!   template_size = stub_definitions[stub_type].template_size;
  
    size = 0;
    for (i = 0; i < template_size; i++)
*************** arm_size_one_stub (struct bfd_hash_entry
*** 3434,3442 ****
  	  break;
  
  	case ARM_TYPE:
! 	  size += 4;
! 	  break;
! 
  	case DATA_TYPE:
  	  size += 4;
  	  break;
--- 3604,3610 ----
  	  break;
  
  	case ARM_TYPE:
! 	case THUMB32_TYPE:
  	case DATA_TYPE:
  	  size += 4;
  	  break;
*************** arm_size_one_stub (struct bfd_hash_entry
*** 3447,3452 ****
--- 3615,3651 ----
  	}
      }
  
+   if (stub_template)
+     *stub_template = template;
+ 
+   if (stub_template_size)
+     *stub_template_size = template_size;
+ 
+   return size;
+ }
+ 
+ /* As above, but don't actually build the stub.  Just bump offset so
+    we know stub section sizes.  */
+ 
+ static bfd_boolean
+ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
+ 		   void * in_arg)
+ {
+   struct elf32_arm_stub_hash_entry *stub_entry;
+   struct elf32_arm_link_hash_table *htab;
+   const insn_sequence *template;
+   int template_size, size;
+ 
+   /* Massage our args to the form they really have.  */
+   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+   htab = (struct elf32_arm_link_hash_table *) in_arg;
+ 
+   BFD_ASSERT((stub_entry->stub_type > arm_stub_none)
+ 	     && stub_entry->stub_type < ARRAY_SIZE(stub_definitions));
+ 
+   size = find_stub_size_and_template (stub_entry->stub_type, &template,
+ 				      &template_size);
+ 
    stub_entry->stub_size = size;
    stub_entry->stub_template = template;
    stub_entry->stub_template_size = template_size;
*************** group_sections (struct elf32_arm_link_ha
*** 3663,3668 ****
--- 3862,4151 ----
  #undef NEXT_SEC
  }
  
+ /* Comparison function for sorting/searching relocations relating to Cortex-A8
+    erratum fix.  */
+ 
+ static int
+ a8_reloc_compare (const void *a, const void *b)
+ {
+   const struct a8_erratum_reloc *ra = a, *rb = b;
+ 
+   if (ra->from < rb->from)
+     return -1;
+   else if (ra->from > rb->from)
+     return 1;
+   else
+     return 0;
+ }
+ 
+ static struct elf_link_hash_entry *find_thumb_glue (struct bfd_link_info *,
+ 						    const char *, char **);
+ 
+ /* Helper function to scan code for sequences which might trigger the Cortex-A8
+    branch/TLB erratum.  Fill in the table described by A8_FIXES_P,
+    NUM_A8_FIXES_P, A8_FIX_TABLE_SIZE_P.  Return 1 if an error occurs, 0
+    otherwise.  */
+ 
+ static int
+ cortex_a8_erratum_scan (bfd *input_bfd, struct bfd_link_info *info,
+ 			struct a8_erratum_fix **a8_fixes_p,
+ 			unsigned int *num_a8_fixes_p,
+ 			unsigned int *a8_fix_table_size_p,
+ 			struct a8_erratum_reloc *a8_relocs,
+ 			unsigned int num_a8_relocs)
+ {
+   asection *section;
+   struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+   struct a8_erratum_fix *a8_fixes = *a8_fixes_p;
+   unsigned int num_a8_fixes = *num_a8_fixes_p;
+   unsigned int a8_fix_table_size = *a8_fix_table_size_p;
+ 
+   for (section = input_bfd->sections;
+        section != NULL;
+        section = section->next)
+     {
+       bfd_byte *contents = NULL;
+       struct _arm_elf_section_data *sec_data;
+       unsigned int span;
+       bfd_vma base_vma;
+ 
+       if (elf_section_type (section) != SHT_PROGBITS
+           || (elf_section_flags (section) & SHF_EXECINSTR) == 0
+           || (section->flags & SEC_EXCLUDE) != 0
+           || (section->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
+           || (section->output_section == bfd_abs_section_ptr))
+         continue;
+ 
+       base_vma = section->output_section->vma + section->output_offset;
+ 
+       if (elf_section_data (section)->this_hdr.contents != NULL)
+         contents = elf_section_data (section)->this_hdr.contents;
+       else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
+         return 1;
+ 
+       sec_data = elf32_arm_section_data (section);
+ 
+       for (span = 0; span < sec_data->mapcount; span++)
+         {
+           unsigned int span_start = sec_data->map[span].vma;
+           unsigned int span_end = (span == sec_data->mapcount - 1)
+             ? section->size : sec_data->map[span + 1].vma;
+           unsigned int i;
+           char span_type = sec_data->map[span].type;
+           bfd_boolean last_was_32bit = FALSE, last_was_branch = FALSE;
+ 
+           if (span_type != 't')
+             continue;
+ 
+           /* Span is entirely within a single 4KB region: skip scanning.  */
+           if (((base_vma + span_start) & ~0xfff)
+ 	      == ((base_vma + span_end) & ~0xfff))
+             continue;
+ 
+           /* Scan for 32-bit Thumb-2 branches which span two 4K regions, where:
+ 
+                * The opcode is BLX.W, BL.W, B.W, Bcc.W
+                * The branch target is in the same 4KB region as the
+                  first half of the branch.
+                * The instruction before the branch is a 32-bit
+                  length non-branch instruction.
+           */
+ 
+           for (i = span_start; i < span_end;)
+             {
+               unsigned int insn = bfd_getl16 (&contents[i]);
+               bfd_boolean insn_32bit = FALSE, is_blx = FALSE, is_b = FALSE;
+ 	      bfd_boolean is_bl = FALSE, is_bcc = FALSE, is_32bit_branch;
+ 
+               if ((insn & 0xe000) == 0xe000 && (insn & 0x1800) != 0x0000)
+                 insn_32bit = TRUE;
+ 
+ 	      if (insn_32bit)
+ 	        {
+                   /* Load the rest of the insn (in manual-friendly order).  */
+                   insn = (insn << 16) | bfd_getl16 (&contents[i + 2]);
+ 
+         	  /* Encoding T4: B<c>.W.  */
+         	  is_b = (insn & 0xf800d000) == 0xf0009000;
+         	  /* Encoding T1: BL<c>.W.  */
+         	  is_bl = (insn & 0xf800d000) == 0xf000d000;
+         	  /* Encoding T2: BLX<c>.W.  */
+         	  is_blx = (insn & 0xf800d000) == 0xf000c000;
+ 		  /* Encoding T3: B<c>.W (not permitted in IT block).  */
+ 		  is_bcc = (insn & 0xf800d000) == 0xf0008000
+ 			   && (insn & 0x07f00000) != 0x03800000;
+ 		}
+ 
+ 	      is_32bit_branch = is_b || is_bl || is_blx || is_bcc;
+ 			   
+               if (((base_vma + i) & 0xfff) == 0xffe && insn_32bit
+ 		  && is_32bit_branch && last_was_32bit && !last_was_branch)
+                 {
+                   bfd_vma offset;
+                   bfd_boolean force_target_arm = FALSE;
+ 		  bfd_boolean force_target_thumb = FALSE;
+                   bfd_vma target;
+                   enum elf32_arm_stub_type stub_type = arm_stub_none;
+                   struct a8_erratum_reloc key, *found;
+ 
+                   key.from = base_vma + i;
+                   found = bsearch (&key, a8_relocs, num_a8_relocs,
+                                    sizeof (struct a8_erratum_reloc),
+                                    &a8_reloc_compare);
+ 
+ 		  if (found)
+ 		    {
+ 		      char *error_message = NULL;
+ 		      struct elf_link_hash_entry *entry;
+ 
+ 		      /* We don't care about the error returned from this
+ 		         function, only if there is glue or not.  */
+ 		      entry = find_thumb_glue (info, found->sym_name,
+ 					       &error_message);
+ 
+ 		      if (entry)
+ 			found->non_a8_stub = TRUE;
+ 
+ 		      if (found->r_type == R_ARM_THM_CALL
+ 			  && found->st_type != STT_ARM_TFUNC)
+ 			force_target_arm = TRUE;
+ 		      else if (found->r_type == R_ARM_THM_CALL
+ 			       && found->st_type == STT_ARM_TFUNC)
+ 			force_target_thumb = TRUE;
+ 		    }
+ 
+                   /* Check if we have an offending branch instruction.  */
+ 
+ 		  if (found && found->non_a8_stub)
+ 		    /* We've already made a stub for this instruction, e.g.
+ 		       it's a long branch or a Thumb->ARM stub.  Assume that
+ 		       stub will suffice to work around the A8 erratum (see
+ 		       setting of always_after_branch above).  */
+ 		    ;
+                   else if (is_bcc)
+                     {
+                       offset = (insn & 0x7ff) << 1;
+                       offset |= (insn & 0x3f0000) >> 4;
+                       offset |= (insn & 0x2000) ? 0x40000 : 0;
+                       offset |= (insn & 0x800) ? 0x80000 : 0;
+                       offset |= (insn & 0x4000000) ? 0x100000 : 0;
+                       if (offset & 0x100000)
+                         offset |= ~0xfffff;
+                       stub_type = arm_stub_a8_veneer_b_cond;
+                     }
+                   else if (is_b || is_bl || is_blx)
+                     {
+                       int s = (insn & 0x4000000) != 0;
+                       int j1 = (insn & 0x2000) != 0;
+                       int j2 = (insn & 0x800) != 0;
+                       int i1 = !(j1 ^ s);
+                       int i2 = !(j2 ^ s);
+ 
+                       offset = (insn & 0x7ff) << 1;
+                       offset |= (insn & 0x3ff0000) >> 4;
+                       offset |= i2 << 22;
+                       offset |= i1 << 23;
+                       offset |= s << 24;
+                       if (offset & 0x1000000)
+                         offset |= ~0xffffff;
+ 
+                       if (is_blx)
+                         offset &= ~3u;
+ 
+                       stub_type = is_blx ? arm_stub_a8_veneer_blx :
+                         is_bl ? arm_stub_a8_veneer_bl : arm_stub_a8_veneer_b;
+                     }
+ 
+                   if (stub_type != arm_stub_none)
+                     {
+                       bfd_vma pc_for_insn = base_vma + i + 4;
+ 
+ 		      /* The original instruction is a BL, but the target is
+ 		         an ARM instruction.  If we were not making a stub,
+ 			 the BL would have been converted to a BLX.  Use the
+ 			 BLX stub instead in that case.  */
+ 		      if (htab->use_blx && force_target_arm
+ 			  && stub_type == arm_stub_a8_veneer_bl)
+ 			{
+ 			  stub_type = arm_stub_a8_veneer_blx;
+ 			  is_blx = TRUE;
+ 			  is_bl = FALSE;
+ 			}
+ 		      /* Conversely, if the original instruction was
+ 			 BLX but the target is Thumb mode, use the BL
+ 			 stub.  */
+ 		      else if (force_target_thumb
+ 			       && stub_type == arm_stub_a8_veneer_blx)
+ 			{
+ 			  stub_type = arm_stub_a8_veneer_bl;
+ 			  is_blx = FALSE;
+ 			  is_bl = TRUE;
+ 			}
+ 
+                       if (is_blx)
+                         pc_for_insn &= ~3u;
+ 
+                       /* If we found a relocation, use the proper destination,
+ 		         not the offset in the (unrelocated) instruction.
+ 			 Note this is always done if we switched the stub type
+ 			 above.  */
+                       if (found)
+                         offset = found->destination - pc_for_insn;
+ 
+                       target = pc_for_insn + offset;
+ 
+                       /* The BLX stub is ARM-mode code.  Adjust the offset to
+ 		         take the different PC value (+8 instead of +4) into
+ 			 account.  */
+                       if (stub_type == arm_stub_a8_veneer_blx)
+                         offset += 4;
+ 
+                       if (((base_vma + i) & ~0xfff) == (target & ~0xfff))
+                         {
+                           char *stub_name;
+ 
+                           if (num_a8_fixes == a8_fix_table_size)
+                             {
+                               a8_fix_table_size *= 2;
+                               a8_fixes = bfd_realloc (a8_fixes,
+                                 sizeof (struct a8_erratum_fix)
+                                 * a8_fix_table_size);
+                             }
+ 
+                           stub_name = bfd_malloc (8 + 1 + 8 + 1);
+                           if (stub_name != NULL)
+                             sprintf (stub_name, "%x:%x", section->id, i);
+ 
+                           a8_fixes[num_a8_fixes].input_bfd = input_bfd;
+                           a8_fixes[num_a8_fixes].section = section;
+                           a8_fixes[num_a8_fixes].offset = i;
+                           a8_fixes[num_a8_fixes].addend = offset;
+                           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;
+ 
+                           num_a8_fixes++;
+                         }
+                     }
+                 }
+ 
+               i += insn_32bit ? 4 : 2;
+               last_was_32bit = insn_32bit;
+ 	      last_was_branch = is_32bit_branch;
+             }
+         }
+ 
+       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 0;
+ }
+ 
  /* Determine and set the size of the stub section for a final link.
  
     The basic idea here is to examine all the relocations looking for
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3681,3686 ****
--- 4164,4181 ----
    bfd_boolean stubs_always_after_branch;
    bfd_boolean stub_changed = 0;
    struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+   struct a8_erratum_fix *a8_fixes = NULL;
+   unsigned int num_a8_fixes = 0, prev_num_a8_fixes = 0, a8_fix_table_size = 10;
+   struct a8_erratum_reloc *a8_relocs = NULL;
+   unsigned int num_a8_relocs = 0, a8_reloc_table_size = 10, i;
+ 
+   if (htab->fix_cortex_a8)
+     {
+       a8_fixes = bfd_zmalloc (sizeof (struct a8_erratum_fix)
+                               * a8_fix_table_size);
+       a8_relocs = bfd_zmalloc (sizeof (struct a8_erratum_reloc)
+                                * a8_reloc_table_size);
+     }
  
    /* Propagate mach to stub bfd, because it may not have been
       finalized when we created stub_bfd.  */
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3692,3697 ****
--- 4187,4199 ----
    htab->add_stub_section = add_stub_section;
    htab->layout_sections_again = layout_sections_again;
    stubs_always_after_branch = group_size < 0;
+ 
+   /* The Cortex-A8 erratum fix depends on stubs not being in the same 4K page
+      as the first half of a 32-bit branch straddling two 4K pages.  This is a
+      crude way of enforcing that.  */
+   if (htab->fix_cortex_a8)
+     stubs_always_after_branch = 1;
+ 
    if (group_size < 0)
      stub_group_size = -group_size;
    else
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3719,3724 ****
--- 4221,4228 ----
        unsigned int bfd_indx;
        asection *stub_sec;
  
+       num_a8_fixes = 0;
+ 
        for (input_bfd = info->input_bfds, bfd_indx = 0;
  	   input_bfd != NULL;
  	   input_bfd = input_bfd->link_next, bfd_indx++)
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3727,3732 ****
--- 4231,4238 ----
  	  asection *section;
  	  Elf_Internal_Sym *local_syms = NULL;
  
+ 	  num_a8_relocs = 0;
+ 
  	  /* We'll need the symbol table in a second.  */
  	  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  	  if (symtab_hdr->sh_info == 0)
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3775,3780 ****
--- 4281,4287 ----
  		  char *stub_name;
  		  const asection *id_sec;
  		  unsigned char st_type;
+ 		  bfd_boolean created_stub = FALSE;
  
  		  r_type = ELF32_R_TYPE (irela->r_info);
  		  r_indx = ELF32_R_SYM (irela->r_info);
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3792,3797 ****
--- 4299,4306 ----
  		  if ((r_type != (unsigned int) R_ARM_CALL)
  		      && (r_type != (unsigned int) R_ARM_THM_CALL)
  		      && (r_type != (unsigned int) R_ARM_JUMP24)
+ 		      && (r_type != (unsigned int) R_ARM_THM_JUMP19)
+ 		      && (r_type != (unsigned int) R_ARM_THM_XPC22)
  		      && (r_type != (unsigned int) R_ARM_THM_JUMP24)
  		      && (r_type != (unsigned int) R_ARM_PLT32))
  		    continue;
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3892,3972 ****
  		      sym_name = hash->root.root.root.string;
  		    }
  
! 		  /* 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);
! 		  if (stub_type == arm_stub_none)
! 		    continue;
! 
! 		  /* Support for grouping stub sections.  */
! 		  id_sec = htab->stub_group[section->id].link_sec;
! 
! 		  /* Get the name of this stub.  */
! 		  stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, irela);
! 		  if (!stub_name)
! 		    goto error_ret_free_internal;
! 
! 		  stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table,
! 						    stub_name,
! 						    FALSE, FALSE);
! 		  if (stub_entry != NULL)
  		    {
! 		      /* The proper stub has already been created.  */
! 		      free (stub_name);
! 		      continue;
! 		    }
  
! 		  stub_entry = elf32_arm_add_stub (stub_name, section, htab);
! 		  if (stub_entry == NULL)
! 		    {
! 		      free (stub_name);
! 		      goto error_ret_free_internal;
! 		    }
  
! 		  stub_entry->target_value = sym_value;
! 		  stub_entry->target_section = sym_sec;
! 		  stub_entry->stub_type = stub_type;
! 		  stub_entry->h = hash;
! 		  stub_entry->st_type = st_type;
! 
! 		  if (sym_name == NULL)
! 		    sym_name = "unnamed";
! 		  stub_entry->output_name
! 		    = bfd_alloc (htab->stub_bfd,
! 				 sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
! 				 + strlen (sym_name));
! 		  if (stub_entry->output_name == NULL)
! 		    {
! 		      free (stub_name);
! 		      goto error_ret_free_internal;
! 		    }
  
! 		  /* For historical reasons, use the existing names for
! 		     ARM-to-Thumb and Thumb-to-ARM stubs.  */
! 		  if ( ((r_type == (unsigned int) R_ARM_THM_CALL)
! 			|| (r_type == (unsigned int) R_ARM_THM_JUMP24))
! 		       && st_type != STT_ARM_TFUNC)
! 		    sprintf (stub_entry->output_name, THUMB2ARM_GLUE_ENTRY_NAME,
! 			     sym_name);
! 		  else if ( ((r_type == (unsigned int) R_ARM_CALL)
! 			     || (r_type == (unsigned int) R_ARM_JUMP24))
! 			   && st_type == STT_ARM_TFUNC)
! 		    sprintf (stub_entry->output_name, ARM2THUMB_GLUE_ENTRY_NAME,
! 			     sym_name);
! 		  else
! 		    sprintf (stub_entry->output_name, STUB_ENTRY_NAME,
! 			     sym_name);
  
! 		  stub_changed = TRUE;
  		}
  
! 	      /* We're done with the internal relocs, free them.  */
! 	      if (elf_section_data (section)->relocs == NULL)
! 		free (internal_relocs);
  	    }
  	}
  
        if (!stub_changed)
  	break;
  
--- 4401,4546 ----
  		      sym_name = hash->root.root.root.string;
  		    }
  
! 		  do
  		    {
! 		      /* 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);
! 		      if (stub_type == arm_stub_none)
! 			break;
! 
! 		      /* Support for grouping stub sections.  */
! 		      id_sec = htab->stub_group[section->id].link_sec;
! 
! 		      /* Get the name of this stub.  */
! 		      stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
! 						       irela);
! 		      if (!stub_name)
! 			goto error_ret_free_internal;
! 
! 		      /* We've either created a stub for this reloc already,
! 			 or we are about to.  */
! 		      created_stub = TRUE;
! 
! 		      stub_entry = arm_stub_hash_lookup
! 				     (&htab->stub_hash_table, stub_name,
! 				      FALSE, FALSE);
! 		      if (stub_entry != NULL)
! 			{
! 			  /* The proper stub has already been created.  */
! 			  free (stub_name);
! 			  break;
! 			}
  
! 		      stub_entry = elf32_arm_add_stub (stub_name, section,
! 						       htab);
! 		      if (stub_entry == NULL)
! 			{
! 			  free (stub_name);
! 			  goto error_ret_free_internal;
! 			}
  
!                       stub_entry->target_value = sym_value;
!                       stub_entry->target_section = sym_sec;
!                       stub_entry->stub_type = stub_type;
!                       stub_entry->h = hash;
!                       stub_entry->st_type = st_type;
! 
!                       if (sym_name == NULL)
!                 	sym_name = "unnamed";
!                       stub_entry->output_name
!                 	= bfd_alloc (htab->stub_bfd,
!                                      sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
!                                      + strlen (sym_name));
!                       if (stub_entry->output_name == NULL)
!                 	{
!                           free (stub_name);
!                           goto error_ret_free_internal;
!                 	}
! 
!                       /* For historical reasons, use the existing names for
!                 	 ARM-to-Thumb and Thumb-to-ARM stubs.  */
!                       if ( ((r_type == (unsigned int) R_ARM_THM_CALL)
!                             || (r_type == (unsigned int) R_ARM_THM_JUMP24))
!                            && st_type != STT_ARM_TFUNC)
!                 	sprintf (stub_entry->output_name,
!                         	 THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
!                       else if ( ((r_type == (unsigned int) R_ARM_CALL)
!                         	 || (r_type == (unsigned int) R_ARM_JUMP24))
!                                && st_type == STT_ARM_TFUNC)
!                 	sprintf (stub_entry->output_name,
!                         	 ARM2THUMB_GLUE_ENTRY_NAME, sym_name);
!                       else
!                 	sprintf (stub_entry->output_name, STUB_ENTRY_NAME,
!                         	 sym_name);
  
!                       stub_changed = TRUE;
!                     }
!                   while (0);
! 
!                   /* Look for relocations which might trigger Cortex-A8
!                      erratum.  */
!                   if (htab->fix_cortex_a8
!                       && (r_type == (unsigned int) R_ARM_THM_JUMP24
!                           || r_type == (unsigned int) R_ARM_THM_JUMP19
!                           || r_type == (unsigned int) R_ARM_THM_CALL
!                           || r_type == (unsigned int) R_ARM_THM_XPC22))
!                     {
!                       bfd_vma from = section->output_section->vma
!                                      + section->output_offset
!                                      + irela->r_offset;
! 
!                       if ((from & 0xfff) == 0xffe)
!                         {
!                           /* Found a candidate.  Note we haven't checked the
!                              destination is within 4K here: if we do so (and
!                              don't create an entry in a8_relocs) we can't tell
!                              that a branch should have been relocated when
!                              scanning later.  */
!                           if (num_a8_relocs == a8_reloc_table_size)
!                             {
!                               a8_reloc_table_size *= 2;
!                               a8_relocs = bfd_realloc (a8_relocs,
!                                 sizeof (struct a8_erratum_reloc)
!                                 * a8_reloc_table_size);
!                             }
! 
!                           a8_relocs[num_a8_relocs].from = from;
!                           a8_relocs[num_a8_relocs].destination = destination;
!                           a8_relocs[num_a8_relocs].r_type = r_type;
!                           a8_relocs[num_a8_relocs].st_type = st_type;
!                           a8_relocs[num_a8_relocs].sym_name = sym_name;
!                           a8_relocs[num_a8_relocs].non_a8_stub = created_stub;
  
!                           num_a8_relocs++;
!                         }
!                     }
  		}
  
!               /* We're done with the internal relocs, free them.  */
!               if (elf_section_data (section)->relocs == NULL)
!                 free (internal_relocs);
!             }
! 
!           if (htab->fix_cortex_a8)
! 	    {
!               /* Sort relocs which might apply to Cortex-A8 erratum.  */
!               qsort (a8_relocs, num_a8_relocs, sizeof (struct a8_erratum_reloc),
!                      &a8_reloc_compare);
! 
!               /* Scan for branches which might trigger Cortex-A8 erratum.  */
!               if (cortex_a8_erratum_scan (input_bfd, info, &a8_fixes,
! 					  &num_a8_fixes, &a8_fix_table_size,
! 					  a8_relocs, num_a8_relocs) != 0)
! 		goto error_ret_free_local;
  	    }
  	}
  
+       if (htab->fix_cortex_a8 && num_a8_fixes != prev_num_a8_fixes)
+         stub_changed = TRUE;
+ 
        if (!stub_changed)
  	break;
  
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 3985,3995 ****
--- 4559,4638 ----
  
        bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab);
  
+       /* Add Cortex-A8 erratum veneers to stub section sizes too.  */
+       if (htab->fix_cortex_a8)
+         for (i = 0; i < num_a8_fixes; i++)
+           {
+ 	    stub_sec = elf32_arm_create_or_find_stub_sec (NULL,
+ 			 a8_fixes[i].section, htab);
+ 
+ 	    if (stub_sec == NULL)
+ 	      goto error_ret_free_local;
+ 
+             stub_sec->size
+               += find_stub_size_and_template (a8_fixes[i].stub_type, NULL,
+                                               NULL);
+           }
+ 
+ 
        /* Ask the linker to do its stuff.  */
        (*htab->layout_sections_again) ();
        stub_changed = FALSE;
+       prev_num_a8_fixes = num_a8_fixes;
      }
  
+   /* Add stubs for Cortex-A8 erratum fixes now.  */
+   if (htab->fix_cortex_a8)
+     {
+       for (i = 0; i < num_a8_fixes; i++)
+         {
+           struct elf32_arm_stub_hash_entry *stub_entry;
+           char *stub_name = a8_fixes[i].stub_name;
+           asection *section = a8_fixes[i].section;
+           unsigned int section_id = a8_fixes[i].section->id;
+           asection *link_sec = htab->stub_group[section_id].link_sec;
+           asection *stub_sec = htab->stub_group[section_id].stub_sec;
+           const insn_sequence *template;
+           int template_size, size = 0;
+ 
+           stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
+                                              TRUE, FALSE);
+           if (stub_entry == NULL)
+             {
+               (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
+                                      section->owner,
+                                      stub_name);
+               return FALSE;
+             }
+ 
+           stub_entry->stub_sec = stub_sec;
+           stub_entry->stub_offset = 0;
+           stub_entry->id_sec = link_sec;
+           stub_entry->stub_type = a8_fixes[i].stub_type;
+           stub_entry->target_section = a8_fixes[i].section;
+           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;
+ 
+           size = find_stub_size_and_template (a8_fixes[i].stub_type, &template,
+                                               &template_size);
+ 
+           stub_entry->stub_size = size;
+           stub_entry->stub_template = template;
+           stub_entry->stub_template_size = template_size;
+         }
+ 
+       /* Stash the Cortex-A8 erratum fix array for use later in
+          elf32_arm_write_section().  */
+       htab->a8_erratum_fixes = a8_fixes;
+       htab->num_a8_erratum_fixes = num_a8_fixes;
+     }
+   else
+     {
+       htab->a8_erratum_fixes = NULL;
+       htab->num_a8_erratum_fixes = 0;
+     }
    return TRUE;
  
   error_ret_free_local:
*************** bfd_elf32_arm_init_maps (bfd *abfd)
*** 4807,4812 ****
--- 5450,5477 ----
  }
  
  
+ /* Auto-select enabling of Cortex-A8 erratum fix if the user didn't explicitly
+    say what they wanted.  */
+ 
+ void
+ bfd_elf32_arm_set_cortex_a8_fix (bfd *obfd, struct bfd_link_info *link_info)
+ {
+   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
+   obj_attribute *out_attr = elf_known_obj_attributes_proc (obfd);
+ 
+   if (globals->fix_cortex_a8 == -1)
+     {
+       /* Turn on Cortex-A8 erratum workaround for ARMv7-A.  */
+       if (out_attr[Tag_CPU_arch].i == TAG_CPU_ARCH_V7
+ 	  && (out_attr[Tag_CPU_arch_profile].i == 'A'
+ 	      || out_attr[Tag_CPU_arch_profile].i == 0))
+ 	globals->fix_cortex_a8 = 1;
+       else
+ 	globals->fix_cortex_a8 = 0;
+     }
+ }
+ 
+ 
  void
  bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)
  {
*************** bfd_elf32_arm_set_target_relocs (struct 
*** 5416,5422 ****
  				 int use_blx,
                                   bfd_arm_vfp11_fix vfp11_fix,
  				 int no_enum_warn, int no_wchar_warn,
! 				 int pic_veneer)
  {
    struct elf32_arm_link_hash_table *globals;
  
--- 6081,6087 ----
  				 int use_blx,
                                   bfd_arm_vfp11_fix vfp11_fix,
  				 int no_enum_warn, int no_wchar_warn,
! 				 int pic_veneer, int fix_cortex_a8)
  {
    struct elf32_arm_link_hash_table *globals;
  
*************** bfd_elf32_arm_set_target_relocs (struct 
*** 5438,5443 ****
--- 6103,6109 ----
    globals->use_blx |= use_blx;
    globals->vfp11_fix = vfp11_fix;
    globals->pic_veneer = pic_veneer;
+   globals->fix_cortex_a8 = fix_cortex_a8;
  
    BFD_ASSERT (is_arm_elf (output_bfd));
    elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
*************** arm_map_one_stub (struct bfd_hash_entry 
*** 12172,12184 ****
  	return FALSE;
        break;
      case THUMB16_TYPE:
        if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
  				      stub_entry->stub_size))
  	return FALSE;
        break;
      default:
        BFD_FAIL ();
!       return FALSE;
      }
  
    prev_type = DATA_TYPE;
--- 12838,12851 ----
  	return FALSE;
        break;
      case THUMB16_TYPE:
+     case THUMB32_TYPE:
        if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
  				      stub_entry->stub_size))
  	return FALSE;
        break;
      default:
        BFD_FAIL ();
!       return 0;
      }
  
    prev_type = DATA_TYPE;
*************** arm_map_one_stub (struct bfd_hash_entry 
*** 12192,12197 ****
--- 12859,12865 ----
  	  break;
  
  	case THUMB16_TYPE:
+ 	case THUMB32_TYPE:
  	  sym_type = ARM_MAP_THUMB;
  	  break;
  
*************** arm_map_one_stub (struct bfd_hash_entry 
*** 12214,12219 ****
--- 12882,12888 ----
        switch (template[i].type)
  	{
  	case ARM_TYPE:
+ 	case THUMB32_TYPE:
  	  size += 4;
  	  break;
  
*************** copy_exidx_entry (bfd *output_bfd, bfd_b
*** 12440,12445 ****
--- 13109,13228 ----
    bfd_put_32 (output_bfd, second_word, to + 4);
  }
  
+ /* Data for make_branch_to_a8_stub().  */
+ 
+ struct a8_branch_to_stub_data {
+   asection *writing_section;
+   bfd_byte *contents;
+ };
+ 
+ 
+ /* Helper to insert branches to Cortex-A8 erratum stubs in the right
+    places for a particular section.  */
+ 
+ static bfd_boolean
+ make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
+                        void *in_arg)
+ {
+   struct elf32_arm_stub_hash_entry *stub_entry;
+   struct a8_branch_to_stub_data *data;
+   bfd_byte *contents;
+   unsigned long branch_insn;
+   bfd_vma veneered_insn_loc, veneer_entry_loc;
+   bfd_signed_vma branch_offset;
+   bfd *abfd;
+   unsigned int index;
+ 
+   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+   data = (struct a8_branch_to_stub_data *) in_arg;
+ 
+   if (stub_entry->target_section != data->writing_section
+       || stub_entry->stub_type < arm_stub_a8_veneer_b_cond)
+     return TRUE;
+ 
+   contents = data->contents;
+ 
+   veneered_insn_loc = stub_entry->target_section->output_section->vma
+ 		      + stub_entry->target_section->output_offset
+ 		      + stub_entry->target_value;
+ 
+   veneer_entry_loc = stub_entry->stub_sec->output_section->vma
+ 		     + stub_entry->stub_sec->output_offset
+ 		     + stub_entry->stub_offset;
+ 
+   if (stub_entry->stub_type == arm_stub_a8_veneer_blx)
+     veneered_insn_loc &= ~3u;
+ 
+   branch_offset = veneer_entry_loc - veneered_insn_loc - 4;
+ 
+   abfd = stub_entry->target_section->owner;
+   index = stub_entry->target_value;
+ 
+   /* We attempt to avoid this condition by setting stubs_always_after_branch
+      in elf32_arm_size_stubs if we've enabled the Cortex-A8 erratum workaround.
+      This check is just to be on the safe side...  */
+   if ((veneered_insn_loc & ~0xfff) == (veneer_entry_loc & ~0xfff))
+     {
+       (*_bfd_error_handler) (_("%B: error: Cortex-A8 erratum stub is "
+ 			       "allocated in unsafe location"), abfd);
+       return FALSE;
+     }
+ 
+   switch (stub_entry->stub_type)
+     {
+     case arm_stub_a8_veneer_b:
+     case arm_stub_a8_veneer_b_cond:
+       branch_insn = 0xf0009000;
+       goto jump24;
+ 
+     case arm_stub_a8_veneer_blx:
+       branch_insn = 0xf000e800;
+       goto jump24;
+ 
+     case arm_stub_a8_veneer_bl:
+       {
+ 	unsigned int i1, j1, i2, j2, s;
+ 
+ 	branch_insn = 0xf000d000;
+ 
+       jump24:
+ 	if (branch_offset < -16777216 || branch_offset > 16777214)
+ 	  {
+ 	    /* There's not much we can do apart from complain if this
+ 	       happens.  */
+ 	    (*_bfd_error_handler) (_("%B: error: Cortex-A8 erratum stub out "
+ 				     "of range (input file too large)"), abfd);
+ 	    return FALSE;
+ 	  }
+ 
+ 	/* i1 = not(j1 eor s), so:
+ 	   not i1 = j1 eor s
+ 	   j1 = (not i1) eor s.  */
+ 
+ 	branch_insn |= (branch_offset >> 1) & 0x7ff;
+ 	branch_insn |= ((branch_offset >> 12) & 0x3ff) << 16;
+ 	i2 = (branch_offset >> 22) & 1;
+ 	i1 = (branch_offset >> 23) & 1;
+ 	s = (branch_offset >> 24) & 1;
+ 	j1 = (!i1) ^ s;
+ 	j2 = (!i2) ^ s;
+ 	branch_insn |= j2 << 11;
+ 	branch_insn |= j1 << 13;
+ 	branch_insn |= s << 26;
+       }
+       break;
+ 
+     default:
+       BFD_FAIL ();
+       return FALSE;
+     }
+ 
+   bfd_put_16 (abfd, (branch_insn >> 16) & 0xffff, &contents[index]);
+   bfd_put_16 (abfd, branch_insn & 0xffff, &contents[index + 2]);
+ 
+   return TRUE;
+ }
+ 
  /* Do code byteswapping.  Return FALSE afterwards so that the section is
     written out as normal.  */
  
*************** elf32_arm_write_section (bfd *output_bfd
*** 12449,12455 ****
  			 asection *sec,
  			 bfd_byte *contents)
  {
!   int mapcount, errcount;
    _arm_elf_section_data *arm_data;
    struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
    elf32_arm_section_map *map;
--- 13232,13238 ----
  			 asection *sec,
  			 bfd_byte *contents)
  {
!   unsigned int mapcount, errcount;
    _arm_elf_section_data *arm_data;
    struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
    elf32_arm_section_map *map;
*************** elf32_arm_write_section (bfd *output_bfd
*** 12458,12464 ****
    bfd_vma end;
    bfd_vma offset = sec->output_section->vma + sec->output_offset;
    bfd_byte tmp;
!   int i;
  
    /* If this section has not been allocated an _arm_elf_section_data
       structure then we cannot record anything.  */
--- 13241,13247 ----
    bfd_vma end;
    bfd_vma offset = sec->output_section->vma + sec->output_offset;
    bfd_byte tmp;
!   unsigned int i;
  
    /* If this section has not been allocated an _arm_elf_section_data
       structure then we cannot record anything.  */
*************** elf32_arm_write_section (bfd *output_bfd
*** 12633,12638 ****
--- 13416,13433 ----
        return TRUE;
      }
  
+   /* Fix code to point to Cortex-A8 erratum stubs.  */
+   if (globals->fix_cortex_a8)
+     {
+       struct a8_branch_to_stub_data data;
+ 
+       data.writing_section = sec;
+       data.contents = contents;
+ 
+       bfd_hash_traverse (&globals->stub_hash_table, make_branch_to_a8_stub,
+ 			 &data);
+     }
+ 
    if (mapcount == 0)
      return FALSE;
  
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.244
diff -c -p -r1.244 ld.texinfo
*** ld/ld.texinfo	19 May 2009 16:08:07 -0000	1.244
--- ld/ld.texinfo	22 May 2009 11:42:39 -0000
*************** instructions into @code{bal} instruction
*** 5865,5870 ****
--- 5865,5877 ----
  target subroutine is a leaf routine (that is, the target subroutine does
  not itself call any subroutines).
  
+ @cindex Cortex-A8 erratum workaround
+ @kindex --fix-cortex-a8
+ @kindex --no-fix-cortex-a8
+ The @samp{--fix-cortex-a8} switch enables a link-time workaround for an erratum in certain Cortex-A8 processors.  The workaround is enabled by default if you are targeting the ARM v7-A architecture profile.  It can be enabled otherwise by specifying @samp{--fix-cortex-a8}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a8}.
+ 
+ The erratum only affects Thumb-2 code.  Please contact ARM for further details.
+ 
  @ifclear GENERIC
  @lowersections
  @end ifclear
Index: ld/emultempl/armelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armelf.em,v
retrieving revision 1.72
diff -c -p -r1.72 armelf.em
*** ld/emultempl/armelf.em	5 May 2009 14:18:30 -0000	1.72
--- ld/emultempl/armelf.em	22 May 2009 11:42:39 -0000
*************** static char *target2_type = "${TARGET2_T
*** 37,42 ****
--- 37,43 ----
  static int fix_v4bx = 0;
  static int use_blx = 0;
  static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT;
+ static int fix_cortex_a8 = -1;
  static int no_enum_size_warning = 0;
  static int no_wchar_size_warning = 0;
  static int pic_veneer = 0;
*************** arm_elf_before_allocation (void)
*** 60,65 ****
--- 61,69 ----
       due to architecture version.  */
    bfd_elf32_arm_set_vfp11_fix (link_info.output_bfd, &link_info);
  
+   /* Auto-select Cortex-A8 erratum fix if it wasn't explicitly specified.  */
+   bfd_elf32_arm_set_cortex_a8_fix (link_info.output_bfd, &link_info);
+ 
    /* We should be able to set the size of the interworking stub section.  We
       can't do it until later if we have dynamic sections, though.  */
    if (! elf_hash_table (&link_info)->dynamic_sections_created)
*************** arm_elf_create_output_section_statements
*** 458,464 ****
  				   target2_type, fix_v4bx, use_blx,
  				   vfp11_denorm_fix, no_enum_size_warning,
  				   no_wchar_size_warning,
! 				   pic_veneer);
  
    stub_file = lang_add_input_file ("linker stubs",
   				   lang_input_file_is_fake_enum,
--- 462,468 ----
  				   target2_type, fix_v4bx, use_blx,
  				   vfp11_denorm_fix, no_enum_size_warning,
  				   no_wchar_size_warning,
! 				   pic_veneer, fix_cortex_a8);
  
    stub_file = lang_add_input_file ("linker stubs",
   				   lang_input_file_is_fake_enum,
*************** PARSE_AND_LIST_PROLOGUE='
*** 520,525 ****
--- 524,531 ----
  #define OPTION_FIX_V4BX_INTERWORKING	311
  #define OPTION_STUBGROUP_SIZE           312
  #define OPTION_NO_WCHAR_SIZE_WARNING	313
+ #define OPTION_FIX_CORTEX_A8		314
+ #define OPTION_NO_FIX_CORTEX_A8		315
  '
  
  PARSE_AND_LIST_SHORTOPTS=p
*************** PARSE_AND_LIST_LONGOPTS='
*** 539,544 ****
--- 545,552 ----
    { "pic-veneer", no_argument, NULL, OPTION_PIC_VENEER},
    { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
    { "no-wchar-size-warning", no_argument, NULL, OPTION_NO_WCHAR_SIZE_WARNING},
+   { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
+   { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
  '
  
  PARSE_AND_LIST_OPTIONS='
*************** PARSE_AND_LIST_OPTIONS='
*** 565,570 ****
--- 573,579 ----
                             after each stub section.  Values of +/-1 indicate\n\
                             the linker should choose suitable defaults.\n"
   		   ));
+   fprintf (file, _("  --[no-]fix-cortex-a8        Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
  '
  
  PARSE_AND_LIST_ARGS_CASES='
*************** PARSE_AND_LIST_ARGS_CASES='
*** 636,641 ****
--- 645,658 ----
  	  einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
        }
        break;
+ 
+     case OPTION_FIX_CORTEX_A8:
+       fix_cortex_a8 = 1;
+       break;
+ 
+     case OPTION_NO_FIX_CORTEX_A8:
+       fix_cortex_a8 = 0;
+       break;
  '
  
  # We have our own before_allocation etc. functions, but they call
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.58
diff -c -p -r1.58 arm-elf.exp
*** ld/testsuite/ld-arm/arm-elf.exp	15 May 2009 00:08:12 -0000	1.58
--- ld/testsuite/ld-arm/arm-elf.exp	22 May 2009 11:42:39 -0000
*************** set armelftests {
*** 161,166 ****
--- 161,210 ----
       "-EL --vfp11-denorm-fix=scalar -Ttext=0x8000" "-EL -mfpu=vfpxd" {vfp11-fix-none.s}
       {{objdump -dr vfp11-fix-none.d}}
       "vfp11-fix-none"}
+     {"Cortex-A8 erratum fix, b.w"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-b.s}
+      {{objdump -dr cortex-a8-fix-b.d}}
+      "cortex-a8-fix-b"}
+     {"Cortex-A8 erratum fix, bl.w"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-bl.s}
+      {{objdump -dr cortex-a8-fix-bl.d}}
+      "cortex-a8-fix-bl"}
+     {"Cortex-A8 erratum fix, bcc.w"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-bcc.s}
+      {{objdump -dr cortex-a8-fix-bcc.d}}
+      "cortex-a8-fix-bcc"}
+     {"Cortex-A8 erratum fix, blx.w"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-blx.s}
+      {{objdump -dr cortex-a8-fix-blx.d}}
+      "cortex-a8-fix-blx"}
+     {"Cortex-A8 erratum fix, relocate b.w to ARM"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-arm-target.s cortex-a8-fix-b-rel.s}
+      {{objdump -dr cortex-a8-fix-b-rel-arm.d}}
+      "cortex-a8-fix-b-rel-arm"}
+     {"Cortex-A8 erratum fix, relocate b.w to Thumb"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-thumb-target.s cortex-a8-fix-b-rel.s}
+      {{objdump -dr cortex-a8-fix-b-rel-thumb.d}}
+      "cortex-a8-fix-b-rel-thumb"}
+     {"Cortex-A8 erratum fix, relocate bl.w to ARM"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-arm-target.s cortex-a8-fix-bl-rel.s}
+      {{objdump -dr cortex-a8-fix-bl-rel-arm.d}}
+      "cortex-a8-fix-bl-rel-arm"}
+     {"Cortex-A8 erratum fix, relocate bl.w to Thumb"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-thumb-target.s cortex-a8-fix-bl-rel.s}
+      {{objdump -dr cortex-a8-fix-bl-rel-thumb.d}}
+      "cortex-a8-fix-bl-rel-thumb"}
+     {"Cortex-A8 erratum fix, relocate b<cond>.w to Thumb"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-thumb-target.s cortex-a8-fix-bcc-rel.s}
+      {{objdump -dr cortex-a8-fix-bcc-rel-thumb.d}}
+      "cortex-a8-fix-bcc-rel-thumb"}
+     {"Cortex-A8 erratum fix, relocate blx.w to ARM"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-arm-target.s cortex-a8-fix-blx-rel.s}
+      {{objdump -dr cortex-a8-fix-blx-rel-arm.d}}
+      "cortex-a8-fix-blx-rel-arm"}
+     {"Cortex-A8 erratum fix, relocate blx.w to Thumb"
+      "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-thumb-target.s cortex-a8-fix-blx-rel.s}
+      {{objdump -dr cortex-a8-fix-blx-rel-thumb.d}}
+      "cortex-a8-fix-blx-rel-thumb"}
      {"Unwinding and -gc-sections" "-gc-sections" "" {gc-unwind.s}
       {{objdump -sj.data gc-unwind.d}}
       "gc-unwind"}
Index: ld/testsuite/ld-arm/cortex-a8-arm-target.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-arm-target.s
diff -N ld/testsuite/ld-arm/cortex-a8-arm-target.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-arm-target.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,9 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.text
+ 	.arm
+ 	.align 3
+ 	.global targetfn
+ 	.type targetfn, %function
+ targetfn:
+ 	bx lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-b-rel-arm.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-b-rel-arm.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-b-rel-arm.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-b-rel-arm.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,83 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	e12fff1e 	bx	lr
+     8f04:	e320f000 	nop	\{0\}
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f000 b87f 	b\.w	9010 <__targetfn_from_thumb>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f000 b87b 	b\.w	9010 <__targetfn_from_thumb>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f000 b877 	b\.w	9010 <__targetfn_from_thumb>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f000 b873 	b\.w	9010 <__targetfn_from_thumb>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f000 b86f 	b\.w	9010 <__targetfn_from_thumb>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f000 b86b 	b\.w	9010 <__targetfn_from_thumb>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f000 b867 	b\.w	9010 <__targetfn_from_thumb>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f000 b863 	b\.w	9010 <__targetfn_from_thumb>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f000 b85f 	b\.w	9010 <__targetfn_from_thumb>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f000 b85b 	b\.w	9010 <__targetfn_from_thumb>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f000 b857 	b\.w	9010 <__targetfn_from_thumb>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f000 b853 	b\.w	9010 <__targetfn_from_thumb>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f000 b84f 	b\.w	9010 <__targetfn_from_thumb>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f000 b84b 	b\.w	9010 <__targetfn_from_thumb>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f000 b847 	b\.w	9010 <__targetfn_from_thumb>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f000 b843 	b\.w	9010 <__targetfn_from_thumb>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f000 b83f 	b\.w	9010 <__targetfn_from_thumb>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f000 b83b 	b\.w	9010 <__targetfn_from_thumb>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f000 b837 	b\.w	9010 <__targetfn_from_thumb>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f000 b833 	b\.w	9010 <__targetfn_from_thumb>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f000 b82f 	b\.w	9010 <__targetfn_from_thumb>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f000 b82b 	b\.w	9010 <__targetfn_from_thumb>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f000 b827 	b\.w	9010 <__targetfn_from_thumb>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f000 b823 	b\.w	9010 <__targetfn_from_thumb>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f000 b81f 	b\.w	9010 <__targetfn_from_thumb>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f000 b81b 	b\.w	9010 <__targetfn_from_thumb>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f000 b817 	b\.w	9010 <__targetfn_from_thumb>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f000 b813 	b\.w	9010 <__targetfn_from_thumb>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f000 b80f 	b\.w	9010 <__targetfn_from_thumb>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f000 b80b 	b\.w	9010 <__targetfn_from_thumb>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 b807 	b\.w	9010 <__targetfn_from_thumb>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f000 b803 	b\.w	9010 <__targetfn_from_thumb>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+ 
+ 00009010 <__targetfn_from_thumb>:
+     9010:	4778      	bx	pc
+     9012:	46c0      	nop			\(mov r8, r8\)
+     9014:	eaffffb9 	b	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-b-rel-thumb.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-b-rel-thumb.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-b-rel-thumb.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-b-rel-thumb.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,80 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	4770      	bx	lr
+     8f02:	bf00      	nop
+     8f04:	f3af 8000 	nop\.w
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff bff7 	b\.w	8f00 <targetfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff bff3 	b\.w	8f00 <targetfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff bfef 	b\.w	8f00 <targetfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff bfeb 	b\.w	8f00 <targetfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff bfe7 	b\.w	8f00 <targetfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff bfe3 	b\.w	8f00 <targetfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff bfdf 	b\.w	8f00 <targetfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff bfdb 	b\.w	8f00 <targetfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff bfd7 	b\.w	8f00 <targetfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff bfd3 	b\.w	8f00 <targetfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff bfcf 	b\.w	8f00 <targetfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff bfcb 	b\.w	8f00 <targetfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff bfc7 	b\.w	8f00 <targetfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff bfc3 	b\.w	8f00 <targetfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff bfbf 	b\.w	8f00 <targetfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff bfbb 	b\.w	8f00 <targetfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff bfb7 	b\.w	8f00 <targetfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff bfb3 	b\.w	8f00 <targetfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff bfaf 	b\.w	8f00 <targetfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff bfab 	b\.w	8f00 <targetfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff bfa7 	b\.w	8f00 <targetfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff bfa3 	b\.w	8f00 <targetfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff bf9f 	b\.w	8f00 <targetfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff bf9b 	b\.w	8f00 <targetfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff bf97 	b\.w	8f00 <targetfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff bf93 	b\.w	8f00 <targetfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff bf8f 	b\.w	8f00 <targetfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff bf8b 	b\.w	8f00 <targetfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff bf87 	b\.w	8f00 <targetfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff bf83 	b\.w	8f00 <targetfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 b807 	b\.w	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f7ff bf7b 	b\.w	8f00 <targetfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	f7ff bf76 	b\.w	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-b-rel.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-b-rel.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-b-rel.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-b-rel.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,41 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         b.w targetfn
+         add.w r0, r1, r2
+         b.w targetfn
+         add.w r0, r1, r2
+         b.w targetfn
+         add.w r0, r1, r2
+         b.w targetfn
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+ 	nop
+ 
+ 	@ If branching to an ARM destination, we *don't* want to create a
+ 	@ Cortex-A8 stub: the Thumb-to-ARM stub will suffice (and we need it
+ 	@ to change mode).
+ 	bw2
+ 	bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-b.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-b.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-b.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-b.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,75 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <_start>:
+     8f00:	bf00      	nop
+     8f02:	eb01 0002 	add\.w	r0, r1, r2
+     8f06:	f7ff bffc 	b\.w	8f02 <_start\+0x2>
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff bff8 	b\.w	8f02 <_start\+0x2>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff bff4 	b\.w	8f02 <_start\+0x2>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff bff0 	b\.w	8f02 <_start\+0x2>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff bffc 	b\.w	8f22 <_start\+0x22>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff bff8 	b\.w	8f22 <_start\+0x22>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff bff4 	b\.w	8f22 <_start\+0x22>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff bff0 	b\.w	8f22 <_start\+0x22>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff bffc 	b\.w	8f42 <_start\+0x42>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff bff8 	b\.w	8f42 <_start\+0x42>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff bff4 	b\.w	8f42 <_start\+0x42>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff bff0 	b\.w	8f42 <_start\+0x42>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff bffc 	b\.w	8f62 <_start\+0x62>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff bff8 	b\.w	8f62 <_start\+0x62>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff bff4 	b\.w	8f62 <_start\+0x62>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff bff0 	b\.w	8f62 <_start\+0x62>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff bffc 	b\.w	8f82 <_start\+0x82>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff bff8 	b\.w	8f82 <_start\+0x82>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff bff4 	b\.w	8f82 <_start\+0x82>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff bff0 	b\.w	8f82 <_start\+0x82>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff bffc 	b\.w	8fa2 <_start\+0xa2>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff bff8 	b\.w	8fa2 <_start\+0xa2>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff bff4 	b\.w	8fa2 <_start\+0xa2>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff bff0 	b\.w	8fa2 <_start\+0xa2>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff bffc 	b\.w	8fc2 <_start\+0xc2>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff bff8 	b\.w	8fc2 <_start\+0xc2>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff bff4 	b\.w	8fc2 <_start\+0xc2>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff bff0 	b\.w	8fc2 <_start\+0xc2>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff bffc 	b\.w	8fe2 <_start\+0xe2>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff bff8 	b\.w	8fe2 <_start\+0xe2>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff bff4 	b\.w	8fe2 <_start\+0xe2>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 b803 	b\.w	9008 <_start\+0x108>
+     9002:	4770      	bx	lr
+     9004:	f3af 8000 	nop\.w
+     9008:	f7ff bfeb 	b\.w	8fe2 <_start\+0xe2>
Index: ld/testsuite/ld-arm/cortex-a8-fix-b.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-b.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-b.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-b.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,39 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         b.w 1b
+         add.w r0, r1, r2
+         b.w 1b
+         add.w r0, r1, r2
+         b.w 1b
+         add.w r0, r1, r2
+         b.w 1b
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+         nop
+ 
+ 	@ Trigger Cortex-A8 erratum workaround with b instructions.
+         bw2
+         bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel-thumb.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel-thumb.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel-thumb.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel-thumb.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,82 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	4770      	bx	lr
+     8f02:	bf00      	nop
+     8f04:	f3af 8000 	nop\.w
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f53f aff7 	bmi\.w	8f00 <targetfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f53f aff3 	bmi\.w	8f00 <targetfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f53f afef 	bmi\.w	8f00 <targetfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f53f afeb 	bmi\.w	8f00 <targetfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f53f afe7 	bmi\.w	8f00 <targetfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f53f afe3 	bmi\.w	8f00 <targetfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f53f afdf 	bmi\.w	8f00 <targetfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f53f afdb 	bmi\.w	8f00 <targetfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f53f afd7 	bmi\.w	8f00 <targetfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f53f afd3 	bmi\.w	8f00 <targetfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f53f afcf 	bmi\.w	8f00 <targetfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f53f afcb 	bmi\.w	8f00 <targetfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f53f afc7 	bmi\.w	8f00 <targetfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f53f afc3 	bmi\.w	8f00 <targetfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f53f afbf 	bmi\.w	8f00 <targetfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f53f afbb 	bmi\.w	8f00 <targetfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f53f afb7 	bmi\.w	8f00 <targetfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f53f afb3 	bmi\.w	8f00 <targetfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f53f afaf 	bmi\.w	8f00 <targetfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f53f afab 	bmi\.w	8f00 <targetfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f53f afa7 	bmi\.w	8f00 <targetfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f53f afa3 	bmi\.w	8f00 <targetfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f53f af9f 	bmi\.w	8f00 <targetfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f53f af9b 	bmi\.w	8f00 <targetfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f53f af97 	bmi\.w	8f00 <targetfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f53f af93 	bmi\.w	8f00 <targetfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f53f af8f 	bmi\.w	8f00 <targetfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f53f af8b 	bmi\.w	8f00 <targetfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f53f af87 	bmi\.w	8f00 <targetfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f53f af83 	bmi\.w	8f00 <targetfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 b807 	b\.w	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f53f af7b 	bmi\.w	8f00 <targetfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	d401      	bmi\.n	9016 <_start\+0x10e>
+     9012:	f7ff bff6 	b\.w	9002 <_start\+0xfa>
+     9016:	f7ff bf73 	b\.w	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bcc-rel.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,38 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         bmi.w targetfn
+         add.w r0, r1, r2
+         bmi.w targetfn
+         add.w r0, r1, r2
+         bmi.w targetfn
+         add.w r0, r1, r2
+         bmi.w targetfn
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+ 	nop
+ 
+ 	bw2
+ 	bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-bcc.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bcc.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bcc.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bcc.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,77 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <_start>:
+     8f00:	bf00      	nop
+     8f02:	eb01 0002 	add\.w	r0, r1, r2
+     8f06:	f4ff affc 	bcc\.w	8f02 <_start\+0x2>
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f4ff aff8 	bcc\.w	8f02 <_start\+0x2>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f4ff aff4 	bcc\.w	8f02 <_start\+0x2>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f4ff aff0 	bcc\.w	8f02 <_start\+0x2>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f4ff affc 	bcc\.w	8f22 <_start\+0x22>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f4ff aff8 	bcc\.w	8f22 <_start\+0x22>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f4ff aff4 	bcc\.w	8f22 <_start\+0x22>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f4ff aff0 	bcc\.w	8f22 <_start\+0x22>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f4ff affc 	bcc\.w	8f42 <_start\+0x42>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f4ff aff8 	bcc\.w	8f42 <_start\+0x42>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f4ff aff4 	bcc\.w	8f42 <_start\+0x42>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f4ff aff0 	bcc\.w	8f42 <_start\+0x42>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f4ff affc 	bcc\.w	8f62 <_start\+0x62>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f4ff aff8 	bcc\.w	8f62 <_start\+0x62>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f4ff aff4 	bcc\.w	8f62 <_start\+0x62>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f4ff aff0 	bcc\.w	8f62 <_start\+0x62>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f4ff affc 	bcc\.w	8f82 <_start\+0x82>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f4ff aff8 	bcc\.w	8f82 <_start\+0x82>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f4ff aff4 	bcc\.w	8f82 <_start\+0x82>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f4ff aff0 	bcc\.w	8f82 <_start\+0x82>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f4ff affc 	bcc\.w	8fa2 <_start\+0xa2>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f4ff aff8 	bcc\.w	8fa2 <_start\+0xa2>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f4ff aff4 	bcc\.w	8fa2 <_start\+0xa2>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f4ff aff0 	bcc\.w	8fa2 <_start\+0xa2>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f4ff affc 	bcc\.w	8fc2 <_start\+0xc2>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f4ff aff8 	bcc\.w	8fc2 <_start\+0xc2>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f4ff aff4 	bcc\.w	8fc2 <_start\+0xc2>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f4ff aff0 	bcc\.w	8fc2 <_start\+0xc2>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f4ff affc 	bcc\.w	8fe2 <_start\+0xe2>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f4ff aff8 	bcc\.w	8fe2 <_start\+0xe2>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f4ff aff4 	bcc\.w	8fe2 <_start\+0xe2>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 b803 	b\.w	9008 <_start\+0x108>
+     9002:	4770      	bx	lr
+     9004:	f3af 8000 	nop\.w
+     9008:	d301      	bcc\.n	900e <_start\+0x10e>
+     900a:	f7ff bffa 	b\.w	9002 <_start\+0x102>
+     900e:	f7ff bfe8 	b\.w	8fe2 <_start\+0xe2>
Index: ld/testsuite/ld-arm/cortex-a8-fix-bcc.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bcc.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bcc.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bcc.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,39 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         bcc.w 1b
+         add.w r0, r1, r2
+         bcc.w 1b
+         add.w r0, r1, r2
+         bcc.w 1b
+         add.w r0, r1, r2
+         bcc.w 1b
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+         nop
+ 
+ 	@ Trigger Cortex-A8 erratum workaround with conditional branches.
+         bw2
+         bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-arm.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-arm.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-arm.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-arm.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,79 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	e12fff1e 	bx	lr
+     8f04:	e320f000 	nop	\{0\}
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff eff8 	blx	8f00 <targetfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff eff4 	blx	8f00 <targetfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff eff0 	blx	8f00 <targetfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff efec 	blx	8f00 <targetfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff efe8 	blx	8f00 <targetfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff efe4 	blx	8f00 <targetfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff efe0 	blx	8f00 <targetfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff efdc 	blx	8f00 <targetfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff efd8 	blx	8f00 <targetfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff efd4 	blx	8f00 <targetfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff efd0 	blx	8f00 <targetfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff efcc 	blx	8f00 <targetfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff efc8 	blx	8f00 <targetfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff efc4 	blx	8f00 <targetfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff efc0 	blx	8f00 <targetfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff efbc 	blx	8f00 <targetfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff efb8 	blx	8f00 <targetfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff efb4 	blx	8f00 <targetfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff efb0 	blx	8f00 <targetfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff efac 	blx	8f00 <targetfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff efa8 	blx	8f00 <targetfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff efa4 	blx	8f00 <targetfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff efa0 	blx	8f00 <targetfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff ef9c 	blx	8f00 <targetfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff ef98 	blx	8f00 <targetfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff ef94 	blx	8f00 <targetfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff ef90 	blx	8f00 <targetfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff ef8c 	blx	8f00 <targetfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff ef88 	blx	8f00 <targetfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff ef84 	blx	8f00 <targetfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 e808 	blx	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f7ff ef7c 	blx	8f00 <targetfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	eaffffba 	b	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-thumb.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-thumb.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-thumb.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bl-rel-thumb.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,80 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	4770      	bx	lr
+     8f02:	bf00      	nop
+     8f04:	f3af 8000 	nop\.w
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff fff7 	bl	8f00 <targetfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff fff3 	bl	8f00 <targetfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff ffef 	bl	8f00 <targetfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff ffeb 	bl	8f00 <targetfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff ffe7 	bl	8f00 <targetfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff ffe3 	bl	8f00 <targetfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff ffdf 	bl	8f00 <targetfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff ffdb 	bl	8f00 <targetfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff ffd7 	bl	8f00 <targetfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff ffd3 	bl	8f00 <targetfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff ffcf 	bl	8f00 <targetfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff ffcb 	bl	8f00 <targetfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff ffc7 	bl	8f00 <targetfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff ffc3 	bl	8f00 <targetfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff ffbf 	bl	8f00 <targetfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff ffbb 	bl	8f00 <targetfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff ffb7 	bl	8f00 <targetfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff ffb3 	bl	8f00 <targetfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff ffaf 	bl	8f00 <targetfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff ffab 	bl	8f00 <targetfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff ffa7 	bl	8f00 <targetfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff ffa3 	bl	8f00 <targetfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff ff9f 	bl	8f00 <targetfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff ff9b 	bl	8f00 <targetfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff ff97 	bl	8f00 <targetfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff ff93 	bl	8f00 <targetfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff ff8f 	bl	8f00 <targetfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff ff8b 	bl	8f00 <targetfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff ff87 	bl	8f00 <targetfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff ff83 	bl	8f00 <targetfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 f807 	bl	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f7ff ff7b 	bl	8f00 <targetfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	f7ff bf76 	b\.w	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-bl-rel.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bl-rel.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bl-rel.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bl-rel.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,40 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         bl.w targetfn
+         add.w r0, r1, r2
+         bl.w targetfn
+         add.w r0, r1, r2
+         bl.w targetfn
+         add.w r0, r1, r2
+         bl.w targetfn
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+ 	nop
+ 
+ 	@ If calling an ARM destination, we *don't* want to create a
+ 	@ Cortex-A8 stub: the Thumb-to-ARM stub will suffice.
+ 	bw2
+ 	bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-bl.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bl.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bl.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bl.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,75 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <_start>:
+     8f00:	bf00      	nop
+     8f02:	eb01 0002 	add\.w	r0, r1, r2
+     8f06:	f7ff fffc 	bl	8f02 <_start\+0x2>
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff fff8 	bl	8f02 <_start\+0x2>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff fff4 	bl	8f02 <_start\+0x2>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff fff0 	bl	8f02 <_start\+0x2>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff fffc 	bl	8f22 <_start\+0x22>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff fff8 	bl	8f22 <_start\+0x22>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff fff4 	bl	8f22 <_start\+0x22>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff fff0 	bl	8f22 <_start\+0x22>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff fffc 	bl	8f42 <_start\+0x42>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff fff8 	bl	8f42 <_start\+0x42>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff fff4 	bl	8f42 <_start\+0x42>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff fff0 	bl	8f42 <_start\+0x42>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff fffc 	bl	8f62 <_start\+0x62>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff fff8 	bl	8f62 <_start\+0x62>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff fff4 	bl	8f62 <_start\+0x62>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff fff0 	bl	8f62 <_start\+0x62>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff fffc 	bl	8f82 <_start\+0x82>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff fff8 	bl	8f82 <_start\+0x82>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff fff4 	bl	8f82 <_start\+0x82>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff fff0 	bl	8f82 <_start\+0x82>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff fffc 	bl	8fa2 <_start\+0xa2>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff fff8 	bl	8fa2 <_start\+0xa2>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff fff4 	bl	8fa2 <_start\+0xa2>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff fff0 	bl	8fa2 <_start\+0xa2>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff fffc 	bl	8fc2 <_start\+0xc2>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff fff8 	bl	8fc2 <_start\+0xc2>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff fff4 	bl	8fc2 <_start\+0xc2>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff fff0 	bl	8fc2 <_start\+0xc2>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff fffc 	bl	8fe2 <_start\+0xe2>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff fff8 	bl	8fe2 <_start\+0xe2>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff fff4 	bl	8fe2 <_start\+0xe2>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 f803 	bl	9008 <_start\+0x108>
+     9002:	4770      	bx	lr
+     9004:	f3af 8000 	nop\.w
+     9008:	f7ff bfeb 	b\.w	8fe2 <_start\+0xe2>
Index: ld/testsuite/ld-arm/cortex-a8-fix-bl.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-bl.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-bl.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-bl.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,39 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         bl.w 1b
+         add.w r0, r1, r2
+         bl.w 1b
+         add.w r0, r1, r2
+         bl.w 1b
+         add.w r0, r1, r2
+         bl.w 1b
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+         nop
+ 
+ 	@ Trigger Cortex-A8 erratum workaround with bl instructions.
+         bw2
+         bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-arm.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-arm.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-arm.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-arm.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,79 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	e12fff1e 	bx	lr
+     8f04:	e320f000 	nop	\{0\}
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff eff8 	blx	8f00 <targetfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff eff4 	blx	8f00 <targetfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff eff0 	blx	8f00 <targetfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff efec 	blx	8f00 <targetfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff efe8 	blx	8f00 <targetfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff efe4 	blx	8f00 <targetfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff efe0 	blx	8f00 <targetfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff efdc 	blx	8f00 <targetfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff efd8 	blx	8f00 <targetfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff efd4 	blx	8f00 <targetfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff efd0 	blx	8f00 <targetfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff efcc 	blx	8f00 <targetfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff efc8 	blx	8f00 <targetfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff efc4 	blx	8f00 <targetfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff efc0 	blx	8f00 <targetfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff efbc 	blx	8f00 <targetfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff efb8 	blx	8f00 <targetfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff efb4 	blx	8f00 <targetfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff efb0 	blx	8f00 <targetfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff efac 	blx	8f00 <targetfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff efa8 	blx	8f00 <targetfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff efa4 	blx	8f00 <targetfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff efa0 	blx	8f00 <targetfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff ef9c 	blx	8f00 <targetfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff ef98 	blx	8f00 <targetfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff ef94 	blx	8f00 <targetfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff ef90 	blx	8f00 <targetfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff ef8c 	blx	8f00 <targetfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff ef88 	blx	8f00 <targetfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff ef84 	blx	8f00 <targetfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 e808 	blx	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f7ff ef7c 	blx	8f00 <targetfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	eaffffba 	b	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-thumb.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-thumb.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-thumb.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-blx-rel-thumb.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,80 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <targetfn>:
+     8f00:	4770      	bx	lr
+     8f02:	bf00      	nop
+     8f04:	f3af 8000 	nop\.w
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff fff7 	bl	8f00 <targetfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff fff3 	bl	8f00 <targetfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff ffef 	bl	8f00 <targetfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff ffeb 	bl	8f00 <targetfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff ffe7 	bl	8f00 <targetfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff ffe3 	bl	8f00 <targetfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff ffdf 	bl	8f00 <targetfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff ffdb 	bl	8f00 <targetfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff ffd7 	bl	8f00 <targetfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff ffd3 	bl	8f00 <targetfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff ffcf 	bl	8f00 <targetfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff ffcb 	bl	8f00 <targetfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff ffc7 	bl	8f00 <targetfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff ffc3 	bl	8f00 <targetfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff ffbf 	bl	8f00 <targetfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff ffbb 	bl	8f00 <targetfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff ffb7 	bl	8f00 <targetfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff ffb3 	bl	8f00 <targetfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff ffaf 	bl	8f00 <targetfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff ffab 	bl	8f00 <targetfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff ffa7 	bl	8f00 <targetfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff ffa3 	bl	8f00 <targetfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff ff9f 	bl	8f00 <targetfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff ff9b 	bl	8f00 <targetfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff ff97 	bl	8f00 <targetfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff ff93 	bl	8f00 <targetfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff ff8f 	bl	8f00 <targetfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff ff8b 	bl	8f00 <targetfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff ff87 	bl	8f00 <targetfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff ff83 	bl	8f00 <targetfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 f807 	bl	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f7ff ff7b 	bl	8f00 <targetfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	f7ff bf76 	b\.w	8f00 <targetfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-blx-rel.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-blx-rel.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-blx-rel.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-blx-rel.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,38 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.thumb
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+ 1:
+         add.w r0, r1, r2
+         blx.w targetfn
+         add.w r0, r1, r2
+         blx.w targetfn
+         add.w r0, r1, r2
+         blx.w targetfn
+         add.w r0, r1, r2
+         blx.w targetfn
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+         .align  3
+         .global _start
+         .thumb
+         .thumb_func
+         .type   _start, %function
+ _start:
+ 	nop
+ 
+ 	bw2
+ 	bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-fix-blx.d
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-blx.d
diff -N ld/testsuite/ld-arm/cortex-a8-fix-blx.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-blx.d	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,79 ----
+ 
+ .*:     file format .*
+ 
+ 
+ Disassembly of section \.text:
+ 
+ 00008f00 <armfn>:
+     8f00:	e1a02413 	lsl	r2, r3, r4
+     8f04:	e12fff1e 	bx	lr
+ 
+ 00008f08 <_start>:
+     8f08:	bf00      	nop
+     8f0a:	eb01 0002 	add\.w	r0, r1, r2
+     8f0e:	f7ff eff8 	blx	8f00 <armfn>
+     8f12:	eb01 0002 	add\.w	r0, r1, r2
+     8f16:	f7ff eff4 	blx	8f00 <armfn>
+     8f1a:	eb01 0002 	add\.w	r0, r1, r2
+     8f1e:	f7ff eff0 	blx	8f00 <armfn>
+     8f22:	eb01 0002 	add\.w	r0, r1, r2
+     8f26:	f7ff efec 	blx	8f00 <armfn>
+     8f2a:	eb01 0002 	add\.w	r0, r1, r2
+     8f2e:	f7ff efe8 	blx	8f00 <armfn>
+     8f32:	eb01 0002 	add\.w	r0, r1, r2
+     8f36:	f7ff efe4 	blx	8f00 <armfn>
+     8f3a:	eb01 0002 	add\.w	r0, r1, r2
+     8f3e:	f7ff efe0 	blx	8f00 <armfn>
+     8f42:	eb01 0002 	add\.w	r0, r1, r2
+     8f46:	f7ff efdc 	blx	8f00 <armfn>
+     8f4a:	eb01 0002 	add\.w	r0, r1, r2
+     8f4e:	f7ff efd8 	blx	8f00 <armfn>
+     8f52:	eb01 0002 	add\.w	r0, r1, r2
+     8f56:	f7ff efd4 	blx	8f00 <armfn>
+     8f5a:	eb01 0002 	add\.w	r0, r1, r2
+     8f5e:	f7ff efd0 	blx	8f00 <armfn>
+     8f62:	eb01 0002 	add\.w	r0, r1, r2
+     8f66:	f7ff efcc 	blx	8f00 <armfn>
+     8f6a:	eb01 0002 	add\.w	r0, r1, r2
+     8f6e:	f7ff efc8 	blx	8f00 <armfn>
+     8f72:	eb01 0002 	add\.w	r0, r1, r2
+     8f76:	f7ff efc4 	blx	8f00 <armfn>
+     8f7a:	eb01 0002 	add\.w	r0, r1, r2
+     8f7e:	f7ff efc0 	blx	8f00 <armfn>
+     8f82:	eb01 0002 	add\.w	r0, r1, r2
+     8f86:	f7ff efbc 	blx	8f00 <armfn>
+     8f8a:	eb01 0002 	add\.w	r0, r1, r2
+     8f8e:	f7ff efb8 	blx	8f00 <armfn>
+     8f92:	eb01 0002 	add\.w	r0, r1, r2
+     8f96:	f7ff efb4 	blx	8f00 <armfn>
+     8f9a:	eb01 0002 	add\.w	r0, r1, r2
+     8f9e:	f7ff efb0 	blx	8f00 <armfn>
+     8fa2:	eb01 0002 	add\.w	r0, r1, r2
+     8fa6:	f7ff efac 	blx	8f00 <armfn>
+     8faa:	eb01 0002 	add\.w	r0, r1, r2
+     8fae:	f7ff efa8 	blx	8f00 <armfn>
+     8fb2:	eb01 0002 	add\.w	r0, r1, r2
+     8fb6:	f7ff efa4 	blx	8f00 <armfn>
+     8fba:	eb01 0002 	add\.w	r0, r1, r2
+     8fbe:	f7ff efa0 	blx	8f00 <armfn>
+     8fc2:	eb01 0002 	add\.w	r0, r1, r2
+     8fc6:	f7ff ef9c 	blx	8f00 <armfn>
+     8fca:	eb01 0002 	add\.w	r0, r1, r2
+     8fce:	f7ff ef98 	blx	8f00 <armfn>
+     8fd2:	eb01 0002 	add\.w	r0, r1, r2
+     8fd6:	f7ff ef94 	blx	8f00 <armfn>
+     8fda:	eb01 0002 	add\.w	r0, r1, r2
+     8fde:	f7ff ef90 	blx	8f00 <armfn>
+     8fe2:	eb01 0002 	add\.w	r0, r1, r2
+     8fe6:	f7ff ef8c 	blx	8f00 <armfn>
+     8fea:	eb01 0002 	add\.w	r0, r1, r2
+     8fee:	f7ff ef88 	blx	8f00 <armfn>
+     8ff2:	eb01 0002 	add\.w	r0, r1, r2
+     8ff6:	f7ff ef84 	blx	8f00 <armfn>
+     8ffa:	eb01 0002 	add\.w	r0, r1, r2
+     8ffe:	f000 e808 	blx	9010 <_start\+0x108>
+     9002:	eb01 0002 	add\.w	r0, r1, r2
+     9006:	f7ff ef7c 	blx	8f00 <armfn>
+     900a:	4770      	bx	lr
+     900c:	f3af 8000 	nop\.w
+     9010:	eaffffba 	b	8f00 <armfn>
Index: ld/testsuite/ld-arm/cortex-a8-fix-blx.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-fix-blx.s
diff -N ld/testsuite/ld-arm/cortex-a8-fix-blx.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-fix-blx.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,44 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.text
+ 
+ 	@ expansion 32 bytes
+         .macro bw1
+         add.w r0, r1, r2
+         blx.w armfn
+         add.w r0, r1, r2
+         blx.w armfn
+         add.w r0, r1, r2
+         blx.w armfn
+         add.w r0, r1, r2
+         blx.w armfn
+         .endm
+ 
+         @ expansion 128 bytes
+         .macro bw2
+         bw1
+         bw1
+         bw1
+         bw1
+         .endm
+ 
+ 	.arm
+         .align  2
+ armfn:
+ 	mov	r2, r3, asl r4
+ 	bx	lr
+ 
+         .global _start
+ 
+ 	.thumb
+         .thumb_func
+ 	.align 3
+         .type   _start, %function
+ _start:
+         nop
+ 
+ 	@ Trigger Cortex-A8 erratum workaround with blx instructions.
+         bw2
+         bw2
+ 
+         bx      lr
Index: ld/testsuite/ld-arm/cortex-a8-thumb-target.s
===================================================================
RCS file: ld/testsuite/ld-arm/cortex-a8-thumb-target.s
diff -N ld/testsuite/ld-arm/cortex-a8-thumb-target.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/cortex-a8-thumb-target.s	22 May 2009 11:42:39 -0000
***************
*** 0 ****
--- 1,10 ----
+ 	.syntax unified
+ 	.cpu cortex-a8
+ 	.text
+ 	.thumb
+ 	.thumb_func
+ 	.align 3
+ 	.global targetfn
+ 	.type targetfn, %function
+ targetfn:
+ 	bx lr

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