mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:27:35 +00:00
Modified CallTo16Register routines to update register context after
call returns. Callers adapted.
This commit is contained in:
parent
52b2d2cff6
commit
a761e3dad0
5 changed files with 73 additions and 25 deletions
|
@ -67,10 +67,10 @@ WORD CALLBACK CallTo16Word( FARPROC16 target, INT nArgs )
|
||||||
LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs )
|
LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs )
|
||||||
{ assert( FALSE ); }
|
{ assert( FALSE ); }
|
||||||
|
|
||||||
LONG CALLBACK CallTo16RegisterShort( const CONTEXT86 *context, INT nArgs )
|
void CALLBACK CallTo16RegisterShort( CONTEXT86 *context, INT nArgs )
|
||||||
{ assert( FALSE ); }
|
{ assert( FALSE ); }
|
||||||
|
|
||||||
LONG CALLBACK CallTo16RegisterLong ( const CONTEXT86 *context, INT nArgs )
|
void CALLBACK CallTo16RegisterLong ( CONTEXT86 *context, INT nArgs )
|
||||||
{ assert( FALSE ); }
|
{ assert( FALSE ); }
|
||||||
|
|
||||||
WORD CallFrom16Word( void )
|
WORD CallFrom16Word( void )
|
||||||
|
@ -327,12 +327,27 @@ void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func )
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RELAY_DebugCallTo16Ret
|
* RELAY_DebugCallTo16Ret
|
||||||
*/
|
*/
|
||||||
void RELAY_DebugCallTo16Ret( int ret_val )
|
void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val )
|
||||||
{
|
{
|
||||||
if (!TRACE_ON(relay)) return;
|
if (!TRACE_ON(relay)) return;
|
||||||
|
|
||||||
DPRINTF("CallTo16() ss:sp=%04x:%04x retval=0x%08x\n",
|
if (!reg_func)
|
||||||
SELECTOROF(NtCurrentTeb()->cur_stack),
|
{
|
||||||
OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
|
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 );
|
SYSLEVEL_CheckNotLevel( 2 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ extern void CallFrom16Thunk();
|
||||||
|
|
||||||
extern WORD CALLBACK CallTo16Word( FARPROC16 target, INT nArgs );
|
extern WORD CALLBACK CallTo16Word( FARPROC16 target, INT nArgs );
|
||||||
extern LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs );
|
extern LONG CALLBACK CallTo16Long( FARPROC16 target, INT nArgs );
|
||||||
extern LONG CALLBACK CallTo16RegisterShort( const struct _CONTEXT86 *context, INT nArgs );
|
extern void CALLBACK CallTo16RegisterShort( struct _CONTEXT86 *context, INT nArgs );
|
||||||
extern LONG CALLBACK CallTo16RegisterLong ( const struct _CONTEXT86 *context, INT nArgs );
|
extern void CALLBACK CallTo16RegisterLong ( struct _CONTEXT86 *context, INT nArgs );
|
||||||
|
|
||||||
#include "pshpack1.h"
|
#include "pshpack1.h"
|
||||||
|
|
||||||
|
|
|
@ -1193,7 +1193,8 @@ static void NE_InitProcess(void)
|
||||||
SELECTOROF(pTask->teb->cur_stack),
|
SELECTOROF(pTask->teb->cur_stack),
|
||||||
OFFSETOF(pTask->teb->cur_stack) );
|
OFFSETOF(pTask->teb->cur_stack) );
|
||||||
|
|
||||||
ExitThread( CallTo16RegisterShort( &context, 0 ) );
|
CallTo16RegisterShort( &context, 0 );
|
||||||
|
ExitThread( AX_reg( &context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSLEVEL_LeaveWin16Lock();
|
SYSLEVEL_LeaveWin16Lock();
|
||||||
|
|
|
@ -504,20 +504,44 @@ static void BuildCallTo16Core( FILE *outfile, int short_ret, int reg_func )
|
||||||
fprintf( outfile, "\tpushl %%cs\n" );
|
fprintf( outfile, "\tpushl %%cs\n" );
|
||||||
fprintf( outfile, "\tcall .LCallTo16%s\n", name );
|
fprintf( outfile, "\tcall .LCallTo16%s\n", name );
|
||||||
|
|
||||||
/* Convert and push return value */
|
if ( !reg_func )
|
||||||
if ( short_ret )
|
|
||||||
{
|
{
|
||||||
fprintf( outfile, "\tmovzwl %%ax, %%eax\n" );
|
/* Convert and push return value */
|
||||||
fprintf( outfile, "\tpushl %%eax\n" );
|
if ( short_ret )
|
||||||
}
|
{
|
||||||
else if ( reg_func != 2 )
|
fprintf( outfile, "\tmovzwl %%ax, %%eax\n" );
|
||||||
{
|
fprintf( outfile, "\tpushl %%eax\n" );
|
||||||
fprintf( outfile, "\tshll $16,%%edx\n" );
|
}
|
||||||
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
else
|
||||||
fprintf( outfile, "\tpushl %%edx\n" );
|
{
|
||||||
|
fprintf( outfile, "\tshll $16,%%edx\n" );
|
||||||
|
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
||||||
|
fprintf( outfile, "\tpushl %%edx\n" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
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 )
|
if ( UsePIC )
|
||||||
{
|
{
|
||||||
|
@ -531,10 +555,14 @@ static void BuildCallTo16Core( FILE *outfile, int short_ret, int reg_func )
|
||||||
/* Print debugging info */
|
/* Print debugging info */
|
||||||
if (debugging)
|
if (debugging)
|
||||||
{
|
{
|
||||||
|
fprintf( outfile, "\tpushl $%d\n", reg_func );
|
||||||
|
|
||||||
if ( UsePIC )
|
if ( UsePIC )
|
||||||
fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16Ret@PLT\n" );
|
fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16Ret@PLT\n" );
|
||||||
else
|
else
|
||||||
fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16Ret\n" );
|
fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16Ret\n" );
|
||||||
|
|
||||||
|
fprintf( outfile, "\taddl $4, %%esp\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Leave Win16 Mutex */
|
/* Leave Win16 Mutex */
|
||||||
|
@ -657,17 +685,20 @@ static void BuildRet16Func( FILE *outfile )
|
||||||
fprintf( outfile, "\t.globl " PREFIX "CallTo16_Ret\n" );
|
fprintf( outfile, "\t.globl " PREFIX "CallTo16_Ret\n" );
|
||||||
fprintf( outfile, 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 */
|
/* 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__
|
#ifdef __svr4__
|
||||||
fprintf( outfile, "\tdata16\n");
|
fprintf( outfile, "\tdata16\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf( outfile, "\tmovw %%bx,%%ds\n" );
|
fprintf( outfile, "\tmovw %%di,%%ds\n" );
|
||||||
#ifdef __svr4__
|
#ifdef __svr4__
|
||||||
fprintf( outfile, "\tdata16\n");
|
fprintf( outfile, "\tdata16\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf( outfile, "\tmovw %%bx,%%es\n" );
|
fprintf( outfile, "\tmovw %%di,%%es\n" );
|
||||||
|
|
||||||
fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" );
|
fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" );
|
||||||
|
|
||||||
|
@ -676,7 +707,7 @@ static void BuildRet16Func( FILE *outfile )
|
||||||
#ifdef __svr4__
|
#ifdef __svr4__
|
||||||
fprintf( outfile, "\tdata16\n");
|
fprintf( outfile, "\tdata16\n");
|
||||||
#endif
|
#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\tmovl (%d),%%esp\n", STACKOFFSET );
|
||||||
fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\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[3] = msg;
|
||||||
args[4] = hwnd;
|
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 );
|
if (offset) stack16_pop( offset );
|
||||||
|
|
||||||
WIN_RestoreWndsLock(iWndsLocks);
|
WIN_RestoreWndsLock(iWndsLocks);
|
||||||
|
|
Loading…
Reference in a new issue