[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - bridges/Library_cpp_uno.mk bridges/source sal/osl

Tor Lillqvist (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 24 09:09:34 UTC 2020


 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             |  149 +++++++++-
 bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx             |  121 +++++++-
 bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s        |   11 
 bridges/source/cpp_uno/shared/vtablefactory.cxx                   |   11 
 sal/osl/unx/salinit.cxx                                           |    8 
 9 files changed, 370 insertions(+), 13 deletions(-)

New commits:
commit 8ff60753d11be4d0c51fa7b362e0adc73d5fb7e0
Author:     Tor Lillqvist <tml at collabora.com>
AuthorDate: Sun Aug 9 10:51:22 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Nov 24 10:09:00 2020 +0100

    Make the C++/UNO bridge work on macOS on arm64
    
    Use the same code as for Linux on aarch64, with minor additional
    hacks. (There are slight differences in the ABI. See
    https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
    
    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.
    
    Unlike the arm64 ABI used on Linux, on macOS (and iOS, but we don't
    really use the C++/UNO bridge for iOS) we need to pack parameters
    smaller than eight bytes according to their natural alignment. Bytes
    take one byte, shorts two bytes aligned at a two-byte boundary, etc.
    
    For some reason, 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.
    
    (This is a combination of what was two patches in master.)
    
    Change-Id: I05f46a122a51ade1ac7dccd57cb90e594547740e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106465
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index 305d47bd6291..c392fa4c60db 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..830c42eb52f8 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
@@ -70,11 +70,142 @@ void call(
     sal_Int32 ngpr = 1;
     sal_Int32 nfpr = 0;
     sal_Int32 sp = 0;
+#ifdef MACOSX
+    sal_Int32 subsp = 0;
+#endif
     for (sal_Int32 i = 0; i != count; ++i) {
         if (!parameters[i].bOut
             && bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef))
         {
             switch (parameters[i].pTypeRef->eTypeClass) {
+#ifdef MACOSX
+            case typelib_TypeClass_BOOLEAN:
+            case typelib_TypeClass_BYTE:
+                if (ngpr < 8)
+                {
+                    args[i] = gpr + ngpr;
+                    ngpr++;
+                }
+                else
+                {
+                    args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+                    subsp += 1;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                }
+                break;
+            case typelib_TypeClass_SHORT:
+            case typelib_TypeClass_UNSIGNED_SHORT:
+            case typelib_TypeClass_CHAR:
+                if (ngpr < 8)
+                {
+                    args[i] = gpr + ngpr;
+                    ngpr++;
+                }
+                else
+                {
+                    subsp = (subsp + 1) & ~0x1;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                    args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+                    subsp += 2;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                }
+                break;
+            case typelib_TypeClass_LONG:
+            case typelib_TypeClass_UNSIGNED_LONG:
+            case typelib_TypeClass_ENUM:
+                if (ngpr < 8)
+                {
+                    args[i] = gpr + ngpr;
+                    ngpr++;
+                }
+                else
+                {
+                    subsp = (subsp + 3) & ~0x3;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                    args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+                    subsp += 4;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                }
+                break;
+            case typelib_TypeClass_HYPER:
+            case typelib_TypeClass_UNSIGNED_HYPER:
+                if (ngpr < 8)
+                {
+                    args[i] = gpr + ngpr;
+                    ngpr++;
+                }
+                else
+                {
+                    if (subsp > 0)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                    args[i] = stack + sp;
+                    sp++;
+                }
+                break;
+            case typelib_TypeClass_FLOAT:
+                if (nfpr < 8)
+                {
+                    args[i] = fpr + nfpr;
+                    nfpr++;
+                }
+                else
+                {
+                    subsp = (subsp + 3) & ~0x3;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                    args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+                    subsp += 4;
+                    if (subsp == 8)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                }
+                break;
+            case typelib_TypeClass_DOUBLE:
+                if (nfpr < 8)
+                {
+                    args[i] = fpr + nfpr;
+                    nfpr++;
+                }
+                else
+                {
+                    if (subsp > 0)
+                    {
+                        sp++;
+                        subsp = 0;
+                    }
+                    args[i] = stack + sp;
+                    sp++;
+                }
+                break;
+#else
             case typelib_TypeClass_BOOLEAN:
             case typelib_TypeClass_BYTE:
             case typelib_TypeClass_SHORT:
@@ -91,11 +222,19 @@ void call(
             case typelib_TypeClass_DOUBLE:
                 args[i] = nfpr == 8 ? stack + sp++ : fpr + nfpr++;
                 break;
+#endif
             default:
                 assert(false);
             }
             argtds[i] = 0;
         } else {
+#ifdef MACOSX
+            if (subsp > 0)
+            {
+                sp++;
+                subsp = 0;
+            }
+#endif
             cppArgs[i] = reinterpret_cast<void *>(
                 ngpr == 8 ? stack[sp++] : gpr[ngpr++]);
             typelib_TypeDescription * ptd = 0;
@@ -357,10 +496,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 +545,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/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
index d1928942eb06..c25f7ccd7993 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
@@ -46,10 +46,82 @@
 namespace {
 
 void pushArgument(
-    unsigned long value, unsigned long * stack, sal_Int32 * sp,
-    unsigned long * regs, sal_Int32 * nregs)
+#ifdef MACOSX
+    typelib_TypeClass typeclass,
+    sal_Int32 * const subsp,
+#endif
+    unsigned long value, unsigned long * const stack, sal_Int32 * const sp,
+    unsigned long * const regs, sal_Int32 * const nregs)
 {
+#ifdef MACOSX
+    if (*nregs != 8)
+    {
+        regs[(*nregs)++] = value;
+    }
+    else
+    {
+        switch (typeclass) {
+        case typelib_TypeClass_BOOLEAN:
+        case typelib_TypeClass_BYTE:
+            *reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value;
+            (*subsp) += 1;
+            if (*subsp == 8)
+            {
+                (*sp)++;
+                *subsp = 0;
+            }
+            break;
+        case typelib_TypeClass_SHORT:
+        case typelib_TypeClass_UNSIGNED_SHORT:
+        case typelib_TypeClass_CHAR:
+            *subsp = (*subsp + 1) & ~0x1;
+            if (*subsp == 8)
+            {
+                (*sp)++;
+                *subsp = 0;
+            }
+            *reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value;
+            (*subsp) += 2;
+            if (*subsp == 8)
+            {
+                (*sp)++;
+                *subsp = 0;
+            }
+            break;
+        case typelib_TypeClass_LONG:
+        case typelib_TypeClass_UNSIGNED_LONG:
+        case typelib_TypeClass_ENUM:
+        case typelib_TypeClass_FLOAT:
+            *subsp = (*subsp + 3) & ~0x3;
+            if (*subsp == 8)
+            {
+                (*sp)++;
+                *subsp = 0;
+            }
+            *reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value;
+            (*subsp) += 4;
+            if (*subsp == 8)
+            {
+                (*sp)++;
+                *subsp = 0;
+            }
+            break;
+        case typelib_TypeClass_HYPER:
+        case typelib_TypeClass_UNSIGNED_HYPER:
+        default:
+            if (*subsp > 0)
+            {
+                (*sp)++;
+                *subsp = 0;
+            }
+            stack[*sp] = value;
+            (*sp)++;
+            break;
+        }
+    }
+#else
     (*nregs != 8 ? regs[(*nregs)++] : stack[(*sp)++]) = value;
+#endif
 }
 
 void call(
@@ -69,6 +141,9 @@ void call(
     unsigned long * stack = static_cast<unsigned long *>(
         alloca(count * sizeof (unsigned long)));
     sal_Int32 sp = 0;
+#ifdef MACOSX
+    sal_Int32 subsp = 0;
+#endif
     unsigned long gpr[8];
     sal_Int32 ngpr = 0;
     unsigned long fpr[8];
@@ -86,57 +161,90 @@ void call(
             switch (parameters[i].pTypeRef->eTypeClass) {
             case typelib_TypeClass_BOOLEAN:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_Bool *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_BYTE:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_Int8 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_SHORT:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_Int16 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_UNSIGNED_SHORT:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_uInt16 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_LONG:
             case typelib_TypeClass_ENUM:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_Int32 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_UNSIGNED_LONG:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_uInt32 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_HYPER:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_Int64 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_UNSIGNED_HYPER:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_uInt64 *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
             case typelib_TypeClass_FLOAT:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<unsigned int *>(arguments[i]), stack, &sp, fpr,
                     &nfpr);
                 break;
             case typelib_TypeClass_DOUBLE:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<unsigned long *>(arguments[i]), stack, &sp,
                     fpr, &nfpr);
                 break;
             case typelib_TypeClass_CHAR:
                 pushArgument(
+#ifdef MACOSX
+                    parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
                     *static_cast<sal_Unicode *>(arguments[i]), stack, &sp, gpr,
                     &ngpr);
                 break;
@@ -151,6 +259,9 @@ void call(
                 uno_constructData(cppArgs[i], ptd);
                 ptds[i] = ptd;
                 pushArgument(
+#ifdef MACOSX
+                    typelib_TypeClass_HYPER, &subsp,
+#endif
                     reinterpret_cast<unsigned long>(cppArgs[i]), stack, &sp,
                     gpr, &ngpr);
             } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) {
@@ -160,11 +271,17 @@ void call(
                     proxy->getBridge()->getUno2Cpp());
                 ptds[i] = ptd;
                 pushArgument(
+#ifdef MACOSX
+                    typelib_TypeClass_HYPER, &subsp,
+#endif
                     reinterpret_cast<unsigned long>(cppArgs[i]), stack, &sp,
                     gpr, &ngpr);
             } else {
                 cppArgs[i] = 0;
                 pushArgument(
+#ifdef MACOSX
+                    typelib_TypeClass_HYPER, &subsp,
+#endif
                     reinterpret_cast<unsigned long>(arguments[i]), stack, &sp,
                     gpr, &ngpr);
                 TYPELIB_DANGER_RELEASE(ptd);
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/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);


More information about the Libreoffice-commits mailing list