Modified CallTo16Register routines to update register context after
call returns. Callers adapted.
This commit is contained in:
parent
52b2d2cff6
commit
a761e3dad0
|
@ -67,10 +67,10 @@ WORD CALLBACK CallTo16Word( FARPROC16 target, INT nArgs )
|
|||
LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs )
|
||||
{ assert( FALSE ); }
|
||||
|
||||
LONG CALLBACK CallTo16RegisterShort( const CONTEXT86 *context, INT nArgs )
|
||||
void CALLBACK CallTo16RegisterShort( CONTEXT86 *context, INT nArgs )
|
||||
{ assert( FALSE ); }
|
||||
|
||||
LONG CALLBACK CallTo16RegisterLong ( const CONTEXT86 *context, INT nArgs )
|
||||
void CALLBACK CallTo16RegisterLong ( CONTEXT86 *context, INT nArgs )
|
||||
{ assert( FALSE ); }
|
||||
|
||||
WORD CallFrom16Word( void )
|
||||
|
@ -327,12 +327,27 @@ void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func )
|
|||
/***********************************************************************
|
||||
* RELAY_DebugCallTo16Ret
|
||||
*/
|
||||
void RELAY_DebugCallTo16Ret( int ret_val )
|
||||
void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val )
|
||||
{
|
||||
if (!TRACE_ON(relay)) return;
|
||||
|
||||
DPRINTF("CallTo16() ss:sp=%04x:%04x retval=0x%08x\n",
|
||||
SELECTOROF(NtCurrentTeb()->cur_stack),
|
||||
OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
|
||||
if (!reg_func)
|
||||
{
|
||||
DPRINTF("CallTo16() ss:sp=%04x:%04x retval=0x%08x\n",
|
||||
SELECTOROF(NtCurrentTeb()->cur_stack),
|
||||
OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONTEXT86 *context = (CONTEXT86 *)ret_val;
|
||||
|
||||
DPRINTF("CallTo16() ss:sp=%04x:%04x\n",
|
||||
SELECTOROF(NtCurrentTeb()->cur_stack),
|
||||
OFFSETOF(NtCurrentTeb()->cur_stack));
|
||||
DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x BP=%04x SP=%04x\n",
|
||||
AX_reg(context), BX_reg(context), CX_reg(context),
|
||||
DX_reg(context), BP_reg(context), LOWORD(ESP_reg(context)));
|
||||
}
|
||||
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ extern void CallFrom16Thunk();
|
|||
|
||||
extern WORD CALLBACK CallTo16Word( FARPROC16 target, INT nArgs );
|
||||
extern LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs );
|
||||
extern LONG CALLBACK CallTo16RegisterShort( const struct _CONTEXT86 *context, INT nArgs );
|
||||
extern LONG CALLBACK CallTo16RegisterLong ( const struct _CONTEXT86 *context, INT nArgs );
|
||||
extern void CALLBACK CallTo16RegisterShort( struct _CONTEXT86 *context, INT nArgs );
|
||||
extern void CALLBACK CallTo16RegisterLong ( struct _CONTEXT86 *context, INT nArgs );
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
|
|
|
@ -1193,7 +1193,8 @@ static void NE_InitProcess(void)
|
|||
SELECTOROF(pTask->teb->cur_stack),
|
||||
OFFSETOF(pTask->teb->cur_stack) );
|
||||
|
||||
ExitThread( CallTo16RegisterShort( &context, 0 ) );
|
||||
CallTo16RegisterShort( &context, 0 );
|
||||
ExitThread( AX_reg( &context ) );
|
||||
}
|
||||
|
||||
SYSLEVEL_LeaveWin16Lock();
|
||||
|
|
|
@ -504,20 +504,44 @@ static void BuildCallTo16Core( FILE *outfile, int short_ret, int reg_func )
|
|||
fprintf( outfile, "\tpushl %%cs\n" );
|
||||
fprintf( outfile, "\tcall .LCallTo16%s\n", name );
|
||||
|
||||
/* Convert and push return value */
|
||||
if ( short_ret )
|
||||
if ( !reg_func )
|
||||
{
|
||||
fprintf( outfile, "\tmovzwl %%ax, %%eax\n" );
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
}
|
||||
else if ( reg_func != 2 )
|
||||
{
|
||||
fprintf( outfile, "\tshll $16,%%edx\n" );
|
||||
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
||||
fprintf( outfile, "\tpushl %%edx\n" );
|
||||
/* Convert and push return value */
|
||||
if ( short_ret )
|
||||
{
|
||||
fprintf( outfile, "\tmovzwl %%ax, %%eax\n" );
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\tshll $16,%%edx\n" );
|
||||
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
||||
fprintf( outfile, "\tpushl %%edx\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
{
|
||||
/*
|
||||
* Modify CONTEXT86 structure to contain new values
|
||||
*
|
||||
* NOTE: We restore only EAX, EBX, EDX, EDX, EBP, and ESP.
|
||||
* The segment registers as well as ESI and EDI should
|
||||
* not be modified by a well-behaved 16-bit routine in
|
||||
* any case. [If necessary, we could restore them as well,
|
||||
* at the cost of a somewhat less efficient return path.]
|
||||
*/
|
||||
|
||||
fprintf( outfile, "\tmovl %d(%%esp), %%edi\n", STACK32OFFSET(target)-12 );
|
||||
fprintf( outfile, "\tmovl %%eax, %d(%%edi)\n", CONTEXTOFFSET(Eax) );
|
||||
fprintf( outfile, "\tmovl %%ebx, %d(%%edi)\n", CONTEXTOFFSET(Ebx) );
|
||||
fprintf( outfile, "\tmovl %%ecx, %d(%%edi)\n", CONTEXTOFFSET(Ecx) );
|
||||
fprintf( outfile, "\tmovl %%edx, %d(%%edi)\n", CONTEXTOFFSET(Edx) );
|
||||
fprintf( outfile, "\tmovl %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) );
|
||||
fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) );
|
||||
/* The return glue code saved %esp into %esi */
|
||||
|
||||
fprintf( outfile, "\tpushl %%edi\n" );
|
||||
}
|
||||
|
||||
if ( UsePIC )
|
||||
{
|
||||
|
@ -531,10 +555,14 @@ static void BuildCallTo16Core( FILE *outfile, int short_ret, int reg_func )
|
|||
/* Print debugging info */
|
||||
if (debugging)
|
||||
{
|
||||
fprintf( outfile, "\tpushl $%d\n", reg_func );
|
||||
|
||||
if ( UsePIC )
|
||||
fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16Ret@PLT\n" );
|
||||
else
|
||||
fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16Ret\n" );
|
||||
|
||||
fprintf( outfile, "\taddl $4, %%esp\n" );
|
||||
}
|
||||
|
||||
/* Leave Win16 Mutex */
|
||||
|
@ -657,17 +685,20 @@ static void BuildRet16Func( FILE *outfile )
|
|||
fprintf( outfile, "\t.globl " PREFIX "CallTo16_Ret\n" );
|
||||
fprintf( outfile, PREFIX "CallTo16_Ret:\n" );
|
||||
|
||||
/* Save %esp into %esi */
|
||||
fprintf( outfile, "\tmovl %%esp,%%esi\n" );
|
||||
|
||||
/* Restore 32-bit segment registers */
|
||||
|
||||
fprintf( outfile, "\tmovw $0x%04x,%%bx\n", data_selector );
|
||||
fprintf( outfile, "\tmovw $0x%04x,%%di\n", data_selector );
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%bx,%%ds\n" );
|
||||
fprintf( outfile, "\tmovw %%di,%%ds\n" );
|
||||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%bx,%%es\n" );
|
||||
fprintf( outfile, "\tmovw %%di,%%es\n" );
|
||||
|
||||
fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" );
|
||||
|
||||
|
@ -676,7 +707,7 @@ static void BuildRet16Func( FILE *outfile )
|
|||
#ifdef __svr4__
|
||||
fprintf( outfile, "\tdata16\n");
|
||||
#endif
|
||||
fprintf( outfile, "\tmovw %%bx,%%ss\n" );
|
||||
fprintf( outfile, "\tmovw %%di,%%ss\n" );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET );
|
||||
|
||||
|
|
|
@ -238,7 +238,8 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
|||
args[3] = msg;
|
||||
args[4] = hwnd;
|
||||
|
||||
ret = CallTo16RegisterShort( &context, 5 * sizeof(WORD) );
|
||||
CallTo16RegisterShort( &context, 5 * sizeof(WORD) );
|
||||
ret = MAKELONG( AX_reg(&context), DX_reg(&context) );
|
||||
if (offset) stack16_pop( offset );
|
||||
|
||||
WIN_RestoreWndsLock(iWndsLocks);
|
||||
|
|
Loading…
Reference in New Issue