From c50a03a5d0f06035cdb8bc9df2b12033e650307a Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Thu, 2 Apr 2009 14:12:46 +0000 Subject: [PATCH] 2009-04-02 Christophe Lyon bfd/ * elf32-arm.c (elf32_arm_stub_long_branch_v4t_thumb_thumb, elf32_arm_stub_long_branch_v4t_thumb_thumb_pic): Two new long branch stubs. (elf32_arm_stub_type): New enum values for the two new stubs. (arm_type_of_stub): Make use of the two new stubs. (arm_size_one_stub): Handle the two new stubs. testsuite/ * ld-arm/farcall-thumb-thumb-pic-veneer.d: Update expected results. * ld-arm/farcall-thumb-thumb.d: Likewise. --- bfd/ChangeLog | 9 +++++ bfd/elf32-arm.c | 46 ++++++++++++++++++---- ld/testsuite/ChangeLog | 6 +++ .../ld-arm/farcall-thumb-thumb-pic-veneer.d | 14 +++---- ld/testsuite/ld-arm/farcall-thumb-thumb.d | 10 ++--- 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 89fab56833..ba220010e7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2009-04-02 Christophe Lyon + + * elf32-arm.c (elf32_arm_stub_long_branch_v4t_thumb_thumb, + elf32_arm_stub_long_branch_v4t_thumb_thumb_pic): Two new long + branch stubs. + (elf32_arm_stub_type): New enum values for the two new stubs. + (arm_type_of_stub): Make use of the two new stubs. + (arm_size_one_stub): Handle the two new stubs. + 2009-04-01 Matt Thomas * elf32-vax.c (elf_vax_check_relocs): Do not put relocations against diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index d8106d3d0f..a47d02c020 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2049,9 +2049,7 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] = DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ }; -/* Thumb -> Thumb long branch stub. Used on architectures which - support only this mode, or on V4T where it is expensive to switch - to ARM. */ +/* Thumb -> Thumb long branch stub. Used on M-profile architectures. */ static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] = { THUMB16_INSN(0xb401), /* push {r0} */ @@ -2063,6 +2061,17 @@ static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] = DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ }; +/* V4T Thumb -> Thumb long branch stub. Using the stack is not + allowed. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] = + { + THUMB16_INSN(0x4778), /* bx pc */ + THUMB16_INSN(0x46c0), /* nop */ + ARM_INSN(0xe59fc000), /* ldr ip, [pc, #0] */ + ARM_INSN(0xe12fff1c), /* bx ip */ + DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ + }; + /* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not available. */ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] = @@ -2122,9 +2131,8 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = DATA_WORD(0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ }; -/* Thumb -> Thumb long branch stub, PIC. Used on architectures which - support only this mode, or on V4T where it is expensive to switch - to ARM. */ +/* Thumb -> Thumb long branch stub, PIC. Used on M-profile + architectures. */ static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = { THUMB16_INSN(0xb401), /* push {r0} */ @@ -2136,6 +2144,18 @@ static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = DATA_WORD(0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */ }; +/* V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not + allowed. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] = + { + THUMB16_INSN(0x4778), /* bx pc */ + THUMB16_INSN(0x46c0), /* nop */ + ARM_INSN(0xe59fc004), /* ldr ip, [pc, #4] */ + ARM_INSN(0xe08fc00c), /* add ip, pc, ip */ + ARM_INSN(0xe12fff1c), /* bx ip */ + DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ + }; + /* Section name for stubs is the associated section name plus this string. */ #define STUB_SUFFIX ".stub" @@ -2146,6 +2166,7 @@ enum elf32_arm_stub_type arm_stub_long_branch_any_any, arm_stub_long_branch_v4t_arm_thumb, arm_stub_long_branch_thumb_only, + arm_stub_long_branch_v4t_thumb_thumb, arm_stub_long_branch_v4t_thumb_arm, arm_stub_short_branch_v4t_thumb_arm, arm_stub_long_branch_any_arm_pic, @@ -2153,6 +2174,7 @@ enum elf32_arm_stub_type arm_stub_long_branch_v4t_arm_thumb_pic, arm_stub_long_branch_v4t_thumb_arm_pic, arm_stub_long_branch_thumb_only_pic, + arm_stub_long_branch_v4t_thumb_thumb_pic, }; struct elf32_arm_stub_hash_entry @@ -2923,14 +2945,14 @@ arm_type_of_stub (struct bfd_link_info *info, /* V5T and above. */ ? arm_stub_long_branch_any_thumb_pic /* On V4T, use Thumb code only. */ - : arm_stub_long_branch_thumb_only_pic) + : arm_stub_long_branch_v4t_thumb_thumb_pic) /* non-PIC stubs. */ : ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_any /* V4T. */ - : arm_stub_long_branch_thumb_only); + : arm_stub_long_branch_v4t_thumb_thumb); } else { @@ -3336,6 +3358,10 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry, template = elf32_arm_stub_long_branch_thumb_only; template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only); break; + case arm_stub_long_branch_v4t_thumb_thumb: + template = elf32_arm_stub_long_branch_v4t_thumb_thumb; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_thumb); + break; case arm_stub_long_branch_v4t_thumb_arm: template = elf32_arm_stub_long_branch_v4t_thumb_arm; template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm); @@ -3364,6 +3390,10 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry, template = elf32_arm_stub_long_branch_thumb_only_pic; template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only_pic); break; + case arm_stub_long_branch_v4t_thumb_thumb_pic: + template = elf32_arm_stub_long_branch_v4t_thumb_thumb_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_thumb_pic); + break; default: BFD_FAIL (); return FALSE; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 00d97220cd..60ed315a24 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-04-02 Christophe Lyon + + * ld-arm/farcall-thumb-thumb-pic-veneer.d: Update expected + results. + * ld-arm/farcall-thumb-thumb.d: Likewise. + 2009-04-02 Nick Clifton PR 9987 diff --git a/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d b/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d index c96ea3f19a..96549a59a3 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d +++ b/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d @@ -8,13 +8,13 @@ Disassembly of section .text: ... 00001008 <__bar_veneer>: - 1008: b401 push {r0} - 100a: 4802 ldr r0, \[pc, #8\] \(1014 <__bar_veneer\+0xc>\) - 100c: 46fc mov ip, pc - 100e: 4484 add ip, r0 - 1010: bc01 pop {r0} - 1012: 4760 bx ip - 1014: 02000005 .word 0x02000005 + 1008: 4778 bx pc + 100a: 46c0 nop \(mov r8, r8\) + 100c: e59fc004 ldr ip, \[pc, #4\] ; 1018 <__bar_veneer\+0x10> + 1010: e08fc00c add ip, pc, ip + 1014: e12fff1c bx ip + 1018: 01fffffd .word 0x01fffffd + 101c: 00000000 .word 0x00000000 Disassembly of section .foo: diff --git a/ld/testsuite/ld-arm/farcall-thumb-thumb.d b/ld/testsuite/ld-arm/farcall-thumb-thumb.d index c98f00a290..e4a96eaae8 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-thumb.d +++ b/ld/testsuite/ld-arm/farcall-thumb-thumb.d @@ -8,12 +8,10 @@ Disassembly of section .text: \.\.\. 00001008 <__bar_veneer>: - 1008: b401 push {r0} - 100a: 4802 ldr r0, \[pc, #8\] \(1014 <__bar_veneer\+0xc>\) - 100c: 4684 mov ip, r0 - 100e: bc01 pop {r0} - 1010: 4760 bx ip - 1012: bf00 nop + 1008: 4778 bx pc + 100a: 46c0 nop \(mov r8, r8\) + 100c: e59fc000 ldr ip, \[pc, #0\] ; 1014 <__bar_veneer\+0xc> + 1010: e12fff1c bx ip 1014: 02001015 .word 0x02001015 Disassembly of section .foo: -- 2.11.0