This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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