Added stdcall64 entry point type to allow correct relay debugging
support for functions that return 64-bit values.
This commit is contained in:
parent
bf69803ce3
commit
a83784944b
|
@ -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
|
||||||
* (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, ... )
|
||||||
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, ... )
|
||||||
|
|
||||||
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, ... )
|
||||||
}
|
}
|
||||||
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, ... )
|
||||||
assert(FALSE);
|
assert(FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ret64)
|
||||||
|
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",
|
DPRINTF( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
|
||||||
buffer, ret, ret_addr, __get_fs() );
|
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
|
||||||
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
|
||||||
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] =
|
||||||
"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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
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)
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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 )
|
||||||
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 );
|
||||||
|
|
Loading…
Reference in New Issue