diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 6523ba9a816..f3976cf80f4 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -273,6 +273,16 @@ AC_DEFUN([GLIBCXX_CHECK_LINKER_FEATURES], [
     fi
   fi
 
+  # Detect weak function support.
+  AC_CACHE_CHECK([whether __attribute__ ((weak)) works],
+                 [glibcxx_cv_can_use_attr_weak], [
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM([__attribute__ ((weak)) void f() {}], [])],
+      [glibcxx_cv_can_use_attr_weak=yes],
+      [glibcxx_cv_can_use_attr_weak=no])
+  ])
+  AC_MSG_RESULT($glibcxx_cv_can_use_attr_weak)
+
   # Set -z,relro.
   # Note this is only for shared objects.
   ac_ld_relro=no
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 2a3972eef54..11467d28417 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -1046,6 +1046,9 @@
 /* Define to 1 if a verbose library is built, or 0 otherwise. */
 #undef _GLIBCXX_VERBOSE
 
+/* Marks a definition as weak, if supported. */
+#undef _GLIBCXX_WEAK_DEFINITION
+
 /* Defined if as can handle rdrand. */
 #undef _GLIBCXX_X86_RDRAND
 
diff --git a/libstdc++-v3/config/os/bsd/darwin/os_defines.h b/libstdc++-v3/config/os/bsd/darwin/os_defines.h
index a8b6d4fa324..ac6dd0faaad 100644
--- a/libstdc++-v3/config/os/bsd/darwin/os_defines.h
+++ b/libstdc++-v3/config/os/bsd/darwin/os_defines.h
@@ -33,12 +33,6 @@
    links to, so there's no need for weak-ness for that.  */
 #define _GLIBCXX_GTHREAD_USE_WEAK 0
 
-// On Darwin, in order to enable overriding of operator new and delete,
-// GCC makes the definition of these functions weak, relies on the
-// loader to implement weak semantics properly, and uses
-// -flat_namespace to work around the way that it doesn't.
-#define _GLIBCXX_WEAK_DEFINITION __attribute__ ((weak))
-
 // Static initializer macro is buggy in darwin, see libstdc++/51906
 #define _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
 
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 42c453099f2..81d914b434a 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -420,6 +420,21 @@ else
   fi
 fi
 
+# Now that we gave link tests and crossconfig a chance to set
+# glibcxx_cv_can_use_attr_weak, apply it.  Also, force it if configure.host
+# says so.
+should_use_attr_weak="$glibcxx_cv_can_use_attr_weak"
+if test x"$force_enable_attr_weak" != xdefault; then
+  should_use_attr_weak="$force_enable_attr_weak"
+fi
+
+if test x"$should_use_attr_weak" = xyes; then
+  AC_DEFINE([_GLIBCXX_WEAK_DEFINITION], [__attribute__ ((weak))],
+            [Marks a definition as weak, if supported.])
+else
+  AC_DEFINE([_GLIBCXX_WEAK_DEFINITION], [])
+fi
+
 # Check for _Unwind_GetIPInfo.
 GCC_CHECK_UNWIND_GETIPINFO
 
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index ec32980aa0d..85afda61ee2 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -58,6 +58,9 @@
 #
 #   error_constants_dir    location of error_constants.h
 #                          defaults to os/generic.
+#   force_enable_attr_weak Forces GLIBCXX_USE_ATTR_WEAK to be (un)set, in spite
+#                          of link tests.  The default is to leave it up to the
+#                          tests, but setting either yes or no force.
 #
 # It possibly modifies the following variables:
 #
@@ -90,6 +93,7 @@ atomic_word_dir=cpu/generic
 atomic_flags=""
 atomicity_dir="cpu/generic"
 cpu_defines_dir="cpu/generic"
+force_enable_attr_weak=default
 try_cpu=generic
 abi_baseline_subdir_switch=--print-multi-directory
 abi_tweaks_dir="cpu/generic"
@@ -230,6 +234,7 @@ case "${host_os}" in
     # for proper treatment of coalesced symbols.
     OPT_LDFLAGS="${OPT_LDFLAGS} -Wl,-single_module -Wl,-flat_namespace"
     os_include_dir="os/bsd/darwin"
+    force_enable_attr_weak=yes
     ;;
   darwin8 | darwin8.* )
     # For 8+ compatibility is better if not -flat_namespace.
@@ -240,10 +245,12 @@ case "${host_os}" in
         ;;
     esac
     os_include_dir="os/bsd/darwin"
+    force_enable_attr_weak=yes
     ;;
   darwin*)
     # Post Darwin8, defaults should be sufficient.
     os_include_dir="os/bsd/darwin"
+    force_enable_attr_weak=yes
     ;;
   *djgpp*)      # leading * picks up "msdosdjgpp"
     os_include_dir="os/djgpp"
@@ -315,6 +322,11 @@ esac
 # Set any OS-dependent and CPU-dependent bits.
 # THIS TABLE IS SORTED.  KEEP IT THAT WAY.
 case "${host}" in
+  *-*-elf*)
+    # ELF targets always have __attribute__((weak)), and besides, this target
+    # is always a cross compile, so no link test is ever possible for it.
+    force_enable_attr_weak=yes
+    ;;
   *-*-linux* | *-*-uclinux*)
     case "${host_cpu}" in
       i[567]86)
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 191880fb99d..fbdab5066e9 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -670,13 +670,6 @@ namespace std
 # define _GLIBCXX_PSEUDO_VISIBILITY(V)
 #endif
 
-// Certain function definitions that are meant to be overridable from
-// user code are decorated with this macro.  For some targets, this
-// macro causes these definitions to be weak.
-#ifndef _GLIBCXX_WEAK_DEFINITION
-# define _GLIBCXX_WEAK_DEFINITION
-#endif
-
 // By default, we assume that __GXX_WEAK__ also means that there is support
 // for declaring functions as weak while not defining such functions.  This
 // allows for referring to functions provided by other libraries (e.g.,
