This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: ARM long branch stubs: shared libs
- From: Christophe LYON <christophe dot lyon at st dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Thu, 12 Mar 2009 15:48:13 +0100
- Subject: Re: ARM long branch stubs: shared libs
- References: <49B69FF6.4050903@st.com>
On 10.03.2009 18:14, Christophe LYON wrote:
Hi all,
I have found an issue in the long branch stubs insertion, in the case
where we are generating a large shared library which references an
undefined external symbol.
I have updated ld-arm/farcall-mixed-lib.d which was unused so far (it
was part of one of my previous patches by mistake).
Christophe.
Here is a slightly updated patch, which preserves the original behavior
with undefined symbols when not generating a shared lib.
Christophe.
2009-03-10 Christophe Lyon <christophe.lyon@st.com>
bfd/
* elf32-arm.c (elf32_arm_size_stubs): Handle long branches through
PLT entries to an undefined symbol when generating a shared
library.
testsuite/
* ld-arm/arm-elf.exp: Add new test farcall-mixed-lib.
* ld-arm/farcall-mixed-lib.d: Update expected output.
* ld-arm/farcall-mixed-lib1.s: New file.
* ld-arm/farcall-mixed-lib2.s: New file.
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:44:04 -0000
@@ -3809,12 +3809,32 @@ elf32_arm_size_stubs (bfd *output_bfd,
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
}
- else if (hash->root.root.type == bfd_link_hash_undefweak
- || hash->root.root.type == bfd_link_hash_undefined)
+ else if (hash->root.root.type == bfd_link_hash_undefweak)
/* For a shared library, these will need a PLT stub,
which is treated separately.
For absolute code, they cannot be handled. */
continue;
+ else if (hash->root.root.type == bfd_link_hash_undefined)
+ {
+ /* For a shared library, use the PLT stub as
+ target address to decide whether a long
+ branch stub is needed. */
+ struct elf32_arm_link_hash_table *globals =
+ elf32_arm_hash_table (info);
+
+ if (globals->splt != NULL && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) -1)
+ {
+ sym_sec = globals->splt;
+ sym_value = hash->root.plt.offset;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else
+ continue;
+ }
else
{
bfd_set_error (bfd_error_bad_value);
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.51
diff -u -p -r1.51 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp 6 Mar 2009 08:57:58 -0000 1.51
+++ ld/testsuite/ld-arm/arm-elf.exp 12 Mar 2009 14:44:10 -0000
@@ -352,6 +352,12 @@ set armeabitests {
{{objdump -fdw farcall-mixed-app-v5.d} {objdump -Rw farcall-mixed-app.r}
{readelf -Ds farcall-mixed-app.sym}}
"farcall-mixed-app-v5"}
+
+ {"Mixed ARM/Thumb shared library with long branches" "-shared -T arm-lib.ld" ""
+ {farcall-mixed-lib1.s farcall-mixed-lib2.s}
+ {{objdump -fdw farcall-mixed-lib.d}}
+ "farcall-mixed-lib.so"}
+
}
run_ld_link_tests $armeabitests
Index: ld/testsuite/ld-arm/farcall-mixed-lib.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/farcall-mixed-lib.d,v
retrieving revision 1.1
diff -u -p -r1.1 farcall-mixed-lib.d
--- ld/testsuite/ld-arm/farcall-mixed-lib.d 5 Mar 2009 17:28:21 -0000 1.1
+++ ld/testsuite/ld-arm/farcall-mixed-lib.d 12 Mar 2009 14:44:10 -0000
@@ -22,16 +22,36 @@ Disassembly of section .text:
.*: ebfffff. bl .* <lib_func1-0x..?>
.*: e89d6800 ldm sp, {fp, sp, lr}
.*: e12fff1e bx lr
- .*: e1a00000 nop \(mov r0,r0\)
- .*: e1a00000 nop \(mov r0,r0\)
- .*: e1a00000 nop \(mov r0,r0\)
-
+ ...
+ .*: e1a00000 .word 0xe1a00000
+ .*: e1a00000 .word 0xe1a00000
+ .*: e1a00000 .word 0xe1a00000
.* <lib_func2>:
+ .*: f000 e806 blx 10002d0 <__app_func2_from_thumb>
.*: 4770 bx lr
.*: 46c0 nop \(mov r8, r8\)
.*: 46c0 nop \(mov r8, r8\)
.*: 46c0 nop \(mov r8, r8\)
.*: 46c0 nop \(mov r8, r8\)
.*: 46c0 nop \(mov r8, r8\)
+
+.* <__app_func2_from_thumb>:
+ .*: e59fc000 ldr ip, \[pc, #0\] ; 10002d8 <__app_func2_from_thumb\+0x8>
+ .*: e08ff00c add pc, pc, ip
+ .*: feffffb0 .word 0xfeffffb0
+ ...
+
+.* <lib_func3>:
+ .*: f000 e806 blx 20002f0 <__app_func2_from_thumb>
+ .*: 4770 bx lr
+ .*: 46c0 nop \(mov r8, r8\)
+ .*: 46c0 nop \(mov r8, r8\)
+ .*: 46c0 nop \(mov r8, r8\)
.*: 46c0 nop \(mov r8, r8\)
.*: 46c0 nop \(mov r8, r8\)
+
+.* <__app_func2_from_thumb>:
+ .*: e59fc000 ldr ip, \[pc, #0\] ; 20002f8 <__app_func2_from_thumb\+0x8>
+ .*: e08ff00c add pc, pc, ip
+ .*: fdffff90 .word 0xfdffff90
+ .*: 00000000 .word 0x00000000
Index: ld/testsuite/ld-arm/farcall-mixed-lib1.s
===================================================================
RCS file: ld/testsuite/ld-arm/farcall-mixed-lib1.s
diff -N ld/testsuite/ld-arm/farcall-mixed-lib1.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/farcall-mixed-lib1.s 12 Mar 2009 14:44:10 -0000
@@ -0,0 +1,27 @@
+@ Create a large shared library so that calls through PLT to an undef
+@ symbol require insertion of a long branch stub.
+
+ .text
+ .arch armv5t
+
+ .p2align 4
+ .globl lib_func1
+ .type lib_func1, %function
+lib_func1:
+ mov ip, sp
+ stmdb sp!, {r11, ip, lr, pc}
+ bl app_func2
+ ldmia sp, {r11, sp, lr}
+ bx lr
+ .size lib_func1, . - lib_func1
+
+ .space 0x1000000
+ .p2align 4
+ .globl lib_func2
+ .type lib_func2, %function
+ .thumb_func
+ .code 16
+lib_func2:
+ bl app_func2
+ bx lr
+ .size lib_func2, . - lib_func2
Index: ld/testsuite/ld-arm/farcall-mixed-lib2.s
===================================================================
RCS file: ld/testsuite/ld-arm/farcall-mixed-lib2.s
diff -N ld/testsuite/ld-arm/farcall-mixed-lib2.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/farcall-mixed-lib2.s 12 Mar 2009 14:44:10 -0000
@@ -0,0 +1,16 @@
+@ Create a large shared library so that calls through PLT to an undef
+@ symbol require insertion of a long branch stub.
+
+ .text
+ .arch armv5t
+
+ .space 0x1000000
+ .p2align 4
+ .globl lib_func3
+ .type lib_func3, %function
+ .thumb_func
+ .code 16
+lib_func3:
+ bl app_func2
+ bx lr
+ .size lib_func3, . - lib_func3