diff options
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx')
-rw-r--r-- | bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx | 135 |
1 files changed, 66 insertions, 69 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx index 22e0c7467e15..38d48241d02c 100644 --- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx @@ -228,10 +228,12 @@ static inline typelib_TypeClass cpp2uno_call( //================================================================================================== extern "C" typelib_TypeClass cpp_vtable_call( - sal_Int32 nFunctionIndex, - sal_Int32 nVtableOffset, + sal_Int64 nOffsetAndIndex, void ** pStack ) { + sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF); + sal_Int32 nVtableOffset = ((nOffsetAndIndex >> 32) & 0xFFFFFFFF); + // pStack points to space for return value, after which // follows our return address (uninteresting) then the spilled // integer or floating-point register parameters from the call to @@ -372,89 +374,84 @@ extern "C" typelib_TypeClass cpp_vtable_call( } //================================================================================================== -extern "C" { - -// These are actually addresses in the code compiled from codeSnippet.asm -extern char - fp_spill_templates, - fp_spill_templates_end, - trampoline_template, - trampoline_template_function_table, - trampoline_template_spill_params, - trampoline_template_spill_params_end, - trampoline_template_function_index, - trampoline_template_vtable_offset, - trampoline_template_cpp_vtable_call, - trampoline_template_end; -} -// Just the code -int const codeSnippetSize = - (int) (&trampoline_template_end - &trampoline_template); +int const codeSnippetSize = 48; + +extern "C" char privateSnippetExecutor; // This function generates the code that acts as a proxy for the UNO function to be called. // The generated code does the following: -// - Save register parametrs. +// - Spills register parameters on stack +// - Loads functionIndex and vtableOffset into scratch registers +// - Jumps to privateSnippetExecutor unsigned char * codeSnippet( unsigned char * code, char param_kind[4], - sal_Int32 functionIndex, - sal_Int32 vtableOffset, + sal_Int32 nFunctionIndex, + sal_Int32 nVtableOffset, bool bHasHiddenParam ) { - OSL_ASSERT( (&fp_spill_templates_end - &fp_spill_templates) == - (&trampoline_template_spill_params_end - &trampoline_template_spill_params) ); - - OSL_ASSERT( ((&fp_spill_templates_end - &fp_spill_templates) / 4) * 4 == - (&fp_spill_templates_end - &fp_spill_templates) ); + sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex ); + unsigned char *p = code; if ( bHasHiddenParam ) - functionIndex |= 0x80000000; - - int const one_spill_instruction_size = - (int) ((&fp_spill_templates_end - &fp_spill_templates)) / 4; + nOffsetAndIndex |= 0x80000000; - memcpy( code, &trampoline_template, codeSnippetSize ); - - for (int i = 0; i < 4; ++i) + // Spill parameters + if ( param_kind[0] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT ) { - if ( param_kind[i] == CPPU_CURRENT_NAMESPACE::REGPARAM_FLT ) - { - memcpy (&trampoline_template_spill_params + i*one_spill_instruction_size, - &fp_spill_templates + i*one_spill_instruction_size, - one_spill_instruction_size); - } + // mov qword ptr 8[rsp], rcx + *p++ = 0x48; *p++ = 0x89; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x08; + } + else + { + // movsd qword ptr 8[rsp], xmm0 + *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x44; *p++ = 0x24; *p++ = 0x08; + } + if ( param_kind[1] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT ) + { + // mov qword ptr 16[rsp], rdx + *p++ = 0x48; *p++ = 0x89; *p++ = 0x54; *p++ = 0x24; *p++ = 0x10; } + else + { + // movsd qword ptr 16[rsp], xmm1 + *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x10; + } + if ( param_kind[2] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT ) + { + // mov qword ptr 24[rsp], r8 + *p++ = 0x4C; *p++ = 0x89; *p++ = 0x44; *p++ = 0x24; *p++ = 0x18; + } + else + { + // movsd qword ptr 24[rsp], xmm2 + *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x54; *p++ = 0x24; *p++ = 0x18; + } + if ( param_kind[3] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT ) + { + // mov qword ptr 32[rsp], r9 + *p++ = 0x4C;*p++ = 0x89; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x20; + } + else + { + // movsd qword ptr 32[rsp], xmm3 + *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x5C; *p++ = 0x24; *p++ = 0x20; + } + + // mov rcx, nOffsetAndIndex + *p++ = 0x48; *p++ = 0xB9; + *((sal_uInt64 *)p) = nOffsetAndIndex; p += 8; + + // mov r11, privateSnippetExecutor + *p++ = 0x49; *p++ = 0xBB; + *((void **)p) = &privateSnippetExecutor; p += 8; + + // jmp r11 + *p++ = 0x41; *p++ = 0xFF; *p++ = 0xE3; - ((sal_uInt64*) (code + (&trampoline_template_function_index - - &trampoline_template)))[-1] = - functionIndex; - ((sal_uInt64*) (code + (&trampoline_template_vtable_offset - - &trampoline_template)))[-1] = - vtableOffset; - ((void**) (code + (&trampoline_template_cpp_vtable_call - - &trampoline_template)))[-1] = - cpp_vtable_call; - - // Add unwind data for the dynamically generated function by - // calling RtlAddFunctionTable(). - - // The unwind data is inside the function code, at a fixed offset - // from the function start. See codeSnippet.asm. Actually this is - // unnecessarily complex, we could as well just allocate the - // function table dynamically. But it doesn't hurt either, I - // think. - - // The real problem now is that we need to remove the unwind data - // with RtlDeleteFunctionTable() in freeExec() in - // vtablefactory.cxx. See comment there. - - RUNTIME_FUNCTION *pFunTable = - (RUNTIME_FUNCTION *) (code + (&trampoline_template_function_table - - &trampoline_template)); - - RtlAddFunctionTable( pFunTable, 1, (DWORD64) code ); + OSL_ASSERT( p < code + codeSnippetSize ); return code + codeSnippetSize; } |