This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

Fix assert.h in shared libraries on Darwin


This rather long and hairy patch makes it possible again to build
shared libraries on Darwin which make use of assert.h.

To recap: The system-provided assert.h relies on libgcc's __eprintf.
This function is not in libgcc_s.so; only in libgcc.a.  That is
deliberate - it's supposed to exist for backward compatibility only.
assert.h is not a required part of a freestanding implementation of
C, and we decided (back in 3.2 days IIRC) that we wanted to get out of
the business of providing assert.h.

Darwin's linker objects to unresolved references in shared libraries,
which is a reasonable thing to do.  Until recently, we were linking
shared libraries against libgcc.a, but this was a bug, because shared
libraries must not re-export libgcc.a symbols (if they do, their
effective ABIs can change silently when they are rebuilt with
different versions of GCC).  So Andrew Pinski took -lgcc off the
-dynamiclib link line, but that caused any shared library that uses
assert.h to contain an unresolved reference to __eprintf, resulting in
a link failure.

The cure is to mark all of the symbols in libgcc.a with "hidden
visibility" (also known as "private external" on Darwin) which
prevents the linker from exporting them from any shared library that
they happen to get included into.  That then allows us to put -lgcc
back in the -dynamiclib link line without ABI consequences.  We were
already doing this for ELF, but by means of an awful hack: we'd build
the object file, run nm over it to find the list of exported symbols,
generate a stub .s file containing only .hidden directives for those
symbols, assemble that, and ld -r the result together with the
original object file.  The Darwin linker will not cooperate with this
hack.

For C source files, we can do what we should have been doing all
along, which is pass -fvisibility=hidden to the compiler in the first
place.  (It is also necessary to #ifdef up some headers so they don't
override this with #pragma GCC visibility push(default).)  For
assembly source files, I opted for a variant of the original hack - we
compile the file once, run nm over that, generate the same list of
.hidden directives, and then we recompile the file using -include to
pull in the list.  Long term, we might want to think about putting
explicit .hidden directives in the assembly sources instead.

There are two additional wrinkles.  The directive for the Darwin
assembler is not .hidden, but .private_extern; to handle this I added
another parameter to mklibgcc.in.  The original ld -r hack did not
just provide .hidden directives; it also injected a .note.GNU-stack
marker into each and every file, specifying that the file did not need
an executable stack.  Upon reflection I decided that this was just
plain wrong.  The compiler can be relied on to get it right for C
source files.  For assembly source files, we must have hand-written
markers, because someone might well want to implement trampoline
helper functions in assembly, at which point that module should
indicate that it *does* need an executable stack.  Furthermore,
injecting these markers makes libgcc.a inconsistent with libgcc_s.so.
Accordingly I ripped that out.  This has no ABI implications, but does
mean that some assembly object modules are now not displaying any
.note.GNU-stack marker.  Architecture maintainers can fix this up at
their leisure - I do not have access to a system that cares about
.note.GNU-stack so I can't reliably do it myself.

The bulk of this patch is restructuring mklibgcc.in to make it
*possible* to compile each file twice, and I made a bunch of changes
which have no relation to the goal other than preserving what is left
of my sanity.  It should be observed that the generated libgcc.mk now
makes use of several GNU make features, notably :=, punctuation
variables in non-suffix rules, and some $(functions).

This has been bootstrapped on powerpc-darwin and verified to fix the
original problem, viz. the patched compiler can build Qt.  I attempted
a build on i686-linux which fell afoul of unrelated breakage.  I'm
going to retry that today, and also try a build on ia64-hpux (a system
which defines LIBUNWIND).  I would appreciate testing on a system
which makes heavy use of multilibs; I can only do that cursorily and
not on mainline.  I'm not going to check this in now, but if I don't
hear anything by Monday I will probably put it in then.

zw

        * gthr-gnat.c, gthr-gnat.h, gthr.h, libgcc2.h, unwind-dw2-fde.h
        * unwind.h: Surround all visibility pragmas with #ifndef HIDE_EXPORTS.

        * mklibgcc.in: Drastic restructure for comprehensibility.
        Remove the old hidden-directive hack.
        Eliminate support for .txt files in LIB2ADD etc (never used).
        Eliminate support for assembly source files in LIB2ADDEH* and
        LIBUNWIND (also never used).
        Build up dependency lists for libraries incrementally.
        If we have SHLIB_LINK, compile each file twice, once for the
        static and once for the shared library; also probe for
        -fvisibility=hidden in the generated libgcc.mk.  If found,
        pass that and -DHIDE_EXPORTS to the compilation of every C
        source file going into the static library.  If found, generate
        hidden-directive lists for every assembly source file going
        into the static library, but incorporate them with -include
        instead of ld -r.
	* Makefile.in: Pass ASM_HIDDEN_OP to mklibgcc.
        * config/t-slibgcc-darwin: Define ASM_HIDDEN_OP.

        * config/darwin.h (REAL_LIBGCC_SPEC): Put -lgcc back in
        -Zdynamiclib case.

===================================================================
Index: gthr-gnat.c
--- gthr-gnat.c	15 Oct 2004 14:47:08 -0000	1.4
+++ gthr-gnat.c	25 Nov 2004 19:24:21 -0000
@@ -28,7 +28,9 @@ Software Foundation, 59 Temple Place - S
 
 #include "gthr-gnat.h"
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility push(default)
+#endif
 
 #ifdef __cplusplus
 #define UNUSED(x)
@@ -81,4 +83,6 @@ __gthread_mutex_unlock (__gthread_mutex_
   return 0;
 }
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
+#endif
===================================================================
Index: gthr-gnat.h
--- gthr-gnat.h	15 Oct 2004 14:47:08 -0000	1.4
+++ gthr-gnat.h	25 Nov 2004 19:24:21 -0000
@@ -28,7 +28,9 @@ Software Foundation, 59 Temple Place - S
 #ifndef GCC_GTHR_GNAT_H
 #define GCC_GTHR_GNAT_H
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility push(default)
+#endif
 
 /* Just provide compatibility for mutex handling.  */
 
@@ -41,7 +43,9 @@ extern int __gthread_active_p (void);
 extern int __gthread_mutex_lock (__gthread_mutex_t *);
 extern int __gthread_mutex_unlock (__gthread_mutex_t *);
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
+#endif
 
 #endif /* ! GCC_GTHR_GNAT_H */
 
===================================================================
Index: gthr.h
--- gthr.h	22 Nov 2004 22:26:06 -0000	1.19
+++ gthr.h	25 Nov 2004 19:24:21 -0000
@@ -29,7 +29,9 @@ Software Foundation, 59 Temple Place - S
 #ifndef GCC_GTHR_H
 #define GCC_GTHR_H
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility push(default)
+#endif
 
 /* If this file is compiled with threads support, it must
        #define __GTHREADS 1
@@ -116,6 +118,8 @@ Software Foundation, 59 Temple Place - S
 #include "gthr-single.h"
 #endif
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
+#endif
 
 #endif /* ! GCC_GTHR_H */
===================================================================
Index: libgcc2.h
--- libgcc2.h	22 Oct 2004 15:03:23 -0000	1.31
+++ libgcc2.h	25 Nov 2004 19:24:22 -0000
@@ -30,7 +30,9 @@ Software Foundation, 59 Temple Place - S
 #ifndef GCC_LIBGCC2_H
 #define GCC_LIBGCC2_H
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility push(default)
+#endif
 
 extern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t);
 extern void __clear_cache (char *, char *);
