diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c45b76cb102c63bca5a45a514ebd66715303f6c2..96652d2b153d17acaa1f60a3098d1906730fafd7 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,19 @@
+2005-11-21  Benjamin Kosnik  <bkoz@redhat.com>
+            Ulrich Drepper  <drepper@redhat.com>
+
+	PR libstdc++/23591
+	* scripts/create_testsuite_files: Support for "C" test files.
+	* testsuite/lib/libstdc++.exp: Same.
+	* testsuite/libstdc++-dg/normal.exp: Same.
+	* testsuite/ext/mt_allocator/22309_thread.cc: Update names.
+	* testsuite/19_diagnostics/23591_thread-1.c: New.
+	* testsuite/testsuite_shared.cc: Add tests, rename existing functions.
+	* libsupc++/eh_globals.cc: Make global thread local if possible.
+	* configure.ac: Use GCC_CHECK_TLS.
+	* acinclude.m4: Include tls.m4.
+	* configure: Regenerate.
+	* config.h.in: Same.
+	
 2005-11-21  Benjamin Kosnik  <bkoz@redhat.com>
 
 	* libsupc++/del_op.cc: Include c++config.h first.
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 9b73b290eb4209ac07cef34e22f30dfb14a21d46..5d5e744d1888d91ffb3039065fd01906740c3af9 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -45,11 +45,12 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \
 	$(top_srcdir)/scripts/testsuite_flags.in ChangeLog
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index f4d11bfabbfef45abc6e9805f5432e7212704819..12d0eb6daf7aad2c80034b5d81bf79a0a97a2368 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -1648,8 +1648,8 @@ EOF
     rm -f conftest*
   fi
 
-  # This is a tad weird, for hysterical raisins.  We have to map enable/disable 
-  # to two different models.
+  # This is a tad weird, for hysterical raisins.  We have to map
+  # enable/disable to two different models.
   case $enable_sjlj_exceptions in
     yes)
       AC_DEFINE(_GLIBCXX_SJLJ_EXCEPTIONS, 1,
@@ -1878,5 +1878,6 @@ AC_DEFUN([AC_LC_MESSAGES], [
   ])
 ])
 
+# Macros from the top-level gcc directory.
+m4_include([../config/tls.m4])
 
-dnl vim:et:ts=2:sw=2
diff --git a/libstdc++-v3/aclocal.m4 b/libstdc++-v3/aclocal.m4
index 757e1cc3e69759459e0de2d37213da9060b34df9..8f4ca5225c68a3ce64fdbd22e795cf46864bb570 100644
--- a/libstdc++-v3/aclocal.m4
+++ b/libstdc++-v3/aclocal.m4
@@ -638,6 +638,7 @@ AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
+m4_include([../config/enable.m4])
 m4_include([../config/lead-dot.m4])
 m4_include([../config/no-executables.m4])
 m4_include([../libtool.m4])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 6fb113d0bfa869bac89d6f81ecb8876fccd21028..2aa1341ec7e6a3f692f50f8cc601cafddd7a7777 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -355,6 +355,9 @@
 /* Define to 1 if you have the `tanl' function. */
 #undef HAVE_TANL
 
+/* Define to 1 if the target supports thread-local storage. */
+#undef HAVE_TLS
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 21a20bc427a789e1b9a0a158905df34d554a100d..7c2ed9875c5d5236b452d9abf65967d3c9f34381 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -887,6 +887,8 @@ Optional Features:
   --enable-fully-dynamic-string
                           do not put empty strings in per-process static
                           memory [default=no]
+  _g_switchUse thread-local storage
+                          [default=yes]
   --enable-symvers=STYLE  enables symbol versioning of the shared library
                           [default=yes]
   --enable-version-specific-runtime-libs
@@ -4456,7 +4458,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4459 "configure"' > conftest.$ac_ext
+  echo '#line 4461 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -5076,7 +5078,7 @@ fi;
     #
     # Fake what AC_TRY_COMPILE does.  XXX Look at redoing this new-style.
     cat > conftest.$ac_ext << EOF
-#line 5079 "configure"
+#line 5081 "configure"
 struct S { ~S(); };
 void bar();
 void foo()
@@ -5104,8 +5106,8 @@ EOF
     rm -f conftest*
   fi
 
-  # This is a tad weird, for hysterical raisins.  We have to map enable/disable
-  # to two different models.
+  # This is a tad weird, for hysterical raisins.  We have to map
+  # enable/disable to two different models.
   case $enable_sjlj_exceptions in
     yes)
 
