From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id DB6533858C52 for ; Fri, 28 Apr 2023 07:34:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DB6533858C52 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1682667289; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=EKyFiylEwzphNlUpeFcEsdGdHWRRLROIlxciUCCehVM=; b=V9ZrNzKppsnAO+gCx5YjhcW9cvoc03wloMQ8bVSbsEoMwpjISJJcV6qXYNjxq0DOmQ0vzB pjcnU8aKrGj1L37CD8vTGtNHLAAixT2mbmJ7LCj6f9P1pvE5O2+XmbXTPrtbzohJS7NGLS 4qDgI8Z1aNuoE/EU4SbBIfyXmpBHObA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-259-M4f2iGW-NgODscHQJ6IOuQ-1; Fri, 28 Apr 2023 03:34:45 -0400 X-MC-Unique: M4f2iGW-NgODscHQJ6IOuQ-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F3275800047; Fri, 28 Apr 2023 07:34:44 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.194.156]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B4823492C13; Fri, 28 Apr 2023 07:34:44 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 33S7Yftd834229 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 28 Apr 2023 09:34:42 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 33S7Yees834228; Fri, 28 Apr 2023 09:34:40 +0200 Date: Fri, 28 Apr 2023 09:34:40 +0200 From: Jakub Jelinek To: Jonathan Wakely , Patrick Palka Cc: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org, Rainer Orth Subject: [PATCH] libstdc++: Another attempt to ensure g++ 13+ compiled programs enforce gcc 13.2+ libstdc++.so.6 [PR108969] Message-ID: Reply-To: Jakub Jelinek MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi! 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! Bootstrapped/regtested on x86_64-linux, i686-linux and sparc-sun-solaris2.11 On the last 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? Ok for trunk and after a while for GCC 13.2? 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. --- libstdc++-v3/config/abi/pre/gnu.ver.jj 2023-04-20 09:36:09.415371050 +0200 +++ libstdc++-v3/config/abi/pre/gnu.ver 2023-04-27 17:58:44.599675359 +0200 @@ -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 { --- libstdc++-v3/testsuite/util/testsuite_abi.cc.jj 2023-01-16 11:52:17.495713257 +0100 +++ libstdc++-v3/testsuite/util/testsuite_abi.cc 2023-04-27 17:30:39.651173917 +0200 @@ -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" --- libstdc++-v3/src/c++98/ios_init.cc.jj 2023-01-16 11:52:16.995720625 +0100 +++ libstdc++-v3/src/c++98/ios_init.cc 2023-04-27 18:34:46.121276617 +0200 @@ -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 --- libstdc++-v3/acinclude.m4.jj 2023-02-02 09:53:31.745525704 +0100 +++ libstdc++-v3/acinclude.m4 2023-04-27 17:27:51.071626279 +0200 @@ -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 --- libstdc++-v3/include/std/iostream.jj 2023-01-16 11:52:16.968721023 +0100 +++ libstdc++-v3/include/std/iostream 2023-04-27 18:34:07.479837226 +0200 @@ -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 --- libstdc++-v3/configure.jj 2023-02-02 09:53:31.795524981 +0100 +++ libstdc++-v3/configure 2023-04-27 17:29:13.263429963 +0200 @@ -68652,7 +68652,7 @@ $as_echo "$as_me: WARNING: === Symbol ve 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 Jakub