Modified Win32 register function handling.
This commit is contained in:
parent
ae5e93e365
commit
9b233bdb8a
|
@ -91,24 +91,19 @@ static inline void WINE_UNUSED stack16_pop( int size )
|
||||||
teb->cur_stack += size;
|
teb->cur_stack += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
/* Push a DWORD on the 32-bit stack */
|
/* Push a DWORD on the 32-bit stack */
|
||||||
static inline void WINE_UNUSED stack32_push( CONTEXT *context, DWORD val )
|
static inline void WINE_UNUSED stack32_push( CONTEXT86 *context, DWORD val )
|
||||||
{
|
{
|
||||||
ESP_reg(context) -= sizeof(DWORD);
|
ESP_reg(context) -= sizeof(DWORD);
|
||||||
*(DWORD *)ESP_reg(context) = val;
|
*(DWORD *)ESP_reg(context) = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pop a DWORD from the 32-bit stack */
|
/* Pop a DWORD from the 32-bit stack */
|
||||||
static inline DWORD WINE_UNUSED stack32_pop( CONTEXT *context )
|
static inline DWORD WINE_UNUSED stack32_pop( CONTEXT86 *context )
|
||||||
{
|
{
|
||||||
DWORD ret = *(DWORD *)ESP_reg(context);
|
DWORD ret = *(DWORD *)ESP_reg(context);
|
||||||
ESP_reg(context) += sizeof(DWORD);
|
ESP_reg(context) += sizeof(DWORD);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* __i386__ */
|
|
||||||
|
|
||||||
/* Win32 register functions */
|
|
||||||
#define REGS_FUNC(name) __regs_##name
|
|
||||||
|
|
||||||
#endif /* __WINE_STACKFRAME_H */
|
#endif /* __WINE_STACKFRAME_H */
|
||||||
|
|
|
@ -561,6 +561,8 @@ typedef struct _STACK_FRAME_HEADER
|
||||||
|
|
||||||
typedef struct _CONTEXT
|
typedef struct _CONTEXT
|
||||||
{
|
{
|
||||||
|
DWORD ContextFlags;
|
||||||
|
|
||||||
/* These are selected by CONTEXT_INTEGER */
|
/* These are selected by CONTEXT_INTEGER */
|
||||||
DWORD g0;
|
DWORD g0;
|
||||||
DWORD g1;
|
DWORD g1;
|
||||||
|
@ -664,6 +666,63 @@ typedef HANDLE *PHANDLE;
|
||||||
#define ISV86(context) (EFL_reg(context) & 0x00020000)
|
#define ISV86(context) (EFL_reg(context) & 0x00020000)
|
||||||
#define V86BASE(context) ((context)->Dr7) /* ugly */
|
#define V86BASE(context) ((context)->Dr7) /* ugly */
|
||||||
|
|
||||||
|
|
||||||
|
/* Macros to retrieve the current context */
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
#define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \
|
||||||
|
__asm__(".align 4\n\t" \
|
||||||
|
".globl " #name "\n\t" \
|
||||||
|
".type " #name ",@function\n\t" \
|
||||||
|
#name ":\n\t" \
|
||||||
|
"call CALL32_Regs\n\t" \
|
||||||
|
".long " #fn "\n\t" \
|
||||||
|
".byte " #args ", " #args "\n\t");
|
||||||
|
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \
|
||||||
|
_DEFINE_REGS_ENTRYPOINT( name, fn, 0 )
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
|
||||||
|
_DEFINE_REGS_ENTRYPOINT( name, fn, 4 )
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \
|
||||||
|
_DEFINE_REGS_ENTRYPOINT( name, fn, 8 )
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \
|
||||||
|
_DEFINE_REGS_ENTRYPOINT( name, fn, 12 )
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \
|
||||||
|
_DEFINE_REGS_ENTRYPOINT( name, fn, 16 )
|
||||||
|
|
||||||
|
#endif /* __i386__ */
|
||||||
|
|
||||||
|
#ifdef __sparc__
|
||||||
|
/* FIXME: use getcontext() to retrieve full context */
|
||||||
|
#define _GET_CONTEXT \
|
||||||
|
CONTEXT context; \
|
||||||
|
do { memset(&context, 0, sizeof(CONTEXT)); \
|
||||||
|
context.ContextFlags = CONTEXT_CONTROL; \
|
||||||
|
context.pc = (DWORD)__builtin_return_address(0); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \
|
||||||
|
void WINAPI name ( void ) \
|
||||||
|
{ _GET_CONTEXT; fn( &context ); }
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
|
||||||
|
void WINAPI name ( t1 a1 ) \
|
||||||
|
{ _GET_CONTEXT; fn( a1, &context ); }
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \
|
||||||
|
void WINAPI name ( t1 a1, t2 a2 ) \
|
||||||
|
{ _GET_CONTEXT; fn( a1, a2, &context ); }
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \
|
||||||
|
void WINAPI name ( t1 a1, t2 a2, t3 a3 ) \
|
||||||
|
{ _GET_CONTEXT; fn( a1, a2, a3, &context ); }
|
||||||
|
#define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \
|
||||||
|
void WINAPI name ( t1 a1, t2 a2, t3 a3, t4 a4 ) \
|
||||||
|
{ _GET_CONTEXT; fn( a1, a2, a3, a4, &context ); }
|
||||||
|
|
||||||
|
#endif /* __sparc__ */
|
||||||
|
|
||||||
|
#ifndef DEFINE_REGS_ENTRYPOINT_0
|
||||||
|
#error You need to define DEFINE_REGS_ENTRYPOINT macros for your CPU
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
# define GET_IP(context) ((LPVOID)(context)->Eip)
|
# define GET_IP(context) ((LPVOID)(context)->Eip)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -472,6 +472,13 @@ static int ParseExportFunction( ORDDEF *odp )
|
||||||
if ((odp->type == TYPE_STDCALL) && !i)
|
if ((odp->type == TYPE_STDCALL) && !i)
|
||||||
odp->type = TYPE_CDECL; /* stdcall is the same as cdecl for 0 args */
|
odp->type = TYPE_CDECL; /* stdcall is the same as cdecl for 0 args */
|
||||||
strcpy(odp->u.func.link_name, GetToken());
|
strcpy(odp->u.func.link_name, GetToken());
|
||||||
|
|
||||||
|
/* Ignore Win32 'register' routines on non-Intel archs */
|
||||||
|
#ifndef __i386__
|
||||||
|
if ( odp->type == TYPE_REGISTER && SpecType == SPEC_WIN32 )
|
||||||
|
odp->type = TYPE_INVALID;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,7 +1031,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
|
||||||
static int BuildSpec32File( char * specfile, FILE *outfile )
|
static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
{
|
{
|
||||||
ORDDEF *odp;
|
ORDDEF *odp;
|
||||||
int i, nb_names, fwd_size = 0;
|
int i, nb_names, fwd_size = 0, have_regs = FALSE;
|
||||||
|
|
||||||
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
|
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
|
||||||
specfile );
|
specfile );
|
||||||
|
@ -1041,33 +1048,6 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
i, DLLName, i );
|
i, DLLName, i );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output code for all register functions */
|
|
||||||
|
|
||||||
fprintf( outfile, "#ifdef __i386__\n" );
|
|
||||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
|
||||||
fprintf( outfile, "static void __asm__dummy() {\n" );
|
|
||||||
fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" );
|
|
||||||
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
|
|
||||||
{
|
|
||||||
if (odp->type != TYPE_REGISTER) continue;
|
|
||||||
fprintf( outfile,
|
|
||||||
"__asm__(\".align 4\\n\\t\"\n"
|
|
||||||
" \".globl " PREFIX "%s\\n\\t\"\n"
|
|
||||||
" \".type " PREFIX "%s,@function\\n\\t\"\n"
|
|
||||||
" \"" PREFIX "%s:\\n\\t\"\n"
|
|
||||||
" \"call " PREFIX "CALL32_Regs\\n\\t\"\n"
|
|
||||||
" \".long " PREFIX "__regs_%s\\n\\t\"\n"
|
|
||||||
" \".byte %d,%d\");\n",
|
|
||||||
odp->u.func.link_name, odp->u.func.link_name,
|
|
||||||
odp->u.func.link_name, odp->u.func.link_name,
|
|
||||||
4 * strlen(odp->u.func.arg_types),
|
|
||||||
4 * strlen(odp->u.func.arg_types) );
|
|
||||||
}
|
|
||||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
|
||||||
fprintf( outfile, "}\n" );
|
|
||||||
fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" );
|
|
||||||
fprintf( outfile, "#endif /* defined(__i386__) */\n" );
|
|
||||||
|
|
||||||
/* Output the DLL functions prototypes */
|
/* Output the DLL functions prototypes */
|
||||||
|
|
||||||
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
|
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
|
||||||
|
@ -1077,7 +1057,6 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
case TYPE_EXTERN:
|
case TYPE_EXTERN:
|
||||||
fprintf( outfile, "extern void %s();\n", odp->u.ext.link_name );
|
fprintf( outfile, "extern void %s();\n", odp->u.ext.link_name );
|
||||||
break;
|
break;
|
||||||
case TYPE_REGISTER:
|
|
||||||
case TYPE_STDCALL:
|
case TYPE_STDCALL:
|
||||||
case TYPE_VARARGS:
|
case TYPE_VARARGS:
|
||||||
case TYPE_CDECL:
|
case TYPE_CDECL:
|
||||||
|
@ -1086,6 +1065,10 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
case TYPE_FORWARD:
|
case TYPE_FORWARD:
|
||||||
fwd_size += strlen(odp->u.fwd.link_name) + 1;
|
fwd_size += strlen(odp->u.fwd.link_name) + 1;
|
||||||
break;
|
break;
|
||||||
|
case TYPE_REGISTER:
|
||||||
|
fprintf( outfile, "extern void __regs_%d();\n", i );
|
||||||
|
have_regs = TRUE;
|
||||||
|
break;
|
||||||
case TYPE_INVALID:
|
case TYPE_INVALID:
|
||||||
case TYPE_STUB:
|
case TYPE_STUB:
|
||||||
break;
|
break;
|
||||||
|
@ -1100,6 +1083,32 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
if (DLLInitFunc[0]) fprintf( outfile, "extern void %s();\n", DLLInitFunc );
|
if (DLLInitFunc[0]) fprintf( outfile, "extern void %s();\n", DLLInitFunc );
|
||||||
|
|
||||||
|
|
||||||
|
/* Output code for all register functions */
|
||||||
|
|
||||||
|
if ( have_regs )
|
||||||
|
{
|
||||||
|
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||||
|
fprintf( outfile, "static void __asm__dummy() {\n" );
|
||||||
|
fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" );
|
||||||
|
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
|
||||||
|
{
|
||||||
|
if (odp->type != TYPE_REGISTER) continue;
|
||||||
|
fprintf( outfile,
|
||||||
|
"__asm__(\".align 4\\n\\t\"\n"
|
||||||
|
" \".type " PREFIX "__regs_%d,@function\\n\\t\"\n"
|
||||||
|
" \"" PREFIX "__regs_%d:\\n\\t\"\n"
|
||||||
|
" \"call " PREFIX "CALL32_Regs\\n\\t\"\n"
|
||||||
|
" \".long " PREFIX "%s\\n\\t\"\n"
|
||||||
|
" \".byte %d,%d\");\n",
|
||||||
|
i, i, odp->u.func.link_name,
|
||||||
|
4 * strlen(odp->u.func.arg_types),
|
||||||
|
4 * strlen(odp->u.func.arg_types) );
|
||||||
|
}
|
||||||
|
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||||
|
fprintf( outfile, "}\n" );
|
||||||
|
fprintf( outfile, "#endif /* !defined(__GNUC__) */\n" );
|
||||||
|
}
|
||||||
|
|
||||||
/* Output the DLL functions table */
|
/* Output the DLL functions table */
|
||||||
|
|
||||||
fprintf( outfile, "\nstatic const ENTRYPOINT32 Functions[%d] =\n{\n",
|
fprintf( outfile, "\nstatic const ENTRYPOINT32 Functions[%d] =\n{\n",
|
||||||
|
@ -1114,7 +1123,6 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
case TYPE_EXTERN:
|
case TYPE_EXTERN:
|
||||||
fprintf( outfile, " %s", odp->u.ext.link_name );
|
fprintf( outfile, " %s", odp->u.ext.link_name );
|
||||||
break;
|
break;
|
||||||
case TYPE_REGISTER:
|
|
||||||
case TYPE_STDCALL:
|
case TYPE_STDCALL:
|
||||||
case TYPE_VARARGS:
|
case TYPE_VARARGS:
|
||||||
case TYPE_CDECL:
|
case TYPE_CDECL:
|
||||||
|
@ -1123,6 +1131,9 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
|
||||||
case TYPE_STUB:
|
case TYPE_STUB:
|
||||||
fprintf( outfile, " __stub_%d", i );
|
fprintf( outfile, " __stub_%d", i );
|
||||||
break;
|
break;
|
||||||
|
case TYPE_REGISTER:
|
||||||
|
fprintf( outfile, " __regs_%d", i );
|
||||||
|
break;
|
||||||
case TYPE_FORWARD:
|
case TYPE_FORWARD:
|
||||||
fprintf( outfile, " (ENTRYPOINT32)\"%s\"", odp->u.fwd.link_name );
|
fprintf( outfile, " (ENTRYPOINT32)\"%s\"", odp->u.fwd.link_name );
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue