winebuild: Support relay debugging for thiscall functions.

This commit is contained in:
Alexandre Julliard 2010-08-24 19:44:01 +02:00
parent adddccb7f9
commit 22d5180b9f
2 changed files with 17 additions and 7 deletions

View File

@ -318,7 +318,7 @@ static inline void RELAY_PrintArgs( const INT_PTR *args, int nb_args, unsigned i
}
}
extern LONGLONG CDECL call_entry_point( void *func, int nb_args, const INT_PTR *args );
extern LONGLONG CDECL call_entry_point( void *func, int nb_args, const INT_PTR *args, int flags );
#ifdef __i386__
__ASM_GLOBAL_FUNC( call_entry_point,
"pushl %ebp\n\t"
@ -340,6 +340,9 @@ __ASM_GLOBAL_FUNC( call_entry_point,
"movl %esp,%edi\n\t"
"cld\n\t"
"rep; movsl\n"
"testl $2,20(%ebp)\n\t" /* (flags & 2) -> thiscall */
"jz 1f\n\t"
"popl %ecx\n\t"
"1:\tcall *8(%ebp)\n\t"
"leal -8(%ebp),%esp\n\t"
"popl %edi\n\t"
@ -404,7 +407,7 @@ static LONGLONG WINAPI relay_call( struct relay_descr *descr, unsigned int idx,
struct relay_entry_point *entry_point = data->entry_points + ordinal;
if (!TRACE_ON(relay))
ret = call_entry_point( entry_point->orig_func, nb_args, stack + 1 );
ret = call_entry_point( entry_point->orig_func, nb_args, stack + 1, flags );
else
{
if (entry_point->name)
@ -414,7 +417,7 @@ static LONGLONG WINAPI relay_call( struct relay_descr *descr, unsigned int idx,
RELAY_PrintArgs( stack + 1, nb_args, descr->arg_types[ordinal] );
DPRINTF( ") ret=%08lx\n", stack[0] );
ret = call_entry_point( entry_point->orig_func, nb_args, stack + 1 );
ret = call_entry_point( entry_point->orig_func, nb_args, stack + 1, flags );
if (entry_point->name)
DPRINTF( "%04x:Ret %s.%s()", GetCurrentThreadId(), data->dllname, entry_point->name );
@ -477,7 +480,7 @@ void WINAPI __regs_relay_call_regs( struct relay_descr *descr, unsigned int idx,
memcpy( args_copy, args, nb_args * sizeof(args[0]) );
args_copy[nb_args++] = (INT_PTR)context; /* append context argument */
call_entry_point( orig_func + 12 + *(int *)(orig_func + 1), nb_args, args_copy );
call_entry_point( orig_func + 12 + *(int *)(orig_func + 1), nb_args, args_copy, 0 );
if (TRACE_ON(relay))
@ -544,7 +547,7 @@ void WINAPI __regs_relay_call_regs( struct relay_descr *descr, INT_PTR idx,
memcpy( args_copy, args, nb_args * sizeof(args[0]) );
args_copy[nb_args++] = (INT_PTR)context; /* append context argument */
call_entry_point( orig_func + 24 + *(int *)(orig_func + 20), nb_args, args_copy );
call_entry_point( orig_func + 24 + *(int *)(orig_func + 20), nb_args, args_copy, 0 );
if (TRACE_ON(relay))

View File

@ -52,7 +52,7 @@ static inline int needs_relay( const ORDDEF *odp )
/* skip nonexistent entry points */
if (!odp) return 0;
/* skip non-functions */
if ((odp->type != TYPE_STDCALL) && (odp->type != TYPE_CDECL)) return 0;
if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL && odp->type != TYPE_THISCALL) return 0;
/* skip norelay and forward entry points */
if (odp->flags & (FLAG_NORELAY|FLAG_FORWARD)) return 0;
return 1;
@ -141,6 +141,13 @@ static void output_relay_debug( DLLSPEC *spec )
switch (target_cpu)
{
case CPU_x86:
if (odp->type == TYPE_THISCALL) /* add the this pointer */
{
output( "\tpopl %%eax\n" );
output( "\tpushl %%ecx\n" );
output( "\tpushl %%eax\n" );
flags |= 2;
}
if (odp->flags & FLAG_REGISTER)
output( "\tpushl %%eax\n" );
else
@ -164,7 +171,7 @@ static void output_relay_debug( DLLSPEC *spec )
else
{
output( "\tcall *4(%%eax)\n" );
if (odp->type == TYPE_STDCALL)
if (odp->type == TYPE_STDCALL || odp->type == TYPE_THISCALL)
output( "\tret $%u\n", args * get_ptr_size() );
else
output( "\tret\n" );