This is an automated email from the ASF dual-hosted git repository. jim pushed a commit to branch AOO419 in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/AOO419 by this push: new 67a794b Updates to macOS UNO implementation pulled from AOO42X but w/o unsupported functionality. new b36e2b2 Merge branch 'AOO419' of https://gitbox.apache.org/repos/asf/openoffice into AOO419 67a794b is described below commit 67a794bc92a1e8ffd80bf2fdc9bf74ed09144659 Author: Jim Jagielski <jim...@gmail.com> AuthorDate: Sat Dec 26 15:54:46 2020 -0500 Updates to macOS UNO implementation pulled from AOO42X but w/o unsupported functionality. --- .../source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx | 137 ++++++++++----------- .../source/cpp_uno/s5abi_macosx_x86-64/except.cxx | 36 ++++-- .../source/cpp_uno/s5abi_macosx_x86-64/makefile.mk | 1 - .../source/cpp_uno/s5abi_macosx_x86-64/share.hxx | 21 ++-- .../source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx | 4 +- 5 files changed, 103 insertions(+), 96 deletions(-) diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx index f65ecea..d7fd5b2 100644 --- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx +++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx @@ -102,12 +102,12 @@ static typelib_TypeClass cpp2uno_call( // stack space // parameters - void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); + 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 = (sal_Int32 *)(pUnoArgs + (2 * nParams)); + sal_Int32 * pTempIndizes = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 * nParams)); // type descriptions for reconversions - typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams)); + typelib_TypeDescription ** ppTempParamTypeDescr = reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams)); sal_Int32 nTempIndizes = 0; @@ -117,10 +117,7 @@ static typelib_TypeClass cpp2uno_call( int nUsedGPR = 0; int nUsedSSE = 0; -#if OSL_DEBUG_LEVEL > 0 - bool bFitsRegisters = -#endif - x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE ); + bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE ); if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value { // Simple types must fit exactly one register on x86_64 @@ -194,7 +191,7 @@ static typelib_TypeClass cpp2uno_call( // invoke uno dispatch call (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); - // in case an exception occured... + // in case an exception occurred... if ( pUnoExc ) { // destruct temporary in/inout params @@ -213,7 +210,7 @@ static typelib_TypeClass cpp2uno_call( // is here for dummy return typelib_TypeClass_VOID; } - else // else no exception occured... + else // else no exception occurred... { // temporary params for ( ; nTempIndizes--; ) @@ -244,7 +241,7 @@ static typelib_TypeClass cpp2uno_call( uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); } // complex return ptr is set to return reg - *(void **)pRegisterReturn = pCppReturn; + *reinterpret_cast<void **>(pRegisterReturn) = pCppReturn; } if ( pReturnTypeDescr ) { @@ -349,7 +346,7 @@ extern "C" typelib_TypeClass cpp_vtable_call( XInterface * pInterface = 0; (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface) ( pCppI->getBridge()->getCppEnv(), - (void **)&pInterface, + reinterpret_cast<void **>(&pInterface), pCppI->getOid().pData, reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) ); @@ -395,70 +392,62 @@ extern "C" typelib_TypeClass cpp_vtable_call( } //================================================================================================== - -// privateSnippetExecutor() is only called by the trampolines created by codeSnippet() -// -// it saves all the registers used for parameter passing in the x86_64 ABI. -// Then it uses them to provide the parameters to its cpp_vtable_call() and -// to handle the return value. -// -// This method makes assumptions about the stack layout of the stack frame above! - extern "C" void privateSnippetExecutor( void ) { - asm volatile ( - "subq $160, %%rsp\n\t" - "movq %%r10, -152(%%rbp)\n\t" // Save (nVtableOffset << 32) + nFunctionIndex - - "movq %%rdi, -112(%%rbp)\n\t" // Save GP registers - "movq %%rsi, -104(%%rbp)\n\t" - "movq %%rdx, -96(%%rbp)\n\t" - "movq %%rcx, -88(%%rbp)\n\t" - "movq %%r8 , -80(%%rbp)\n\t" - "movq %%r9 , -72(%%rbp)\n\t" - - "movsd %%xmm0, -64(%%rbp)\n\t" // Save FP registers - "movsd %%xmm1, -56(%%rbp)\n\t" - "movsd %%xmm2, -48(%%rbp)\n\t" - "movsd %%xmm3, -40(%%rbp)\n\t" - "movsd %%xmm4, -32(%%rbp)\n\t" - "movsd %%xmm5, -24(%%rbp)\n\t" - "movsd %%xmm6, -16(%%rbp)\n\t" - "movsd %%xmm7, -8(%%rbp)\n\t" - - "leaq -144(%%rbp), %%r9\n\t" // 6th param: sal_uInt64* pRegisterReturn - "leaq 16(%%rbp), %%r8\n\t" // 5rd param: void** ovrflw - "leaq -64(%%rbp), %%rcx\n\t" // 4th param: void** fpreg - "leaq -112(%%rbp), %%rdx\n\t" // 3rd param: void** gpreg - "movl -148(%%rbp), %%esi\n\t" // 2nd param: sal_int32 nVtableOffset - "movl -152(%%rbp), %%edi\n\t" // 1st param: sal_int32 nFunctionIndex - - "call _cpp_vtable_call\n\t" - - "cmp $10, %%rax\n\t" // typelib_TypeClass_FLOAT - "je .Lfloat\n\t" - "cmp $11, %%rax\n\t" // typelib_TypeClass_DOUBLE - "je .Lfloat\n\t" - - "movq -144(%%rbp), %%rax\n\t" // Return value (int case) - "movq -136(%%rbp), %%rdx\n\t" // Return value (int case) - "movq -144(%%rbp), %%xmm0\n\t" // Return value (int case) - "movq -136(%%rbp), %%xmm1\n\t" // Return value (int case) - "jmp .Lfinish\n" -".Lfloat:\n\t" - "movlpd -144(%%rbp), %%xmm0\n" // Return value (float/double case) -".Lfinish:\n\t" - "addq $160, %%rsp\n" - : - : - : "rax", "r10", "xmm0" ); + asm volatile ( + " subq $160, %rsp\n" + " movq %r10, -152(%rbp)\n" // Save (nVtableOffset << 32) + nFunctionIndex + + " movq %rdi, -112(%rbp)\n" // Save GP registers + " movq %rsi, -104(%rbp)\n" + " movq %rdx, -96(%rbp)\n" + " movq %rcx, -88(%rbp)\n" + " movq %r8 , -80(%rbp)\n" + " movq %r9 , -72(%rbp)\n" + + " movsd %xmm0, -64(%rbp)\n" // Save FP registers + " movsd %xmm1, -56(%rbp)\n" + " movsd %xmm2, -48(%rbp)\n" + " movsd %xmm3, -40(%rbp)\n" + " movsd %xmm4, -32(%rbp)\n" + " movsd %xmm5, -24(%rbp)\n" + " movsd %xmm6, -16(%rbp)\n" + " movsd %xmm7, -8(%rbp)\n" + + " leaq -144(%rbp), %r9\n" // 6th param: sal_uInt64* pRegisterReturn + " leaq 16(%rbp), %r8\n" // 5rd param: void** ovrflw + " leaq -64(%rbp), %rcx\n" // 4th param: void** fpreg + " leaq -112(%rbp), %rdx\n" // 3rd param: void** gpreg + " movl -148(%rbp), %esi\n" // 2nd param: sal_int32 nVtableOffset + " movl -152(%rbp), %edi\n" // 1st param: sal_int32 nFunctionIndex + + " call _cpp_vtable_call\n" + + " cmp $10, %rax\n" // typelib_TypeClass_FLOAT + " je .Lfloat\n" + " cmp $11, %rax\n" // typelib_TypeClass_DOUBLE + " je .Lfloat\n" + + " movq -144(%rbp), %rax\n" // Return value (int case) + " movq -136(%rbp), %rdx\n" // Return value (int case) + " movq -144(%rbp), %xmm0\n" // Return value (int case) + " movq -136(%rbp), %xmm1\n" // Return value (int case) + " jmp .Lfinish\n" + ".Lfloat:\n" + " movlpd -144(%rbp), %xmm0\n" // Return value (float/double case) + ".Lfinish:\n" + " addq $160, %rsp\n" + ); } - -static const int codeSnippetSize = 24; +const int codeSnippetSize = 24; // Generate a trampoline that redirects method calls to // privateSnippetExecutor(). // +// privateSnippetExecutor() saves all the registers that are used for +// parameter passing on x86_64, and calls the cpp_vtable_call(). +// When it returns, privateSnippetExecutor() sets the return value. +// // Note: The code snippet we build here must not create a stack frame, // otherwise the UNO exceptions stop working thanks to non-existing // unwinding info. @@ -466,18 +455,18 @@ unsigned char * codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam ) SAL_THROW( () ) { - sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex ); + sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>( nVtableOffset ) << 32 ) | static_cast<sal_uInt64>( nFunctionIndex ); if ( bHasHiddenParam ) nOffsetAndIndex |= 0x80000000; // movq $<nOffsetAndIndex>, %r10 - *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49; - *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex; + *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49; + *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex; // movq $<address of the privateSnippetExecutor>, %r11 - *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49; - *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor ); + *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49; + *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor ); // jmpq *%r11 *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49; @@ -519,7 +508,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset, sal_Int32 functionCount, sal_Int32 nVtableOffset ) { - static const sal_PtrDiff writetoexecdiff = 0; + const sal_PtrDiff writetoexecdiff = 0; (*slots) -= functionCount; Slot * s = *slots; for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos ) diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx index f82ef9f..9e89ee0 100644 --- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx +++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx @@ -141,7 +141,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) ); if (iFind == m_rttis.end()) { - // build the mangled name for unoName's RTTI typeinfo symbol + // RTTI symbol OStringBuffer buf( 64 ); buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") ); sal_Int32 index = 0; @@ -156,7 +156,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR buf.append( 'E' ); OString symName( buf.makeStringAndClear() ); - rtti = (type_info *)dlsym( m_hApp, symName.getStr() ); + rtti = static_cast<std::type_info *>(dlsym( m_hApp, symName.getStr() )); if (rtti) { @@ -174,15 +174,12 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR // symbol and rtti-name is nearly identical, // the symbol is prefixed with _ZTI char const * rttiName = symName.getStr() +4; -#if OSL_DEBUG_LEVEL >= 1 +#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 -#if 0 // TODO: enable it again when the generated class_type_infos always work. - // Forcing the toolchain to create authentic typeinfos is much better though - // than the sick concept of reverse-engineering the platform's toolchain - // and generating the missing type_infos. +#if 0 if (pTypeDescr->pBaseTypeDescription) { // ensure availability of base @@ -197,9 +194,8 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR rtti = new __class_type_info( strdup( rttiName ) ); } #else - rtti = NULL; + rtti = NULL; #endif - bool bOK = m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti )).second; OSL_ENSURE( bOK, "### inserting new generated rtti failed?!" ); } @@ -220,7 +216,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR //-------------------------------------------------------------------------------------------------- static void deleteException( void * pExc ) { - __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); + __cxa_exception const * header = static_cast<__cxa_exception const *>(pExc) - 1; if( !header->exceptionType) // TODO: remove this when getRTTI() always returns non-NULL return; // NOTE: leak for now typelib_TypeDescription * pTD = 0; @@ -242,7 +238,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) OUStringToOString( *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), RTL_TEXTENCODING_ASCII_US ) ); - fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() ); + fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() ); #endif void * pCppExc; type_info * rtti; @@ -312,11 +308,27 @@ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping 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 + */ + { + // Does this look like the newer struct __cxa_exception? + // That is, is the 1st element NULL (*reserved)? + if (*reinterpret_cast<void **>(header) == NULL) { + // Yes. So we move up a slot to offset + header = reinterpret_cast<__cxa_exception *>(reinterpret_cast<void **>(header) + 1); + } + } + 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 occured: %s\n", cstr_unoName.getStr() ); + fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() ); #endif typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); if (0 == pExcTypeDescr) diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk index 7f92ad1..f6fcc98 100644 --- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk +++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk @@ -69,4 +69,3 @@ SHL1STDLIBS= \ # --- Targets ------------------------------------------------------ .INCLUDE : target.mk - diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx index b64609d..82bdd29 100644 --- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx +++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx @@ -32,19 +32,28 @@ 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 { - unsigned long exception_class; + uint64_t exception_class; void * exception_cleanup; uintptr_t private_1; uintptr_t private_2; }; struct __cxa_exception -{ -#if __LP64__ // ----- from libcxxabi/src/cxa_exception.hpp +{ +#if __LP64__ + // From LLVM 10 - Added reserved member at top of struct. Who the hell does that? + // https://reviews.llvm.org/rG674ec1eb16678b8addc02a4b0534ab383d22fa77 + // Sure would be nice to be able to test for CCNUMVER >= 1000000000 + // and COM == CLANG here. + // void *reserved; + // ----- from libcxxabi/src/cxa_exception.hpp // This is a new field to support C++ 0x exception_ptr. // For binary compatibility it is at the start of this // struct which is prepended to the object thrown in @@ -85,12 +94,12 @@ extern "C" __cxa_eh_globals *__cxa_get_globals () throw(); // ----- -#if 0 // #i124421# disabled because its use in except.cxx is disabled - +#if 0 // 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: @@ -107,9 +116,7 @@ public: : __class_type_info( pRttiName), mpBaseType( pBaseType) {} }; - #endif - //================================================================================================== void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx index ca38fb3..c9f5e5d 100644 --- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx +++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx @@ -149,7 +149,7 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, : : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ), "m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 ), - "m" (pCallStack) // dummy input to prevent the compiler from optimizing it out + "m" (pCallStack) // dummy input to prevent the compiler from optimizing the alloca out : "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "r8", "r9", "r10", "r11", "r10", "r12", "r13", "r14", "r15", "rbx", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" @@ -409,7 +409,7 @@ static void cpp_call( Reference< XInterface >()); } - // NO exception occured... + // NO exception occurred... *ppUnoExc = 0; // reconvert temporary params