public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [0/8] AIX cross toolchains
@ 2009-06-02 12:03 Richard Sandiford
  2009-06-02 12:05 ` [1/8] Don't build newlib for AIX Richard Sandiford
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:03 UTC (permalink / raw)
  To: gcc-patches

This series of patches adds support for AIX-targetted cross toolchains.
As with other cross toolchains for "hosted" systems, the assumption is
that you have an AIX sysroot available and are using --with-sysroot to
point to it.  (This assumption also implicitly requires GNU ld, with its
support for --sysroot.)

Until recently, binutils could not build working AIX shared libraries,
so the patches only work with a CVS copy of binutils.  And because of
the binutils problems, current libtool doesn't let you try to use
binutils to build AIX shared libraries; it will always switch to
static libraries instead.  The following patches remove this
restriction:

    http://lists.gnu.org/archive/html/libtool-patches/2009-03/msg00007.html
    http://lists.gnu.org/archive/html/libtool-patches/2009-04/msg00013.html

The patches haven't been accepted, so you'll need to apply them locally
and then regenerate each configure script.

All patches were tested by:

  - A native bootstrap on powerpc-ibm-aix6.1 using binutils, with a hack
    to disable the stuff in config/mh-ppc-aix.  Test flags: {,-pthread}.
    (I couldn't test for -maix64 for reasons explained in patch 8.)

  - A native boostrap on x86_64-linux-gnu.  Test flags: {,-m32}.

  - A cross build and cross test from x86_64-linux-gnu to
    powerpc-ibm-aix6.1.  Test flags: {,-pthread}{,-maix64}.

The patches are covered by the IBM copyright assignment.

Richard

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [1/8] Don't build newlib for AIX
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
@ 2009-06-02 12:05 ` Richard Sandiford
  2009-06-02 12:58   ` Paolo Bonzini
  2009-06-02 12:10 ` [2/8] Handle sysroots on AIX (needs build-system maintainer) Richard Sandiford
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:05 UTC (permalink / raw)
  To: gcc-patches

This patch allows a combined src/gcc tree to build on AIX.  It simply adds
newlib to the list of unsupported directories.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


	* configure.ac (powerpc-*-aix*, rs6000-*-aix*): Add target-newlib
	to noconfdirs.
	* configure: Regenerate.

Index: configure.ac
===================================================================
--- configure.ac	2009-02-25 10:55:35.000000000 +0000
+++ configure.ac	2009-02-25 11:08:15.000000000 +0000
@@ -797,7 +797,7 @@ case "${target}" in
     ;;
   powerpc-*-aix*)
     # copied from rs6000-*-* entry
-    noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp ${libgcj}"
+    noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}"
     ;;
   powerpc*-*-winnt* | powerpc*-*-pe* | ppc*-*-pe)
     target_configdirs="$target_configdirs target-winsup"
@@ -824,7 +824,7 @@ case "${target}" in
     noconfigdirs="$noconfigdirs target-newlib gprof ${libgcj}"
     ;;
   rs6000-*-aix*)
-    noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp ${libgcj}"
+    noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}"
     ;;
   rs6000-*-*)
     noconfigdirs="$noconfigdirs gprof ${libgcj}"

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [2/8] Handle sysroots on AIX (needs build-system maintainer)
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
  2009-06-02 12:05 ` [1/8] Don't build newlib for AIX Richard Sandiford
@ 2009-06-02 12:10 ` Richard Sandiford
  2009-06-02 12:58   ` Paolo Bonzini
  2009-06-02 12:11 ` [3/8] Fix premature post-increment in collect2.c Richard Sandiford
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:10 UTC (permalink / raw)
  To: gcc-patches

[Build or global write maintainer needed for point (2) below.]

This patch adds --sysroot support to the AIX configurations.  There are
three changes:

  (1) Add %R to absolute spec filenames (pretty trivial).

  (2) Make TARGET_SYSTEM_ROOT available to the libgcc makefiles
      (needed by (3)).

  (3) Add $(TARGET_SYSTEM_ROOT) to absolute filenames in the t-aix*
      libgcc fragments.

We used to assume that the syscall lists aren't available for cross builds:

    #ifndef CROSS_DIRECTORY_STRUCTURE
    #define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
    #else
    #define LINK_LIBG_SPEC ""
    #endif

But you can't really build anything useful without access to the core
libraries and syscall lists, so I think we should just drop this
behaviour and require --sysroot instead.  I've therefore used the
!CROSS_DIRECTORY_STRUCTURE for cross builds too and applied (1) to it.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


