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]

[committed] Ignore global linkage symbols when statically linking against AIX shared objects


AIX bootstraps with binutils currently hang during the configuration
of a target library (libgomp, I think).  The test tries a simple,
statically-linked pthreads test:

    gcc ... -static -pthread

which on AIX involves linking statically against the shared shr.o object
in libc.a.

Some parts of libc.a rely on libcrypt.a, and use global linkage code to
resolve the symbol references.  This global linkage code can't possibly
work in a static link, so the native tools rightly ignore it.  The link
line above therefore fails with native tools; you need to add -lcrypt
for the link to succeed.

This patch makes GNU ld follow the native linker.  It ignores global
linkage code when linking statically.

Tested on powerpc-ibm-aix6.1, in combination with the gcc patches
I posted today.  Applied.

Richard


bfd/
	* coff-rs6000.c (xcoff_ppc_relocate_section): Allow undefined
	symbols to be left unimported when linking statically.
	* xcofflink.c (xcoff_link_add_symbols): Ignore global linkage
	code when linking statically.

ld/testsuite/
	* ld-powerpc/aix-glink-3.s, ld-powerpc/aix-glink-3a.s,
	ld-powerpc/aix-glink-3b.s, ld-powerpc/aix-glink-3.dd,
	ld-powerpc/aix-glink-3-32.d, ld-powerpc/aix-glink-3-64.d: New tests.
	* ld-powerpc/aix52.exp: Run them.  Move the lineno tests to maintain
	alphabetical order.

