Alexandre Julliard : ntdll: Make __wine_call_from_32_restore_regs take a context pointer.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Dec 19 03:22:41 CST 2005


Module: wine
Branch: refs/heads/master
Commit: 8651ceb18e5bfff69421c2c85c323fff84ef6a82
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=8651ceb18e5bfff69421c2c85c323fff84ef6a82

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec 19 09:59:50 2005 +0100

ntdll: Make __wine_call_from_32_restore_regs take a context pointer.
Changed exception raise functions to call it explicitly.

---

 dlls/ntdll/signal_i386.c |   55 +++++++++++++++++++++++++++++++---------------
 tools/winebuild/relay.c  |    2 +-
 2 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 4c0529f..d11e37d 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -452,7 +452,7 @@ static size_t signal_stack_size;
 
 static wine_signal_handler handlers[256];
 
-extern void DECLSPEC_NORETURN __wine_call_from_32_restore_regs( CONTEXT context );
+extern void DECLSPEC_NORETURN __wine_call_from_32_restore_regs( const CONTEXT *context );
 
 
 /***********************************************************************
@@ -703,6 +703,7 @@ inline static void *init_handler( const 
  */
 inline static void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
 {
+    context->ContextFlags |= CONTEXT86_FLOATING_POINT;
 #ifdef FPU_sig
     if (FPU_sig(sigcontext))
     {
@@ -794,6 +795,20 @@ inline static void restore_context( cons
 
 
 /***********************************************************************
+ *           set_cpu_context
+ *
+ * Set the new CPU context.
+ */
+inline static void DECLSPEC_NORETURN set_cpu_context( CONTEXT *context )
+{
+    DWORD flags = context->ContextFlags & ~CONTEXT_i386;
+
+    if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context );
+    __wine_call_from_32_restore_regs( context );
+}
+
+
+/***********************************************************************
  *           is_privileged_instr
  *
  * Check if the fault location is a privileged instruction.
@@ -872,7 +887,6 @@ static EXCEPTION_RECORD *setup_exception
         void             *ret_addr;      /* return address from raise_func */
         EXCEPTION_RECORD *rec_ptr;       /* first arg for raise_func */
         CONTEXT          *context_ptr;   /* second arg for raise_func */
-        void             *dummy;         /* dummy ret addr for __wine_call_from_32_restore_regs */
         CONTEXT           context;
         EXCEPTION_RECORD  rec;
         DWORD             ebp;
@@ -912,7 +926,7 @@ static EXCEPTION_RECORD *setup_exception
     }
 
     stack--;  /* push the stack_layout structure */
-    stack->ret_addr     = __wine_call_from_32_restore_regs;
+    stack->ret_addr     = (void *)0xdeadbabe;  /* raise_func must not return */
     stack->rec_ptr      = &stack->rec;
     stack->context_ptr  = &stack->context;
 
@@ -977,16 +991,13 @@ static inline DWORD get_fpu_code( const 
 /**********************************************************************
  *		raise_segv_exception
  */
-static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
+static void WINAPI DECLSPEC_NORETURN raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
 {
     switch(rec->ExceptionCode)
     {
     case EXCEPTION_ACCESS_VIOLATION:
         if (rec->NumberParameters == 2)
-        {
-            if (!(rec->ExceptionCode = VIRTUAL_HandleFault( (void *)rec->ExceptionInformation[1] )))
-                return;
-        }
+            rec->ExceptionCode = VIRTUAL_HandleFault( (void *)rec->ExceptionInformation[1] );
         break;
     case EXCEPTION_DATATYPE_MISALIGNMENT:
         /* FIXME: pass through exception handler first? */
@@ -994,18 +1005,20 @@ static void WINAPI raise_segv_exception(
         {
             /* Disable AC flag, return */
             context->EFlags &= ~0x00040000;
-            return;
+            goto done;
         }
         break;
     }
     __regs_RtlRaiseException( rec, context );
+done:
+    set_cpu_context( context );
 }
 
 
 /**********************************************************************
  *		raise_trap_exception
  */
-static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
+static void WINAPI DECLSPEC_NORETURN raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
 {
     DWORD dr0, dr1, dr2, dr3, dr6, dr7;
 
@@ -1043,16 +1056,20 @@ static void WINAPI raise_trap_exception(
         context->ContextFlags = CONTEXT_DEBUG_REGISTERS;
         NtSetContextThread(GetCurrentThread(), context);
     }
+    context->ContextFlags = CONTEXT_FULL;  /* restore flags */
+    set_cpu_context( context );
 }
 
 
 /**********************************************************************
- *		raise_fpu_exception
+ *		raise_exception
+ *
+ * Generic raise function for exceptions that don't need special treatment.
  */
-static void WINAPI raise_fpu_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
+static void WINAPI DECLSPEC_NORETURN raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
 {
     __regs_RtlRaiseException( rec, context );
-    restore_fpu( context );
+    set_cpu_context( context );
 }
 
 
@@ -1060,7 +1077,7 @@ static void WINAPI raise_fpu_exception( 
 /**********************************************************************
  *		raise_vm86_sti_exception
  */
-static void WINAPI raise_vm86_sti_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
+static void WINAPI DECLSPEC_NORETURN raise_vm86_sti_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
 {
     /* merge_vm86_pending_flags merges the vm86_pending flag in safely */
     NtCurrentTeb()->vm86_pending |= VIP_MASK;
@@ -1071,7 +1088,7 @@ static void WINAPI raise_vm86_sti_except
             ((char*)context->Eip <= (char*)vm86_return_end) &&
             (VM86_TYPE(context->Eax) != VM86_SIGNAL)) {
             /* exiting from VM86, can't throw */
-            return;
+            goto done;
         }
         merge_vm86_pending_flags( rec );
     }
@@ -1083,6 +1100,8 @@ static void WINAPI raise_vm86_sti_except
         NtCurrentTeb()->vm86_pending = 0;
         __regs_RtlRaiseException( rec, context );
     }
+done:
+    set_cpu_context( context );
 }
 
 
@@ -1200,7 +1219,7 @@ static HANDLER_DEF(trap_handler)
  */
 static HANDLER_DEF(fpe_handler)
 {
-    EXCEPTION_RECORD *rec = setup_exception( HANDLER_CONTEXT, raise_fpu_exception );
+    EXCEPTION_RECORD *rec = setup_exception( HANDLER_CONTEXT, raise_exception );
     CONTEXT *context;
 
     context = get_exception_context( rec );
@@ -1239,7 +1258,7 @@ static HANDLER_DEF(int_handler)
     init_handler( HANDLER_CONTEXT, &fs, &gs );
     if (!dispatch_signal(SIGINT))
     {
-        EXCEPTION_RECORD *rec = setup_exception( HANDLER_CONTEXT, __regs_RtlRaiseException );
+        EXCEPTION_RECORD *rec = setup_exception( HANDLER_CONTEXT, raise_exception );
         rec->ExceptionCode = CONTROL_C_EXIT;
     }
 }
@@ -1251,7 +1270,7 @@ static HANDLER_DEF(int_handler)
  */
 static HANDLER_DEF(abrt_handler)
 {
-    EXCEPTION_RECORD *rec = setup_exception( HANDLER_CONTEXT, __regs_RtlRaiseException );
+    EXCEPTION_RECORD *rec = setup_exception( HANDLER_CONTEXT, raise_exception );
     rec->ExceptionCode  = EXCEPTION_WINE_ASSERTION;
     rec->ExceptionFlags = EH_NONCONTINUABLE;
 }
diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c
index de8dd60..60ed6cc 100644
--- a/tools/winebuild/relay.c
+++ b/tools/winebuild/relay.c
@@ -850,7 +850,7 @@ static void BuildCallFrom32Regs( FILE *o
     output_function_size( outfile, "__wine_call_from_32_regs" );
 
     function_header( outfile, "__wine_call_from_32_restore_regs" );
-    fprintf( outfile, "\tleal 4(%%esp),%%ecx\n" );
+    fprintf( outfile, "\tmovl 4(%%esp),%%ecx\n" );
     fprintf( outfile, "\tjmp 2b\n" );
     output_function_size( outfile, "__wine_call_from_32_restore_regs" );
 }




More information about the wine-cvs mailing list