From: Christophe LYON <christophe.lyon@st.com>
To: Binutils <binutils@sourceware.org>
Subject: ARM long branch stubs: pic take 2
Date: Wed, 25 Feb 2009 15:21:00 -0000 [thread overview]
Message-ID: <49A561EB.2070809@st.com> (raw)
[-- 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
next reply other threads:[~2009-02-25 15:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-25 15:21 Christophe LYON [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49A561EB.2070809@st.com \
--to=christophe.lyon@st.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).