aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.c
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@st.com>2009-02-23 10:03:47 +0000
committerChristophe Lyon <christophe.lyon@st.com>2009-02-23 10:03:47 +0000
commitc2b4a39dd204173238cb5bb8a367dc68c8d803ad (patch)
tree82a16ebfa41b8badf75adfd5f885058c8c8a71aa /bfd/elf32-arm.c
parent0c37646508ccd3222db567f20d0ed44a9c3ba1d2 (diff)
downloadgdb-c2b4a39dd204173238cb5bb8a367dc68c8d803ad.zip
gdb-c2b4a39dd204173238cb5bb8a367dc68c8d803ad.tar.gz
gdb-c2b4a39dd204173238cb5bb8a367dc68c8d803ad.tar.bz2
2009-02-23 Christophe Lyon <christophe.lyon@st.com>
bfd/ * elf32-arm.c (elf32_arm_stub_long_branch_thumb_only): Fix stub code. (elf32_arm_stub_long_branch_v4t_thumb_arm): Likewise. (arm_type_of_stub): Use Thumb-only long branch stub (non-PIC) when BLX is not available. Fix typo in warning message. Add comments and improve formatting. (arm_build_one_stub): Adjust to new elf32_arm_stub_long_branch_v4t_thumb_arm stub. (arm_map_one_stub): Likewise. testsuite/ * ld-arm/arm-elf.exp: Rewrite non-EABI variants of thumb2-bl-as-thumb1-bad and thumb2-bl-bad tests, which now pass. farcall-thumb-thumb now passes in EABI mode. * ld-arm/farcall-thumb-arm-pic-veneer.d: Fixed name, source, as and ld flags to match intended test. * ld-arm/farcall-thumb-arm.d: New expected result. * ld-arm/farcall-thumb-thumb-m.d: Likewise. * ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Fixed name and ld flags. * ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise. * ld-arm/farcall-thumb-thumb.d: New expected result, this test is now expected to pass. * ld-arm/thumb2-bl-as-thumb1-bad-noeabi.d: Likewise. * ld-arm/thumb2-bl-bad-noeabi.d: Likewise. * ld-arm/thumb2-bl-as-thumb1-bad.d: Update addresses according to new use. * ld-arm/thumb2-bl-as-thumb1-bad.s: Update comment.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r--bfd/elf32-arm.c73
1 files changed, 45 insertions, 28 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 04f5405..6cf3322 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2032,11 +2032,11 @@ static const bfd_vma elf32_arm_stub_long_branch_v4t_arm_thumb[] =
to ARM. */
static const bfd_vma elf32_arm_stub_long_branch_thumb_only[] =
{
- 0x4e02b540, /* push {r6, lr} */
- /* ldr r6, [pc, #8] */
- 0x473046fe, /* mov lr, pc */
- /* bx r6 */
- 0xbf00bd40, /* pop {r6, pc} */
+ 0x4802b401, /* push {r0} */
+ /* ldr r0, [pc, #8] */
+ 0xbc014684, /* mov ip, r0 */
+ /* pop {r0} */
+ 0xbf004760, /* bx ip */
/* nop */
0x00000000, /* dcd R_ARM_ABS32(X) */
};
@@ -2045,13 +2045,10 @@ static const bfd_vma elf32_arm_stub_long_branch_thumb_only[] =
available. */
static const bfd_vma elf32_arm_stub_long_branch_v4t_thumb_arm[] =
{
- 0x4e03b540, /* push {r6, lr} */
- /* ldr r6, [pc, #12] */
- 0x473046fe, /* mov lr, pc */
- /* bx r6 */
- 0xe8bd4040, /* pop {r6, pc} */
- 0xe12fff1e, /* bx lr */
- 0x00000000, /* dcd R_ARM_ABS32(X) */
+ 0x46c04778, /* bx pc */
+ /* nop */
+ 0xe51ff004, /* ldr pc, [pc, #-4] */
+ 0x00000000, /* dcd R_ARM_ABS32(X) */
};
/* V4T Thumb -> ARM short branch stub. Shorter variant of the above
@@ -2819,20 +2816,27 @@ arm_type_of_stub (struct bfd_link_info *info,
if (!thumb_only)
{
stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
? ((globals->use_blx)
+ /* V5T and above. */
? arm_stub_long_branch_any_any_pic
+ /* not yet supported on V4T. */
: arm_stub_none)
- : (globals->use_blx)
- ? arm_stub_long_branch_any_any
- : arm_stub_none;
+
+ /* non-PIC stubs. */
+ : ((globals->use_blx)
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_any
+ /* V4T. */
+ : arm_stub_long_branch_thumb_only);
}
else
{
stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stub not yet supported on V4T. */
? arm_stub_none
- : (globals->use_blx)
- ? arm_stub_long_branch_thumb_only
- : arm_stub_none;
+ /* non-PIC stub. */
+ : arm_stub_long_branch_thumb_only;
}
}
else
@@ -2849,12 +2853,19 @@ arm_type_of_stub (struct bfd_link_info *info,
}
stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
? ((globals->use_blx)
+ /* V5T and above. */
? arm_stub_long_branch_any_any_pic
+ /* not yet supported on V4T. */
: arm_stub_none)
- : (globals->use_blx)
- ? arm_stub_long_branch_any_any
- : arm_stub_long_branch_v4t_thumb_arm;
+
+ /* non-PIC stubs. */
+ : ((globals->use_blx)
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_any
+ /* V4T. */
+ : arm_stub_long_branch_v4t_thumb_arm);
/* Handle v4t short branches. */
if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
@@ -2876,7 +2887,7 @@ arm_type_of_stub (struct bfd_link_info *info,
{
(*_bfd_error_handler)
(_("%B(%s): warning: interworking not enabled.\n"
- " first occurrence: %B: Thumb call to ARM"),
+ " first occurrence: %B: ARM call to Thumb"),
sym_sec->owner, input_bfd, name);
}
@@ -2887,10 +2898,14 @@ arm_type_of_stub (struct bfd_link_info *info,
|| !globals->use_blx)
{
stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
? arm_stub_long_branch_any_any_pic
- : (globals->use_blx)
- ? arm_stub_long_branch_any_any
- : arm_stub_long_branch_v4t_arm_thumb;
+ /* non-PIC stubs. */
+ : ((globals->use_blx)
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_any
+ /* V4T. */
+ : arm_stub_long_branch_v4t_arm_thumb);
}
}
else
@@ -2900,7 +2915,9 @@ arm_type_of_stub (struct bfd_link_info *info,
|| (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
{
stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
? arm_stub_long_branch_any_any_pic
+ /* non-PIC stubs. */
: arm_stub_long_branch_any_any;
}
}
@@ -3188,7 +3205,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
case arm_stub_long_branch_v4t_thumb_arm:
_bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
stub_bfd, stub_sec, stub_sec->contents,
- stub_entry->stub_offset + 16, sym_value, 0);
+ stub_entry->stub_offset + 8, sym_value, 0);
break;
case arm_stub_short_branch_v4t_thumb_arm:
{
@@ -11697,9 +11714,9 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
return FALSE;
if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
return FALSE;
- if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 8))
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 4))
return FALSE;
- if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
return FALSE;
break;
case arm_stub_short_branch_v4t_thumb_arm: