diff options
author | Tor Lillqvist <tml@collabora.com> | 2020-08-09 10:51:22 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-11-24 10:09:00 +0100 |
commit | 8ff60753d11be4d0c51fa7b362e0adc73d5fb7e0 (patch) | |
tree | 5a96d8806c0be1d1a68f6bbe2c5a25cbe0c7ce99 /bridges | |
parent | 0516e495272c9aeff325d595e7f92e11c7ab8b47 (diff) |
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@redhat.com>
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/Library_cpp_uno.mk | 16 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx | 62 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx | 3 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx | 2 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx | 149 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx | 121 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s | 11 | ||||
-rw-r--r-- | bridges/source/cpp_uno/shared/vtablefactory.cxx | 11 |
8 files changed, 364 insertions, 11 deletions
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], |