From f4ac8484646f3c9e8e7a89d49f2d01b5bdd1c39f Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Mon, 9 Jun 2008 14:53:13 +0000 Subject: [PATCH] 2008-06-03 Christophe Lyon bfd/ * elf32-arm.c (arm_stub_is_thumb): Define. (elf32_arm_final_link_relocate): Handle near mode switching stubs. ld/testsuite/ * ld-arm/farcall-thumb-thumb-m.d: Fix branch type. * ld-arm/farcall-thumb-arm.d: Likewise. --- bfd/ChangeLog | 5 ++++ bfd/elf32-arm.c | 30 ++++++++++++++++++--- ld/testsuite/ChangeLog | 5 ++++ ld/testsuite/ld-arm/farcall-thumb-arm.d | 2 +- ld/testsuite/ld-arm/farcall-thumb-thumb-m.d | 2 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d096a2bfac..b886cbf8e4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2008-06-09 Christophe Lyon + + * elf32-arm.c (arm_stub_is_thumb): Define. + (elf32_arm_final_link_relocate): Handle near mode switching stubs. + 2008-06-07 Alan Modra * elf32-spu.c (spu_elf_auto_overlay): Add valid area below sp diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 1e32554dc0..1101369917 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2713,6 +2713,23 @@ using_thumb2 (struct elf32_arm_link_hash_table *globals) return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7; } +static bfd_boolean +arm_stub_is_thumb (enum elf32_arm_stub_type stub_type) +{ + switch (stub_type) + { + case arm_thumb_thumb_stub_long_branch: + case arm_thumb_arm_v4t_stub_long_branch: + return TRUE; + case arm_stub_none: + BFD_FAIL (); + return FALSE; + break; + default: + return FALSE; + } +} + /* Determine the type of stub needed, if any, for a call. */ static enum elf32_arm_stub_type @@ -6426,7 +6443,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, || (thumb2 && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET - || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))) + || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET))) + || ((sym_flags != STT_ARM_TFUNC) && !globals->use_blx)) { /* The target is out of reach or we are changing modes, so redirect the branch to the local stub for this @@ -6439,8 +6457,14 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, + stub_entry->stub_sec->output_offset + stub_entry->stub_sec->output_section->vma); - /* This call becomes a call to Arm for sure. Force BLX. */ - lower_insn = (lower_insn & ~0x1000) | 0x0800; + /* If this call becomes a call to Arm, force BLX. */ + if (globals->use_blx) + { + if ((stub_entry + && !arm_stub_is_thumb (stub_entry->stub_type)) + || (sym_flags != STT_ARM_TFUNC)) + lower_insn = (lower_insn & ~0x1000) | 0x0800; + } } } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 5b55275c42..61f6dd9ccd 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-06-09 Christophe Lyon + + * ld-arm/farcall-thumb-thumb-m.d: Fix branch type. + * ld-arm/farcall-thumb-arm.d: Likewise. + 2008-05-31 Nick Clifton PR ld/6430 diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm.d b/ld/testsuite/ld-arm/farcall-thumb-arm.d index bcabeb91e2..d733511d73 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-arm.d +++ b/ld/testsuite/ld-arm/farcall-thumb-arm.d @@ -12,7 +12,7 @@ Disassembly of section .text: ... 00001018 <_start>: - 1018: f7ff eff2 blx 1000 <_start-0x18> + 1018: f7ff fff2 bl 1000 <_start-0x18> Disassembly of section .foo: 02001014 : diff --git a/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d b/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d index 691d4e092d..6415be7551 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d +++ b/ld/testsuite/ld-arm/farcall-thumb-thumb-m.d @@ -12,7 +12,7 @@ Disassembly of section .text: 100c: 02001015 .word 0x02001015 00001010 <_start>: - 1010: f7ff eff6 blx 1000 <_start-0x10> + 1010: f7ff fff6 bl 1000 <_start-0x10> Disassembly of section .foo: 02001014 : -- 2.34.1