Commit a8378494 authored by Alexandre Julliard's avatar Alexandre Julliard

Added stdcall64 entry point type to allow correct relay debugging

support for functions that return 64-bit values.
parent bf69803c
...@@ -70,7 +70,7 @@ typedef struct ...@@ -70,7 +70,7 @@ typedef struct
DWORD callfrom32 WINE_PACKED; /* RELAY_CallFrom32 relative addr */ DWORD callfrom32 WINE_PACKED; /* RELAY_CallFrom32 relative addr */
BYTE ret; /* 0xc2 ret $n or 0xc3 ret */ BYTE ret; /* 0xc2 ret $n or 0xc3 ret */
WORD args; /* nb of args to remove from the stack */ WORD args; /* nb of args to remove from the stack */
FARPROC orig; /* original entry point */ void *orig; /* original entry point */
DWORD argtypes; /* argument types */ DWORD argtypes; /* argument types */
} DEBUG_ENTRY_POINT; } DEBUG_ENTRY_POINT;
...@@ -166,10 +166,11 @@ static inline void RELAY_PrintArgs( int *args, int nb_args, unsigned int typemas ...@@ -166,10 +166,11 @@ static inline void RELAY_PrintArgs( int *args, int nb_args, unsigned int typemas
* (esp+4) ret_addr * (esp+4) ret_addr
* (esp) return addr to relay code * (esp) return addr to relay code
*/ */
static int RELAY_CallFrom32( int ret_addr, ... ) static LONGLONG RELAY_CallFrom32( int ret_addr, ... )
{ {
int ret; LONGLONG ret;
char buffer[80]; char buffer[80];
BOOL ret64;
int *args = &ret_addr + 1; int *args = &ret_addr + 1;
/* Relay addr is the return address for this function */ /* Relay addr is the return address for this function */
...@@ -182,6 +183,7 @@ static int RELAY_CallFrom32( int ret_addr, ... ) ...@@ -182,6 +183,7 @@ static int RELAY_CallFrom32( int ret_addr, ... )
DPRINTF( "Call %s(", buffer ); DPRINTF( "Call %s(", buffer );
RELAY_PrintArgs( args, nb_args, relay->argtypes ); RELAY_PrintArgs( args, nb_args, relay->argtypes );
DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, __get_fs() ); DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, __get_fs() );
ret64 = (relay->argtypes & 0x80000000) && (nb_args < 16);
/* the user driver functions may be called with the window lock held */ /* the user driver functions may be called with the window lock held */
if (memcmp( buffer, "x11drv.", 7 ) && memcmp( buffer, "ttydrv.", 7 )) if (memcmp( buffer, "x11drv.", 7 ) && memcmp( buffer, "ttydrv.", 7 ))
...@@ -189,7 +191,7 @@ static int RELAY_CallFrom32( int ret_addr, ... ) ...@@ -189,7 +191,7 @@ static int RELAY_CallFrom32( int ret_addr, ... )
if (relay->ret == 0xc3) /* cdecl */ if (relay->ret == 0xc3) /* cdecl */
{ {
LRESULT (*cfunc)() = (LRESULT(*)())relay->orig; LONGLONG (*cfunc)() = relay->orig;
switch(nb_args) switch(nb_args)
{ {
case 0: ret = cfunc(); break; case 0: ret = cfunc(); break;
...@@ -232,7 +234,7 @@ static int RELAY_CallFrom32( int ret_addr, ... ) ...@@ -232,7 +234,7 @@ static int RELAY_CallFrom32( int ret_addr, ... )
} }
else /* stdcall */ else /* stdcall */
{ {
FARPROC func = relay->orig; LONGLONG (WINAPI *func)() = relay->orig;
switch(nb_args) switch(nb_args)
{ {
case 0: ret = func(); break; case 0: ret = func(); break;
...@@ -273,8 +275,12 @@ static int RELAY_CallFrom32( int ret_addr, ... ) ...@@ -273,8 +275,12 @@ static int RELAY_CallFrom32( int ret_addr, ... )
assert(FALSE); assert(FALSE);
} }
} }
DPRINTF( "Ret %s() retval=%08x ret=%08x fs=%04x\n", if (ret64)
buffer, ret, ret_addr, __get_fs() ); DPRINTF( "Ret %s() retval=%08x%08x ret=%08x fs=%04x\n",
buffer, (UINT)(ret >> 32), (UINT)ret, ret_addr, __get_fs() );
else
DPRINTF( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
buffer, (UINT)ret, ret_addr, __get_fs() );
if (memcmp( buffer, "x11drv.", 7 ) && memcmp( buffer, "ttydrv.", 7 )) if (memcmp( buffer, "x11drv.", 7 ) && memcmp( buffer, "ttydrv.", 7 ))
SYSLEVEL_CheckNotLevel( 2 ); SYSLEVEL_CheckNotLevel( 2 );
......
...@@ -43,6 +43,7 @@ typedef enum ...@@ -43,6 +43,7 @@ typedef enum
TYPE_INTERRUPT, /* interrupt handler function (Win16) */ TYPE_INTERRUPT, /* interrupt handler function (Win16) */
TYPE_STUB, /* unimplemented stub */ TYPE_STUB, /* unimplemented stub */
TYPE_STDCALL, /* stdcall function (Win32) */ TYPE_STDCALL, /* stdcall function (Win32) */
TYPE_STDCALL64, /* stdcall function with 64-bit return (Win32) */
TYPE_CDECL, /* cdecl function (Win32) */ TYPE_CDECL, /* cdecl function (Win32) */
TYPE_VARARGS, /* varargs function (Win32) */ TYPE_VARARGS, /* varargs function (Win32) */
TYPE_EXTERN, /* external symbol (Win32) */ TYPE_EXTERN, /* external symbol (Win32) */
...@@ -75,7 +76,7 @@ typedef struct ...@@ -75,7 +76,7 @@ typedef struct
typedef struct typedef struct
{ {
int n_args; int n_args;
char arg_types[32]; char arg_types[17];
char link_name[80]; char link_name[80];
} ORD_FUNCTION; } ORD_FUNCTION;
......
...@@ -38,6 +38,7 @@ static const char * const TypeNames[TYPE_NBTYPES] = ...@@ -38,6 +38,7 @@ static const char * const TypeNames[TYPE_NBTYPES] =
"interrupt", /* TYPE_INTERRUPT */ "interrupt", /* TYPE_INTERRUPT */
"stub", /* TYPE_STUB */ "stub", /* TYPE_STUB */
"stdcall", /* TYPE_STDCALL */ "stdcall", /* TYPE_STDCALL */
"stdcall64", /* TYPE_STDCALL64 */
"cdecl", /* TYPE_CDECL */ "cdecl", /* TYPE_CDECL */
"varargs", /* TYPE_VARARGS */ "varargs", /* TYPE_VARARGS */
"extern", /* TYPE_EXTERN */ "extern", /* TYPE_EXTERN */
...@@ -167,7 +168,7 @@ static void ParseExportFunction( ORDDEF *odp ) ...@@ -167,7 +168,7 @@ static void ParseExportFunction( ORDDEF *odp )
switch(SpecType) switch(SpecType)
{ {
case SPEC_WIN16: case SPEC_WIN16:
if (odp->type == TYPE_STDCALL) if (odp->type == TYPE_STDCALL || odp->type == TYPE_STDCALL64)
fatal_error( "'stdcall' not supported for Win16\n" ); fatal_error( "'stdcall' not supported for Win16\n" );
if (odp->type == TYPE_VARARGS) if (odp->type == TYPE_VARARGS)
fatal_error( "'varargs' not supported for Win16\n" ); fatal_error( "'varargs' not supported for Win16\n" );
...@@ -183,7 +184,7 @@ static void ParseExportFunction( ORDDEF *odp ) ...@@ -183,7 +184,7 @@ static void ParseExportFunction( ORDDEF *odp )
token = GetToken(); token = GetToken();
if (*token != '(') fatal_error( "Expected '(' got '%s'\n", token ); if (*token != '(') fatal_error( "Expected '(' got '%s'\n", token );
for (i = 0; i < sizeof(odp->u.func.arg_types)-1; i++) for (i = 0; i < sizeof(odp->u.func.arg_types); i++)
{ {
token = GetToken(); token = GetToken();
if (*token == ')') if (*token == ')')
...@@ -206,7 +207,7 @@ static void ParseExportFunction( ORDDEF *odp ) ...@@ -206,7 +207,7 @@ static void ParseExportFunction( ORDDEF *odp )
else if (!strcmp(token, "double")) else if (!strcmp(token, "double"))
{ {
odp->u.func.arg_types[i++] = 'l'; odp->u.func.arg_types[i++] = 'l';
odp->u.func.arg_types[i] = 'l'; if (i < sizeof(odp->u.func.arg_types)) odp->u.func.arg_types[i] = 'l';
} }
else fatal_error( "Unknown variable type '%s'\n", token ); else fatal_error( "Unknown variable type '%s'\n", token );
...@@ -372,6 +373,7 @@ static void ParseOrdinal(int ordinal) ...@@ -372,6 +373,7 @@ static void ParseOrdinal(int ordinal)
case TYPE_PASCAL_16: case TYPE_PASCAL_16:
case TYPE_PASCAL: case TYPE_PASCAL:
case TYPE_STDCALL: case TYPE_STDCALL:
case TYPE_STDCALL64:
case TYPE_VARARGS: case TYPE_VARARGS:
case TYPE_CDECL: case TYPE_CDECL:
ParseExportFunction( odp ); ParseExportFunction( odp );
......
...@@ -149,6 +149,7 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd ...@@ -149,6 +149,7 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd
fprintf( outfile, "%s", odp->u.ext.link_name ); fprintf( outfile, "%s", odp->u.ext.link_name );
break; break;
case TYPE_STDCALL: case TYPE_STDCALL:
case TYPE_STDCALL64:
case TYPE_VARARGS: case TYPE_VARARGS:
case TYPE_CDECL: case TYPE_CDECL:
fprintf( outfile, "%s", odp->u.func.link_name); fprintf( outfile, "%s", odp->u.func.link_name);
...@@ -220,6 +221,7 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd ...@@ -220,6 +221,7 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd
ORDDEF *odp = Ordinals[i]; ORDDEF *odp = Ordinals[i];
if (odp && ((odp->type == TYPE_STDCALL) || if (odp && ((odp->type == TYPE_STDCALL) ||
(odp->type == TYPE_STDCALL64) ||
(odp->type == TYPE_CDECL) || (odp->type == TYPE_CDECL) ||
(odp->type == TYPE_REGISTER))) (odp->type == TYPE_REGISTER)))
{ {
...@@ -232,6 +234,9 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd ...@@ -232,6 +234,9 @@ static void output_exports( FILE *outfile, int nr_exports, int nr_names, int fwd
switch(odp->type) switch(odp->type)
{ {
case TYPE_STDCALL64:
if (j < 16) mask |= 0x80000000;
/* fall through */
case TYPE_STDCALL: case TYPE_STDCALL:
fprintf( outfile, " { 0xe9, { 0,0,0,0 }, 0xc2, 0x%04x, %s, 0x%08x }", fprintf( outfile, " { 0xe9, { 0,0,0,0 }, 0xc2, 0x%04x, %s, 0x%08x }",
strlen(odp->u.func.arg_types) * sizeof(int), strlen(odp->u.func.arg_types) * sizeof(int),
...@@ -310,6 +315,7 @@ void BuildSpec32File( FILE *outfile ) ...@@ -310,6 +315,7 @@ void BuildSpec32File( FILE *outfile )
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_STDCALL: case TYPE_STDCALL:
case TYPE_STDCALL64:
case TYPE_VARARGS: case TYPE_VARARGS:
case TYPE_CDECL: case TYPE_CDECL:
fprintf( outfile, "extern void %s();\n", odp->u.func.link_name ); fprintf( outfile, "extern void %s();\n", odp->u.func.link_name );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment