summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-12-16 15:35:30 +0100
committerStephan Bergmann <sbergman@redhat.com>2020-12-16 19:53:16 +0100
commitbf858e4b224ae4dc04f968a3d3c66d184dd1e33d (patch)
treecf8201ff847c90ab874f4132e0ecf4068597ddb6 /bridges
parent651ffebdb7cad18ec0a2dda294a6fff231638409 (diff)
Fix macOS ARM64 RTTI generation
The Apple ARM64 ABI can use RTTI that is either unique (std::type_info equality is decided by comparing pointers to RTTI names) or non-unique (equality is decided by deep string comparison of RTTI names), where the most-significant bit of a std::type_info's name pointer must be set to indicate the non-unique case. See the " NonUniqueARMRTTIBit" comment at <https://github.com/llvm/llvm-project/ blob/be00e8893fdb814e67d8f06401afe869f878c4cf/libcxx/include/typeinfo#L143> for details. It appears that Clang, at least under -fvisibility=hidden as used by LO, emits RTTI for a C++ class as .private_extern and non-unique, even if the class is marked as visibility("default") (as is done for the C++ classes representing UNO exception types, cf. CPPU_GCC_DLLPUBLIC_EXPORT in include/cppu/macros.hxx). So it is expected and harmless that Rtti::getRtti will not find existing RTTI symbols via dlsym, and needs to create RTTI on the fly. However, what was missing was to set the most-significant bit of the name pointer, to indicate non-uniqueness. (My understanding is that things should even have worked whe we failed to set that bit, as comparison should fall back to deep string comparison if at least one of the involved RTTIs has the bit set, which the RTTI emitted by Clang does, see above. It looks like there is a bug though, see <http://lists.llvm.org/pipermail/libcxx-dev/2020-December/001060.html> "[libcxx-dev] Is the implementation of two-argument __non_unique_arm_rtti_bit_impl;;__is_type_name_unique correct?") Change-Id: I3c39edf569ac668352bbb73e60303856e1b63445 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107839 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'bridges')
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx67
1 files changed, 13 insertions, 54 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
index f1cacf8d54ba..0fce88db6749 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
@@ -21,6 +21,7 @@
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <cstring>
#include <typeinfo>
@@ -31,7 +32,6 @@
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/ustring.hxx>
-#include <sal/log.hxx>
#include <sal/types.h>
#include <typelib/typeclass.h>
#include <typelib/typedescription.h>
@@ -107,44 +107,29 @@ std::type_info * Rtti::getRtti(typelib_TypeDescription const & type) {
OString sym(b.makeStringAndClear());
std::type_info * rtti = static_cast<std::type_info *>(
dlsym(app_, sym.getStr()));
+ if (rtti == 0) {
+ char const * rttiName = strdup(sym.getStr() + std::strlen("_ZTI"));
+ if (rttiName == nullptr) {
+ throw std::bad_alloc();
+ }
#if defined MACOSX
-
- // Horrible but hopefully temporary hack.
-
- // For some reason, with the Xcode 12 betas, when compiling for arm64-apple-macos, the
- // symbols for the typeinfos for the UNO exception types
- // (_ZTIN3com3sun4star3uno16RuntimeExceptionE etc) end up as "weak private external" in the
- // object file, as displayed by "nm -f darwin". We try to look them up with dlsym() above,
- // but that then fails. So use a hackaround... introduce separate real variables (see end of
- // this file) that point to these typeinfos.
-
- // When compiling for x86_64-apple-macos, the typeinfo symbols end up as "weak external"
- // which is fine.
-
- if (rtti == nullptr)
- {
- const OString ptrSym = "ptr" + sym;
- auto ptr = static_cast<std::type_info **>(dlsym(app_, ptrSym.getStr()));
- if (ptr != nullptr)
- rtti = *ptr;
- else
- SAL_WARN("bridges", dlerror());
- }
+ // For the Apple ARM64 ABI, if the most significant ("non-unique RTTI") bit is set, it
+ // means that the instance of the name is not unique (and thus RTTI equality needs to be
+ // determined by string comparison rather than by pointer comparison):
+ rttiName = reinterpret_cast<char const *>(
+ reinterpret_cast<std::uintptr_t>(rttiName) | 0x8000'0000'0000'0000);
#endif
-
- if (rtti == 0) {
- char const * rttiName = sym.getStr() + std::strlen("_ZTI");
assert(type.eTypeClass == typelib_TypeClass_EXCEPTION);
typelib_CompoundTypeDescription const & ctd
= reinterpret_cast<typelib_CompoundTypeDescription const &>(
type);
if (ctd.pBaseTypeDescription == 0) {
- rtti = new __cxxabiv1::__class_type_info(strdup(rttiName));
+ rtti = new __cxxabiv1::__class_type_info(rttiName);
} else {
std::type_info * base = getRtti(
ctd.pBaseTypeDescription->aBase);
rtti = new __cxxabiv1::__si_class_type_info(
- strdup(rttiName),
+ rttiName,
static_cast<__cxxabiv1::__class_type_info *>(base));
}
}
@@ -386,30 +371,4 @@ ReturnKind getReturnKind(typelib_TypeDescription const * type) {
}
-#ifdef MACOSX
-
-// See the comment about the horrible hack above.
-
-// This set of types are compiled based on what 'make check' needs, but I haven't been able to run
-// it completely yet. And of course as such this hack isn't a viable long-term solution.
-
-#include <com/sun/star/lang/IllegalArgumentException.hpp>
-#include <com/sun/star/task/ClassifiedInteractionRequest.hpp>
-#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
-#include <com/sun/star/ucb/InteractiveIOException.hpp>
-#include <com/sun/star/ucb/NameClashException.hpp>
-#include <com/sun/star/uno/Exception.hpp>
-
-extern "C" {
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star4lang24IllegalArgumentExceptionE = &typeid(css::lang::IllegalArgumentException);
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star3uno9ExceptionE = &typeid(css::uno::Exception);
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star3uno16RuntimeExceptionE = &typeid(css::uno::RuntimeException);
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE = &typeid(css::ucb::InteractiveAugmentedIOException);
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star3ucb22InteractiveIOExceptionE = &typeid(css::ucb::InteractiveIOException);
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star3ucb18NameClashExceptionE = &typeid(css::ucb::NameClashException);
- const std::type_info* __attribute((visibility("default"),used)) ptr_ZTIN3com3sun4star4task28ClassifiedInteractionRequestE = &typeid(css::task::ClassifiedInteractionRequest);
-}
-
-#endif
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */