Alexandre Julliard : winebuild: Support relay debugging for thiscall functions.

Alexandre Julliard julliard at winehq.org
Wed Aug 25 12:35:03 CDT 2010


Module: wine
Branch: master
Commit: 22d5180b9fd9138a9f196f9135a2bf0b21bdd25e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=22d5180b9fd9138a9f196f9135a2bf0b21bdd25e

Author: Alexandre Julliard <julliard at 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" );




More information about the wine-cvs mailing list