@@ -29929,6 +29931,135 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+  # For TLS support.
+
+   # Check whether --enable-tls or --disable-tls was given.
+if test "${enable_tls+set}" = set; then
+  enableval="$enable_tls"
+
+      case "$enableval" in
+       yes|no) ;;
+       *) { { echo "$as_me:$LINENO: error: Argument to enable/disable tls must be yes or no" >&5
+echo "$as_me: error: Argument to enable/disable tls must be yes or no" >&2;}
+   { (exit 1); exit 1; }; } ;;
+      esac
+
+else
+  enable_tls=yes
+fi;
+
+  echo "$as_me:$LINENO: checking whether the target supports thread-local storage" >&5
+echo $ECHO_N "checking whether the target supports thread-local storage... $ECHO_C" >&6
+if test "${have_tls+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+__thread int foo;
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_tls=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_tls=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+__thread int a; int b; int main() { return a = b; }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+                    save_LDFLAGS="$LDFLAGS"
+      LDFLAGS="-static $LDFLAGS"
+      if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+__thread int a; int b; int main() { return a = b; }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_tls=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_tls=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+      LDFLAGS="$save_LDFLAGS"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_tls=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $have_tls" >&5
+echo "${ECHO_T}$have_tls" >&6
+  if test "$enable_tls $have_tls" = "yes yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS 1
+_ACEOF
+
+  fi
+
 
   if test "${ac_cv_header_locale_h+set}" = set; then
   echo "$as_me:$LINENO: checking for locale.h" >&5
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 986c0ef39faa2b2d912703755c1ac297dfbc6008..9db10226dcabda4d1e00abcb1998518fa5f46c30 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -157,6 +157,9 @@ if $GLIBCXX_IS_NATIVE; then
   # For LFS support.
   GLIBCXX_CHECK_LFS
 
+  # For TLS support.
+  GCC_CHECK_TLS
+
   AC_LC_MESSAGES
 
   AC_TRY_COMPILE(
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index cfdfdf2283eb49eaa945b2f9d069bd203f2b1b3f..a0c358c6cad59b665c55ca0d439d6b2b73292500 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/fragment.am
 subdir = include
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 CONFIG_HEADER = $(top_builddir)/config.h
diff --git a/libstdc++-v3/libmath/Makefile.in b/libstdc++-v3/libmath/Makefile.in
index af3d6c1fc7c5676e17dab23b367f3a7ca7c41b1a..73cd3ca127e7546917c48d064dbe6407f3868b3a 100644
--- a/libstdc++-v3/libmath/Makefile.in
+++ b/libstdc++-v3/libmath/Makefile.in
@@ -40,11 +40,12 @@ target_triplet = @target@
 subdir = libmath
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 CONFIG_HEADER = $(top_builddir)/config.h
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index 016bdb3dba9d3e2f4d3663542bff4c6dc2b10b35..1d5ee5695b4b1839277ddab8751b2da21a5846c6 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -42,11 +42,12 @@ DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(top_srcdir)/fragment.am
 subdir = libsupc++
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 CONFIG_HEADER = $(top_builddir)/config.h
diff --git a/libstdc++-v3/libsupc++/eh_globals.cc b/libstdc++-v3/libsupc++/eh_globals.cc
index 00465dedf93a311582ed11dbb79e029945d9609a..9b7e916716d52252008d1c8a08e45d6e4aab8763 100644
--- a/libstdc++-v3/libsupc++/eh_globals.cc
+++ b/libstdc++-v3/libsupc++/eh_globals.cc
@@ -1,5 +1,5 @@
 // -*- C++ -*- Manage the thread-local exception globals.
-// Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -27,101 +27,127 @@
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-
+#include <bits/c++config.h>
 #include <exception>
 #include <cstdlib>
+#include "cxxabi.h"
 #include "unwind-cxx.h"
-#include "bits/c++config.h"
 #include "bits/gthr.h"
 
 using namespace __cxxabiv1;
 
+#if _GLIBCXX_HAVE_TLS
+
+namespace __gnu_internal
+{
+  using namespace abi;
+  using namespace std;
+
+  __cxa_eh_globals*
+  get_global() throw()
+  {
+    static __thread __cxa_eh_globals global;
+    return &global;
+  }
+}
+
+extern "C" __cxa_eh_globals*
+__cxxabiv1::__cxa_get_globals_fast() throw()
+{ return __gnu_internal::get_global(); }
+
+extern "C" __cxa_eh_globals*
+__cxxabiv1::__cxa_get_globals() throw()
+{ return __gnu_internal::get_global(); }
+
+
+#else
 
 // Single-threaded fallback buffer.
-static __cxa_eh_globals globals_static;
+static __cxa_eh_globals eh_globals;
 
 #if __GTHREADS
-static __gthread_key_t globals_key;
-static int use_thread_key = -1;
 
 static void
-get_globals_dtor (void *ptr)
+eh_globals_dtor(void* ptr)
 {
   if (ptr)
     {
-      __cxa_exception *exn, *next;
-      exn = ((__cxa_eh_globals *) ptr)->caughtExceptions;
+      __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr);
+      __cxa_exception* exn = g->caughtExceptions;
+      __cxa_exception* next;
       while (exn)
 	{
 	  next = exn->nextException;
-	  _Unwind_DeleteException (&exn->unwindHeader);
+	  _Unwind_DeleteException(&exn->unwindHeader);
 	  exn = next;
 	}
-      std::free (ptr);
+      std::free(ptr);
     }
 }
 