@@ -324,6 +326,8 @@ extern int __parityDI2 (UDWtype);
 
 extern void __enable_execute_stack (void *);
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
+#endif
 
 #endif /* ! GCC_LIBGCC2_H */
===================================================================
Index: unwind-dw2-fde.h
--- unwind-dw2-fde.h	3 Aug 2004 16:57:40 -0000	1.15
+++ unwind-dw2-fde.h	25 Nov 2004 19:24:24 -0000
@@ -32,7 +32,9 @@ Software Foundation, 59 Temple Place - S
 #ifndef GCC_UNWIND_DW2_FDE_H
 #define GCC_UNWIND_DW2_FDE_H
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility push(default)
+#endif
 
 struct fde_vector
 {
@@ -179,6 +181,8 @@ last_fde (struct object *obj __attribute
 #endif
 }
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
+#endif
 
 #endif /* unwind-dw2-fde.h */
===================================================================
Index: unwind.h
--- unwind.h	3 Aug 2004 16:57:40 -0000	1.16
+++ unwind.h	25 Nov 2004 19:24:24 -0000
@@ -31,7 +31,9 @@
 #ifndef _UNWIND_H
 #define _UNWIND_H
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility push(default)
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -231,6 +233,8 @@ extern void * _Unwind_FindEnclosingFunct
 }
 #endif
 
+#ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
+#endif
 
 #endif /* unwind.h */
===================================================================
Index: mklibgcc.in
--- mklibgcc.in	18 Oct 2004 15:52:39 -0000	1.72
+++ mklibgcc.in	25 Nov 2004 19:24:22 -0000
@@ -40,13 +40,15 @@
 # SHLIB_NM_FLAGS
 # SHLIB_INSTALL
 # MULTILIB_OSDIRNAMES
+# ASM_HIDDEN_OP
 
 # Make needs VPATH to be literal.
 echo 'srcdir = @srcdir@'
 echo 'VPATH = @srcdir@'
 echo 'EQ = ='
+echo 'objects = $(filter %'$objext',$^)'
 echo
-echo 'force:'
+echo 'all: all-real'
 echo
 
 # Library members defined in libgcc2.c.
@@ -89,290 +91,503 @@ libgcov_c_dep='stmp-dirs $(srcdir)/libgc
 # Dependencies for fp-bit.c
 fpbit_c_dep='stmp-dirs config.status tsystem.h'
 
+if [ "$SHLIB_LINK" ]; then
+  # Test -fvisibility=hidden.  We need both a -fvisibility=hidden on
+  # the command line, and a #define to prevent libgcc2.h etc from
+  # overriding that with #pragmas.  The dance with @ is to prevent
+  # echo from seeing anything it might take for an option.
+  echo "vis_hide := \$(strip \$(subst @,-,\\"
+  echo "    \$(shell if echo 'void foo(void);' | \\"
+  echo "          $gcc_compile -fvisibility=hidden -Werror \\"
+  echo "          -c -xc - -o /dev/null 2> /dev/null; \\"
+  echo "          then echo @fvisibility=hidden @DHIDE_EXPORTS; \\"
+  echo "          fi)))"
+  echo
+
+  # If we have -fvisibility=hidden, then we need to generate hide
+  # lists for object files implemented in assembly.  The default
+  # pseudo-op for this is ".hidden", but can be overridden with
+  # ASM_HIDDEN_OP.
+  [ "$ASM_HIDDEN_OP" ] || ASM_HIDDEN_OP=".hidden"
+  
+  echo "ifneq (,\$(vis_hide))"
+  echo "define gen-hide-list"
+  echo "\$(NM_FOR_TARGET) ${SHLIB_NM_FLAGS} \$< | \\"
+  # non-GNU nm emits three fields even for undefined and typeless symbols,
+  # so explicitly omit them
+  echo "  \$(AWK) 'NF == 3 && \$\$2 !~ /^[UN]\$\$/ { print \"\\t${ASM_HIDDEN_OP}\", \$\$3 }' > \$@T"
+  echo "mv -f \$@T \$@"
+  echo "endef"
+  echo "else"
+  echo "gen-hide-list = echo > \$@"
+  echo "endif"
+  echo
+else
+  # It is too hard to guarantee that vis_hide and gen-hide-list will never
+  # be referenced if SHLIB_LINK is not set, so set them to the values they'd
+  # have if SHLIB_LINK were set and we didn't have visibility support.
+  echo "vis_hide ="
+  echo "gen-hide-list = echo > \$@"
+fi
+
+# Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
+# defined as optimized assembly code in LIB1ASMFUNCS.
+for name in $LIB1ASMFUNCS; do
+  lib2funcs=`echo $lib2funcs | sed -e 's/^'$name' //' \
+				   -e 's/ '$name' / /' \
+				   -e 's/ '$name'$//'`
+  LIB2_DIVMOD_FUNCS=`echo $LIB2_DIVMOD_FUNCS | sed -e 's/^'$name' //' \
+				                   -e 's/ '$name' / /' \
+				                   -e 's/ '$name'$//'`
+done
+
 #
-# Build libgcc1 components.
+# Rules to generate object files.
 #
 
-libgcc1_objs=""
+for ml in $MULTILIBS; do
+  echo
+  echo \#
+  echo \# $ml
+  echo \#
+  dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
+  flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
 
-for name in $LIB1ASMFUNCS; do
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-    out="libgcc/${dir}/${name}${objext}"
+  libgcc_a=$dir/libgcc.a
+  libgcc_eh_a=
+  libgcc_s_so=
+  libunwind_a=
+  libunwind_so=
 
