* ARM long branch stubs: pic take 2 @ 2009-02-25 15:21 Christophe LYON 2009-02-25 17:33 ` Richard Earnshaw 2009-02-26 19:01 ` Paul Brook 0 siblings, 2 replies; 14+ messages in thread From: Christophe LYON @ 2009-02-25 15:21 UTC (permalink / raw) To: Binutils [-- Attachment #1: Type: text/plain, Size: 357 bytes --] Hi all, I am continuing the submission in small pieces of my original big patch (http://sourceware.org/ml/binutils/2009-02/msg00041.html). I think that I will submit 2 more patches in the coming days. Here I propose 3 new stubs to handle PIC cases which were so far unsupported. I suspect the stub code will need careful review again :-) Christophe. [-- Attachment #2: pic2.changelog --] [-- Type: text/plain, Size: 796 bytes --] 2009-02-25 Christophe Lyon <christophe.lyon@st.com> bfd/ * elf32-arm.c (elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub. (elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise. (elf32_arm_stub_long_branch_thumb_only_pic): Likewise. (elf32_arm_stub_type): Add new enum entries for the new stubs. (arm_stub_is_thumb): Catch new stubs. (arm_type_of_stub): Handle new stubs. (arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs. (bfd_elf32_arm_process_before_allocation): Remove useless condition. testsuite/ * ld-arm/arm-elf.exp: Add 3 tests for the 3 new stubs. * ld-arm/farcall-thumb-arm-pic-veneer.d: New expected result, the test is now expected to pass. * ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Likewise. * ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise. [-- Attachment #3: pic2.patch --] [-- Type: text/plain, Size: 13648 bytes --] Index: bfd/elf32-arm.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-arm.c,v retrieving revision 1.177 diff -u -p -r1.177 elf32-arm.c --- bfd/elf32-arm.c 24 Feb 2009 22:44:18 -0000 1.177 +++ bfd/elf32-arm.c 25 Feb 2009 15:19:13 -0000 @@ -2110,6 +2110,40 @@ static const insn_sequence elf32_arm_stu DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ }; +/* V4T ARM -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] = + { + 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) */ + }; + +/* V4T Thumb -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = + { + THUMB16_INSN(0x4778), /* bx pc */ + THUMB16_INSN(0x46c0), /* nop */ + ARM_INSN(0xe59fc004), /* ldr ip, [pc, #4] */ + ARM_INSN(0xe08cc00f), /* add ip, ip, pc */ + ARM_INSN(0xe1a0f00c), /* mov pc, ip */ + DATA_WORD(0, R_ARM_REL32, 0), /* 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. */ +static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = + { + THUMB16_INSN(0xb401), /* push {r0} */ + THUMB16_INSN(0x4802), /* ldr r0, [pc, #8] */ + THUMB16_INSN(0x46fc), /* mov ip, pc */ + THUMB16_INSN(0x4484), /* add ip, r0 */ + THUMB16_INSN(0xbc01), /* pop {r0} */ + THUMB16_INSN(0x4760), /* bx ip */ + DATA_WORD(0, R_ARM_REL32, 2), /* dcd R_ARM_REL32(X) */ + }; + /* Section name for stubs is the associated section name plus this string. */ #define STUB_SUFFIX ".stub" @@ -2124,6 +2158,9 @@ enum elf32_arm_stub_type arm_stub_short_branch_v4t_thumb_arm, arm_stub_long_branch_any_arm_pic, arm_stub_long_branch_any_thumb_pic, + arm_stub_long_branch_v4t_arm_thumb_pic, + arm_stub_long_branch_v4t_thumb_arm_pic, + arm_stub_long_branch_thumb_only_pic, }; struct elf32_arm_stub_hash_entry @@ -2796,6 +2833,8 @@ arm_stub_is_thumb (enum elf32_arm_stub_t case arm_stub_long_branch_thumb_only: case arm_stub_long_branch_v4t_thumb_arm: case arm_stub_short_branch_v4t_thumb_arm: + case arm_stub_long_branch_v4t_thumb_arm_pic: + case arm_stub_long_branch_thumb_only_pic: return TRUE; case arm_stub_none: BFD_FAIL (); @@ -2872,8 +2911,8 @@ arm_type_of_stub (struct bfd_link_info * ? ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_thumb_pic - /* not yet supported on V4T. */ - : arm_stub_none) + /* On V4T, use Thumb code only. */ + : arm_stub_long_branch_thumb_only_pic) /* non-PIC stubs. */ : ((globals->use_blx) @@ -2885,8 +2924,8 @@ arm_type_of_stub (struct bfd_link_info * else { stub_type = (info->shared | globals->pic_veneer) - /* PIC stub not yet supported on V4T. */ - ? arm_stub_none + /* PIC stub. */ + ? arm_stub_long_branch_thumb_only_pic /* non-PIC stub. */ : arm_stub_long_branch_thumb_only; } @@ -2909,8 +2948,8 @@ arm_type_of_stub (struct bfd_link_info * ? ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_arm_pic - /* not yet supported on V4T. */ - : arm_stub_none) + /* V4T PIC stub. */ + : arm_stub_long_branch_v4t_thumb_arm_pic) /* non-PIC stubs. */ : ((globals->use_blx) @@ -2951,7 +2990,12 @@ arm_type_of_stub (struct bfd_link_info * { stub_type = (info->shared | globals->pic_veneer) /* PIC stubs. */ - ? arm_stub_long_branch_any_thumb_pic + ? ((globals->use_blx) + /* V5T and above. */ + ? arm_stub_long_branch_any_thumb_pic + /* V4T stub. */ + : arm_stub_long_branch_v4t_arm_thumb_pic) + /* non-PIC stubs. */ : ((globals->use_blx) /* V5T and above. */ @@ -3271,32 +3315,43 @@ arm_size_one_stub (struct bfd_hash_entry { case arm_stub_long_branch_any_any: template = elf32_arm_stub_long_branch_any_any; - template_size = sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (insn_sequence); - + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_any); break; case arm_stub_long_branch_v4t_arm_thumb: template = elf32_arm_stub_long_branch_v4t_arm_thumb; - template_size = sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb); break; case arm_stub_long_branch_thumb_only: template = elf32_arm_stub_long_branch_thumb_only; - template_size = sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only); break; case arm_stub_long_branch_v4t_thumb_arm: template = elf32_arm_stub_long_branch_v4t_thumb_arm; - template_size = sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm); break; case arm_stub_short_branch_v4t_thumb_arm: template = elf32_arm_stub_short_branch_v4t_thumb_arm; - template_size = sizeof (elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_short_branch_v4t_thumb_arm); break; case arm_stub_long_branch_any_arm_pic: template = elf32_arm_stub_long_branch_any_arm_pic; - template_size = sizeof (elf32_arm_stub_long_branch_any_arm_pic) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_arm_pic); break; case arm_stub_long_branch_any_thumb_pic: template = elf32_arm_stub_long_branch_any_thumb_pic; - template_size = sizeof (elf32_arm_stub_long_branch_any_thumb_pic) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_thumb_pic); + break; + case arm_stub_long_branch_v4t_arm_thumb_pic: + template = elf32_arm_stub_long_branch_v4t_arm_thumb_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb_pic); + break; + case arm_stub_long_branch_v4t_thumb_arm_pic: + template = elf32_arm_stub_long_branch_v4t_thumb_arm_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm_pic); + break; + case arm_stub_long_branch_thumb_only_pic: + template = elf32_arm_stub_long_branch_thumb_only_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only_pic); break; default: BFD_FAIL (); @@ -4647,8 +4702,7 @@ bfd_elf32_arm_process_before_allocation /* This one is a call from arm code. We need to look up the target of the call. If it is a thumb target, we insert glue. */ - if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC - && !(r_type == R_ARM_CALL && globals->use_blx)) + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) record_arm_to_thumb_glue (link_info, h); break; Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v retrieving revision 1.48 diff -u -p -r1.48 arm-elf.exp --- ld/testsuite/ld-arm/arm-elf.exp 24 Feb 2009 22:43:10 -0000 1.48 +++ ld/testsuite/ld-arm/arm-elf.exp 25 Feb 2009 15:19:20 -0000 @@ -296,6 +296,12 @@ set armeabitests { {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s} {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}} "farcall-thumb-thumb-blx-pic-veneer"} + {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7m" {farcall-thumb-thumb.s} + {{objdump -d farcall-thumb-thumb-m-pic-veneer.d}} + "farcall-thumb-thumb-m-pic-veneer"} + {"Thumb-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv4t" {farcall-thumb-thumb.s} + {{objdump -d farcall-thumb-thumb-pic-veneer.d}} + "farcall-thumb-thumb-pic-veneer"} {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm.d}} @@ -315,6 +321,9 @@ set armeabitests { {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}} "farcall-thumb-arm-blx-pic-veneer"} + {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s} + {{objdump -d farcall-thumb-arm-pic-veneer.d}} + "farcall-thumb-arm-pic-veneer"} {"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" {farcall-mix.s} {{objdump -d farcall-mix.d}} @@ -350,9 +359,6 @@ run_dump_test "attr-merge-wchar-24-nowar run_dump_test "attr-merge-wchar-40-nowarn" run_dump_test "attr-merge-wchar-42-nowarn" run_dump_test "attr-merge-wchar-44-nowarn" -run_dump_test "farcall-thumb-thumb-pic-veneer" -run_dump_test "farcall-thumb-thumb-m-pic-veneer" -run_dump_test "farcall-thumb-arm-pic-veneer" run_dump_test "farcall-section" run_dump_test "attr-merge-unknown-1" run_dump_test "attr-merge-unknown-2" Index: ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-arm-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d 25 Feb 2009 15:19:20 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-ARM farcall without BLX (PIC veneer) -#source: farcall-thumb-arm.s -#as: -march=armv4t -W -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_from_thumb> + 1004: 0000 lsls r0, r0, #0 + ... + +00001008 <__bar_from_thumb>: + 1008: 4778 bx pc + 100a: 46c0 nop \(mov r8, r8\) + 100c: e59fc004 ldr ip, \[pc, #4\] ; 1018 <__bar_from_thumb\+0x10> + 1010: e08cc00f add ip, ip, pc + 1014: e1a0f00c mov pc, ip + 1018: 01fffffc .word 0x01fffffc + 101c: 00000000 .word 0x00000000 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: e12fff1e bx lr Index: ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-thumb-m-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d 25 Feb 2009 15:19:20 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-Thumb farcall M profile (PIC veneer) -#source: farcall-thumb-thumb.s -#as: -march=armv4t -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_veneer> + 1004: 0000 lsls r0, r0, #0 + ... + +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: 02000003 .word 0x02000003 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: 4770 bx lr Index: ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-thumb-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 25 Feb 2009 15:19:20 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-Thumb farcall without BLX (PIC veneer) -#source: farcall-thumb-thumb.s -#as: -march=armv4t -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_veneer> + 1004: 0000 lsls r0, r0, #0 + ... + +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: 02000003 .word 0x02000003 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: 4770 bx lr ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-25 15:21 ARM long branch stubs: pic take 2 Christophe LYON @ 2009-02-25 17:33 ` Richard Earnshaw 2009-02-25 17:51 ` Christophe LYON 2009-02-26 19:01 ` Paul Brook 1 sibling, 1 reply; 14+ messages in thread From: Richard Earnshaw @ 2009-02-25 17:33 UTC (permalink / raw) To: Christophe LYON; +Cc: Binutils On Wed, 2009-02-25 at 16:21 +0100, Christophe LYON wrote: > +/* V4T Thumb -> ARM long branch stub, PIC. */ > +static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = > + { > + THUMB16_INSN(0x4778), /* bx pc */ > + THUMB16_INSN(0x46c0), /* nop */ > + ARM_INSN(0xe59fc004), /* ldr ip, [pc, #4] */ > + ARM_INSN(0xe08cc00f), /* add ip, ip, pc */ > + ARM_INSN(0xe1a0f00c), /* mov pc, ip */ > + DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ > + }; We can do slightly better than that: .thumb bx pc nop .arm ldr ip, [pc, #0] add pc, pc, ip dcd R_ARM_REL32(X) Which is OK because we know the target address is ARM. R. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-25 17:33 ` Richard Earnshaw @ 2009-02-25 17:51 ` Christophe LYON 2009-02-26 10:31 ` Richard Earnshaw 0 siblings, 1 reply; 14+ messages in thread From: Christophe LYON @ 2009-02-25 17:51 UTC (permalink / raw) To: Binutils [-- Attachment #1: Type: text/plain, Size: 346 bytes --] On 25.02.2009 18:33, Richard Earnshaw wrote: > We can do slightly better than that: Thanks. I have updated my patch accordingly. In addition to the previous one, I have removed a useless enum type (stub_reloc_type) and renamed the reloc_type field of insn_sequence to r_type to have the same name as usually used in other parts. Christophe. [-- Attachment #2: pic2.changelog --] [-- Type: text/plain, Size: 878 bytes --] 2009-02-25 Christophe Lyon <christophe.lyon@st.com> bfd/ * elf32-arm.c (stub_reloc_type): Removed. (insn_sequence): Renamed reloc_type field to r_type. (elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub. (elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise. (elf32_arm_stub_long_branch_thumb_only_pic): Likewise. (elf32_arm_stub_type): Add new enum entries for the new stubs. (arm_stub_is_thumb): Catch new stubs. (arm_type_of_stub): Handle new stubs. (arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs. (bfd_elf32_arm_process_before_allocation): Remove useless condition. testsuite/ * ld-arm/arm-elf.exp: Add 3 tests for the 3 new stubs. * ld-arm/farcall-thumb-arm-pic-veneer.d: New expected result, the test is now expected to pass. * ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Likewise. * ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise. [-- Attachment #3: pic2.patch --] [-- Type: text/plain, Size: 14960 bytes --] Index: bfd/elf32-arm.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-arm.c,v retrieving revision 1.177 diff -u -p -r1.177 elf32-arm.c --- bfd/elf32-arm.c 24 Feb 2009 22:44:18 -0000 1.177 +++ bfd/elf32-arm.c 25 Feb 2009 17:47:22 -0000 @@ -2018,13 +2018,6 @@ enum stub_insn_type DATA_TYPE }; -enum stub_reloc_type - { - STUB_RELOC_NONE = 0, - STUB_RELOC_ABS, - STUB_RELOC_PIC, - }; - #define THUMB16_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 0} #define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0} #define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0} @@ -2035,7 +2028,7 @@ typedef struct { bfd_vma data; enum stub_insn_type type; - enum stub_reloc_type reloc_type; + unsigned int r_type; int reloc_addend; } insn_sequence; @@ -2110,6 +2103,39 @@ static const insn_sequence elf32_arm_stu DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ }; +/* V4T ARM -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] = + { + 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) */ + }; + +/* V4T Thumb -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = + { + THUMB16_INSN(0x4778), /* bx pc */ + THUMB16_INSN(0x46c0), /* nop */ + ARM_INSN(0xe59fc000), /* ldr ip, [pc, #0] */ + ARM_INSN(0xe08cf00f), /* add pc, ip, pc */ + DATA_WORD(0, R_ARM_REL32, 0), /* 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. */ +static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = + { + THUMB16_INSN(0xb401), /* push {r0} */ + THUMB16_INSN(0x4802), /* ldr r0, [pc, #8] */ + THUMB16_INSN(0x46fc), /* mov ip, pc */ + THUMB16_INSN(0x4484), /* add ip, r0 */ + THUMB16_INSN(0xbc01), /* pop {r0} */ + THUMB16_INSN(0x4760), /* bx ip */ + DATA_WORD(0, R_ARM_REL32, 2), /* dcd R_ARM_REL32(X) */ + }; + /* Section name for stubs is the associated section name plus this string. */ #define STUB_SUFFIX ".stub" @@ -2124,6 +2150,9 @@ enum elf32_arm_stub_type arm_stub_short_branch_v4t_thumb_arm, arm_stub_long_branch_any_arm_pic, arm_stub_long_branch_any_thumb_pic, + arm_stub_long_branch_v4t_arm_thumb_pic, + arm_stub_long_branch_v4t_thumb_arm_pic, + arm_stub_long_branch_thumb_only_pic, }; struct elf32_arm_stub_hash_entry @@ -2796,6 +2825,8 @@ arm_stub_is_thumb (enum elf32_arm_stub_t case arm_stub_long_branch_thumb_only: case arm_stub_long_branch_v4t_thumb_arm: case arm_stub_short_branch_v4t_thumb_arm: + case arm_stub_long_branch_v4t_thumb_arm_pic: + case arm_stub_long_branch_thumb_only_pic: return TRUE; case arm_stub_none: BFD_FAIL (); @@ -2872,8 +2903,8 @@ arm_type_of_stub (struct bfd_link_info * ? ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_thumb_pic - /* not yet supported on V4T. */ - : arm_stub_none) + /* On V4T, use Thumb code only. */ + : arm_stub_long_branch_thumb_only_pic) /* non-PIC stubs. */ : ((globals->use_blx) @@ -2885,8 +2916,8 @@ arm_type_of_stub (struct bfd_link_info * else { stub_type = (info->shared | globals->pic_veneer) - /* PIC stub not yet supported on V4T. */ - ? arm_stub_none + /* PIC stub. */ + ? arm_stub_long_branch_thumb_only_pic /* non-PIC stub. */ : arm_stub_long_branch_thumb_only; } @@ -2909,8 +2940,8 @@ arm_type_of_stub (struct bfd_link_info * ? ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_arm_pic - /* not yet supported on V4T. */ - : arm_stub_none) + /* V4T PIC stub. */ + : arm_stub_long_branch_v4t_thumb_arm_pic) /* non-PIC stubs. */ : ((globals->use_blx) @@ -2951,7 +2982,12 @@ arm_type_of_stub (struct bfd_link_info * { stub_type = (info->shared | globals->pic_veneer) /* PIC stubs. */ - ? arm_stub_long_branch_any_thumb_pic + ? ((globals->use_blx) + /* V5T and above. */ + ? arm_stub_long_branch_any_thumb_pic + /* V4T stub. */ + : arm_stub_long_branch_v4t_arm_thumb_pic) + /* non-PIC stubs. */ : ((globals->use_blx) /* V5T and above. */ @@ -3207,7 +3243,7 @@ arm_build_one_stub (struct bfd_hash_entr put_arm_insn (globals, stub_bfd, template[i].data, loc + size); /* Handle cases where the target is encoded within the instruction. */ - if (template[i].reloc_type == R_ARM_JUMP24) + if (template[i].r_type == R_ARM_JUMP24) { stub_reloc_idx = i; stub_reloc_offset = size; @@ -3241,7 +3277,7 @@ arm_build_one_stub (struct bfd_hash_entr /* Assume there is one and only one entry to relocate in each stub. */ BFD_ASSERT (stub_reloc_idx != -1); - _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].reloc_type), + _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].r_type), stub_bfd, stub_sec, stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset, sym_value, template[stub_reloc_idx].reloc_addend); @@ -3271,32 +3307,43 @@ arm_size_one_stub (struct bfd_hash_entry { case arm_stub_long_branch_any_any: template = elf32_arm_stub_long_branch_any_any; - template_size = sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (insn_sequence); - + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_any); break; case arm_stub_long_branch_v4t_arm_thumb: template = elf32_arm_stub_long_branch_v4t_arm_thumb; - template_size = sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb); break; case arm_stub_long_branch_thumb_only: template = elf32_arm_stub_long_branch_thumb_only; - template_size = sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only); break; case arm_stub_long_branch_v4t_thumb_arm: template = elf32_arm_stub_long_branch_v4t_thumb_arm; - template_size = sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm); break; case arm_stub_short_branch_v4t_thumb_arm: template = elf32_arm_stub_short_branch_v4t_thumb_arm; - template_size = sizeof (elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_short_branch_v4t_thumb_arm); break; case arm_stub_long_branch_any_arm_pic: template = elf32_arm_stub_long_branch_any_arm_pic; - template_size = sizeof (elf32_arm_stub_long_branch_any_arm_pic) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_arm_pic); break; case arm_stub_long_branch_any_thumb_pic: template = elf32_arm_stub_long_branch_any_thumb_pic; - template_size = sizeof (elf32_arm_stub_long_branch_any_thumb_pic) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_thumb_pic); + break; + case arm_stub_long_branch_v4t_arm_thumb_pic: + template = elf32_arm_stub_long_branch_v4t_arm_thumb_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb_pic); + break; + case arm_stub_long_branch_v4t_thumb_arm_pic: + template = elf32_arm_stub_long_branch_v4t_thumb_arm_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm_pic); + break; + case arm_stub_long_branch_thumb_only_pic: + template = elf32_arm_stub_long_branch_thumb_only_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only_pic); break; default: BFD_FAIL (); @@ -4647,8 +4694,7 @@ bfd_elf32_arm_process_before_allocation /* This one is a call from arm code. We need to look up the target of the call. If it is a thumb target, we insert glue. */ - if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC - && !(r_type == R_ARM_CALL && globals->use_blx)) + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) record_arm_to_thumb_glue (link_info, h); break; Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v retrieving revision 1.48 diff -u -p -r1.48 arm-elf.exp --- ld/testsuite/ld-arm/arm-elf.exp 24 Feb 2009 22:43:10 -0000 1.48 +++ ld/testsuite/ld-arm/arm-elf.exp 25 Feb 2009 17:47:34 -0000 @@ -296,6 +296,12 @@ set armeabitests { {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s} {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}} "farcall-thumb-thumb-blx-pic-veneer"} + {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7m" {farcall-thumb-thumb.s} + {{objdump -d farcall-thumb-thumb-m-pic-veneer.d}} + "farcall-thumb-thumb-m-pic-veneer"} + {"Thumb-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv4t" {farcall-thumb-thumb.s} + {{objdump -d farcall-thumb-thumb-pic-veneer.d}} + "farcall-thumb-thumb-pic-veneer"} {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm.d}} @@ -315,6 +321,9 @@ set armeabitests { {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}} "farcall-thumb-arm-blx-pic-veneer"} + {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s} + {{objdump -d farcall-thumb-arm-pic-veneer.d}} + "farcall-thumb-arm-pic-veneer"} {"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" {farcall-mix.s} {{objdump -d farcall-mix.d}} @@ -350,9 +359,6 @@ run_dump_test "attr-merge-wchar-24-nowar run_dump_test "attr-merge-wchar-40-nowarn" run_dump_test "attr-merge-wchar-42-nowarn" run_dump_test "attr-merge-wchar-44-nowarn" -run_dump_test "farcall-thumb-thumb-pic-veneer" -run_dump_test "farcall-thumb-thumb-m-pic-veneer" -run_dump_test "farcall-thumb-arm-pic-veneer" run_dump_test "farcall-section" run_dump_test "attr-merge-unknown-1" run_dump_test "attr-merge-unknown-2" Index: ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-arm-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d 25 Feb 2009 17:47:34 -0000 @@ -1,5 +1,20 @@ -#name: Thumb-ARM farcall without BLX (PIC veneer) -#source: farcall-thumb-arm.s -#as: -march=armv4t -W -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_from_thumb> + 1004: 0000 lsls r0, r0, #0 + ... + +00001008 <__bar_from_thumb>: + 1008: 4778 bx pc + 100a: 46c0 nop \(mov r8, r8\) + 100c: e59fc000 ldr ip, \[pc, #0\] ; 1014 <__bar_from_thumb\+0xc> + 1010: e08cf00f add pc, ip, pc + 1014: 02000000 .word 0x02000000 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: e12fff1e bx lr Index: ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-thumb-m-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d 25 Feb 2009 17:47:34 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-Thumb farcall M profile (PIC veneer) -#source: farcall-thumb-thumb.s -#as: -march=armv4t -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_veneer> + 1004: 0000 lsls r0, r0, #0 + ... + +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: 02000003 .word 0x02000003 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: 4770 bx lr Index: ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-thumb-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 25 Feb 2009 17:47:34 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-Thumb farcall without BLX (PIC veneer) -#source: farcall-thumb-thumb.s -#as: -march=armv4t -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_veneer> + 1004: 0000 lsls r0, r0, #0 + ... + +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: 02000003 .word 0x02000003 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: 4770 bx lr ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-25 17:51 ` Christophe LYON @ 2009-02-26 10:31 ` Richard Earnshaw 2009-02-26 11:55 ` Christophe LYON 0 siblings, 1 reply; 14+ messages in thread From: Richard Earnshaw @ 2009-02-26 10:31 UTC (permalink / raw) To: Christophe LYON; +Cc: Binutils On Wed, 2009-02-25 at 18:51 +0100, Christophe LYON wrote: > +00001000 <_start>: > + 1000: f000 f802 bl 1008 <__bar_from_thumb> > + 1004: 0000 lsls r0, r0, #0 > + ... > + > +00001008 <__bar_from_thumb>: > + 1008: 4778 bx pc > + 100a: 46c0 nop \(mov r8, r8\) > + 100c: e59fc000 ldr ip, \[pc, #0\] ; 1014 > <__bar_from_thumb\+0xc> > + 1010: e08cf00f add pc, ip, pc > + 1014: 02000000 .word 0x02000000 > + > +Disassembly of section .foo: > + > +02001014 <bar>: > + 2001014: e12fff1e bx lr I think that this shows that the offset calculation is wrong: The offset needs to be based on the location of the instruction that uses the PC -- in this case address 0x1010, with PC=0x1018 (since it's an ARM instruction), so 0x1018 + 0x02000000 = 0x02001018, which is the instruction after your bx lr instruction. R. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-26 10:31 ` Richard Earnshaw @ 2009-02-26 11:55 ` Christophe LYON 2009-02-26 14:59 ` Richard Earnshaw 0 siblings, 1 reply; 14+ messages in thread From: Christophe LYON @ 2009-02-26 11:55 UTC (permalink / raw) To: Binutils [-- Attachment #1: Type: text/plain, Size: 629 bytes --] > I think that this shows that the offset calculation is wrong: The > offset needs to be based on the location of the instruction that uses > the PC -- in this case address 0x1010, with PC=0x1018 (since it's an ARM > instruction), so 0x1018 + 0x02000000 = 0x02001018, which is the > instruction after your bx lr instruction. > Good catch! Here an updated patch, with updated offsets for elf32_arm_stub_long_branch_v4t_thumb_arm_pic and elf32_arm_stub_long_branch_thumb_only_pic (and updated expected results farcall-thumb-arm-pic-veneer.d farcall-thumb-thumb-m-pic-veneer.d farcall-thumb-thumb-pic-veneer.d) Christophe. [-- Attachment #2: pic2.changelog --] [-- Type: text/plain, Size: 878 bytes --] 2009-02-25 Christophe Lyon <christophe.lyon@st.com> bfd/ * elf32-arm.c (stub_reloc_type): Removed. (insn_sequence): Renamed reloc_type field to r_type. (elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub. (elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise. (elf32_arm_stub_long_branch_thumb_only_pic): Likewise. (elf32_arm_stub_type): Add new enum entries for the new stubs. (arm_stub_is_thumb): Catch new stubs. (arm_type_of_stub): Handle new stubs. (arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs. (bfd_elf32_arm_process_before_allocation): Remove useless condition. testsuite/ * ld-arm/arm-elf.exp: Add 3 tests for the 3 new stubs. * ld-arm/farcall-thumb-arm-pic-veneer.d: New expected result, the test is now expected to pass. * ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Likewise. * ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise. [-- Attachment #3: pic2.patch --] [-- Type: text/plain, Size: 14961 bytes --] Index: bfd/elf32-arm.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-arm.c,v retrieving revision 1.177 diff -u -p -r1.177 elf32-arm.c --- bfd/elf32-arm.c 24 Feb 2009 22:44:18 -0000 1.177 +++ bfd/elf32-arm.c 26 Feb 2009 11:51:21 -0000 @@ -2018,13 +2018,6 @@ enum stub_insn_type DATA_TYPE }; -enum stub_reloc_type - { - STUB_RELOC_NONE = 0, - STUB_RELOC_ABS, - STUB_RELOC_PIC, - }; - #define THUMB16_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 0} #define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0} #define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0} @@ -2035,7 +2028,7 @@ typedef struct { bfd_vma data; enum stub_insn_type type; - enum stub_reloc_type reloc_type; + unsigned int r_type; int reloc_addend; } insn_sequence; @@ -2110,6 +2103,39 @@ static const insn_sequence elf32_arm_stu DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ }; +/* V4T ARM -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] = + { + 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) */ + }; + +/* V4T Thumb -> ARM long branch stub, PIC. */ +static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = + { + THUMB16_INSN(0x4778), /* bx pc */ + THUMB16_INSN(0x46c0), /* nop */ + ARM_INSN(0xe59fc000), /* ldr ip, [pc, #0] */ + ARM_INSN(0xe08cf00f), /* add pc, ip, pc */ + 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. */ +static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = + { + THUMB16_INSN(0xb401), /* push {r0} */ + THUMB16_INSN(0x4802), /* ldr r0, [pc, #8] */ + THUMB16_INSN(0x46fc), /* mov ip, pc */ + THUMB16_INSN(0x4484), /* add ip, r0 */ + THUMB16_INSN(0xbc01), /* pop {r0} */ + THUMB16_INSN(0x4760), /* bx ip */ + DATA_WORD(0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */ + }; + /* Section name for stubs is the associated section name plus this string. */ #define STUB_SUFFIX ".stub" @@ -2124,6 +2150,9 @@ enum elf32_arm_stub_type arm_stub_short_branch_v4t_thumb_arm, arm_stub_long_branch_any_arm_pic, arm_stub_long_branch_any_thumb_pic, + arm_stub_long_branch_v4t_arm_thumb_pic, + arm_stub_long_branch_v4t_thumb_arm_pic, + arm_stub_long_branch_thumb_only_pic, }; struct elf32_arm_stub_hash_entry @@ -2796,6 +2825,8 @@ arm_stub_is_thumb (enum elf32_arm_stub_t case arm_stub_long_branch_thumb_only: case arm_stub_long_branch_v4t_thumb_arm: case arm_stub_short_branch_v4t_thumb_arm: + case arm_stub_long_branch_v4t_thumb_arm_pic: + case arm_stub_long_branch_thumb_only_pic: return TRUE; case arm_stub_none: BFD_FAIL (); @@ -2872,8 +2903,8 @@ arm_type_of_stub (struct bfd_link_info * ? ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_thumb_pic - /* not yet supported on V4T. */ - : arm_stub_none) + /* On V4T, use Thumb code only. */ + : arm_stub_long_branch_thumb_only_pic) /* non-PIC stubs. */ : ((globals->use_blx) @@ -2885,8 +2916,8 @@ arm_type_of_stub (struct bfd_link_info * else { stub_type = (info->shared | globals->pic_veneer) - /* PIC stub not yet supported on V4T. */ - ? arm_stub_none + /* PIC stub. */ + ? arm_stub_long_branch_thumb_only_pic /* non-PIC stub. */ : arm_stub_long_branch_thumb_only; } @@ -2909,8 +2940,8 @@ arm_type_of_stub (struct bfd_link_info * ? ((globals->use_blx) /* V5T and above. */ ? arm_stub_long_branch_any_arm_pic - /* not yet supported on V4T. */ - : arm_stub_none) + /* V4T PIC stub. */ + : arm_stub_long_branch_v4t_thumb_arm_pic) /* non-PIC stubs. */ : ((globals->use_blx) @@ -2951,7 +2982,12 @@ arm_type_of_stub (struct bfd_link_info * { stub_type = (info->shared | globals->pic_veneer) /* PIC stubs. */ - ? arm_stub_long_branch_any_thumb_pic + ? ((globals->use_blx) + /* V5T and above. */ + ? arm_stub_long_branch_any_thumb_pic + /* V4T stub. */ + : arm_stub_long_branch_v4t_arm_thumb_pic) + /* non-PIC stubs. */ : ((globals->use_blx) /* V5T and above. */ @@ -3207,7 +3243,7 @@ arm_build_one_stub (struct bfd_hash_entr put_arm_insn (globals, stub_bfd, template[i].data, loc + size); /* Handle cases where the target is encoded within the instruction. */ - if (template[i].reloc_type == R_ARM_JUMP24) + if (template[i].r_type == R_ARM_JUMP24) { stub_reloc_idx = i; stub_reloc_offset = size; @@ -3241,7 +3277,7 @@ arm_build_one_stub (struct bfd_hash_entr /* Assume there is one and only one entry to relocate in each stub. */ BFD_ASSERT (stub_reloc_idx != -1); - _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].reloc_type), + _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].r_type), stub_bfd, stub_sec, stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset, sym_value, template[stub_reloc_idx].reloc_addend); @@ -3271,32 +3307,43 @@ arm_size_one_stub (struct bfd_hash_entry { case arm_stub_long_branch_any_any: template = elf32_arm_stub_long_branch_any_any; - template_size = sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (insn_sequence); - + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_any); break; case arm_stub_long_branch_v4t_arm_thumb: template = elf32_arm_stub_long_branch_v4t_arm_thumb; - template_size = sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb); break; case arm_stub_long_branch_thumb_only: template = elf32_arm_stub_long_branch_thumb_only; - template_size = sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only); break; case arm_stub_long_branch_v4t_thumb_arm: template = elf32_arm_stub_long_branch_v4t_thumb_arm; - template_size = sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm); break; case arm_stub_short_branch_v4t_thumb_arm: template = elf32_arm_stub_short_branch_v4t_thumb_arm; - template_size = sizeof (elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_short_branch_v4t_thumb_arm); break; case arm_stub_long_branch_any_arm_pic: template = elf32_arm_stub_long_branch_any_arm_pic; - template_size = sizeof (elf32_arm_stub_long_branch_any_arm_pic) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_arm_pic); break; case arm_stub_long_branch_any_thumb_pic: template = elf32_arm_stub_long_branch_any_thumb_pic; - template_size = sizeof (elf32_arm_stub_long_branch_any_thumb_pic) / sizeof (insn_sequence); + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_thumb_pic); + break; + case arm_stub_long_branch_v4t_arm_thumb_pic: + template = elf32_arm_stub_long_branch_v4t_arm_thumb_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb_pic); + break; + case arm_stub_long_branch_v4t_thumb_arm_pic: + template = elf32_arm_stub_long_branch_v4t_thumb_arm_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm_pic); + break; + case arm_stub_long_branch_thumb_only_pic: + template = elf32_arm_stub_long_branch_thumb_only_pic; + template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only_pic); break; default: BFD_FAIL (); @@ -4647,8 +4694,7 @@ bfd_elf32_arm_process_before_allocation /* This one is a call from arm code. We need to look up the target of the call. If it is a thumb target, we insert glue. */ - if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC - && !(r_type == R_ARM_CALL && globals->use_blx)) + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) record_arm_to_thumb_glue (link_info, h); break; Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v retrieving revision 1.48 diff -u -p -r1.48 arm-elf.exp --- ld/testsuite/ld-arm/arm-elf.exp 24 Feb 2009 22:43:10 -0000 1.48 +++ ld/testsuite/ld-arm/arm-elf.exp 26 Feb 2009 11:51:26 -0000 @@ -296,6 +296,12 @@ set armeabitests { {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s} {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}} "farcall-thumb-thumb-blx-pic-veneer"} + {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7m" {farcall-thumb-thumb.s} + {{objdump -d farcall-thumb-thumb-m-pic-veneer.d}} + "farcall-thumb-thumb-m-pic-veneer"} + {"Thumb-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv4t" {farcall-thumb-thumb.s} + {{objdump -d farcall-thumb-thumb-pic-veneer.d}} + "farcall-thumb-thumb-pic-veneer"} {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm.d}} @@ -315,6 +321,9 @@ set armeabitests { {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}} "farcall-thumb-arm-blx-pic-veneer"} + {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s} + {{objdump -d farcall-thumb-arm-pic-veneer.d}} + "farcall-thumb-arm-pic-veneer"} {"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" {farcall-mix.s} {{objdump -d farcall-mix.d}} @@ -350,9 +359,6 @@ run_dump_test "attr-merge-wchar-24-nowar run_dump_test "attr-merge-wchar-40-nowarn" run_dump_test "attr-merge-wchar-42-nowarn" run_dump_test "attr-merge-wchar-44-nowarn" -run_dump_test "farcall-thumb-thumb-pic-veneer" -run_dump_test "farcall-thumb-thumb-m-pic-veneer" -run_dump_test "farcall-thumb-arm-pic-veneer" run_dump_test "farcall-section" run_dump_test "attr-merge-unknown-1" run_dump_test "attr-merge-unknown-2" Index: ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-arm-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d 26 Feb 2009 11:51:27 -0000 @@ -1,5 +1,20 @@ -#name: Thumb-ARM farcall without BLX (PIC veneer) -#source: farcall-thumb-arm.s -#as: -march=armv4t -W -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_from_thumb> + 1004: 0000 lsls r0, r0, #0 + ... + +00001008 <__bar_from_thumb>: + 1008: 4778 bx pc + 100a: 46c0 nop \(mov r8, r8\) + 100c: e59fc000 ldr ip, \[pc, #0\] ; 1014 <__bar_from_thumb\+0xc> + 1010: e08cf00f add pc, ip, pc + 1014: 01fffffc .word 0x01fffffc + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: e12fff1e bx lr Index: ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-thumb-m-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d 26 Feb 2009 11:51:27 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-Thumb farcall M profile (PIC veneer) -#source: farcall-thumb-thumb.s -#as: -march=armv4t -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_veneer> + 1004: 0000 lsls r0, r0, #0 + ... + +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 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: 4770 bx lr Index: ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d,v retrieving revision 1.2 diff -u -p -r1.2 farcall-thumb-thumb-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 23 Feb 2009 10:03:47 -0000 1.2 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 26 Feb 2009 11:51:27 -0000 @@ -1,5 +1,22 @@ -#name: Thumb-Thumb farcall without BLX (PIC veneer) -#source: farcall-thumb-thumb.s -#as: -march=armv4t -#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer -#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar' +.*: file format .* + +Disassembly of section .text: + +00001000 <_start>: + 1000: f000 f802 bl 1008 <__bar_veneer> + 1004: 0000 lsls r0, r0, #0 + ... + +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 + +Disassembly of section .foo: + +02001014 <bar>: + 2001014: 4770 bx lr ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-26 11:55 ` Christophe LYON @ 2009-02-26 14:59 ` Richard Earnshaw 2009-02-26 15:06 ` Daniel Jacobowitz 0 siblings, 1 reply; 14+ messages in thread From: Richard Earnshaw @ 2009-02-26 14:59 UTC (permalink / raw) To: Christophe LYON; +Cc: Binutils, Daniel Jacobowitz On Thu, 2009-02-26 at 12:55 +0100, Christophe LYON wrote: > > I think that this shows that the offset calculation is wrong: The > > offset needs to be based on the location of the instruction that uses > > the PC -- in this case address 0x1010, with PC=0x1018 (since it's an ARM > > instruction), so 0x1018 + 0x02000000 = 0x02001018, which is the > > instruction after your bx lr instruction. > > > > Good catch! > Here an updated patch, with updated offsets for > elf32_arm_stub_long_branch_v4t_thumb_arm_pic and > elf32_arm_stub_long_branch_thumb_only_pic (and updated expected results > farcall-thumb-arm-pic-veneer.d farcall-thumb-thumb-m-pic-veneer.d > farcall-thumb-thumb-pic-veneer.d) > > Christophe. > plain text document attachment (pic2.changelog) > 2009-02-25 Christophe Lyon <christophe.lyon@st.com> > > bfd/ > * elf32-arm.c (stub_reloc_type): Removed. > (insn_sequence): Renamed reloc_type field to r_type. > (elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub. > (elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise. > (elf32_arm_stub_long_branch_thumb_only_pic): Likewise. > (elf32_arm_stub_type): Add new enum entries for the new stubs. > (arm_stub_is_thumb): Catch new stubs. > (arm_type_of_stub): Handle new stubs. > (arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs. > (bfd_elf32_arm_process_before_allocation): Remove useless > condition. > > testsuite/ > * ld-arm/arm-elf.exp: Add 3 tests for the 3 new stubs. > * ld-arm/farcall-thumb-arm-pic-veneer.d: New expected result, the > test is now expected to pass. > * ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Likewise. > * ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise. Yes, I think this is OK now. Daniel, you've reviewed most of this series, do you have any final comments? R. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-26 14:59 ` Richard Earnshaw @ 2009-02-26 15:06 ` Daniel Jacobowitz 2009-02-26 15:34 ` Christophe LYON 0 siblings, 1 reply; 14+ messages in thread From: Daniel Jacobowitz @ 2009-02-26 15:06 UTC (permalink / raw) To: Richard Earnshaw; +Cc: Christophe LYON, Binutils On Thu, Feb 26, 2009 at 02:59:28PM +0000, Richard Earnshaw wrote: > Yes, I think this is OK now. Daniel, you've reviewed most of this > series, do you have any final comments? It looks good to me also. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-26 15:06 ` Daniel Jacobowitz @ 2009-02-26 15:34 ` Christophe LYON 2009-02-26 15:41 ` Daniel Jacobowitz 0 siblings, 1 reply; 14+ messages in thread From: Christophe LYON @ 2009-02-26 15:34 UTC (permalink / raw) To: Binutils On 26.02.2009 16:06, Daniel Jacobowitz wrote: > On Thu, Feb 26, 2009 at 02:59:28PM +0000, Richard Earnshaw wrote: >> Yes, I think this is OK now. Daniel, you've reviewed most of this >> series, do you have any final comments? > > It looks good to me also. > Thanks to all of you! Sorry for making the reviewers job so useful :-) I commit this patch asap and prepare the next one. Christophe. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-26 15:34 ` Christophe LYON @ 2009-02-26 15:41 ` Daniel Jacobowitz 0 siblings, 0 replies; 14+ messages in thread From: Daniel Jacobowitz @ 2009-02-26 15:41 UTC (permalink / raw) To: Christophe LYON; +Cc: Binutils On Thu, Feb 26, 2009 at 04:34:37PM +0100, Christophe LYON wrote: > Thanks to all of you! > Sorry for making the reviewers job so useful :-) Thank you, too. We're going through a couple of rough spots on these patches - but they're very useful, and it's a worthwhile exercise on all sides. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-25 15:21 ARM long branch stubs: pic take 2 Christophe LYON 2009-02-25 17:33 ` Richard Earnshaw @ 2009-02-26 19:01 ` Paul Brook 2009-02-27 16:42 ` Christophe LYON 1 sibling, 1 reply; 14+ messages in thread From: Paul Brook @ 2009-02-26 19:01 UTC (permalink / raw) To: binutils; +Cc: Christophe LYON On Wednesday 25 February 2009, Christophe LYON wrote: > +/* 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. */ > +static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = > + { > + THUMB16_INSN(0xb401), /* push {r0} */ The EABI specifies that veneers may only use the stack on M profile devices (i.e. when ARM mode is not available). Paul ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-26 19:01 ` Paul Brook @ 2009-02-27 16:42 ` Christophe LYON 2009-03-12 14:28 ` Christophe LYON 0 siblings, 1 reply; 14+ messages in thread From: Christophe LYON @ 2009-02-27 16:42 UTC (permalink / raw) To: Paul Brook; +Cc: binutils On 26.02.2009 20:01, Paul Brook wrote: > On Wednesday 25 February 2009, Christophe LYON wrote: >> +/* 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. */ >> +static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = >> + { >> + THUMB16_INSN(0xb401), /* push {r0} */ > > The EABI specifies that veneers may only use the stack on M profile devices > (i.e. when ARM mode is not available). > I have just updated my copy of EABI, and saw the sentence you are referring to. So this means that the sample code you provided in http://sourceware.org/ml/binutils/2009-02/msg00224.html should also have a variant for Thumb -> Thumb stub (pic and non-pic) on V4T. I'll give a look at that. Thanks Christophe. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-02-27 16:42 ` Christophe LYON @ 2009-03-12 14:28 ` Christophe LYON 2009-04-01 15:51 ` Nick Clifton 0 siblings, 1 reply; 14+ messages in thread From: Christophe LYON @ 2009-03-12 14:28 UTC (permalink / raw) To: binutils [-- Attachment #1: Type: text/plain, Size: 589 bytes --] Hello, >> The EABI specifies that veneers may only use the stack on M profile >> devices (i.e. when ARM mode is not available). >> > > I have just updated my copy of EABI, and saw the sentence you are > referring to. > > So this means that the sample code you provided in > http://sourceware.org/ml/binutils/2009-02/msg00224.html should also have > a variant for Thumb -> Thumb stub (pic and non-pic) on V4T. > > I'll give a look at that. > I propose a new patch that takes care of this issue. I think the M-profile stubs could be improved; maybe for another patch? Christophe. [-- Attachment #2: thumb-nostack.changelog --] [-- Type: text/plain, Size: 488 bytes --] 2009-03-12 Christophe Lyon <christophe.lyon@st.com> 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. [-- Attachment #3: thumb-nostack.patch --] [-- Type: text/plain, Size: 7087 bytes --] Index: bfd/elf32-arm.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-arm.c,v retrieving revision 1.180 diff -u -p -r1.180 elf32-arm.c --- bfd/elf32-arm.c 6 Mar 2009 08:57:57 -0000 1.180 +++ bfd/elf32-arm.c 12 Mar 2009 14:13:08 -0000 @@ -2049,9 +2049,7 @@ static const insn_sequence elf32_arm_stu 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_stu 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_stu 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_stu 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 * /* 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 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 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; Index: ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d,v retrieving revision 1.3 diff -u -p -r1.3 farcall-thumb-thumb-pic-veneer.d --- ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 26 Feb 2009 15:37:53 -0000 1.3 +++ ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d 12 Mar 2009 14:13:22 -0000 @@ -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: Index: ld/testsuite/ld-arm/farcall-thumb-thumb.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-thumb-thumb.d,v retrieving revision 1.3 diff -u -p -r1.3 farcall-thumb-thumb.d --- ld/testsuite/ld-arm/farcall-thumb-thumb.d 24 Feb 2009 22:43:10 -0000 1.3 +++ ld/testsuite/ld-arm/farcall-thumb-thumb.d 12 Mar 2009 14:13:22 -0000 @@ -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: ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-03-12 14:28 ` Christophe LYON @ 2009-04-01 15:51 ` Nick Clifton 2009-04-02 14:13 ` Christophe LYON 0 siblings, 1 reply; 14+ messages in thread From: Nick Clifton @ 2009-04-01 15:51 UTC (permalink / raw) To: Christophe LYON; +Cc: binutils Hi Christophe, > I propose a new patch that takes care of this issue. Approved - please apply. Cheers Nick ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ARM long branch stubs: pic take 2 2009-04-01 15:51 ` Nick Clifton @ 2009-04-02 14:13 ` Christophe LYON 0 siblings, 0 replies; 14+ messages in thread From: Christophe LYON @ 2009-04-02 14:13 UTC (permalink / raw) To: Nick Clifton; +Cc: binutils On 01.04.2009 17:51, Nick Clifton wrote: > Hi Christophe, > >> I propose a new patch that takes care of this issue. > > Approved - please apply. > Thanks, committed. Christophe. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2009-04-02 14:13 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-02-25 15:21 ARM long branch stubs: pic take 2 Christophe LYON 2009-02-25 17:33 ` Richard Earnshaw 2009-02-25 17:51 ` Christophe LYON 2009-02-26 10:31 ` Richard Earnshaw 2009-02-26 11:55 ` Christophe LYON 2009-02-26 14:59 ` Richard Earnshaw 2009-02-26 15:06 ` Daniel Jacobowitz 2009-02-26 15:34 ` Christophe LYON 2009-02-26 15:41 ` Daniel Jacobowitz 2009-02-26 19:01 ` Paul Brook 2009-02-27 16:42 ` Christophe LYON 2009-03-12 14:28 ` Christophe LYON 2009-04-01 15:51 ` Nick Clifton 2009-04-02 14:13 ` Christophe LYON
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).