bridges/Library_cpp_uno.mk                                        |   16 +-
 bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx                 |   62 
+++++++++-
 bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx                 |    3 
 bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx |    2 
 bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx             |   10 +
 bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s        |   11 +
 bridges/source/cpp_uno/shared/vtablefactory.cxx                   |   11 +
 cppuhelper/source/exc_thrower.cxx                                 |    6 
 sal/osl/unx/salinit.cxx                                           |    8 -
 9 files changed, 115 insertions(+), 14 deletions(-)

New commits:
commit e2bd5afd726abd5df438b6b821416bd7cf496e4d
Author:     Tor Lillqvist <t...@collabora.com>
AuthorDate: Sun Aug 9 10:51:22 2020 +0100
Commit:     Tor Lillqvist <t...@collabora.com>
CommitDate: Mon Aug 10 17:51:27 2020 +0200

    Make the C++/UNO bridge work to some extent on macOS on arm64
    
    Use the same code as for Linux on aarch64, with minor
    additional hacks. But that will not actually work in all cases, as
    there are slight differences in the ABI. See
    
https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
    
    Thus we can drop the use of the lo_mobile_throwException() hack that
    was very temporarily used.
    
    The run-time code generation requires use of a new API on macOS to
    work: See the use of pthread_jit_write_protect_np() in
    bridges/source/cpp_uno/shared/vtablefactory.cxx.
    
    For some reason, with the Xcode 12 betas, when compiling for
    arm64-apple-macos, the symbols for the type_infos 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(), but that then fails. So
    use a gross hack: Introduce separate real variables that point to
    these typeinfos, and look up and dereference them instead. If this
    hack ends up needing to be permanent, instead of having a manually
    edited set of such pointer variables, we should teach codemaker to
    generate corresponding functions, and look up and invoke them to get
    the std::type_info pointer.
    
    When compiling for x86_64-apple-macos, the type_info symbols end up as
    "weak external" which is fine.
    
    With this, LibreOffice starts and seems to work to some extent, and
    many unit tests succeed.
    
    Change-Id: I05f46a122a51ade1ac7dccd57cb90e594547740e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100408
    Tested-by: Jenkins
    Reviewed-by: Tor Lillqvist <t...@collabora.com>

diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index cf6fb489c3a1..9adc891f4e3d 100644
--- a/bridges/Library_cpp_uno.mk
+++ b/bridges/Library_cpp_uno.mk
@@ -23,7 +23,7 @@ endif
 
 else ifeq ($(CPUNAME),AARCH64)
 
-ifneq ($(filter ANDROID DRAGONFLY FREEBSD LINUX NETBSD OPENBSD,$(OS)),)
+ifneq ($(filter ANDROID DRAGONFLY FREEBSD LINUX MACOSX NETBSD OPENBSD,$(OS)),)
 bridges_SELECTED_BRIDGE := gcc3_linux_aarch64
 bridge_asm_objects := vtableslotcall
 bridge_exception_objects := abi cpp2uno uno2cpp
@@ -32,10 +32,8 @@ $(eval $(call 
gb_Library_add_exception_objects,$(gb_CPPU_ENV)_uno, \
     bridges/source/cpp_uno/$(bridges_SELECTED_BRIDGE)/callvirtualfunction, \
     $(if $(HAVE_GCC_STACK_CLASH_PROTECTION),-fno-stack-clash-protection) \
 ))
-else ifneq ($(filter iOS MACOSX,$(OS)),)
-# For now, use the same bridge for macOS on arm64 as for iOS. But we
-# will eventually obviously want one that does generate code
-# dynamically on macOS.
+
+else ifeq ($(OS),iOS)
 bridges_SELECTED_BRIDGE := gcc3_ios
 bridge_noopt_objects := cpp2uno except uno2cpp
 bridge_asm_objects := ios64_helper
@@ -184,6 +182,14 @@ $(eval $(call 
gb_Library_use_internal_comprehensive_api,$(gb_CPPU_ENV)_uno,\
        udkapi \
 ))
 
