summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2008-06-09 14:53:12 +0000
committerDaniel Jacobowitz <dan@debian.org>2008-06-09 14:53:12 +0000
commit5e7d4fdbe3e519e81b6cac5a53a93c2749508b13 (patch)
treef1797c9aacd5408fa4e81b3d59b1cfe2a7a98284
parent0513b64766eac642ff2dd74bb34ecd645840020c (diff)
downloadgdb-5e7d4fdbe3e519e81b6cac5a53a93c2749508b13.tar.gz
2008-06-03 Christophe Lyon <christophe.lyon@st.com>
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.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf32-arm.c30
2 files changed, 32 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d096a2bface..b886cbf8e4e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-09 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_stub_is_thumb): Define.
+ (elf32_arm_final_link_relocate): Handle near mode switching stubs.
+
2008-06-07 Alan Modra <amodra@bigpond.net.au>
* 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 1e32554dc0f..1101369917e 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;
+ }
}
}