-    echo ${out}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)'
-    echo "	$gcc_compile" $flags -DL$name -xassembler-with-cpp \
-	  -c '$(srcdir)/config/$(LIB1ASMSRC)' -o $out
+  if [ "$LIBUNWIND" ]; then
+    libunwind_a=$dir/libunwind.a
+  fi
+  if [ "$SHLIB_LINK" ]; then
+    if [ -z "$SHLIB_MULTILIB" ]; then
+      if [ "$dir" = . ]; then
+	libgcc_eh_a=$dir/libgcc_eh.a
+	libgcc_s_so=$dir/libgcc_s${SHLIB_EXT}
+	if [ "$LIBUNWIND" ]; then
+	  libunwind_so=$dir/libunwind${SHLIB_EXT}
+	fi
+      else
+	libgcc_eh_a=$dir/libgcc_eh.a
+	libgcc_so=$dir/libgcc_s_`echo $dir | sed s,/,_,g`${SHLIB_EXT}
+	if [ "$LIBUNWIND" ]; then
+	  libunwind_so=$dir/libunwind_`echo $dir | sed s,/,_,g`${SHLIB_EXT}
+	fi
+      fi
+    elif [ "$SHLIB_MULTILIB" = "$dir" ]; then
+      libgcc_eh_a=$dir/libgcc_eh.a
+      libgcc_s_so=$dir/libgcc_s${SHLIB_EXT}
+      if [ "$LIBUNWIND" ]; then
+        libunwind_so=$dir/libunwind${SHLIB_EXT}
+      fi
+    fi
+  fi
 
-    # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
-    # defined as optimized assembly code in LIB1ASMFUNCS.
-    lib2funcs=`echo $lib2funcs | sed -e 's/^'$name' //' \
-				     -e 's/ '$name' / /' \
-				     -e 's/ '$name'$//'`
-    LIB2_DIVMOD_FUNCS=`echo $LIB2_DIVMOD_FUNCS | sed -e 's/^'$name' //' \
-				                     -e 's/ '$name' / /' \
-				                     -e 's/ '$name'$//'`
+  #
+  # Build libgcc1 components.
+  #
+  for name in $LIB1ASMFUNCS; do
+    if [ "$libgcc_s_so" ]; then
+      out="libgcc/${dir}/${name}${objext}"
+      outS="libgcc/${dir}/${name}_s${objext}"
+      outV="libgcc/${dir}/${name}.vis"
+
+      echo ${outS}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)'
+      echo "	$gcc_compile" $flags -DL$name -xassembler-with-cpp \
+	  -c '$(srcdir)/config/$(LIB1ASMSRC)' -o $outS
+
+      echo ${out}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)' ${outV}
+      echo "	$gcc_compile" $flags -DL$name -xassembler-with-cpp \
+	  -c '$(srcdir)/config/$(LIB1ASMSRC)' -include $outV -o $out
+
+      echo "${outV}: ${outS}; \$(gen-hide-list)"
+
+      echo $libgcc_a: $out
+      echo $libgcc_s_so: $outS
+      if [ "$SHLIB_MKMAP" ]; then
+        echo libgcc/${dir}/libgcc.map: $outS
+      fi
+    else
+      out="libgcc/${dir}/${name}${objext}"
+      echo ${out}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)'
+      echo "	$gcc_compile" $flags -DL$name -xassembler-with-cpp \
+	  -c '$(srcdir)/config/$(LIB1ASMSRC)' -o $out
+      echo $libgcc_a: $out
+    fi
   done
-  libgcc1_objs="$libgcc1_objs ${name}${objext}"
-done
 
-#
-# Build libgcc2 components.
-#
+  #
+  # Build libgcc2 components.
+  #
 
-libgcc2_objs=""
-libgcc2_st_objs=""
-libgcc2_eh_static_objs=""
-libgcc2_eh_shared_objs=""
+  for name in $lib2funcs; do
+    if [ "$libgcc_s_so" ]; then
+      out="libgcc/${dir}/${name}${objext}"
+      outS="libgcc/${dir}/${name}_s${objext}"
 
-for name in $lib2funcs; do
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-    out="libgcc/${dir}/${name}${objext}"
+      echo $outS: $libgcc2_c_dep
+      echo "	$gcc_compile" $flags -DL$name -c '$(srcdir)/libgcc2.c' -o $outS
 
-    echo $out: $libgcc2_c_dep
-    echo "	$gcc_compile" $flags -DL$name \
-      -c '$(srcdir)/libgcc2.c' -o $out
+      echo $out: $libgcc2_c_dep
+      echo "	$gcc_compile" $flags -DL$name '$(vis_hide)' \
+        -c '$(srcdir)/libgcc2.c' -o $out
+
+      echo $libgcc_a: $out
+      echo $libgcc_s_so: $outS
+      if [ "$SHLIB_MKMAP" ]; then
+        echo libgcc/${dir}/libgcc.map: $outS
+      fi
+    else
+      out="libgcc/${dir}/${name}${objext}"
+      echo ${out}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)'
+      echo "	$gcc_compile" $flags -DL$name -c '$(srcdir)/libgcc2.c' -o $outS
+      echo $libgcc_a: $out
+    fi
   done
-  libgcc2_objs="$libgcc2_objs ${name}${objext}"
-done
 
-for name in $LIB2FUNCS_ST; do
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
+  for name in $LIB2FUNCS_ST; do
     out="libgcc/${dir}/${name}${objext}"
 
     echo $out: $libgcc2_c_dep
-    echo "	$gcc_compile" $flags -DL$name \
+    echo "	$gcc_compile" $flags -DL$name '$(vis_hide)' \
       -c '$(srcdir)/libgcc2.c' -o $out
+    echo ${dir}/libgcc.a: $out
   done
-  libgcc2_st_objs="$libgcc2_st_objs ${name}${objext}"
-done
 
-for name in $LIB2_DIVMOD_FUNCS; do
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-    out="libgcc/${dir}/${name}${objext}"
+  for name in $LIB2_DIVMOD_FUNCS; do
+    if [ "$libgcc_s_so" ]; then
+      out="libgcc/${dir}/${name}${objext}"
+      outS="libgcc/${dir}/${name}_s${objext}"
 
-    echo $out: $libgcc2_c_dep
-    echo "	$gcc_compile" $flags -DL$name \
-      -c '$(srcdir)/libgcc2.c' -fexceptions -fnon-call-exceptions -o $out
+      echo $outS: $libgcc2_c_dep
+      echo "	$gcc_compile" $flags -DL$name \
+        -fexceptions -fnon-call-exceptions -c '$(srcdir)/libgcc2.c' -o $outS
+
+      echo $out: $libgcc2_c_dep
+      echo "	$gcc_compile" $flags -DL$name '$(vis_hide)' \
+        -fexceptions -fnon-call-exceptions -c '$(srcdir)/libgcc2.c' -o $out
+
+      echo $libgcc_a: $out
+      echo $libgcc_s_so: $outS
+      if [ "$SHLIB_MKMAP" ]; then
+        echo libgcc/${dir}/libgcc.map: $outS
+      fi
+    else
+      out="libgcc/${dir}/${name}${objext}"
+      echo ${out}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)'
+      echo "	$gcc_compile" $flags -DL$name \
+        -fexceptions -fnon-call-exceptions -c '$(srcdir)/libgcc2.c' -o $outS
+      echo $libgcc_a: $out
+    fi
   done