+ifeq ($(OS),MACOSX)
+ifeq ($(CPUNAME),AARCH64)
+$(eval $(call gb_Library_use_internal_comprehensive_api,$(gb_CPPU_ENV)_uno,\
+       offapi \
+))
+endif
+endif
+
 $(eval $(call gb_Library_set_include,$(gb_CPPU_ENV)_uno,\
        -I$(SRCDIR)/bridges/inc \
        $$(INCLUDE) \
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx 
b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
index 4a5a1d1b662d..b0a35996784e 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
 /*
  * This file is part of the LibreOffice project.
  *
@@ -31,6 +31,7 @@
 #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>
@@ -106,6 +107,31 @@ 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 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.osx", dlerror());
+        }
+#endif
+
         if (rtti == 0) {
             char const * rttiName = sym.getStr() + std::strlen("_ZTI");
             assert(type.eTypeClass == typelib_TypeClass_EXCEPTION);
@@ -152,6 +178,12 @@ extern "C" void _GLIBCXX_CDTOR_CALLABI 
deleteException(void * exception) {
     // point to this function (the use of __cxa_exception in fillUnoException 
is
     // unaffected, as it only accesses members towards the start of the struct,
     // through a pointer known to actually point at the start):
+
+    // Later, libcxxabi, as used at least on macOS on arm64, added a
+    // void *reserve at the start of the __cxa_exception in front of
+    // the referenceCount. See
+    // 
https://github.com/llvm/llvm-project/commit/f2a436058fcbc11291e73badb44e243f61046183#diff-ba9cda1ceca630ba040b154fe198adbd
+
     if (header->exceptionDestructor != &deleteException) {
         header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
             reinterpret_cast<char *>(header) - 8);
@@ -283,7 +315,9 @@ ReturnKind getReturnKind(typelib_TypeDescription const * 
type) {
     switch (type->eTypeClass) {
     default:
         assert(false);
+#ifdef NDEBUG
         [[fallthrough]];
+#endif
     case typelib_TypeClass_VOID:
     case typelib_TypeClass_BOOLEAN:
     case typelib_TypeClass_BYTE:
@@ -327,4 +361,30 @@ 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: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx 
b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
index e3dc9b5872a7..008d4723e295 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
@@ -71,6 +71,9 @@ namespace __cxxabiv1 {
 struct __cxa_exception {
 #if defined _LIBCPPABI_VERSION // detect libc++abi
 #if defined __LP64__ || LIBCXXABI_ARM_EHABI
+#ifdef MACOSX // on arm64
+    void *reserve;
+#endif
     std::size_t referenceCount;
 #endif
 #endif
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx 
b/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx
index ba5194d6f8c8..b944f31cfd2a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx
@@ -55,7 +55,7 @@ void callVirtualFunction(
            "m" (stackargs) // dummy input to prevent optimizing the alloca away
         : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
           "r11", "r12", "r13", "r14", "r15", "r16", "r17",
-#if !defined ANDROID
+#if !defined ANDROID && !defined MACOSX
           "r18"/*TODO?*/,
 #endif
           "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", 
"v11",
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx 
b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
index f9f26419b381..a67f2ca611ea 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
@@ -357,10 +357,16 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
 }
 
 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+    Slot ** slots, unsigned char * code,
+#ifdef USE_DOUBLE_MMAP
+    sal_PtrDiff writetoexecdiff,
+#endif
     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
     sal_Int32 functionCount, sal_Int32 vtableOffset)
 {
+#ifndef USE_DOUBLE_MMAP
+    constexpr sal_PtrDiff writetoexecdiff = 0;
+#endif
     (*slots) -= functionCount;
     Slot * s = *slots;
     for (sal_Int32 i = 0; i != type->nMembers; ++i) {
@@ -400,7 +406,7 @@ unsigned char * 
bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
 void bridges::cpp_uno::shared::VtableFactory::flushCode(
     unsigned char const * begin, unsigned char const * end)
 {
-#ifndef ANDROID
+#if !defined ANDROID && !defined MACOSX
    static void (*clear_cache)(unsigned char const *, unsigned char const *)
        = (void (*)(unsigned char const *, unsigned char const *)) dlsym(
            RTLD_DEFAULT, "__clear_cache");
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s 
b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s
index 39873b64d7a6..60bdb4c9cf4e 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s
@@ -20,10 +20,15 @@
     .arch armv8-a
     .text
     .align 2
+#ifndef __APPLE__
     .global vtableSlotCall
     .hidden vtableSlotCall
     .type vtableSlotCall, %function
 vtableSlotCall:
+#else
+       .global _vtableSlotCall
+_vtableSlotCall:
+#endif
     .cfi_startproc
     stp x29, x30, [sp, -192]!
     .cfi_def_cfa_offset 192
@@ -53,7 +58,11 @@ vtableSlotCall:
     stp d2, d3, [sp, 144]
     stp d4, d5, [sp, 160]
     stp d6, d7, [sp, 176]
+#ifndef __APPLE__
     bl vtableCall
+#else
+       bl _vtableCall
+#endif
     ldp x0, x1, [x19]
     ldp d0, d1, [x20]
     ldp d2, d3, [x20, #16]
@@ -66,7 +75,9 @@ vtableSlotCall:
     .cfi_def_cfa_offset 0
     ret
     .cfi_endproc
+#ifndef __APPLE__
     .size vtableSlotCall, .-vtableSlotCall
     .section .note.GNU-stack, "", @progbits
+#endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab */
diff --git a/bridges/source/cpp_uno/shared/vtablefactory.cxx 
b/bridges/source/cpp_uno/shared/vtablefactory.cxx
index 036b81c4218a..52309c6ec617 100644
--- a/bridges/source/cpp_uno/shared/vtablefactory.cxx
+++ b/bridges/source/cpp_uno/shared/vtablefactory.cxx
@@ -53,6 +53,10 @@
 #include <fcntl.h>
 #endif
 
+#if defined MACOSX && defined __aarch64__
+#include <pthread.h>
+#endif
+
 using bridges::cpp_uno::shared::VtableFactory;
 
 namespace {
@@ -322,6 +326,10 @@ sal_Int32 VtableFactory::createVtables(
     typelib_InterfaceTypeDescription * type, sal_Int32 vtableNumber,
     typelib_InterfaceTypeDescription * mostDerived, bool includePrimary) const
 {
+#if defined MACOSX && defined __aarch64__
+    // TODO: Should we handle resetting this in a exception-throwing-safe way?
+    pthread_jit_write_protect_np(0);
+#endif
     if (includePrimary) {
         sal_Int32 slotCount
             = bridges::cpp_uno::shared::getPrimaryFunctions(type);
@@ -361,6 +369,9 @@ sal_Int32 VtableFactory::createVtables(
             throw;
         }
     }
+#if defined MACOSX && defined __aarch64__
+    pthread_jit_write_protect_np(1);
+#endif
     for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
         vtableNumber = createVtables(
             blocks, baseOffset, type->ppBaseTypes[i],
diff --git a/cppuhelper/source/exc_thrower.cxx 
b/cppuhelper/source/exc_thrower.cxx
index 2963572e4770..7c40d12db16e 100644
--- a/cppuhelper/source/exc_thrower.cxx
+++ b/cppuhelper/source/exc_thrower.cxx
@@ -173,7 +173,7 @@ ExceptionThrower::ExceptionThrower()
 
 class theExceptionThrower : public rtl::Static<ExceptionThrower, 
theExceptionThrower> {};
 
-#if defined(IOS) || (defined(__aarch64__) && (defined(ANDROID) || 
defined(MACOSX)))
+#if defined(IOS) || (defined(__aarch64__) && defined(ANDROID))
 // In the native iOS / Android app, where we don't have any Java, Python,
 // BASIC, or other scripting, the only thing that would use the C++/UNO bridge
 // functionality that invokes codeSnippet() was cppu::throwException().
@@ -211,7 +211,7 @@ void lo_mobile_throwException(css::uno::Any const& 
aException)
 
     assert(false);
 }
-#endif // defined(IOS) || (defined(__aarch64__) && (defined(ANDROID) || 
defined(MACOSX)))
+#endif // defined(IOS) || (defined(__aarch64__) && defined(ANDROID))
 
 } // anonymous namespace
 
@@ -229,7 +229,7 @@ void SAL_CALL throwException( Any const & exc )
             "(must be derived from com::sun::star::uno::Exception)!" );
     }
 
