--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.hxx @@ -24,9 +24,22 @@ #include +namespace x86_64 +{ + union funArg + { + sal_uInt64 val; + void * p; + + operator sal_uInt64() const noexcept { return val; } + template + operator T *() const noexcept { return static_cast( p ); } + }; +} // namespace x86_64 + extern "C" typelib_TypeClass cpp_vtable_call( sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, - void ** gpreg, void ** fpreg, void ** ovrflw, + x86_64::funArg * gpreg, x86_64::funArg * fpreg, x86_64::funArg * ovrflw, sal_uInt64 * pRegisterReturn /* space for register return */ ); #endif --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx @@ -54,25 +54,25 @@ // registers than available" error: struct Data { sal_uInt64 pMethod; - sal_uInt64 * pStack; - sal_uInt32 nStack; - sal_uInt64 * pGPR; - double * pFPR; + sal_uInt64 pStack; + sal_uInt64 nStack; + sal_uInt64 pGPR; + sal_uInt64 pFPR; // Return values: sal_uInt64 rax; sal_uInt64 rdx; double xmm0; double xmm1; } data; - data.pStack = pStack; + data.pStack = reinterpret_cast(pStack); data.nStack = nStack; - data.pGPR = pGPR; - data.pFPR = pFPR; + data.pGPR = reinterpret_cast(pGPR); + data.pFPR = reinterpret_cast(pFPR); // Get pointer to method - sal_uInt64 pMethod = *static_cast(pThis); - pMethod += 8 * nVtableIndex; - data.pMethod = *reinterpret_cast(pMethod); + sal_uIntPtr pMethod = *static_cast(pThis); + pMethod += sizeof(void *) * nVtableIndex; + data.pMethod = *reinterpret_cast(pMethod); asm volatile ( // Push arguments to stack --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx @@ -59,7 +59,7 @@ const typelib_TypeDescription * pMemberTypeDescr, typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return sal_Int32 nParams, typelib_MethodParameter * pParams, - void ** gpreg, void ** fpreg, void ** ovrflw, + x86_64::funArg * gpreg, x86_64::funArg * fpreg, x86_64::funArg * ovrflw, sal_uInt64 * pRegisterReturn /* space for register return */ ) { unsigned int nr_gpr = 0; //number of gpr registers used @@ -233,7 +233,7 @@ uno_destructData( pUnoReturn, pReturnTypeDescr, nullptr ); } // complex return ptr is set to return reg - *reinterpret_cast(pRegisterReturn) = pCppReturn; + *pRegisterReturn = reinterpret_cast( pCppReturn ); } if ( pReturnTypeDescr ) { @@ -249,7 +249,7 @@ typelib_TypeClass cpp_vtable_call( sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, - void ** gpreg, void ** fpreg, void ** ovrflw, + x86_64::funArg * gpreg, x86_64::funArg * fpreg, x86_64::funArg * ovrflw, sal_uInt64 * pRegisterReturn /* space for register return */ ) { // gpreg: [ret *], this, [other gpr params] @@ -356,7 +356,7 @@ pInterface->release(); TYPELIB_DANGER_RELEASE( pTD ); - reinterpret_cast( pRegisterReturn )[0] = gpreg[0]; + *pRegisterReturn = gpreg[0]; eRet = typelib_TypeClass_ANY; break; } @@ -388,7 +388,7 @@ return eRet; } -const int codeSnippetSize = 24; +const int codeSnippetSize = sizeof(void *) == 8 ? 24 : 16; // Generate a trampoline that redirects method calls to // privateSnippetExecutor(). @@ -400,7 +400,11 @@ // 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. +#ifdef __ILP32__ +unsigned char * codeSnippet( unsigned char * code, sal_PtrDiff writetoexecdiff, +#else unsigned char * codeSnippet( unsigned char * code, +#endif sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam ) { @@ -415,6 +419,13 @@ *reinterpret_cast( code + 4 ) = nOffsetAndIndex >> 16; *reinterpret_cast( code + 8 ) = nOffsetAndIndex >> 48; +#ifdef __ILP32__ + // addr32 jmp privateSnippetExecutor(%rip) + *reinterpret_cast( code + 10 ) = 0xe967; + *reinterpret_cast( code + 12 ) + = reinterpret_cast( privateSnippetExecutor ) + - reinterpret_cast( code ) - 16ul - writetoexecdiff; +#else // movq $
, %r11 *reinterpret_cast( code + 10 ) = 0xbb49; *reinterpret_cast( code + 12 ) @@ -424,6 +435,7 @@ // jmpq *%r11 *reinterpret_cast( code + 20 ) = 0x00e3ff49; +#endif #if OSL_DEBUG_LEVEL > 1 fprintf(stderr, @@ -486,14 +498,22 @@ // get method (s++)->fn = code + writetoexecdiff; +#ifdef __ILP32__ + code = codeSnippet( code, writetoexecdiff, nFunctionOffset++, nVtableOffset, +#else code = codeSnippet( code, nFunctionOffset++, nVtableOffset, +#endif x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) ); if ( ! pAttrTD->bReadOnly ) { // set method (s++)->fn = code + writetoexecdiff; +#ifdef __ILP32__ + code = codeSnippet( code, writetoexecdiff, nFunctionOffset++, nVtableOffset, false ); +#else code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false ); +#endif } } else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD ) @@ -502,7 +522,11 @@ reinterpret_cast( pTD ); (s++)->fn = code + writetoexecdiff; +#ifdef __ILP32__ + code = codeSnippet( code, writetoexecdiff, nFunctionOffset++, nVtableOffset, +#else code = codeSnippet( code, nFunctionOffset++, nVtableOffset, +#endif x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) ); } else --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx @@ -68,6 +68,15 @@ *pDS++ = *static_cast( pSV ); } +void INSERT_PTR( + void const * pSV, sal_uInt32 & nr, sal_uInt64 * pGPR, sal_uInt64 *& pDS) +{ + if ( nr < x86_64::MAX_GPR_REGS ) + pGPR[nr++] = *static_cast( pSV ); + else + *pDS++ = *static_cast( pSV ); +} + void INSERT_INT32( void const * pSV, sal_uInt32 & nr, sal_uInt64 * pGPR, sal_uInt64 *& pDS) { @@ -135,13 +144,13 @@ // complex return via ptr pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )? __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn; - INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack ); + INSERT_PTR( &pCppReturn, nGPR, pGPR, pStack ); } } // Push "this" pointer void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset; - INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack ); + INSERT_PTR( &pAdjustedThisPtr, nGPR, pGPR, pStack ); // Args void ** pCppArgs = static_cast(alloca( 3 * sizeof(void *) * nParams )); @@ -223,7 +232,7 @@ // no longer needed TYPELIB_DANGER_RELEASE( pParamTypeDescr ); } - INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack ); + INSERT_PTR( &(pCppArgs[nPos]), nGPR, pGPR, pStack ); } }