[2/3] ntdll: Implement handling of int $0x2d for x86_64.

Sebastian Lackner sebastian at fds-team.de
Thu Feb 18 02:58:36 CST 2016


Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
 dlls/ntdll/signal_x86_64.c |   53 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 0c64541..be5a342 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2170,6 +2170,17 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun
 }
 
 
+/***********************************************************************
+ *           get_exception_context
+ *
+ * Get a pointer to the context built by setup_exception.
+ */
+static inline CONTEXT *get_exception_context( EXCEPTION_RECORD *rec )
+{
+    return (CONTEXT *)rec - 1;  /* cf. stack_layout structure */
+}
+
+
 /**********************************************************************
  *           find_function_info
  */
@@ -2513,9 +2524,20 @@ static void raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
                 set_cpu_context( context );
         }
         break;
+    case EXCEPTION_BREAKPOINT:
+        switch (rec->ExceptionInformation[0])
+        {
+            case 1: /* BREAKPOINT_PRINT */
+            case 3: /* BREAKPOINT_LOAD_SYMBOLS */
+            case 4: /* BREAKPOINT_UNLOAD_SYMBOLS */
+            case 5: /* BREAKPOINT_COMMAND_STRING (>= Win2003) */
+                goto done;
+        }
+        break;
     }
     status = raise_exception( rec, context, TRUE );
     if (status) raise_status( status, rec );
+done:
     set_cpu_context( context );
 }
 
@@ -2533,6 +2555,28 @@ static void raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
 }
 
 
+/***********************************************************************
+ *           handle_interrupt
+ *
+ * Handle an interrupt.
+ */
+static inline BOOL handle_interrupt( unsigned int interrupt, EXCEPTION_RECORD *rec, CONTEXT *context )
+{
+    switch(interrupt)
+    {
+    case 0x2d:
+        context->Rip += 3;
+        rec->ExceptionCode = EXCEPTION_BREAKPOINT;
+        rec->ExceptionAddress = (void *)context->Rip;
+        rec->NumberParameters = 1;
+        rec->ExceptionInformation[0] = context->Rax;
+        return TRUE;
+    default:
+        return FALSE;
+    }
+}
+
+
 /**********************************************************************
  *		segv_handler
  *
@@ -2560,8 +2604,13 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
     case TRAP_x86_SEGNPFLT:  /* Segment not present exception */
     case TRAP_x86_PROTFLT:   /* General protection fault */
     case TRAP_x86_UNKNOWN:   /* Unknown fault code */
-        rec->ExceptionCode = ERROR_sig(ucontext) ? EXCEPTION_ACCESS_VIOLATION : EXCEPTION_PRIV_INSTRUCTION;
-        rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+        {
+            CONTEXT *win_context = get_exception_context( rec );
+            WORD err = ERROR_sig(ucontext);
+            if ((err & 7) == 2 && handle_interrupt( err >> 3, rec, win_context )) break;
+            rec->ExceptionCode = err ? EXCEPTION_ACCESS_VIOLATION : EXCEPTION_PRIV_INSTRUCTION;
+            rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+        }
         break;
     case TRAP_x86_PAGEFLT:  /* Page fault */
         rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
-- 
2.7.1



More information about the wine-patches mailing list