rpcrt4: Add support for float parameters in client calls on x86_64.
This commit is contained in:
parent
5f06809ab3
commit
ffb8f4bedf
|
@ -131,11 +131,15 @@ __ASM_GLOBAL_FUNC(call_stubless_func,
|
|||
"movzwq (%rdx,%r10,2),%rdx\n\t" /* FormatStringOffset[index] */
|
||||
"addq 8(%rcx),%rdx\n\t" /* info->ProcFormatString + offset */
|
||||
"movq (%rcx),%rcx\n\t" /* info->pStubDesc */
|
||||
"subq $0x28,%rsp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 0x28\n\t")
|
||||
"subq $0x38,%rsp\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"
|
||||
"addq $0x28,%rsp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset -0x28\n\t")
|
||||
"addq $0x38,%rsp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset -0x38\n\t")
|
||||
"ret" );
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
|
|
@ -285,8 +285,8 @@ static void client_free_handle(
|
|||
}
|
||||
|
||||
static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
|
||||
int phase, unsigned char *args, unsigned short number_of_params,
|
||||
unsigned char *pRetVal)
|
||||
int phase, unsigned char *args, void **fpu_args,
|
||||
unsigned short number_of_params, unsigned char *pRetVal)
|
||||
{
|
||||
/* current format string offset */
|
||||
int current_offset = 0;
|
||||
|
@ -314,6 +314,14 @@ static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
|
|||
const unsigned char * pTypeFormat =
|
||||
&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)
|
||||
{
|
||||
pArg = *(unsigned char **)pArg;
|
||||
|
@ -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 */
|
||||
RPC_MESSAGE rpcMsg;
|
||||
|
@ -652,16 +661,28 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma
|
|||
number_of_params = pOIFHeader->number_of_params;
|
||||
|
||||
pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
|
||||
}
|
||||
|
||||
TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags);
|
||||
|
||||
if (Oif_flags.HasExtensions)
|
||||
{
|
||||
const NDR_PROC_HEADER_EXTS *pExtensions =
|
||||
(const NDR_PROC_HEADER_EXTS *)pFormat;
|
||||
const NDR_PROC_HEADER_EXTS *pExtensions = (const NDR_PROC_HEADER_EXTS *)pFormat;
|
||||
ext_flags = pExtensions->Flags2;
|
||||
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;
|
||||
|
@ -766,7 +787,7 @@ LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma
|
|||
case PROXY_MARSHAL:
|
||||
case PROXY_UNMARSHAL:
|
||||
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);
|
||||
else
|
||||
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
|
|||
case PROXY_MARSHAL:
|
||||
case PROXY_UNMARSHAL:
|
||||
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);
|
||||
else
|
||||
client_do_args_old_format(&stubMsg, pFormat, phase,
|
||||
|
@ -919,6 +940,7 @@ __ASM_GLOBAL_FUNC( NdrClientCall2,
|
|||
"movq %r8,0x18(%rsp)\n\t"
|
||||
"movq %r9,0x20(%rsp)\n\t"
|
||||
"leaq 0x18(%rsp),%r8\n\t"
|
||||
"xorq %r9,%r9\n\t"
|
||||
"subq $0x28,%rsp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 0x28\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
|
|||
LONG_PTR ret;
|
||||
|
||||
__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 );
|
||||
return *(CLIENT_CALL_RETURN *)&ret;
|
||||
}
|
||||
|
@ -1947,7 +1969,7 @@ CLIENT_CALL_RETURN WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc,
|
|||
case PROXY_CALCSIZE:
|
||||
case PROXY_MARSHAL:
|
||||
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);
|
||||
else
|
||||
client_do_args_old_format(pStubMsg, pFormat, phase,
|
||||
|
@ -2032,7 +2054,7 @@ RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply)
|
|||
case PROXY_UNMARSHAL:
|
||||
if (bV2Format)
|
||||
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
|
||||
client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase,
|
||||
pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE);
|
||||
|
|
|
@ -237,7 +237,7 @@ typedef struct _NDR_EHD_CONTEXT
|
|||
#include "poppack.h"
|
||||
|
||||
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,
|
||||
PFORMAT_STRING pFormat, int phase, unsigned char *args,
|
||||
unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc,
|
||||
|
|
Loading…
Reference in New Issue