-  libgcc2_objs="$libgcc2_objs ${name}${objext}"
-done
 
-if [ "$FPBIT" ]; then
-  for name in $FPBIT_FUNCS; do
-    for ml in $MULTILIBS; do
-      dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-      flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-      out="libgcc/${dir}/${name}${objext}"
+  #
+  # Build software floating point functions.
+  #
+
+  if [ "$FPBIT" ]; then
+    for name in $FPBIT_FUNCS; do
+      if [ "$libgcc_s_so" ]; then
+	out="libgcc/${dir}/${name}${objext}"
+	outS="libgcc/${dir}/${name}_s${objext}"
+
+	echo $outS: $FPBIT $fpbit_c_dep
+	echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  -c $FPBIT -o $outS
+
+        echo $out: $FPBIT $fpbit_c_dep
+        echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  '$(vis_hide)' -c $FPBIT -o $out
+
+	echo $libgcc_a: $out
+	echo $libgcc_s_so: $outS
+	if [ "$SHLIB_MKMAP" ]; then
+	  echo libgcc/${dir}/libgcc.map: $outS
+	fi
+      else
+	out="libgcc/${dir}/${name}${objext}"
+	echo $out: $FPBIT $fpbit_c_dep
+	echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  -c $FPBIT -o $out
 
-      echo $out: $FPBIT $fpbit_c_dep
-      echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
-	-c $FPBIT -o $out
+	echo $libgcc_a: $out
+      fi
     done
-    libgcc2_objs="$libgcc2_objs ${name}${objext}"
-  done
-fi
+  fi
 
-if [ "$DPBIT" ]; then
-  for name in $DPBIT_FUNCS; do
-    for ml in $MULTILIBS; do
-      dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-      flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-      out="libgcc/${dir}/${name}${objext}"
+  if [ "$DPBIT" ]; then
+    for name in $DPBIT_FUNCS; do
+      if [ "$libgcc_s_so" ]; then
+	out="libgcc/${dir}/${name}${objext}"
+	outS="libgcc/${dir}/${name}_s${objext}"
+
+	echo $outS: $DPBIT $fpbit_c_dep
+	echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  -c $DPBIT -o $outS
+
+        echo $out: $DPBIT $fpbit_c_dep
+        echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  '$(vis_hide)' -c $DPBIT -o $out
+
+	echo $libgcc_a: $out
+	echo $libgcc_s_so: $outS
+	if [ "$SHLIB_MKMAP" ]; then
+	  echo libgcc/${dir}/libgcc.map: $outS
+	fi
+      else
+	out="libgcc/${dir}/${name}${objext}"
+	echo $out: $DPBIT $fpbit_c_dep
+	echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  -c $DPBIT -o $out
 
-      echo $out: $DPBIT $fpbit_c_dep
-      echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
-	-c $DPBIT -o $out
+	echo $libgcc_a: $out
+      fi
     done
-    libgcc2_objs="$libgcc2_objs ${name}${objext}"
-  done
-fi
+  fi
 
-if [ "$TPBIT" ]; then
-  for name in $TPBIT_FUNCS; do
-    for ml in $MULTILIBS; do
-      dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-      flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-      out="libgcc/${dir}/${name}${objext}"
+  if [ "$TPBIT" ]; then
+    for name in $TPBIT_FUNCS; do
+      if [ "$libgcc_s_so" ]; then
+	out="libgcc/${dir}/${name}${objext}"
+	outS="libgcc/${dir}/${name}_s${objext}"
+
+	echo $outS: $TPBIT $fpbit_c_dep
+	echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  -c $TPBIT -o $outS
+
+        echo $out: $TPBIT $fpbit_c_dep
+        echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  '$(vis_hide)' -c $TPBIT -o $out
+
+	echo $libgcc_a: $out
+	echo $libgcc_s_so: $outS
+	if [ "$SHLIB_MKMAP" ]; then
+	  echo libgcc/${dir}/libgcc.map: $outS
+	fi
+      else
+	out="libgcc/${dir}/${name}${objext}"
+	echo $out: $TPBIT $fpbit_c_dep
+	echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
+	  -c $TPBIT -o $out
 
-      echo $out: $TPBIT $fpbit_c_dep
-      echo "	$gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \
-	-c $TPBIT -o $out
+	echo $libgcc_a: $out
+      fi
     done
-    libgcc2_objs="$libgcc2_objs ${name}${objext}"
-  done
-fi
+  fi
 
-for file in $LIB2ADD; do
-  name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'`
-  oname=`echo $name | sed -e 's,.*/,,'`
+  for file in $LIB2ADD; do
+    name=`echo $file | sed -e 's/[.][cS]$//' -e 's/[.]asm$//'`
+    oname=`echo $name | sed -e 's,.*/,,'`
 
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-    out="libgcc/${dir}/${oname}${objext}"
-    if [ ${name}.asm = ${file} ]; then
-      flags="$flags -xassembler-with-cpp"
-    fi
+    if [ "$libgcc_s_so" ]; then
+      out="libgcc/${dir}/${oname}${objext}"
+      outS="libgcc/${dir}/${oname}_s${objext}"
 
-    echo $out: stmp-dirs $file $libgcc_dep
-    echo "	$gcc_compile" $flags -c $file -o $out
+      case $file in
+	*.c)
+	  echo $outS: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags -c $file -o $outS
+
+	  echo $out: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags '$(vis_hide)' -c $file -o $out
+	;;
+
+	*.asm | *.S)
+	  outV="libgcc/${dir}/${oname}.vis"
+
+	  echo $outS: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags -xassembler-with-cpp \
+	         -c $file -o $outS
+
+	  echo $out: stmp-dirs $file $libgcc_dep $outV
+	  echo "	$gcc_compile" $flags -xassembler-with-cpp \
+	         -include $outV -c $file -o $out
+	  echo "${outV}: ${outS}; \$(gen-hide-list)"
+	;;
+	
+        *)
+	  echo "Unhandled extension: $file" >&2
+	  exit 1
+	;;
+      esac
+
+      echo $libgcc_a: $out
+      echo $libgcc_s_so: $outS
+      if [ "$SHLIB_MKMAP" ]; then
+	echo libgcc/${dir}/libgcc.map: $outS
+      fi
+    else
+      out="libgcc/${dir}/${oname}${objext}"
+      case $file in
+	*.c)
+	  echo $out: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags -c $file -o $out
+	;;
+
+	*.asm | *.S)
+	  echo $out: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags -xassembler-with-cpp \
+	         -c $file -o $out
+	;;
+	
+        *)
+	  echo "Unhandled extension: $file" >&2
+	  exit 1
+	;;
+      esac
+      
+      echo $libgcc_a: $out
+    fi
   done