Index: bfd/coff-rs6000.c
===================================================================
--- bfd/coff-rs6000.c	2009-05-20 20:04:35.000000000 +0100
+++ bfd/coff-rs6000.c	2009-06-02 19:33:25.000000000 +0100
@@ -3460,6 +3460,8 @@ xcoff_ppc_relocate_section (output_bfd, 
 	      else
 		{
 		  BFD_ASSERT (info->relocatable
+			      || (info->static_link
+				  && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
 			      || (h->flags & XCOFF_DEF_DYNAMIC) != 0
 			      || (h->flags & XCOFF_IMPORT) != 0);
 		}
Index: bfd/xcofflink.c
===================================================================
--- bfd/xcofflink.c	2009-05-20 20:04:38.000000000 +0100
+++ bfd/xcofflink.c	2009-06-02 19:46:38.000000000 +0100
@@ -1889,6 +1889,15 @@ #define N_BTSHFT n_btshft
 	      || sym._n._n_n._n_offset == 0)
 	    copy = TRUE;
 
+	  /* Ignore global linkage code when linking statically.  */
+	  if (info->static_link
+	      && (smtyp == XTY_SD || smtyp == XTY_LD)
+	      && aux.x_csect.x_smclas == XMC_GL)
+	    {
+	      section = bfd_und_section_ptr;
+	      value = 0;
+	    }
+
 	  /* The AIX linker appears to only detect multiple symbol
 	     definitions when there is a reference to the symbol.  If
 	     a symbol is defined multiple times, and the only
@@ -1913,8 +1922,7 @@ #define N_BTSHFT n_btshft
 	     We also have to handle the case of statically linking a
 	     shared object, which will cause symbol redefinitions,
 	     although this is an easier case to detect.  */
-
- 	  if (info->output_bfd->xvec == abfd->xvec)
+ 	  else if (info->output_bfd->xvec == abfd->xvec)
 	    {
 	      if (! bfd_is_und_section (section))
 		*sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info),
@@ -1934,23 +1942,8 @@ #define N_BTSHFT n_btshft
 		  && ! bfd_is_com_section (section))
 		{
 		  /* This is a second definition of a defined symbol.  */
-		  if ((abfd->flags & DYNAMIC) != 0
-		      && ((*sym_hash)->smclas != XMC_GL
-			  || aux.x_csect.x_smclas == XMC_GL
-			  || ((*sym_hash)->root.u.def.section->owner->flags
-			      & DYNAMIC) == 0))
-		    {
-		      /* The new symbol is from a shared library, and
-			 either the existing symbol is not global
-			 linkage code or this symbol is global linkage
-			 code.  If the existing symbol is global
-			 linkage code and the new symbol is not, then
-			 we want to use the new symbol.  */
-		      section = bfd_und_section_ptr;
-		      value = 0;
-		    }
-		  else if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0
-			   && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0)
+		  if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0
+		      && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0)
 		    {
 		      /* The existing symbol is from a shared library.
 			 Replace it.  */
@@ -2049,7 +2042,9 @@ #define N_BTSHFT n_btshft
 	    {
 	      int flag;
 
-	      if (smtyp == XTY_ER || smtyp == XTY_CM)
+	      if (smtyp == XTY_ER
+		  || smtyp == XTY_CM
+		  || section == bfd_und_section_ptr)
 		flag = XCOFF_REF_REGULAR;
 	      else
 		flag = XCOFF_DEF_REGULAR;
@@ -2741,6 +2736,10 @@ xcoff_mark_symbol (struct bfd_link_info 
 	  /* We handle writing out the contents of the descriptor in
 	     xcoff_write_global_symbol.  */
 	}
+      else if (info->static_link)
+	/* We can't get a symbol value dynamically, so just assume
+	   that it's undefined.  */
+	h->flags |= XCOFF_WAS_UNDEFINED;
       else if ((h->flags & XCOFF_CALLED) != 0)
 	{
 	  /* This is a function symbol for which we need to create
Index: ld/testsuite/ld-powerpc/aix-glink-3.s
===================================================================
--- /dev/null	2009-06-02 19:24:49.510184787 +0100
+++ ld/testsuite/ld-powerpc/aix-glink-3.s	2009-06-02 19:33:25.000000000 +0100
@@ -0,0 +1,5 @@
+	.extern	.f
+	.globl	__start
+	.csect	__start[PR]
+__start:
+	bl	.f
Index: ld/testsuite/ld-powerpc/aix-glink-3a.s
===================================================================
--- /dev/null	2009-06-02 19:24:49.510184787 +0100
+++ ld/testsuite/ld-powerpc/aix-glink-3a.s	2009-06-02 19:33:25.000000000 +0100
@@ -0,0 +1,10 @@
+	.toc
+
+	.globl	.g
+	.csect	.g[PR]
+.g:
+	blr
+
+	.globl	g
+	.csect	g[DS]
+g:	.long	.g,TOC[tc0],0
Index: ld/testsuite/ld-powerpc/aix-glink-3b.s
===================================================================
--- /dev/null	2009-06-02 19:24:49.510184787 +0100
+++ ld/testsuite/ld-powerpc/aix-glink-3b.s	2009-06-02 19:33:25.000000000 +0100
@@ -0,0 +1,11 @@
+	.toc
+
+	.extern	.g
+	.globl	.f
+	.csect	.f[PR]
+.f:
+	bl	.g
+
+	.globl	f
+	.csect	f[DS]
+f:	.long	.f,TOC[tc0],0
Index: ld/testsuite/ld-powerpc/aix-glink-3.dd
===================================================================
--- /dev/null	2009-06-02 19:24:49.510184787 +0100
+++ ld/testsuite/ld-powerpc/aix-glink-3.dd	2009-06-02 19:33:25.000000000 +0100
@@ -0,0 +1,14 @@
+
+.*
+
+
+Disassembly of section \.text:
+
+0*10000000 <\.f>:
+ *10000000:	48 00 00 05 	bl      10000004 <\.g>
+
+0*10000004 <\.g>:
+ *10000004:	4e 80 00 20 	bl?r
+
+0*10000008 <__start>:
+ *10000008:	4b ff ff f9 	bl      10000000 <\.f>
Index: ld/testsuite/ld-powerpc/aix-glink-3-32.d
===================================================================
--- /dev/null	2009-06-02 19:24:49.510184787 +0100
+++ ld/testsuite/ld-powerpc/aix-glink-3-32.d	2009-06-02 19:33:25.000000000 +0100
@@ -0,0 +1,5 @@
+#name: Glink test 3 (error) (32-bit)
+#source: aix-glink-3.s
+#as: -a32
+#ld: -b32 -bnoautoimp tmpdir/aix-glink-3b.so
+#error: undefined reference to `\.g'
Index: ld/testsuite/ld-powerpc/aix-glink-3-64.d
===================================================================
--- /dev/null	2009-06-02 19:24:49.510184787 +0100
+++ ld/testsuite/ld-powerpc/aix-glink-3-64.d	2009-06-02 19:33:25.000000000 +0100
@@ -0,0 +1,5 @@
+#name: Glink test 3 (error) (64-bit)
+#source: aix-glink-3.s
+#as: -a64
+#ld: -b64 -bnoautoimp tmpdir/aix64-glink-3b.so
+#error: undefined reference to `\.g'
Index: ld/testsuite/ld-powerpc/aix52.exp
===================================================================
--- ld/testsuite/ld-powerpc/aix52.exp	2009-04-17 00:07:00.000000000 +0100
+++ ld/testsuite/ld-powerpc/aix52.exp	2009-06-02 19:33:25.000000000 +0100
@@ -145,16 +145,6 @@ set aix52tests {
      {{objdump {-D -j.text -j.data} aix-glink-1-SIZE.dd}}
      "aix-glink-1.so"}
 
-    {"Line number test 1 (no discards)" "-e.main"
-     "" {aix-lineno-1.s}
-     {{objdump -dS aix-lineno-1a.dd} {nm {} aix-lineno-1a.nd}}
-     "aix-lineno-1a.exe"}
-
-    {"Line number test 1 (discard locals)" "-e.main -x"
-     "" {aix-lineno-1.s}
-     {{objdump -dS aix-lineno-1b.dd} {nm {} aix-lineno-1b.nd}}
-     "aix-lineno-1b.exe"}
-
     {"Glink test 2 (part a)" "-shared -bE:aix-glink-2a.ex"
      "" {aix-glink-2a.s}
      {}
@@ -176,6 +166,32 @@ set aix52tests {
      {{objdump -d aix-glink-2-SIZE.dd}}
      "aix-glink-2"}
 
+    {"Glink test 3 (shared library a)"
+     "-shared -bexpall"
+     "" {aix-glink-3a.s}
+     {} "aix-glink-3a.so"}
+
+    {"Glink test 3 (shared library b)"
+     "-shared -bexpall"
+     "" {aix-glink-3b.s}
+     {} "aix-glink-3b.so"}
+
+    {"Glink test 3 (main test)"
+     "-bnoautoimp tmpdir/aix-glink-3b.so tmpdir/aix-glink-3a.so"
+     "" {aix-glink-3.s}
+     {{objdump -d aix-glink-3.dd}}
+     "aix-glink-3"}
+
+    {"Line number test 1 (no discards)" "-e.main"
+     "" {aix-lineno-1.s}
+     {{objdump -dS aix-lineno-1a.dd} {nm {} aix-lineno-1a.nd}}
+     "aix-lineno-1a.exe"}
+
+    {"Line number test 1 (discard locals)" "-e.main -x"
+     "" {aix-lineno-1.s}
+     {{objdump -dS aix-lineno-1b.dd} {nm {} aix-lineno-1b.nd}}
+     "aix-lineno-1b.exe"}
+
     {"Relocatable test 1" "-r"
      "" {aix-rel-1.s}
      {{objdump -hr aix-rel-1.od}} "aix-rel-1.ro"}
@@ -236,5 +252,9 @@ foreach test $aix52tests {
     }
 }
 
+run_dump_test "aix-glink-1-32"
+run_dump_test "aix-glink-1-64"
+run_dump_test "aix-glink-3-32"
+run_dump_test "aix-glink-3-64"
 run_dump_test "aix-weak-3-32"
 run_dump_test "aix-weak-3-64"


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