This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[committed] Ignore global linkage symbols when statically linking against AIX shared objects
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Tue, 02 Jun 2009 19:50:25 +0100
- Subject: [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"