I want to highlight the two hugely important contributions in this commit.

1. Native Apple Silicon support.
2. Python 3.10 support.

A big thanks to Jim!

Best,
Dave

> On Jun 5, 2026, at 8:46 AM, [email protected] wrote:
> 
> This is an automated email from the ASF dual-hosted git repository.
> 
> jimjag pushed a commit to branch trunk
> in repository https://gitbox.apache.org/repos/asf/openoffice.git
> 
> 
> The following commit(s) were added to refs/heads/trunk by this push:
>     new 5e139d9fe4 Native Apple Silicon (arm64) support and bundled Python 
> 3.10 baseline
> 5e139d9fe4 is described below
> 
> commit 5e139d9fe42a654147771da4118aea6285c03168
> Author: Jim Jagielski <[email protected]>
> AuthorDate: Fri Jun 5 09:44:36 2026 -0400
> 
>    Native Apple Silicon (arm64) support and bundled Python 3.10 baseline
> 
>    Squashed combination of two efforts, applied onto trunk as a single
>    commit. (trunk is not intended to be buildable; this lands the work for
>    reference/integration.)
> 
>    === Apple Silicon (macOS arm64 / AAPCS64) ===
>    Build plumbing: set_soenv.in + source_soenv.sh arm64 Darwin branch
>    (CPU=R, CPUNAME=AARCH64, OUTPATH=unxmaccr); new solenv/inc/unxmaccr.mk
>    and unx.mk dispatch; macro.hxx AARCH64 arch string; osarch.pm +
>    gbuild/platform/macosx.mk arch entries; configure.ac arm64 host
>    detection, Big Sur+ version math, and 11.0 deployment target.
> 
>    C++/UNO bridge (new s5abi_macosx_aarch64): abi.cxx/hxx AAPCS64 classifier
>    (HFA + <=16B/>16B size rules), uno2cpp + call.s AArch64 trampoline,
>    cpp2uno incoming path + privateSnippetExecutor + AArch64 codeSnippet
>    codegen (x8 indirect-result handled, not displacing this/x0), share.hxx
>    __cxa_exception reserved-member alignment fix; Library_cpp_uno.mk +
>    makefile.mk wiring. sal/osl/unx/interlck.c arm64 atomics (__sync_* ->
>    LSE).
> 
>    Externals: openssl darwin64-arm64-cc; icu arm64 little-endian. (NSS 3.39
>    deferred -- too old for arm64.)
> 
>    Packaging/JVM: Info.plist LSMinimumSystemVersion 11.0; installer
>    download.pm/worker.pm/update_module_ignore_lists.pl recognize unxmaccr;
>    jvmfwk modern macOS JDK discovery (/Library/Java/JavaVirtualMachines +
>    Contents/Home probe).
> 
>    The ABI/atomics/trampoline/JDK-discovery code was unit-tested natively
>    on an arm64 macOS host; a full AOO build (and bridgetest) was not run.
>    Code-signing infra (mandatory for arm64 distribution) is NOT included.
> 
>    === Bundled Python 2.7.18 -> 3.10 baseline (Unix/macOS first) ===
>    pyversion.mk/_dmake.mk -> 3.10.18 (single version knob). Shipped .py
>    fixes: imp -> types.ModuleType (pythonscript.py, pythonloader.py) and
>    file() -> open(); mailmerge.py Py3 email module imports + encoders.
>    Windows Python 3 build and the makefile.mk/d.lst/configure.ac Py3 work
>    are NOT included (separate, larger effort).
> 
>    NOTE: macOS 11 becomes the minimum supported version. Python 3.10 is
>    EOL 2026-10; the version knob allows a later bump.
> ---
> main/bridges/Library_cpp_uno.mk                    |  18 +
> .../source/cpp_uno/s5abi_macosx_aarch64/abi.cxx    | 261 +++++++++
> .../source/cpp_uno/s5abi_macosx_aarch64/abi.hxx    |  86 +++
> .../source/cpp_uno/s5abi_macosx_aarch64/call.s     | 168 ++++++
> .../cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx       | 543 +++++++++++++++++++
> .../source/cpp_uno/s5abi_macosx_aarch64/except.cxx | 358 +++++++++++++
> .../cpp_uno/s5abi_macosx_aarch64/makefile.mk       |  81 +++
> .../source/cpp_uno/s5abi_macosx_aarch64/share.hxx  | 116 ++++
> .../cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx       | 581 +++++++++++++++++++++
> main/configure.ac                                  |  42 +-
> main/icu/icu4c-4_2_1-src.patch                     |   2 +-
> main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx    |  14 +
> main/openssl/makefile.mk                           |   4 +
> main/python/pyversion.mk                           |   4 +-
> main/python/pyversion_dmake.mk                     |   4 +-
> main/pyuno/source/loader/pythonloader.py           |   6 +-
> main/sal/osl/unx/interlck.c                        |  23 +
> main/sal/rtl/source/macro.hxx                      |   2 +
> main/scripting/source/pyprov/mailmerge.py          |  16 +-
> main/scripting/source/pyprov/pythonscript.py       |  10 +-
> main/set_soenv.in                                  |   8 +
> main/setup_native/source/mac/Info.plist.langpack   |   2 +-
> main/solenv/bin/modules/installer/download.pm      |   4 +
> main/solenv/bin/modules/installer/worker.pm        |   4 +
> main/solenv/bin/modules/osarch.pm                  |  12 +-
> main/solenv/bin/update_module_ignore_lists.pl      |   1 +
> main/solenv/gbuild/platform/macosx.mk              |   2 +
> main/solenv/inc/unx.mk                             |   4 +
> main/solenv/inc/unxmaccr.mk                        |  42 ++
> main/source_soenv.sh                               |   3 +
> main/sysui/desktop/macosx/Info.plist               |   2 +-
> 31 files changed, 2391 insertions(+), 32 deletions(-)
> 
> diff --git a/main/bridges/Library_cpp_uno.mk b/main/bridges/Library_cpp_uno.mk
> index d868df954f..0d8525362a 100644
> --- a/main/bridges/Library_cpp_uno.mk
> +++ b/main/bridges/Library_cpp_uno.mk
> @@ -431,6 +431,24 @@ $(eval $(call 
> gb_Library_add_exception_objects,$(COMNAME)_uno,\
>       bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp \
> ))
> 
> +###########################################################
> +else ifeq ($(OS)-$(CPUNAME)-$(COMNAME),MACOSX-AARCH64-s5abi)
> +###########################################################
> +# Apple Silicon (arm64) bridge. The COMNAME is "s5abi" macOS-wide (set in
> +# solenv/gbuild/platform/macosx.mk); for arm64 the actual calling convention
> +# is AAPCS64, so "s5abi" here is a historical label, not a literal ABI claim.
> +
> +$(eval $(call gb_Library_add_exception_objects,$(COMNAME)_uno,\
> +     bridges/source/cpp_uno/s5abi_macosx_aarch64/abi \
> +     bridges/source/cpp_uno/s5abi_macosx_aarch64/except \
> +     bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno \
> +     bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp \
> +))
> +
> +$(eval $(call gb_Library_add_asmobjects,$(COMNAME)_uno,\
> +     bridges/source/cpp_uno/s5abi_macosx_aarch64/call \
> +))
> +
> #########################################################
> else ifeq ($(OS)-$(CPUNAME)-$(COMNAME),NETBSD-INTEL-gcc3)
> #########################################################
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
> new file mode 100644
> index 0000000000..d51c5ccf12
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
> @@ -0,0 +1,261 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +
> +
> +// MARKER(update_precomp.py): autogen include statement, do not remove
> +#include "precompiled_bridges.hxx"
> +
> +// This is an implementation of the parameter-classification rules of the
> +// AArch64 procedure call standard ("Procedure Call Standard for the Arm 
> 64-bit
> +// Architecture", ARM IHI 0055), with the deviations documented in Apple's
> +// "Writing ARM64 Code for Apple Platforms".
> +//
> +// Unlike the System V AMD64 ABI (used by the x86-64 bridge), AAPCS64 does 
> not
> +// split aggregates into per-eightbyte INTEGER/SSE classes.  Instead:
> +//   * scalars go in one GPR (x) or one FP/SIMD (v) register;
> +//   * a Homogeneous Floating-point Aggregate (HFA: <= 4 members, all the 
> same
> +//     FP type, recursively) goes in consecutive v registers;
> +//   * any other aggregate <= 16 bytes goes in 1-2 GPRs;
> +//   * a non-HFA aggregate > 16 bytes is passed indirectly (a pointer to a
> +//     caller-allocated copy).
> +// Register fill is "all or nothing": if an aggregate does not fit entirely 
> in
> +// the remaining registers of its bank, it is passed wholly on the stack.
> +//
> +// This is a clean-room implementation from the public specifications; see
> +// ../../../../AAPCS64_BRIDGE_SPEC.md.  libffi's aarch64 backend was 
> consulted
> +// only as a behavioural reference; no code is copied.
> +
> +#include "abi.hxx"
> +
> +#include <rtl/ustring.hxx>
> +
> +using namespace aarch64;
> +
> +namespace {
> +
> +// The element type of a Homogeneous Floating-point Aggregate.
> +enum HfaKind
> +{
> +    HFA_NONE,       // not (yet) an HFA
> +    HFA_FLOAT,      // all members are FLOAT (4-byte)
> +    HFA_DOUBLE      // all members are DOUBLE (8-byte)
> +};
> +
> +// Combine the running HFA kind with a newly-seen member kind.  Two members
> +// of different FP types, or any non-FP member, break the homogeneity.
> +HfaKind mergeHfa( HfaKind running, HfaKind seen )
> +{
> +    if ( seen == HFA_NONE )
> +        return HFA_NONE;
> +    if ( running == HFA_NONE )
> +        return seen;
> +    return ( running == seen ) ? running : HFA_NONE;
> +}
> +
> +// Recursively determine whether pTypeRef is (part of) a homogeneous
> +// floating-point aggregate, accumulating the element kind and member count.
> +//
> +// Returns false the moment homogeneity is violated (a non-FP scalar, or a
> +// second distinct FP type, or > 4 elements).  A FLOAT/DOUBLE scalar counts 
> as
> +// a 1-element HFA of itself; a struct flattens its members (and base 
> classes).
> +bool collectHfa( typelib_TypeDescriptionReference *pTypeRef, HfaKind &rKind, 
> int &rCount )
> +{
> +    switch ( pTypeRef->eTypeClass )
> +    {
> +        case typelib_TypeClass_FLOAT:
> +            rKind = mergeHfa( rKind, HFA_FLOAT );
> +            if ( rKind == HFA_NONE ) return false;
> +            return ( ++rCount <= 4 );
> +
> +        case typelib_TypeClass_DOUBLE:
> +            rKind = mergeHfa( rKind, HFA_DOUBLE );
> +            if ( rKind == HFA_NONE ) return false;
> +            return ( ++rCount <= 4 );
> +
> +        case typelib_TypeClass_STRUCT:
> +        case typelib_TypeClass_EXCEPTION:
> +        {
> +            typelib_TypeDescription * pTypeDescr = 0;
> +            TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
> +
> +            const typelib_CompoundTypeDescription *pComp =
> +                reinterpret_cast<const typelib_CompoundTypeDescription*>( 
> pTypeDescr );
> +
> +            bool bOk = true;
> +
> +            // Flatten base class first (its members precede ours in layout).
> +            if ( pComp->pBaseTypeDescription )
> +            {
> +                bOk = collectHfa(
> +                    pComp->pBaseTypeDescription->aBase.pWeakRef, rKind, 
> rCount );
> +            }
> +
> +            for ( sal_Int32 i = 0; bOk && i < pComp->nMembers; ++i )
> +                bOk = collectHfa( pComp->ppTypeRefs[i], rKind, rCount );
> +
> +            TYPELIB_DANGER_RELEASE( pTypeDescr );
> +            return bOk;
> +        }
> +
> +        default:
> +            // Any non-FP, non-aggregate member breaks homogeneity.
> +            rKind = HFA_NONE;
> +            return false;
> +    }
> +}
> +
> +// Classify an aggregate (STRUCT/EXCEPTION).  Sets the GPR/FPR counts and
> +// returns true if it is passed in registers, false if it must be passed
> +// indirectly (in memory).
> +bool classifyAggregate( typelib_TypeDescriptionReference *pTypeRef, int 
> &nUsedGPR, int &nUsedFPR )
> +{
> +    // First, the HFA test.
> +    HfaKind kind = HFA_NONE;
> +    int count = 0;
> +    if ( collectHfa( pTypeRef, kind, count ) && kind != HFA_NONE && count >= 
> 1 && count <= 4 )
> +    {
> +        nUsedGPR = 0;
> +        nUsedFPR = count;       // one v register per member
> +        return true;
> +    }
> +
> +    // Otherwise classify by size.
> +    typelib_TypeDescription * pTypeDescr = 0;
> +    TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
> +    sal_Int32 nSize = pTypeDescr->nSize;
> +    TYPELIB_DANGER_RELEASE( pTypeDescr );
> +
> +    if ( nSize > 16 )
> +    {
> +        // Non-HFA aggregate > 16 bytes => passed indirectly.
> +        return false;
> +    }
> +
> +    // Non-HFA aggregate <= 16 bytes => 1 or 2 GPRs (8 bytes each).
> +    nUsedGPR = ( nSize > 8 ) ? 2 : 1;
> +    nUsedFPR = 0;
> +    return true;
> +}
> +
> +} // anonymous namespace
> +
> +bool aarch64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, 
> bool /*bInReturn*/, int &nUsedGPR, int &nUsedFPR )
> +{
> +    nUsedGPR = 0;
> +    nUsedFPR = 0;
> +
> +    switch ( pTypeRef->eTypeClass )
> +    {
> +        case typelib_TypeClass_VOID:
> +            return true;
> +
> +        case typelib_TypeClass_CHAR:
> +        case typelib_TypeClass_BOOLEAN:
> +        case typelib_TypeClass_BYTE:
> +        case typelib_TypeClass_SHORT:
> +        case typelib_TypeClass_UNSIGNED_SHORT:
> +        case typelib_TypeClass_LONG:
> +        case typelib_TypeClass_UNSIGNED_LONG:
> +        case typelib_TypeClass_HYPER:
> +        case typelib_TypeClass_UNSIGNED_HYPER:
> +        case typelib_TypeClass_ENUM:
> +            nUsedGPR = 1;
> +            return true;
> +
> +        case typelib_TypeClass_FLOAT:
> +        case typelib_TypeClass_DOUBLE:
> +            nUsedFPR = 1;
> +            return true;
> +
> +        // These UNO types are always handled by the bridge as a pointer/
> +        // reference (one GPR), never passed by value through this 
> classifier.
> +        case typelib_TypeClass_STRING:
> +        case typelib_TypeClass_TYPE:
> +        case typelib_TypeClass_ANY:
> +        case typelib_TypeClass_TYPEDEF:
> +        case typelib_TypeClass_SEQUENCE:
> +        case typelib_TypeClass_INTERFACE:
> +            nUsedGPR = 1;
> +            return true;
> +
> +        case typelib_TypeClass_STRUCT:
> +        case typelib_TypeClass_EXCEPTION:
> +            return classifyAggregate( pTypeRef, nUsedGPR, nUsedFPR );
> +
> +        default:
> +#if OSL_DEBUG_LEVEL > 1
> +            OSL_TRACE( "Unhandled case: pTypeRef->eTypeClass == %d\n", 
> pTypeRef->eTypeClass );
> +#endif
> +            OSL_ASSERT( 0 );
> +    }
> +    return false;
> +}
> +
> +bool aarch64::return_in_hidden_param( typelib_TypeDescriptionReference 
> *pTypeRef )
> +{
> +    int g, s;
> +    // Returned in registers iff examine_argument() says it fits; otherwise 
> the
> +    // caller must pass an indirect-result buffer in x8.
> +    return !examine_argument( pTypeRef, true, g, s );
> +}
> +
> +void aarch64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, const 
> sal_uInt64 *pGPR, const double *pFPR, void *pStruct )
> +{
> +    int nUsedGPR = 0;
> +    int nUsedFPR = 0;
> +    if ( !examine_argument( pTypeRef, true, nUsedGPR, nUsedFPR ) )
> +    {
> +        // Should not happen: indirect returns are written through x8 
> directly,
> +        // not scattered here.
> +        OSL_ASSERT( 0 );
> +        return;
> +    }
> +
> +    if ( nUsedFPR > 0 )
> +    {
> +        // HFA: each member occupies one v register; the members are 
> contiguous
> +        // in the struct.  Copy element-by-element to honour FLOAT (4-byte) 
> vs
> +        // DOUBLE (8-byte) element width.
> +        HfaKind kind = HFA_NONE;
> +        int count = 0;
> +        collectHfa( pTypeRef, kind, count );
> +        if ( kind == HFA_FLOAT )
> +        {
> +            float *pDest = reinterpret_cast<float *>( pStruct );
> +            for ( int i = 0; i < nUsedFPR; ++i )
> +                pDest[i] = static_cast<float>( pFPR[i] );
> +        }
> +        else // HFA_DOUBLE
> +        {
> +            double *pDest = reinterpret_cast<double *>( pStruct );
> +            for ( int i = 0; i < nUsedFPR; ++i )
> +                pDest[i] = pFPR[i];
> +        }
> +    }
> +    else
> +    {
> +        // Non-HFA aggregate <= 16 bytes: raw copy of the 1-2 GPRs.
> +        sal_uInt64 *pDest = reinterpret_cast<sal_uInt64 *>( pStruct );
> +        for ( int i = 0; i < nUsedGPR; ++i )
> +            pDest[i] = pGPR[i];
> +    }
> +}
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
> new file mode 100644
> index 0000000000..7d55ac076c
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
> @@ -0,0 +1,86 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +
> +
> +#ifndef _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
> +#define _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
> +
> +// This is an implementation of the AArch64 procedure call standard, as
> +// described in "Procedure Call Standard for the Arm 64-bit Architecture"
> +// (ARM IHI 0055), with the deviations documented in Apple's "Writing ARM64
> +// Code for Apple Platforms".  It is a clean-room implementation written from
> +// those public specifications; see ../../../../AAPCS64_BRIDGE_SPEC.md.
> +
> +#include <typelib/typedescription.hxx>
> +
> +namespace aarch64
> +{
> +
> +/* 8 general purpose registers (x0..x7) are used for parameter passing.
> +   Note: the indirect-result-location register x8 is *separate* and is NOT
> +   part of this count. */
> +const sal_uInt32 MAX_GPR_REGS = 8;
> +
> +/* 8 SIMD/FP registers (v0..v7) are used for parameter passing. */
> +const sal_uInt32 MAX_FPR_REGS = 8;
> +
> +/* The largest number of registers a single aggregate can occupy: an HFA/HVA
> +   may use up to 4 FP registers; a non-HFA aggregate passed in GPRs uses at
> +   most 2 (16 bytes / 8). */
> +const sal_uInt32 MAX_AGGREGATE_REGS = 4;
> +
> +/* Count the number of registers required to pass the given type.
> +
> +   Examines the argument and sets the number of GPR (x) and FPR (v) registers
> +   it would consume.  For a Homogeneous Floating-point Aggregate the FPR 
> count
> +   is the number of members (<= 4); for a non-HFA aggregate <= 16 bytes the 
> GPR
> +   count is 1 or 2; scalars use exactly one register of the appropriate bank.
> +
> +   Returns false iff the parameter must be passed indirectly (in memory): a
> +   non-HFA aggregate larger than 16 bytes.  When bInReturn is true the same
> +   classification answers "can this be returned in registers?" (false => the
> +   caller must allocate a buffer and pass it in x8).
> +*/
> +bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool 
> bInReturn, int &nUsedGPR, int &nUsedFPR );
> +
> +/** Does a function returning this type use the hidden indirect-result 
> pointer
> +    (passed by the caller in x8), or can it return in registers?
> +
> +    A scalar returns in x0 or v0; an HFA returns in v0..v3; a non-HFA 
> aggregate
> +    of <= 16 bytes returns in x0,x1.  Anything larger (non-HFA aggregate
> +    > 16 bytes) is returned via the caller-allocated buffer addressed by x8 -
> +    that is the "hidden param" case, for which this returns true.
> +*/
> +bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
> +
> +/** Scatter a register-resident return value (an HFA returned in v0..v3, or a
> +    non-HFA aggregate <= 16 bytes returned in x0,x1) into the caller's 
> struct.
> +
> +    pGPR points at the saved x0,x1,... ; pFPR at the saved v0,v1,... (each
> +    element the low 8 bytes of a v register, i.e. a double slot).  Only valid
> +    when return_in_hidden_param() is false.
> +*/
> +void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const 
> sal_uInt64* pGPR, const double* pFPR, void *pStruct );
> +
> +} // namespace aarch64
> +
> +#endif // _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
> new file mode 100644
> index 0000000000..035b38555a
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
> @@ -0,0 +1,168 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +// AArch64 (Apple Silicon, AAPCS64) outgoing-call trampoline for the C++-UNO
> +// bridge.  Loads the argument registers from caller-prepared arrays, copies
> +// any overflow arguments to the outgoing stack, performs the indirect call,
> +// and stores the integer and FP/SIMD return registers back.
> +//
> +// See AAPCS64_BRIDGE_SPEC.md.  Mach-O assembler syntax; symbols are prefixed
> +// with an underscore per the Darwin C ABI.
> +//
> +// extern "C" void callVirtualFunction(
> +//     sal_uInt64  pFunction,     // x0: target C++ virtual method
> +//     sal_uInt64  pIndirectRet,  // x1: value for x8 (indirect result ptr), 
> 0 if none
> +//     sal_uInt64 *pGPR,          // x2: 8 words  -> x0..x7
> +//     double     *pFPR,          // x3: 8 doubles -> d0..d7
> +//     sal_uInt64 *pStack,        // x4: overflow-arg words
> +//     sal_uInt32  nStackWords,   // x5: number of 8-byte overflow words
> +//     sal_uInt64 *pGPRReturn,    // x6: [out] x0,x1
> +//     double     *pFPRReturn);   // x7: [out] d0..d3 (HFA up to 4 elements)
> +
> +    .text
> +    .globl _callVirtualFunction
> +    .p2align 2
> +_callVirtualFunction:
> +    // prologue: save fp/lr and the callee-saved registers we use
> +    stp     x29, x30, [sp, #-16]!
> +    stp     x19, x20, [sp, #-16]!
> +    stp     x21, x22, [sp, #-16]!
> +    stp     x23, x24, [sp, #-16]!
> +    mov     x29, sp
> +
> +    // stash inputs that must survive the call into callee-saved registers
> +    mov     x19, x0                     // pFunction
> +    mov     x20, x2                     // pGPR
> +    mov     x21, x3                     // pFPR
> +    mov     x22, x6                     // pGPRReturn
> +    mov     x23, x7                     // pFPRReturn
> +    mov     x24, x1                     // x8 indirect-result value
> +
> +    // allocate and copy the outgoing overflow stack arguments.
> +    // bytes = ((nStackWords + 1) & ~1) * 8, to keep sp 16-byte aligned.
> +    add     x9, x5, #1
> +    bic     x9, x9, #1
> +    lsl     x9, x9, #3
> +    sub     sp, sp, x9
> +    mov     x10, #0
> +Lcvf_copy:
> +    cmp     x10, x5
> +    b.ge    Lcvf_copied
> +    ldr     x11, [x4, x10, lsl #3]
> +    str     x11, [sp, x10, lsl #3]
> +    add     x10, x10, #1
> +    b       Lcvf_copy
> +Lcvf_copied:
> +
> +    // load the FP/SIMD argument registers d0..d7
> +    ldp     d0, d1, [x21, #0]
> +    ldp     d2, d3, [x21, #16]
> +    ldp     d4, d5, [x21, #32]
> +    ldp     d6, d7, [x21, #48]
> +
> +    // load the GP argument registers x0..x7 and the x8 indirect-result reg
> +    mov     x8, x24
> +    ldp     x6, x7, [x20, #48]
> +    ldp     x4, x5, [x20, #32]
> +    ldp     x2, x3, [x20, #16]
> +    ldp     x0, x1, [x20, #0]
> +
> +    // perform the virtual call
> +    blr     x19
> +
> +    // store the return registers
> +    str     x0, [x22, #0]
> +    str     x1, [x22, #8]
> +    str     d0, [x23, #0]
> +    str     d1, [x23, #8]
> +    str     d2, [x23, #16]
> +    str     d3, [x23, #24]
> +
> +    // epilogue
> +    mov     sp, x29
> +    ldp     x23, x24, [sp], #16
> +    ldp     x21, x22, [sp], #16
> +    ldp     x19, x20, [sp], #16
> +    ldp     x29, x30, [sp], #16
> +    ret
> +
> +// 
> ---------------------------------------------------------------------------
> +// privateSnippetExecutor: the incoming (cpp2uno) register-spill executor.
> +//
> +// Reached by a BR from a per-vtable-slot code snippet (see codeSnippet() in
> +// cpp2uno.cxx) with:
> +//   x16 = (nVtableOffset << 32) | nFunctionIndex  (low bit 0x80000000 flags 
> a
> +//         hidden/indirect return)
> +//   x0..x7, d0..d7, x8 = the original incoming arguments (untouched)
> +//   sp  = the caller's stack-argument area (overflow)
> +//   x30 = return address back into the original C++ caller
> +//
> +// It spills the argument registers to a save area and calls cpp_vtable_call,
> +// then loads the return value back into x0/x1 and d0/d1 (or d0 for fp).
> +//
> +//   typelib_TypeClass cpp_vtable_call(
> +//       sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
> +//       void** gpreg, void** fpreg, void** ovrflw,
> +//       void* pIndirectReturn, sal_uInt64* pRegisterReturn);
> +//
> +// Frame (176 bytes): [0]=x29,x30  [16..79]=x0..x7  [80..143]=d0..d7
> +//                    [144..159]=return buffer.
> +    .globl _privateSnippetExecutor
> +    .p2align 2
> +_privateSnippetExecutor:
> +    mov     x17, sp                     // x17 = ovrflw (incoming stack args)
> +    stp     x29, x30, [sp, #-176]!
> +    mov     x29, sp
> +
> +    stp     x0, x1, [sp, #16]           // save GP argument registers x0..x7
> +    stp     x2, x3, [sp, #32]
> +    stp     x4, x5, [sp, #48]
> +    stp     x6, x7, [sp, #64]
> +
> +    stp     d0, d1, [sp, #80]           // save FP/SIMD argument registers 
> d0..d7
> +    stp     d2, d3, [sp, #96]
> +    stp     d4, d5, [sp, #112]
> +    stp     d6, d7, [sp, #128]
> +
> +    mov     w0, w16                     // nFunctionIndex (low 32 bits)
> +    lsr     x1, x16, #32                // nVtableOffset (high 32 bits)
> +    add     x2, sp, #16                 // gpreg
> +    add     x3, sp, #80                 // fpreg
> +    mov     x4, x17                     // ovrflw
> +    mov     x5, x8                      // pIndirectReturn (x8 
> indirect-result reg)
> +    add     x6, sp, #144                // pRegisterReturn (16-byte buffer)
> +    bl      _cpp_vtable_call
> +
> +    cmp     w0, #10                     // typelib_TypeClass_FLOAT
> +    b.eq    Lpse_float
> +    cmp     w0, #11                     // typelib_TypeClass_DOUBLE
> +    b.eq    Lpse_float
> +    // integer / pointer / <=16B aggregate: load both banks; caller reads the
> +    // ones that matter for its return type.
> +    ldp     x0, x1, [sp, #144]
> +    ldp     d0, d1, [sp, #144]
> +    b       Lpse_done
> +Lpse_float:
> +    ldr     d0, [sp, #144]
> +Lpse_done:
> +    mov     sp, x29
> +    ldp     x29, x30, [sp], #176
> +    ret
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
> new file mode 100644
> index 0000000000..6fa6bac7a2
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
> @@ -0,0 +1,543 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +
> +
> +// MARKER(update_precomp.py): autogen include statement, do not remove
> +#include "precompiled_bridges.hxx"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <hash_map>
> +
> +#include <rtl/alloc.h>
> +#include <osl/mutex.hxx>
> +
> +#include <com/sun/star/uno/genfunc.hxx>
> +#include "com/sun/star/uno/RuntimeException.hpp"
> +#include <uno/data.h>
> +#include <typelib/typedescription.hxx>
> +
> +#include "bridges/cpp_uno/shared/bridge.hxx"
> +#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
> +#include "bridges/cpp_uno/shared/types.hxx"
> +#include "bridges/cpp_uno/shared/vtablefactory.hxx"
> +
> +#include "abi.hxx"
> +#include "share.hxx"
> +
> +using namespace ::osl;
> +using namespace ::rtl;
> +using namespace ::com::sun::star::uno;
> +
> +//==================================================================================================
> +
> +// Perform the UNO call
> +//
> +// We must convert the parameters stored in gpreg, fpreg and ovrflw to UNO
> +// arguments and call pThis->getUnoI()->pDispatcher.
> +//
> +// gpreg:  this, [gpr params x0..x7]   (the indirect-result ptr is x8, 
> separate)
> +// fpreg:  [fpr params d0..d7]
> +// ovrflw: [gpr or fpr params (properly aligned)]
> +//
> +// On AArch64 a structure bigger than 16 bytes is returned via the buffer
> +// addressed by x8 (pIndirectReturn); 'this' is always x0 = gpreg[0].
> +// Simple types are returned in x0,x1 (int) or d0,d1 (fp); HFAs in d0..d3;
> +// non-HFA structures <= 16 bytes in x0,x1.
> +static typelib_TypeClass cpp2uno_call(
> +     bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
> +     const typelib_TypeDescription * pMemberTypeDescr,
> +     typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void 
> return
> +     sal_Int32 nParams, typelib_MethodParameter * pParams,
> +     void ** gpreg, void ** fpreg, void ** ovrflw,
> +     void * pIndirectReturn, // AArch64 x8 indirect-result pointer (0 if 
> none)
> +     sal_uInt64 * pRegisterReturn /* space for register return */ )
> +{
> +     unsigned int nr_gpr = 0; //number of gpr registers used
> +     unsigned int nr_fpr = 0; //number of fpr registers used
> +
> +     // return
> +     typelib_TypeDescription * pReturnTypeDescr = 0;
> +     if (pReturnTypeRef)
> +             TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
> +
> +     void * pUnoReturn = 0;
> +     void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, 
> reconversion need
> +
> +     if ( pReturnTypeDescr )
> +     {
> +             if ( aarch64::return_in_hidden_param( pReturnTypeRef ) )
> +             {
> +                     // AArch64: the indirect-result pointer arrives in x8, 
> NOT in the
> +                     // first general-purpose argument register (unlike 
> x86-64 SysV).
> +                     // So we take it from pIndirectReturn and do NOT 
> consume a gpreg
> +                     // slot here; 'this' still occupies gpreg[0] below.
> +                     pCppReturn = pIndirectReturn;
> +
> +                     pUnoReturn = ( 
> bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
> +                                                ? alloca( 
> pReturnTypeDescr->nSize )
> +                                                : pCppReturn ); // direct way
> +             }
> +             else
> +                     pUnoReturn = pRegisterReturn; // direct way for simple 
> types
> +     }
> +
> +     // pop this (x0)
> +     gpreg++;
> +     nr_gpr++;
> +
> +     // stack space
> +     // parameters
> +     void ** pUnoArgs = reinterpret_cast<void **>(alloca( 4 * sizeof(void *) 
> * nParams ));
> +     void ** pCppArgs = pUnoArgs + nParams;
> +     // indizes of values this have to be converted (interface conversion 
> cpp<=>uno)
> +     sal_Int32 * pTempIndizes = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 
> * nParams));
> +     // type descriptions for reconversions
> +     typelib_TypeDescription ** ppTempParamTypeDescr = 
> reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
> +
> +     sal_Int32 nTempIndizes = 0;
> +
> +     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
> +     {
> +             const typelib_MethodParameter & rParam = pParams[nPos];
> +
> +             int nUsedGPR = 0;
> +             int nUsedFPR = 0;
> +             bool bFitsRegisters = aarch64::examine_argument( 
> rParam.pTypeRef, false, nUsedGPR, nUsedFPR );
> +             if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
> rParam.pTypeRef ) ) // value
> +             {
> +                     // A simple UNO type occupies exactly one register, GPR 
> or FPR.
> +                     OSL_ASSERT( bFitsRegisters && ( ( nUsedFPR == 1 && 
> nUsedGPR == 0 ) || ( nUsedFPR == 0 && nUsedGPR == 1 ) ) );
> +
> +                     if ( nUsedFPR == 1 )
> +                     {
> +                             if ( nr_fpr < aarch64::MAX_FPR_REGS )
> +                             {
> +                                     pCppArgs[nPos] = pUnoArgs[nPos] = 
> fpreg++;
> +                                     nr_fpr++;
> +                             }
> +                             else
> +                                     pCppArgs[nPos] = pUnoArgs[nPos] = 
> ovrflw++;
> +                     }
> +                     else if ( nUsedGPR == 1 )
> +                     {
> +                             if ( nr_gpr < aarch64::MAX_GPR_REGS )
> +                             {
> +                                     pCppArgs[nPos] = pUnoArgs[nPos] = 
> gpreg++;
> +                                     nr_gpr++;
> +                             }
> +                             else
> +                                     pCppArgs[nPos] = pUnoArgs[nPos] = 
> ovrflw++;
> +                     }
> +             }
> +             else // struct <= 16 bytes || ptr to complex value || ref
> +             {
> +                     typelib_TypeDescription * pParamTypeDescr = 0;
> +                     TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
> +
> +                     void *pCppStack;
> +                     if ( nr_gpr < aarch64::MAX_GPR_REGS )
> +                     {
> +                             pCppArgs[nPos] = pCppStack = *gpreg++;
> +                             nr_gpr++;
> +                     }
> +                     else
> +                             pCppArgs[nPos] = pCppStack = *ovrflw++;
> +
> +                     if (! rParam.bIn) // is pure out
> +                     {
> +                             // uno out is unconstructed mem!
> +                             pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize 
> );
> +                             pTempIndizes[nTempIndizes] = nPos;
> +                             // will be released at reconversion
> +                             ppTempParamTypeDescr[nTempIndizes++] = 
> pParamTypeDescr;
> +                     }
> +                     else if ( 
> bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is 
> in/inout
> +                     {
> +                             uno_copyAndConvertData( pUnoArgs[nPos] = 
> alloca( pParamTypeDescr->nSize ),
> +                                                                             
> pCppStack, pParamTypeDescr,
> +                                                                             
> pThis->getBridge()->getCpp2Uno() );
> +                             pTempIndizes[nTempIndizes] = nPos; // has to be 
> reconverted
> +                             // will be released at reconversion
> +                             ppTempParamTypeDescr[nTempIndizes++] = 
> pParamTypeDescr;
> +                     }
> +                     else // direct way
> +                     {
> +                             pUnoArgs[nPos] = pCppStack;
> +                             // no longer needed
> +                             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
> +                     }
> +             }
> +     }
> +
> +     // ExceptionHolder
> +     uno_Any aUnoExc; // Any will be constructed by callee
> +     uno_Any * pUnoExc = &aUnoExc;
> +
> +     // invoke uno dispatch call
> +     (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, 
> pUnoReturn, pUnoArgs, &pUnoExc );
> +
> +     // in case an exception occurred...
> +     if ( pUnoExc )
> +     {
> +             // destruct temporary in/inout params
> +             for ( ; nTempIndizes--; )
> +             {
> +                     sal_Int32 nIndex = pTempIndizes[nTempIndizes];
> +
> +                     if (pParams[nIndex].bIn) // is in/inout => was 
> constructed
> +                             uno_destructData( pUnoArgs[nIndex], 
> ppTempParamTypeDescr[nTempIndizes], 0 );
> +                     TYPELIB_DANGER_RELEASE( 
> ppTempParamTypeDescr[nTempIndizes] );
> +             }
> +             if (pReturnTypeDescr)
> +                     TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
> +
> +             CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, 
> pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
> +             // is here for dummy
> +             return typelib_TypeClass_VOID;
> +     }
> +     else // else no exception occurred...
> +     {
> +             // temporary params
> +             for ( ; nTempIndizes--; )
> +             {
> +                     sal_Int32 nIndex = pTempIndizes[nTempIndizes];
> +                     typelib_TypeDescription * pParamTypeDescr = 
> ppTempParamTypeDescr[nTempIndizes];
> +
> +                     if ( pParams[nIndex].bOut ) // inout/out
> +                     {
> +                             // convert and assign
> +                             uno_destructData( pCppArgs[nIndex], 
> pParamTypeDescr, cpp_release );
> +                             uno_copyAndConvertData( pCppArgs[nIndex], 
> pUnoArgs[nIndex], pParamTypeDescr,
> +                                                                             
> pThis->getBridge()->getUno2Cpp() );
> +                     }
> +                     // destroy temp uno param
> +                     uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 
> );
> +
> +                     TYPELIB_DANGER_RELEASE( pParamTypeDescr );
> +             }
> +             // return
> +             if ( pCppReturn ) // has complex return
> +             {
> +                     if ( pUnoReturn != pCppReturn ) // needs reconversion
> +                     {
> +                             uno_copyAndConvertData( pCppReturn, pUnoReturn, 
> pReturnTypeDescr,
> +                                                                             
> pThis->getBridge()->getUno2Cpp() );
> +                             // destroy temp uno return
> +                             uno_destructData( pUnoReturn, pReturnTypeDescr, 
> 0 );
> +                     }
> +                     // complex return ptr is set to return reg
> +                     *reinterpret_cast<void **>(pRegisterReturn) = 
> pCppReturn;
> +             }
> +             if ( pReturnTypeDescr )
> +             {
> +                     typelib_TypeClass eRet = 
> (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
> +                     TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
> +                     return eRet;
> +             }
> +             else
> +                     return typelib_TypeClass_VOID;
> +     }
> +}
> +
> +
> +//==================================================================================================
> +extern "C" typelib_TypeClass cpp_vtable_call(
> +     sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
> +     void ** gpreg, void ** fpreg, void ** ovrflw,
> +     void * pIndirectReturn, // AArch64 x8 indirect-result pointer (0 if 
> none)
> +     sal_uInt64 * pRegisterReturn /* space for register return */ )
> +{
> +     // gpreg:  this, [other gpr params x0..x7]
> +     // fpreg:  [fpr params d0..d7]
> +     // ovrflw: [gpr or fpr params (properly aligned)]
> +     // pIndirectReturn: x8 (the hidden return buffer), when bit 0x80000000 
> set.
> +     //
> +     // On AArch64 'this' is ALWAYS x0 = gpreg[0]; the hidden return pointer 
> is
> +     // the separate x8 register, not a displaced first GPR (unlike x86-64 
> SysV
> +     // where it occupied gpreg[0] and 'this' moved to gpreg[1]).
> +     if ( nFunctionIndex & 0x80000000 )
> +             nFunctionIndex &= 0x7fffffff;
> +
> +     void * pThis = gpreg[0];
> +     pThis = static_cast<char *>( pThis ) - nVtableOffset;
> +
> +     bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
> +             
> bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
> +
> +     typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
> +
> +     OSL_ENSURE( nFunctionIndex < 
> pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" );
> +     if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
> +     {
> +             throw RuntimeException( OUString::createFromAscii("illegal 
> vtable index!"),
> +                                                             
> reinterpret_cast<XInterface *>( pCppI ) );
> +     }
> +
> +     // determine called method
> +     sal_Int32 nMemberPos = 
> pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
> +     OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member 
> index!\n" );
> +
> +     TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
> +
> +     typelib_TypeClass eRet;
> +     switch ( aMemberDescr.get()->eTypeClass )
> +     {
> +             case typelib_TypeClass_INTERFACE_ATTRIBUTE:
> +             {
> +                     typelib_TypeDescriptionReference *pAttrTypeRef =
> +                             
> reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( 
> aMemberDescr.get() )->pAttributeTypeRef;
> +
> +                     if ( 
> pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
> +                     {
> +                             // is GET method
> +                             eRet = cpp2uno_call( pCppI, aMemberDescr.get(), 
> pAttrTypeRef,
> +                                             0, 0, // no params
> +                                             gpreg, fpreg, ovrflw, 
> pIndirectReturn, pRegisterReturn );
> +                     }
> +                     else
> +                     {
> +                             // is SET method
> +                             typelib_MethodParameter aParam;
> +                             aParam.pTypeRef = pAttrTypeRef;
> +                             aParam.bIn              = sal_True;
> +                             aParam.bOut             = sal_False;
> +
> +                             eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
> +                                             0, // indicates void return
> +                                             1, &aParam,
> +                                             gpreg, fpreg, ovrflw, 
> pIndirectReturn, pRegisterReturn );
> +                     }
> +                     break;
> +             }
> +             case typelib_TypeClass_INTERFACE_METHOD:
> +             {
> +                     // is METHOD
> +                     switch ( nFunctionIndex )
> +                     {
> +                             case 1: // acquire()
> +                                     pCppI->acquireProxy(); // non virtual 
> call!
> +                                     eRet = typelib_TypeClass_VOID;
> +                                     break;
> +                             case 2: // release()
> +                                     pCppI->releaseProxy(); // non virtual 
> call!
> +                                     eRet = typelib_TypeClass_VOID;
> +                                     break;
> +                             case 0: // queryInterface() opt
> +                             {
> +                                     // queryInterface([in] type) returns an 
> Any (> 16 bytes),
> +                                     // so on AArch64 the result buffer is 
> x8 (pIndirectReturn),
> +                                     // 'this' is gpreg[0], and the type 
> argument is the first
> +                                     // real parameter, gpreg[1].
> +                                     typelib_TypeDescription * pTD = 0;
> +                                     TYPELIB_DANGER_GET( &pTD, 
> reinterpret_cast<Type *>( gpreg[1] )->getTypeLibType() );
> +                                     if ( pTD )
> +                                     {
> +                                             XInterface * pInterface = 0;
> +                                             
> (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
> +                                                     ( 
> pCppI->getBridge()->getCppEnv(),
> +                                                       reinterpret_cast<void 
> **>(&pInterface),
> +                                                       pCppI->getOid().pData,
> +                                                       
> reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
> +
> +                                             if ( pInterface )
> +                                             {
> +                                                     ::uno_any_construct( 
> reinterpret_cast<uno_Any *>( pIndirectReturn ),
> +                                                                             
>                  &pInterface, pTD, cpp_acquire );
> +
> +                                                     pInterface->release();
> +                                                     TYPELIB_DANGER_RELEASE( 
> pTD );
> +
> +                                                     reinterpret_cast<void 
> **>( pRegisterReturn )[0] = pIndirectReturn;
> +                                                     eRet = 
> typelib_TypeClass_ANY;
> +                                                     break;
> +                                             }
> +                                             TYPELIB_DANGER_RELEASE( pTD );
> +                                     }
> +                             } // else perform queryInterface()
> +                             default:
> +                             {
> +                                     typelib_InterfaceMethodTypeDescription 
> *pMethodTD =
> +                                             
> reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( 
> aMemberDescr.get() );
> +
> +                                     eRet = cpp2uno_call( pCppI, 
> aMemberDescr.get(),
> +                                                                             
>  pMethodTD->pReturnTypeRef,
> +                                                                             
>  pMethodTD->nParams,
> +                                                                             
>  pMethodTD->pParams,
> +                                                                             
>  gpreg, fpreg, ovrflw, pIndirectReturn, pRegisterReturn );
> +                             }
> +                     }
> +                     break;
> +             }
> +             default:
> +             {
> +                     throw RuntimeException( OUString::createFromAscii("no 
> member description found!"),
> +                                                                     
> reinterpret_cast<XInterface *>( pCppI ) );
> +                     // is here for dummy
> +                     eRet = typelib_TypeClass_VOID;
> +             }
> +     }
> +
> +     return eRet;
> +}
> +
> +//==================================================================================================
> +// The incoming register-spill executor, implemented in call.s.  It is 
> reached
> +// via BR from a per-slot snippet (codeSnippet below) with x16 carrying the
> +// packed (nVtableOffset << 32) | nFunctionIndex; it spills the argument
> +// registers and calls cpp_vtable_call.
> +extern "C" void privateSnippetExecutor( void );
> +
> +// Each snippet is 5 AArch64 instructions (20 bytes) + 4 bytes padding to an
> +// 8-byte boundary + two 8-byte literals (the packed index and the executor
> +// address) = 40 bytes.
> +const int codeSnippetSize = 40;
> +
> +// Generate a per-vtable-slot trampoline that loads the packed function index
> +// into x16 and branches to privateSnippetExecutor(), preserving every
> +// argument register.  Uses PC-relative literal loads because AArch64 cannot
> +// embed a 64-bit immediate in a single instruction.
> +//
> +// Layout (offsets in bytes from code):
> +//    0:  ldr  x16, #24      ; x16 = nOffsetAndIndex (literal at +24)
> +//    4:  ldr  x17, #28      ; x17 = privateSnippetExecutor (literal at +32)
> +//    8:  br   x17
> +//   12:  (unused / padding)
> +//   16:  (padding to 8-byte align the literals at 24)
> +//   24:  .quad nOffsetAndIndex
> +//   32:  .quad privateSnippetExecutor
> +//
> +// Note: the snippet creates no stack frame, so the C++ unwinder walks 
> straight
> +// through it to the original caller (required for UNO exception 
> propagation).
> +unsigned char * codeSnippet( unsigned char * code,
> +        sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
> +        bool bHasHiddenParam ) SAL_THROW( () )
> +{
> +     sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>( nVtableOffset ) 
> << 32 ) | static_cast<sal_uInt64>( nFunctionIndex );
> +
> +     if ( bHasHiddenParam )
> +             nOffsetAndIndex |= 0x80000000;
> +
> +     sal_uInt32 * p = reinterpret_cast<sal_uInt32 *>( code );
> +
> +     // ldr x16, #24  -> literal at code+24. imm19 = 24/4 = 6.
> +     //   encoding: 0x58000000 | (imm19 << 5) | Rt(16)
> +     p[0] = 0x58000000 | ( 6 << 5 ) | 16;
> +     // ldr x17, #28  -> literal at code+32 (relative to this insn at +4): 
> 28.
> +     //   imm19 = 28/4 = 7.
> +     p[1] = 0x58000000 | ( 7 << 5 ) | 17;
> +     // br x17  -> 0xD61F0000 | (Rn(17) << 5)
> +     p[2] = 0xD61F0000 | ( 17 << 5 );
> +     // p[3] (offset 12) and p[4] (offset 16..20) are padding.
> +     p[3] = 0xD503201F; // NOP
> +     p[4] = 0xD503201F; // NOP
> +
> +     // literals, 8-byte aligned at offset 24 and 32
> +     *reinterpret_cast<sal_uInt64 *>( code + 24 ) = nOffsetAndIndex;
> +     *reinterpret_cast<sal_uInt64 *>( code + 32 ) = 
> reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
> +
> +     return code + codeSnippetSize;
> +}
> +
> +//==================================================================================================
> +struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
> +
> +bridges::cpp_uno::shared::VtableFactory::Slot *
> +bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
> +{
> +    return static_cast< Slot * >(block) + 2;
> +}
> +
> +//==================================================================================================
> +sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
> +    sal_Int32 slotCount)
> +{
> +    return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
> +}
> +
> +//==================================================================================================
> +bridges::cpp_uno::shared::VtableFactory::Slot *
> +bridges::cpp_uno::shared::VtableFactory::initializeBlock(
> +    void * block, sal_Int32 slotCount)
> +{
> +    Slot * slots = mapBlockToVtable(block);
> +    slots[-2].fn = 0;
> +    slots[-1].fn = 0;
> +    return slots + slotCount;
> +}
> +
> +//==================================================================================================
> +
> +unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
> +     Slot ** slots, unsigned char * code, /*sal_PtrDiff writetoexecdiff,*/
> +     typelib_InterfaceTypeDescription const * type, sal_Int32 
> nFunctionOffset,
> +     sal_Int32 functionCount, sal_Int32 nVtableOffset )
> +{
> +     const sal_PtrDiff writetoexecdiff = 0;
> +     (*slots) -= functionCount;
> +     Slot * s = *slots;
> +     for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
> +     {
> +             typelib_TypeDescription * pTD = 0;
> +
> +             TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
> +             OSL_ASSERT( pTD );
> +
> +             if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
> +             {
> +                     typelib_InterfaceAttributeTypeDescription *pAttrTD =
> +                             
> reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
> +
> +                     // get method
> +                     (s++)->fn = code + writetoexecdiff;
> +                     code = codeSnippet( code, nFunctionOffset++, 
> nVtableOffset,
> +                                                             
> aarch64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
> +
> +                     if ( ! pAttrTD->bReadOnly )
> +                     {
> +                             // set method
> +                             (s++)->fn = code + writetoexecdiff;
> +                             code = codeSnippet( code, nFunctionOffset++, 
> nVtableOffset, false );
> +                     }
> +             }
> +             else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass 
> )
> +             {
> +                     typelib_InterfaceMethodTypeDescription *pMethodTD =
> +                             
> reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
> +
> +                     (s++)->fn = code + writetoexecdiff;
> +                     code = codeSnippet( code, nFunctionOffset++, 
> nVtableOffset,
> +                                                             
> aarch64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
> +             }
> +             else
> +                     OSL_ASSERT( false );
> +
> +             TYPELIB_DANGER_RELEASE( pTD );
> +     }
> +     return code;
> +}
> +
> +//==================================================================================================
> +void bridges::cpp_uno::shared::VtableFactory::flushCode(
> +     unsigned char const *, unsigned char const * )
> +{
> +}
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
> new file mode 100644
> index 0000000000..60784a4172
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
> @@ -0,0 +1,358 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +
> +
> +// MARKER(update_precomp.py): autogen include statement, do not remove
> +#include "precompiled_bridges.hxx"
> +
> +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
> +#include <exception>
> +#endif
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <dlfcn.h>
> +#include <cxxabi.h>
> +#include <hash_map>
> +#include <sys/param.h>
> +
> +#include <rtl/strbuf.hxx>
> +#include <rtl/ustrbuf.hxx>
> +#include <osl/diagnose.h>
> +#include <osl/mutex.hxx>
> +
> +#include <com/sun/star/uno/genfunc.hxx>
> +#include "com/sun/star/uno/RuntimeException.hpp"
> +#include <typelib/typedescription.hxx>
> +#include <uno/any2.h>
> +
> +#include "share.hxx"
> +
> +
> +using namespace ::std;
> +using namespace ::osl;
> +using namespace ::rtl;
> +using namespace ::com::sun::star::uno;
> +using namespace ::__cxxabiv1;
> +
> +
> +namespace CPPU_CURRENT_NAMESPACE
> +{
> +
> +void dummy_can_throw_anything( char const * )
> +{
> +}
> +
> +//==================================================================================================
> +static OUString toUNOname( char const * p ) SAL_THROW( () )
> +{
> +#if OSL_DEBUG_LEVEL > 1
> +    char const * start = p;
> +#endif
> +
> +    // example: N3com3sun4star4lang24IllegalArgumentExceptionE
> +
> +     OUStringBuffer buf( 64 );
> +    OSL_ASSERT( 'N' == *p );
> +    ++p; // skip N
> +
> +    while ('E' != *p)
> +    {
> +        // read chars count
> +        long n = (*p++ - '0');
> +        while ('0' <= *p && '9' >= *p)
> +        {
> +            n *= 10;
> +            n += (*p++ - '0');
> +        }
> +        buf.appendAscii( p, n );
> +        p += n;
> +        if ('E' != *p)
> +            buf.append( (sal_Unicode)'.' );
> +    }
> +
> +#if OSL_DEBUG_LEVEL > 1
> +    OUString ret( buf.makeStringAndClear() );
> +    OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
> +    fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
> +    return ret;
> +#else
> +    return buf.makeStringAndClear();
> +#endif
> +}
> +
> +//==================================================================================================
> +class RTTI
> +{
> +    typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
> +
> +    Mutex m_mutex;
> +     t_rtti_map m_rttis;
> +    t_rtti_map m_generatedRttis;
> +
> +    void * m_hApp;
> +
> +public:
> +    RTTI() SAL_THROW( () );
> +    ~RTTI() SAL_THROW( () );
> +
> +    type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
> +};
> +
> +//__________________________________________________________________________________________________
> +RTTI::RTTI() SAL_THROW( () )
> +    : m_hApp( dlopen( 0, RTLD_LAZY ) )
> +{
> +}
> +
> +//__________________________________________________________________________________________________
> +RTTI::~RTTI() SAL_THROW( () )
> +{
> +    dlclose( m_hApp );
> +}
> +
> +//__________________________________________________________________________________________________
> +type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) 
> SAL_THROW( () )
> +{
> +    type_info * rtti;
> +
> +    OUString const & unoName = *(OUString const 
> *)&pTypeDescr->aBase.pTypeName;
> +
> +    MutexGuard guard( m_mutex );
> +    t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
> +    if (iFind == m_rttis.end())
> +    {
> +        // RTTI symbol
> +        OStringBuffer buf( 64 );
> +        buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
> +        sal_Int32 index = 0;
> +        do
> +        {
> +            OUString token( unoName.getToken( 0, '.', index ) );
> +            buf.append( token.getLength() );
> +            OString c_token( OUStringToOString( token, 
> RTL_TEXTENCODING_ASCII_US ) );
> +            buf.append( c_token );
> +        }
> +        while (index >= 0);
> +        buf.append( 'E' );
> +
> +        OString symName( buf.makeStringAndClear() );
> +        rtti = static_cast<std::type_info *>(dlsym( m_hApp, symName.getStr() 
> ));
> +
> +        if (rtti)
> +        {
> +            pair< t_rtti_map::iterator, bool > insertion(
> +                m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
> +            OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" 
> );
> +        }
> +        else
> +        {
> +            // try to lookup the symbol in the generated rtti map
> +            t_rtti_map::const_iterator iFind2( m_generatedRttis.find( 
> unoName ) );
> +            if (iFind2 == m_generatedRttis.end())
> +            {
> +                // we must generate it !
> +                // symbol and rtti-name is nearly identical,
> +                // the symbol is prefixed with _ZTI
> +                char const * rttiName = symName.getStr() +4;
> +#if OSL_DEBUG_LEVEL > 1
> +                fprintf( stderr,"generated rtti for %s\n", rttiName );
> +                const OString aCUnoName = OUStringToOString( unoName, 
> RTL_TEXTENCODING_UTF8);
> +                OSL_TRACE( "TypeInfo for \"%s\" not found and cannot be 
> generated.\n", aCUnoName.getStr());
> +#endif
> +#ifndef AOO_BYPASS_RTTI
> +                if (pTypeDescr->pBaseTypeDescription)
> +                {
> +                    // ensure availability of base
> +                    type_info * base_rtti = getRTTI(
> +                        (typelib_CompoundTypeDescription 
> *)pTypeDescr->pBaseTypeDescription );
> +                    rtti = new __si_class_type_info(
> +                        strdup( rttiName ), (__class_type_info *)base_rtti );
> +                }
> +                else
> +                {
> +                    // this class has no base class
> +                    rtti = new __class_type_info( strdup( rttiName ) );
> +                }
> +#else
> +                rtti = NULL;
> +#endif
> +                bool bOK = m_generatedRttis.insert( t_rtti_map::value_type( 
> unoName, rtti )).second;
> +                OSL_ENSURE( bOK, "### inserting new generated rtti failed?!" 
> );
> +            }
> +            else // taking already generated rtti
> +            {
> +                rtti = iFind2->second;
> +            }
> +        }
> +    }
> +    else
> +    {
> +        rtti = iFind->second;
> +    }
> +
> +    return rtti;
> +}
> +
> +//--------------------------------------------------------------------------------------------------
> +static void deleteException( void * pExc )
> +{
> +    __cxa_exception const * header = static_cast<__cxa_exception const 
> *>(pExc) - 1;
> +    /* More __cxa_exception mumbo-jumbo. See share.hxx and 
> fillUnoException() below */
> +    if (header->exceptionDestructor != &deleteException)
> +    {
> +        header = reinterpret_cast<__cxa_exception const 
> *>(reinterpret_cast<char const *>(header) - 8);
> +    }
> +    if( !header->exceptionType)
> +    {
> +        return; // NOTE: leak for now
> +    }
> +    typelib_TypeDescription * pTD = 0;
> +    OUString unoName( toUNOname( header->exceptionType->name() ) );
> +    ::typelib_typedescription_getByName( &pTD, unoName.pData );
> +    OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => 
> leaking!!!" );
> +    if (pTD)
> +    {
> +             ::uno_destructData( pExc, pTD, cpp_release );
> +             ::typelib_typedescription_release( pTD );
> +     }
> +}
> +
> +//==================================================================================================
> +void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
> +{
> +#if OSL_DEBUG_LEVEL > 1
> +    OString cstr(
> +        OUStringToOString(
> +            *reinterpret_cast< OUString const * >( 
> &pUnoExc->pType->pTypeName ),
> +            RTL_TEXTENCODING_ASCII_US ) );
> +    fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
> +#endif
> +    void * pCppExc;
> +    type_info * rtti;
> +
> +    {
> +    // construct cpp exception object
> +     typelib_TypeDescription * pTypeDescr = 0;
> +     TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
> +    OSL_ASSERT( pTypeDescr );
> +    if (! pTypeDescr)
> +    {
> +        throw RuntimeException(
> +            OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get 
> typedescription for type ") ) +
> +            *reinterpret_cast< OUString const * >( 
> &pUnoExc->pType->pTypeName ),
> +            Reference< XInterface >() );
> +    }
> +
> +     pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
> +     ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp 
> );
> +
> +     // destruct uno exception
> +     ::uno_any_destruct( pUnoExc, 0 );
> +    // avoiding locked counts
> +    static RTTI * s_rtti = 0;
> +    if (! s_rtti)
> +    {
> +        MutexGuard guard( Mutex::getGlobalMutex() );
> +        if (! s_rtti)
> +        {
> +#ifdef LEAK_STATIC_DATA
> +            s_rtti = new RTTI();
> +#else
> +            static RTTI rtti_data;
> +            s_rtti = &rtti_data;
> +#endif
> +        }
> +    }
> +     rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription 
> *) pTypeDescr );
> +    TYPELIB_DANGER_RELEASE( pTypeDescr );
> +    OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
> +    if (! rtti)
> +    {
> +        throw RuntimeException(
> +            OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
> +            *reinterpret_cast< OUString const * >( 
> &pUnoExc->pType->pTypeName ),
> +            Reference< XInterface >() );
> +    }
> +    }
> +
> +     __cxa_throw( pCppExc, rtti, deleteException );
> +}
> +
> +//==================================================================================================
> +void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, 
> uno_Mapping * pCpp2Uno )
> +{
> +    if (! header)
> +    {
> +        RuntimeException aRE(
> +            OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
> +            Reference< XInterface >() );
> +        Type const & rType = ::getCppuType( &aRE );
> +        uno_type_any_constructAndConvert( pUnoExc, &aRE, 
> rType.getTypeLibType(), pCpp2Uno );
> +#if OSL_DEBUG_LEVEL > 0
> +        OString cstr( OUStringToOString( aRE.Message, 
> RTL_TEXTENCODING_ASCII_US ) );
> +        OSL_ENSURE( 0, cstr.getStr() );
> +#endif
> +        return;
> +    }
> +
> +    /*
> +     * Handle the case where we are built on llvm 10 (or later) but are 
> running
> +     * on an earlier version (eg, community builds). In this situation the
> +     * reserved ptr doesn't exist in the struct returned and so the offsets
> +     * that header uses are wrong. This assumes that reserved isn't used
> +     * and that referenceCount is always >0 in the cases we handle.
> +     * See share.hxx for the definition of __cxa_exception
> +     */
> +    if (*reinterpret_cast<void **>(header) == 0)
> +    {
> +        header = reinterpret_cast<__cxa_exception *>(reinterpret_cast<char 
> *>(header) + 8);
> +    }
> +
> +     typelib_TypeDescription * pExcTypeDescr = 0;
> +    OUString unoName( toUNOname( header->exceptionType->name() ) );
> +#if OSL_DEBUG_LEVEL > 1
> +    OString cstr_unoName( OUStringToOString( unoName, 
> RTL_TEXTENCODING_ASCII_US ) );
> +    fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() 
> );
> +#endif
> +     typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
> +    if (0 == pExcTypeDescr)
> +    {
> +        RuntimeException aRE(
> +            OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: 
> ") ) + unoName,
> +            Reference< XInterface >() );
> +        Type const & rType = ::getCppuType( &aRE );
> +        uno_type_any_constructAndConvert( pUnoExc, &aRE, 
> rType.getTypeLibType(), pCpp2Uno );
> +#if OSL_DEBUG_LEVEL > 0
> +        OString cstr( OUStringToOString( aRE.Message, 
> RTL_TEXTENCODING_ASCII_US ) );
> +        OSL_ENSURE( 0, cstr.getStr() );
> +#endif
> +    }
> +    else
> +    {
> +        // construct uno exception any
> +        uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, 
> pExcTypeDescr, pCpp2Uno );
> +        typelib_typedescription_release( pExcTypeDescr );
> +    }
> +}
> +
> +}
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/makefile.mk 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/makefile.mk
> new file mode 100644
> index 0000000000..af6c6c22d4
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/makefile.mk
> @@ -0,0 +1,81 @@
> +#**************************************************************
> +#
> +#  Licensed to the Apache Software Foundation (ASF) under one
> +#  or more contributor license agreements.  See the NOTICE file
> +#  distributed with this work for additional information
> +#  regarding copyright ownership.  The ASF licenses this file
> +#  to you under the Apache License, Version 2.0 (the
> +#  "License"); you may not use this file except in compliance
> +#  with the License.  You may obtain a copy of the License at
> +#
> +#    http://www.apache.org/licenses/LICENSE-2.0
> +#
> +#  Unless required by applicable law or agreed to in writing,
> +#  software distributed under the License is distributed on an
> +#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> +#  KIND, either express or implied.  See the License for the
> +#  specific language governing permissions and limitations
> +#  under the License.
> +#
> +#**************************************************************
> +
> +
> +
> +PRJ=..$/..$/..
> +
> +PRJNAME=bridges
> +TARGET=$(COMNAME)_uno
> +LIBTARGET=no
> +ENABLE_EXCEPTIONS=TRUE
> +
> +# --- Settings -----------------------------------------------------
> +
> +.INCLUDE :  settings.mk
> +
> +# --- Files --------------------------------------------------------
> +
> +# Apple Silicon (arm64 / AAPCS64) C++-UNO bridge. CPU=R, CPUNAME=AARCH64.
> +# Note: the "s5abi" in this directory's name is the macOS-wide COMNAME (see
> +# solenv/gbuild/platform/macosx.mk); the actual arm64 calling convention is
> +# AAPCS64, so "s5abi" here is a historical label, not a literal ABI claim.
> +.IF "$(OS)$(CPU)" == "MACOSXR"
> +
> +.IF "$(cppu_no_leak)" == ""
> +CFLAGS += -DLEAK_STATIC_DATA
> +.ENDIF
> +
> +# In case someone enabled the non-standard -fomit-frame-pointer which does 
> not
> +# work with the .cxx sources in this directory:
> +CFLAGSCXX += -fno-omit-frame-pointer -fnon-call-exceptions
> +
> +SLOFILES= \
> +     $(SLO)$/abi.obj                 \
> +     $(SLO)$/except.obj              \
> +     $(SLO)$/cpp2uno.obj             \
> +     $(SLO)$/uno2cpp.obj             \
> +     $(SLO)$/call.obj
> +
> +SHL1TARGET= $(TARGET)
> +
> +SHL1DEF=$(MISC)$/$(SHL1TARGET).def
> +SHL1IMPLIB=i$(TARGET)
> +SHL1VERSIONMAP=..$/..$/bridge_exports.map
> +SHL1RPATH=URELIB
> +
> +SHL1OBJS = $(SLOFILES)
> +SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
> +
> +SHL1STDLIBS= \
> +     $(CPPULIB)                      \
> +     $(SALLIB)
> +
> +.ENDIF
> +
> +# --- Targets ------------------------------------------------------
> +
> +.INCLUDE :  target.mk
> +
> +# Assemble the AArch64 call trampoline (call.s) into call.obj, mirroring the
> +# pattern rule used by the gcc3_linux_arm bridge for its armhelper.S.
> +$(SLO)$/%.obj: %.s
> +     $(CXX) -c -o $(SLO)$/$(@:b).o $< -fPIC ; touch $@
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
> new file mode 100644
> index 0000000000..e4fcf4dbf9
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
> @@ -0,0 +1,116 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +
> +
> +#include "uno/mapping.h"
> +
> +#include <typeinfo>
> +#include <exception>
> +#include <cstddef>
> +
> +namespace CPPU_CURRENT_NAMESPACE
> +{
> +
> +void dummy_can_throw_anything( char const * );
> +
> +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
> +
> +// ----- the following structure is compatible with the one declared in 
> libunwind's unwind.h
> +// (use forced types)
> +
> +struct _Unwind_Exception
> +{
> +    uint64_t exception_class;
> +    void * exception_cleanup;
> +    uintptr_t private_1;
> +    uintptr_t private_2;
> +};
> +
> +struct __cxa_exception
> +{
> +    /* From LLVM 10 a reserved member was added at the top of the struct on
> +       64-bit targets. Who the hell does that?
> +       https://reviews.llvm.org/rG674ec1eb16678b8addc02a4b0534ab383d22fa77
> +       It is required on arm64 (Apple Silicon): the trailing 
> _Unwind_Exception
> +       must be 16-byte aligned within the allocation, and only WITH this 
> member
> +       does unwindHeader land at a 16-byte boundary (offset 96, vs a 
> misaligned
> +       88 without it).  Verified empirically against this host's libc++abi.
> +       NOTE: Apple clang version != upstream LLVM version. */
> +    void *reserved;
> +    size_t referenceCount;
> +    ::std::type_info *exceptionType;
> +    void (*exceptionDestructor)(void *);
> +    ::std::unexpected_handler unexpectedHandler;
> +    ::std::terminate_handler terminateHandler;
> +    __cxa_exception *nextException;
> +    int handlerCount;
> +    int handlerSwitchValue;
> +    const unsigned char *actionRecord;
> +    const unsigned char *languageSpecificData;
> +    void *catchTemp;
> +    void *adjustedPtr;
> +    _Unwind_Exception unwindHeader;
> +};
> +
> +extern "C" void *__cxa_allocate_exception(
> +    std::size_t thrown_size ) throw();
> +extern "C" void __cxa_throw (
> +    void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) 
> __attribute__((noreturn));
> +
> +struct __cxa_eh_globals
> +{
> +    __cxa_exception *caughtExceptions;
> +    unsigned int uncaughtExceptions;
> +};
> +extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
> +
> +// -----
> +
> +// on OSX 64bit the class_type_info classes are specified
> +// in http://refspecs.linuxbase.org/cxxabi-1.86.html#rtti but
> +// these details are not generally available in a public header
> +// of most development environments. So we define them here.
> +// NOTE: 
> https://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf
> +class __class_type_info : public std::type_info
> +{
> +public:
> +        explicit __class_type_info( const char* pRttiName)
> +        : std::type_info( pRttiName)
> +        {}
> +};
> +
> +class __si_class_type_info : public __class_type_info
> +{
> +        const __class_type_info* mpBaseType;
> +public:
> +        explicit __si_class_type_info( const char* pRttiName, 
> __class_type_info* pBaseType)
> +        : __class_type_info( pRttiName), mpBaseType( pBaseType)
> +        {}
> +};
> +
> +//==================================================================================================
> +void raiseException(
> +    uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
> +//==================================================================================================
> +void fillUnoException(
> +    __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
> +}
> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx 
> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
> new file mode 100644
> index 0000000000..adaa3f2a5f
> --- /dev/null
> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
> @@ -0,0 +1,581 @@
> +/**************************************************************
> + *
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *
> + *************************************************************/
> +
> +
> +
> +// MARKER(update_precomp.py): autogen include statement, do not remove
> +#include "precompiled_bridges.hxx"
> +
> +#include <exception>
> +#include <typeinfo>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "rtl/alloc.h"
> +#include "rtl/ustrbuf.hxx"
> +
> +#include <com/sun/star/uno/genfunc.hxx>
> +#include "com/sun/star/uno/RuntimeException.hpp"
> +#include <uno/data.h>
> +
> +#include <bridges/cpp_uno/shared/bridge.hxx>
> +#include <bridges/cpp_uno/shared/types.hxx>
> +#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
> +#include "bridges/cpp_uno/shared/vtables.hxx"
> +
> +#include "abi.hxx"
> +#include "share.hxx"
> +
> +using namespace ::rtl;
> +using namespace ::com::sun::star::uno;
> +
> +//==================================================================================================
> +
> +// The AArch64 outgoing-call trampoline, implemented in call.s.  It loads the
> +// argument registers from the caller-prepared arrays, copies overflow args 
> to
> +// the outgoing stack, performs the indirect call, and returns x0/x1 and 
> d0..d3.
> +extern "C" void callVirtualFunction(
> +    sal_uInt64 pFunction, sal_uInt64 pIndirectRet,
> +    sal_uInt64 *pGPR, double *pFPR,
> +    sal_uInt64 *pStack, sal_uInt32 nStackWords,
> +    sal_uInt64 *pGPRReturn, double *pFPRReturn );
> +
> +static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
> +                              void * pRegisterReturn, 
> typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
> +                              void * pIndirectReturn,
> +                              sal_uInt64 *pStack, sal_uInt32 nStack,
> +                              sal_uInt64 *pGPR, sal_uInt32 nGPR,
> +                              double *pFPR, sal_uInt32 nFPR) 
> __attribute__((noinline));
> +
> +static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
> +                              void * pRegisterReturn, 
> typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
> +                              void * pIndirectReturn,
> +                              sal_uInt64 *pStack, sal_uInt32 nStack,
> +                              sal_uInt64 *pGPR, sal_uInt32 nGPR,
> +                              double *pFPR, sal_uInt32 nFPR)
> +{
> +#if OSL_DEBUG_LEVEL > 1
> +    // Let's figure out what is really going on here
> +    {
> +        fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
> +        for ( unsigned int i = 0; i < nGPR; ++i )
> +            fprintf( stderr, "0x%lx, ", pGPR[i] );
> +        fprintf( stderr, "\nFPR's (%d): ", nFPR );
> +        for ( unsigned int i = 0; i < nFPR; ++i )
> +            fprintf( stderr, "%f, ", pFPR[i] );
> +        fprintf( stderr, "\nStack (%d): ", nStack );
> +        for ( unsigned int i = 0; i < nStack; ++i )
> +            fprintf( stderr, "0x%lx, ", pStack[i] );
> +        fprintf( stderr, "\n" );
> +    }
> +#endif
> +
> +    // The call instruction within callVirtualFunction may throw exceptions. 
>  So
> +    // that the compiler handles this correctly, it is important that (a)
> +    // callVirtualMethod might call dummy_can_throw_anything (although this 
> never
> +    // happens at runtime), which in turn can throw exceptions, and (b)
> +    // callVirtualMethod is not inlined at its call site (so that any 
> exceptions
> +    // thrown across the call are caught):
> +    if ( !pThis )
> +        CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // 
> address something
> +
> +    // Should not happen, but...
> +    if ( nFPR > aarch64::MAX_FPR_REGS )
> +        nFPR = aarch64::MAX_FPR_REGS;
> +    if ( nGPR > aarch64::MAX_GPR_REGS )
> +        nGPR = aarch64::MAX_GPR_REGS;
> +
> +    // Get pointer to the C++ virtual method from the vtable.
> +    sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
> +    pMethod += 8 * nVtableIndex;
> +    pMethod = *((sal_uInt64 *)pMethod);
> +
> +    // Return register save areas: x0,x1 and d0..d3 (HFA up to 4 elements).
> +    sal_uInt64 gpReturn[2] = { 0, 0 };
> +    double fpReturn[4] = { 0, 0, 0, 0 };
> +
> +    // Ensure the GPR/FPR arrays are the full register width even if fewer 
> were
> +    // filled (the trampoline always loads all 8 of each).
> +    sal_uInt64 gpr[aarch64::MAX_GPR_REGS];
> +    double fpr[aarch64::MAX_FPR_REGS];
> +    for ( sal_uInt32 i = 0; i < aarch64::MAX_GPR_REGS; ++i )
> +        gpr[i] = ( i < nGPR ) ? pGPR[i] : 0;
> +    for ( sal_uInt32 i = 0; i < aarch64::MAX_FPR_REGS; ++i )
> +        fpr[i] = ( i < nFPR ) ? pFPR[i] : 0;
> +
> +    callVirtualFunction(
> +        pMethod,
> +        reinterpret_cast<sal_uInt64>( pIndirectReturn ), // x8, 0 if none
> +        gpr, fpr,
> +        pStack, nStack,
> +        gpReturn, fpReturn );
> +
> +    switch (pReturnTypeRef->eTypeClass)
> +    {
> +    case typelib_TypeClass_HYPER:
> +    case typelib_TypeClass_UNSIGNED_HYPER:
> +        *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = gpReturn[0];
> +        break;
> +    case typelib_TypeClass_LONG:
> +    case typelib_TypeClass_UNSIGNED_LONG:
> +    case typelib_TypeClass_ENUM:
> +        *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = 
> *reinterpret_cast<sal_uInt32*>( &gpReturn[0] );
> +        break;
> +    case typelib_TypeClass_CHAR:
> +    case typelib_TypeClass_SHORT:
> +    case typelib_TypeClass_UNSIGNED_SHORT:
> +        *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = 
> *reinterpret_cast<sal_uInt16*>( &gpReturn[0] );
> +        break;
> +    case typelib_TypeClass_BOOLEAN:
> +    case typelib_TypeClass_BYTE:
> +        *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = 
> *reinterpret_cast<sal_uInt8*>( &gpReturn[0] );
> +        break;
> +    case typelib_TypeClass_FLOAT:
> +    case typelib_TypeClass_DOUBLE:
> +        *reinterpret_cast<double *>( pRegisterReturn ) = fpReturn[0];
> +        break;
> +    default:
> +        {
> +            sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
> +            if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
> +            {
> +                // Register-returned aggregate: an HFA arrives in d0..d3, a
> +                // non-HFA <= 16 bytes in x0,x1.  fill_struct picks the 
> right one.
> +                aarch64::fill_struct( pReturnTypeRef, &gpReturn[0], 
> &fpReturn[0], pRegisterReturn);
> +            }
> +            break;
> +        }
> +    }
> +}
> +
> +//==================================================================================================
> +
> +// Macros for easier insertion of values to registers or stack
> +// pSV - pointer to the source
> +// nr - order of the value [will be increased if stored to register]
> +// pFPR, pGPR - pointer to the registers
> +// pDS - pointer to the stack [will be increased if stored here]
> +
> +// The pFPR slot holds the value to be loaded into a v register; the 
> trampoline
> +// loads it with LDR d<n>, so float and double are stored the same way here.
> +#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
> +     if ( nr < aarch64::MAX_FPR_REGS ) \
> +             pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
> +     else \
> +             *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
> +
> +#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
> +     if ( nr < aarch64::MAX_GPR_REGS ) \
> +             pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
> +     else \
> +             *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
> +
> +#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
> +     if ( nr < aarch64::MAX_GPR_REGS ) \
> +             pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
> +     else \
> +             *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
> +
> +#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
> +     if ( nr < aarch64::MAX_GPR_REGS ) \
> +             pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
> +     else \
> +             *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
> +
> +#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
> +     if ( nr < aarch64::MAX_GPR_REGS ) \
> +             pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
> +     else \
> +             *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
> +
> +//==================================================================================================
> +
> +namespace {
> +
> +void appendCString(OUStringBuffer & buffer, char const * text) {
> +    if (text != 0) {
> +        buffer.append(
> +            OStringToOUString(OString(text), RTL_TEXTENCODING_ISO_8859_1));
> +            // use 8859-1 to avoid conversion failure
> +    }
> +}
> +
> +}
> +
> +static void cpp_call(
> +     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
> +     bridges::cpp_uno::shared::VtableSlot aVtableSlot,
> +     typelib_TypeDescriptionReference * pReturnTypeRef,
> +     sal_Int32 nParams, typelib_MethodParameter * pParams,
> +     void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
> +{
> +     // Maxium space for [complex ret ptr], values | ptr ...
> +     // (but will be used less - some of the values will be in pGPR and pFPR)
> +     sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * 
> sizeof(sal_uInt64) );
> +     sal_uInt64 *pStackStart = pStack;
> +
> +     sal_uInt64 pGPR[aarch64::MAX_GPR_REGS];
> +     sal_uInt32 nGPR = 0;
> +
> +     double pFPR[aarch64::MAX_FPR_REGS];
> +     sal_uInt32 nFPR = 0;
> +
> +     // Return
> +     typelib_TypeDescription * pReturnTypeDescr = 0;
> +     TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
> +     OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
> +
> +     void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 
> (see below)
> +
> +     // Indirect-result pointer. On AArch64 this is passed in the dedicated 
> x8
> +     // register, NOT as the first general-purpose argument (unlike x86-64 
> SysV).
> +     // So we do NOT insert it into pGPR here; it is threaded to the 
> trampoline
> +     // separately as pIndirectReturn.
> +     void * pIndirectReturn = 0;
> +
> +     bool bSimpleReturn = true;
> +     if ( pReturnTypeDescr )
> +     {
> +             if ( aarch64::return_in_hidden_param( pReturnTypeRef ) )
> +                     bSimpleReturn = false;
> +
> +             if ( bSimpleReturn )
> +                     pCppReturn = pUnoReturn; // direct way for simple types
> +             else
> +             {
> +                     // complex return via the x8 indirect-result buffer
> +                     pCppReturn = 
> bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
> +                                              __builtin_alloca( 
> pReturnTypeDescr->nSize ) : pUnoReturn;
> +                     pIndirectReturn = pCppReturn;
> +             }
> +     }
> +
> +     // Push "this" pointer
> +     void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() 
> ) + aVtableSlot.offset;
> +     INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
> +
> +     // Args
> +     void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
> +     // Indizes of values this have to be converted (interface conversion 
> cpp<=>uno)
> +     sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
> +     // Type descriptions for reconversions
> +     typelib_TypeDescription ** ppTempParamTypeDescr = 
> (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
> +
> +     sal_Int32 nTempIndizes = 0;
> +
> +     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
> +     {
> +             const typelib_MethodParameter & rParam = pParams[nPos];
> +             typelib_TypeDescription * pParamTypeDescr = 0;
> +             TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
> +
> +             if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
> pParamTypeDescr ))
> +             {
> +                     uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), 
> pUnoArgs[nPos], pParamTypeDescr,
> +                                                                     
> pThis->getBridge()->getUno2Cpp() );
> +
> +                     switch (pParamTypeDescr->eTypeClass)
> +                     {
> +                     case typelib_TypeClass_HYPER:
> +                     case typelib_TypeClass_UNSIGNED_HYPER:
> +                             INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, 
> pStack );
> +                             break;
> +                     case typelib_TypeClass_LONG:
> +                     case typelib_TypeClass_UNSIGNED_LONG:
> +                     case typelib_TypeClass_ENUM:
> +                             INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, 
> pStack );
> +                             break;
> +                     case typelib_TypeClass_SHORT:
> +                     case typelib_TypeClass_CHAR:
> +                     case typelib_TypeClass_UNSIGNED_SHORT:
> +                             INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, 
> pStack );
> +                             break;
> +                     case typelib_TypeClass_BOOLEAN:
> +                     case typelib_TypeClass_BYTE:
> +                             INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack 
> );
> +                             break;
> +                     case typelib_TypeClass_FLOAT:
> +                     case typelib_TypeClass_DOUBLE:
> +                             INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, 
> pFPR, pStack );
> +                             break;
> +                     default:
> +                             break;
> +                     }
> +
> +                     // no longer needed
> +                     TYPELIB_DANGER_RELEASE( pParamTypeDescr );
> +             }
> +             else // ptr to complex value | ref
> +             {
> +                     if (! rParam.bIn) // is pure out
> +                     {
> +                             // cpp out is constructed mem, uno out is not!
> +                             uno_constructData(
> +                                     pCppArgs[nPos] = alloca( 
> pParamTypeDescr->nSize ),
> +                                     pParamTypeDescr );
> +                             pTempIndizes[nTempIndizes] = nPos; // default 
> constructed for cpp call
> +                             // will be released at reconversion
> +                             ppTempParamTypeDescr[nTempIndizes++] = 
> pParamTypeDescr;
> +                     }
> +                     // is in/inout
> +                     else if 
> (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
> +                     {
> +                             uno_copyAndConvertData(
> +                                     pCppArgs[nPos] = alloca( 
> pParamTypeDescr->nSize ),
> +                                     pUnoArgs[nPos], pParamTypeDescr, 
> pThis->getBridge()->getUno2Cpp() );
> +
> +                             pTempIndizes[nTempIndizes] = nPos; // has to be 
> reconverted
> +                             // will be released at reconversion
> +                             ppTempParamTypeDescr[nTempIndizes++] = 
> pParamTypeDescr;
> +                     }
> +                     else // direct way
> +                     {
> +                             pCppArgs[nPos] = pUnoArgs[nPos];
> +                             // no longer needed
> +                             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
> +                     }
> +                     INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
> +             }
> +     }
> +
> +     try
> +     {
> +        try {
> +            callVirtualMethod(
> +                pAdjustedThisPtr, aVtableSlot.index,
> +                pCppReturn, pReturnTypeRef, bSimpleReturn,
> +                pIndirectReturn,
> +                pStackStart, ( pStack - pStackStart ),
> +                pGPR, nGPR,
> +                pFPR, nFPR );
> +        } catch (Exception &) {
> +            throw;
> +        } catch (std::exception & e) {
> +            OUStringBuffer buf;
> +            buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("C++ code threw "));
> +            appendCString(buf, typeid(e).name());
> +            buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(": "));
> +            appendCString(buf, e.what());
> +            throw RuntimeException(
> +                buf.makeStringAndClear(), Reference< XInterface >());
> +        } catch (...) {
> +            throw RuntimeException(
> +                OUString(
> +                    RTL_CONSTASCII_USTRINGPARAM(
> +                        "C++ code threw unknown exception")),
> +                Reference< XInterface >());
> +        }
> +
> +             // NO exception occurred...
> +             *ppUnoExc = 0;
> +
> +             // reconvert temporary params
> +             for ( ; nTempIndizes--; )
> +             {
> +                     sal_Int32 nIndex = pTempIndizes[nTempIndizes];
> +                     typelib_TypeDescription * pParamTypeDescr = 
> ppTempParamTypeDescr[nTempIndizes];
> +
> +                     if (pParams[nIndex].bIn)
> +                     {
> +                             if (pParams[nIndex].bOut) // inout
> +                             {
> +                                     uno_destructData( pUnoArgs[nIndex], 
> pParamTypeDescr, 0 ); // destroy uno value
> +                                     uno_copyAndConvertData( 
> pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
> +                                                                             
>         pThis->getBridge()->getCpp2Uno() );
> +                             }
> +                     }
> +                     else // pure out
> +                     {
> +                             uno_copyAndConvertData( pUnoArgs[nIndex], 
> pCppArgs[nIndex], pParamTypeDescr,
> +                                                                             
> pThis->getBridge()->getCpp2Uno() );
> +                     }
> +                     // destroy temp cpp param => cpp: every param was 
> constructed
> +                     uno_destructData( pCppArgs[nIndex], pParamTypeDescr, 
> cpp_release );
> +
> +                     TYPELIB_DANGER_RELEASE( pParamTypeDescr );
> +             }
> +             // return value
> +             if (pCppReturn && pUnoReturn != pCppReturn)
> +             {
> +                     uno_copyAndConvertData( pUnoReturn, pCppReturn, 
> pReturnTypeDescr,
> +                                                                     
> pThis->getBridge()->getCpp2Uno() );
> +                     uno_destructData( pCppReturn, pReturnTypeDescr, 
> cpp_release );
> +             }
> +     }
> +     catch (...)
> +     {
> +             // fill uno exception
> +             fillUnoException( 
> CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, 
> pThis->getBridge()->getCpp2Uno() );
> +
> +             // temporary params
> +             for ( ; nTempIndizes--; )
> +             {
> +                     sal_Int32 nIndex = pTempIndizes[nTempIndizes];
> +                     // destroy temp cpp param => cpp: every param was 
> constructed
> +                     uno_destructData( pCppArgs[nIndex], 
> ppTempParamTypeDescr[nTempIndizes], cpp_release );
> +                     TYPELIB_DANGER_RELEASE( 
> ppTempParamTypeDescr[nTempIndizes] );
> +             }
> +             // return type
> +             if (pReturnTypeDescr)
> +                     TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
> +     }
> +}
> +
> +//==================================================================================================
> +
> +namespace bridges { namespace cpp_uno { namespace shared {
> +
> +void unoInterfaceProxyDispatch(
> +     uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
> +     void * pReturn, void * pArgs[], uno_Any ** ppException )
> +{
> +     // is my surrogate
> +     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
> +             = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * 
> >(pUnoI);
> +#if OSL_DEBUG_LEVEL > 0
> +     typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
> +#endif
> +
> +     switch (pMemberDescr->eTypeClass)
> +     {
> +     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
> +     {
> +#if OSL_DEBUG_LEVEL > 0
> +             // determine vtable call index
> +             sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
> *)pMemberDescr)->nPosition;
> +             OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member 
> pos out of range!" );
> +#endif
> +             VtableSlot aVtableSlot(
> +                             getVtableSlot(
> +                                     reinterpret_cast<
> +                                     
> typelib_InterfaceAttributeTypeDescription const * >(
> +                                             pMemberDescr)));
> +
> +             if (pReturn)
> +             {
> +                     // dependent dispatch
> +                     cpp_call(
> +                             pThis, aVtableSlot,
> +                             ((typelib_InterfaceAttributeTypeDescription 
> *)pMemberDescr)->pAttributeTypeRef,
> +                             0, 0, // no params
> +                             pReturn, pArgs, ppException );
> +             }
> +             else
> +             {
> +                     // is SET
> +                     typelib_MethodParameter aParam;
> +                     aParam.pTypeRef =
> +                             ((typelib_InterfaceAttributeTypeDescription 
> *)pMemberDescr)->pAttributeTypeRef;
> +                     aParam.bIn              = sal_True;
> +                     aParam.bOut             = sal_False;
> +
> +                     typelib_TypeDescriptionReference * pReturnTypeRef = 0;
> +                     OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") 
> );
> +                     typelib_typedescriptionreference_new(
> +                             &pReturnTypeRef, typelib_TypeClass_VOID, 
> aVoidName.pData );
> +
> +                     // dependent dispatch
> +                     aVtableSlot.index += 1; // get, then set method
> +                     cpp_call(
> +                             pThis, aVtableSlot, // get, then set method
> +                             pReturnTypeRef,
> +                             1, &aParam,
> +                             pReturn, pArgs, ppException );
> +
> +                     typelib_typedescriptionreference_release( 
> pReturnTypeRef );
> +             }
> +
> +             break;
> +     }
> +     case typelib_TypeClass_INTERFACE_METHOD:
> +     {
> +#if OSL_DEBUG_LEVEL > 0
> +             // determine vtable call index
> +             sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
> *)pMemberDescr)->nPosition;
> +             OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member 
> pos out of range!" );
> +#endif
> +             VtableSlot aVtableSlot(
> +                             getVtableSlot(
> +                                     reinterpret_cast<
> +                                     typelib_InterfaceMethodTypeDescription 
> const * >(
> +                                             pMemberDescr)));
> +
> +             switch (aVtableSlot.index)
> +             {
> +                     // standard calls
> +             case 1: // acquire uno interface
> +                     (*pUnoI->acquire)( pUnoI );
> +                     *ppException = 0;
> +                     break;
> +             case 2: // release uno interface
> +                     (*pUnoI->release)( pUnoI );
> +                     *ppException = 0;
> +                     break;
> +             case 0: // queryInterface() opt
> +             {
> +                     typelib_TypeDescription * pTD = 0;
> +                     TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( 
> pArgs[0] )->getTypeLibType() );
> +                     if (pTD)
> +                     {
> +                uno_Interface * pInterface = 0;
> +                (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
> +                    pThis->getBridge()->getUnoEnv(),
> +                    (void **)&pInterface, pThis->oid.pData, 
> (typelib_InterfaceTypeDescription *)pTD );
> +
> +                if (pInterface)
> +                {
> +                    ::uno_any_construct(
> +                        reinterpret_cast< uno_Any * >( pReturn ),
> +                        &pInterface, pTD, 0 );
> +                    (*pInterface->release)( pInterface );
> +                    TYPELIB_DANGER_RELEASE( pTD );
> +                    *ppException = 0;
> +                    break;
> +                }
> +                TYPELIB_DANGER_RELEASE( pTD );
> +            }
> +             } // else perform queryInterface()
> +             default:
> +                     // dependent dispatch
> +                     cpp_call(
> +                             pThis, aVtableSlot,
> +                             ((typelib_InterfaceMethodTypeDescription 
> *)pMemberDescr)->pReturnTypeRef,
> +                             ((typelib_InterfaceMethodTypeDescription 
> *)pMemberDescr)->nParams,
> +                             ((typelib_InterfaceMethodTypeDescription 
> *)pMemberDescr)->pParams,
> +                             pReturn, pArgs, ppException );
> +             }
> +             break;
> +     }
> +     default:
> +     {
> +             ::com::sun::star::uno::RuntimeException aExc(
> +                     OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member 
> type description!") ),
> +                     ::com::sun::star::uno::Reference< 
> ::com::sun::star::uno::XInterface >() );
> +
> +             Type const & rExcType = ::getCppuType( &aExc );
> +             // binary identical null reference
> +             ::uno_type_any_construct( *ppException, &aExc, 
> rExcType.getTypeLibType(), 0 );
> +     }
> +     }
> +}
> +
> +} } }
> diff --git a/main/configure.ac b/main/configure.ac
> index 3f67e5b3fb..8731dc71f4 100644
> --- a/main/configure.ac
> +++ b/main/configure.ac
> @@ -922,8 +922,8 @@ AC_ARG_WITH(arm-target,
> AC_ARG_WITH(macosx-target,
> [  --macosx-target            The minimal macOS/OSX deployment and build 
> target
> 
> -                              Usage: --with-macosx-target=10.9
> -],with_macosx_target=$withval,with_macosx_target=10.9)
> +                              Usage: --with-macosx-target=11.0
> +],with_macosx_target=$withval,with_macosx_target=11.0)
> AC_ARG_WITH(macosx-sdk,
> [  --macosx-sdk            The macOS SDK to build against
> 
> @@ -1159,9 +1159,29 @@ case "$build_os" in
>               fi
>               # Don't use OSVERSION until we know no conflicts result from it
>               _darwin_version="`uname -r | $AWK -F . '{ print $1 }'`"
> -             # FIXME: Assumes 10.x, breaks w/ Big Sur
> -             _osx_version="10.`expr $_darwin_version - 4`"
> +             # Map the Darwin (XNU) major version to the macOS version.
> +             # Darwin 6..19  => macOS 10.(darwin-4)   (10.2 .. 10.15)
> +             # Darwin 20+    => macOS (darwin-9)       (11, 12, 13, ...)
> +             if test "$_darwin_version" -ge 20; then
> +                _osx_version="`expr $_darwin_version - 9`"
> +             else
> +                _osx_version="10.`expr $_darwin_version - 4`"
> +             fi
>               AC_MSG_NOTICE([Detected Darwin version: $_darwin_version 
> ($_osx_version)])
> +             # Detect the build CPU architecture. Apple Silicon (arm64) 
> reports
> +             # "arm64" from uname -m and maps to the aarch64 
> toolchain/bridge.
> +             _darwin_cpu="`uname -m`"
> +             case "$_darwin_cpu" in
> +                arm64|aarch64)
> +                   AC_MSG_NOTICE([Detected Apple Silicon (arm64) build host])
> +                   ;;
> +                x86_64|i*86)
> +                   AC_MSG_NOTICE([Detected Intel (x86_64) build host])
> +                   ;;
> +                *)
> +                   AC_MSG_ERROR([Unsupported macOS CPU architecture: 
> $_darwin_cpu])
> +                   ;;
> +             esac
>               ;;
>       os2*)
>               test_x=no
> @@ -3907,10 +3927,20 @@ if test  "$_os" = "Darwin"; then
>    sdk_target=$with_macosx_target
>    AC_MSG_CHECKING([checking SDK compatibility with OSX $sdk_target])
> 
> +   sdk_major=`echo $sdk_target | cut -d"." -f1`
>    sdk_minor=`echo $sdk_target | cut -d"." -f2`
> +   test -z "$sdk_minor" && sdk_minor=0
> +
> +   dnl Minimum supported macOS is 11.0 (Big Sur). Pre-11 targets are only
> +   dnl accepted down to the old 10.9 floor for legacy Intel builds.
> +   if test "$_darwin_cpu" = "arm64" -o "$_darwin_cpu" = "aarch64"; then
> +      if test "$sdk_major" -lt "11"; then
> +         AC_MSG_ERROR([Apple Silicon (arm64) requires 
> --with-macosx-target=11.0 or later])
> +      fi
> +   fi
> 
> -   if test "$sdk_minor" -lt "9"; then
> -      AC_MSG_ERROR([SDK version < 10.9 is not longer supported])
> +   if test "$sdk_major" -lt "10" -o \( "$sdk_major" -eq "10" -a "$sdk_minor" 
> -lt "9" \); then
> +      AC_MSG_ERROR([macOS deployment target < 10.9 is no longer supported])
>    else
>       MACOSX_DEPLOYMENT_TARGET=$sdk_target
>       sdk_path=$with_macosx_sdk
> diff --git a/main/icu/icu4c-4_2_1-src.patch b/main/icu/icu4c-4_2_1-src.patch
> index 77fc719528..572572a3ea 100644
> --- a/main/icu/icu4c-4_2_1-src.patch
> +++ b/main/icu/icu4c-4_2_1-src.patch
> @@ -212,7 +212,7 @@ diff -ru misc/icu/source/tools/genuca/genuca.cpp 
> misc/build/icu/source/tools/gen
> +     echo "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}"
>       case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in  #(
> -       *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;;
> -+      *-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=no;;
> ++      *-arch*i386*|*-arch*x86_64*|*-arch*arm64*|*-arch*aarch64*) 
> ac_cv_c_bigendian=no;;
> +       *-arch*ppc*) ac_cv_c_bigendian=yes;;
>       esac
>  else
> diff --git a/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx 
> b/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
> index daec7fe94a..fbeb1ef201 100644
> --- a/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
> +++ b/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
> @@ -102,6 +102,12 @@ struct JavaSearchPathEntry {
> struct JavaSearchPathEntry g_arSearchPaths[] = {
> #ifdef MACOSX
>     { 0, "" },
> +    // Modern macOS JDK location (Oracle/Temurin/etc., both arm64 and x86_64
> +    // install here). Each subdirectory is a JDK whose home is Contents/Home,
> +    // so scan the immediate contents. A JDK of the wrong architecture (e.g. 
> a
> +    // Rosetta x86_64 JDK on Apple Silicon) is harmlessly skipped when its
> +    // libjvm.dylib fails to load into the native-arch process.
> +    { 1, "Library/Java/JavaVirtualMachines/" },
>     { 0, "Library/Internet 
> Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin" },
>     { 0, "System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/" },
> #else
> @@ -1245,6 +1251,14 @@ void 
> createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
>                                    OUSTR(" is a Java. \n"));
> 
>                         getJREInfoByPath(aStatus.getFileURL(),vecInfos);
> +#ifdef MACOSX
> +                        // On macOS a JDK bundle's home is at 
> <bundle>/Contents/Home
> +                        // (e.g. under 
> /Library/Java/JavaVirtualMachines/<jdk>/),
> +                        // not the bundle directory itself, so also probe 
> there.
> +                        getJREInfoByPath(
> +                            aStatus.getFileURL() +
> +                            OUSTR("/Contents/Home"), vecInfos);
> +#endif
>                     }
> 
>                     JFW_ENSURE(errNext == File::E_None || errNext == 
> File::E_NOENT,
> diff --git a/main/openssl/makefile.mk b/main/openssl/makefile.mk
> index cecba9e26e..a5662eabea 100644
> --- a/main/openssl/makefile.mk
> +++ b/main/openssl/makefile.mk
> @@ -107,8 +107,12 @@ UNAME=$(shell uname)
> .ENDIF
> 
> .IF "$(OS)" == "MACOSX"
> +.IF "$(CPUNAME)" == "AARCH64"
> +     CONFIGURE_ACTION=Configure darwin64-arm64-cc no-dso no-shared $(NO_ASM)
> +.ELSE
>       CONFIGURE_ACTION=Configure darwin64-x86_64-cc no-dso no-shared $(NO_ASM)
> .ENDIF
> +.ENDIF
> 
> .IF "$(OS)" == "WNT"
> 
> diff --git a/main/python/pyversion.mk b/main/python/pyversion.mk
> index 353925e92e..95f7b299da 100644
> --- a/main/python/pyversion.mk
> +++ b/main/python/pyversion.mk
> @@ -20,8 +20,8 @@
> # *************************************************************
> # when you want to change the python version, you must update the d.lst
> # in the python project accordingly !!!
> -PYMAJOR=2
> -PYMINOR=7
> +PYMAJOR=3
> +PYMINOR=10
> PYMICRO=18
> PYVERSION=$(PYMAJOR).$(PYMINOR).$(PYMICRO)
> 
> diff --git a/main/python/pyversion_dmake.mk b/main/python/pyversion_dmake.mk
> index 37aa099277..b8252a9767 100644
> --- a/main/python/pyversion_dmake.mk
> +++ b/main/python/pyversion_dmake.mk
> @@ -20,8 +20,8 @@
> # *************************************************************
> # when you want to change the python version, you must update the d.lst
> # in the python project accordingly !!!
> -PYMAJOR=2
> -PYMINOR=7
> +PYMAJOR=3
> +PYMINOR=10
> PYMICRO=18
> PYVERSION=$(PYMAJOR).$(PYMINOR).$(PYMICRO)
> 
> diff --git a/main/pyuno/source/loader/pythonloader.py 
> b/main/pyuno/source/loader/pythonloader.py
> index 46e051da98..34ff1c532b 100644
> --- a/main/pyuno/source/loader/pythonloader.py
> +++ b/main/pyuno/source/loader/pythonloader.py
> @@ -21,7 +21,7 @@
> import uno
> import unohelper
> import sys
> -import imp
> +import types
> import os
> from com.sun.star.uno import Exception,RuntimeException
> from com.sun.star.loader import XImplementationLoader
> @@ -84,14 +84,14 @@ class Loader( XImplementationLoader, XServiceInfo, 
> unohelper.Base ):
>                 # did we load the module already ?
>                 mod = g_loadedComponents.get( url )
>                 if not mod:
> -                    mod = imp.new_module("uno_component")
> +                    mod = types.ModuleType("uno_component")
> 
>                     # check for pythonpath.zip beside .py files
>                     checkForPythonPathBesideComponent( url[0:url.rfind('/')] )
> 
>                     # read the file
>                     filename = unohelper.fileUrlToSystemPath( url )
> -                    fileHandle = file( filename )
> +                    fileHandle = open( filename )
>                     src = fileHandle.read().replace("\r","")
>                     if not src.endswith( "\n" ):
>                         src = src + "\n"
> diff --git a/main/sal/osl/unx/interlck.c b/main/sal/osl/unx/interlck.c
> index cfcea0fbc0..d24db7b341 100644
> --- a/main/sal/osl/unx/interlck.c
> +++ b/main/sal/osl/unx/interlck.c
> @@ -178,6 +178,29 @@ oslInterlockedCount SAL_CALL 
> osl_decrementInterlockedCount(oslInterlockedCount*
> #endif
> }
> 
> +#elif (defined(__GNUC__) || defined(__clang__)) && defined ( AARCH64 )
> +/* AArch64 (ARM 64-bit, e.g. Apple Silicon). Use the compiler's atomic
> +   built-ins, which clang/gcc lower to the AArch64 
> load-exclusive/store-exclusive
> +   (ldaxr/stlxr) sequence, or to LSE atomics (ldadd) on ARMv8.1+. This 
> avoids the
> +   global-mutex fallback below. __sync_*_and_fetch are full-barrier and 
> return
> +   the new value, matching the required semantics. */
> +
> +/*****************************************************************************/
> +/* osl_incrementInterlockedCount */
> +/*****************************************************************************/
> +oslInterlockedCount SAL_CALL 
> osl_incrementInterlockedCount(oslInterlockedCount* pCount)
> +{
> +    return __sync_add_and_fetch( pCount, 1 );
> +}
> +
> +/*****************************************************************************/
> +/* osl_decrementInterlockedCount */
> +/*****************************************************************************/
> +oslInterlockedCount SAL_CALL 
> osl_decrementInterlockedCount(oslInterlockedCount* pCount)
> +{
> +    return __sync_sub_and_fetch( pCount, 1 );
> +}
> +
> #else
> /* use only if nothing else works, expensive due to single mutex for all 
> reference counts */
> 
> diff --git a/main/sal/rtl/source/macro.hxx b/main/sal/rtl/source/macro.hxx
> index 10948868f3..4aee4358aa 100644
> --- a/main/sal/rtl/source/macro.hxx
> +++ b/main/sal/rtl/source/macro.hxx
> @@ -77,6 +77,8 @@ this is inserted for the case that the preprocessor ignores 
> error
> #    else
> #        define THIS_ARCH "MIPS_EL"
> #    endif
> +#elif defined AARCH64
> +#    define THIS_ARCH "AARCH64"
> #elif defined ARM
> #    ifdef __ARM_EABI__
> #        define THIS_ARCH "ARM_EABI"
> diff --git a/main/scripting/source/pyprov/mailmerge.py 
> b/main/scripting/source/pyprov/mailmerge.py
> index 4a4c430c28..c11ddd8c7a 100644
> --- a/main/scripting/source/pyprov/mailmerge.py
> +++ b/main/scripting/source/pyprov/mailmerge.py
> @@ -54,13 +54,13 @@ from com.sun.star.lang import IllegalArgumentException
> from com.sun.star.lang import EventObject
> from com.sun.star.mail import SendMailMessageFailedException
> 
> -from email.MIMEBase import MIMEBase
> -from email.Message import Message
> -from email import Encoders
> -from email.Header import Header
> -from email.MIMEMultipart import MIMEMultipart
> -from email.Utils import formatdate
> -from email.Utils import parseaddr
> +from email.mime.base import MIMEBase
> +from email.message import Message
> +from email import encoders
> +from email.header import Header
> +from email.mime.multipart import MIMEMultipart
> +from email.utils import formatdate
> +from email.utils import parseaddr
> from socket import _GLOBAL_DEFAULT_TIMEOUT
> 
> import sys, smtplib, imaplib, poplib
> @@ -245,7 +245,7 @@ class PyMailSMTPService(unohelper.Base, XSmtpService):
>             msgattachment = MIMEBase(maintype, subtype)
>             data = content.getTransferData(flavor)
>             msgattachment.set_payload(data)
> -            Encoders.encode_base64(msgattachment)
> +            encoders.encode_base64(msgattachment)
>             fname = attachment.ReadableName
>             try:
>                 fname.encode('ascii')
> diff --git a/main/scripting/source/pyprov/pythonscript.py 
> b/main/scripting/source/pyprov/pythonscript.py
> index 4e7fc4667e..03f52b897a 100644
> --- a/main/scripting/source/pyprov/pythonscript.py
> +++ b/main/scripting/source/pyprov/pythonscript.py
> @@ -24,7 +24,7 @@ import uno
> import unohelper
> import sys
> import os
> -import imp
> +import types
> import time
> import ast
> 
> @@ -356,7 +356,7 @@ class ScriptContext(unohelper.Base):
> #        code = readTextFromStream( sfa.openFileRead( url ) )
> 
>         # execute the module
> -#        entry = ModuleEntry( lastRead, 
> imp.new_module("ooo_script_framework") )
> +#        entry = ModuleEntry( lastRead, 
> types.ModuleType("ooo_script_framework") )
> #        entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext
> #        entry.module.__file__ = url
> #        exec code in entry.module.__dict__
> @@ -489,7 +489,7 @@ class ProviderContext:
>             src = ensureSourceState( src )
> 
>             # execute the module
> -            entry = ModuleEntry( lastRead, 
> imp.new_module("ooo_script_framework") )
> +            entry = ModuleEntry( lastRead, 
> types.ModuleType("ooo_script_framework") )
>             entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = 
> self.scriptContext
> 
>             code = None
> @@ -666,7 +666,7 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode, 
> XPropertySet, XInvocation,
>             if event.ActionCommand == "Run":
>                 code = self.editor.getControl("EditorTextField").getText()
>                 code = ensureSourceState( code )
> -                mod = imp.new_module("ooo_script_framework")
> +                mod = types.ModuleType("ooo_script_framework")
>                 mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = 
> self.provCtx.scriptContext
>                 exec(code, mod.__dict__)
>                 values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
> @@ -827,7 +827,7 @@ class FileBrowseNode( unohelper.Base, XBrowseNode, 
> XPropertySet, XInvocation, XA
>             if event.ActionCommand == "Run":
>                 code = self.editor.getControl("EditorTextField").getText()
>                 code = ensureSourceState( code )
> -                mod = imp.new_module("ooo_script_framework")
> +                mod = types.ModuleType("ooo_script_framework")
>                 mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = 
> self.provCtx.scriptContext
>                 exec(code, mod.__dict__)
>                 values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
> diff --git a/main/set_soenv.in b/main/set_soenv.in
> index 189b6afdfe..6812905f8e 100644
> --- a/main/set_soenv.in
> +++ b/main/set_soenv.in
> @@ -807,6 +807,14 @@ elsif ( $platform =~ m/darwin/ )
>           $CPUNAME        = "X86_64";
>           $OUTPATH        = "unxmaccx";
>       }
> +      elsif ($platform =~ m/^(aarch64|arm64)/)
> +      {
> +          print "Setting values for MacOSX/Darwin on aarch64 (Apple 
> Silicon)... ";
> +          $outfile        = "MacOSXAARCH64Env.Set";
> +          $CPU            = "R";
> +          $CPUNAME        = "AARCH64";
> +          $OUTPATH        = "unxmaccr";
> +      }
>       else
>       {
>         print "\nset_soenv: Unknown MacOSX/Darwin platform: $platform\n";
> diff --git a/main/setup_native/source/mac/Info.plist.langpack 
> b/main/setup_native/source/mac/Info.plist.langpack
> index 0e12cc1c19..80ad91f30b 100644
> --- a/main/setup_native/source/mac/Info.plist.langpack
> +++ b/main/setup_native/source/mac/Info.plist.langpack
> @@ -23,7 +23,7 @@
> <plist version="1.0">
> <dict>
>       <key>LSMinimumSystemVersion</key>
> -     <string>10.7.0</string>
> +     <string>11.0</string>
>       <key>CFBundleDevelopmentRegion</key>
>       <string>English</string>
>       <!-- UTI declarations for OS X >= 10.4  -->
> diff --git a/main/solenv/bin/modules/installer/download.pm 
> b/main/solenv/bin/modules/installer/download.pm
> index 6605bbdbc6..6ad1570ab0 100644
> --- a/main/solenv/bin/modules/installer/download.pm
> +++ b/main/solenv/bin/modules/installer/download.pm
> @@ -607,6 +607,10 @@ sub get_download_architecture
>       {
>               $arch = "x86-64";
>       }
> +     elsif ( $installer::globals::compiler =~ /^unxmaccr/ )
> +     {
> +             $arch = "aarch64";
> +     }
>       elsif ( $installer::globals::issolarissparcbuild )
>       {
>               $arch = "Sparc";
> diff --git a/main/solenv/bin/modules/installer/worker.pm 
> b/main/solenv/bin/modules/installer/worker.pm
> index 0d387a3e33..ef22a34e2a 100644
> --- a/main/solenv/bin/modules/installer/worker.pm
> +++ b/main/solenv/bin/modules/installer/worker.pm
> @@ -2280,6 +2280,10 @@ sub get_platform_name
>       {
>               $platformname = "MacOSXX86-64";
>       }
> +     elsif ( $installer::globals::compiler =~ /^unxmaccr/ )
> +     {
> +             $platformname = "MacOSXAArch64";
> +     }
>       elsif ( $installer::globals::compiler =~ /^unxmacxp/ )
>       {
>               $platformname = "MacOSXPowerPC";
> diff --git a/main/solenv/bin/modules/osarch.pm 
> b/main/solenv/bin/modules/osarch.pm
> index 4ded37ed15..1093b81a27 100644
> --- a/main/solenv/bin/modules/osarch.pm
> +++ b/main/solenv/bin/modules/osarch.pm
> @@ -102,7 +102,9 @@ chop( $m_str, $s_str );
>                          "IP22",          "mips",         # voyager
>                          "IP32",          "mips",         # giotto
>                          "Power Macintosh",                   "ppc",          
>         # NetBSD/arm32
> -                        "arm32",                     "arm32"                 
> # NetBSD/arm32
> +                        "arm32",                     "arm32",                
> # NetBSD/arm32
> +                        "arm64",                     "aarch64",              
> # macOS Apple Silicon (uname -m)
> +                        "aarch64",           "aarch64"               # Linux 
> aarch64
>                          );
> 
> %archDefTable=("sun4c",                       "-DSPARC -DSUN -DSUN4", # hawai
> @@ -130,7 +132,9 @@ chop( $m_str, $s_str );
>                          "IP22",          "-DMIPS",                   # 
> voyager
>                          "IP32",          "-DMIPS",                   # giotto
>                          "Power Macintosh",           "-DPPC",                
> # NetBSD/arm32
> -                        "arm32",                     "-DARM32"               
> # NetBSD/arm32
> +                        "arm32",                     "-DARM32",              
> # NetBSD/arm32
> +                        "arm64",                     "-DAARCH64",            
> # macOS Apple Silicon (uname -m)
> +                        "aarch64",           "-DAARCH64"             # Linux 
> aarch64
>                          );
> 
> %archDosTable=("sun4c",                       "s",            # hawai
> @@ -158,7 +162,9 @@ chop( $m_str, $s_str );
>                          "IP22",          "m",                # voyager
>                          "IP32",          "m",                # giotto
>                          "Power Macintosh",                   "p",            
>         # NetBSD/arm32
> -                        "arm32",                     "a"                     
> # NetBSD/arm32
> +                        "arm32",                     "a",                    
> # NetBSD/arm32
> +                        "arm64",                     "r",                    
> # macOS Apple Silicon (uname -m)
> +                        "aarch64",           "r"                     # Linux 
> aarch64
>                          );
> 
> $main::solarDef               = $osDefTable{ $s_str }.' '.$archDefTable{ 
> $m_str };
> diff --git a/main/solenv/bin/update_module_ignore_lists.pl 
> b/main/solenv/bin/update_module_ignore_lists.pl
> index 3a827d743f..f7eecef05d 100644
> --- a/main/solenv/bin/update_module_ignore_lists.pl
> +++ b/main/solenv/bin/update_module_ignore_lists.pl
> @@ -47,6 +47,7 @@ my @platforms = (
>         "unxmacxp",
>         "unxmacci",
>         "unxmaccx",
> +        "unxmaccr",
>         "unxubit8",
>         "unxaixp",
>         "unxbsda",
> diff --git a/main/solenv/gbuild/platform/macosx.mk 
> b/main/solenv/gbuild/platform/macosx.mk
> index 3b5d65805a..b9501be453 100644
> --- a/main/solenv/gbuild/platform/macosx.mk
> +++ b/main/solenv/gbuild/platform/macosx.mk
> @@ -64,6 +64,8 @@ ifeq ($(CPUNAME),POWERPC)
> gb_CPUDEFS += -DPOWERPC -DPPC
> else ifeq ($(CPUNAME),INTEL)
> gb_CPUDEFS += -DX86
> +else ifeq ($(CPUNAME),AARCH64)
> +gb_CPUDEFS += -DARM64
> endif
> 
> ifeq ($(strip $(SYSBASE)),)
> diff --git a/main/solenv/inc/unx.mk b/main/solenv/inc/unx.mk
> index f956e43a82..b5b4731cd6 100644
> --- a/main/solenv/inc/unx.mk
> +++ b/main/solenv/inc/unx.mk
> @@ -160,6 +160,10 @@
> .INCLUDE : unxmaccx.mk
> .ENDIF
> 
> +.IF "$(COM)$(OS)$(CPU)" == "CLANGMACOSXR"
> +.INCLUDE : unxmaccr.mk
> +.ENDIF
> +
> .IF "$(OS)$(CPU)" == "LINUXM"
> .INCLUDE : unxlngmips.mk
> .ENDIF
> diff --git a/main/solenv/inc/unxmaccr.mk b/main/solenv/inc/unxmaccr.mk
> new file mode 100644
> index 0000000000..0fdf36cc2d
> --- /dev/null
> +++ b/main/solenv/inc/unxmaccr.mk
> @@ -0,0 +1,42 @@
> +#**************************************************************
> +#
> +#  Licensed to the Apache Software Foundation (ASF) under one
> +#  or more contributor license agreements.  See the NOTICE file
> +#  distributed with this work for additional information
> +#  regarding copyright ownership.  The ASF licenses this file
> +#  to you under the Apache License, Version 2.0 (the
> +#  "License"); you may not use this file except in compliance
> +#  with the License.  You may obtain a copy of the License at
> +#
> +#    http://www.apache.org/licenses/LICENSE-2.0
> +#
> +#  Unless required by applicable law or agreed to in writing,
> +#  software distributed under the License is distributed on an
> +#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> +#  KIND, either express or implied.  See the License for the
> +#  specific language governing permissions and limitations
> +#  under the License.
> +#
> +#**************************************************************
> +
> +# Mac OSX aarch64 (Apple Silicon) specific defines
> +
> +PROCESSOR_DEFINES=-DAARCH64
> +BUILD64=1
> +
> +DLLPOSTFIX=
> +
> +# Build explicitly for arm64. Use conditional assignment (*=) so the value 
> can
> +# still be overridden by exporting ARCH_FLAGS in the environment. unxmacc.mk
> +# also declares ARCH_FLAGS*= (empty), which becomes a no-op once set here.
> +ARCH_FLAGS*=-arch arm64
> +
> +# flags to enable build with symbols; required by crashdump feature
> +.IF "$(ENABLE_SYMBOLS)"=="SMALL"
> +CFLAGSENABLESYMBOLS=-g1
> +.ELSE
> +CFLAGSENABLESYMBOLS=-g
> +.ENDIF
> +
> +# Include generic Mac OS X makefile
> +.INCLUDE : unxmacc.mk
> diff --git a/main/source_soenv.sh b/main/source_soenv.sh
> index 9d522c359f..ce87621c36 100644
> --- a/main/source_soenv.sh
> +++ b/main/source_soenv.sh
> @@ -108,6 +108,9 @@ else
>         i[3456]86-*-darwin*|x86_64-*-darwin*)
>             . ./MacOSXX64Env.Set.sh
>         ;;
> +        aarch64-*-darwin*|arm64-*-darwin*)
> +            . ./MacOSXAARCH64Env.Set.sh
> +        ;;
>         powerpc-*-darwin*)
>             . ./MacOSXPPCEnv.Set.sh
>         ;;
> diff --git a/main/sysui/desktop/macosx/Info.plist 
> b/main/sysui/desktop/macosx/Info.plist
> index d26d4251fe..9ffda6b8fa 100644
> --- a/main/sysui/desktop/macosx/Info.plist
> +++ b/main/sysui/desktop/macosx/Info.plist
> @@ -23,7 +23,7 @@
> <plist version="1.0">
> <dict>
>       <key>LSMinimumSystemVersion</key>
> -     <string>10.7.0</string>
> +     <string>11.0</string>
>       <key>CFBundleDevelopmentRegion</key>
>       <string>English</string>
>       <!-- UTI declarations for OS X >= 10.4  -->
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to