-static void
-get_globals_init ()
+struct __eh_globals_init
 {
-  use_thread_key =
-    (__gthread_key_create (&globals_key, get_globals_dtor) == 0);
-}
-
-static void
-get_globals_init_once ()
+  __gthread_key_t  	_M_key;
+  bool 			_M_init;
+
+  __eh_globals_init() : _M_init(false)
+  { 
+    if (__gthread_active_p())
+      _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0; 
+  }
+
+  ~__eh_globals_init()
+  {
+    if (_M_init)
+      __gthread_key_delete(_M_key);
+  }
+};
+
+static __eh_globals_init init;
+
+extern "C" __cxa_eh_globals*
+__cxxabiv1::__cxa_get_globals_fast() throw()
 {
-  static __gthread_once_t once = __GTHREAD_ONCE_INIT;
-  if (__gthread_once (&once, get_globals_init) != 0
-      || use_thread_key < 0)
-    use_thread_key = 0;
+  __cxa_eh_globals* g;
+  if (init._M_init)
+    g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
+  else
+    g = &eh_globals;
+  return g;
 }
-#endif
 
-extern "C" __cxa_eh_globals *
-__cxxabiv1::__cxa_get_globals_fast () throw()
+extern "C" __cxa_eh_globals*
+__cxxabiv1::__cxa_get_globals() throw()
 {
-#if __GTHREADS
-  if (use_thread_key)
-    return (__cxa_eh_globals *) __gthread_getspecific (globals_key);
+  __cxa_eh_globals* g;
+  if (init._M_init)
+    {
+      g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
+      if (!g)
+	{
+	  void* v = std::malloc(sizeof(__cxa_eh_globals));
+	  if (v == 0 || __gthread_setspecific(init._M_key, v) != 0)
+	    std::terminate();
+	  g = static_cast<__cxa_eh_globals*>(v);
+	  g->caughtExceptions = 0;
+	  g->uncaughtExceptions = 0;
+	}
+    }
   else
-    return &globals_static;
-#else
-  return &globals_static;
-#endif
+    g = &eh_globals;
+  return g;
 }
 
