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]

Fix R_ARM_THM_CALL relocations against undefined weak symbols in shared libraries


This patch fixes a problem with the handling of R_ARM_THM_CALL
relocations against undefined weak symbols when linking a shared
library.  The ARM linker was turning these calls into branches to the
next instruction - but the call needs to be preserved (the symbol
handled as a dynamic symbol) in case it is defined in one of the
libraries linked into the final program being linked with the shared
library.  This patch stops the conversion happening if a PLT entry is
going to be created for the symbol - in that case, a branch to the PLT
entry can safely and appropriately be generated (and the condition
used in the code is the same as it uses further down to determine
whether to use a branch to a PLT entry).

In particular, GCC's gthread interface (as used by thread support in
libstdc++) calls a weak reference to pthread_once only if
pthread_cancel != 0, to avoid threading overhead in programs not
linked with libpthread while allowing a single libstdc++ binary to
work with both threaded and nonthreaded binaries.  So if the shared
libstdc++ was built as Thumb-2 then it would contain not the desired
call to pthread_once (which would only be executed at runtime if
thread support was linked in) but a branch to the next instruction (so
the call would never be executed), and threaded C++ programs would
break.

Tested with no regressions with cross to arm-none-linux-gnueabi.  OK
to commit?

bfd:
2008-11-24  Joseph Myers  <joseph@codesourcery.com>

	* elf32-arm.c (elf32_arm_final_link_relocate): Do not turn
	branches to undefine weak symbols into branches to the next
	instruction if creating PLT entries for those symbols.

ld/testsuite:
2008-11-24  Joseph Myers  <joseph@codesourcery.com>

	* ld-arm/thumb2-bl-undefweak.d, ld-arm/thumb2-bl-undefweak.s: New.
	* ld-arm/arm-elf.exp: Run thumb2-bl-undefweak test.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.158
diff -u -r1.158 elf32-arm.c
--- bfd/elf32-arm.c	18 Nov 2008 15:45:02 -0000	1.158
+++ bfd/elf32-arm.c	25 Nov 2008 01:14:39 -0000
@@ -6381,8 +6381,9 @@
 	int thumb2 = using_thumb2 (globals);
 
 	/* A branch to an undefined weak symbol is turned into a jump to
-	   the next instruction.  */
-	if (h && h->root.type == bfd_link_hash_undefweak)
+	   the next instruction unless a PLT entry will be created.  */
+	if (h && h->root.type == bfd_link_hash_undefweak
+	    && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
 	  {
 	    bfd_put_16 (input_bfd, 0xe000, hit_data);
 	    bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.41
diff -u -r1.41 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	26 Aug 2008 11:46:41 -0000	1.41
+++ ld/testsuite/ld-arm/arm-elf.exp	25 Nov 2008 01:14:40 -0000
@@ -184,6 +184,7 @@
 run_dump_test "group-relocs-ldr-bad"
 run_dump_test "group-relocs-ldrs-bad"
 run_dump_test "group-relocs-ldc-bad"
+run_dump_test "thumb2-bl-undefweak"
 run_dump_test "emit-relocs1"
 
 # Exclude non-ARM-EABI targets.
Index: ld/testsuite/ld-arm/thumb2-bl-undefweak.d
===================================================================
RCS file: ld/testsuite/ld-arm/thumb2-bl-undefweak.d
diff -N ld/testsuite/ld-arm/thumb2-bl-undefweak.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/thumb2-bl-undefweak.d	25 Nov 2008 01:14:40 -0000
@@ -0,0 +1,9 @@
+#source: thumb2-bl-undefweak.s
+#as:
+#ld: -shared
+#objdump: -dr
+#...
+Disassembly of section .text:
+
+.* <foo>:
+ .*:	.... .... 	blx	... <foo-0x.*>
Index: ld/testsuite/ld-arm/thumb2-bl-undefweak.s
===================================================================
RCS file: ld/testsuite/ld-arm/thumb2-bl-undefweak.s
diff -N ld/testsuite/ld-arm/thumb2-bl-undefweak.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/thumb2-bl-undefweak.s	25 Nov 2008 01:14:40 -0000
@@ -0,0 +1,10 @@
+@ Test that calls to undefined weak functions resolve to call through
+@ the PLT in shared libraries.
+
+	.arch armv7
+	.syntax unified
+	.text
+	.thumb_func
+foo:
+	bl bar
+	.weak bar

-- 
Joseph S. Myers
joseph@codesourcery.com


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