From nobody Mon Apr 25 23:22:12 2022 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 1B7A11994B3D for ; Mon, 25 Apr 2022 23:22:29 +0000 (UTC) (envelope-from marklmi@yahoo.com) Received: from sonic311-25.consmr.mail.gq1.yahoo.com (sonic311-25.consmr.mail.gq1.yahoo.com [98.137.65.206]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4KnLdc0s9Kz3RGC for ; Mon, 25 Apr 2022 23:22:28 +0000 (UTC) (envelope-from marklmi@yahoo.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650928940; bh=NjFvFwCwUdgR+9WlW6j52xyAcfmGrHWRsTBPhyq78+A=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From:Subject:Reply-To; b=FrgFyzWZTsFeE8v+EmUlU/bYg8J1p51PIQlvc3R5hWXRKGsQuoa10lpgs8jFl8/xwQY6UvDjde9rplfk7teXvlZrChDMI+VYxVuaXZRDEZpxQrbVOsAjDwYTev9PXO/exU6jJzKLW3DCv3yvH27eWSAl+6c49WhFgEGlG3+WJRX4XVzoiVLznnv2hAwBIHJ1cx8m+bI/gREOkkXwp142RUa3BHIyIhCvxiBadlOP3+eGbpgcxBcc5WrHHEQAriu9ylJdxnTpcx6oSSfe94mC0CRWFBjsyD40LEqs1zO7gJEzSgHf8s60XFVTQumpMI8uA3korFPmwJBdrpZylY/wOA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650928940; bh=n6Pm/t8iWROfUuxcubH/8gjfFdf6Het7tRzy9tKlegj=; h=X-Sonic-MF:Subject:From:Date:To:From:Subject; b=ToNMSs4LdQ6IvVcVOh6dA8LfwB1g7wAq/vIhrO97ilmYD0Jljn1NO+DAwkikn5jl47Exrr2UoHUURDZFkGxFH6uYJ9tX0qwO0C9ntxrb5Jnjb6YolxLeWkohbI8qO4zHa1wNNSZjAGW2/F4hXL5Bb667lKHl7kEX8kbz+oRl2E80epb4FBKYiB9qjYMQltSXKWQRxVzp51MmGFmRCsckmCistalFmE185Otf98xn43Rf//RteMHE5eNy1EQBMl9CPkXIsFVFXUbYgVWEkOAosjcRPC29K7gow9Bih+P+lg/X8ziBBp+LSAURU7RGzUhoRAXrn/Z17nQbfeW7swx1rg== X-YMail-OSG: oLDRER8VM1le9LnOgpMhXbfc9I2W3rqcBypw5aCblPoWRqCzvrFmmzlV8lojhtP rnbNEZTDhpPQKVTxxQPHxU9a5sgZKLQZr0agnVGohFt.ylH94nRIhaKiKmVgEx5WrqIuFRUtHnNE 38SsF3KJ.WP2R21ZMRoZOwMsCGsMioOn.d6DY8usdRe0jUwVTN1ilSFfBNJ8uAbVctb2UhPWMBLw YvSg2uiZvlgQdTUBGFwOEGWWdEPhrp72FPrW28TN.NYft7YaJbA4TbhK9ywCY16PVY3uxYeyhK6c 7dgKl99a2jjEEh7MHkvn0SOOLUI5OKJUdqiKNW4A4kyHd9urGKpDpu7BjlymM7zRYXcIJcYpIlk6 OLgWuF4nKGAXHYzYU6SqmS69KYUKeXHfuvUGv_oEq5T7mM6QO9Psr3rxqRRsUg85ATVK92G88HUX s0ZgOoQ_mLiP35TsNNFju5BBOU83BcOgx5toh2t9ZaK5m0PFX8rWZcphwwp7ky_5._lexRpJpxfo fDmtwhSbGdMFWWcueO1bI8nuZGWgyJh4L9khpJ0a_swRyvC2myYcatKzbcQrf_NYZD_7Ccm0IKn7 5OJH0.b75GKAICLVMOz5kMN2mDJ7frsSfO9gLHUqsYhS4J1j2c06tMv..ZU6PGl5WST5No8NCj1Q pQVFr4fPYMaxQqZSUBd6tk2BDYdfL9iTrpUhvShPxiSganw7K_Emaut_nJGAdHTmN7evGKhg7m.U moeuaPzTGqXBHaPI7ZoH2lh6jKX3USPJXySWJiwGqh8P4btIOt1Tj1zEv70wuKgURxjdANQVs8Zx v1et992OO0O4FrdmbDHAgQrVkfmMrR0d3dAFzcuTAGW1866HDwdExW_DYTho4LXz1V5CPlbTjzXm cm4Muw17rP3qlOEgroRKPsccjcgteI8qBi9BVj6TmJti2l8g_0Wi8X.W2xp0GZRwzBmAMDKl2TRg rBcu2byLjrIo_0xaWfSnN5NiHMlv_1mua.WUSdLjJzrJOQ7N6tClb9JdH6qfcNFklu47HlusGqJD P8rnWA6jSkFmuSU5RTAC_B68II_R.CM.z8wv414kPwaHoCULS7ZjnT.el7Mk1ZGECPVQ_kC4qalZ DhoPdzkQiqmm8ej7fdxogZ4m_qvUt.n.YqYYw7af55ds49hJbWaoai2k1Ae44SARvMcohcZ5iXiS 9ZQffA2fCgs0T3m4NB75B4429auDU8jQdbxZMs0luKb4TbWxzt4kBQctHZ99nK0ULzQVfea.45cz 3m5eepXiUI2RLFDIoDXm7pPqovBiLcRbGsafQQsNAj2Y6qMwhoxok9fCm35V92Z48SCG.dmjoi6y f_U5csDikURUC5mTd0Q.2W93dY6E3ghPyEijkDMmfLT71ug6pLJ565Uq3AHjv2gTfNHZt5o5KSsD JBxU6hmHHkBPYS6uCn8RD_rSF11UyGuevXXHfZIIuu08tRBEur_lG9nZoRbgTXZ2KIglZaeE2I_m wL5NT2vyOYw1vkkd9nofJ1DST07DCNb9JTlE_1h3l4RN.d2WUOdfFh6E5dap3uwobGq0BAJQBjIW coJJgCkpcB7771ENEwy2MjrCM.4sFMze5WlBh27K3htOJt9Hl93W1EDMU.zjTKJexZdKyxZFGm.b nMW2G0VWyHEhIP0yVcVWkYps.EJCsosQZTY8kE5MKCg_wVWWhfJdmvG97wlgxbEi0C7UmT2bVV9t iEZ65SI9t9xRx6B8QFXhvW3b0HtuE4H9OucX5.9bJwobufczIuw8MTcpekBqmhu1VcplUAv44frK h3om.s4s3uT_qznSTWEaIQuXrmpPe9DuN8mBq1coLKI7sMCbwqvPAiAoeTbTudYymzsYUMdB8HsW _UTtKVKOWy1PwqA.E1dsxQ_KXzDHjIXi_he5wvDgo6A.iIC4NDrQfVv6gWzGPs3iiAJ6zNUiPZaj SICUpMB0n75dsVJh9F97Q1J4uLJugKlSvdE1rTwy8HtzpzsgSEmEO_GArn3IQml1E5Rk9Ge8L1b7 olRDpT3fgeB37j8a_5QulwmneCyzAFL56.WjwoQ0Z57DxBpfdUf.IYoL4oik.mNpl8Z9hj2GK84p lOEmtl.iW73QyUGE_._pPTJotWOoVtykNoBo12k0CHmzmtmZiuksTMbZXwdyjyXqnIz6SwkezWVw BSRzbwKxduvIL29gIARuu.KXvIkJtlONGnszFZyJjzxDDyJ0LltILuZIMF2DRxLZte7XAL.Hpl3a pCUWE8YYrlQidgt0zzVbVXMUef8Gz.ob2GmiefdbSvTr5bpv_Mk4y._0JEGGq88A098fF3mtiuqB IOWNbsbDdNCAcSm9gfAarITNlzbK6zA-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.gq1.yahoo.com with HTTP; Mon, 25 Apr 2022 23:22:20 +0000 Received: by hermes--canary-production-bf1-7cfdddd556-6zdns (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 5f2497e382a047bcfe300b0838d011f2; Mon, 25 Apr 2022 23:22:15 +0000 (UTC) Content-Type: text/plain; charset=utf-8 List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.120.0.1.13\)) Subject: Re: llvm & RTTI over shared libraries From: Mark Millard In-Reply-To: <079B1A26-DA8B-4158-8FD4-28EE1374CF1F@yahoo.com> Date: Mon, 25 Apr 2022 16:22:12 -0700 Cc: joerg@bec.de Content-Transfer-Encoding: quoted-printable Message-Id: References: <079B1A26-DA8B-4158-8FD4-28EE1374CF1F@yahoo.com> To: jbo@insane.engineer, FreeBSD Hackers X-Mailer: Apple Mail (2.3654.120.0.1.13) X-Rspamd-Queue-Id: 4KnLdc0s9Kz3RGC X-Spamd-Bar: - Authentication-Results: mx1.freebsd.org; dkim=pass header.d=yahoo.com header.s=s2048 header.b=FrgFyzWZ; dmarc=pass (policy=reject) header.from=yahoo.com; spf=pass (mx1.freebsd.org: domain of marklmi@yahoo.com designates 98.137.65.206 as permitted sender) smtp.mailfrom=marklmi@yahoo.com X-Spamd-Result: default: False [-1.68 / 15.00]; RCVD_TLS_LAST(0.00)[]; ARC_NA(0.00)[]; R_DKIM_ALLOW(-0.20)[yahoo.com:s=s2048]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; FREEMAIL_FROM(0.00)[yahoo.com]; MV_CASE(0.50)[]; MIME_GOOD(-0.10)[text/plain]; R_SPF_ALLOW(-0.20)[+ptr:yahoo.com]; NEURAL_HAM_LONG(-1.00)[-1.000]; TO_DN_SOME(0.00)[]; NEURAL_SPAM_SHORT(0.82)[0.818]; TO_MATCH_ENVRCPT_SOME(0.00)[]; DKIM_TRACE(0.00)[yahoo.com:+]; DMARC_POLICY_ALLOW(-0.50)[yahoo.com,reject]; RCVD_IN_DNSWL_NONE(0.00)[98.137.65.206:from]; MLMMJ_DEST(0.00)[freebsd-hackers]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; FREEMAIL_ENVFROM(0.00)[yahoo.com]; ASN(0.00)[asn:36647, ipnet:98.137.64.0/20, country:US]; RCVD_COUNT_TWO(0.00)[2]; MID_RHS_MATCH_FROM(0.00)[]; DWL_DNSWL_NONE(0.00)[yahoo.com:dkim] X-ThisMailContainsUnwantedMimeParts: N On 2022-Apr-25, at 15:39, Mark Millard wrote: > =E2=80=A2 wrote on > =E2=80=A2 Date: Mon, 25 Apr 2022 13:01:48 UTC : >=20 >> I've created a small minimal test case which reproduces the problem = (attached). >> The key points here are: >> - CMake based project consisting of: >> - The header-only interface for the plugin and the types = (test-interface). >> - The main executable that loads the plugin (test-core). >> - A plugin implementation (plugin-one). >> - Compiles out-of-the-box on FreeBSD 13/stable with both lang/gcc11 = and devel/llvm14. >> - It uses the exact mechanism I use to load the plugins in my actual = application. >>=20 >> stdout output when compiling with lang/gcc11: >>=20 >> t is type int >> t is type string >> done. >>=20 >>=20 >> stdout output when compiling with lang/llvm14: >>=20 >> could not cast t >> could not cast t >> done. >>=20 >>=20 >> Unfortunately, I could not yet figure out which compiler/linker flags = llvm requires to implement the same behavior as GCC does. I understand = that eventually I'd be better of rewriting the necessary parts to = eliminate that problem but this is not a quick job. >>=20 >> Could somebody lend me a hand in figuring out which compiler/linker = flags are necessary to get this to work with llvm? >=20 > The GCC default behavior is technically wrong. GCC allows being = configured to > do the correct thing --at the cost of ABI mismatches vs. what they = originally > did. (At least that is how I understand what I read in the code.) >=20 > To my knowledge LLVM does not allow clang++ being configured to do the = wrong > thing: it never had the ABI messed up and so did not face the = self-compatibility > question. (Bug-for-bug clang++ vs. g++ compatibility has not been the = major > goal.) Looks like I may have got that wrong, although, like gcc11, it is is more of a when-building-the-C++-library time frame operation than a when-copmiling/linking to use the C++ library time frame thing. Also, nothing says the same strings would be used by clang++ vs. g++, possibly the comparisons might not agree across toolchains when string comparisons are used. . . ./contrib/llvm-project/libcxx/include/typeinfo has the following material for !defined(_LIBCPP_ABI_MICROSOFT): // = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D = // // Implementations // = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D = // // = ------------------------------------------------------------------------- = // // Unique // (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION =3D 1) // = ------------------------------------------------------------------------- = // // This implementation of type_info assumes a unique copy of the RTTI = for a // given type inside a program. This is a valid assumption when abiding = to the // Itanium ABI = (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components). // Under this assumption, we can always compare the addresses of the = type names // to implement equality-comparison of type_infos instead of having to = perform // a deep string comparison. // = --------------------------------------------------------------------------= // // NonUnique // (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION =3D 2) // = --------------------------------------------------------------------------= // // This implementation of type_info does not assume there is always a = unique // copy of the RTTI for a given type inside a program. For various = reasons // the linker may have failed to merge every copy of a types RTTI // (For example: -Bsymbolic or llvm.org/PR37398). Under this assumption, = two // type_infos are equal if their addresses are equal or if a deep string // comparison is equal. // = --------------------------------------------------------------------------= // // NonUniqueARMRTTIBit // (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION =3D 3) // = --------------------------------------------------------------------------= // // This implementation is specific to ARM64 on Apple platforms. // // This implementation of type_info does not assume always a unique copy = of // the RTTI for a given type inside a program. When constructing the = type_info, // the compiler packs the pointer to the type name into a uintptr_t and = reserves // the high bit of that pointer, which is assumed to be free for use = under that // ABI. If that high bit is set, that specific copy of the RTTI can't be = assumed // to be unique within the program. If the high bit is unset, then the = RTTI can // be assumed to be unique within the program. // // When comparing type_infos, if both RTTIs can be assumed to be unique, = it // suffices to compare their addresses. If both the RTTIs can't be = assumed to // be unique, we must perform a deep string comparison of the type = names. // However, if one of the RTTIs is guaranteed unique and the other one = isn't, // then both RTTIs are necessarily not to be considered equal. // // The intent of this design is to remove the need for weak symbols. = Specifically, // if a type would normally have a default-visibility RTTI emitted as a = weak // symbol, it is given hidden visibility instead and the non-unique bit = is set. // Otherwise, types declared with hidden visibility are always = considered to have // a unique RTTI: the RTTI is emitted with linkonce_odr linkage and is = assumed // to be deduplicated by the linker within the linked image. Across = linked image // boundaries, such types are thus considered different types. // This value can be overriden in the __config_site. When it's not = overriden, // we pick a default implementation based on the platform here. > I have a nearly-minimalist change to your example that makes it result = in: >=20 > # ./test-core > t is type_int > t is type_string > done. >=20 > under clang. I pasted a diff -ruN in the message later below but that = may > lead to white space not being fully preserved. (I could send it to you = in > another form if it proved needed.) >=20 > Basically I avoid inline definitions of: >=20 > virtual ~type_base(); > virtual ~type_int(); > virtual ~type_string(); >=20 > Also, these are deliberately(!) the first non-inline virtual > member functions in the 3 types. Where the implementations > are placed controls were the type_info is put for the 3 types. > (Not a language definition issue but a fairly common > implementation technique.) >=20 > I also make the place with the implementation be a tiny .so > that both test-core and libplugin-one.so are bound to. This > makes them use the same type_info definitions instead of > having multiple competing ones around, sort of a form of > single-definition-rule (unique addresses in the process). > With the single definition rule followed, RTTI works just > fine. >=20 > I do warn that this is the first direct adjustment of cmake > material that I've ever done. So if anything looks odd for > how I did the cmake aspects, do not be surprised. I'm not > cmake literate. >=20 > For reference: >=20 > # find clang_test_dist_m_m/ -print > clang_test_dist_m_m/ > clang_test_dist_m_m/plugins > clang_test_dist_m_m/plugins/CMakeLists.txt > clang_test_dist_m_m/plugins/plugin_one > clang_test_dist_m_m/plugins/plugin_one/CMakeLists.txt > clang_test_dist_m_m/plugins/plugin_one/plugin.cpp > clang_test_dist_m_m/shared_types_impl > clang_test_dist_m_m/shared_types_impl/CMakeLists.txt > clang_test_dist_m_m/shared_types_impl/types_impl.cpp > clang_test_dist_m_m/core > clang_test_dist_m_m/core/dlclass.hpp > clang_test_dist_m_m/core/CMakeLists.txt > clang_test_dist_m_m/core/main.cpp > clang_test_dist_m_m/CMakeLists.txt > clang_test_dist_m_m/interface > clang_test_dist_m_m/interface/plugin.hpp > clang_test_dist_m_m/interface/types.hpp > clang_test_dist_m_m/interface/CMakeLists.txt >=20 > where the diff -ruN is . . . >=20 > diff -ruN clang_test_dist/ clang_test_dist_m_m/ | more > diff -ruN clang_test_dist/CMakeLists.txt = clang_test_dist_m_m/CMakeLists.txt > --- clang_test_dist/CMakeLists.txt 2022-04-19 13:38:59.000000000 = -0700 > +++ clang_test_dist_m_m/CMakeLists.txt 2022-04-25 12:51:03.448582000 = -0700 > @@ -5,4 +5,5 @@ >=20 > add_subdirectory(core) > add_subdirectory(interface) > +add_subdirectory(shared_types_impl) > add_subdirectory(plugins) > diff -ruN clang_test_dist/core/CMakeLists.txt = clang_test_dist_m_m/core/CMakeLists.txt > --- clang_test_dist/core/CMakeLists.txt 2022-04-19 13:38:59.000000000 = -0700 > +++ clang_test_dist_m_m/core/CMakeLists.txt 2022-04-25 = 13:18:52.539921000 -0700 > @@ -19,9 +19,12 @@ > PRIVATE > test-interface > dl > + PUBLIC > + shared-types-impl > ) >=20 > add_dependencies( > ${TARGET} > + shared-types-impl > plugin-one > ) > diff -ruN clang_test_dist/interface/types.hpp = clang_test_dist_m_m/interface/types.hpp > --- clang_test_dist/interface/types.hpp 2022-04-19 13:38:59.000000000 = -0700 > +++ clang_test_dist_m_m/interface/types.hpp 2022-04-25 = 14:48:52.534159000 -0700 > @@ -7,18 +7,20 @@ >=20 > struct type_base > { > - virtual ~type_base() =3D default; > + virtual ~type_base(); > }; >=20 > struct type_int : > type_base > { > + virtual ~type_int(); > int data; > }; >=20 > struct type_string : > type_base > { > + virtual ~type_string(); > std::string data; > }; >=20 > diff -ruN clang_test_dist/plugins/plugin_one/CMakeLists.txt = clang_test_dist_m_m/plugins/plugin_one/CMakeLists.txt > --- clang_test_dist/plugins/plugin_one/CMakeLists.txt 2022-04-19 = 13:38:59.000000000 -0700 > +++ clang_test_dist_m_m/plugins/plugin_one/CMakeLists.txt = 2022-04-25 13:19:20.188778000 -0700 > @@ -12,3 +12,14 @@ > PRIVATE > plugin.cpp > ) > + > +target_link_libraries( > + ${TARGET} > + PUBLIC > + shared-types-impl > +) > + > +add_dependencies( > + ${TARGET} > + shared-types-impl > +) > diff -ruN clang_test_dist/shared_types_impl/CMakeLists.txt = clang_test_dist_m_m/shared_types_impl/CMakeLists.txt > --- clang_test_dist/shared_types_impl/CMakeLists.txt 1969-12-31 = 16:00:00.000000000 -0800 > +++ clang_test_dist_m_m/shared_types_impl/CMakeLists.txt = 2022-04-25 12:55:29.760985000 -0700 > @@ -0,0 +1,15 @@ > +set(TARGET shared-types-impl) > +add_library(${TARGET} SHARED) > + > +target_compile_features( > + ${TARGET} > + PRIVATE > + cxx_std_20 > +) > + > +target_sources( > + ${TARGET} > + PRIVATE > + types_impl.cpp > +) > + > diff -ruN clang_test_dist/shared_types_impl/types_impl.cpp = clang_test_dist_m_m/shared_types_impl/types_impl.cpp > --- clang_test_dist/shared_types_impl/types_impl.cpp 1969-12-31 = 16:00:00.000000000 -0800 > +++ clang_test_dist_m_m/shared_types_impl/types_impl.cpp = 2022-04-25 14:49:23.599440000 -0700 > @@ -0,0 +1,5 @@ > +#include "../interface/types.hpp" > + > +interface::type_base::~type_base() {} > +interface::type_int::~type_int() {} > +interface::type_string::~type_string() {} >=20 >=20 > That is all there is to the changes. >=20 =3D=3D=3D Mark Millard marklmi at yahoo.com