-  libgcc2_objs="$libgcc2_objs ${oname}${objext}"
-done
 
-for file in $LIB2ADDEH; do
-  name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'`
-  oname=`echo $name | sed -e 's,.*/,,'`
 
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
+  for file in $LIB2ADD_ST; do
+    name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//'`
+    oname=`echo $name | sed -e 's,.*/,,'`
     out="libgcc/${dir}/${oname}${objext}"
-    if [ ${name}.asm = ${file} ]; then
-      flags="$flags -xassembler-with-cpp"
-    fi
 
-    echo $out: stmp-dirs $file $LIB2ADDEHDEP $libgcc_dep
-    echo "	$gcc_compile" $flags -fexceptions -c $file -o $out
-  done
-  if [ -z "$SHLIB_LINK" ]; then
-    libgcc2_objs="$libgcc2_objs ${oname}${objext}"
-  fi
-done
+    case $file in
+      *.c)
+	echo $out: stmp-dirs $file $libgcc_dep
+	echo "	$gcc_compile" $flags '$(vis_hide)' -c $file -o $out
+      ;;
+
+      *.asm | *.S)
+        # We may have to compile it twice in order to establish the list
+        # of symbols to be marked hidden.
+	if [ "$libgcc_so" ]; then
+	  outV="libgcc/${dir}/${oname}.vis"
+	  outT="libgcc/${dir}/${oname}_t${objext}"
+	  echo ${outT}: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags -xassembler-with-cpp \
+	          -c $file -o ${outT}
+	  echo $out: stmp-dirs $file $libgcc_dep $outV
+	  echo "	$gcc_compile" $flags -xassembler-with-cpp \
+	          -include $outV -c $file -o $out
+	  echo "${outV}: ${outT}; \$(gen-hide-list)"
+	else
+	  echo $out: stmp-dirs $file $libgcc_dep
+	  echo "	$gcc_compile" $flags -xassembler-with-cpp \
+	          -c $file -o $out
+	fi
+      ;;
 
-if [ "$SHLIB_LINK" ]; then
-  # Those should be in libgcc_eh.a.
-  for file in $LIB2ADDEHSTATIC; do
-    name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'`
-    oname=`echo $name | sed -e 's,.*/,,'`
-    libgcc2_eh_static_objs="$libgcc2_eh_static_objs ${oname}${objext}"
+      *)
+      echo "Unhandled extension: $file" >&2
+      exit 1
+      ;;
+    esac
+    echo $libgcc_a: $out
   done
 
-  # Those should be in libgcc.so.
-  for file in $LIB2ADDEHSHARED; do
-    name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'`
-    oname=`echo $name | sed -e 's,.*/,,'`
-    libgcc2_eh_shared_objs="$libgcc2_eh_shared_objs ${oname}${objext}"
-  done
-fi
+  # If we don't have libgcc_eh.a, only LIB2ADDEH matters.  If we do, only
+  # LIB2ADDEHSTATIC and LIB2ADDEHSHARED matter.  (Usually all three are
+  # identical.)  We do _not_ handle assembly files in this context.
+
+  if [ "$libgcc_eh_a" ]; then
+    for file in $LIB2ADDEHSTATIC; do
+      case $file in
+        *.c) ;;
+	*)   echo "Unhandled extension: $file">&2; exit 1 ;;
+       esac
 
-for file in $LIB2ADD_ST; do
-  name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'`
-  oname=`echo $name | sed -e 's,.*/,,'`
+      name=`echo $file | sed -e 's/[.]c$//'`
+      oname=`echo $name | sed -e 's,.*/,,'`
+      out="libgcc/${dir}/${oname}${objext}"
 
-  for ml in $MULTILIBS; do
-    dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-    flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
-    out="libgcc/${dir}/${oname}${objext}"
-    if [ ${name}.asm = ${file} ]; then
-      flags="$flags -xassembler-with-cpp"
-    fi
+      echo $out: stmp-dirs $file $LIB2ADDEHDEP $libgcc_dep
+      echo "	$gcc_compile" $flags '$(vis_hide)' -fexceptions -c $file -o $out
+      echo $libgcc_eh_a: $out
+    done
 
-    echo $out: stmp-dirs $file $libgcc_dep
-    echo "	$gcc_compile" $flags -c $file -o $out
-  done
-  libgcc2_st_objs="$libgcc2_st_objs ${oname}${objext}"
-done
+    for file in $LIB2ADDEHSHARED; do
+      case $file in
+        *.c) ;;
+	*)   echo "Unhandled extension: $file">&2; exit 1 ;;
+       esac
+
+      name=`echo $file | sed -e 's/[.]c$//'`
+      oname=`echo $name | sed -e 's,.*/,,'`
+      out="libgcc/${dir}/${oname}_s${objext}"
 
-if [ "$LIBUNWIND" ]; then
-  libunwind_static_objs=""
-  libunwind_shared_objs=""
-  for file in $LIBUNWIND; do
-    name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'`
-    oname=`echo $name | sed -e 's,.*/,,'`
+      echo $out: stmp-dirs $file $LIB2ADDEHDEP $libgcc_dep
+      echo "	$gcc_compile" $flags -fexceptions -c $file -o $out
+      echo $libgcc_s_so: $out
+      if [ "$SHLIB_MKMAP" ]; then
+	echo libgcc/${dir}/libgcc.map: $out
+      fi
+    done
+
+  else # no SHLIB_LINK
+    for file in $LIB2ADDEH; do
+      case $file in
+        *.c) ;;
+	*)   echo "Unhandled extension: $file">&2; exit 1 ;;
+       esac
 
-    for ml in $MULTILIBS; do
-      dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-      flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
+      name=`echo $file | sed -e 's/[.]c$//'`
+      oname=`echo $name | sed -e 's,.*/,,'`
       out="libgcc/${dir}/${oname}${objext}"
-      if [ ${name}.asm = ${file} ]; then
-	flags="$flags -xassembler-with-cpp"
-      fi
 
