Moved 16-bit calls initialization and exception handling to kernel32.
Store the call_to_16 return address on the stack from the C code so that we don't need two variants of call_to_16_regs.
This commit is contained in:
parent
d631f30945
commit
3be5d62b29
|
@ -41,10 +41,10 @@
|
|||
#include "thread.h"
|
||||
#include "stackframe.h"
|
||||
#include "wincon.h"
|
||||
#include "kernel_private.h"
|
||||
#include "console_private.h"
|
||||
|
||||
extern void LOCALE_Init(void);
|
||||
extern BOOL RELAY_Init(void);
|
||||
extern void COMPUTERNAME_Init(void);
|
||||
|
||||
extern int __wine_set_signal_handler(unsigned, int (*)(unsigned));
|
||||
|
@ -115,8 +115,8 @@ static BOOL process_attach(void)
|
|||
/* Setup codepage info */
|
||||
LOCALE_Init();
|
||||
|
||||
/* Initialize relay entry points */
|
||||
if (!RELAY_Init()) return FALSE;
|
||||
/* Initialize 16-bit thunking entry points */
|
||||
if (!WOWTHUNK_Init()) return FALSE;
|
||||
|
||||
/* Initialize DOS memory */
|
||||
if (!DOSMEM_Init(0)) return FALSE;
|
||||
|
|
|
@ -49,4 +49,6 @@ static inline HANDLE console_handle_unmap(HANDLE h)
|
|||
extern HANDLE dos_handles[DOS_TABLE_SIZE];
|
||||
void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing );
|
||||
|
||||
extern BOOL WOWTHUNK_Init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,12 +27,14 @@
|
|||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wownt32.h"
|
||||
#include "excpt.h"
|
||||
#include "winternl.h"
|
||||
#include "syslevel.h"
|
||||
#include "file.h"
|
||||
#include "task.h"
|
||||
#include "miscemu.h"
|
||||
#include "stackframe.h"
|
||||
#include "wine/exception.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(thunk);
|
||||
|
@ -70,6 +72,86 @@ static DWORD CALLBACK start_thread16( LPVOID threadArgs )
|
|||
return K32WOWCallback16( (DWORD)args.proc, args.param );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
/* symbols exported from relay16.s */
|
||||
extern DWORD WINAPI wine_call_to_16( FARPROC16 target, DWORD cbArgs, PEXCEPTION_HANDLER handler );
|
||||
extern void WINAPI wine_call_to_16_regs( CONTEXT86 *context, DWORD cbArgs, PEXCEPTION_HANDLER handler );
|
||||
extern void Call16_Ret_Start(), Call16_Ret_End();
|
||||
extern void CallTo16_Ret();
|
||||
extern void CALL32_CBClient_Ret();
|
||||
extern void CALL32_CBClientEx_Ret();
|
||||
extern DWORD CallTo16_DataSelector;
|
||||
extern SEGPTR CALL32_CBClient_RetAddr;
|
||||
extern SEGPTR CALL32_CBClientEx_RetAddr;
|
||||
|
||||
static SEGPTR call16_ret_addr; /* segptr to CallTo16_Ret routine */
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* WOWTHUNK_Init
|
||||
*/
|
||||
BOOL WOWTHUNK_Init(void)
|
||||
{
|
||||
#ifdef __i386__
|
||||
/* allocate the code selector for CallTo16 routines */
|
||||
WORD codesel = SELECTOR_AllocBlock( (void *)Call16_Ret_Start,
|
||||
(char *)Call16_Ret_End - (char *)Call16_Ret_Start,
|
||||
WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
|
||||
if (!codesel) return FALSE;
|
||||
|
||||
/* Patch the return addresses for CallTo16 routines */
|
||||
|
||||
CallTo16_DataSelector = wine_get_ds();
|
||||
call16_ret_addr = MAKESEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start );
|
||||
CALL32_CBClient_RetAddr =
|
||||
MAKESEGPTR( codesel, (char*)CALL32_CBClient_Ret - (char*)Call16_Ret_Start );
|
||||
CALL32_CBClientEx_RetAddr =
|
||||
MAKESEGPTR( codesel, (char*)CALL32_CBClientEx_Ret - (char*)Call16_Ret_Start );
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* call16_handler
|
||||
*
|
||||
* Handler for exceptions occurring in 16-bit code.
|
||||
*/
|
||||
static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
|
||||
CONTEXT *context, EXCEPTION_FRAME **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
||||
{
|
||||
/* unwinding: restore the stack pointer in the TEB, and leave the Win16 mutex */
|
||||
STACK32FRAME *frame32 = (STACK32FRAME *)((char *)frame - offsetof(STACK32FRAME,frame));
|
||||
NtCurrentTeb()->cur_stack = frame32->frame16;
|
||||
_LeaveWin16Lock();
|
||||
}
|
||||
else if (!IS_SELECTOR_SYSTEM(context->SegCs)) /* check for Win16 __GP handler */
|
||||
{
|
||||
SEGPTR gpHandler = HasGPHandler16( MAKESEGPTR( context->SegCs, context->Eip ) );
|
||||
if (gpHandler)
|
||||
{
|
||||
WORD *stack = wine_ldt_get_ptr( context->SegSs, context->Esp );
|
||||
*--stack = context->SegCs;
|
||||
*--stack = context->Eip;
|
||||
|
||||
if (!IS_SELECTOR_32BIT(context->SegSs))
|
||||
context->Esp = MAKELONG( LOWORD(context->Esp - 2*sizeof(WORD)),
|
||||
HIWORD(context->Esp) );
|
||||
else
|
||||
context->Esp -= 2*sizeof(WORD);
|
||||
|
||||
context->SegCs = SELECTOROF( gpHandler );
|
||||
context->Eip = OFFSETOF( gpHandler );
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
}
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 32-bit WOW routines (in WOW32, but actually forwarded to KERNEL32)
|
||||
*/
|
||||
|
@ -295,16 +377,14 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
|||
DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode )
|
||||
{
|
||||
#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
|
||||
* (both for PASCAL and CDECL calling convention), so we simply
|
||||
* copy them to the 16-bit stack ...
|
||||
*/
|
||||
memcpy( (LPBYTE)CURRENT_STACK16 - cbArgs, (LPBYTE)pArgs, cbArgs );
|
||||
WORD *stack = (WORD *)CURRENT_STACK16 - cbArgs / sizeof(WORD);
|
||||
|
||||
memcpy( stack, pArgs, cbArgs );
|
||||
|
||||
if (dwFlags & (WCB16_REGS|WCB16_REGS_LONG))
|
||||
{
|
||||
|
@ -312,13 +392,12 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
|||
|
||||
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 );
|
||||
while (count) DPRINTF( ",%04x", stack[--count] );
|
||||
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",
|
||||
|
@ -328,11 +407,21 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
|||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
}
|
||||
|
||||
_EnterWin16Lock();
|
||||
/* push return address */
|
||||
if (dwFlags & WCB16_REGS_LONG)
|
||||
wine_call_to_16_regs_long( context, cbArgs );
|
||||
{
|
||||
*((DWORD *)stack - 1) = HIWORD(call16_ret_addr);
|
||||
*((DWORD *)stack - 2) = LOWORD(call16_ret_addr);
|
||||
cbArgs += 2 * sizeof(DWORD);
|
||||
}
|
||||
else
|
||||
wine_call_to_16_regs_short( context, cbArgs );
|
||||
{
|
||||
*((SEGPTR *)stack - 1) = call16_ret_addr;
|
||||
cbArgs += sizeof(SEGPTR);
|
||||
}
|
||||
|
||||
_EnterWin16Lock();
|
||||
wine_call_to_16_regs( context, cbArgs, call16_handler );
|
||||
_LeaveWin16Lock();
|
||||
|
||||
if (TRACE_ON(relay))
|
||||
|
@ -352,18 +441,21 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
|||
|
||||
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 );
|
||||
while (count) DPRINTF( ",%04x", stack[--count] );
|
||||
DPRINTF(") ss:sp=%04x:%04x\n",
|
||||
SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) );
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
}
|
||||
|
||||
/* push return address */
|
||||
*((SEGPTR *)stack - 1) = call16_ret_addr;
|
||||
cbArgs += sizeof(SEGPTR);
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -371,7 +463,7 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
|||
* stack pointer is always reset to the position it had before.
|
||||
*/
|
||||
_EnterWin16Lock();
|
||||
ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs );
|
||||
ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs, call16_handler );
|
||||
if (pdwRetCode) *pdwRetCode = ret;
|
||||
_LeaveWin16Lock();
|
||||
|
||||
|
|
|
@ -27,10 +27,7 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "global.h"
|
||||
#include "wine/exception.h"
|
||||
#include "stackframe.h"
|
||||
#include "miscemu.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
#include "excpt.h"
|
||||
|
@ -410,22 +407,3 @@ DWORD __wine_finally_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
|
|||
}
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* __wine_callto16_handler
|
||||
*
|
||||
* Handler for exceptions occurring in 16-bit code.
|
||||
*/
|
||||
DWORD __wine_callto16_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
|
||||
CONTEXT *context, LPVOID pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
||||
{
|
||||
/* unwinding: restore the stack pointer in the TEB, and leave the Win16 mutex */
|
||||
STACK32FRAME *frame32 = (STACK32FRAME *)((char *)frame - offsetof(STACK32FRAME,frame));
|
||||
NtCurrentTeb()->cur_stack = frame32->frame16;
|
||||
_LeaveWin16Lock();
|
||||
}
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
|
|
@ -37,43 +37,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(relay);
|
||||
|
||||
/***********************************************************************
|
||||
* RELAY_Init
|
||||
*/
|
||||
BOOL RELAY_Init(void)
|
||||
{
|
||||
#ifdef __i386__
|
||||
WORD codesel;
|
||||
|
||||
/* Allocate the code selector for CallTo16 routines */
|
||||
|
||||
extern void Call16_Ret_Start(), Call16_Ret_End();
|
||||
extern void CallTo16_Ret();
|
||||
extern void CALL32_CBClient_Ret();
|
||||
extern void CALL32_CBClientEx_Ret();
|
||||
extern SEGPTR CallTo16_RetAddr;
|
||||
extern DWORD CallTo16_DataSelector;
|
||||
extern SEGPTR CALL32_CBClient_RetAddr;
|
||||
extern SEGPTR CALL32_CBClientEx_RetAddr;
|
||||
|
||||
codesel = SELECTOR_AllocBlock( (void *)Call16_Ret_Start,
|
||||
(char *)Call16_Ret_End - (char *)Call16_Ret_Start,
|
||||
WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
|
||||
if (!codesel) return FALSE;
|
||||
|
||||
/* Patch the return addresses for CallTo16 routines */
|
||||
|
||||
CallTo16_DataSelector = wine_get_ds();
|
||||
CallTo16_RetAddr =
|
||||
MAKESEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start );
|
||||
CALL32_CBClient_RetAddr =
|
||||
MAKESEGPTR( codesel, (char*)CALL32_CBClient_Ret - (char*)Call16_Ret_Start );
|
||||
CALL32_CBClientEx_RetAddr =
|
||||
MAKESEGPTR( codesel, (char*)CALL32_CBClientEx_Ret - (char*)Call16_Ret_Start );
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stubs for the CallTo16/CallFrom16 routines on non-Intel architectures
|
||||
* (these will never be called but need to be present to satisfy the linker ...)
|
||||
|
|
|
@ -181,7 +181,6 @@ extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved );
|
|||
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
|
||||
extern enum binary_type MODULE_GetBinaryType( HANDLE hfile );
|
||||
extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
|
||||
extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
|
||||
extern void MODULE_WalkModref( DWORD id );
|
||||
|
||||
/* loader/ne/module.c */
|
||||
|
|
|
@ -810,24 +810,6 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check for Win16 __GP handler */
|
||||
if (!IS_SELECTOR_SYSTEM(context->SegCs))
|
||||
{
|
||||
SEGPTR gpHandler = HasGPHandler16( MAKESEGPTR( context->SegCs, context->Eip ) );
|
||||
if (gpHandler)
|
||||
{
|
||||
WORD *stack = get_stack( context );
|
||||
*--stack = context->SegCs;
|
||||
*--stack = context->Eip;
|
||||
add_stack(context, -2*sizeof(WORD));
|
||||
|
||||
context->SegCs = SELECTOROF( gpHandler );
|
||||
context->Eip = OFFSETOF( gpHandler );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return ret; /* Unable to emulate it */
|
||||
}
|
||||
|
||||
|
|
|
@ -449,32 +449,23 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
|||
*
|
||||
* This routine builds the core routines used in 32->16 thunks:
|
||||
*
|
||||
* extern LONG WINAPI wine_call_to_16( SEGPTR target, int nb_args );
|
||||
* extern void WINAPI wine_call_to_16_regs_short( const CONTEXT86 *context, int nb_args );
|
||||
* extern void WINAPI wine_call_to_16_regs_long ( const CONTEXT86 *context, int nb_args );
|
||||
* extern DWORD WINAPI wine_call_to_16( FARPROC16 target, DWORD cbArgs, PEXCEPTION_HANDLER handler );
|
||||
* extern void WINAPI wine_call_to_16_regs( CONTEXT86 *context, DWORD cbArgs, PEXCEPTION_HANDLER handler );
|
||||
*
|
||||
* These routines can be called directly from 32-bit code.
|
||||
*
|
||||
* All routines expect that the 16-bit stack contents (arguments) were
|
||||
* already set up by the caller; nb_args must contain the number of bytes
|
||||
* to be conserved. The 16-bit SS:SP will be set accordinly.
|
||||
* All routines expect that the 16-bit stack contents (arguments) and the
|
||||
* return address (segptr to CallTo16_Ret) were already set up by the
|
||||
* caller; nb_args must contain the number of bytes to be conserved. The
|
||||
* 16-bit SS:SP will be set accordinly.
|
||||
*
|
||||
* All other registers are either taken from the CONTEXT86 structure
|
||||
* or else set to default values. The target routine address is either
|
||||
* given directly or taken from the CONTEXT86.
|
||||
*
|
||||
* If you want to call a 16-bit routine taking only standard argument types
|
||||
* (WORD and LONG), you can also have an appropriate argument conversion
|
||||
* stub automatically generated (see BuildCallTo16); you'd then call this
|
||||
* stub, which in turn would prepare the 16-bit stack and call the appropiate
|
||||
* core routine.
|
||||
*
|
||||
*/
|
||||
static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
||||
{
|
||||
const char *name = reg_func == 2 ? "wine_call_to_16_regs_long" :
|
||||
reg_func == 1 ? "wine_call_to_16_regs_short" :
|
||||
"wine_call_to_16";
|
||||
const char *name = reg_func ? "wine_call_to_16_regs" : "wine_call_to_16";
|
||||
|
||||
/* Function header */
|
||||
function_header( outfile, name );
|
||||
|
@ -489,33 +480,12 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
|||
fprintf( outfile, "\tpushl %%edi\n" );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovl %%gs,(%d)\n", STRUCTOFFSET(TEB,gs_sel) );
|
||||
|
||||
if ( UsePIC )
|
||||
{
|
||||
/* Get Global Offset Table into %ebx */
|
||||
fprintf( outfile, "\tcall .L%s.getgot1\n", name );
|
||||
fprintf( outfile, ".L%s.getgot1:\n", name );
|
||||
fprintf( outfile, "\tpopl %%ebx\n" );
|
||||
fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L%s.getgot1], %%ebx\n", name );
|
||||
}
|
||||
|
||||
/* Setup exception frame */
|
||||
fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET );
|
||||
if (UsePIC)
|
||||
fprintf( outfile, "\tpushl " __ASM_NAME("__wine_callto16_handler@GOT") "(%%ebx)\n" );
|
||||
else
|
||||
fprintf( outfile, "\tpushl $" __ASM_NAME("__wine_callto16_handler") "\n" );
|
||||
fprintf( outfile, "\tpushl 16(%%ebp)\n" ); /* handler */
|
||||
fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STRUCTOFFSET(TEB,except) );
|
||||
fprintf( outfile, "\t.byte 0x64\n\tmovl %%esp,(%d)\n", STRUCTOFFSET(TEB,except) );
|
||||
|
||||
/* Get return address */
|
||||
if ( UsePIC )
|
||||
{
|
||||
fprintf( outfile, "\tmovl " __ASM_NAME("CallTo16_RetAddr@GOT") "(%%ebx), %%ecx\n" );
|
||||
fprintf( outfile, "\tmovl (%%ecx), %%ecx\n" );
|
||||
}
|
||||
else
|
||||
fprintf( outfile, "\tmovl " __ASM_NAME("CallTo16_RetAddr") ", %%ecx\n" );
|
||||
|
||||
/* Call the actual CallTo16 routine (simulate a lcall) */
|
||||
fprintf( outfile, "\tpushl %%cs\n" );
|
||||
fprintf( outfile, "\tcall .L%s\n", name );
|
||||
|
@ -528,9 +498,9 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
|||
if ( !reg_func )
|
||||
{
|
||||
/* Convert return value */
|
||||
fprintf( outfile, "\tandl $0xffff,%%eax\n" );
|
||||
fprintf( outfile, "\tshll $16,%%edx\n" );
|
||||
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
||||
fprintf( outfile, "\tmovl %%edx,%%eax\n" );
|
||||
fprintf( outfile, "\torl %%edx,%%eax\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -563,7 +533,7 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
|||
|
||||
/* Function exit sequence */
|
||||
fprintf( outfile, "\tpopl %%ebp\n" );
|
||||
fprintf( outfile, "\tret $8\n" );
|
||||
fprintf( outfile, "\tret $12\n" );
|
||||
|
||||
|
||||
/* Start of the actual CallTo16 routine */
|
||||
|
@ -586,21 +556,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
|||
/* Add the specified offset to the new sp */
|
||||
fprintf( outfile, "\tsubw %d(%%edx), %%sp\n", STACK32OFFSET(nb_args) );
|
||||
|
||||
/* Push the return address
|
||||
* With sreg suffix, we push 16:16 address (normal lret)
|
||||
* With lreg suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
|
||||
*/
|
||||
if (reg_func != 2)
|
||||
fprintf( outfile, "\tpushl %%ecx\n" );
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\tshldl $16, %%ecx, %%eax\n" );
|
||||
fprintf( outfile, "\tpushw $0\n" );
|
||||
fprintf( outfile, "\tpushw %%ax\n" );
|
||||
fprintf( outfile, "\tpushw $0\n" );
|
||||
fprintf( outfile, "\tpushw %%cx\n" );
|
||||
}
|
||||
|
||||
if (reg_func)
|
||||
{
|
||||
/* Push the called routine address */
|
||||
|
@ -700,8 +655,6 @@ static void BuildRet16Func( FILE *outfile )
|
|||
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
|
||||
fprintf( outfile, "\t.globl " __ASM_NAME("CallTo16_DataSelector") "\n" );
|
||||
fprintf( outfile, __ASM_NAME("CallTo16_DataSelector") ":\t.long 0\n" );
|
||||
fprintf( outfile, "\t.globl " __ASM_NAME("CallTo16_RetAddr") "\n" );
|
||||
fprintf( outfile, __ASM_NAME("CallTo16_RetAddr") ":\t.long 0\n" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1139,12 +1092,9 @@ void BuildRelays16( FILE *outfile )
|
|||
/* Standard CallTo16 routine */
|
||||
BuildCallTo16Core( outfile, 0 );
|
||||
|
||||
/* Register CallTo16 routine (16:16 retf) */
|
||||
/* Register CallTo16 routine */
|
||||
BuildCallTo16Core( outfile, 1 );
|
||||
|
||||
/* Register CallTo16 routine (16:32 retf) */
|
||||
BuildCallTo16Core( outfile, 2 );
|
||||
|
||||
/* CBClientThunkSL routine */
|
||||
BuildCallTo32CBClient( outfile, FALSE );
|
||||
|
||||
|
|
Loading…
Reference in New Issue