Commit 3a5b7cf1 authored by Alexandre Julliard's avatar Alexandre Julliard

Extended WOWCallback16Ex to support register functions too. This

allows simplifying the wine_call_to_16 assembly code by moving part of it to C code, and getting rid of the extra kernel exports.
parent cb1c112d
...@@ -1126,9 +1126,6 @@ ...@@ -1126,9 +1126,6 @@
@ varargs __wine_call_from_16_word() @ varargs __wine_call_from_16_word()
@ varargs __wine_call_from_16_long() @ varargs __wine_call_from_16_long()
@ varargs __wine_call_from_16_regs() @ varargs __wine_call_from_16_regs()
@ stdcall wine_call_to_16(ptr long)
@ stdcall wine_call_to_16_regs_short(ptr long)
@ stdcall wine_call_to_16_regs_long (ptr long)
# Unix files # Unix files
@ stdcall wine_get_unix_file_name(str ptr long) @ stdcall wine_get_unix_file_name(str ptr long)
......
...@@ -1284,7 +1284,7 @@ DWORD NE_StartTask(void) ...@@ -1284,7 +1284,7 @@ DWORD NE_StartTask(void)
SELECTOROF(pTask->teb->cur_stack), SELECTOROF(pTask->teb->cur_stack),
OFFSETOF(pTask->teb->cur_stack) ); OFFSETOF(pTask->teb->cur_stack) );
wine_call_to_16_regs_short( &context, 0 ); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
ExitThread( LOWORD(context.Eax) ); ExitThread( LOWORD(context.Eax) );
} }
return hInstance; /* error code */ return hInstance; /* error code */
......
...@@ -682,7 +682,7 @@ static BOOL NE_InitDLL( NE_MODULE *pModule ) ...@@ -682,7 +682,7 @@ static BOOL NE_InitDLL( NE_MODULE *pModule )
TRACE_(dll)("Calling LibMain, cs:ip=%04lx:%04lx ds=%04lx di=%04x cx=%04x\n", TRACE_(dll)("Calling LibMain, cs:ip=%04lx:%04lx ds=%04lx di=%04x cx=%04x\n",
context.SegCs, context.Eip, context.SegDs, context.SegCs, context.Eip, context.SegDs,
LOWORD(context.Edi), LOWORD(context.Ecx) ); LOWORD(context.Edi), LOWORD(context.Ecx) );
wine_call_to_16_regs_short( &context, 0 ); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
return TRUE; return TRUE;
} }
...@@ -769,8 +769,8 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason ) ...@@ -769,8 +769,8 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
} }
else else
{ {
LPBYTE stack = (LPBYTE)CURRENT_STACK16;
CONTEXT86 context; CONTEXT86 context;
WORD args[8];
memset( &context, 0, sizeof(context) ); memset( &context, 0, sizeof(context) );
context.SegDs = ds; context.SegDs = ds;
...@@ -781,14 +781,15 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason ) ...@@ -781,14 +781,15 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack )
+ (WORD)&((STACK16FRAME*)0)->bp; + (WORD)&((STACK16FRAME*)0)->bp;
*(DWORD *)(stack - 4) = dwReason; /* dwReason */ args[7] = HIWORD(dwReason);
*(WORD *) (stack - 6) = hInst; /* hInst */ args[6] = LOWORD(dwReason);
*(WORD *) (stack - 8) = ds; /* wDS */ args[5] = hInst;
*(WORD *) (stack - 10) = heap; /* wHeapSize */ args[4] = ds;
*(DWORD *)(stack - 14) = 0; /* dwReserved1 */ args[3] = heap;
*(WORD *) (stack - 16) = 0; /* wReserved2 */ args[2] = 0; /* HIWORD(dwReserved1) */
args[1] = 0; /* LOWORD(dwReserved1) */
wine_call_to_16_regs_short( &context, 16 ); args[0] = 0; /* wReserved2 */
WOWCallback16Ex( 0, WCB16_REGS, sizeof(args), args, (DWORD *)&context );
} }
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "wingdi.h" #include "wingdi.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "wownt32.h"
#include "stackframe.h" #include "stackframe.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -173,7 +174,7 @@ static void call_timer_proc16( WORD timer ) ...@@ -173,7 +174,7 @@ static void call_timer_proc16( WORD timer )
+ (WORD)&((STACK16FRAME*)0)->bp; + (WORD)&((STACK16FRAME*)0)->bp;
context.Eax = timer; context.Eax = timer;
wine_call_to_16_regs_short( &context, 0 ); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
} }
/**********************************************************************/ /**********************************************************************/
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "winternl.h" #include "winternl.h"
#include "wownt32.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -349,12 +350,7 @@ void WINAPI QT_Thunk( CONTEXT86 *context ) ...@@ -349,12 +350,7 @@ void WINAPI QT_Thunk( CONTEXT86 *context )
if (argsize > 64) if (argsize > 64)
argsize = 64; /* 32 WORDs */ argsize = 64; /* 32 WORDs */
memcpy( (LPBYTE)CURRENT_STACK16 - argsize, WOWCallback16Ex( 0, WCB16_REGS, argsize, (void *)context->Esp, (DWORD *)&context16 );
(LPBYTE)context->Esp, argsize );
/* let's hope call_to_16 won't mind getting called with such a
* potentially bogus large number of arguments */
wine_call_to_16_regs_short( &context16, argsize );
context->Eax = context16.Eax; context->Eax = context16.Eax;
context->Edx = context16.Edx; context->Edx = context16.Edx;
context->Ecx = context16.Ecx; context->Ecx = context16.Ecx;
...@@ -460,7 +456,8 @@ void WINAPI FT_Thunk( CONTEXT86 *context ) ...@@ -460,7 +456,8 @@ void WINAPI FT_Thunk( CONTEXT86 *context )
CONTEXT86 context16; CONTEXT86 context16;
DWORD i, argsize; DWORD i, argsize;
LPBYTE newstack, oldstack; DWORD newstack[32];
LPBYTE oldstack;
memcpy(&context16,context,sizeof(context16)); memcpy(&context16,context,sizeof(context16));
...@@ -470,7 +467,7 @@ void WINAPI FT_Thunk( CONTEXT86 *context ) ...@@ -470,7 +467,7 @@ void WINAPI FT_Thunk( CONTEXT86 *context )
+ (WORD)&((STACK16FRAME*)0)->bp; + (WORD)&((STACK16FRAME*)0)->bp;
argsize = context->Ebp-context->Esp-0x40; argsize = context->Ebp-context->Esp-0x40;
newstack = (LPBYTE)CURRENT_STACK16 - argsize; if (argsize > sizeof(newstack)) argsize = sizeof(newstack);
oldstack = (LPBYTE)context->Esp; oldstack = (LPBYTE)context->Esp;
memcpy( newstack, oldstack, argsize ); memcpy( newstack, oldstack, argsize );
...@@ -478,13 +475,13 @@ void WINAPI FT_Thunk( CONTEXT86 *context ) ...@@ -478,13 +475,13 @@ void WINAPI FT_Thunk( CONTEXT86 *context )
for (i = 0; i < 32; i++) /* NOTE: What about > 32 arguments? */ for (i = 0; i < 32; i++) /* NOTE: What about > 32 arguments? */
if (mapESPrelative & (1 << i)) if (mapESPrelative & (1 << i))
{ {
SEGPTR *arg = (SEGPTR *)(newstack + 2*i); SEGPTR *arg = (SEGPTR *)newstack[i];
*arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack), *arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack),
OFFSETOF(NtCurrentTeb()->cur_stack) - argsize OFFSETOF(NtCurrentTeb()->cur_stack) - argsize
+ (*(LPBYTE *)arg - oldstack)); + (*(LPBYTE *)arg - oldstack));
} }
wine_call_to_16_regs_short( &context16, argsize ); WOWCallback16Ex( 0, WCB16_REGS, argsize, newstack, (DWORD *)&context16 );
context->Eax = context16.Eax; context->Eax = context16.Eax;
context->Edx = context16.Edx; context->Edx = context16.Edx;
context->Ecx = context16.Ecx; context->Ecx = context16.Ecx;
...@@ -688,10 +685,11 @@ void WINAPI Common32ThkLS( CONTEXT86 *context ) ...@@ -688,10 +685,11 @@ void WINAPI Common32ThkLS( CONTEXT86 *context )
if (context->Edx == context->Eip) if (context->Edx == context->Eip)
argsize = 6 * 4; argsize = 6 * 4;
memcpy( (LPBYTE)CURRENT_STACK16 - argsize, /* Note: the first 32 bytes we copy are just garbage from the 32-bit stack, in order to reserve
(LPBYTE)context->Esp, argsize ); * the space. It is safe to do that since the register function prefix has reserved
* a lot more space than that below context->Esp.
wine_call_to_16_regs_long(&context16, argsize + 32); */
WOWCallback16Ex( 0, WCB16_REGS, argsize + 32, (LPBYTE)context->Esp - 32, (DWORD *)&context16 );
context->Eax = context16.Eax; context->Eax = context16.Eax;
/* Clean up caller's stack frame */ /* Clean up caller's stack frame */
...@@ -739,10 +737,7 @@ void WINAPI OT_32ThkLSF( CONTEXT86 *context ) ...@@ -739,10 +737,7 @@ void WINAPI OT_32ThkLSF( CONTEXT86 *context )
argsize = 2 * *(WORD *)context->Esp + 2; argsize = 2 * *(WORD *)context->Esp + 2;
memcpy( (LPBYTE)CURRENT_STACK16 - argsize, WOWCallback16Ex( 0, WCB16_REGS, argsize, (void *)context->Esp, (DWORD *)&context16 );
(LPBYTE)context->Esp, argsize );
wine_call_to_16_regs_short(&context16, argsize);
context->Eax = context16.Eax; context->Eax = context16.Eax;
context->Edx = context16.Edx; context->Edx = context16.Edx;
......
...@@ -21,11 +21,14 @@ ...@@ -21,11 +21,14 @@
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
#include <assert.h>
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "wownt32.h" #include "wownt32.h"
#include "winternl.h" #include "winternl.h"
#include "syslevel.h"
#include "file.h" #include "file.h"
#include "task.h" #include "task.h"
#include "miscemu.h" #include "miscemu.h"
...@@ -33,6 +36,7 @@ ...@@ -33,6 +36,7 @@
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(thunk); WINE_DEFAULT_DEBUG_CHANNEL(thunk);
WINE_DECLARE_DEBUG_CHANNEL(relay);
/* /*
* These are the 16-bit side WOW routines. They reside in wownt16.h * These are the 16-bit side WOW routines. They reside in wownt16.h
...@@ -290,7 +294,10 @@ WORD WINAPI K32WOWHandle16( HANDLE handle, WOW_HANDLE_TYPE type ) ...@@ -290,7 +294,10 @@ WORD WINAPI K32WOWHandle16( HANDLE handle, WOW_HANDLE_TYPE type )
BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode ) DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode )
{ {
DWORD ret; #ifdef __i386__
extern DWORD WINAPI wine_call_to_16( FARPROC16 target, DWORD cbArgs );
extern void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, DWORD cbArgs );
extern void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, DWORD cbArgs );
/* /*
* Arguments must be prepared in the correct order by the caller * Arguments must be prepared in the correct order by the caller
...@@ -299,17 +306,86 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, ...@@ -299,17 +306,86 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
*/ */
memcpy( (LPBYTE)CURRENT_STACK16 - cbArgs, (LPBYTE)pArgs, cbArgs ); memcpy( (LPBYTE)CURRENT_STACK16 - cbArgs, (LPBYTE)pArgs, cbArgs );
/* if (dwFlags & (WCB16_REGS|WCB16_REGS_LONG))
* Actually, we should take care whether the called routine cleans up {
* its stack or not. Fortunately, our wine_call_to_16 core doesn't rely on CONTEXT *context = (CONTEXT *)pdwRetCode;
* the callee to do so; after the routine has returned, the 16-bit
* stack pointer is always reset to the position it had before. if (TRACE_ON(relay))
*/ {
WORD *stack16 = (WORD *)CURRENT_STACK16;
DWORD count = cbArgs / sizeof(WORD);
DPRINTF("%04lx:CallTo16(func=%04lx:%04x,ds=%04lx",
GetCurrentThreadId(),
context->SegCs, LOWORD(context->Eip), context->SegDs );
while (count--) DPRINTF( ",%04x", *--stack16 );
DPRINTF(") ss:sp=%04x:%04x",
SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) );
DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x es=%04x fs=%04x\n",
(WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx,
(WORD)context->Edx, (WORD)context->Esi, (WORD)context->Edi,
(WORD)context->Ebp, (WORD)context->SegEs, (WORD)context->SegFs );
SYSLEVEL_CheckNotLevel( 2 );
}
ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs ); _EnterWin16Lock();
if (dwFlags & WCB16_REGS_LONG)
wine_call_to_16_regs_long( context, cbArgs );
else
wine_call_to_16_regs_short( context, cbArgs );
_LeaveWin16Lock();
if (TRACE_ON(relay))
{
DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x ",
GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack),
OFFSETOF(NtCurrentTeb()->cur_stack));
DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n",
(WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx,
(WORD)context->Edx, (WORD)context->Ebp, (WORD)context->Esp );
SYSLEVEL_CheckNotLevel( 2 );
}
}
else
{
DWORD ret;
if (TRACE_ON(relay))
{
WORD *stack16 = (WORD *)CURRENT_STACK16;
DWORD count = cbArgs / sizeof(WORD);
DPRINTF("%04lx:CallTo16(func=%04x:%04x,ds=%04x",
GetCurrentThreadId(), HIWORD(vpfn16), LOWORD(vpfn16),
SELECTOROF(NtCurrentTeb()->cur_stack) );
while (count--) DPRINTF( ",%04x", *--stack16 );
DPRINTF(") ss:sp=%04x:%04x\n",
SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) );
SYSLEVEL_CheckNotLevel( 2 );
}
if ( pdwRetCode ) /*
*pdwRetCode = ret; * Actually, we should take care whether the called routine cleans up
* its stack or not. Fortunately, our wine_call_to_16 core doesn't rely on
* the callee to do so; after the routine has returned, the 16-bit
* stack pointer is always reset to the position it had before.
*/
_EnterWin16Lock();
ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs );
if (pdwRetCode) *pdwRetCode = ret;
_LeaveWin16Lock();
if (TRACE_ON(relay))
{
DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x retval=%08lx\n",
GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack),
OFFSETOF(NtCurrentTeb()->cur_stack), ret);
SYSLEVEL_CheckNotLevel( 2 );
}
}
#else
assert(0); /* cannot call to 16-bit on non-Intel architectures */
#endif /* __i386__ */
return TRUE; /* success */ return TRUE; /* success */
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "windef.h" #include "windef.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wownt32.h"
#include "miscemu.h" #include "miscemu.h"
#include "task.h" #include "task.h"
#include "msdos.h" #include "msdos.h"
...@@ -362,7 +363,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag ) ...@@ -362,7 +363,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag )
ctx.SegEs = rmcb->regs_sel; ctx.SegEs = rmcb->regs_sel;
ctx.Edi = rmcb->regs_ofs; ctx.Edi = rmcb->regs_ofs;
/* FIXME: I'm pretty sure this isn't right - should push flags first */ /* FIXME: I'm pretty sure this isn't right - should push flags first */
wine_call_to_16_regs_short(&ctx, 0); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
es = ctx.SegEs; es = ctx.SegEs;
edi = ctx.Edi; edi = ctx.Edi;
} }
...@@ -585,7 +586,7 @@ static void StartPM( CONTEXT86 *context ) ...@@ -585,7 +586,7 @@ static void StartPM( CONTEXT86 *context )
__TRY __TRY
{ {
wine_call_to_16_regs_short(&pm_ctx, 0); WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&pm_ctx );
} }
__EXCEPT(dpmi_exception_handler) __EXCEPT(dpmi_exception_handler)
{ {
......
...@@ -80,30 +80,6 @@ BOOL RELAY_Init(void) ...@@ -80,30 +80,6 @@ BOOL RELAY_Init(void)
*/ */
#ifndef __i386__ #ifndef __i386__
/*********************************************************************** /***********************************************************************
* wine_call_to_16 (KERNEL32.@)
*/
LONG WINAPI wine_call_to_16( FARPROC16 target, INT nArgs )
{
assert( FALSE );
}
/***********************************************************************
* wine_call_to_16_regs_short (KERNEL32.@)
*/
void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, INT nArgs )
{
assert( FALSE );
}
/***********************************************************************
* wine_call_to_16_regs_long (KERNEL32.@)
*/
void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, INT nArgs )
{
assert( FALSE );
}
/***********************************************************************
* __wine_call_from_16_word (KERNEL32.@) * __wine_call_from_16_word (KERNEL32.@)
*/ */
WORD __wine_call_from_16_word() WORD __wine_call_from_16_word()
...@@ -387,82 +363,3 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) ...@@ -387,82 +363,3 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val )
} }
SYSLEVEL_CheckNotLevel( 2 ); SYSLEVEL_CheckNotLevel( 2 );
} }
/***********************************************************************
* RELAY_DebugCallTo16
*
* 'target' contains either the function to call (normal CallTo16)
* or a pointer to the CONTEXT86 struct (register CallTo16).
* 'nb_args' is the number of argument bytes on the 16-bit stack;
* 'reg_func' specifies whether we have a register CallTo16 or not.
*/
void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func )
{
WORD *stack16;
TEB *teb;
if (!TRACE_ON(relay)) return;
teb = NtCurrentTeb();
stack16 = (WORD *)THREAD_STACK16(teb);
nb_args /= sizeof(WORD);
if ( reg_func )
{
CONTEXT86 *context = (CONTEXT86 *)target;
DPRINTF("%04lx:CallTo16(func=%04lx:%04x,ds=%04lx",
GetCurrentThreadId(),
context->SegCs, LOWORD(context->Eip), context->SegDs );
while (nb_args--) DPRINTF( ",%04x", *--stack16 );
DPRINTF(") ss:sp=%04x:%04x", SELECTOROF(teb->cur_stack),
OFFSETOF(teb->cur_stack) );
DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x es=%04x fs=%04x\n",
(WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx,
(WORD)context->Edx, (WORD)context->Esi, (WORD)context->Edi,
(WORD)context->Ebp, (WORD)context->SegEs, (WORD)context->SegFs );
}
else
{
DPRINTF("%04lx:CallTo16(func=%04x:%04x,ds=%04x",
GetCurrentThreadId(),
HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) );
while (nb_args--) DPRINTF( ",%04x", *--stack16 );
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
OFFSETOF(teb->cur_stack) );
}
SYSLEVEL_CheckNotLevel( 2 );
}
/***********************************************************************
* RELAY_DebugCallTo16Ret
*/
void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val )
{
if (!TRACE_ON(relay)) return;
if (!reg_func)
{
DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x retval=%08x\n",
GetCurrentThreadId(),
SELECTOROF(NtCurrentTeb()->cur_stack),
OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
}
else
{
CONTEXT86 *context = (CONTEXT86 *)ret_val;
DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x ",
GetCurrentThreadId(),
SELECTOROF(NtCurrentTeb()->cur_stack),
OFFSETOF(NtCurrentTeb()->cur_stack));
DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n",
(WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx,
(WORD)context->Edx, (WORD)context->Ebp, (WORD)context->Esp );
}
SYSLEVEL_CheckNotLevel( 2 );
}
...@@ -38,13 +38,11 @@ typedef struct _STACK32FRAME ...@@ -38,13 +38,11 @@ typedef struct _STACK32FRAME
SEGPTR frame16; /* 10 16-bit frame from last CallFrom16() */ SEGPTR frame16; /* 10 16-bit frame from last CallFrom16() */
DWORD edi; /* 14 saved registers */ DWORD edi; /* 14 saved registers */
DWORD esi; /* 18 */ DWORD esi; /* 18 */
DWORD edx; /* 1c */ DWORD ebx; /* 1c */
DWORD ecx; /* 20 */ DWORD ebp; /* 20 saved 32-bit frame pointer */
DWORD ebx; /* 24 */ DWORD retaddr; /* 24 return address */
DWORD ebp; /* 28 saved 32-bit frame pointer */ DWORD target; /* 28 target address / CONTEXT86 pointer */
DWORD retaddr; /* 2c return address */ DWORD nb_args; /* 2c number of 16-bit argument bytes */
DWORD target; /* 30 target address / CONTEXT86 pointer */
DWORD nb_args; /* 34 number of 16-bit argument bytes */
} STACK32FRAME; } STACK32FRAME;
/* 16-bit stack layout after CallFrom16() */ /* 16-bit stack layout after CallFrom16() */
......
...@@ -220,6 +220,7 @@ HGLOBAL16 WINAPI GlobalLRUOldest16(HGLOBAL16); ...@@ -220,6 +220,7 @@ HGLOBAL16 WINAPI GlobalLRUOldest16(HGLOBAL16);
VOID WINAPI GlobalNotify16(FARPROC16); VOID WINAPI GlobalNotify16(FARPROC16);
WORD WINAPI GlobalPageLock16(HGLOBAL16); WORD WINAPI GlobalPageLock16(HGLOBAL16);
WORD WINAPI GlobalPageUnlock16(HGLOBAL16); WORD WINAPI GlobalPageUnlock16(HGLOBAL16);
SEGPTR WINAPI HasGPHandler16(SEGPTR);
BOOL16 WINAPI IsSharedSelector16(HANDLE16); BOOL16 WINAPI IsSharedSelector16(HANDLE16);
BOOL16 WINAPI IsTask16(HTASK16); BOOL16 WINAPI IsTask16(HTASK16);
HTASK16 WINAPI IsTaskLocked16(void); HTASK16 WINAPI IsTaskLocked16(void);
...@@ -392,11 +393,6 @@ BOOL16 WINAPI WritePrivateProfileSection16(LPCSTR,LPCSTR,LPCSTR); ...@@ -392,11 +393,6 @@ BOOL16 WINAPI WritePrivateProfileSection16(LPCSTR,LPCSTR,LPCSTR);
BOOL16 WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR); BOOL16 WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR);
BOOL16 WINAPI WriteProfileSection16(LPCSTR,LPCSTR); BOOL16 WINAPI WriteProfileSection16(LPCSTR,LPCSTR);
/* Wine-specific functions */
LONG WINAPI wine_call_to_16( FARPROC16 target, INT nArgs );
void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, INT nArgs );
void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, INT nArgs );
/* Some optimizations */ /* Some optimizations */
extern inline LPVOID WINAPI MapSL( SEGPTR segptr ) extern inline LPVOID WINAPI MapSL( SEGPTR segptr )
{ {
......
...@@ -140,6 +140,10 @@ BOOL WINAPI K32WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD); ...@@ -140,6 +140,10 @@ BOOL WINAPI K32WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD);
#define WCB16_CDECL 1 #define WCB16_CDECL 1
#define WCB16_MAX_CBARGS 16 #define WCB16_MAX_CBARGS 16
/* Wine extensions: call register function, context ptr is passed in the return value LPDWORD */
#define WCB16_REGS 2
#define WCB16_REGS_LONG 4 /* function uses 32-bit lret */
DWORD WINAPI WOWCallback16(DWORD,DWORD); DWORD WINAPI WOWCallback16(DWORD,DWORD);
BOOL WINAPI WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD); BOOL WINAPI WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD);
......
...@@ -485,8 +485,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) ...@@ -485,8 +485,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
/* Save the 32-bit registers */ /* Save the 32-bit registers */
fprintf( outfile, "\tpushl %%ebx\n" ); fprintf( outfile, "\tpushl %%ebx\n" );
fprintf( outfile, "\tpushl %%ecx\n" );
fprintf( outfile, "\tpushl %%edx\n" );
fprintf( outfile, "\tpushl %%esi\n" ); fprintf( outfile, "\tpushl %%esi\n" );
fprintf( outfile, "\tpushl %%edi\n" ); fprintf( outfile, "\tpushl %%edi\n" );
fprintf( outfile, "\t.byte 0x64\n\tmovl %%gs,(%d)\n", STRUCTOFFSET(TEB,gs_sel) ); fprintf( outfile, "\t.byte 0x64\n\tmovl %%gs,(%d)\n", STRUCTOFFSET(TEB,gs_sel) );
...@@ -500,28 +498,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) ...@@ -500,28 +498,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L%s.getgot1], %%ebx\n", name ); fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L%s.getgot1], %%ebx\n", name );
} }
/* Print debugging info */
if (debugging)
{
/* Push flags, number of arguments, and target */
fprintf( outfile, "\tpushl $%d\n", reg_func );
fprintf( outfile, "\tpushl 12(%%ebp)\n" );
fprintf( outfile, "\tpushl 8(%%ebp)\n" );
if ( UsePIC )
fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16@PLT") "\n" );
else
fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16") "\n" );
fprintf( outfile, "\taddl $12, %%esp\n" );
}
/* Enter Win16 Mutex */
if ( UsePIC )
fprintf( outfile, "\tcall " __ASM_NAME("_EnterWin16Lock@PLT") "\n" );
else
fprintf( outfile, "\tcall " __ASM_NAME("_EnterWin16Lock") "\n" );
/* Setup exception frame */ /* Setup exception frame */
fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET ); fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET );
if (UsePIC) if (UsePIC)
...@@ -551,10 +527,10 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) ...@@ -551,10 +527,10 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
if ( !reg_func ) if ( !reg_func )
{ {
/* Convert and push return value */ /* Convert return value */
fprintf( outfile, "\tshll $16,%%edx\n" ); fprintf( outfile, "\tshll $16,%%edx\n" );
fprintf( outfile, "\tmovw %%ax,%%dx\n" ); fprintf( outfile, "\tmovw %%ax,%%dx\n" );
fprintf( outfile, "\tpushl %%edx\n" ); fprintf( outfile, "\tmovl %%edx,%%eax\n" );
} }
else else
{ {
...@@ -578,46 +554,11 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) ...@@ -578,46 +554,11 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
fprintf( outfile, "\tmovl %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) ); fprintf( outfile, "\tmovl %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) );
fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) ); fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) );
/* The return glue code saved %esp into %esi */ /* The return glue code saved %esp into %esi */
fprintf( outfile, "\tpushl %%edi\n" );
}
if ( UsePIC )
{
/* Get Global Offset Table into %ebx (might have been overwritten) */
fprintf( outfile, "\tcall .L%s.getgot2\n", name );
fprintf( outfile, ".L%s.getgot2:\n", name );
fprintf( outfile, "\tpopl %%ebx\n" );
fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L%s.getgot2], %%ebx\n", name );
}
/* Leave Win16 Mutex */
if ( UsePIC )
fprintf( outfile, "\tcall " __ASM_NAME("_LeaveWin16Lock@PLT") "\n" );
else
fprintf( outfile, "\tcall " __ASM_NAME("_LeaveWin16Lock") "\n" );
/* Print debugging info */
if (debugging)
{
fprintf( outfile, "\tpushl $%d\n", reg_func );
if ( UsePIC )
fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16Ret@PLT") "\n" );
else
fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16Ret") "\n" );
fprintf( outfile, "\taddl $4, %%esp\n" );
} }
/* Get return value */
fprintf( outfile, "\tpopl %%eax\n" );
/* Restore the 32-bit registers */ /* Restore the 32-bit registers */
fprintf( outfile, "\tpopl %%edi\n" ); fprintf( outfile, "\tpopl %%edi\n" );
fprintf( outfile, "\tpopl %%esi\n" ); fprintf( outfile, "\tpopl %%esi\n" );
fprintf( outfile, "\tpopl %%edx\n" );
fprintf( outfile, "\tpopl %%ecx\n" );
fprintf( outfile, "\tpopl %%ebx\n" ); fprintf( outfile, "\tpopl %%ebx\n" );
/* Function exit sequence */ /* Function exit sequence */
......
...@@ -244,7 +244,7 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, ...@@ -244,7 +244,7 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
{ {
CONTEXT86 context; CONTEXT86 context;
LRESULT ret; LRESULT ret;
WORD *args; WORD args[5];
DWORD offset = 0; DWORD offset = 0;
TEB *teb = NtCurrentTeb(); TEB *teb = NtCurrentTeb();
int iWndsLocks; int iWndsLocks;
...@@ -287,15 +287,14 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, ...@@ -287,15 +287,14 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
iWndsLocks = WIN_SuspendWndsLock(); iWndsLocks = WIN_SuspendWndsLock();
args = (WORD *)THREAD_STACK16(teb) - 5;
args[0] = LOWORD(lParam);
args[1] = HIWORD(lParam);
args[2] = wParam;
args[3] = msg;
args[4] = hwnd; args[4] = hwnd;
args[3] = msg;
wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) ); args[2] = wParam;
args[1] = HIWORD(lParam);
args[0] = LOWORD(lParam);
WOWCallback16Ex( 0, WCB16_REGS, sizeof(args), args, (DWORD *)&context );
ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) ); ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
if (offset) stack16_pop( offset ); if (offset) stack16_pop( offset );
WIN_RestoreWndsLock(iWndsLocks); WIN_RestoreWndsLock(iWndsLocks);
......
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