gcc/
	* Makefile.in (libgcc.mvars): Add TARGET_SYSTEM_ROOT.
	* config/rs6000/aix.h (LINK_SYSCALLS_SPEC): Add %R to the
	!CROSS_DIRECTORY_STRUCTURE alternative and use it for
	CROSS_DIRECTORY_STRUCTURE too.
	(LINK_LIBG_SPEC): Likewise.
	(LIB_SPEC): Add %R to sysroot paths.
	* config/rs6000/aix43.h (CPP_SPEC): Add %R to sysroot paths.
	(CPLUSPLUS_CPP_SPEC, LIB_SPEC): Likewise.
	* config/rs6000/aix51.h: As for aix43.h.
	* config/rs6000/aix52.h: Likewise.
	* config/rs6000/aix53.h: Likewise.
	* config/rs6000/aix61.h: Likewise.
	* config/rs6000/t-aix52 (SHLIB_LINK): Add $(TARGET_SYSTEM_ROOT)
	to the beginning of sysroot paths.

Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	2009-06-02 13:05:47.000000000 +0100
+++ gcc/Makefile.in	2009-06-02 13:06:03.000000000 +0100
@@ -1753,6 +1753,7 @@ libgcc.mvars: config.status Makefile $(L
 	echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars
 	echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars
 	echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars
+	echo TARGET_SYSTEM_ROOT = '$(TARGET_SYSTEM_ROOT)' >> tmp-libgcc.mvars
 
 	mv tmp-libgcc.mvars libgcc.mvars
 
Index: gcc/config/rs6000/aix.h
===================================================================
--- gcc/config/rs6000/aix.h	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/aix.h	2009-06-02 13:06:03.000000000 +0100
@@ -120,18 +120,10 @@ #define ASM_DEFAULT_SPEC ""
 /* #define ASM_SPEC "-u %(asm_cpu)" */
 
 /* Default location of syscalls.exp under AIX */
-#ifndef CROSS_DIRECTORY_STRUCTURE
-#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
-#else
-#define LINK_SYSCALLS_SPEC ""
-#endif
+#define LINK_SYSCALLS_SPEC "-bI:%R/lib/syscalls.exp"
 
 /* Default location of libg.exp under AIX */
-#ifndef CROSS_DIRECTORY_STRUCTURE
-#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
-#else
-#define LINK_LIBG_SPEC ""
-#endif
+#define LINK_LIBG_SPEC "-bexport:%R/usr/lib/libg.exp"
 
 /* Define the options for the binder: Start text at 512, align all segments
    to 512 bytes, and warn if there is text relocation.
@@ -152,8 +144,8 @@ #define LINK_SPEC "-T512 -H512 %{!r:-bte
 %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
 
 /* Profiled library versions are used by linking with special directories.  */
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+%{p:-L%R/lib/profiled -L%R/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
 
 /* Static linking with shared libstdc++ requires libsupc++ as well.  */
 #define LIBSTDCXX_STATIC "-lstdc++ -lsupc++"
Index: gcc/config/rs6000/aix43.h
===================================================================
--- gcc/config/rs6000/aix43.h	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/aix43.h	2009-06-02 13:06:03.000000000 +0100
@@ -104,7 +104,7 @@ #define TARGET_OS_CPP_BUILTINS()     \
 #define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
    %{ansi: -D_ANSI_C_SOURCE}\
    %{maix64: -D__64BIT__}\
-   %{mpe: -I/usr/lpp/ppe.poe/include}\
+   %{mpe: -I%R/usr/lpp/ppe.poe/include}\
    %{pthread: -D_THREAD_SAFE}"
 
 /* The GNU C++ standard library requires that these macros be 
@@ -113,7 +113,7 @@ #define CPP_SPEC "%{posix: -D_POSIX_SOUR
 #define CPLUSPLUS_CPP_SPEC			\
   "-D_ALL_SOURCE				\
    %{maix64: -D__64BIT__}			\
-   %{mpe: -I/usr/lpp/ppe.poe/include}		\
+   %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
    %{pthread: -D_THREAD_SAFE}"
 
 #undef TARGET_DEFAULT
@@ -141,11 +141,11 @@ #define TARGET_ALTIVEC_ABI 0
 #define	MULTILIB_DEFAULTS { "mcpu=common" }
 
 #undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+   %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
    %{!maix64:%{!shared:%{g*:-lg}}}\
-   %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
-   %{pthread:-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a}\
+   %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+   %{pthread:-L%R/usr/lib/threads -lpthreads -lc_r %R/usr/lib/libc.a}\
    %{!pthread:-lc}"
 
 #undef LINK_SPEC
Index: gcc/config/rs6000/aix51.h
===================================================================
--- gcc/config/rs6000/aix51.h	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/aix51.h	2009-06-02 13:06:03.000000000 +0100
@@ -101,7 +101,7 @@ #define TARGET_OS_CPP_BUILTINS()     \
 #define CPP_SPEC "%{posix: -D_POSIX_SOURCE}	\
   %{ansi: -D_ANSI_C_SOURCE}			\
   %{maix64: -D__64BIT__}			\
-  %{mpe: -I/usr/lpp/ppe.poe/include}		\
+  %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
   %{pthread: -D_THREAD_SAFE}"
 
 /* The GNU C++ standard library requires that these macros be 
@@ -110,7 +110,7 @@ #define CPP_SPEC "%{posix: -D_POSIX_SOUR
 #define CPLUSPLUS_CPP_SPEC			\
   "-D_ALL_SOURCE				\
    %{maix64: -D__64BIT__}			\
-   %{mpe: -I/usr/lpp/ppe.poe/include}		\
+   %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
    %{pthread: -D_THREAD_SAFE}"
 
 #undef TARGET_DEFAULT
@@ -138,10 +138,10 @@ #define TARGET_ALTIVEC_ABI 0
 #define	MULTILIB_DEFAULTS { "mcpu=common" }
 
 #undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+   %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
    %{!maix64:%{!shared:%{g*:-lg}}}\
-   %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+   %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
    %{pthread:-lpthreads} -lc"
 
 #undef LINK_SPEC
Index: gcc/config/rs6000/aix52.h
===================================================================
--- gcc/config/rs6000/aix52.h	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/aix52.h	2009-06-02 13:06:03.000000000 +0100
@@ -99,7 +99,7 @@ #define TARGET_OS_CPP_BUILTINS()     \
 #define CPP_SPEC "%{posix: -D_POSIX_SOURCE}	\
   %{ansi: -D_ANSI_C_SOURCE}			\
   %{maix64: -D__64BIT__}			\
-  %{mpe: -I/usr/lpp/ppe.poe/include}		\
+  %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
   %{pthread: -D_THREAD_SAFE}"
 
 /* The GNU C++ standard library requires that these macros be 
@@ -108,7 +108,7 @@ #define CPP_SPEC "%{posix: -D_POSIX_SOUR
 #define CPLUSPLUS_CPP_SPEC			\
   "-D_ALL_SOURCE				\
    %{maix64: -D__64BIT__}			\
-   %{mpe: -I/usr/lpp/ppe.poe/include}		\
+   %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
    %{pthread: -D_THREAD_SAFE}"
 
 #undef  TARGET_DEFAULT
@@ -140,10 +140,10 @@ #define TARGET_ALTIVEC_ABI 0
 #undef	MULTILIB_DEFAULTS
 
 #undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+   %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
    %{!maix64:%{!shared:%{g*:-lg}}}\
-   %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+   %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
    %{pthread:-lpthreads} -lc"
 
 #undef LINK_SPEC
Index: gcc/config/rs6000/aix53.h
===================================================================
--- gcc/config/rs6000/aix53.h	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/aix53.h	2009-06-02 13:06:03.000000000 +0100
@@ -101,7 +101,7 @@ #define TARGET_OS_CPP_BUILTINS()     \
 #define CPP_SPEC "%{posix: -D_POSIX_SOURCE}	\
   %{ansi: -D_ANSI_C_SOURCE}			\
   %{maix64: -D__64BIT__}			\
-  %{mpe: -I/usr/lpp/ppe.poe/include}		\
+  %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
   %{pthread: -D_THREAD_SAFE}"
 
 /* The GNU C++ standard library requires that these macros be 
@@ -110,7 +110,7 @@ #define CPP_SPEC "%{posix: -D_POSIX_SOUR
 #define CPLUSPLUS_CPP_SPEC			\
   "-D_ALL_SOURCE				\
    %{maix64: -D__64BIT__}			\
-   %{mpe: -I/usr/lpp/ppe.poe/include}		\
+   %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
    %{pthread: -D_THREAD_SAFE}"
 
 #undef  TARGET_DEFAULT
@@ -136,10 +136,10 @@ #define TARGET_POWER 0
 #undef	MULTILIB_DEFAULTS
 
 #undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+   %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
    %{!maix64:%{!shared:%{g*:-lg}}}\
-   %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+   %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
    %{pthread:-lpthreads} -lc"
 
 #undef LINK_SPEC
Index: gcc/config/rs6000/aix61.h
===================================================================
--- gcc/config/rs6000/aix61.h	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/aix61.h	2009-06-02 13:06:03.000000000 +0100
@@ -102,7 +102,7 @@ #define TARGET_OS_CPP_BUILTINS()     \
 #define CPP_SPEC "%{posix: -D_POSIX_SOURCE}	\
   %{ansi: -D_ANSI_C_SOURCE}			\
   %{maix64: -D__64BIT__}			\
-  %{mpe: -I/usr/lpp/ppe.poe/include}		\
+  %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
   %{pthread: -D_THREAD_SAFE}"
 
 /* The GNU C++ standard library requires that these macros be 
@@ -111,7 +111,7 @@ #define CPP_SPEC "%{posix: -D_POSIX_SOUR
 #define CPLUSPLUS_CPP_SPEC			\
   "-D_ALL_SOURCE -D__COMPATMATH__		\
    %{maix64: -D__64BIT__}			\
-   %{mpe: -I/usr/lpp/ppe.poe/include}		\
+   %{mpe: -I%R/usr/lpp/ppe.poe/include}		\
    %{pthread: -D_THREAD_SAFE}"
 
 #undef  TARGET_DEFAULT
@@ -137,10 +137,10 @@ #define TARGET_POWER 0
 #undef	MULTILIB_DEFAULTS
 
 #undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+   %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
    %{!maix64:%{!shared:%{g*:-lg}}}\
-   %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+   %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
    %{pthread:-lpthreads} -lc"
 
 #undef LINK_SPEC
Index: gcc/config/rs6000/t-aix52
===================================================================
--- gcc/config/rs6000/t-aix52	2009-06-02 13:05:47.000000000 +0100
+++ gcc/config/rs6000/t-aix52	2009-06-02 13:06:03.000000000 +0100
@@ -47,7 +47,7 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2
 	-Wl,-bE:@shlib_map_file@ -o @multilib_dir@/shr.o \
 	@multilib_flags@ @shlib_objs@ -lc \
 	`case @multilib_dir@ in \
-	*pthread*) echo -L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a ;; \
+	*pthread*) echo -L$(TARGET_SYSTEM_ROOT)/usr/lib/threads -lpthreads -lc_r $(TARGET_SYSTEM_ROOT)/usr/lib/libc.a ;; \
 	*) echo -lc ;; esac` ; \
 	rm -f @multilib_dir@/tmp-@shlib_base_name@.a ; \
 	$(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-@shlib_base_name@.a \

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [3/8] Fix premature post-increment in collect2.c
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
  2009-06-02 12:05 ` [1/8] Don't build newlib for AIX Richard Sandiford
  2009-06-02 12:10 ` [2/8] Handle sysroots on AIX (needs build-system maintainer) Richard Sandiford
@ 2009-06-02 12:11 ` Richard Sandiford
  2009-06-02 14:14   ` Ian Lance Taylor
  2009-06-02 12:20 ` [4/8] Implement the ldopen() family of routines for cross collect2s Richard Sandiford
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:11 UTC (permalink / raw)
  To: gcc-patches

A misplaced post-increment in collect2.c:ignore_library causes us to
skip the first element of aix_std_libs and dereference the null
terminator instead.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


gcc/
	* collect2.c (ignore_library): Avoid premature post-increment
	and null deference.

Index: gcc/collect2.c
===================================================================
--- gcc/collect2.c	2009-06-02 13:05:46.000000000 +0100
+++ gcc/collect2.c	2009-06-02 13:06:04.000000000 +0100
@@ -2444,8 +2444,9 @@ static int ignore_library (const char *)
 ignore_library (const char *name)
 {
   const char *const *p = &aix_std_libs[0];
-  while (*p++ != NULL)
-    if (! strcmp (name, *p)) return 1;
+  while (*p)
+    if (! strcmp (name, *p++))
+      return 1;
   return 0;
 }
 #endif /* COLLECT_EXPORT_LIST */

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [4/8] Implement the ldopen() family of routines for cross collect2s
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
                   ` (2 preceding siblings ...)
  2009-06-02 12:11 ` [3/8] Fix premature post-increment in collect2.c Richard Sandiford
@ 2009-06-02 12:20 ` Richard Sandiford
  2009-06-02 14:28   ` Ian Lance Taylor
  2009-06-02 12:21 ` [5/8] Make collect2 honour --sysroot Richard Sandiford
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:20 UTC (permalink / raw)
  To: gcc-patches

AIX collect2 currently relies on the ldopen()/ldclose() family of routines,
which are only available on AIX systems.  This patch tries to emulate the
routines for cross toolchains.

For the record, I did this work without referring to AIX header files,
and I have no access to the AIX code itself.  The file format definitions
were adapted from bfd code while everything else was written from scratch.
I used delimiters (usually frowned on, I know) to show which parts came
from bfd.

The main restrictions with this support are:

  (1) It requires mmap().

  (2) It only works for "big"-format archives.

It would be easy to add support for small archives, but I haven't had
chance to do that.  Small archives are of pretty niche importance
these days anyway.

collect2.c has one instance of a host-acting-as-target preprocessor check:

    #ifdef _AIX51

I replaced this with a new TARGET_AIX_VERSION macro.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


gcc/
	* Makefile.in (COLLECT2_OBJS): Add collect2-aix.o.
	(collect2.o): Depend on collect2-aix.h.
	(collect2-aix.o): New rule.
	* collect2-aix.h: New file.
	* collect2-aix.c: Likewise.
	* collect2.c: Include collect-aix.h.  Don't undefine OBJECT_FORMAT_COFF
	if CROSS_AIX_SUPPORT is defined.  Guard native includes with
	#ifndef CROSS_DIRECTORY_STRUCTURE.  Use TARGET_AIX_VERSION
	instead of _AIX51.
	* config/rs6000/aix43.h (TARGET_AIX_VERSION): Define.
	* config/rs6000/aix51.h (TARGET_AIX_VERSION): Likewise.
	* config/rs6000/aix52.h (TARGET_AIX_VERSION): Likewise.
	* config/rs6000/aix53.h (TARGET_AIX_VERSION): Likewise.
	* config/rs6000/aix61.h (TARGET_AIX_VERSION): Likewise.

Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	2009-06-02 13:06:03.000000000 +0100
+++ gcc/Makefile.in	2009-06-02 13:06:05.000000000 +0100
@@ -1897,7 +1897,7 @@ ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTE
 	$(EBITMAP_H) $(RTL_H) $(FLAGS_H) $(OBSTACK_H)
 sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
 
-COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
+COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o intl.o version.o
 COLLECT2_LIBS = @COLLECT2_LIBS@
 collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
 # Don't try modifying collect2 (aka ld) in place--it might be linking this.
@@ -1906,10 +1906,13 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LI
 	mv -f T$@ $@
 
 collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
-	$(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h
+	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h
 	$(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS)  \
 	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
-	-c $(srcdir)/collect2.c $(OUTPUT_OPTION)
+	-c $(srcdir)/collect2.c $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
+
+collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+    collect2-aix.h
 
 tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(OBSTACK_H) collect2.h intl.h
Index: gcc/collect2-aix.h
===================================================================
--- /dev/null	2009-05-22 08:46:47.449511000 +0100
+++ gcc/collect2-aix.h	2009-06-02 13:06:05.000000000 +0100
@@ -0,0 +1,301 @@
+/* AIX cross support for collect2.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* collect2-aix.c requires mmap support.  It should otherwise be
+   fairly portable.  */
+#if defined(CROSS_DIRECTORY_STRUCTURE) \
+    && defined(TARGET_AIX_VERSION) \
+    && HAVE_MMAP
+
+#define CROSS_AIX_SUPPORT 1
+
+/* -------------------------------------------------------------------------
+   Definitions adapted from bfd.  (Fairly heavily adapted in some cases.)
+   ------------------------------------------------------------------------- */
+
+/* Compatiblity types for bfd.  */
+typedef unsigned HOST_WIDE_INT bfd_vma;
+
+/* The size of an archive's fl_magic field.  */
+#define FL_MAGIC_SIZE 8
+
+/* The expected contents of fl_magic for big archives.  */
+#define FL_MAGIC_BIG_AR "<bigaf>\012"
+
+/* The size of each offset string in the header of a big archive.  */
+#define AR_BIG_OFFSET_SIZE 20
+
+/* The format of the file header in a "big" XCOFF archive.  */
+struct external_big_ar_filehdr
+{
+  /* Magic string.  */
+  char fl_magic[FL_MAGIC_SIZE];
+
+  /* Offset of the member table (decimal ASCII string).  */
+  char fl_memoff[AR_BIG_OFFSET_SIZE];
+
+  /* Offset of the global symbol table for 32-bit objects (decimal ASCII
+     string).  */
+  char fl_symoff[AR_BIG_OFFSET_SIZE];
+
+  /* Offset of the global symbol table for 64-bit objects (decimal ASCII
+     string).  */
+  char fl_symoff64[AR_BIG_OFFSET_SIZE];
+
+  /* Offset of the first member in the archive (decimal ASCII string).  */
+  char fl_firstmemoff[AR_BIG_OFFSET_SIZE];
+
+  /* Offset of the last member in the archive (decimal ASCII string).  */
+  char fl_lastmemoff[AR_BIG_OFFSET_SIZE];
+
+  /* Offset of the first member on the free list (decimal ASCII
+     string).  */
+  char fl_freeoff[AR_BIG_OFFSET_SIZE];
+};
+
+/* Each archive name is followed by this many bytes of magic string.  */
+#define SXCOFFARFMAG 2
+
+/* The format of a member header in a "big" XCOFF archive.  */
+struct external_big_ar_member
+{
+  /* File size not including the header (decimal ASCII string).  */
+  char ar_size[AR_BIG_OFFSET_SIZE];
+
+  /* File offset of next archive member (decimal ASCII string).  */
+  char ar_nextoff[AR_BIG_OFFSET_SIZE];
+
+  /* File offset of previous archive member (decimal ASCII string).  */
+  char ar_prevoff[AR_BIG_OFFSET_SIZE];
+
+  /* File mtime (decimal ASCII string).  */
+  char ar_date[12];
+
+  /* File UID (decimal ASCII string).  */
+  char ar_uid[12];
+
+  /* File GID (decimal ASCII string).  */
+  char ar_gid[12];
+
+  /* File mode (octal ASCII string).  */
+  char ar_mode[12];
+
+  /* Length of file name (decimal ASCII string).  */
+  char ar_namlen[4];
+
+  /* This structure is followed by the file name.  The length of the
+     name is given in the namlen field.  If the length of the name is
+     odd, the name is followed by a null byte.  The name and optional
+     null byte are followed by XCOFFARFMAG, which is not included in
+     namlen.  The contents of the archive member follow; the number of
+     bytes is given in the size field.  */
+};
+
+/* The known values of f_magic in an XCOFF file header.  */
+#define U802WRMAGIC 0730	/* Writeable text segments.  */
+#define U802ROMAGIC 0735	/* Readonly sharable text segments.  */
+#define U802TOCMAGIC 0737	/* Readonly text segments and TOC.  */
+#define U803XTOCMAGIC 0757	/* Aix 4.3 64-bit XCOFF.  */
+#define U64_TOCMAGIC 0767	/* AIX 5+ 64-bit XCOFF.  */
+
+/* The number of bytes in an XCOFF file's f_magic field.  */
+#define F_MAGIC_SIZE 2
+
+/* The format of a 32-bit XCOFF file header.  */
+struct external_filehdr_32
+{
+  /* The magic number.  */
+  char f_magic[F_MAGIC_SIZE];
+
+  /* The number of sections.  */
+  char f_nscns[2];
+
+  /* Time & date stamp.  */
+  char f_timdat[4];
+
+  /* The offset of the symbol table from the start of the file.  */
+  char f_symptr[4];
+
+  /* The number of entries in the symbol table.  */
+  char f_nsyms[4];
+
+  /* The size of the auxillary header.  */
+  char f_opthdr[2];
+
+  /* Flags.  */
+  char f_flags[2];
+};
+
+/* The format of a 64-bit XCOFF file header.  */
+struct external_filehdr_64
+{
+  /* The magic number.  */
+  char f_magic[F_MAGIC_SIZE];
+
+  /* The number of sections.  */
+  char f_nscns[2];
+
+  /* Time & date stamp.  */
+  char f_timdat[4];
+
+  /* The offset of the symbol table from the start of the file.  */
+  char f_symptr[8];
+
+  /* The size of the auxillary header.  */
+  char f_opthdr[2];
+
+  /* Flags.  */
+  char f_flags[2];
+
+  /* The number of entries in the symbol table.  */
+  char f_nsyms[4];
+};
+
+/* An internal representation of the XCOFF file header.  */
+struct internal_filehdr
+{
+  unsigned short f_magic;
+  unsigned short f_nscns;
+  long f_timdat;
+  bfd_vma f_symptr;
+  long f_nsyms;
+  unsigned short f_opthdr;
+  unsigned short f_flags;
+};
+
+/* Symbol classes have their names in the debug section if this flag
+   is set.  */
+#define DBXMASK 0x80
+
+/* The format of an XCOFF symbol-table entry.  */
+struct external_syment
+{
+  union {
+    struct {
+      union {
+	/* The name of the symbol.  There is an implicit null character
+	   after the end of the array.  */
+	char n_name[8];
+	struct {
+	  /* If n_zeroes is zero, n_offset is the offset the name from
+	     the start of the string table.  */
+	  char n_zeroes[4];
+	  char n_offset[4];
+	} u;
+      } u;
+
+      /* The symbol's value.  */
+      char n_value[4];
+    } xcoff32;
+    struct {
+      /* The symbol's value.  */
+      char n_value[8];
+
+      /* The offset of the symbol from the start of the string table.  */
+      char n_offset[4];
+    } xcoff64;
+  } u;
+
+  /* The number of the section to which this symbol belongs.  */
+  char n_scnum[2];
+
+  /* The type of symbol.  (It can be interpreted as an n_lang
+     and an n_cpu byte, but we don't care about that here.)  */
+  char n_type[2];
+
+  /* The class of symbol (a C_* value).  */
+  char n_sclass[1];
+
+  /* The number of auxillary symbols attached to this entry.  */
+  char n_numaux[1];
+};
+
+/* Definitions required by collect2.  */
+#define C_EXT 2
+
+#define F_SHROBJ 0x2000
+
+#define N_UNDEF ((short) 0)
+#define N_TMASK 060
+#define N_BTSHFT 4
+
+#define DT_NON 0
+#define DT_FCN 2
+
+/* -------------------------------------------------------------------------
+   Local code.
+   ------------------------------------------------------------------------- */
+
+/* An internal representation of an XCOFF symbol-table entry,
+   which is associated with the API-defined SYMENT type.  */
+struct internal_syment
+{
+  char n_name[9];
+  unsigned int n_zeroes;
+  bfd_vma n_offset;
+  bfd_vma n_value;
+  short n_scnum;
+  unsigned short n_flags;
+  unsigned short n_type;
+  unsigned char n_sclass;
+  unsigned char n_numaux;
+};
+typedef struct internal_syment SYMENT;
+
+/* The internal representation of the API-defined LDFILE type.  */
+struct internal_ldfile
+{
+  /* The file handle for the associated file, or -1 if it hasn't been
+     opened yet.  */
+  int fd;
+
+  /* The start of the current XCOFF object, if one has been mapped
+     into memory.  Null otherwise.  */
+  char *object;
+
+  /* The offset of OBJECT from the start of the containing page.  */
+  size_t page_offset;
+
+  /* The size of the file pointed to by OBJECT.  Valid iff OFFSET
+     is nonnull.  */
+  size_t object_size;
+
+  /* The offset of the next member in an archive after OBJECT,
+     or -1 if this isn't an archive.  Valid iff OFFSET is nonnull.  */
+  off_t next_member;
+
+  /* The parsed version of the XCOFF file header.  */
+  struct internal_filehdr filehdr;
+};
+typedef struct internal_ldfile LDFILE;
+
+/* The API allows the file header to be directly accessed via this macro.  */
+#define HEADER(FILE) ((FILE)->filehdr)
+
+/* API-defined return codes.  SUCCESS must be > 0 and FAILURE must be <= 0.  */
+#define SUCCESS 1
+#define FAILURE 0
+
+/* API-defined functions.  */
+extern LDFILE *ldopen (char *, LDFILE *);
+extern char *ldgetname (LDFILE *, SYMENT *);
+extern int ldtbread (LDFILE *, long, SYMENT *);
+extern int ldclose (LDFILE *);
+
+#endif
Index: gcc/collect2-aix.c
===================================================================
--- /dev/null	2009-05-22 08:46:47.449511000 +0100
+++ gcc/collect2-aix.c	2009-06-02 13:06:05.000000000 +0100
@@ -0,0 +1,371 @@
+/* AIX cross support for collect2.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "collect2-aix.h"
+
+#ifdef CROSS_AIX_SUPPORT
+
+#include <sys/mman.h>
+
+/* Read SIZE bytes starting at DATA as a big-endian value.  */
+
+static inline bfd_vma
+read_value (char *data, unsigned int size)
+{
+  bfd_vma value;
+  unsigned int i;
+
+  value = 0;
+  for (i = 0; i < size; i++)
+    {
+      value <<= 8;
+      value += (unsigned char) data[i];
+    }
+  return value;
+}
+
+/* FIELD is a char array.  Read the contents as a big-endian integer.  */
+#define READ_FIELD(FIELD) \
+  read_value (FIELD, sizeof (FIELD))
+
+/* OBJECT is a char pointer to an in-file object of type struct TYPE.
+   Return the address of field FIELD.  */
+#define OBJECT_FIELD(OBJECT, TYPE, FIELD) \
+  (OBJECT) + offsetof (struct TYPE, FIELD)
+
+/* Return the size of FIELD, which is a field of struct TYPE.  */
+#define FIELD_SIZE(TYPE, FIELD) \
+  sizeof (((struct TYPE *) (0))->FIELD)
+
+/* OBJECT is a char pointer to an in-file object of type struct TYPE.
+   Read the value of field FIELD as a big-endian integer.  */
+#define READ_OBJECT(OBJECT, TYPE, FIELD) \
+  read_value (OBJECT_FIELD (OBJECT, TYPE, FIELD), FIELD_SIZE (TYPE, FIELD))
+
+/* Copy FIELD from an external structure of type TYPE at address FROM
+   to an internal structure pointed to by TO.  */
+#define COPY_FIELD(TO, FROM, TYPE, FIELD) \
+  ((TO)->FIELD = READ_OBJECT (FROM, TYPE, FIELD))
+
+/* Return true if STRING is less than SIZE bytes long.  EXTRA_TERMINATOR
+   is another character (besides '\0') that acts as a terminator,
+   or '\0' if none.  */
+
+static bool
+string_within_bounds_p (const char *string, size_t size, char extra_terminator)
+{
+  const char *p;
+
+  for (p = string; p < string + size; p++)
+    if (*p == '\0' || *p == extra_terminator)
+      return true;
+  return false;
+}
+
+/* STRING is a pointer to a char array.  Try to read its value as an
+   ASCII-encoded integer.  On success, return true and store the result
+   in TARGET.  */
+#define PARSE_INTEGER(TARGET, STRING) \
+  (string_within_bounds_p (&(STRING)[0], sizeof (STRING), ' ') \
+   && ((TARGET) = strtoul (STRING, NULL, 0), true))
+
+/* Check that LDFILE's current object has SIZE bytes starting at OFFSET.  */
+
+static inline bool
+within_object_p (LDFILE *ldfile, size_t offset, size_t size)
+{
+  return offset <= ldfile->object_size && offset + size <= ldfile->object_size;
+}
+
+/* Try to read the file header for an XCOFF object at OFFSET bytes into
+   LDFILE.  The object is expected to be OBJECT_SIZE bytes in size.
+   If the object is a member of an archive, NEXT_MEMBER is the offset
+   of the next member, otherwise it is -1.
+
+   Return true on success, recording the object information in LDFILE.  */
+
+static bool
+read_xcoff_object (LDFILE *ldfile, size_t offset, size_t object_size,
+		   off_t next_member)
+{
+  struct internal_filehdr *internal;
+  char *external;
+  void *map;
+  size_t page_size;
+
+  /* First try to map the file into memory.  */
+  page_size = getpagesize ();
+  ldfile->page_offset = offset & (page_size - 1);
+  map = mmap (NULL, object_size + ldfile->page_offset, PROT_READ,
+              MAP_SHARED, ldfile->fd, offset - ldfile->page_offset);
+  if (map == MAP_FAILED)
+    return false;
+
+  /* Record the success.  */
+  ldfile->object = (char *) map + ldfile->page_offset;
+  ldfile->object_size = object_size;
+  ldfile->next_member = next_member;
+
+  /* Read the magic value to determine the type of file.  */
+  if (!within_object_p (ldfile, 0, F_MAGIC_SIZE))
+    return false;
+
+  internal = &ldfile->filehdr;
+  external = ldfile->object;
+  internal->f_magic = read_value (external, F_MAGIC_SIZE);
+  if (internal->f_magic == U802TOCMAGIC)
+    {
+      if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_32)))
+	return false;
+
+      COPY_FIELD (internal, external, external_filehdr_32, f_nscns);
+      COPY_FIELD (internal, external, external_filehdr_32, f_timdat);
+      COPY_FIELD (internal, external, external_filehdr_32, f_symptr);
+      COPY_FIELD (internal, external, external_filehdr_32, f_nsyms);
+      COPY_FIELD (internal, external, external_filehdr_32, f_opthdr);
+      COPY_FIELD (internal, external, external_filehdr_32, f_flags);
+      return true;
+    }
+  else if (internal->f_magic == U803XTOCMAGIC
+	   || internal->f_magic == U64_TOCMAGIC)
+    {
+      if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_64)))
+	return false;
+
+      COPY_FIELD (internal, external, external_filehdr_64, f_nscns);
+      COPY_FIELD (internal, external, external_filehdr_64, f_timdat);
+      COPY_FIELD (internal, external, external_filehdr_64, f_symptr);
+      COPY_FIELD (internal, external, external_filehdr_64, f_nsyms);
+      COPY_FIELD (internal, external, external_filehdr_64, f_opthdr);
+      COPY_FIELD (internal, external, external_filehdr_64, f_flags);
+      return true;
+    }
+  return false;
+}
+
+/* Try to read an archive member at OFFSET bytes into LDFILE.
+   Return true on success, recording the member and object
+   information in LDFILE.  */
+
+static bool
+read_archive_member (LDFILE *ldfile, size_t offset)
+{
+  struct external_big_ar_member member;
+  size_t namlen;
+  size_t size;
+  off_t next_member;
+
+  if (lseek (ldfile->fd, offset, SEEK_SET) >= 0
+      && read (ldfile->fd, &member, sizeof (member)) == sizeof (member)
+      && PARSE_INTEGER (namlen, member.ar_namlen)
+      /* Stop once we reach the member table entry, which has a name
+	 of length 0.  */
+      && namlen > 0
+      && PARSE_INTEGER (size, member.ar_size)
+      && PARSE_INTEGER (next_member, member.ar_nextoff))
+    {
+      /* The archive is followed by an even-padded name, then by
+	 a magic string of length SXCOFFARFMAG.  The object itself
+	 starts after that. */
+      offset += sizeof (member) + namlen + SXCOFFARFMAG;
+      offset += offset & 1;
+      return read_xcoff_object (ldfile, offset, size, next_member);
+    }
+  return false;
+}
+
+/* Try to treat LDFILE as a non-empty big archive.  Return true
+   on success, storing the member and object information for
+   the first member in LDFILE.  */
+
+static bool
+read_big_archive (LDFILE *ldfile)
+{
+  struct external_big_ar_filehdr filehdr;
+  size_t offset;
+
+  return (lseek (ldfile->fd, 0L, SEEK_SET) == 0
+	  && read (ldfile->fd, &filehdr, sizeof (filehdr)) == sizeof (filehdr)
+	  && memcmp (filehdr.fl_magic, FL_MAGIC_BIG_AR, FL_MAGIC_SIZE) == 0
+	  && PARSE_INTEGER (offset, filehdr.fl_firstmemoff)
+	  && read_archive_member (ldfile, offset));
+}
+
+/* LDFILE is a zero-initialized structure.  Try to open FILENAME,
+   returning true on success.  */
+
+static bool
+open_file (LDFILE *ldfile, const char *filename)
+{
+  struct stat st;
+
+  ldfile->fd = open (filename, O_RDONLY);
+  if (ldfile->fd < 0)
+    return false;
+
+  if (read_big_archive (ldfile))
+    return true;
+
+  if (fstat (ldfile->fd, &st) < 0)
+    return false;
+
+  return read_xcoff_object (ldfile, 0, st.st_size, -1);
+}
+
+/* Release the memory associated with the current object, if one has
+   been mapped.  */
+
+static void
+free_object (LDFILE *ldfile)
+{
+  if (ldfile->object)
+    munmap (ldfile->object - ldfile->page_offset,
+	    ldfile->object_size + ldfile->page_offset);
+}
+
+/* Free LDFILE and all resources associated with it.  */
+
+static void
+free_ldfile (LDFILE *ldfile)
+{
+  if (ldfile->fd >= 0)
+    close (ldfile->fd);
+  XDELETE (ldfile);
+}
+
+/* Implement the API-defined ldopen function.  */
+
+LDFILE *
+ldopen (char *filename, LDFILE *ldfile)
+{
+  if (ldfile == NULL)
+    {
+      ldfile = XCNEW (LDFILE);
+      if (!open_file (ldfile, filename))
+	{
+	  free_object (ldfile);
+	  free_ldfile (ldfile);
+	  return NULL;
+	}
+    }
+  return ldfile;
+}
+
+/* Implement the API-defined ldtbread function.  */
+
+int
+ldtbread (LDFILE *ldfile, long index, SYMENT *internal)
+{
+  size_t offset, name_length;
+  char *external;
+
+  /* Make sure that the symbol index is valid.  */
+  if (index < 0 || index >= HEADER (ldfile).f_nsyms)
+    return FAILURE;
+
+  /* Work out the offset of the symbol table entry.  */
+  offset = HEADER (ldfile).f_symptr + index * sizeof (struct external_syment);
+  if (!within_object_p (ldfile, offset, sizeof (struct external_syment)))
+    return FAILURE;
+
+  /* Read all the fields.  The format differs between 32-bit and
+     64-bit files.  */
+  external = ldfile->object + offset;
+  if (HEADER (ldfile).f_magic == U802TOCMAGIC)
+    {
+      /* Copy the n_zeroes/n_offset interpretation.  */
+      internal->n_zeroes = READ_OBJECT (external, external_syment,
+					u.xcoff32.u.u.n_zeroes);
+      internal->n_offset = READ_OBJECT (external, external_syment,
+					u.xcoff32.u.u.n_offset);
+
+      /* Copy the n_name interpretation.  The internal version has room
+	 for a null terminator.  */
+      name_length = FIELD_SIZE (external_syment, u.xcoff32.u.n_name);
+      memcpy (internal->n_name,
+	      external + offsetof (struct external_syment, u.xcoff32.u.n_name),
+	      name_length);
+      internal->n_name[name_length] = 0;
+
+      internal->n_value = READ_OBJECT (external, external_syment,
+				       u.xcoff32.n_value);
+    }
+  else
+    {
+      internal->n_zeroes = 0;
+      internal->n_offset = READ_OBJECT (external, external_syment,
+					u.xcoff64.n_offset);
+      internal->n_value = READ_OBJECT (external, external_syment,
+				       u.xcoff64.n_value);
+    }
+  COPY_FIELD (internal, external, external_syment, n_scnum);
+  COPY_FIELD (internal, external, external_syment, n_type);
+  COPY_FIELD (internal, external, external_syment, n_sclass);
+  COPY_FIELD (internal, external, external_syment, n_numaux);
+  return SUCCESS;
+}
+
+/* Implement the API-defined ldgetname function.  */
+
+char *
+ldgetname (LDFILE *ldfile, SYMENT *symbol)
+{
+  char *name;
+  size_t offset;
+
+  /* If the zeroes field is nonzero, the name is in the symbol table
+     entry itself.  */
+  if (symbol->n_zeroes != 0)
+    return symbol->n_name;
+
+  /* Otherwise, the symbol table entry contains an offset into the
+     string table, which starts after the end of the symbol table.  */
+  offset = (HEADER (ldfile).f_symptr
+	    + HEADER (ldfile).f_nsyms * sizeof (struct external_syment)
+	    + symbol->n_offset);
+  if (offset >= ldfile->object_size)
+    return NULL;
+
+  /* Make sure that the name is entirely contained within the object.  */
+  name = ldfile->object + offset;
+  if (!string_within_bounds_p (name, ldfile->object_size - offset, '\0'))
+    return NULL;
+
+  return name;
+}
+
+/* Implement the API-defined ldclose function.  */
+
+int
+ldclose (LDFILE *ldfile)
+{
+  free_object (ldfile);
+  if (ldfile->next_member >= 0
+      && read_archive_member (ldfile, ldfile->next_member))
+    return FAILURE;
+
+  free_ldfile (ldfile);
+  return SUCCESS;
+}
+
+#endif
Index: gcc/collect2.c
===================================================================
--- gcc/collect2.c	2009-06-02 13:06:04.000000000 +0100
+++ gcc/collect2.c	2009-06-02 13:06:05.000000000 +0100
@@ -42,6 +42,7 @@ #define LIBRARY_PATH_ENV "LIBRARY_PATH"
 #define COLLECT
 
 #include "collect2.h"
+#include "collect2-aix.h"
 #include "demangle.h"
 #include "obstack.h"
 #include "intl.h"
@@ -54,7 +55,9 @@ #define COLLECT
    cross-versions are in the proper directories.  */
 
 #ifdef CROSS_DIRECTORY_STRUCTURE
+#ifndef CROSS_AIX_SUPPORT
 #undef OBJECT_FORMAT_COFF
+#endif
 #undef MD_EXEC_PREFIX
 #undef REAL_LD_FILE_NAME
 #undef REAL_NM_FILE_NAME
@@ -72,6 +75,7 @@ #define OBJECT_FORMAT_NONE
 
 #ifdef OBJECT_FORMAT_COFF
 
+#ifndef CROSS_DIRECTORY_STRUCTURE
 #include <a.out.h>
 #include <ar.h>
 
@@ -86,6 +90,7 @@ #define OBJECT_FORMAT_NONE
 #endif
 
 #include <ldfcn.h>
+#endif
 
 /* Some systems have an ISCOFF macro, but others do not.  In some cases
    the macro may be wrong.  MY_ISCOFF is defined in tm.h files for machines
@@ -2404,7 +2409,7 @@ scan_libraries (const char *prog_name)
 #   define GCC_SYMZERO(X)	0
 
 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
-#ifdef _AIX51
+#if TARGET_AIX_VERSION >= 51
 #   define GCC_CHECK_HDR(X) \
      ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
       || (HEADER (X).f_magic == 0767 && aix64_flag))
Index: gcc/config/rs6000/aix43.h
===================================================================
--- gcc/config/rs6000/aix43.h	2009-06-02 13:06:03.000000000 +0100
+++ gcc/config/rs6000/aix43.h	2009-06-02 13:06:05.000000000 +0100
@@ -187,3 +187,5 @@ #define TARGET_DEFERRED_OUTPUT_DEFS(DECL
 
 /* This target uses the aix64.opt file.  */
 #define TARGET_USES_AIX64_OPT 1
+
+#define TARGET_AIX_VERSION 43
Index: gcc/config/rs6000/aix51.h
===================================================================
--- gcc/config/rs6000/aix51.h	2009-06-02 13:06:03.000000000 +0100
+++ gcc/config/rs6000/aix51.h	2009-06-02 13:06:05.000000000 +0100
@@ -191,3 +191,5 @@ #define TARGET_USES_AIX64_OPT 1
    but does not have crtbegin/end.  */
 
 #define TARGET_USE_JCR_SECTION 0
+
+#define TARGET_AIX_VERSION 51
Index: gcc/config/rs6000/aix52.h
===================================================================
--- gcc/config/rs6000/aix52.h	2009-06-02 13:06:03.000000000 +0100
+++ gcc/config/rs6000/aix52.h	2009-06-02 13:06:05.000000000 +0100
@@ -201,3 +201,5 @@ #define TARGET_USES_AIX64_OPT 1
    but does not have crtbegin/end.  */
 
 #define TARGET_USE_JCR_SECTION 0
+
+#define TARGET_AIX_VERSION 52
Index: gcc/config/rs6000/aix53.h
===================================================================
--- gcc/config/rs6000/aix53.h	2009-06-02 13:06:03.000000000 +0100
+++ gcc/config/rs6000/aix53.h	2009-06-02 13:06:05.000000000 +0100
@@ -197,3 +197,5 @@ #define TARGET_USES_AIX64_OPT 1
    but does not have crtbegin/end.  */
 
 #define TARGET_USE_JCR_SECTION 0
+
+#define TARGET_AIX_VERSION 53
Index: gcc/config/rs6000/aix61.h
===================================================================
--- gcc/config/rs6000/aix61.h	2009-06-02 13:06:03.000000000 +0100
+++ gcc/config/rs6000/aix61.h	2009-06-02 13:06:05.000000000 +0100
@@ -202,3 +202,5 @@ #define TARGET_USE_JCR_SECTION 0
 /* Default to 128 bit long double.  */
 
 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
+
+#define TARGET_AIX_VERSION 61

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [5/8] Make collect2 honour --sysroot
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
                   ` (3 preceding siblings ...)
  2009-06-02 12:20 ` [4/8] Implement the ldopen() family of routines for cross collect2s Richard Sandiford
@ 2009-06-02 12:21 ` Richard Sandiford
  2009-06-02 14:30   ` Ian Lance Taylor
  2009-06-02 12:23 ` [6/8] Add AIX support to GLIBCXX_CROSSCONFIG Richard Sandiford
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:21 UTC (permalink / raw)
  To: gcc-patches

This patch adds --sysroot support to collect2.  Specifically, it makes
sure that ignore_library strips the sysroot directory from the start
of a library path before comparing it against aix_std_libs.

I haven't tried to cope with cases where there are two "/"s after
the sysroot path, or where the sysroot path ends in more "/"s than
the paths themselves.  These situations would not occur in the
automatically-generated paths we care about, and I think allowing
slash variations is conceptually a separate change.  (Slash variations
would also allow native toolchains to treat "///unix" as "/unix",
for example.)

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


gcc/
	* collect2.c (target_system_root): New variable.
	(main): Handle --sysroot=.
	(ignore_library): Strip the sysroot from the library path.

Index: gcc/collect2.c
===================================================================
--- gcc/collect2.c	2009-06-02 13:06:05.000000000 +0100
+++ gcc/collect2.c	2009-06-02 13:06:07.000000000 +0100
@@ -217,6 +217,14 @@ static const char *ldd_file_name;	/* pat
 struct obstack temporary_obstack;
 char * temporary_firstobj;
 
+/* A string that must be prepended to a target OS path in order to find
+   it on the host system.  */
+#ifdef TARGET_SYSTEM_ROOT
+static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = "";
+#endif
+
 /* Structure to hold all the directories in which to search for files to
    execute.  */
 
@@ -1220,6 +1228,8 @@ main (int argc, char **argv)
 		  ld1--;
 		  ld2--;
 		}
+	      else if (strncmp (arg, "--sysroot=", 10) == 0)
+		target_system_root = arg + 10;
 	      break;
 	    }
 	}
@@ -2449,6 +2459,15 @@ static int ignore_library (const char *)
 ignore_library (const char *name)
 {
   const char *const *p = &aix_std_libs[0];
+  size_t length;
+
+  if (target_system_root[0] != '\0')
+    {
+      length = strlen (target_system_root);
+      if (strncmp (name, target_system_root, length) != 0)
+	return 0;
+      name += length;
+    }
   while (*p)
     if (! strcmp (name, *p++))
       return 1;

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [6/8] Add AIX support to GLIBCXX_CROSSCONFIG
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
                   ` (4 preceding siblings ...)
  2009-06-02 12:21 ` [5/8] Make collect2 honour --sysroot Richard Sandiford
@ 2009-06-02 12:23 ` Richard Sandiford
  2009-06-05  4:59   ` Benjamin Kosnik
  2009-06-02 12:29 ` [7/8] Don't compile collect2 init and fini routines with -fwhole-program Richard Sandiford
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++

This patch adds AIX cross support to libstdc++ configure.  It uses:

    GLIBCXX_CHECK_LINKER_FEATURES
    GLIBCXX_CHECK_MATH_SUPPORT
    GLIBCXX_CHECK_STDLIB_SUPPORT

just like native toolchains, and just like other cross toolchains
that require a "working" linker and access to the sysroot.

I've treated TLS as unsupported.  AIX does have a defined TLS ABI,
but we don't use it yet.  I don't think we should rely on emultls
when a dedicated ABI is available.

I've assumed /dev/random and /dev/urandom are both available.
This is certainly true on the AIX 6.1 box that I have access to.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


libstdc++-v3/
	* crossconfig.m4 (GLIBCXX_CROSSCONFIG): Handle AIX targets.
	* configure: Regenerate.
	
Index: libstdc++-v3/crossconfig.m4
===================================================================
--- libstdc++-v3/crossconfig.m4	2009-06-02 13:05:35.000000000 +0100
+++ libstdc++-v3/crossconfig.m4	2009-06-02 13:06:07.000000000 +0100
@@ -28,6 +28,16 @@ case "${host}" in
     AC_DEFINE(HAVE_SQRTF)
     ;;
 
+  *-aix*)
+    GLIBCXX_CHECK_LINKER_FEATURES
+    GLIBCXX_CHECK_MATH_SUPPORT
+    GLIBCXX_CHECK_STDLIB_SUPPORT
+    AC_DEFINE(_GLIBCXX_USE_RANDOM_TR1)
+    # We don't yet support AIX's TLS ABI.
+    #GCC_CHECK_TLS
+    AM_ICONV
+    ;;
+
   *-darwin*)
     # Darwin versions vary, but the linker should work in a cross environment,
     # so we just check for all the features here.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [7/8] Don't compile collect2 init and fini routines with -fwhole-program
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
                   ` (5 preceding siblings ...)
  2009-06-02 12:23 ` [6/8] Add AIX support to GLIBCXX_CROSSCONFIG Richard Sandiford
@ 2009-06-02 12:29 ` Richard Sandiford
  2009-06-02 14:33   ` Ian Lance Taylor
  2009-06-02 12:33 ` [8/8] Tidy up testsuite handling of LD_LIBRARY_PATH (needs testsuite maintainer) Richard Sandiford
  2009-06-02 18:01 ` [0/8] AIX cross toolchains Ralf Wildenhues
  8 siblings, 1 reply; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:29 UTC (permalink / raw)
  To: gcc-patches

As Dave explained in:

    http://gcc.gnu.org/ml/gcc-patches/2008-09/msg00573.html

collect2 should not pass -fwhole-program to gcc when compiling the
init and fini functions, because the option causes the functions
to be optimised away.  The easiest way of handling this is to
stop -fwhole-program being added to the COLLECT_GCC_OPTIONS
environment variable.

I don't think there's anything target-specific here, so I'd like
to handle it in gcc.c rather than the target files.  I'm also a bit
wary of using %<fwhole-program, because -fwhole-program seems like
the kind of option that future specs might conceivably care about.
In other words, %< is really for hiding options from other _specs_,
so it doesn't seem like a good idea to hide an option for purely
non-spec reasons.  (COLLECT_GCC_OPTIONS doesn't use the specs mechanism.)

So, while I can see it makes sense for COLLECT_GCC_OPTIONS to ignore
options that have been removed by %< (as the current code does),
I'm not sure it makes sense to use %< to remove options purely
for the sake of COLLECT_GCC_OPTIONS.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


gcc/
	* config/pa/pa-hpux.h (LINK_SPEC): Remove "%<fwhole-program".
	* config/pa/pa-hpux10.h (LINK_SPEC): Likewise.
	* config/pa/pa-hpux11.h (LINK_SPEC): Likewise.
	* gcc.c (set_collect_gcc_options): Don't add -fwhole-program
	to COLLECT_GCC_OPTIONS.

Index: gcc/config/pa/pa-hpux.h
===================================================================
--- gcc/config/pa/pa-hpux.h	2009-06-02 13:05:35.000000000 +0100
+++ gcc/config/pa/pa-hpux.h	2009-06-02 13:06:09.000000000 +0100
@@ -95,12 +95,10 @@ #define LIB_SPEC "%{!shared:%{!p:%{!pg:-
 #undef LINK_SPEC
 #if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_PA_11)
 #define LINK_SPEC \
-  "%<fwhole-program\
-   %{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
+  "%{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
 #else
 #define LINK_SPEC \
-  "%<fwhole-program\
-   %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
+  "%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
 #endif
 
 /* hpux8 and later have C++ compatible include files, so do not
Index: gcc/config/pa/pa-hpux10.h
===================================================================
--- gcc/config/pa/pa-hpux10.h	2009-06-02 13:05:35.000000000 +0100
+++ gcc/config/pa/pa-hpux10.h	2009-06-02 13:06:09.000000000 +0100
@@ -82,8 +82,7 @@ #define CPP_SPEC "%{threads: -D_REENTRAN
 #undef LINK_SPEC
 #if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_PA_11)
 #define LINK_SPEC \
-  "%<fwhole-program\
-   %{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}\
+  "%{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}\
    %{!shared:%{p:-L/lib/libp %{!static:\
      %nWarning: consider linking with `-static' as system libraries with\n\
      %n  profiling support are only provided in archive format}}}\
@@ -94,8 +93,7 @@ #define LINK_SPEC \
    %{static:-a archive} %{shared:-b}"
 #else
 #define LINK_SPEC \
-  "%<fwhole-program\
-   %{!shared:%{p:-L/lib/libp %{!static:\
+  "%{!shared:%{p:-L/lib/libp %{!static:\
      %nWarning: consider linking with `-static' as system libraries with\n\
      %n  profiling support are only provided in archive format}}}\
    %{!shared:%{pg:-L/lib/libp %{!static:\
Index: gcc/config/pa/pa-hpux11.h
===================================================================
--- gcc/config/pa/pa-hpux11.h	2009-06-02 13:05:35.000000000 +0100
+++ gcc/config/pa/pa-hpux11.h	2009-06-02 13:06:09.000000000 +0100
@@ -104,8 +104,7 @@ #define CPP_SPEC \
    want dereferencing of a NULL pointer to cause a SEGV.  */
 #undef LINK_SPEC
 #define LINK_SPEC \
-  "%<fwhole-program\
-   %{!shared:%{p:-L/lib/libp -L/usr/lib/libp %{!static:\
+  "%{!shared:%{p:-L/lib/libp -L/usr/lib/libp %{!static:\
      %nWarning: consider linking with `-static' as system libraries with\n\
      %n  profiling support are only provided in archive format}}}\
    %{!shared:%{pg:-L/lib/libp -L/usr/lib/libp %{!static:\
Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	2009-06-02 13:05:35.000000000 +0100
+++ gcc/gcc.c	2009-06-02 13:26:45.000000000 +0100
@@ -4429,6 +4429,11 @@ set_collect_gcc_options (void)
       if ((switches[i].live_cond & SWITCH_IGNORE) != 0)
 	continue;
 
+      /* Don't use -fwhole-program when compiling the init and fini routines,
+	 since we'd wrongly assume that the routines aren't needed.  */
+      if (strcmp (switches[i].part1, "fwhole-program") == 0)
+	continue;
+
       obstack_grow (&collect_obstack, "'-", 2);
       q = switches[i].part1;
       while ((p = strchr (q, '\'')))

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [8/8] Tidy up testsuite handling of LD_LIBRARY_PATH (needs testsuite maintainer)
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
                   ` (6 preceding siblings ...)
  2009-06-02 12:29 ` [7/8] Don't compile collect2 init and fini routines with -fwhole-program Richard Sandiford
@ 2009-06-02 12:33 ` Richard Sandiford
  2009-06-02 18:01 ` [0/8] AIX cross toolchains Ralf Wildenhues
  8 siblings, 0 replies; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 12:33 UTC (permalink / raw)
  To: gcc-patches

This patch tries to tidy up (and tighten up) the runtime library paths
that we use during testing.  From an AIX standpoint, the two main problems
with the current paths are:

  (1) We often add the directories for all libgcc_s multilibs,
      not just the current multilib.

  (2) We often add the current directory to the path, either explicitly
      through "." or implicitly (and probably accidentally) by having
      empty path components like ":foo:bar:..." or "foo::bar:...".

This is redundant but harmless on most unixy targets, which skip
libraries that don't use the right ABI.  However, it's wrong on AIX
for two reasons:

  - We have separate multilibs for AIX threads and POSIX threads.
    This has led to the following special case in libgomp:

	# Add AIX pthread directory first.
	if { [llength [glob -nocomplain ${gccdir}/pthread/libgcc_s*.a]] >= 1 } {
	    append always_ld_library_path ":${gccdir}/pthread"
	}

    but the problem hits libstdc++ too.

  - AIX shared libraries are normal .a archives that have shared
    objects within them.  Archives aren't ABI-specific, and can even
    contain objects that follow different ABIs.  (E.g. you can put
    64-bit and 32-bit shared objects in the same archive.)  The idea of
    "skipping incompatible libraries" is therefore less well-defined
    than it is for other targets, and the loader doesn't try to do it.
    The upshot is that -maix64 tests run against the 32-bit libraries,
    causing every execution test to fail.

There are still some cases where we need "." to be in the path:

  - Some testsuites might build their own shared libraries and store
    them in the current directory.  There's nothing wrong with this
    _provided that_ "." doesn't also contain installable libraries
    for the default multilib.

    libjava falls into this category (and its "." is safe).

    I think the default should be not to be add "." to the path.
    The testsuites that really do need "." to be in the path
    should then add it explicitly, with a comment explaining why.

  - Some remote-testing setups copy libraries to the target's
    current directory.

    I think these setups should add "."  to the library paths themselves,
    such as by adding it to the appropriate environment variable.  Using
    "." can be actively harmful for other remote-testing setups.

The patch adds a new function, find_libgcc_s, that finds the
libgcc_s directory for the current multilib.  The patch also adds a
utility function called add_path for adding new components to a path.
This function is a no-op if the new component is empty, avoiding the
empty path problem mentioned in (2) above.

There's a further problem that I don't try to fix here.  When running
tests natively, we use the new library paths for both the compilation
and execution phases of a test.  This means that we run the compiler
itself with the new paths.  These days, the compilers (can) depend on
libgcc_s via libmpfr, and we'll end up using the newly-built libgcc_s
instead of the usual one.

Again, this probably isn't much of a problem on most unixy systems,
because the loader can skip objects that use the wrong ABI, and because
libgcc_s is supposed to be backwards-compatible.  But it causes problems
on AIX when the multilib you're testing is not the one that the compiler
itself uses, for the same reasons as above.

Tested on powerpc-ibm-aix6.1 and x86_64-linux-gnu.  OK to install?

Richard


gcc/testsuite/
	* lib/gcc-defs.exp (gcc-set-multilib-library-path): Delete.
	* lib/target-libpath.exp (ld_library_path_vars): New variable.
	(init_ld_library_path_env_vars): New function, replacing the
	orig_*_saved assignments.  Call it after defining it.
	(set_ld_library_path_env_vars): Rewrite to use ld_library_path_vars.
	(restore_ld_library_path_env_vars): Likewise.
	(add_path, find_libgcc_s): New functions.
	* lib/objc.exp (objc_init): Use find_libgcc_s instead of
	gcc-set-multilib-library-path.
	(objc_target_compile): Don't add "." to ld_library_path.
	Use add_path.
	* lib/gfortran.exp (gfortran_link_flags): Don't add "." to
	ld_library_path.  Use add_path.  Use find_libgcc_s instead of
	gcc-set-multilib-library-path.
	* lib/g++.exp (g++_link_flags): Likewise.
	* lib/obj-c++.exp (obj-c++_link_flags): Likewise.
	* lib/c-torture.exp: Do not manipulate ld_library_path at the
	top level; do it...
	(c-torture-execute): ...here instead.  Use $ld_library_path_multilib
	to tell when this needs to happen.  Use find_libgcc_s instead of
	gcc-set-multilib-library-path.
	* lib/gcc-dg.exp: Likewise.
	* lib/gnat.exp (gnat_target_compile): Don't add "." to ld_library_path.
	* g++.dg/compat/compat.exp (alt_ld_library_path): Don't add "."
	unless it is in $ALT_LD_LIBRARY_PATH.
	* g++.dg/compat/struct-layout-1.exp (alt_ld_library_path): Likewise.

libffi/
	* testsuite/lib/libffi-dg.exp (libffi-init): Don't add "."
	to ld_library_path.  Use add_path.  Add just find_libgcc_s
	to ld_library_path, not every libgcc multilib directory.

libgomp/
	* testsuite/lib/libgomp.exp (libgomp_init): Don't add "." to
	ld_library_path.  Use add_path.  Add just find_libgcc_s to
	ld_library_path, not every libgcc multilib directory.
	* testsuite/libgomp.c/c.exp (ld_library_path): Don't call
	gcc-set-multilib-library-path; rely on $always_ld_library_path instead.
	* testsuite/libgomp.c++/c++.exp (ld_library_path): Likewise.
	Use add_path.
	* testsuite/libgomp.fortran/fortran.exp (ld_library_path): Likewise.

libjava/
	* testsuite/lib/libjava.exp (libjava_init): Just add
	find_libgcc_s to libjava_libgcc_s_path, rather than every
	libgcc multilib directory.
	(libjava_arguments): Explain why we add "." to ld_library_path.
	(gcj_invoke, exec_gij, libjava_invoke): Use add_path.

libmudflap/
	* testsuite/lib/libmudflap.exp (libmudflap-init): Don't add "."
	to ld_library_path.  Use add_path.  Add just find_libgcc_s to
	ld_library_path, not every libgcc multilib directory.

libstdc++-v3/
	* testsuite/lib/libstdc++.exp (libstdc++_init): Don't add "."
	to ld_library_path.  Use add_path.  Add just find_libgcc_s to
	ld_library_path, not every libgcc multilib directory.

Index: gcc/testsuite/lib/gcc-defs.exp
===================================================================
--- gcc/testsuite/lib/gcc-defs.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/gcc-defs.exp	2009-06-02 13:06:11.000000000 +0100
@@ -233,35 +233,3 @@ proc dg-additional-files-options { optio
 
     return $options
 }
-
-# Return a colon-separate list of directories to search for libraries
-# for COMPILER, including multilib directories.
-
-proc gcc-set-multilib-library-path { compiler } {
-    global rootme
-
-    # ??? rootme will not be set when testing an installed compiler.
-    # In that case, we should perhaps use some other method to find
-    # libraries.
-    if {![info exists rootme]} {
-	return ""
-    }
-
-    set libpath ":${rootme}"
-    set compiler [lindex $compiler 0]
-    if { [is_remote host] == 0 && [which $compiler] != 0 } {
-	foreach i "[exec $compiler --print-multi-lib]" {
-	    set mldir ""
-	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-	    set mldir [string trimright $mldir "\;@"]
-	    if { "$mldir" == "." } {
-		continue
-	    }
-	    if { [llength [glob -nocomplain ${rootme}/${mldir}/libgcc_s*.so.*]] >= 1 } {
-		append libpath ":${rootme}/${mldir}"
-	    }
-	}
-    }
-
-    return $libpath
-}
Index: gcc/testsuite/lib/target-libpath.exp
===================================================================
--- gcc/testsuite/lib/target-libpath.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/target-libpath.exp	2009-06-02 13:06:11.000000000 +0100
@@ -16,175 +16,106 @@
 
 # This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca)
 
+# A list of ld library path environment variables that might need to be
+# defined.
+#
+# Some variables represent ABI-specific paths, and if these variables
+# aren't defined, the dynamic loader might fall back on a more general
+# variable.  We must do the same when trying to read the current setting
+# of such a path.  Each element of this list is therefore itself a list:
+# the first element of each sublist specifies the name of the variable,
+# and the other elements specify fallback alternatives.  We use FOO as a
+# shorthand for { FOO }.
+set ld_library_path_vars {
+    LD_LIBRARY_PATH
+    LD_RUN_PATH
+    SHLIB_PATH
+    { LD_LIBRARYN32_PATH LD_LIBRARY_PATH }
+    { LD_LIBRARY64_PATH LD_LIBRARY_PATH }
+    { LD_LIBRARY_PATH_32 LD_LIBRARY_PATH }
+    { LD_LIBRARY_PATH_64 LD_LIBRARY_PATH }
+    DYLD_LIBRARY_PATH
+}
+
+# Set up the global orig_FOO_saved variables.  We define this as a function
+# to avoid polluting the global namespace with local variables.
+proc init_ld_library_path_env_vars { } {
+    global ld_library_path_vars
+
+    foreach spec $ld_library_path_vars {
+	set var orig_[string tolower [lindex $spec 0]]_saved
+	global $var
+	set $var 0
+    }
+}
+init_ld_library_path_env_vars
 set orig_environment_saved 0
-set orig_ld_library_path_saved 0
-set orig_ld_run_path_saved 0
-set orig_shlib_path_saved 0
-set orig_ld_libraryn32_path_saved 0
-set orig_ld_library64_path_saved 0
-set orig_ld_library_path_32_saved 0
-set orig_ld_library_path_64_saved 0
-set orig_dyld_library_path_saved 0
 set orig_gcc_exec_prefix_saved 0
 set orig_gcc_exec_prefix_checked 0
-
+set ld_library_path_multilib unset
 
 #######################################
 # proc set_ld_library_path_env_vars { }
 #######################################
 
 proc set_ld_library_path_env_vars { } {
-  global ld_library_path
-  global orig_environment_saved
-  global orig_ld_library_path_saved
-  global orig_ld_run_path_saved
-  global orig_shlib_path_saved
-  global orig_ld_libraryn32_path_saved
-  global orig_ld_library64_path_saved
-  global orig_ld_library_path_32_saved
-  global orig_ld_library_path_64_saved
-  global orig_dyld_library_path_saved
-  global orig_gcc_exec_prefix_saved
-  global orig_gcc_exec_prefix_checked
-  global orig_ld_library_path
-  global orig_ld_run_path
-  global orig_shlib_path
-  global orig_ld_libraryn32_path
-  global orig_ld_library64_path
-  global orig_ld_library_path_32
-  global orig_ld_library_path_64
-  global orig_dyld_library_path
-  global orig_gcc_exec_prefix
-  global TEST_GCC_EXEC_PREFIX
-  global env
-
-  # Save the original GCC_EXEC_PREFIX.
-  if { $orig_gcc_exec_prefix_checked == 0 } {
-    if [info exists env(GCC_EXEC_PREFIX)] {
-      set orig_gcc_exec_prefix "$env(GCC_EXEC_PREFIX)"
-      set orig_gcc_exec_prefix_saved 1
-    }
-    set orig_gcc_exec_prefix_checked 1
-  }
-
-  # Set GCC_EXEC_PREFIX for the compiler under test to pick up files not in
-  # the build tree from a specified location (normally the install tree).
-  if [info exists TEST_GCC_EXEC_PREFIX] {
-    setenv GCC_EXEC_PREFIX "$TEST_GCC_EXEC_PREFIX"
-  }
-
-  # Setting the ld library path causes trouble when testing cross-compilers.
-  if { [is_remote target] } {
-    return
-  }
-
-  if { $orig_environment_saved == 0 } {
+    global ld_library_path
+    global orig_environment_saved
+    global ld_library_path_vars
+    global orig_gcc_exec_prefix_saved
+    global orig_gcc_exec_prefix_checked
+    global orig_gcc_exec_prefix
+    global TEST_GCC_EXEC_PREFIX
+    global ld_library_path_multilib
+    global env
+
+    # Save the original GCC_EXEC_PREFIX.
+    if { $orig_gcc_exec_prefix_checked == 0 } {
+	if [info exists env(GCC_EXEC_PREFIX)] {
+	    set orig_gcc_exec_prefix "$env(GCC_EXEC_PREFIX)"
+	    set orig_gcc_exec_prefix_saved 1
+	}
+	set orig_gcc_exec_prefix_checked 1
+    }
+
+    # Set GCC_EXEC_PREFIX for the compiler under test to pick up files not in
+    # the build tree from a specified location (normally the install tree).
+    if [info exists TEST_GCC_EXEC_PREFIX] {
+	setenv GCC_EXEC_PREFIX "$TEST_GCC_EXEC_PREFIX"
+    }
+
+    # Setting the ld library path causes trouble when testing cross-compilers.
+    if { [is_remote target] } {
+	return
+    }
+
+    set ld_library_path_multilib [board_info target multilib_flags]
+
+    foreach spec $ld_library_path_vars {
+	set var [lindex $spec 0]
+	set lvar [string tolower $var]
+
+	global orig_$lvar
+	global orig_${lvar}_saved
+
+	if { $orig_environment_saved == 0 } {
+	    if [info exists env($var)] {
+		set orig_$lvar [set env($var)]
+		set orig_${lvar}_saved 1
+	    }
+	}
+	set value $ld_library_path
+	foreach extra $spec {
+	    set lextra [string tolower $extra]
+	    if [set orig_${lextra}_saved] {
+		add_path value [set orig_$lextra]
+		break
+	    }
+	}
+	setenv $var $value
+    }
     set orig_environment_saved 1
-
-    # Save the original environment.
-    if [info exists env(LD_LIBRARY_PATH)] {
-      set orig_ld_library_path "$env(LD_LIBRARY_PATH)"
-      set orig_ld_library_path_saved 1
-    }
-    if [info exists env(LD_RUN_PATH)] {
-      set orig_ld_run_path "$env(LD_RUN_PATH)"
-      set orig_ld_run_path_saved 1
-    }
-    if [info exists env(SHLIB_PATH)] {
-      set orig_shlib_path "$env(SHLIB_PATH)"
-      set orig_shlib_path_saved 1
-    }
-    if [info exists env(LD_LIBRARYN32_PATH)] {
-      set orig_ld_libraryn32_path "$env(LD_LIBRARYN32_PATH)"
-      set orig_ld_libraryn32_path_saved 1
-    }
-    if [info exists env(LD_LIBRARY64_PATH)] {
-      set orig_ld_library64_path "$env(LD_LIBRARY64_PATH)"
-      set orig_ld_library64_path_saved 1
-    }
-    if [info exists env(LD_LIBRARY_PATH_32)] {
-      set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)"
-      set orig_ld_library_path_32_saved 1
-    }
-    if [info exists env(LD_LIBRARY_PATH_64)] {
-      set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)"
-      set orig_ld_library_path_64_saved 1
-    }
-    if [info exists env(DYLD_LIBRARY_PATH)] {
-      set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)"
-      set orig_dyld_library_path_saved 1
-    }
-  }
-
-  # We need to set ld library path in the environment.  Currently,
-  # unix.exp doesn't set the environment correctly for all systems.
-  # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a
-  # program.  We also need the environment set for compilations, etc.
-  #
-  # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but
-  # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH
-  # (for the 64-bit ABI).  The same applies to Darwin (DYLD_LIBRARY_PATH),
-  # Solaris 32 bit (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64),
-  # and HP-UX (SHLIB_PATH).  In some cases, the variables are independent
-  # of LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the
-  # variable is not defined.
-  #
-  # Doing this is somewhat of a hack as ld_library_path gets repeated in
-  # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables.
-  if { $orig_ld_library_path_saved } {
-    setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path"
-  } else {
-    setenv LD_LIBRARY_PATH "$ld_library_path"
-  }
-  if { $orig_ld_run_path_saved } {
-    setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path"
-  } else {
-    setenv LD_RUN_PATH "$ld_library_path"
-  }
-  # The default shared library dynamic path search for 64-bit
-  # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH.
-  # LD_LIBRARY_PATH isn't used for 32-bit executables.  Thus, we
-  # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent.
-  if { $orig_shlib_path_saved } {
-    setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path"
-  } else {
-    setenv SHLIB_PATH "$ld_library_path"
-  }
-  if { $orig_ld_libraryn32_path_saved } {
-    setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_libraryn32_path"
-  } elseif { $orig_ld_library_path_saved } {
-    setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_library_path"
-  } else {
-    setenv LD_LIBRARYN32_PATH "$ld_library_path"
-  }
-  if { $orig_ld_library64_path_saved } {
-    setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library64_path"
-  } elseif { $orig_ld_library_path_saved } {
-    setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library_path"
-  } else {
-    setenv LD_LIBRARY64_PATH "$ld_library_path"
-  }
-  if { $orig_ld_library_path_32_saved } {
-    setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32"
-  } elseif { $orig_ld_library_path_saved } {
-    setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path"
-  } else {
-    setenv LD_LIBRARY_PATH_32 "$ld_library_path"
-  }
-  if { $orig_ld_library_path_64_saved } {
-    setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64"
-  } elseif { $orig_ld_library_path_saved } {
-    setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path"
-  } else {
-    setenv LD_LIBRARY_PATH_64 "$ld_library_path"
-  }
-  if { $orig_dyld_library_path_saved } {
-    setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path"
-  } else {
-    setenv DYLD_LIBRARY_PATH "$ld_library_path"
-  }
-
-  verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path"
+    verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path"
 }
 
 #######################################
@@ -192,77 +123,35 @@ proc set_ld_library_path_env_vars { } {
 #######################################
 
 proc restore_ld_library_path_env_vars { } {
-  global orig_environment_saved
-  global orig_ld_library_path_saved
-  global orig_ld_run_path_saved
-  global orig_shlib_path_saved
-  global orig_ld_libraryn32_path_saved
-  global orig_ld_library64_path_saved
-  global orig_ld_library_path_32_saved
-  global orig_ld_library_path_64_saved
-  global orig_dyld_library_path_saved
-  global orig_gcc_exec_prefix_saved
-  global orig_ld_library_path
-  global orig_ld_run_path
-  global orig_shlib_path
-  global orig_ld_libraryn32_path
-  global orig_ld_library64_path
-  global orig_ld_library_path_32
-  global orig_ld_library_path_64
-  global orig_dyld_library_path
-  global orig_gcc_exec_prefix
-  global env
-
-  if { $orig_gcc_exec_prefix_saved } {
-    setenv GCC_EXEC_PREFIX "$orig_gcc_exec_prefix"
-  } elseif [info exists env(GCC_EXEC_PREFIX)] {
-    unsetenv GCC_EXEC_PREFIX
-  }
-
-  if { $orig_environment_saved == 0 } {
-    return
-  }
-
-  if { $orig_ld_library_path_saved } {
-    setenv LD_LIBRARY_PATH "$orig_ld_library_path"
-  } elseif [info exists env(LD_LIBRARY_PATH)] {
-    unsetenv LD_LIBRARY_PATH
-  }
-  if { $orig_ld_run_path_saved } {
-    setenv LD_RUN_PATH "$orig_ld_run_path"
-  } elseif [info exists env(LD_RUN_PATH)] {
-    unsetenv LD_RUN_PATH
-  }
-  if { $orig_shlib_path_saved } {
-    setenv SHLIB_PATH "$orig_shlib_path"
-  } elseif [info exists env(SHLIB_PATH)] {
-    unsetenv SHLIB_PATH
-  }
-  if { $orig_ld_libraryn32_path_saved } {
-    setenv LD_LIBRARYN32_PATH "$orig_ld_libraryn32_path"
-  } elseif [info exists env(LD_LIBRARYN32_PATH)] {
-    unsetenv LD_LIBRARYN32_PATH
-  }
-  if { $orig_ld_library64_path_saved } {
-    setenv LD_LIBRARY64_PATH "$orig_ld_library64_path"
-  } elseif [info exists env(LD_LIBRARY64_PATH)] {
-    unsetenv LD_LIBRARY64_PATH
-  }
-  if { $orig_ld_library_path_32_saved } {
-    setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32"
-  } elseif [info exists env(LD_LIBRARY_PATH_32)] {
-    unsetenv LD_LIBRARY_PATH_32
-  }
-  if { $orig_ld_library_path_64_saved } {
-    setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64"
-  } elseif [info exists env(LD_LIBRARY_PATH_64)] {
-    unsetenv LD_LIBRARY_PATH_64
-  }
-  if { $orig_dyld_library_path_saved } {
-    setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path"
-  } elseif [info exists env(DYLD_LIBRARY_PATH)] {
-    unsetenv DYLD_LIBRARY_PATH
-  }
+    global orig_environment_saved
+    global ld_library_path_vars
+    global orig_gcc_exec_prefix_saved
+    global orig_gcc_exec_prefix
+    global env
+
+    if { $orig_gcc_exec_prefix_saved } {
+	setenv GCC_EXEC_PREFIX "$orig_gcc_exec_prefix"
+    } elseif [info exists env(GCC_EXEC_PREFIX)] {
+	unsetenv GCC_EXEC_PREFIX
+    }
+
+    if { $orig_environment_saved == 0 } {
+	return
+    }
+
+    foreach spec $ld_library_path_vars {
+	set var [lindex $spec 0]
+	set lvar [string tolower $var]
+
+	global orig_$lvar
+	global orig_${lvar}_saved
+
+	if [set orig_${lvar}_saved] {
+	    setenv $var [set orig_$lvar]
+	} elseif [info exists env($var)] {
+	    unsetenv $var
+	}
+    }
 }
 
 #######################################
@@ -284,3 +173,46 @@ proc get_shlib_extension { } {
     return $shlib_ext
 }
 
+# If DIR is not an empty string, add it to the end of variable UPPATH,
+# which represents a colon-separated path.
+proc add_path { uppath dir } {
+    upvar $uppath path
+
+    if { $dir != "" } {
+	if { [info exists path] && $path != "" } {
+	    append path ":"
+	}
+	append path $dir
+    }
+}
+
+# Return the directory that contains the shared libgcc for this multilib,
+# or "" if we don't know.
+proc find_libgcc_s { compiler } {
+    # Remote host testing requires an installed compiler (get_multilibs
+    # imposes the same restriction).  It is up to the board file or
+    # tester to make sure that the installed compiler's libraries
+    # can be found in the library path.
+    if { [is_remote host] } {
+	return ""
+    }
+    # The same goes if we can't find the compiler.
+    set compiler_path [which [lindex $compiler 0]]
+    if { $compiler_path == "" } {
+	return ""
+    }
+    # Run the compiler with the current multilib flags to get the
+    # relative multilib directory.
+    set subdir [eval exec $compiler [board_info target multilib_flags] \
+		    --print-multi-directory]
+    # We are only interested in cases where libgcc_s is in the same
+    # directory as the compiler itself.
+    set dir [file dirname $compiler_path]
+    if { $subdir != "." } {
+	set dir [file join $dir $subdir]
+    }
+    if { ![file exists $dir] } {
+	return ""
+    }
+    return $dir
+}
Index: gcc/testsuite/lib/objc.exp
===================================================================
--- gcc/testsuite/lib/objc.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/objc.exp	2009-06-02 13:06:11.000000000 +0100
@@ -121,7 +121,7 @@ proc objc_init { args } {
 
     objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o"
 
-    set objc_libgcc_s_path [gcc-set-multilib-library-path $OBJC_UNDER_TEST]
+    set objc_libgcc_s_path [find_libgcc_s $OBJC_UNDER_TEST]
 }
 
 proc objc_target_compile { source dest type options } {
@@ -135,7 +135,7 @@ proc objc_target_compile { source dest t
     global objc_libgcc_s_path
     global shlib_ext
 
-    set ld_library_path ".:${objc_libgcc_s_path}"
+    set ld_library_path ${objc_libgcc_s_path}
     lappend options "libs=-lobjc"
     set shlib_ext [get_shlib_extension]
     verbose "shared lib extension: $shlib_ext"
@@ -191,7 +191,7 @@ proc objc_target_compile { source dest t
 	set libobjc_dir [file dirname ${libobjc_dir}]
 	set objc_link_flags "-L${libobjc_dir}"
 	lappend options "additional_flags=${objc_link_flags}"
-	append ld_library_path ":${libobjc_dir}"
+	add_path ld_library_path ${libobjc_dir}
     }
     if { $type == "precompiled_header" } {
 	# If we generating a precompiled header, we have say this is an
Index: gcc/testsuite/lib/gfortran.exp
===================================================================
--- gcc/testsuite/lib/gfortran.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/gfortran.exp	2009-06-02 13:06:11.000000000 +0100
@@ -84,7 +84,7 @@ proc gfortran_link_flags { paths } {
     set gccpath ${paths}
     set libio_dir ""
     set flags ""
-    set ld_library_path "."
+    set ld_library_path ""
     set shlib_ext [get_shlib_extension]
     verbose "shared lib extension: $shlib_ext"
 
@@ -94,11 +94,11 @@ proc gfortran_link_flags { paths } {
           # for uninstalled testing.
           append flags "-B${gccpath}/libgfortran/.libs "
           append flags "-L${gccpath}/libgfortran/.libs "
-          append ld_library_path ":${gccpath}/libgfortran/.libs"
+	  add_path ld_library_path "${gccpath}/libgfortran/.libs"
       }
       if [file exists "${gccpath}/libgfortran/.libs/libgfortran.${shlib_ext}"] {
 	  append flags "-L${gccpath}/libgfortran/.libs "
-	  append ld_library_path ":${gccpath}/libgfortran/.libs"
+	  add_path ld_library_path "${gccpath}/libgfortran/.libs"
       }
       if [file exists "${gccpath}/libgfortran/libgforbegin.a"] {
           append flags "-L${gccpath}/libgfortran "
@@ -106,8 +106,7 @@ proc gfortran_link_flags { paths } {
       if [file exists "${gccpath}/libiberty/libiberty.a"] {
           append flags "-L${gccpath}/libiberty "
       }
-      append ld_library_path \
-	[gcc-set-multilib-library-path $GFORTRAN_UNDER_TEST]
+      add_path ld_library_path [find_libgcc_s $GFORTRAN_UNDER_TEST]
     }
 
     set_ld_library_path_env_vars
Index: gcc/testsuite/lib/g++.exp
===================================================================
--- gcc/testsuite/lib/g++.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/g++.exp	2009-06-02 13:06:11.000000000 +0100
@@ -106,52 +106,51 @@ proc g++_link_flags { paths } {
     set gccpath ${paths}
     set libio_dir ""
     set flags ""
-    set ld_library_path "."
+    set ld_library_path ""
 
     set shlib_ext [get_shlib_extension]
     verbose "shared lib extension: $shlib_ext"
 
     if { $gccpath != "" } {
       if [file exists "${gccpath}/lib/libstdc++.a"] {
-          append ld_library_path ":${gccpath}/lib"
+	  add_path ld_library_path "${gccpath}/lib"
       }
       if [file exists "${gccpath}/libg++/libg++.a"] {
           append flags "-L${gccpath}/libg++ "
-          append ld_library_path ":${gccpath}/libg++"
+	  add_path ld_library_path "${gccpath}/libg++"
       }
       if [file exists "${gccpath}/libstdc++/libstdc++.a"] {
           append flags "-L${gccpath}/libstdc++ "
-          append ld_library_path ":${gccpath}/libstdc++"
+	  add_path ld_library_path "${gccpath}/libstdc++"
       }
       if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] {
           append flags " -L${gccpath}/libstdc++-v3/src/.libs "
-          append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs"
+	  add_path ld_library_path "${gccpath}/libstdc++-v3/src/.libs"
       }
       # Look for libstdc++.${shlib_ext}.
       if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] {
 	  append flags " -L${gccpath}/libstdc++-v3/src/.libs "
-	  append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs"
+	  add_path ld_library_path "${gccpath}/libstdc++-v3/src/.libs"
       }
-
       if [file exists "${gccpath}/libiberty/libiberty.a"] {
           append flags "-L${gccpath}/libiberty "
       }
       if [file exists "${gccpath}/librx/librx.a"] {
           append flags "-L${gccpath}/librx "
       }
-      append ld_library_path [gcc-set-multilib-library-path $GXX_UNDER_TEST]
+      add_path ld_library_path [find_libgcc_s $GXX_UNDER_TEST]
     } else {
       global tool_root_dir
 
       set libgpp [lookfor_file ${tool_root_dir} libg++]
       if { $libgpp != "" } {
           append flags "-L${libgpp} "
-          append ld_library_path ":${libgpp}"
+	  add_path ld_library_path ${libgpp}
       }
       set libstdcpp [lookfor_file ${tool_root_dir} libstdc++]
       if { $libstdcpp != "" } {
           append flags "-L${libstdcpp} "
-          append ld_library_path ":${libstdcpp}"
+	  add_path ld_library_path ${libstdcpp}
       }
       set libiberty [lookfor_file ${tool_root_dir} libiberty]
       if { $libiberty != "" } {
Index: gcc/testsuite/lib/obj-c++.exp
===================================================================
--- gcc/testsuite/lib/obj-c++.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/obj-c++.exp	2009-06-02 13:06:11.000000000 +0100
@@ -106,30 +106,30 @@ proc obj-c++_link_flags { paths } {
     set gccpath ${paths}
     set libio_dir ""
     set flags ""
-    set ld_library_path "."
+    set ld_library_path ""
     set shlib_ext [get_shlib_extension]
     verbose "shared lib extension: $shlib_ext"
 
     if { $gccpath != "" } {
       if [file exists "${gccpath}/lib/libstdc++.a"] {
-          append ld_library_path ":${gccpath}/lib"
+	  add_path ld_library_path "${gccpath}/lib"
       }
       if [file exists "${gccpath}/libg++/libg++.a"] {
           append flags "-L${gccpath}/libg++ "
-          append ld_library_path ":${gccpath}/libg++"
+	  add_path ld_library_path "${gccpath}/libg++"
       }
       if [file exists "${gccpath}/libstdc++/libstdc++.a"] {
           append flags "-L${gccpath}/libstdc++ "
-          append ld_library_path ":${gccpath}/libstdc++"
+	  add_path ld_library_path "${gccpath}/libstdc++"
       }
       if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] {
           append flags " -L${gccpath}/libstdc++-v3/src/.libs "
-          append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs"
+	  add_path ld_library_path "${gccpath}/libstdc++-v3/src/.libs"
       }
       # Look for libstdc++.${shlib_ext}.
       if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] {
 	  append flags " -L${gccpath}/libstdc++-v3/src/.libs "
-	  append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs"
+	  add_path ld_library_path "${gccpath}/libstdc++-v3/src/.libs"
       }
       if [file exists "${gccpath}/libiberty/libiberty.a"] {
           append flags "-L${gccpath}/libiberty "
@@ -158,23 +158,21 @@ proc obj-c++_link_flags { paths } {
       if { $libobjc_dir != "" } {
 	  set libobjc_dir [file dirname ${libobjc_dir}]
 	  append flags "-L${libobjc_dir}"
-	  append ld_library_path ":${libobjc_dir}"
+	  add_path ld_library_path ${libobjc_dir}
       }
-      append ld_library_path \
-	  [gcc-set-multilib-library-path $OBJCXX_UNDER_TEST]
-
+      add_path ld_library_path [find_libgcc_s $OBJCXX_UNDER_TEST]
     } else {
       global tool_root_dir;
 
       set libgpp [lookfor_file ${tool_root_dir} libg++];
       if { $libgpp != "" } {
           append flags "-L${libgpp} ";
-          append ld_library_path ":${libgpp}"
+	  add_path ld_library_path ${libgpp}
       }
       set libstdcpp [lookfor_file ${tool_root_dir} libstdc++];
       if { $libstdcpp != "" } {
           append flags "-L${libstdcpp} ";
-          append ld_library_path ":${libstdcpp}"
+	  add_path ld_library_path ${libstdcpp}
       }
       set libiberty [lookfor_file ${tool_root_dir} libiberty];
       if { $libiberty != "" } {
Index: gcc/testsuite/lib/c-torture.exp
===================================================================
--- gcc/testsuite/lib/c-torture.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/c-torture.exp	2009-06-02 13:06:11.000000000 +0100
@@ -54,15 +54,6 @@ if ![info exists GCC_UNDER_TEST] {
     set GCC_UNDER_TEST "[find_gcc]"
 }
 
-global orig_environment_saved
-
-# This file may be sourced, so don't override environment settings
-# that have been previously setup.
-if { $orig_environment_saved == 0 } {
-    append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
-    set_ld_library_path_env_vars
-}
-
 #
 # c-torture-compile -- runs the Tege C-torture test
 #
@@ -108,6 +99,13 @@ proc c-torture-compile { src option } {
 #
 proc c-torture-execute { sources args } {
     global tmpdir tool srcdir output compiler_conditional_xfail_data
+    global ld_library_path ld_library_path_multilib GCC_UNDER_TEST
+
+    if { "$ld_library_path_multilib"
+	 != "[board_info target multilib_flags]" } {
+	set ld_library_path [find_libgcc_s $GCC_UNDER_TEST]
+	set_ld_library_path_env_vars
+    }
 
     # Use the first source filename given as the filename under test.
     set src [lindex $sources 0]
Index: gcc/testsuite/lib/gcc-dg.exp
===================================================================
--- gcc/testsuite/lib/gcc-dg.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/gcc-dg.exp	2009-06-02 13:06:11.000000000 +0100
@@ -65,15 +65,6 @@ if ![info exists GCC_UNDER_TEST] {
     set GCC_UNDER_TEST "[find_gcc]"
 }
 
-global orig_environment_saved
-
-# This file may be sourced, so don't override environment settings
-# that have been previously setup.
-if { $orig_environment_saved == 0 } {
-    append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
-    set_ld_library_path_env_vars
-}
-
 # Define gcc callbacks for dg.exp.
 
 proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } {
@@ -117,6 +108,14 @@ proc gcc-dg-test-1 { target_compile prog
 	    set output_file "[file rootname [file tail $prog]].o"
 	}
 	"run" {
+	    global ld_library_path ld_library_path_multilib GCC_UNDER_TEST
+
+	    if { "$ld_library_path_multilib"
+		 != "[board_info target multilib_flags]" } {
+		set ld_library_path [find_libgcc_s $GCC_UNDER_TEST]
+		set_ld_library_path_env_vars
+	    }
+
 	    set compile_type "executable"
 	    # FIXME: "./" is to cope with "." not being in $PATH.
 	    # Should this be handled elsewhere?
Index: gcc/testsuite/lib/gnat.exp
===================================================================
--- gcc/testsuite/lib/gnat.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/lib/gnat.exp	2009-06-02 13:06:11.000000000 +0100
@@ -147,7 +147,7 @@ proc gnat_target_compile { source dest t
         set GNAT_UNDER_TEST "$GNAT_UNDER_TEST_ORIG $gnat_rts_opt"
     }
 
-    set ld_library_path ".:${gnat_libgcc_s_path}"
+    set ld_library_path ${gnat_libgcc_s_path}
     lappend options "compiler=$GNAT_UNDER_TEST -q -f"
     lappend options "timeout=[timeout_value]"
 
Index: gcc/testsuite/g++.dg/compat/compat.exp
===================================================================
--- gcc/testsuite/g++.dg/compat/compat.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/g++.dg/compat/compat.exp	2009-06-02 13:06:11.000000000 +0100
@@ -103,14 +103,14 @@ set sid "cp_compat"
 # are different.
 set use_alt 0
 set same_alt 0
-set alt_ld_library_path "."
+set alt_ld_library_path ""
 if [info exists ALT_CXX_UNDER_TEST] then {
     set use_alt 1
     if [string match "same" $ALT_CXX_UNDER_TEST] then {
 	set same_alt 1
     } else {
 	if [info exists ALT_LD_LIBRARY_PATH] then {
-	    append alt_ld_library_path ":${ALT_LD_LIBRARY_PATH}"
+	    set alt_ld_library_path $ALT_LD_LIBRARY_PATH
 	}
     }
 }
Index: gcc/testsuite/g++.dg/compat/struct-layout-1.exp
===================================================================
--- gcc/testsuite/g++.dg/compat/struct-layout-1.exp	2009-06-02 13:05:35.000000000 +0100
+++ gcc/testsuite/g++.dg/compat/struct-layout-1.exp	2009-06-02 13:06:11.000000000 +0100
@@ -109,14 +109,14 @@ set sid "cp_compat"
 # are different.
 set use_alt 0
 set same_alt 0
-set alt_ld_library_path "."
+set alt_ld_library_path ""
 if [info exists ALT_CXX_UNDER_TEST] then {
     set use_alt 1
     if [string match "same" $ALT_CXX_UNDER_TEST] then {
 	set same_alt 1
     } else {
 	if [info exists ALT_LD_LIBRARY_PATH] then {
-	    append alt_ld_library_path ":${ALT_LD_LIBRARY_PATH}"
+	    set alt_ld_library_path $ALT_LD_LIBRARY_PATH
 	}
     }
 }
Index: libffi/testsuite/lib/libffi-dg.exp
===================================================================
--- libffi/testsuite/lib/libffi-dg.exp	2009-06-02 13:05:35.000000000 +0100
+++ libffi/testsuite/lib/libffi-dg.exp	2009-06-02 13:06:11.000000000 +0100
@@ -108,32 +108,11 @@ proc libffi-init { args } {
     verbose "libstdc++ $blddircxx"
 
     set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
-    if {$gccdir != ""} {
-	set gccdir [file dirname $gccdir]
-    }
-    verbose "gccdir $gccdir"
-
-    set ld_library_path "."
-    append ld_library_path ":${gccdir}"
-
-    set compiler "${gccdir}/xgcc"
-    if { [is_remote host] == 0 && [which $compiler] != 0 } {
-	foreach i "[exec $compiler --print-multi-lib]" {
-	    set mldir ""
-	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-	    set mldir [string trimright $mldir "\;@"]
-	    if { "$mldir" == "." } {
-		continue
-	    }
-	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
-		append ld_library_path ":${gccdir}/${mldir}"
-	    }
-	}
-    }
+    add_path ld_library_path [find_libgcc_s "$gccdir/xgcc"]
     # add the library path for libffi.
-    append ld_library_path ":${blddirffi}/.libs"
+    add_path ld_library_path "${blddirffi}/.libs"
     # add the library path for libstdc++ as well.
-    append ld_library_path ":${blddircxx}/src/.libs"
+    add_path ld_library_path "${blddircxx}/src/.libs"
 
     verbose "ld_library_path: $ld_library_path"
 
Index: libgomp/testsuite/lib/libgomp.exp
===================================================================
--- libgomp/testsuite/lib/libgomp.exp	2009-06-02 13:05:35.000000000 +0100
+++ libgomp/testsuite/lib/libgomp.exp	2009-06-02 13:06:11.000000000 +0100
@@ -86,39 +86,8 @@ proc libgomp_init { args } {
 	set CFLAGS ""
     }
 
-    # Locate libgcc.a so we don't need to account for different values of
-    # SHLIB_EXT on different platforms
-    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
-    if {$gccdir != ""} {
-        set gccdir [file dirname $gccdir]
-    }
-
-    # Compute what needs to be put into LD_LIBRARY_PATH
-    set always_ld_library_path ".:${blddir}/.libs"
-
-    # Compute what needs to be added to the existing LD_LIBRARY_PATH.
-    if {$gccdir != ""} {
-	# Add AIX pthread directory first.
-	if { [llength [glob -nocomplain ${gccdir}/pthread/libgcc_s*.a]] >= 1 } {
-	    append always_ld_library_path ":${gccdir}/pthread"
-	}
-	append always_ld_library_path ":${gccdir}"
-	set compiler [lindex $GCC_UNDER_TEST 0]
-
-	if { [is_remote host] == 0 && [which $compiler] != 0 } {
-	  foreach i "[exec $compiler --print-multi-lib]" {
-	    set mldir ""
-	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-	    set mldir [string trimright $mldir "\;@"]
-	    if { "$mldir" == "." } {
-	      continue
-	    }
-	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
-	      append always_ld_library_path ":${gccdir}/${mldir}"
-	    }
-	  }
-	}
-    }
+    set always_ld_library_path "${blddir}/.libs"
+    add_path always_ld_library_path [find_libgcc_s $GCC_UNDER_TEST]
 
     set ALWAYS_CFLAGS ""
     if { $blddir != "" } {
Index: libgomp/testsuite/libgomp.c/c.exp
===================================================================
--- libgomp/testsuite/libgomp.c/c.exp	2009-06-02 13:05:35.000000000 +0100
+++ libgomp/testsuite/libgomp.c/c.exp	2009-06-02 13:06:11.000000000 +0100
@@ -20,7 +20,6 @@ dg-init
 set tests [lsort [find $srcdir/$subdir *.c]]
 
 set ld_library_path $always_ld_library_path
-append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
 set_ld_library_path_env_vars
 
 # Main loop.
Index: libgomp/testsuite/libgomp.c++/c++.exp
===================================================================
--- libgomp/testsuite/libgomp.c++/c++.exp	2009-06-02 13:05:35.000000000 +0100
+++ libgomp/testsuite/libgomp.c++/c++.exp	2009-06-02 13:06:11.000000000 +0100
@@ -37,12 +37,10 @@ if { $lang_test_file_found } {
     # Gather a list of all tests.
     set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]]
 
+    set ld_library_path $always_ld_library_path
     if { $blddir != "" } {
-        set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
-    } else {
-        set ld_library_path "$always_ld_library_path"
+	add_path ld_library_path "${blddir}/${lang_library_path}"
     }
-    append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
     set_ld_library_path_env_vars
 
     set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags"
Index: libgomp/testsuite/libgomp.fortran/fortran.exp
===================================================================
--- libgomp/testsuite/libgomp.fortran/fortran.exp	2009-06-02 13:05:35.000000000 +0100
+++ libgomp/testsuite/libgomp.fortran/fortran.exp	2009-06-02 13:06:11.000000000 +0100
@@ -26,12 +26,10 @@ if { $lang_test_file_found } {
     # Gather a list of all tests.
     set tests [lsort [find $srcdir/$subdir *.\[fF\]{,90,95,03,08}]]
 
+    set ld_library_path $always_ld_library_path
     if { $blddir != "" } {
-        set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
-    } else {
-        set ld_library_path "$always_ld_library_path"
+	add_path ld_library_path "${blddir}/${lang_library_path}"
     }
-    append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
     set_ld_library_path_env_vars
 
     # Main loop.
Index: libjava/testsuite/lib/libjava.exp
===================================================================
--- libjava/testsuite/lib/libjava.exp	2009-06-02 13:05:35.000000000 +0100
+++ libjava/testsuite/lib/libjava.exp	2009-06-02 13:06:11.000000000 +0100
@@ -197,36 +197,8 @@ proc libjava_init { args } {
     }
 
     # Finally, add the gcc build directory so that we can find the
-    # shared libgcc.  This, like much of dejagnu, is hideous.
-    set libjava_libgcc_s_path {}
-
-    if { [istarget "*-*-darwin*"] } {
-	set so_extension "dylib"
-    } elseif { [istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"] } {
-	set so_extension "dll"
-    } else {
-	set so_extension "so"
-    }
-    set gccdir [lookfor_file $tool_root_dir gcc/libgcc_s.${so_extension}]
-    if {$gccdir != ""} {
-	set gccdir [file dirname $gccdir]
-	lappend libjava_libgcc_s_path $gccdir
-	verbose "libjava_libgcc_s_path = $libjava_libgcc_s_path"
-	set compiler ${gccdir}/xgcc
-	if { [is_remote host] == 0 && [which $compiler] != 0 } {
-	    foreach i "[exec $compiler --print-multi-lib]" {
-		set mldir ""
-		regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-		set mldir [string trimright $mldir "\;@"]
-		if { "$mldir" == "." } {
-		    continue
-		}
-		if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.${so_extension}.*]] >= 1 } {
-		    lappend libjava_libgcc_s_path "${gccdir}/${mldir}"
-		}
-	    }
-	}
-    }
+    # shared libgcc.
+    set libjava_libgcc_s_path [find_libgcc_s $GCJ_UNDER_TEST]
 
     set libjava_initialized 1
 }
@@ -337,6 +309,8 @@ proc libjava_arguments {{mode compile}} 
     # Basically we want to build up a colon separated path list from
     # the value of $libjava.
 
+    # Add "." to the list so that we pick up shared libraries created
+    # by the testsuite itself.
     set lpath "."
     foreach dir [list $libjava] {
 	foreach item [split $dir " "] {
@@ -470,8 +444,8 @@ proc gcj_invoke {program expectFile ld_l
   global ld_library_path
 
   set ld_library_path "$libjava_ld_library_path"
-  if {[llength $ld_library_additions] > 0} {
-    append ld_library_path :[join $ld_library_additions :]
+  foreach path $ld_library_additions {
+    add_path ld_library_path $path
   }
 
   set_ld_library_path_env_vars
@@ -512,8 +486,8 @@ proc exec_gij {jarfile expectFile {ld_li
   global ld_library_path
 
   set ld_library_path "$libjava_ld_library_path"
-  if {[llength $ld_library_additions] > 0} {
-  append ld_library_path :[join $ld_library_additions :]
+  foreach path $ld_library_additions {
+    add_path ld_library_path $path
   }
 	
   set_ld_library_path_env_vars
@@ -562,8 +536,8 @@ proc libjava_invoke {errname testName op
     global ld_library_path
 
     set ld_library_path "$libjava_ld_library_path"
-    if {[llength $ld_library_additions] > 0} {
-	append ld_library_path :[join $ld_library_additions :]
+    foreach path $ld_library_additions {
+	add_path ld_library_path $path
     }
 
     set_ld_library_path_env_vars
Index: libmudflap/testsuite/lib/libmudflap.exp
===================================================================
--- libmudflap/testsuite/lib/libmudflap.exp	2009-06-02 13:05:35.000000000 +0100
+++ libmudflap/testsuite/lib/libmudflap.exp	2009-06-02 13:06:11.000000000 +0100
@@ -60,28 +60,9 @@ proc libmudflap-init { language } {
     # set LD_LIBRARY_PATH so that libgcc_s, libstdc++ binaries can be found.
     # locate libgcc.a so we don't need to account for different values of
     # SHLIB_EXT on different platforms
-    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
-    if {$gccdir != ""} {
-	set gccdir [file dirname $gccdir]
-    }
-
-    set ld_library_path "."
-    append ld_library_path ":${gccdir}"
-    append ld_library_path ":${cxxblddir}/src/.libs"
-    if {[is_remote host] == 0} {
-	foreach i "[exec ${gccdir}/xgcc --print-multi-lib]" {
-	    set mldir ""
-	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-	    set mldir [string trimright $mldir "\;@"]
-	    if { "$mldir" == "." } {
-		continue
-	    }
-	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
-		append ld_library_path ":${gccdir}/${mldir}"
-	    }
-	}
-    }
-    append ld_library_path ":${blddir}/.libs"
+    set ld_library_path [find_libgcc_s $cxx]
+    add_path ld_library_path "${cxxblddir}/src/.libs"
+    add_path ld_library_path "${blddir}/.libs"
 
     set libs "-L${blddir}/.libs"
     set cxxflags "-ggdb3 -DDEBUG_ASSERT"
Index: libstdc++-v3/testsuite/lib/libstdc++.exp
===================================================================
--- libstdc++-v3/testsuite/lib/libstdc++.exp	2009-06-02 13:05:35.000000000 +0100
+++ libstdc++-v3/testsuite/lib/libstdc++.exp	2009-06-02 13:06:11.000000000 +0100
@@ -132,7 +132,6 @@ proc libstdc++_init { testfile } {
     set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
     if {$gccdir != ""} {
         set gccdir [file dirname $gccdir]
-	append ld_library_path_tmp ":${gccdir}"
     }
     v3track gccdir 3
 
@@ -142,7 +141,7 @@ proc libstdc++_init { testfile } {
     if {$libgompdir != ""} {
 	set v3-libgomp 1
         set libgompdir [file dirname $libgompdir]
-	append ld_library_path_tmp ":${libgompdir}"
+	add_path ld_library_path_tmp ${libgompdir}
 	verbose -log "libgomp support detected"
     }
     v3track libgompdir 3
@@ -162,22 +161,8 @@ proc libstdc++_init { testfile } {
     if {$gccdir != ""} {
 	set compiler ${gccdir}/g++
 	set ld_library_path ${ld_library_path_tmp}
-	append ld_library_path ":${blddir}/src/.libs"
-
-	if { [is_remote host] == 0 && [which $compiler] != 0 } {
-	  foreach i "[exec $compiler --print-multi-lib]" {
-	    set mldir ""
-	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
-	    set mldir [string trimright $mldir "\;@"]
-	    if { "$mldir" == "." } {
-	      continue
-	    }
-	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
-	      append ld_library_path ":${gccdir}/${mldir}"
-	    }
-	  }
-	}
-
+	add_path ld_library_path "${blddir}/src/.libs"
+	add_path ld_library_path [find_libgcc_s $compiler]
 	set_ld_library_path_env_vars
 	if [info exists env(LD_LIBRARY_PATH)] {
 	  verbose -log "LD_LIBRARY_PATH = $env(LD_LIBRARY_PATH)"

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [2/8] Handle sysroots on AIX (needs build-system maintainer)
  2009-06-02 12:10 ` [2/8] Handle sysroots on AIX (needs build-system maintainer) Richard Sandiford
@ 2009-06-02 12:58   ` Paolo Bonzini
  0 siblings, 0 replies; 19+ messages in thread
From: Paolo Bonzini @ 2009-06-02 12:58 UTC (permalink / raw)
  To: gcc-patches, richards

Ok for gcc/Makefile.in.

Paolo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [1/8] Don't build newlib for AIX
  2009-06-02 12:05 ` [1/8] Don't build newlib for AIX Richard Sandiford
@ 2009-06-02 12:58   ` Paolo Bonzini
  0 siblings, 0 replies; 19+ messages in thread
From: Paolo Bonzini @ 2009-06-02 12:58 UTC (permalink / raw)
  To: gcc-patches, richards

Ok.

Paolo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [3/8] Fix premature post-increment in collect2.c
  2009-06-02 12:11 ` [3/8] Fix premature post-increment in collect2.c Richard Sandiford
@ 2009-06-02 14:14   ` Ian Lance Taylor
  2009-06-02 19:06     ` Richard Sandiford
  0 siblings, 1 reply; 19+ messages in thread
From: Ian Lance Taylor @ 2009-06-02 14:14 UTC (permalink / raw)
  To: gcc-patches; +Cc: richards

Richard Sandiford <richards@transitive.com> writes:

> 	* collect2.c (ignore_library): Avoid premature post-increment
> 	and null deference.
>
> Index: gcc/collect2.c
> ===================================================================
> --- gcc/collect2.c	2009-06-02 13:05:46.000000000 +0100
> +++ gcc/collect2.c	2009-06-02 13:06:04.000000000 +0100
> @@ -2444,8 +2444,9 @@ static int ignore_library (const char *)
>  ignore_library (const char *name)
>  {
>    const char *const *p = &aix_std_libs[0];
> -  while (*p++ != NULL)
> -    if (! strcmp (name, *p)) return 1;
> +  while (*p)
> +    if (! strcmp (name, *p++))
> +      return 1;

Burying the postincrement in the argument to a function call doesn't
seem like a big step forward in clarity.  I would write something more
like

  const char *const *p;
  for (p = &aix_std_libs[0]; *p != NULL; ++p)
    if (strcmp (name, *p) == 0)
      return 1;

I won't insist on that change.  This is OK either way.

Ian

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [4/8] Implement the ldopen() family of routines for cross collect2s
  2009-06-02 12:20 ` [4/8] Implement the ldopen() family of routines for cross collect2s Richard Sandiford
@ 2009-06-02 14:28   ` Ian Lance Taylor
  0 siblings, 0 replies; 19+ messages in thread
From: Ian Lance Taylor @ 2009-06-02 14:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: richards

Richard Sandiford <richards@transitive.com> writes:

> gcc/
> 	* Makefile.in (COLLECT2_OBJS): Add collect2-aix.o.
> 	(collect2.o): Depend on collect2-aix.h.
> 	(collect2-aix.o): New rule.
> 	* collect2-aix.h: New file.
> 	* collect2-aix.c: Likewise.
> 	* collect2.c: Include collect-aix.h.  Don't undefine OBJECT_FORMAT_COFF
> 	if CROSS_AIX_SUPPORT is defined.  Guard native includes with
> 	#ifndef CROSS_DIRECTORY_STRUCTURE.  Use TARGET_AIX_VERSION
> 	instead of _AIX51.
> 	* config/rs6000/aix43.h (TARGET_AIX_VERSION): Define.
> 	* config/rs6000/aix51.h (TARGET_AIX_VERSION): Likewise.
> 	* config/rs6000/aix52.h (TARGET_AIX_VERSION): Likewise.
> 	* config/rs6000/aix53.h (TARGET_AIX_VERSION): Likewise.
> 	* config/rs6000/aix61.h (TARGET_AIX_VERSION): Likewise.

Entry for collect2.c should say collect2-aix.h.

This is OK.  Nice work.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [5/8] Make collect2 honour --sysroot
  2009-06-02 12:21 ` [5/8] Make collect2 honour --sysroot Richard Sandiford
@ 2009-06-02 14:30   ` Ian Lance Taylor
  0 siblings, 0 replies; 19+ messages in thread
From: Ian Lance Taylor @ 2009-06-02 14:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: richards

Richard Sandiford <richards@transitive.com> writes:

> gcc/
> 	* collect2.c (target_system_root): New variable.
> 	(main): Handle --sysroot=.
> 	(ignore_library): Strip the sysroot from the library path.

This is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [7/8] Don't compile collect2 init and fini routines with -fwhole-program
  2009-06-02 12:29 ` [7/8] Don't compile collect2 init and fini routines with -fwhole-program Richard Sandiford
@ 2009-06-02 14:33   ` Ian Lance Taylor
  0 siblings, 0 replies; 19+ messages in thread
From: Ian Lance Taylor @ 2009-06-02 14:33 UTC (permalink / raw)
  To: gcc-patches; +Cc: richards

Richard Sandiford <richards@transitive.com> writes:

> gcc/
> 	* config/pa/pa-hpux.h (LINK_SPEC): Remove "%<fwhole-program".
> 	* config/pa/pa-hpux10.h (LINK_SPEC): Likewise.
> 	* config/pa/pa-hpux11.h (LINK_SPEC): Likewise.
> 	* gcc.c (set_collect_gcc_options): Don't add -fwhole-program
> 	to COLLECT_GCC_OPTIONS.

This is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [0/8] AIX cross toolchains
  2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
                   ` (7 preceding siblings ...)
  2009-06-02 12:33 ` [8/8] Tidy up testsuite handling of LD_LIBRARY_PATH (needs testsuite maintainer) Richard Sandiford
@ 2009-06-02 18:01 ` Ralf Wildenhues
  8 siblings, 0 replies; 19+ messages in thread
From: Ralf Wildenhues @ 2009-06-02 18:01 UTC (permalink / raw)
  To: gcc-patches, richards

Hello Richard,

* Richard Sandiford wrote on Tue, Jun 02, 2009 at 02:03:21PM CEST:
> 
>     http://lists.gnu.org/archive/html/libtool-patches/2009-03/msg00007.html
>     http://lists.gnu.org/archive/html/libtool-patches/2009-04/msg00013.html
> 
> The patches haven't been accepted, so you'll need to apply them locally
> and then regenerate each configure script.

Sorry about the long delay.  I've been seeing some not yet analyzed
failures on an AIX 4.3.3 system with these patches, will try to look
into them soon.

Cheers,
Ralf

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [3/8] Fix premature post-increment in collect2.c
  2009-06-02 14:14   ` Ian Lance Taylor
@ 2009-06-02 19:06     ` Richard Sandiford
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Sandiford @ 2009-06-02 19:06 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches

Ian Lance Taylor <iant@google.com> writes:
> Richard Sandiford <richards@transitive.com> writes:
>
>> 	* collect2.c (ignore_library): Avoid premature post-increment
>> 	and null deference.
>>
>> Index: gcc/collect2.c
>> ===================================================================
>> --- gcc/collect2.c	2009-06-02 13:05:46.000000000 +0100
>> +++ gcc/collect2.c	2009-06-02 13:06:04.000000000 +0100
>> @@ -2444,8 +2444,9 @@ static int ignore_library (const char *)
>>  ignore_library (const char *name)
>>  {
>>    const char *const *p = &aix_std_libs[0];
>> -  while (*p++ != NULL)
>> -    if (! strcmp (name, *p)) return 1;
>> +  while (*p)
>> +    if (! strcmp (name, *p++))
>> +      return 1;
>
> Burying the postincrement in the argument to a function call doesn't
> seem like a big step forward in clarity.  I would write something more
> like
>
>   const char *const *p;
>   for (p = &aix_std_libs[0]; *p != NULL; ++p)
>     if (strcmp (name, *p) == 0)
>       return 1;
>
> I won't insist on that change.  This is OK either way.

Thanks, applied with the suggested change.

Richard

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [6/8] Add AIX support to GLIBCXX_CROSSCONFIG
  2009-06-02 12:23 ` [6/8] Add AIX support to GLIBCXX_CROSSCONFIG Richard Sandiford
@ 2009-06-05  4:59   ` Benjamin Kosnik
  0 siblings, 0 replies; 19+ messages in thread
From: Benjamin Kosnik @ 2009-06-05  4:59 UTC (permalink / raw)
  Cc: gcc-patches, libstdc++


> libstdc++-v3/
> 	* crossconfig.m4 (GLIBCXX_CROSSCONFIG): Handle AIX targets.
> 	* configure: Regenerate.

ok with me.

-benjamin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [5/8] Make collect2 honour --sysroot
@ 2009-06-02 13:06 David Edelsohn
  0 siblings, 0 replies; 19+ messages in thread
From: David Edelsohn @ 2009-06-02 13:06 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches

gcc/
	* collect2.c (target_system_root): New variable.
	(main): Handle --sysroot=.
	(ignore_library): Strip the sysroot from the library path.

Okay.

Thanks, David

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-06-05  4:59 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-02 12:03 [0/8] AIX cross toolchains Richard Sandiford
2009-06-02 12:05 ` [1/8] Don't build newlib for AIX Richard Sandiford
2009-06-02 12:58   ` Paolo Bonzini
2009-06-02 12:10 ` [2/8] Handle sysroots on AIX (needs build-system maintainer) Richard Sandiford
2009-06-02 12:58   ` Paolo Bonzini
2009-06-02 12:11 ` [3/8] Fix premature post-increment in collect2.c Richard Sandiford
2009-06-02 14:14   ` Ian Lance Taylor
2009-06-02 19:06     ` Richard Sandiford
2009-06-02 12:20 ` [4/8] Implement the ldopen() family of routines for cross collect2s Richard Sandiford
2009-06-02 14:28   ` Ian Lance Taylor
2009-06-02 12:21 ` [5/8] Make collect2 honour --sysroot Richard Sandiford
2009-06-02 14:30   ` Ian Lance Taylor
2009-06-02 12:23 ` [6/8] Add AIX support to GLIBCXX_CROSSCONFIG Richard Sandiford
2009-06-05  4:59   ` Benjamin Kosnik
2009-06-02 12:29 ` [7/8] Don't compile collect2 init and fini routines with -fwhole-program Richard Sandiford
2009-06-02 14:33   ` Ian Lance Taylor
2009-06-02 12:33 ` [8/8] Tidy up testsuite handling of LD_LIBRARY_PATH (needs testsuite maintainer) Richard Sandiford
2009-06-02 18:01 ` [0/8] AIX cross toolchains Ralf Wildenhues
2009-06-02 13:06 [5/8] Make collect2 honour --sysroot David Edelsohn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).