Moved most of the implementation of CALL32_CBClient(Ex) to the C

code.
This commit is contained in:
Alexandre Julliard 2005-07-01 16:24:32 +00:00
parent 89503c182a
commit 71914125ce
4 changed files with 42 additions and 118 deletions

View file

@ -224,4 +224,7 @@ extern HTASK16 TASK_GetTaskFromThread( DWORD thread );
extern TDB *TASK_GetCurrent(void);
extern void TASK_InstallTHHook( THHOOK *pNewThook );
extern SEGPTR CALL32_CBClient_RetAddr;
extern SEGPTR CALL32_CBClientEx_RetAddr;
#endif /* __WINE_KERNEL16_PRIVATE_H */

View file

@ -144,6 +144,9 @@ struct SLApiDB
DWORD errorReturnValue;
};
SEGPTR CALL32_CBClient_RetAddr = 0;
SEGPTR CALL32_CBClientEx_RetAddr = 0;
#ifdef __i386__
extern void __wine_call_from_16_thunk();
#else
@ -1997,7 +2000,7 @@ void WINAPI CBClientGlueSL( CONTEXT86 *context )
/***********************************************************************
* CBClientThunkSL (KERNEL.620)
*/
extern DWORD CALL32_CBClient( FARPROC proc, LPWORD args, DWORD *esi );
extern DWORD CALL32_CBClient( FARPROC proc, LPWORD args, WORD *stackLin, DWORD *esi );
void WINAPI CBClientThunkSL( CONTEXT86 *context )
{
/* Call 32-bit relay code */
@ -2005,13 +2008,24 @@ void WINAPI CBClientThunkSL( CONTEXT86 *context )
LPWORD args = MapSL( MAKESEGPTR( context->SegSs, LOWORD(context->Ebp) ) );
FARPROC proc = CBClientRelay32[ args[2] ][ args[1] ];
context->Eax = CALL32_CBClient( proc, args, &context->Esi );
/* fill temporary area for the asm code (see comments in winebuild) */
SEGPTR stack = stack16_push( 12 );
LPWORD stackLin = MapSL(stack);
/* stackLin[0] and stackLin[1] reserved for the 32-bit stack ptr */
stackLin[2] = wine_get_ss();
stackLin[3] = 0;
stackLin[4] = OFFSETOF(stack) + 12;
stackLin[5] = SELECTOROF(stack);
stackLin[6] = OFFSETOF(CALL32_CBClientEx_RetAddr); /* overwrite return address */
stackLin[7] = SELECTOROF(CALL32_CBClientEx_RetAddr);
context->Eax = CALL32_CBClient( proc, args, stackLin + 4, &context->Esi );
stack16_pop( 12 );
}
/***********************************************************************
* CBClientThunkSLEx (KERNEL.621)
*/
extern DWORD CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArgs );
extern DWORD CALL32_CBClientEx( FARPROC proc, LPWORD args, WORD *stackLin, DWORD *esi, INT *nArgs );
void WINAPI CBClientThunkSLEx( CONTEXT86 *context )
{
/* Call 32-bit relay code */
@ -2021,7 +2035,21 @@ void WINAPI CBClientThunkSLEx( CONTEXT86 *context )
INT nArgs;
LPWORD stackLin;
context->Eax = CALL32_CBClientEx( proc, args, &context->Esi, &nArgs );
/* fill temporary area for the asm code (see comments in winebuild) */
SEGPTR stack = stack16_push( 24 );
stackLin = MapSL(stack);
stackLin[0] = OFFSETOF(stack) + 4;
stackLin[1] = SELECTOROF(stack);
stackLin[2] = wine_get_ds();
stackLin[5] = OFFSETOF(stack) + 24;
/* stackLin[6] and stackLin[7] reserved for the 32-bit stack ptr */
stackLin[8] = wine_get_ss();
stackLin[9] = 0;
stackLin[10] = OFFSETOF(CALL32_CBClientEx_RetAddr);
stackLin[11] = SELECTOROF(CALL32_CBClientEx_RetAddr);
context->Eax = CALL32_CBClientEx( proc, args, stackLin, &context->Esi, &nArgs );
stack16_pop( 24 );
/* Restore registers saved by CBClientGlueSL */
stackLin = (LPWORD)((LPBYTE)CURRENT_STACK16 + sizeof(STACK16FRAME) - 4);

View file

@ -85,8 +85,6 @@ extern void DPMI_PendingEventCheck();
extern void DPMI_PendingEventCheck_Cleanup();
extern void DPMI_PendingEventCheck_Return();
extern DWORD CallTo16_DataSelector;
extern SEGPTR CALL32_CBClient_RetAddr;
extern SEGPTR CALL32_CBClientEx_RetAddr;
extern BYTE Call16_Start;
extern BYTE Call16_End;

View file

@ -743,7 +743,6 @@ static void BuildRet16Func( FILE *outfile )
static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
{
const char *name = isEx? "CALL32_CBClientEx" : "CALL32_CBClient";
int size = isEx? 24 : 12;
/* Function header */
@ -759,106 +758,21 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
fprintf( outfile, "\tpushl %%esi\n" );
fprintf( outfile, "\tpushl %%ebx\n" );
if (UsePIC)
{
/* Get Global Offset Table into %edx */
fprintf( outfile, "\tcall .L__wine_%s.getgot1\n", name );
fprintf( outfile, ".L__wine_%s.getgot1:\n", name );
fprintf( outfile, "\tpopl %%edx\n" );
fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L__wine_%s.getgot1], %%edx\n", name );
}
/* Get pointer to temporary area and save the 32-bit stack pointer */
/* Get the 16-bit stack */
fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%ebx\n", STACKOFFSET);
/* Convert it to a flat address */
fprintf( outfile, "\tshldl $16,%%ebx,%%eax\n" );
fprintf( outfile, "\tandl $0xfff8,%%eax\n" );
fprintf( outfile, "\tshrl $1,%%eax\n" );
if (!UsePIC)
fprintf( outfile, "\tmovl %s(%%eax),%%esi\n", asm_name("wine_ldt_copy") );
else
{
fprintf( outfile, "\tmovl %s(%%edx), %%esi\n", asm_name("wine_ldt_copy@GOT") );
fprintf( outfile, "\tmovl (%%esi,%%eax), %%esi\n" );
}
fprintf( outfile, "\tmovw %%bx,%%ax\n" );
fprintf( outfile, "\taddl %%eax,%%esi\n" );
/* Allocate temporary area (simulate STACK16_PUSH) */
fprintf( outfile, "\tpushf\n" );
fprintf( outfile, "\tcld\n" );
fprintf( outfile, "\tleal -%d(%%esi), %%edi\n", size );
fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) );
fprintf( outfile, "\trep\n\tmovsb\n" );
fprintf( outfile, "\tpopf\n" );
fprintf( outfile, "\t.byte 0x64\n\tsubw $%d,(%d)\n", size, STACKOFFSET );
fprintf( outfile, "\tpushl %%edi\n" ); /* remember address */
/* Set up temporary area */
fprintf( outfile, "\tmovl 16(%%ebp), %%ebx\n" );
fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
if ( !isEx )
{
fprintf( outfile, "\tleal 4(%%edi), %%edi\n" );
fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
fprintf( outfile, "\tmovl %%eax, -8(%%edi)\n" ); /* 32-bit sp */
fprintf( outfile, "\tmovw %%ss, %%ax\n" );
fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" );
fprintf( outfile, "\tmovl %%eax, -4(%%edi)\n" ); /* 32-bit ss */
fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 + 4 );
fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" ); /* 16-bit ss:sp */
if (!UsePIC)
fprintf( outfile, "\tmovl %s_RetAddr, %%eax\n", asm_name(name) );
else
{
fprintf( outfile, "\tmovl %s_RetAddr@GOT(%%edx), %%eax\n", asm_name(name) );
fprintf( outfile, "\tmovl (%%eax), %%eax\n" );
}
fprintf( outfile, "\tmovl %%eax, 4(%%edi)\n" ); /* overwrite return address */
}
fprintf( outfile, "\tmovl %%eax, -8(%%ebx)\n" );
else
{
fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-size+4 );
fprintf( outfile, "\tmovl %%ebx, 0(%%edi)\n" );
fprintf( outfile, "\tmovw %%ds, %%ax\n" );
fprintf( outfile, "\tmovw %%ax, 4(%%edi)\n" );
fprintf( outfile, "\taddl $20, %%ebx\n" );
fprintf( outfile, "\tmovw %%bx, 10(%%edi)\n" );
fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
fprintf( outfile, "\tmovl %%eax, 12(%%edi)\n" );
fprintf( outfile, "\tmovw %%ss, %%ax\n" );
fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" );
fprintf( outfile, "\tmovl %%eax, 16(%%edi)\n" );
if (!UsePIC)
fprintf( outfile, "\tmovl %s_RetAddr, %%eax\n", asm_name(name) );
else
{
fprintf( outfile, "\tmovl %s_RetAddr@GOT(%%edx), %%eax\n", asm_name(name) );
fprintf( outfile, "\tmovl (%%eax), %%eax\n" );
}
fprintf( outfile, "\tmovl %%eax, 20(%%edi)\n" );
}
fprintf( outfile, "\tmovl %%eax, 12(%%ebx)\n" );
/* Set up registers and call CBClient relay stub (simulating a far call) */
fprintf( outfile, "\tmovl 16(%%ebp), %%esi\n" );
fprintf( outfile, "\tmovl 20(%%ebp), %%esi\n" );
fprintf( outfile, "\tmovl (%%esi), %%esi\n" );
fprintf( outfile, "\tmovl %%edi, %%ebx\n" );
fprintf( outfile, "\tmovl 8(%%ebp), %%eax\n" );
fprintf( outfile, "\tmovl 12(%%ebp), %%ebp\n" );
@ -870,24 +784,10 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
fprintf( outfile, "\tmovl 32(%%esp), %%edi\n" );
fprintf( outfile, "\tmovl %%esi, (%%edi)\n" );
/* Cleanup temporary area (simulate STACK16_POP) */
fprintf( outfile, "\tpop %%esi\n" );
fprintf( outfile, "\tpushf\n" );
fprintf( outfile, "\tstd\n" );
fprintf( outfile, "\tdec %%esi\n" );
fprintf( outfile, "\tleal %d(%%esi), %%edi\n", size );
fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) );
fprintf( outfile, "\trep\n\tmovsb\n" );
fprintf( outfile, "\tpopf\n" );
fprintf( outfile, "\t.byte 0x64\n\taddw $%d,(%d)\n", size, STACKOFFSET );
/* Return argument size to caller */
if ( isEx )
{
fprintf( outfile, "\tmovl 32(%%esp), %%ebx\n" );
fprintf( outfile, "\tmovl 36(%%esp), %%ebx\n" );
fprintf( outfile, "\tmovl %%ebp, (%%ebx)\n" );
}
@ -924,11 +824,6 @@ static void BuildCallTo32CBClientRet( FILE *outfile, BOOL isEx )
}
fprintf( outfile, "\tlret\n" );
function_footer( outfile, name );
/* Declare the return address variable */
fprintf( outfile, "\n\t.globl %sAddr\n", asm_name(name) );
fprintf( outfile, "%sAddr:\t.long 0\n", asm_name(name) );
}