libstdc++: Enable _GLIBCXX_WEAK_DEFINITION on more platforms

Message ID 20221019191929.3262862-1-arsen@aarsen.me
State Accepted
Headers
Series libstdc++: Enable _GLIBCXX_WEAK_DEFINITION on more platforms |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Arsen Arsenović Oct. 19, 2022, 7:19 p.m. UTC
  This should permit redefining `operator new' where-ever that is
possible, and should allow libsupc++ to be more broadly useful in
freestanding.

libstdc++-v3/ChangeLog:

	* acinclude.m4: Add link test for __attribute__ ((weak)).
	* config.h.in: Regenerate.
	* config/os/bsd/darwin/os_defines.h (_GLIBCXX_WEAK_DEFINITION):
	Remove.  It's defined by configure.ac now, depending on a link
	test and host configuration.
	* configure.ac: Define _GLIBCXX_WEAK_DEFINITION according to
	link test and configure.host/crossconfig.
	* configure: Regenerate.
	* configure.host: Set force_enable_attr_weak for ELF and Darwin
	targets.
	* include/bits/c++config: Remove redundant
	_GLIBCXX_WEAK_DEFINITION default.
---
Evening,

This patch should permit more targets to redefine operators new and delete, and
any other function we might see fit in the future.
There's currently a few points of discussion/consideration here, most notably,
can giving a bunch of targets weak definitions of operators new and delete be
considered an ABI break?  If so, the link test should be dropped in favor of
targets enabling it explicitly (which is useful for new targets, e.g. a
kernel).  The only hypothetical I could think of ``going wrong'' is a link test
that attempts to detect whether operators new/delete can be redefined, and if
so, changes program behaviour in some way, but I've never observed this, and I
fail to come up with why a silent fallback would be useful in such a case.
Second (though, worthy of it's own patchset) point would be considering whether
any other functions in libsupc++ should be weak.

WDYT?

Thanks.

 libstdc++-v3/acinclude.m4                      | 10 ++++++++++
 libstdc++-v3/config.h.in                       |  3 +++
 libstdc++-v3/config/os/bsd/darwin/os_defines.h |  6 ------
 libstdc++-v3/configure.ac                      | 15 +++++++++++++++
 libstdc++-v3/configure.host                    | 12 ++++++++++++
 libstdc++-v3/include/bits/c++config            |  7 -------
 6 files changed, 40 insertions(+), 13 deletions(-)
  

Comments

Arsen Arsenović Nov. 14, 2022, 6:46 p.m. UTC | #1
Evening,

Similar to the other patch, pinging this before it drifts unreasonably
far into S3, and hence into GCC14.

Archive:
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603931.html

Have a great evening :)
  

Patch

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.,