* 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).