This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: ARM long branch stubs: pic take 2
- From: Christophe LYON <christophe dot lyon at st dot com>
- To: binutils at sourceware dot org
- Date: Thu, 12 Mar 2009 15:28:17 +0100
- Subject: Re: ARM long branch stubs: pic take 2
- References: <49A561EB.2070809@st.com> <200902261901.24644.paul@codesourcery.com> <49A817E6.5030503@st.com>
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.
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.
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: