Module: wine Branch: master Commit: 22d5180b9fd9138a9f196f9135a2bf0b21bdd25e URL: http://source.winehq.org/git/wine.git/?a=commit;h=22d5180b9fd9138a9f196f9135...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Aug 24 19:44:01 2010 +0200
winebuild: Support relay debugging for thiscall functions.
---
dlls/ntdll/relay.c | 13 ++++++++----- tools/winebuild/spec32.c | 11 +++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/relay.c b/dlls/ntdll/relay.c index 95575bb..cd9412c 100644 --- a/dlls/ntdll/relay.c +++ b/dlls/ntdll/relay.c @@ -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)) diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index cf0b76e..330db30 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -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" );