From 82715c4ce7b2602ca64dae38c77ca8a877f32d34 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 18 Jul 2013 11:24:08 +0000 Subject: * elf32-arm.c (elf32_arm_stub_long_branch_arm_nacl): New variable. (elf32_arm_stub_long_branch_arm_nacl_pic): New variable. (arm_build_one_stub): Increase MAXRELOCS to 3. (arm_type_of_stub): Use them if GLOBALS->nacl_p. (struct elf32_arm_link_hash_table): Give add_stub_section member's pointee type a third argument. (elf32_arm_create_or_find_stub_sec): Update caller. (elf32_arm_size_stubs): Update argument type. * bfd-in.h (elf32_arm_size_stubs): Update decl. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * emultempl/armelf.em (elf32_arm_add_stub_section): Take third argument ALIGNMENT_POWER, use it instead of constant 3. * ld-arm/farcall-arm-nacl.d: New file. * ld-arm/farcall-arm-nacl-pic.d: New file. * ld-arm/farcall-data-nacl.d: New file. * ld-arm/arm-elf.exp (armeabitests_common): Add extra element to "action" lists for those cases to use a different dump file for NaCl targets. Massage $armeabitests_common to drop the extra element or the one before it, depending on [istarget "arm*-*-nacl*"]. * ld-arm/arm-elf.exp (armelftests_common): Move all "Cortex-A8 erratum fix", Thumb-only and interworking cases to ... (armelftests_nonacl): ... here. (armeabitests_common): Move all "erratum 760522 fix", Thumb-only and interworking cases to ... (armeabitests_nonacl): ... here. --- bfd/elf32-arm.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'bfd/elf32-arm.c') diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index eef1b1361a..427ac6d1c0 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2415,6 +2415,33 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] = DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ }; +/* NaCl ARM -> ARM long branch stub. */ +static const insn_sequence elf32_arm_stub_long_branch_arm_nacl[] = +{ + ARM_INSN (0xe59fc00c), /* ldr ip, [pc, #12] */ + ARM_INSN (0xe3ccc13f), /* bic ip, ip, #0xc000000f */ + ARM_INSN (0xe12fff1c), /* bx ip */ + ARM_INSN (0xe320f000), /* nop */ + ARM_INSN (0xe125be70), /* bkpt 0x5be0 */ + DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ + DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ + DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ +}; + +/* NaCl ARM -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_arm_nacl_pic[] = +{ + ARM_INSN (0xe59fc00c), /* ldr ip, [pc, #12] */ + ARM_INSN (0xe08cc00f), /* add ip, ip, pc */ + ARM_INSN (0xe3ccc13f), /* bic ip, ip, #0xc000000f */ + ARM_INSN (0xe12fff1c), /* bx ip */ + ARM_INSN (0xe125be70), /* bkpt 0x5be0 */ + DATA_WORD (0, R_ARM_REL32, 8), /* dcd R_ARM_REL32(X+8) */ + DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ + DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ +}; + + /* Cortex-A8 erratum-workaround stubs. */ /* Stub used for conditional branches (which may be beyond +/-1MB away, so we @@ -2491,6 +2518,8 @@ static const insn_sequence elf32_arm_stub_a8_veneer_blx[] = DEF_STUB(long_branch_thumb_only_pic) \ DEF_STUB(long_branch_any_tls_pic) \ DEF_STUB(long_branch_v4t_thumb_tls_pic) \ + DEF_STUB(long_branch_arm_nacl) \ + DEF_STUB(long_branch_arm_nacl_pic) \ DEF_STUB(a8_veneer_b_cond) \ DEF_STUB(a8_veneer_b) \ DEF_STUB(a8_veneer_bl) \ @@ -2983,7 +3012,7 @@ struct elf32_arm_link_hash_table bfd *stub_bfd; /* Linker call-backs. */ - asection * (*add_stub_section) (const char *, asection *); + asection * (*add_stub_section) (const char *, asection *, unsigned int); void (*layout_sections_again) (void); /* Array to keep track of which stub sections have been created, and @@ -3772,9 +3801,13 @@ arm_type_of_stub (struct bfd_link_info *info, ? (r_type == R_ARM_TLS_CALL /* TLS PIC Stub */ ? arm_stub_long_branch_any_tls_pic - : arm_stub_long_branch_any_arm_pic) + : (globals->nacl_p + ? arm_stub_long_branch_arm_nacl_pic + : arm_stub_long_branch_any_arm_pic)) /* non-PIC stubs. */ - : arm_stub_long_branch_any_any; + : (globals->nacl_p + ? arm_stub_long_branch_arm_nacl + : arm_stub_long_branch_any_any); } } } @@ -3910,7 +3943,8 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section, memcpy (s_name, link_sec->name, namelen); memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX)); - stub_sec = (*htab->add_stub_section) (s_name, link_sec); + stub_sec = (*htab->add_stub_section) (s_name, link_sec, + htab->nacl_p ? 4 : 3); if (stub_sec == NULL) return NULL; htab->stub_group[link_sec->id].stub_sec = stub_sec; @@ -4043,6 +4077,10 @@ arm_stub_required_alignment (enum elf32_arm_stub_type stub_type) case arm_stub_a8_veneer_blx: return 4; + case arm_stub_long_branch_arm_nacl: + case arm_stub_long_branch_arm_nacl_pic: + return 16; + default: abort (); /* Should be unreachable. */ } @@ -4052,7 +4090,7 @@ static bfd_boolean arm_build_one_stub (struct bfd_hash_entry *gen_entry, void * in_arg) { -#define MAXRELOCS 2 +#define MAXRELOCS 3 struct elf32_arm_stub_hash_entry *stub_entry; struct elf32_arm_link_hash_table *globals; struct bfd_link_info *info; @@ -4864,7 +4902,8 @@ elf32_arm_size_stubs (bfd *output_bfd, bfd *stub_bfd, struct bfd_link_info *info, bfd_signed_vma group_size, - asection * (*add_stub_section) (const char *, asection *), + asection * (*add_stub_section) (const char *, asection *, + unsigned int), void (*layout_sections_again) (void)) { bfd_size_type stub_group_size; -- cgit v1.2.1