diff --git a/dlls/krnl386.exe16/kernel16_private.h b/dlls/krnl386.exe16/kernel16_private.h index 279058ac68f..7ce1921e40b 100644 --- a/dlls/krnl386.exe16/kernel16_private.h +++ b/dlls/krnl386.exe16/kernel16_private.h @@ -291,8 +291,9 @@ extern WORD DOSMEM_BiosDataSeg DECLSPEC_HIDDEN; extern WORD DOSMEM_BiosSysSeg DECLSPEC_HIDDEN; extern DWORD CallTo16_DataSelector DECLSPEC_HIDDEN; extern DWORD CallTo16_TebSelector DECLSPEC_HIDDEN; -extern SEGPTR CALL32_CBClient_RetAddr DECLSPEC_HIDDEN; -extern SEGPTR CALL32_CBClientEx_RetAddr DECLSPEC_HIDDEN; + +extern WORD cbclient_selector DECLSPEC_HIDDEN; +extern WORD cbclientex_selector DECLSPEC_HIDDEN; struct tagSYSLEVEL; diff --git a/dlls/krnl386.exe16/thunk.c b/dlls/krnl386.exe16/thunk.c index 21c2ce5c524..c8a247299b4 100644 --- a/dlls/krnl386.exe16/thunk.c +++ b/dlls/krnl386.exe16/thunk.c @@ -137,8 +137,8 @@ struct SLApiDB DWORD errorReturnValue; }; -SEGPTR CALL32_CBClient_RetAddr = 0; -SEGPTR CALL32_CBClientEx_RetAddr = 0; +WORD cbclient_selector = 0; +WORD cbclientex_selector = 0; extern int call_entry_point( void *func, int nb_args, const DWORD *args ); extern void __wine_call_from_16_thunk(void); @@ -2094,8 +2094,8 @@ void WINAPI CBClientThunkSL( CONTEXT *context ) stackLin[3] = 0; stackLin[4] = OFFSETOF(stack) + 12; stackLin[5] = SELECTOROF(stack); - stackLin[6] = OFFSETOF(CALL32_CBClient_RetAddr); /* overwrite return address */ - stackLin[7] = SELECTOROF(CALL32_CBClient_RetAddr); + stackLin[6] = 0; /* overwrite return address */ + stackLin[7] = cbclient_selector; context->Eax = CALL32_CBClient( proc, args, stackLin + 4, &context->Esi ); stack16_pop( 12 ); } @@ -2159,8 +2159,8 @@ void WINAPI CBClientThunkSLEx( CONTEXT *context ) /* stackLin[6] and stackLin[7] reserved for the 32-bit stack ptr */ stackLin[8] = get_ds(); stackLin[9] = 0; - stackLin[10] = OFFSETOF(CALL32_CBClientEx_RetAddr); - stackLin[11] = SELECTOROF(CALL32_CBClientEx_RetAddr); + stackLin[10] = 0; + stackLin[11] = cbclientex_selector; context->Eax = CALL32_CBClientEx( proc, args, stackLin, &context->Esi, &nArgs ); stack16_pop( 24 ); diff --git a/dlls/krnl386.exe16/wowthunk.c b/dlls/krnl386.exe16/wowthunk.c index 800f3c275a5..ca3c57f8e0b 100644 --- a/dlls/krnl386.exe16/wowthunk.c +++ b/dlls/krnl386.exe16/wowthunk.c @@ -30,6 +30,7 @@ #include "winternl.h" #include "ntgdi.h" #include "kernel16_private.h" +#include "wine/asm.h" #include "wine/exception.h" #include "wine/debug.h" @@ -41,13 +42,29 @@ WINE_DECLARE_DEBUG_CHANNEL(snoop); extern DWORD WINAPI wine_call_to_16( FARPROC16 target, DWORD cbArgs, PEXCEPTION_HANDLER handler ); extern void WINAPI wine_call_to_16_regs( CONTEXT *context, DWORD cbArgs, PEXCEPTION_HANDLER handler ); extern void __wine_call_to_16_ret(void); -extern void CALL32_CBClient_Ret(void); -extern void CALL32_CBClientEx_Ret(void); extern BYTE __wine_call16_start[]; extern BYTE __wine_call16_end[]; static SEGPTR call16_ret_addr; /* segptr to __wine_call_to_16_ret routine */ +extern const BYTE cbclient_ret[], cbclient_ret_end[]; +__ASM_GLOBAL_FUNC( cbclient_ret, + "movzwl %sp,%ebx\n\t" + "lssl %ss:-16(%ebx),%esp\n\t" + "lretl\n\t" + ".globl " __ASM_NAME("cbclient_ret_end") "\n" + __ASM_NAME("cbclient_ret_end") ":" ) + +extern const BYTE cbclientex_ret[], cbclientex_ret_end[]; +__ASM_GLOBAL_FUNC( cbclientex_ret, + "movzwl %bp,%ebx\n\t" + "subw %bp,%sp\n\t" + "movzwl %sp,%ebp\n\t" + "lssl %ss:-12(%ebx),%esp\n\t" + "lretl\n\t" + ".globl " __ASM_NAME("cbclientex_ret_end") "\n" + __ASM_NAME("cbclientex_ret_end") ":" ) + /*********************************************************************** * WOWTHUNK_Init */ @@ -57,16 +74,18 @@ BOOL WOWTHUNK_Init(void) WORD codesel = SELECTOR_AllocBlock( __wine_call16_start, (BYTE *)(&CallTo16_TebSelector + 1) - __wine_call16_start, LDT_FLAGS_CODE | LDT_FLAGS_32BIT ); - if (!codesel) return FALSE; + + cbclient_selector = SELECTOR_AllocBlock( cbclient_ret, cbclient_ret_end - cbclient_ret, + LDT_FLAGS_CODE | LDT_FLAGS_32BIT ); + cbclientex_selector = SELECTOR_AllocBlock( cbclientex_ret, cbclientex_ret_end - cbclientex_ret, + LDT_FLAGS_CODE | LDT_FLAGS_32BIT ); + if (!codesel || cbclient_selector || !cbclientex_selector) + return FALSE; /* Patch the return addresses for CallTo16 routines */ CallTo16_DataSelector = get_ds(); call16_ret_addr = MAKESEGPTR( codesel, (BYTE *)__wine_call_to_16_ret - __wine_call16_start ); - CALL32_CBClient_RetAddr = - MAKESEGPTR( codesel, (BYTE *)CALL32_CBClient_Ret - __wine_call16_start ); - CALL32_CBClientEx_RetAddr = - MAKESEGPTR( codesel, (BYTE *)CALL32_CBClientEx_Ret - __wine_call16_start ); if (TRACE_ON(relay) || TRACE_ON(snoop)) RELAY16_InitDebugLists(); diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c index eaa70888986..43a35af211c 100644 --- a/tools/winebuild/relay.c +++ b/tools/winebuild/relay.c @@ -564,28 +564,6 @@ static void BuildRet16Func(void) } -static void BuildCallTo32CBClient( int isEx ) -{ - /* '16-bit' return stub */ - - function_header( isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); - if ( !isEx ) - { - output( "\tmovzwl %%sp, %%ebx\n" ); - output( "\tlssl %%ss:-16(%%ebx), %%esp\n" ); - } - else - { - output( "\tmovzwl %%bp, %%ebx\n" ); - output( "\tsubw %%bp, %%sp\n" ); - output( "\tmovzwl %%sp, %%ebp\n" ); - output( "\tlssl %%ss:-12(%%ebx), %%esp\n" ); - } - output( "\tlret\n" ); - output_function_size( isEx ? "CALL32_CBClientEx_Ret" : "CALL32_CBClient_Ret" ); -} - - /******************************************************************* * output_asm_relays16 * @@ -618,12 +596,6 @@ void output_asm_relays16(void) /* Standard CallTo16 return stub */ BuildRet16Func(); - /* CBClientThunkSL routine */ - BuildCallTo32CBClient( 0 ); - - /* CBClientThunkSLEx routine */ - BuildCallTo32CBClient( 1 ); - output( "%s\n", asm_globl("__wine_call16_end") ); output_function_size( "__wine_spec_thunk_text_16" );