Commit ffb8f4be authored by Alexandre Julliard's avatar Alexandre Julliard

rpcrt4: Add support for float parameters in client calls on x86_64.

parent 5f06809a
...@@ -131,11 +131,15 @@ __ASM_GLOBAL_FUNC(call_stubless_func, ...@@ -131,11 +131,15 @@ __ASM_GLOBAL_FUNC(call_stubless_func,
"movzwq (%rdx,%r10,2),%rdx\n\t" /* FormatStringOffset[index] */ "movzwq (%rdx,%r10,2),%rdx\n\t" /* FormatStringOffset[index] */
"addq 8(%rcx),%rdx\n\t" /* info->ProcFormatString + offset */ "addq 8(%rcx),%rdx\n\t" /* info->ProcFormatString + offset */
"movq (%rcx),%rcx\n\t" /* info->pStubDesc */ "movq (%rcx),%rcx\n\t" /* info->pStubDesc */
"subq $0x28,%rsp\n\t" "subq $0x38,%rsp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 0x28\n\t") __ASM_CFI(".cfi_adjust_cfa_offset 0x38\n\t")
"movq %xmm1,0x20(%rsp)\n\t"
"movq %xmm2,0x28(%rsp)\n\t"
"movq %xmm3,0x30(%rsp)\n\t"
"leaq 0x18(%rsp),%r9\n\t" /* fpu_args */
"call " __ASM_NAME("ndr_client_call") "\n\t" "call " __ASM_NAME("ndr_client_call") "\n\t"
"addq $0x28,%rsp\n\t" "addq $0x38,%rsp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset -0x28\n\t") __ASM_CFI(".cfi_adjust_cfa_offset -0x38\n\t")
"ret" ); "ret" );
#include "pshpack1.h" #include "pshpack1.h"
......
...@@ -285,8 +285,8 @@ static void client_free_handle( ...@@ -285,8 +285,8 @@ static void client_free_handle(
} }
static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
int phase, unsigned char *args, unsigned short number_of_params, int phase, unsigned char *args, void **fpu_args,
unsigned char *pRetVal) unsigned short number_of_params, unsigned char *pRetVal)
{ {
/* current format string offset */ /* current format string offset */
int current_offset = 0; int current_offset = 0;
...@@ -314,6 +314,14 @@ static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, ...@@ -314,6 +314,14 @@ static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
const unsigned char * pTypeFormat = const unsigned char * pTypeFormat =
&pParam->type_format_char; &pParam->type_format_char;
#ifdef __x86_64__ /* floats are passed as doubles through varargs functions */
float f;
if (*pTypeFormat == RPC_FC_FLOAT && !pParam->param_attributes.IsSimpleRef && !fpu_args)
{
f = *(double *)pArg;
pArg = (unsigned char *)&f;
}
#endif
if (pParam->param_attributes.IsSimpleRef) if (pParam->param_attributes.IsSimpleRef)
{ {
pArg = *(unsigned char **)pArg; pArg = *(unsigned char **)pArg;
...@@ -565,7 +573,8 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -565,7 +573,8 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
} }
} }
LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, void **stack_top ) LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat,
void **stack_top, void **fpu_stack )
{ {
/* pointer to start of stack where arguments start */ /* pointer to start of stack where arguments start */
RPC_MESSAGE rpcMsg; RPC_MESSAGE rpcMsg;
...@@ -652,16 +661,28 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma ...@@ -652,16 +661,28 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma
number_of_params = pOIFHeader->number_of_params; number_of_params = pOIFHeader->number_of_params;
pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
}
TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags);
if (Oif_flags.HasExtensions) if (Oif_flags.HasExtensions)
{ {
const NDR_PROC_HEADER_EXTS *pExtensions = const NDR_PROC_HEADER_EXTS *pExtensions = (const NDR_PROC_HEADER_EXTS *)pFormat;
(const NDR_PROC_HEADER_EXTS *)pFormat; ext_flags = pExtensions->Flags2;
ext_flags = pExtensions->Flags2; pFormat += pExtensions->Size;
pFormat += pExtensions->Size; #ifdef __x86_64__
if (pExtensions->Size > sizeof(*pExtensions) && fpu_stack)
{
int i;
unsigned short fpu_mask = *(unsigned short *)(pExtensions + 1);
for (i = 0; i < 4; i++, fpu_mask >>= 2)
switch (fpu_mask & 3)
{
case 1: *(float *)&stack_top[i] = *(float *)&fpu_stack[i]; break;
case 2: *(double *)&stack_top[i] = *(double *)&fpu_stack[i]; break;
}
}
#endif
}
} }
stubMsg.BufferLength = 0; stubMsg.BufferLength = 0;
...@@ -766,7 +787,7 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma ...@@ -766,7 +787,7 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma
case PROXY_MARSHAL: case PROXY_MARSHAL:
case PROXY_UNMARSHAL: case PROXY_UNMARSHAL:
if (bV2Format) if (bV2Format)
client_do_args(&stubMsg, pFormat, phase, stubMsg.StackTop, client_do_args(&stubMsg, pFormat, phase, stubMsg.StackTop, fpu_stack,
number_of_params, (unsigned char *)&RetVal); number_of_params, (unsigned char *)&RetVal);
else else
client_do_args_old_format(&stubMsg, pFormat, phase, client_do_args_old_format(&stubMsg, pFormat, phase,
...@@ -870,7 +891,7 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma ...@@ -870,7 +891,7 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma
case PROXY_MARSHAL: case PROXY_MARSHAL:
case PROXY_UNMARSHAL: case PROXY_UNMARSHAL:
if (bV2Format) if (bV2Format)
client_do_args(&stubMsg, pFormat, phase, stubMsg.StackTop, client_do_args(&stubMsg, pFormat, phase, stubMsg.StackTop, fpu_stack,
number_of_params, (unsigned char *)&RetVal); number_of_params, (unsigned char *)&RetVal);
else else
client_do_args_old_format(&stubMsg, pFormat, phase, client_do_args_old_format(&stubMsg, pFormat, phase,
...@@ -919,6 +940,7 @@ __ASM_GLOBAL_FUNC( NdrClientCall2, ...@@ -919,6 +940,7 @@ __ASM_GLOBAL_FUNC( NdrClientCall2,
"movq %r8,0x18(%rsp)\n\t" "movq %r8,0x18(%rsp)\n\t"
"movq %r9,0x20(%rsp)\n\t" "movq %r9,0x20(%rsp)\n\t"
"leaq 0x18(%rsp),%r8\n\t" "leaq 0x18(%rsp),%r8\n\t"
"xorq %r9,%r9\n\t"
"subq $0x28,%rsp\n\t" "subq $0x28,%rsp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 0x28\n\t") __ASM_CFI(".cfi_adjust_cfa_offset 0x28\n\t")
"call " __ASM_NAME("ndr_client_call") "\n\t" "call " __ASM_NAME("ndr_client_call") "\n\t"
...@@ -937,7 +959,7 @@ CLIENT_CALL_RETURN WINAPIV NdrClientCall2( PMIDL_STUB_DESC desc, PFORMAT_STRING ...@@ -937,7 +959,7 @@ CLIENT_CALL_RETURN WINAPIV NdrClientCall2( PMIDL_STUB_DESC desc, PFORMAT_STRING
LONG_PTR ret; LONG_PTR ret;
__ms_va_start( args, format ); __ms_va_start( args, format );
ret = ndr_client_call( desc, format, va_arg( args, void ** )); ret = ndr_client_call( desc, format, va_arg( args, void ** ), NULL );
__ms_va_end( args ); __ms_va_end( args );
return *(CLIENT_CALL_RETURN *)&ret; return *(CLIENT_CALL_RETURN *)&ret;
} }
...@@ -1947,7 +1969,7 @@ CLIENT_CALL_RETURN WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc, ...@@ -1947,7 +1969,7 @@ CLIENT_CALL_RETURN WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc,
case PROXY_CALCSIZE: case PROXY_CALCSIZE:
case PROXY_MARSHAL: case PROXY_MARSHAL:
if (bV2Format) if (bV2Format)
client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop, client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop, NULL,
async_call_data->number_of_params, NULL); async_call_data->number_of_params, NULL);
else else
client_do_args_old_format(pStubMsg, pFormat, phase, client_do_args_old_format(pStubMsg, pFormat, phase,
...@@ -2032,7 +2054,7 @@ RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply) ...@@ -2032,7 +2054,7 @@ RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply)
case PROXY_UNMARSHAL: case PROXY_UNMARSHAL:
if (bV2Format) if (bV2Format)
client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop, client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop,
async_call_data->number_of_params, Reply); NULL, async_call_data->number_of_params, Reply);
else else
client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase, client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase,
pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE); pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE);
......
...@@ -237,7 +237,7 @@ typedef struct _NDR_EHD_CONTEXT ...@@ -237,7 +237,7 @@ typedef struct _NDR_EHD_CONTEXT
#include "poppack.h" #include "poppack.h"
LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat,
void **stack_top ) DECLSPEC_HIDDEN; void **stack_top, void **fpu_stack ) DECLSPEC_HIDDEN;
void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat, int phase, unsigned char *args, PFORMAT_STRING pFormat, int phase, unsigned char *args,
unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc, unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment