This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ARM long branch stubs: shared libs


Hi all,

Here is an updated version of the patch, which now takes care of undef weak references too.

Christophe.
2009-04-15  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.186
diff -u -p -r1.186 elf32-arm.c
--- bfd/elf32-arm.c	15 Apr 2009 13:49:54 -0000	1.186
+++ bfd/elf32-arm.c	15 Apr 2009 15:40:49 -0000
@@ -3832,12 +3832,29 @@ 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)
-			/* 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)
+			       || (hash->root.root.type == bfd_link_hash_undefweak))
+			{
+			  /* For a shared library, use the PLT stub as
+			     target address to decide whether a long
+			     branch stub is needed.
+			     For absolute code, they cannot be handled.  */
+			  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.53
diff -u -p -r1.53 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	15 Apr 2009 13:49:54 -0000	1.53
+++ ld/testsuite/ld-arm/arm-elf.exp	15 Apr 2009 15:40:54 -0000
@@ -353,6 +353,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	15 Apr 2009 15:40:54 -0000
@@ -14,24 +14,56 @@ Disassembly of section .plt:
  .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
  .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
  .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
 Disassembly of section .text:
 
 .* <lib_func1>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	push	{fp, ip, lr, pc}
  .*:	ebfffff. 	bl	.* <lib_func1-0x..?>
+ .*:	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
 
 .* <lib_func2>:
+ .*:	f000 e80c 	blx	100030c <__app_func_from_thumb>
+ .*:	f000 e804 	blx	1000300 <__app_func_weak_from_thumb>
  .*:	4770      	bx	lr
  .*:	46c0      	nop			\(mov r8, r8\)
  .*:	46c0      	nop			\(mov r8, r8\)
  .*:	46c0      	nop			\(mov r8, r8\)
+
+.* <__app_func_weak_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000308 <__app_func_weak_from_thumb\+0x8>
+ .*:	e08ff00c 	add	pc, pc, ip
+ .*:	feffffb4 	.word	0xfeffffb4
+
+.* <__app_func_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 1000314 <__app_func_from_thumb\+0x8>
+ .*:	e08ff00c 	add	pc, pc, ip
+ .*:	feffff9c 	.word	0xfeffff9c
+	...
+
+.* <lib_func3>:
+ .*:	f000 e80c 	blx	200033c <__app_func_from_thumb>
+ .*:	f000 e804 	blx	2000330 <__app_func_weak_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\)
+
+.* <__app_func_weak_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 2000338 <__app_func_weak_from_thumb\+0x8>
+ .*:	e08ff00c 	add	pc, pc, ip
+ .*:	fdffff84 	.word	0xfdffff84
+
+.* <__app_func_from_thumb>:
+ .*:	e59fc000 	ldr	ip, \[pc, #0\]	; 2000344 <__app_func_from_thumb\+0x8>
+ .*:	e08ff00c 	add	pc, pc, ip
+ .*:	fdffff6c 	.word	0xfdffff6c
+	...
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	15 Apr 2009 15:40:54 -0000
@@ -0,0 +1,31 @@
+@ Create a large shared library so that calls through PLT to an undef
+@ symbol require insertion of a long branch stub.
+@ Check also calls to an undef weak symbol.
+
+	.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_func
+	.weak	app_func_weak
+	bl	app_func_weak
+	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_func
+	bl	app_func_weak
+	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	15 Apr 2009 15:40:54 -0000
@@ -0,0 +1,19 @@
+@ Create a large shared library so that calls through PLT to an undef
+@ symbol require insertion of a long branch stub.
+@ Check also calls to an undef weak symbol.
+
+	.text
+	.arch armv5t
+
+	.space 0x1000000
+	.p2align 4
+	.globl lib_func3
+	.type lib_func3, %function
+	.thumb_func
+	.code 16
+lib_func3:
+	bl	app_func
+	.weak	app_func_weak
+	bl	app_func_weak
+	bx lr
+	.size lib_func3, . - lib_func3

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]