mirror of
https://github.com/reactos/wine.git
synced 2025-02-03 18:53:17 +00:00
Moved return value handling to the individual relay thunks so that we
only need one version of wine_call_from_16. Patch the wine_call_from_16 address along with the cs value directly in the 16-bit code segment to avoid the need for special magic in the import thunks.
This commit is contained in:
parent
2cf740619f
commit
96508ad686
@ -126,8 +126,8 @@ typedef struct
|
||||
BYTE lcall; /* lcall __FLATCS__:glue */
|
||||
void *glue;
|
||||
WORD flatcs;
|
||||
WORD lret; /* lret $nArgs */
|
||||
WORD nArgs;
|
||||
WORD ret[5]; /* return sequence */
|
||||
WORD movl; /* movl arg_types[1],arg_types[0](%esi) */
|
||||
DWORD arg_types[2]; /* type of each argument */
|
||||
} CALLFROM16;
|
||||
|
||||
@ -147,6 +147,9 @@ typedef struct _THHOOK
|
||||
HTASK16 LockTDB; /* 14 hLockedTask */
|
||||
} THHOOK;
|
||||
|
||||
extern LONG __wine_call_from_16();
|
||||
extern void __wine_call_from_16_regs();
|
||||
|
||||
extern THHOOK *pThhook;
|
||||
|
||||
#include "poppack.h"
|
||||
|
@ -1247,9 +1247,7 @@
|
||||
# 16-bit relays
|
||||
@ cdecl __wine_dll_register_16(ptr str)
|
||||
@ cdecl __wine_dll_unregister_16(ptr)
|
||||
@ varargs __wine_call_from_16_word()
|
||||
@ varargs __wine_call_from_16_long()
|
||||
@ varargs __wine_call_from_16_regs()
|
||||
@ varargs -private __wine_call_from_16_regs()
|
||||
|
||||
# Unix files
|
||||
@ cdecl wine_get_unix_file_name(wstr)
|
||||
|
@ -112,8 +112,15 @@ inline static void patch_code_segment( NE_MODULE *pModule )
|
||||
|
||||
call = GlobalLock16( pSeg->hSeg );
|
||||
|
||||
if (call->flatcs != wine_get_cs()) /* need to patch cs values */
|
||||
for (i = 0; call[i].pushl == 0x68; i++) call[i].flatcs = wine_get_cs();
|
||||
/* patch glue code address and code selector */
|
||||
for (i = 0; call[i].pushl == 0x68; i++)
|
||||
{
|
||||
if (call[i].ret[0] == 0xca66 || call[i].ret[0] == 0xcb66) /* register entry point? */
|
||||
call[i].glue = __wine_call_from_16_regs;
|
||||
else
|
||||
call[i].glue = __wine_call_from_16;
|
||||
call[i].flatcs = wine_get_cs();
|
||||
}
|
||||
|
||||
if (TRACE_ON(relay)) /* patch relay functions to all point to relay_call_from_16 */
|
||||
for (i = 0; call[i].pushl == 0x68; i++) call[i].relay = relay_call_from_16;
|
||||
|
@ -277,7 +277,7 @@ static const CALLFROM16 *get_entry_point( STACK16FRAME *frame, LPSTR module, LPS
|
||||
/* Retrieve entry point call structure */
|
||||
p = MapSL( MAKESEGPTR( frame->module_cs, frame->callfrom_ip ) );
|
||||
/* p now points to lret, get the start of CALLFROM16 structure */
|
||||
return (CALLFROM16 *)(p - (BYTE *)&((CALLFROM16 *)0)->lret);
|
||||
return (CALLFROM16 *)(p - (BYTE *)&((CALLFROM16 *)0)->ret);
|
||||
}
|
||||
|
||||
|
||||
@ -304,10 +304,14 @@ __ASM_GLOBAL_FUNC( call_entry_point,
|
||||
static int relay_call_from_16_no_debug( void *entry_point, unsigned char *args16, CONTEXT86 *context,
|
||||
const CALLFROM16 *call )
|
||||
{
|
||||
int i, nb_args, args32[20];
|
||||
unsigned int i, j, nb_args = 0;
|
||||
int args32[20];
|
||||
|
||||
nb_args = 0;
|
||||
if (call->lret == 0xcb66) /* cdecl */
|
||||
/* look for the ret instruction */
|
||||
for (j = 0; j < sizeof(call->ret)/sizeof(call->ret[0]); j++)
|
||||
if (call->ret[j] == 0xca66 || call->ret[j] == 0xcb66) break;
|
||||
|
||||
if (call->ret[j] == 0xcb66) /* cdecl */
|
||||
{
|
||||
for (i = 0; i < 20; i++, nb_args++)
|
||||
{
|
||||
@ -345,7 +349,7 @@ static int relay_call_from_16_no_debug( void *entry_point, unsigned char *args16
|
||||
else /* not cdecl */
|
||||
{
|
||||
/* Start with the last arg */
|
||||
args16 += call->nArgs;
|
||||
args16 += call->ret[j + 1];
|
||||
for (i = 0; i < 20; i++, nb_args++)
|
||||
{
|
||||
int type = (call->arg_types[i / 10] >> (3 * (i % 10))) & 7;
|
||||
@ -377,7 +381,8 @@ static int relay_call_from_16_no_debug( void *entry_point, unsigned char *args16
|
||||
}
|
||||
}
|
||||
|
||||
if (call->arg_types[0] & ARG_REGISTER) args32[nb_args++] = (int)context;
|
||||
if (!j) /* register function */
|
||||
args32[nb_args++] = (int)context;
|
||||
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
|
||||
@ -394,7 +399,8 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
{
|
||||
STACK16FRAME *frame;
|
||||
WORD ordinal;
|
||||
int i, ret_val, nb_args, args32[20];
|
||||
unsigned int i, j, nb_args = 0;
|
||||
int ret_val, args32[20];
|
||||
char module[10], func[64];
|
||||
const CALLFROM16 *call;
|
||||
|
||||
@ -405,8 +411,11 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
|
||||
DPRINTF( "%04lx:Call %s.%d: %s(",GetCurrentThreadId(), module, ordinal, func );
|
||||
|
||||
nb_args = 0;
|
||||
if (call->lret == 0xcb66) /* cdecl */
|
||||
/* look for the ret instruction */
|
||||
for (j = 0; j < sizeof(call->ret)/sizeof(call->ret[0]); j++)
|
||||
if (call->ret[j] == 0xca66 || call->ret[j] == 0xcb66) break;
|
||||
|
||||
if (call->ret[j] == 0xcb66) /* cdecl */
|
||||
{
|
||||
for (i = 0; i < 20; i++, nb_args++)
|
||||
{
|
||||
@ -460,7 +469,7 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
else /* not cdecl */
|
||||
{
|
||||
/* Start with the last arg */
|
||||
args16 += call->nArgs;
|
||||
args16 += call->ret[j + 1];
|
||||
for (i = 0; i < 20; i++, nb_args++)
|
||||
{
|
||||
int type = (call->arg_types[i / 10] >> (3 * (i % 10))) & 7;
|
||||
@ -513,7 +522,7 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
|
||||
DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
|
||||
|
||||
if (call->arg_types[0] & ARG_REGISTER)
|
||||
if (!j) /* register function */
|
||||
{
|
||||
args32[nb_args++] = (int)context;
|
||||
DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
|
||||
@ -529,7 +538,7 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
|
||||
DPRINTF( "%04lx:Ret %s.%d: %s() ",GetCurrentThreadId(), module, ordinal, func );
|
||||
if (call->arg_types[0] & ARG_REGISTER)
|
||||
if (!j) /* register function */
|
||||
{
|
||||
DPRINTF("retval=none ret=%04x:%04x ds=%04x\n",
|
||||
(WORD)context->SegCs, LOWORD(context->Eip), (WORD)context->SegDs);
|
||||
@ -541,7 +550,7 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
else
|
||||
{
|
||||
frame = CURRENT_STACK16; /* might have be changed by the entry point */
|
||||
if (call->arg_types[0] & ARG_RET16)
|
||||
if (j == 1) /* 16-bit return sequence */
|
||||
DPRINTF( "retval=%04x ret=%04x:%04x ds=%04x\n",
|
||||
ret_val & 0xffff, frame->cs, frame->ip, frame->ds );
|
||||
else
|
||||
@ -558,22 +567,6 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT86 *con
|
||||
* (these will never be called but need to be present to satisfy the linker ...)
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* __wine_call_from_16_word (KERNEL32.@)
|
||||
*/
|
||||
WORD __wine_call_from_16_word()
|
||||
{
|
||||
assert( FALSE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* __wine_call_from_16_long (KERNEL32.@)
|
||||
*/
|
||||
LONG __wine_call_from_16_long()
|
||||
{
|
||||
assert( FALSE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* __wine_call_from_16_regs (KERNEL32.@)
|
||||
*/
|
||||
|
@ -167,6 +167,7 @@ void DOSVM_RelayHandler( CONTEXT86 *context )
|
||||
*/
|
||||
void DOSVM_BuildCallFrame( CONTEXT86 *context, DOSRELAY relay, LPVOID data )
|
||||
{
|
||||
static void (*__wine_call_from_16_regs_ptr)();
|
||||
WORD code_sel = DOSVM_dpmi_segments->relay_code_sel;
|
||||
|
||||
/*
|
||||
@ -195,6 +196,9 @@ void DOSVM_BuildCallFrame( CONTEXT86 *context, DOSRELAY relay, LPVOID data )
|
||||
/*
|
||||
* Adjust code pointer.
|
||||
*/
|
||||
if (!__wine_call_from_16_regs_ptr)
|
||||
__wine_call_from_16_regs_ptr = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
|
||||
"__wine_call_from_16_regs" );
|
||||
context->SegCs = wine_get_cs();
|
||||
context->Eip = (DWORD)__wine_call_from_16_regs;
|
||||
context->Eip = (DWORD)__wine_call_from_16_regs_ptr;
|
||||
}
|
||||
|
@ -217,14 +217,6 @@ enum arg_types
|
||||
ARG_VARARG /* start of varargs */
|
||||
};
|
||||
|
||||
/* flags added to arg_types[0] */
|
||||
#define ARG_RET16 0x80000000 /* function returns 16-bit value */
|
||||
#define ARG_REGISTER 0x40000000 /* function is register */
|
||||
|
||||
extern WORD __wine_call_from_16_word();
|
||||
extern LONG __wine_call_from_16_long();
|
||||
extern void __wine_call_from_16_regs();
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#define INVALID_HANDLE_VALUE16 ((HANDLE16) -1)
|
||||
|
@ -637,34 +637,12 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta
|
||||
case CPU_x86:
|
||||
if (!UsePIC)
|
||||
{
|
||||
if (strstr( name, "__wine_call_from_16" )) fprintf( outfile, "\t.byte 0x2e\n" );
|
||||
fprintf( outfile, "\tjmp *(%s+%d)\n", table, pos );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strcmp( name, "__wine_call_from_16_regs" ))
|
||||
{
|
||||
/* special case: need to preserve all registers */
|
||||
fprintf( outfile, "\tpushl %%eax\n" );
|
||||
fprintf( outfile, "\tpushl %%ecx\n" );
|
||||
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
|
||||
fprintf( outfile, ".L__wine_spec_%s:\n", name );
|
||||
fprintf( outfile, "1:\t.byte 0x2e\n" );
|
||||
fprintf( outfile, "\tmovl %s+%d-1b(%%eax),%%eax\n", table, pos );
|
||||
fprintf( outfile, "\tmovzwl %%sp, %%ecx\n" );
|
||||
fprintf( outfile, "\t.byte 0x36\n" );
|
||||
fprintf( outfile, "\txchgl %%eax,4(%%ecx)\n" );
|
||||
fprintf( outfile, "\tpopl %%ecx\n" );
|
||||
fprintf( outfile, "\tret\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
|
||||
fprintf( outfile, "1:" );
|
||||
if (strstr( name, "__wine_call_from_16" ))
|
||||
fprintf( outfile, "\t.byte 0x2e\n" );
|
||||
fprintf( outfile, "\tjmp *%s+%d-1b(%%eax)\n", table, pos );
|
||||
}
|
||||
fprintf( outfile, "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
|
||||
fprintf( outfile, "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos );
|
||||
}
|
||||
break;
|
||||
case CPU_x86_64:
|
||||
|
@ -118,15 +118,12 @@ static inline const char *data16_prefix(void)
|
||||
* (sp-20) long saved edx
|
||||
* (sp-24) long saved previous stack
|
||||
*/
|
||||
static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int short_ret )
|
||||
static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk )
|
||||
{
|
||||
const char *name = thunk? "thunk" : reg_func? "regs" : short_ret? "word" : "long";
|
||||
|
||||
/* Function header */
|
||||
if (thunk) function_header( outfile, "__wine_call_from_16_thunk" );
|
||||
else if (reg_func) function_header( outfile, "__wine_call_from_16_regs" );
|
||||
else if (short_ret) function_header( outfile, "__wine_call_from_16_word" );
|
||||
else function_header( outfile, "__wine_call_from_16_long" );
|
||||
else function_header( outfile, "__wine_call_from_16" );
|
||||
|
||||
/* Create STACK16FRAME (except STACK32FRAME link) */
|
||||
fprintf( outfile, "\tpushw %%gs\n" );
|
||||
@ -142,11 +139,10 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
||||
|
||||
if ( UsePIC )
|
||||
{
|
||||
fprintf( outfile, "\tcall .Lcall_from_16_%s.getpc\n", name );
|
||||
fprintf( outfile, ".Lcall_from_16_%s.getpc:\n", name );
|
||||
fprintf( outfile, "\tpopl %%ecx\n" );
|
||||
fprintf( outfile, "\t.byte 0x2e\n\tmovl %s-.Lcall_from_16_%s.getpc(%%ecx),%%edx\n",
|
||||
asm_name("CallTo16_DataSelector"), name );
|
||||
fprintf( outfile, "\tcall 1f\n" );
|
||||
fprintf( outfile, "1:\tpopl %%ecx\n" );
|
||||
fprintf( outfile, "\t.byte 0x2e\n\tmovl %s-1b(%%ecx),%%edx\n",
|
||||
asm_name("CallTo16_DataSelector") );
|
||||
}
|
||||
else
|
||||
fprintf( outfile, "\t.byte 0x2e\n\tmovl %s,%%edx\n", asm_name("CallTo16_DataSelector") );
|
||||
@ -156,8 +152,7 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
||||
fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() );
|
||||
|
||||
if ( UsePIC )
|
||||
fprintf( outfile, "\tmovw %s-.Lcall_from_16_%s.getpc(%%ecx), %%fs\n",
|
||||
asm_name("CallTo16_TebSelector"), name );
|
||||
fprintf( outfile, "\tmovw %s-1b(%%ecx), %%fs\n", asm_name("CallTo16_TebSelector") );
|
||||
else
|
||||
fprintf( outfile, "\tmovw %s, %%fs\n", asm_name("CallTo16_TebSelector") );
|
||||
|
||||
@ -169,7 +164,7 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
||||
fprintf( outfile, "\tshrl $1, %%edx\n" );
|
||||
if (UsePIC)
|
||||
{
|
||||
fprintf( outfile, "\taddl wine_ldt_copy_ptr-.Lcall_from_16_%s.getpc(%%ecx),%%edx\n", name );
|
||||
fprintf( outfile, "\taddl wine_ldt_copy_ptr-1b(%%ecx),%%edx\n" );
|
||||
fprintf( outfile, "\tmovl (%%edx), %%edx\n" );
|
||||
}
|
||||
else
|
||||
@ -352,18 +347,12 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
|
||||
fprintf( outfile, "\tpopw %%fs\n" );
|
||||
fprintf( outfile, "\tpopw %%gs\n" );
|
||||
|
||||
/* Prepare return value and set flags accordingly */
|
||||
if ( !short_ret )
|
||||
fprintf( outfile, "\tshldl $16, %%eax, %%edx\n" );
|
||||
fprintf( outfile, "\torl %%eax, %%eax\n" );
|
||||
|
||||
/* Return to return stub which will return to caller */
|
||||
fprintf( outfile, "\tlret $12\n" );
|
||||
}
|
||||
if (thunk) function_footer( outfile, "__wine_call_from_16_thunk" );
|
||||
else if (reg_func) function_footer( outfile, "__wine_call_from_16_regs" );
|
||||
else if (short_ret) function_footer( outfile, "__wine_call_from_16_word" );
|
||||
else function_footer( outfile, "__wine_call_from_16_long" );
|
||||
else function_footer( outfile, "__wine_call_from_16" );
|
||||
}
|
||||
|
||||
|
||||
@ -935,17 +924,14 @@ void BuildRelays16( FILE *outfile )
|
||||
|
||||
fprintf( outfile, "%s\n", asm_globl("__wine_call16_start") );
|
||||
|
||||
/* Standard CallFrom16 routine (WORD return) */
|
||||
BuildCallFrom16Core( outfile, FALSE, FALSE, TRUE );
|
||||
|
||||
/* Standard CallFrom16 routine (DWORD return) */
|
||||
BuildCallFrom16Core( outfile, FALSE, FALSE, FALSE );
|
||||
/* Standard CallFrom16 routine */
|
||||
BuildCallFrom16Core( outfile, FALSE, FALSE );
|
||||
|
||||
/* Register CallFrom16 routine */
|
||||
BuildCallFrom16Core( outfile, TRUE, FALSE, FALSE );
|
||||
BuildCallFrom16Core( outfile, TRUE, FALSE );
|
||||
|
||||
/* C16ThkSL CallFrom16 routine */
|
||||
BuildCallFrom16Core( outfile, FALSE, TRUE, FALSE );
|
||||
BuildCallFrom16Core( outfile, FALSE, TRUE );
|
||||
|
||||
/* Standard CallTo16 routine */
|
||||
BuildCallTo16Core( outfile, 0 );
|
||||
|
@ -28,29 +28,11 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "wine/exception.h"
|
||||
#include "wine/winbase16.h"
|
||||
|
||||
#include "build.h"
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* get_cs
|
||||
*/
|
||||
static inline unsigned short get_cs(void)
|
||||
{
|
||||
unsigned short res = 0;
|
||||
#ifdef __i386__
|
||||
# ifdef __GNUC__
|
||||
__asm__("movw %%cs,%w0" : "=r"(res));
|
||||
# elif defined(_MSC_VER)
|
||||
__asm { mov res, cs }
|
||||
# endif
|
||||
#endif /* __i386__ */
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* output_file_header
|
||||
*
|
||||
@ -404,16 +386,11 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
unsigned int et_size, et_offset;
|
||||
|
||||
char constructor[100], destructor[100];
|
||||
unsigned short code_selector = get_cs();
|
||||
|
||||
/* File header */
|
||||
|
||||
output_file_header( outfile );
|
||||
fprintf( outfile, "static const char __wine_spec16_file_name[] = \"%s\";\n", spec->file_name );
|
||||
fprintf( outfile, "extern unsigned short __wine_call_from_16_word();\n" );
|
||||
fprintf( outfile, "extern unsigned int __wine_call_from_16_long();\n" );
|
||||
fprintf( outfile, "extern void __wine_call_from_16_regs();\n" );
|
||||
fprintf( outfile, "extern void __wine_call_from_16_thunk();\n" );
|
||||
|
||||
data_buffer = xmalloc( 0x10000 );
|
||||
memset( data_buffer, 0, 16 );
|
||||
@ -471,7 +448,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
/* compute code and data sizes, set offsets, and output prototypes */
|
||||
|
||||
entrypoint_size = 2 + 5 + 4; /* pushw bp + pushl target + call */
|
||||
callfrom_size = 5 + 7 + 4 + 8; /* pushl relay + lcall cs:glue + lret n + args */
|
||||
callfrom_size = 5 + 7 + 10 + 2 + 8; /* pushl relay + lcall cs:glue + ret sequence + movl + args */
|
||||
code_size = nTypes * callfrom_size;
|
||||
|
||||
for (i = 0; i <= spec->limit; i++)
|
||||
@ -508,7 +485,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
|
||||
/* DOS header */
|
||||
|
||||
fprintf( outfile, "\n#include \"pshpack1.h\"\n" );
|
||||
fprintf( outfile, "\n#pragma pack(1)\n" );
|
||||
fprintf( outfile, "static const struct module_data\n{\n" );
|
||||
fprintf( outfile, " struct\n {\n" );
|
||||
fprintf( outfile, " unsigned short e_magic;\n" );
|
||||
@ -623,8 +600,8 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
fprintf( outfile, " unsigned char lcall;\n" ); /* lcall __FLATCS__:glue */
|
||||
fprintf( outfile, " void *glue;\n" );
|
||||
fprintf( outfile, " unsigned short flatcs;\n" );
|
||||
fprintf( outfile, " unsigned short lret;\n" ); /* lret $args */
|
||||
fprintf( outfile, " unsigned short args;\n" );
|
||||
fprintf( outfile, " unsigned short ret[5];\n" ); /* return sequence */
|
||||
fprintf( outfile, " unsigned short movl;\n" ); /* movl arg_types[1],arg_types[0](%esi) */
|
||||
fprintf( outfile, " unsigned int arg_types[2];\n" );
|
||||
fprintf( outfile, " } call[%d];\n", nTypes );
|
||||
fprintf( outfile, " struct {\n" );
|
||||
@ -778,19 +755,37 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
arg_types[j / 10] |= type << (3 * (j % 10));
|
||||
}
|
||||
if (typelist[i]->type == TYPE_VARARGS) arg_types[j / 10] |= ARG_VARARG << (3 * (j % 10));
|
||||
if (typelist[i]->flags & FLAG_REGISTER) arg_types[0] |= ARG_REGISTER;
|
||||
if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16;
|
||||
|
||||
fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n",
|
||||
make_c_identifier(spec->file_name), profile,
|
||||
(typelist[i]->flags & FLAG_REGISTER) ? "regs":
|
||||
(typelist[i]->flags & FLAG_RET16) ? "word" : "long" );
|
||||
if (argsize)
|
||||
fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n",
|
||||
code_selector, argsize, arg_types[0], arg_types[1] );
|
||||
fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, 0, 0,\n ",
|
||||
make_c_identifier(spec->file_name), profile );
|
||||
|
||||
if (typelist[i]->flags & FLAG_REGISTER)
|
||||
{
|
||||
/* ret sequence: ret $n; nop */
|
||||
if (argsize)
|
||||
fprintf( outfile, "{ 0xca66, %d, 0xb68d, 0x0000, 0x0000 },", argsize );
|
||||
else
|
||||
fprintf( outfile, "{ 0xcb66, 0x748d, 0x0026, 0x748d, 0x0026 }," );
|
||||
}
|
||||
else if (typelist[i]->flags & FLAG_RET16)
|
||||
{
|
||||
/* ret sequence: orl %eax,%eax; ret $n; nop */
|
||||
if (argsize)
|
||||
fprintf( outfile, "{ 0xc009, 0xca66, %d, 0x748d, 0x0026 },", argsize );
|
||||
else
|
||||
fprintf( outfile, "{ 0xc009, 0xcb66, 0xb68d, 0x0000, 0x0000 }," );
|
||||
}
|
||||
else
|
||||
fprintf( outfile, " 0x%04x, 0xcb66, 0x9090, { 0x%08x, 0x%08x } },\n",
|
||||
code_selector, arg_types[0], arg_types[1] );
|
||||
{
|
||||
/* ret sequence: shld $16,%eax,%edx; orl %eax,%eax; ret $n [; nop] */
|
||||
if (argsize)
|
||||
fprintf( outfile, "{ 0xa40f, 0x10c2, 0xc009, 0xca66, %d },", argsize );
|
||||
else
|
||||
fprintf( outfile, "{ 0xa40f, 0x10c2, 0xc009, 0xcb66, 0xf689 }," );
|
||||
}
|
||||
/* the movl is here so that the code contains only valid instructions, */
|
||||
/* it's never actually executed, we only care about the arg_types[] values */
|
||||
fprintf( outfile, " 0x86c7, { 0x%08x, 0x%08x } },\n", arg_types[0], arg_types[1] );
|
||||
}
|
||||
fprintf( outfile, " },\n {\n" );
|
||||
|
||||
@ -835,7 +830,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
|
||||
}
|
||||
|
||||
fprintf( outfile, "};\n" );
|
||||
fprintf( outfile, "#include \"poppack.h\"\n\n" );
|
||||
fprintf( outfile, "#pragma pack()\n\n" );
|
||||
|
||||
/* Output the DLL constructor */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user