From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 3FE163858D37; Fri, 28 Apr 2023 08:50:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3FE163858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682671851; bh=WJvW71mx1VTjD4n8EobBh/0PLOunUsEwD86+NeOaPB4=; h=From:To:Subject:Date:From; b=IPRjr9a9CXQsST2DuRQ+YWQ28f1eeXH7iyhyDQNmBfMZxkTR31sZmfUg6g9Gj9uzQ vmy4g/J5kAE4ma9stR4JURR78gUu6hLY2zbnK2jmttN8n6l6Rnx1Xv6vYZDeabVE3G IDcBH6TXBSSmTdtd4TgwsbZYq85FevBBlQGymUwo= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-321] libstdc++: Another attempt to ensure g++ 13+ compiled programs enforce gcc 13.2+ libstdc++.so.6 [PR1 X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/master X-Git-Oldrev: 889a0791c632aa2804c4e01cc7dddca1ae0d229c X-Git-Newrev: 9a41d2cdbcd2af77a3a91a840a3a13f0eb39971b Message-Id: <20230428085051.3FE163858D37@sourceware.org> Date: Fri, 28 Apr 2023 08:50:51 +0000 (GMT) List-Id: https://gcc.gnu.org/g:9a41d2cdbcd2af77a3a91a840a3a13f0eb39971b commit r14-321-g9a41d2cdbcd2af77a3a91a840a3a13f0eb39971b Author: Jakub Jelinek Date: Fri Apr 28 10:49:40 2023 +0200 libstdc++: Another attempt to ensure g++ 13+ compiled programs enforce gcc 13.2+ libstdc++.so.6 [PR108969] GCC used to emit an instance of an empty ios_base::Init class in every TU which included to ensure it is std::cout etc. is initialized, but thanks to Patrick work on some targets (which have init_priority attribute support) it is now initialized only inside of libstdc++.so.6/libstdc++.a. This causes a problem if people do something that has never been supported, try to run GCC 13 compiled C++ code against GCC 12 or earlier libstdc++.so.6 - std::cout etc. are then never initialized because code including expects the library to initialize it and the library expects code including to do that. The following patch is second attempt to make this work cheaply as the earlier attempt of aliasing the std::cout etc. symbols with another symbol version didn't work out due to copy relocation breaking the aliases appart. The patch forces just a _ZSt21ios_base_library_initv undefined symbol into all *.o files which include and while there is no runtime relocation against that, it seems to enforce the right version of libstdc++.so.6. /home/jakub/src/gcc/obj08i/usr/local/ is the install directory of trunk patched with this patch, /home/jakub/src/gcc/obj06/ is builddir of trunk without this patch, system g++ is GCC 12.1.1. $ cat /tmp/hw.C #include int main () { std::cout << "Hello, world!" << std::endl; } $ cd /home/jakub/src/gcc/obj08i/usr/local/bin $ ./g++ -o /tmp/hw /tmp/hw.C $ readelf -Wa /tmp/hw 2>/dev/null | grep initv 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZSt21ios_base_library_initv@GLIBCXX_3.4.32 (4) 71: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZSt21ios_base_library_initv@GLIBCXX_3.4.32 $ /tmp/hw /tmp/hw: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by /tmp/hw) $ LD_LIBRARY_PATH=/home/jakub/src/gcc/obj08i/usr/local/lib64/ /tmp/hw Hello, world! $ LD_LIBRARY_PATH=/home/jakub/src/gcc/obj06/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/ /tmp/hw /tmp/hw: /home/jakub/src/gcc/obj06/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by /tmp/hw) $ g++ -o /tmp/hw /tmp/hw.C $ /tmp/hw Hello, world! $ LD_LIBRARY_PATH=/home/jakub/src/gcc/obj06/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/ /tmp/hw Hello, world! $ LD_LIBRARY_PATH=/home/jakub/src/gcc/obj08i/usr/local/lib64/ /tmp/hw Hello, world! On sparc-sun-solaris2.11 one I've actually checked a version which had defined(_GLIBCXX_SYMVER_SUN) next to defined(_GLIBCXX_SYMVER_GNU), but init_priority attribute doesn't seem to be supported there and so I couldn't actually test how this works there. Using gas and Sun ld, Rainer, does one need to use gas + gld for init_priority or something else? 2023-04-28 Jakub Jelinek PR libstdc++/108969 * config/abi/pre/gnu.ver (GLIBCXX_3.4.32): Export _ZSt21ios_base_library_initv. * testsuite/util/testsuite_abi.cc (check_version): Add GLIBCXX_3.4.32 symver and make it the latestp. * src/c++98/ios_init.cc (ios_base_library_init): New alias. * acinclude.m4 (libtool_VERSION): Change to 6:32:0. * include/std/iostream: If init_priority attribute is supported and _GLIBCXX_SYMVER_GNU, force undefined _ZSt21ios_base_library_initv symbol into the object. * configure: Regenerated. Diff: --- libstdc++-v3/acinclude.m4 | 2 +- libstdc++-v3/config/abi/pre/gnu.ver | 4 ++++ libstdc++-v3/configure | 2 +- libstdc++-v3/include/std/iostream | 2 ++ libstdc++-v3/src/c++98/ios_init.cc | 5 +++++ libstdc++-v3/testsuite/util/testsuite_abi.cc | 3 ++- 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 5136c0571e8..89e7f5f5f45 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3841,7 +3841,7 @@ changequote([,])dnl fi # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:31:0 +libtool_VERSION=6:32:0 # Everything parsed; figure out what files and settings to use. case $enable_symvers in diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 4ae63094eb7..36bb87880d7 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -2514,6 +2514,10 @@ GLIBCXX_3.4.31 { } GLIBCXX_3.4.30; +GLIBCXX_3.4.32 { + _ZSt21ios_base_library_initv; +} GLIBCXX_3.4.31; + # Symbols in the support library (libsupc++) have their own tag. CXXABI_1.3 { diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 68ee94c9e28..99f4927aa8c 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -68652,7 +68652,7 @@ $as_echo "$as_me: WARNING: === Symbol versioning will be disabled." >&2;} fi # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:31:0 +libtool_VERSION=6:32:0 # Everything parsed; figure out what files and settings to use. case $enable_symvers in diff --git a/libstdc++-v3/include/std/iostream b/libstdc++-v3/include/std/iostream index 76530029b86..cfd124dcf43 100644 --- a/libstdc++-v3/include/std/iostream +++ b/libstdc++-v3/include/std/iostream @@ -77,6 +77,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // in the compiled library instead (src/c++98/globals_io.cc). #if !__has_attribute(__init_priority__) static ios_base::Init __ioinit; +#elif defined(_GLIBCXX_SYMVER_GNU) + __extension__ __asm (".globl _ZSt21ios_base_library_initv"); #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/src/c++98/ios_init.cc b/libstdc++-v3/src/c++98/ios_init.cc index 6b43a6bf563..0c2ba945f36 100644 --- a/libstdc++-v3/src/c++98/ios_init.cc +++ b/libstdc++-v3/src/c++98/ios_init.cc @@ -199,5 +199,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret; } +#ifdef _GLIBCXX_SYMVER_GNU + void ios_base_library_init (void) + __attribute__((alias ("_ZNSt8ios_base4InitC1Ev"))); +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 5b7d0435110..cea6c217433 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -213,6 +213,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_LDBL_3.4.29"); known_versions.push_back("GLIBCXX_3.4.30"); known_versions.push_back("GLIBCXX_3.4.31"); + known_versions.push_back("GLIBCXX_3.4.32"); known_versions.push_back("GLIBCXX_LDBL_3.4.31"); known_versions.push_back("GLIBCXX_IEEE128_3.4.29"); known_versions.push_back("GLIBCXX_IEEE128_3.4.30"); @@ -251,7 +252,7 @@ check_version(symbol& test, bool added) test.version_status = symbol::incompatible; // Check that added symbols are added in the latest pre-release version. - bool latestp = (test.version_name == "GLIBCXX_3.4.31" + bool latestp = (test.version_name == "GLIBCXX_3.4.32" // XXX remove next 2 lines when baselines have been regenerated. || test.version_name == "GLIBCXX_IEEE128_3.4.31" || test.version_name == "GLIBCXX_LDBL_3.4.31"