Sebastian Lackner : ntdll: Implement handling of int $0x2d for x86_64.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Apr 12 06:45:26 CDT 2016
Module: wine
Branch: stable
Commit: 58264a1ed8b96a5a6ecbb95483666500ce341e06
URL: http://source.winehq.org/git/wine.git/?a=commit;h=58264a1ed8b96a5a6ecbb95483666500ce341e06
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Thu Feb 18 09:58:36 2016 +0100
ntdll: Implement handling of int $0x2d for x86_64.
Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit e1d68b2e169580be8dc6f8927e01a19c60f79d65)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
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;
More information about the wine-cvs
mailing list