-extern "C" __cxa_eh_globals *
-__cxxabiv1::__cxa_get_globals () throw()
-{
-#if __GTHREADS
-  __cxa_eh_globals *g;
-
-  if (use_thread_key == 0)
-    return &globals_static;
+#else
 
-  if (use_thread_key < 0)
-    {
-      get_globals_init_once ();
+extern "C" __cxa_eh_globals*
+__cxxabiv1::__cxa_get_globals_fast() throw()
+{ return &eh_globals; }
 
-      // Make sure use_thread_key got initialized.
-      if (use_thread_key == 0)
-	return &globals_static;
-    }
+extern "C" __cxa_eh_globals*
+__cxxabiv1::__cxa_get_globals() throw()
+{ return &eh_globals; }
 
-  g = (__cxa_eh_globals *) __gthread_getspecific (globals_key);
-  if (! g)
-    {
-      if ((g = (__cxa_eh_globals *)
-	   std::malloc (sizeof (__cxa_eh_globals))) == 0
-	  || __gthread_setspecific (globals_key, (void *) g) != 0)
-        std::terminate ();
-      g->caughtExceptions = 0;
-      g->uncaughtExceptions = 0;
-    }
+#endif
 
-  return g;
-#else
-  return &globals_static;
 #endif
-}
diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in
index 6252acf03621874fcdf082acaefeb6abb703c6b0..e814e23eb5c0501e5ed6d162e049c56d67837788 100644
--- a/libstdc++-v3/po/Makefile.in
+++ b/libstdc++-v3/po/Makefile.in
@@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/fragment.am
 subdir = po
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 CONFIG_HEADER = $(top_builddir)/config.h
diff --git a/libstdc++-v3/scripts/create_testsuite_files b/libstdc++-v3/scripts/create_testsuite_files
index 4b9a41fc5fc5090111351cb356a4b57161d5d6d2..d5305236140aed1f7347836d32d8531556cda422 100755
--- a/libstdc++-v3/scripts/create_testsuite_files
+++ b/libstdc++-v3/scripts/create_testsuite_files
@@ -35,7 +35,9 @@ dlist=`echo [0-9][0-9]*`
 for d in [a-z]*; do
   test -d $d && dlist="$dlist $d"
 done