-#if defined(IOS) || (defined(__aarch64__) && (defined(ANDROID) || 
defined(MACOSX)))
+#if defined(IOS) || (defined(__aarch64__) && defined(ANDROID))
     lo_mobile_throwException(exc);
 #else
     Mapping uno2cpp(Environment(UNO_LB_UNO), Environment::getCurrent());
diff --git a/sal/osl/unx/salinit.cxx b/sal/osl/unx/salinit.cxx
index 9424089dbba0..c3ac48c575d1 100644
--- a/sal/osl/unx/salinit.cxx
+++ b/sal/osl/unx/salinit.cxx
@@ -1,3 +1,4 @@
+#include <sal/log.hxx>
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * This file is part of the LibreOffice project.
@@ -22,6 +23,7 @@
 #include <sal/config.h>
 
 #if defined MACOSX
+#include <algorithm>
 #include <cassert>
 #include <limits>
 #include <unistd.h>
@@ -71,8 +73,10 @@ void sal_detail_initialize(int argc, char ** argv) {
         // Some random value, but hopefully sysconf never returns -1 anyway:
         openMax = 1024;
     }
-    assert(openMax >= 0 && openMax <= std::numeric_limits< int >::max());
-    for (int fd = 3; fd < int(openMax); ++fd) {
+    // When LibreOffice restarts itself on macOS 11 beta on arm64, for
+    // some reason sysconf(_SC_OPEN_MAX) returns 0x7FFFFFFFFFFFFFFF,
+    // so use a sanity limit here.
+    for (int fd = 3; fd < std::min(100000l, openMax); ++fd) {
         struct stat s;
         if (fstat(fd, &s) != -1 && S_ISREG(s.st_mode))
             close(fd);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to