-      echo $out: stmp-dirs $file $LIBUNWINDDEP
-      echo "	$gcc_compile" $flags -fexceptions -c $file -o $out
-      echo ${out}s: stmp-dirs $file $LIBUNWINDDEP
-      echo "	$gcc_compile" $flags -fexceptions -DSHARED -c $file -o ${out}s
+      echo $out: stmp-dirs $file $LIB2ADDEHDEP $libgcc_dep
+      echo "	$gcc_compile" $flags -fexceptions '$(vis_hide)' -c $file -o $out
+      echo $libgcc_a: $out
     done
-    libunwind_static_objs="$libunwind_static_objs ${oname}${objext}"
-    libunwind_shared_objs="$libunwind_shared_objs ${oname}${objext}s"
-  done
-fi
+  fi
 
-#
-# build libgcov components
-#
+  # Again, this does not handle assembly.
+  if [ "$LIBUNWIND" ]; then
+    for file in $LIBUNWIND; do
+      case $file in
+        *.c) ;;
+	*)   echo "Unhandled extension: $file">&2; exit 1 ;;
+       esac
+
+      name=`echo $file | sed -e 's/[.]c$//'`
+      oname=`echo $name | sed -e 's,.*/,,'`
+
+      if [ "$libunwind_so" ]; then
+        out="libgcc/${dir}/${oname}${objext}"
+	outS="libgcc/${dir}/${oname}_s${objext}"
 
-libgcov_objs=""
+	echo $out: stmp-dirs $file $LIBUNWINDDEP
+	echo "	$gcc_compile $flags -fexceptions \$(vis_hide) -c $file -o $out"
 
-for name in $LIBGCOV; do
-  for ml in $MULTILIBS; do
+	echo $outS: stmp-dirs $file $LIBUNWINDDEP
+	echo "	$gcc_compile $flags -fexceptions -DSHARED -c $file -o $outS"
+
+	echo $libunwind_a: $out
+	echo $libunwind_so: $outS
+      else
+        out="libgcc/${dir}/${oname}${objext}"
+	echo $out: stmp-dirs $file $LIBUNWINDDEP
+	echo "	$gcc_compile $flags -fexceptions \$(vis_hide) -c $file -o $out"
+	echo $libunwind_a: $out
+      fi
+    done
+  fi
+
+  #
+  # build libgcov components
+  #
+  for name in $LIBGCOV; do
     dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
     flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
     out="libgcc/${dir}/${name}${objext}"
 
     echo $out: $libgcov_c_dep
-    echo "	$gcc_compile" $flags -DL$name \
-      -c '$(srcdir)/libgcov.c' -o $out
+    echo "	$gcc_compile $flags -DL$name -c \$(srcdir)/libgcov.c -o $out"
+    echo ${dir}/libgcov.a: $out
   done
-  libgcov_objs="$libgcov_objs ${name}${objext}"
-done
 
-# SHLIB_MKMAP
-# SHLIB_MKMAP_OPTS
-# SHLIB_MAPFILES
-for ml in $MULTILIBS; do
+  # Library build rules.
   dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
   flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
 
-  libgcc_objs=""
-  libgcc_eh_static_objs=""
-  libgcc_eh_shared_objs=""
-  for o in $libgcc1_objs; do
-    libgcc_objs="$libgcc_objs libgcc/${dir}/$o"
-  done
-  for o in $libgcc2_objs; do
-    libgcc_objs="$libgcc_objs libgcc/${dir}/$o"
-  done
-  for o in $libgcc2_eh_static_objs; do
-    libgcc_eh_static_objs="$libgcc_eh_static_objs libgcc/${dir}/$o"
-  done
-  for o in $libgcc2_eh_shared_objs; do
-    libgcc_eh_shared_objs="$libgcc_eh_shared_objs libgcc/${dir}/$o"
-  done
-  libgcc_sh_objs="$libgcc_objs $libgcc_eh_shared_objs"
-  shlib_deps="$libgcc_sh_objs"
-
-  libgcc_st_objs=""
-  for o in $libgcc2_st_objs; do
-    libgcc_st_objs="$libgcc_st_objs libgcc/${dir}/$o"
-  done
-
-  libgcov_a_objs=""
-  for o in $libgcov_objs; do
-    libgcov_a_objs="$libgcov_a_objs libgcc/${dir}/$o"
-  done
-
-  if [ "$LIBUNWIND" ]; then
-    libunwind_a_objs=""
-    for o in $libunwind_static_objs; do
-      libunwind_a_objs="$libunwind_a_objs libgcc/${dir}/$o"
-    done
-    libunwind_sh_objs=""
-    for o in $libunwind_shared_objs; do
-      libunwind_sh_objs="$libunwind_sh_objs libgcc/${dir}/$o"
-    done
-    shlibunwind_deps="$libunwind_sh_objs"
-  fi
-  
+  # Map-file generation.
   if [ "$SHLIB_LINK" -a "$SHLIB_MKMAP" ]; then
     mapfile="libgcc/${dir}/libgcc.map"
     tmpmapfile="libgcc/${dir}/tmp-libgcc.map"
@@ -381,43 +596,27 @@ for ml in $MULTILIBS; do
     # The behavior of here documents is more predictable.
     cat <<EOF
 