-find $dlist "(" -type f -o -type l ")" -name "*.cc" -print | sort > $tmp.1
+find $dlist "(" -type f -o -type l ")" -name "*.cc" -print > $tmp.01
+find $dlist "(" -type f -o -type l ")" -name "*.c" -print > $tmp.02
+cat  $tmp.01 $tmp.02 | sort > $tmp.1
 if test ! -s "$tmp.1"; then
   exit 1
 fi
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index d205c01eac86f0adaf771b84edc8d624c69d8cdc..f285e898e68872d7b2d96ca2734105718d5f63e2 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/fragment.am
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 CONFIG_HEADER = $(top_builddir)/config.h
diff --git a/libstdc++-v3/testsuite/19_diagnostics/23591_thread-1.c b/libstdc++-v3/testsuite/19_diagnostics/23591_thread-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c953eaed0e9f4207800234b17c7c2ff6e05238a
--- /dev/null
+++ b/libstdc++-v3/testsuite/19_diagnostics/23591_thread-1.c
@@ -0,0 +1,63 @@
+// { dg-require-sharedlib "" }
+// { dg-options "-g -O2 -pthread -ldl -x c" { target *-*-linux* } }
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <pthread.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+// NB: This must be compiled and linked as a "C" executable.
+static void* run(void* arg)
+{
+  typedef void (*function_type) (void);
+  void* lib;
+  void (*cb)();
+
+  lib = dlopen("./testsuite_shared.so", RTLD_NOW);
+  if (lib == NULL)
+    {
+      printf("dlopen failed: %s\n", strerror(errno));
+      return NULL;
+    }
+  cb = (function_type) dlsym(lib, "try_throw_exception");
+  if (cb == NULL)
+    {
+      printf("dlsym failed: %s\n", strerror(errno));
+      return NULL;
+    }
+  cb();
+  dlclose(lib);
+  return NULL;
+}
+
+// libstdc++/23591
+int main(void)
+{
+  pthread_t pt;
+
+  if (pthread_create(&pt, NULL, &run, NULL) != 0)
+    return 1;
+  if (pthread_join(pt, NULL) != 0)
+    return 1;
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index dcfb5f8069607d90a2fcc48e8e4b2ffabf320545..0b25a5a868692461b03eaef69de7e557ecdc8694 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/fragment.am
 subdir = testsuite
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+	$(top_srcdir)/../config/lead-dot.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
 	$(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \
 	$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 CONFIG_HEADER = $(top_builddir)/config.h
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc b/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc
index f2243657a5d847b00475f8cd04885f52bbfbddd0..1df94b7c666b91fdc0f1eb9cca3823db7bccdcae 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc
@@ -50,7 +50,7 @@ check_dlsym(void*& h)
 
   typedef void (*function_type) (void);
   function_type fn;
-  fn = reinterpret_cast<function_type>(dlsym(h, "foo"));
+  fn = reinterpret_cast<function_type>(dlsym(h, "try_allocation"));
 
   try 
     {
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 0f10e6dff917b7aaf6f1ab296f73675225e74358..ee5111dfaf979558eb2ce677d3c9cc2a032ecb1a 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -266,14 +266,32 @@ proc libstdc++-dg-test { prog do_what extra_tool_flags } {
             # created or not.  If it was, dg.exp will try to run it.
             remote_file build delete $output_file;
         }
-        default {
+	default {
             perror "$do_what: not a valid dg-do keyword"
             return ""
         }
     }
+
     set options ""
     if { $extra_tool_flags != "" } {
-        lappend options "additional_flags=$extra_tool_flags"
+	verbose -log "extra_tool_flags are:"
+	verbose -log $extra_tool_flags
+	if { [string first "-x c" $extra_tool_flags ] != -1 } {
+	    # Short-circut a bunch of complicated goo here for the
+	    # special case of compiling a test file as a "C" file, not
+	    # as C++: just use target_compile, instead of the usual
+	    # gimmicks.
+	    verbose -log "compiling and executing as C, not C++"
+            set compile_type "executable"
+            set output_file "./[file rootname [file tail $prog]].exe"
+            remote_file build delete $output_file;
+	    lappend options "additional_flags=$extra_tool_flags"
+	    set comp_output [target_compile "$prog" "$output_file" "$compile_type" $options];
+	    set comp_output [ prune_g++_output $comp_output ];
+	    return [list $comp_output $output_file]
+        } else {
+	    lappend options "additional_flags=$extra_tool_flags"
+	}
     }
 
     # There is a libstdc++_compile made for us by default (via the tool-
@@ -608,8 +626,7 @@ proc check_v3_target_debug_mode { } {
 	set et_debug_mode 0
 
 	# Set up, compile, and execute a C++ test program that depends
-	# on correct ordering of static object destructors. This is
-	# indicative of the presence and use of __cxa_atexit.
+	# on debug mode working.
 	set src debug_mode[pid].cc
 	set exe debug_mode[pid].exe
 
diff --git a/libstdc++-v3/testsuite/libstdc++-dg/normal.exp b/libstdc++-v3/testsuite/libstdc++-dg/normal.exp
index 6ebe6b439ec6c8e65a75ca52f4440c1e0ba5035c..21bc3c1b9150f41c854ca649b980abba6ae3af38 100644
--- a/libstdc++-v3/testsuite/libstdc++-dg/normal.exp
+++ b/libstdc++-v3/testsuite/libstdc++-dg/normal.exp
@@ -1,4 +1,4 @@
-# Primary test file for libstdc++.
+# Functional and regression tests in C++ for libstdc++.
 
 # Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 #
@@ -61,6 +61,11 @@ if {[info exists tests_file] && [file exists $tests_file]} {
     # Find all the tests.
     foreach s $subdirs {
 	set subdir_tests [find $s *.cc]
+	set subdir_tests_c [find $s *.c]
+	foreach e $subdir_tests_c {
+	    lappend subdir_tests $e
+	}
+
 	# Filter out tests that should not be run.
 	foreach t $subdir_tests {
 	    # The DejaGNU "find" procedure sometimes returns a list 
diff --git a/libstdc++-v3/testsuite/testsuite_shared.cc b/libstdc++-v3/testsuite/testsuite_shared.cc
index a829fb47aa74bd131a6ebffc53b4e3b8a6a0154d..58803a2ae4f4c15cb923d63d8d119e622f8915ef 100644
--- a/libstdc++-v3/testsuite/testsuite_shared.cc
+++ b/libstdc++-v3/testsuite/testsuite_shared.cc
@@ -17,11 +17,14 @@
 // USA.
 
 #include <string>
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
 #include <ext/mt_allocator.h>
 
 // libstdc++/22309
 extern "C" void
-foo()
+try_allocation()
 {
   typedef char value_t;
 
@@ -34,3 +37,37 @@ foo()
   string_t s;
   s += "west beach, indiana dunes";
 }
+
+// libstdc++/23591
+extern "C" void 
+try_throw_exception()
+{
+  try
+    {
+      throw std::bad_exception();
+    }
+  catch (const std::exception& e)
+    { }
+}
+
+extern "C" void 
+try_function_random_fail()
+{
+  long seed = lrand48();
+  if (seed < 2000)
+    seed = 2000;
+
+  {
+    std::ostringstream s;
+    s << "random_throw, seed: " << seed << std::endl;
+    std::cout << s.str();
+  }
+
+  while (--seed > 0)
+    {
+      try_throw_exception();
+    }
+
+  // Randomly throw. See if other threads cleanup.
+  throw std::bad_exception();
+}