-${mapfile}: $SHLIB_MKMAP $SHLIB_MAPFILES $libgcc_sh_objs
-	{ \$(NM_FOR_TARGET) $SHLIB_NM_FLAGS $libgcc_sh_objs; echo %%; \\
+${mapfile}: $SHLIB_MKMAP $SHLIB_MAPFILES
+	{ \$(NM_FOR_TARGET) $SHLIB_NM_FLAGS \$(objects); echo %%; \\
 	  cat $SHLIB_MAPFILES \\
 	    | sed -e '/^[   ]*#/d' \\
 	          -e 's/^%\(if\|else\|elif\|endif\|define\)/#\1/' \\
 	    | $gcc_compile $flags -E -xassembler-with-cpp -; \\
 	} | \$(AWK) -f $SHLIB_MKMAP $SHLIB_MKMAP_OPTS > ${tmpmapfile}
 	mv '$tmpmapfile' \$@
+$libgcc_s_so: ${mapfile}
 EOF
   fi
-  shlib_deps="$shlib_deps $mapfile"
 
   # Depend on EXTRA_MULTILIB_PARTS, since that's where crtbegin/end
   # usually are put in a true multilib situation.
+  shlib_extra_deps=""
   for f in $EXTRA_MULTILIB_PARTS; do
-    shlib_deps="$shlib_deps $dir/$f"
+    shlib_extra_deps="$shlib_extra_deps $dir/$f"
   done
+  echo $libgcc_s_so: $shlib_extra_deps
 
-  libgcc_a_objs="$libgcc_objs $libgcc_st_objs"
-
-  if [ "@libgcc_visibility@" = yes -a "$SHLIB_LINK" ]; then
-    libgcc_a_objs=
-    echo ""
-    echo "libgcc/${dir}/stacknote.s: stmp-dirs"
-    echo '	@( echo | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -S -o - -xc - | grep .note.GNU-stack || : ) > $@.tmp'
-    echo '	@mv -f $@.tmp $@'
-    echo ""
-    for o in $libgcc_objs $libgcc_st_objs; do
-      # .oS objects will have all non-local symbol definitions .hidden
-      oS=`echo ${o} | sed s~${objext}'$~.oS~g'`
-      echo "${oS}: stmp-dirs libgcc/${dir}/stacknote.s ${o}"
-      # non-GNU nm emits three fields even for undefined and typeless symbols,
-      # so explicitly omit them
-      echo '	( $(NM_FOR_TARGET) '${SHLIB_NM_FLAGS} ${o}' | $(AWK) '\''NF == 3 && $$2 !~ /^[UN]$$/ { print "\t.hidden", $$3 }'\''; cat libgcc/${dir}/stacknote.s ) | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -r -nostdinc -nostdlib -o $@ '${o}' -xassembler -'
-      libgcc_a_objs="${libgcc_a_objs} ${oS}"
-    done
-  fi
+  # Static libraries.
 
   # Each of these .a files depends on stmp-dirs.  It would seem that
   # this dependency is redundant, since each of the object files
@@ -426,22 +625,22 @@ EOF
   # dependency is required; the directory containing the archive must
   # exist before the archive itself can be created.
   echo ""
-  echo "${dir}/libgcc.a: stmp-dirs $libgcc_a_objs"
-  echo "	-rm -rf ${dir}/libgcc.a"
-  echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcc.a $libgcc_a_objs
+  echo "${dir}/libgcc.a: stmp-dirs"
+  echo "	-rm -f ${dir}/libgcc.a"
+  echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcc.a '$(objects)'
   echo '	$(RANLIB_FOR_TARGET)' ${dir}/libgcc.a
 
   echo ""
-  echo "${dir}/libgcov.a: stmp-dirs $libgcov_a_objs"
-  echo "	-rm -rf ${dir}/libgcov.a"
-  echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcov.a $libgcov_a_objs
+  echo "${dir}/libgcov.a: stmp-dirs"
+  echo "	-rm -f ${dir}/libgcov.a"
+  echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcov.a '$(objects)'
   echo '	$(RANLIB_FOR_TARGET)' ${dir}/libgcov.a
 
   if [ "$LIBUNWIND" ]; then
     echo ""
-    echo "${dir}/libunwind.a: stmp-dirs $libunwind_a_objs"
-    echo "	-rm -rf ${dir}/libunwind.a"
-    echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libunwind.a $libunwind_a_objs
+    echo "${dir}/libunwind.a: stmp-dirs"
+    echo "	-rm -f ${dir}/libunwind.a"
+    echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libunwind.a '$(objects)'
     echo '	$(RANLIB_FOR_TARGET)' ${dir}/libunwind.a
     echo ""
     echo "${dir}/libgcc.a: ${dir}/libunwind.a"
@@ -450,9 +649,9 @@ EOF
   if [ "$SHLIB_LINK" ]; then
 
     echo ""
-    echo "${dir}/libgcc_eh.a: stmp-dirs $libgcc_eh_static_objs"
-    echo "	-rm -rf ${dir}/libgcc_eh.a"
-    echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_static_objs
+    echo "${dir}/libgcc_eh.a: stmp-dirs"
+    echo "	-rm -f ${dir}/libgcc_eh.a"
+    echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a '$(objects)'
     echo '	$(RANLIB_FOR_TARGET)' ${dir}/libgcc_eh.a
 
     if [ -z "$SHLIB_MULTILIB" ]; then
@@ -465,9 +664,7 @@ EOF
       fi
       shlib_so_name="$shlib_base_name"
       shlibunwind_so_name="$shlibunwind_base_name"
-      if [ "$LIBUNWIND" ]; then
-	shlib_deps="$shlib_deps ${dir}/${shlibunwind_base_name}${SHLIB_EXT}"
-      fi
+      shlib_deps="$libunwind_so" 
       shlib_dir=
       shlib_slibdir_qual=
       if [ -n "$MULTILIB_OSDIRNAMES" ]; then
@@ -490,12 +687,13 @@ EOF
 	  fi
 	fi
       fi
+
       echo ""
-      echo "${dir}/${shlib_base_name}${SHLIB_EXT}: $shlib_deps"
+      echo "$libgcc_s_so: stmp-dirs $shlib_deps"
       echo "	$SHLIB_LINK" \
 	 | sed -e "s%@multilib_flags@%$flags%g" \
 	       -e "s%@multilib_dir@%$dir%g" \
-	       -e "s%@shlib_objs@%$libgcc_sh_objs%g" \
+	       -e "s%@shlib_objs@%\$(objects)%g" \
 	       -e "s%@shlib_base_name@%$shlib_base_name%g" \
 	       -e "s%@shlib_map_file@%$mapfile%g" \
 	       -e "s%@shlib_so_name@%$shlib_so_name%g" \
@@ -503,11 +701,11 @@ EOF
 	       -e "s%@shlib_slibdir_qual@%%g"
       if [ "$LIBUNWIND" ]; then
 	echo ""
-	echo "${dir}/${shlibunwind_base_name}${SHLIB_EXT}: $shlibunwind_deps"
+	echo "$libunwind_so: stmp-dirs"
 	echo "	$SHLIBUNWIND_LINK" \
 	   | sed -e "s%@multilib_flags@%$flags%g" \
 		 -e "s%@multilib_dir@%$dir%g" \
-		 -e "s%@shlib_objs@%$libunwind_sh_objs%g" \
+		 -e "s%@shlib_objs@%\$(objects)%g" \
 		 -e "s%@shlib_base_name@%$shlibunwind_base_name%g" \
 		 -e "s%@shlib_so_name@%$shlibunwind_so_name%g" \
 		 -e "s%@shlib_dir@%$shlib_dir%g" \
@@ -516,8 +714,9 @@ EOF
     elif [ "$SHLIB_MULTILIB" = "$dir" ]; then
       shlib_base_name="libgcc_s";
       shlibunwind_base_name="libunwind";
+      shlib_deps=$libunwind_so
       echo ""
-      echo "${shlib_base_name}${SHLIB_EXT}: $shlib_deps"
+      echo "$libgcc_s_so: stmp-dirs $shlib_deps"
       echo "	$SHLIB_LINK" \
 	 | sed -e "s%@multilib_flags@%$flags%g" \
 	       -e "s%@multilib_dir@%$dir%g" \
@@ -529,7 +728,7 @@ EOF
 	       -e "s%@shlib_slibdir_qual@%%g"
       if [ "$LIBUNWIND" ]; then
 	echo ""
-	echo "${shlibunwind_base_name}${SHLIB_EXT}: $shlibunwind_deps"
+	echo "$libunwind_so: stmp-dirs"
 	echo "	$SHLIBUNWIND_LINK" \
 	   | sed -e "s%@multilib_flags@%$flags%g" \
 		 -e "s%@multilib_dir@%$dir%g" \
@@ -541,7 +740,7 @@ EOF
       fi
     fi
   fi
-done
+done # ml in MULTILIBS
 
 dirs=libgcc
 for ml in $MULTILIBS; do
@@ -550,17 +749,17 @@ for ml in $MULTILIBS; do
     dirs="$dirs ${dir} libgcc/${dir}"
   fi
 done
-echo ''
-echo 'libgcc-stage-start:'
-echo '	for dir in '"${dirs}"'; do \'
-echo '	  if [ -d $(stage)/$$dir ]; then true; else '$mkinstalldirs' $(stage)/$$dir; fi; \'
-echo '	done'
-echo '	-for dir in '"${dirs}"'; do \'
-echo '	  mv $$dir/*'"${objext}"' $(stage)/$$dir; \'
-echo '	  mv $$dir/*'"${objext}s"' $(stage)/$$dir || true; \'
-echo '	  test ! -f $$dir/stacknote.s || mv $$dir/stacknote.s $(stage)/$$dir; \'
-echo '	  test ! -f $$dir/libgcc.a || mv $$dir/lib* $(stage)/$$dir; \'
-echo '	done'
+echo
+echo "libgcc-stage-start:"
+echo "	for dir in ${dirs}; do \\"
+echo "	  if [ -d \$(stage)/\$\$dir ]; then :; \\"
+echo "	  else $mkinstalldirs \$(stage)/\$\$dir; fi; \\"
+echo "	done"
+echo "	-for dir in ${dirs}; do \\"
+echo "	  mv \$\$dir/*${objext} \$(stage)/\$\$dir; \\"
+echo "	  mv \$\$dir/*.vis \$(stage)/\$\$dir; \\"
+echo "	  test ! -f \$\$dir/libgcc.a || mv \$\$dir/lib* \$(stage)/\$\$dir; \\"
+echo "	done"
 
 echo ""
 all=stmp-dirs
@@ -585,18 +784,18 @@ for ml in $MULTILIBS; do
       fi
       all="$all ${dir}/libgcc_s${suff}${SHLIB_EXT}"
       if [ "$LIBUNWIND" ]; then
-	all="$all ${dir}/${dir}/libunwind${suff}${SHLIB_EXT}"
+	all="$all ${dir}/libunwind${suff}${SHLIB_EXT}"
       fi
     elif [ "$SHLIB_MULTILIB" = "$dir" ]; then
       all="$all libgcc_s${SHLIB_EXT}"
       if [ "$LIBUNWIND" ]; then
-	all="$all ${dir}/${dir}/libunwind${SHLIB_EXT}"
+	all="$all ${dir}/libunwind${SHLIB_EXT}"
       fi
     fi
   fi
 done
 
-echo 'stmp-dirs: force'
+echo 'stmp-dirs:'
 echo '	for d in '"$dirs"'; do \'
 echo '	  if [ -d $$d ]; then true; else '$mkinstalldirs' $$d; fi; \'
 echo '	done'
@@ -626,10 +825,10 @@ for f in $EXTRA_MULTILIB_PARTS; do
 done
 
 echo ""
-echo "all: $all"
+echo "all-real: $all"
 
 echo ""
-echo "install: $all"
+echo "install: all-real"
 for ml in $MULTILIBS; do
   dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
   flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
@@ -728,3 +927,5 @@ for f in $EXTRA_MULTILIB_PARTS; do
     echo '	$(INSTALL_DATA)' $out $ldir/
   done
 done
+
+echo '.PHONY: all all-real install'
===================================================================
Index: Makefile.in
--- Makefile.in	22 Nov 2004 12:23:39 -0000	1.1424
+++ Makefile.in	25 Nov 2004 19:24:20 -0000
@@ -1235,6 +1235,7 @@ libgcc.mk: config.status Makefile mklibg
 	SHLIB_MAPFILES='$(SHLIB_MAPFILES)' \
 	SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \
 	MULTILIB_OSDIRNAMES='$(MULTILIB_OSDIRNAMES)' \
+	ASM_HIDDEN_OP='$(ASM_HIDDEN_OP)' \
 	mkinstalldirs='$(mkinstalldirs)' \
 	  $(SHELL) mklibgcc > tmp-libgcc.mk
 	mv tmp-libgcc.mk libgcc.mk
===================================================================
Index: config/darwin.h
--- config/darwin.h	23 Nov 2004 01:17:55 -0000	1.107
+++ config/darwin.h	25 Nov 2004 19:24:29 -0000
@@ -316,8 +316,8 @@ extern const char *darwin_fix_and_contin
 #define REAL_LIBGCC_SPEC \
    "%{static|static-libgcc:-lgcc -lgcc_eh}\
     %{!static:%{!static-libgcc:\
-      %{!Zdynamiclib:%{!shared-libgcc:-lgcc  -lgcc_eh}\
-      %{shared-libgcc:-lgcc_s -lgcc} } %{Zdynamiclib:-lgcc_s}}}"
+      %{!Zdynamiclib:%{!shared-libgcc:-lgcc -lgcc_eh}\
+      %{shared-libgcc:-lgcc_s -lgcc}} %{Zdynamiclib:-lgcc_s -lgcc}}}"
 
 /* We specify crt0.o as -lcrt0.o so that ld will search the library path.  */
 
===================================================================
Index: config/t-slibgcc-darwin
--- config/t-slibgcc-darwin	17 Nov 2004 05:39:02 -0000	1.5
+++ config/t-slibgcc-darwin	25 Nov 2004 19:24:29 -0000
@@ -34,3 +34,6 @@ SHLIB_INSTALL = \
 SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
 SHLIB_MKMAP_OPTS = -v leading_underscore=1
 SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
+
+# Must use a different directive for hidden visibility in assembly sources.
+ASM_HIDDEN_OP = .private_extern


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