Module: wine Branch: master Commit: 0bd24653266dd4cb3c232748f2b0ad115af60092 URL: https://source.winehq.org/git/wine.git/?a=commit;h=0bd24653266dd4cb3c232748f...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Sep 12 19:48:48 2019 +0200
ntdll: Handle breakpoint interrupt in signal handler on i386.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/signal_i386.c | 80 ++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 4087b9b0c1..9ce318c27d 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -1589,30 +1589,6 @@ static inline DWORD is_privileged_instr( 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->Eip += 3; - rec->ExceptionCode = EXCEPTION_BREAKPOINT; - rec->ExceptionAddress = (void *)context->Eip; - rec->NumberParameters = is_wow64 ? 1 : 3; - rec->ExceptionInformation[0] = context->Eax; - rec->ExceptionInformation[1] = context->Ecx; - rec->ExceptionInformation[2] = context->Edx; - return TRUE; - default: - return FALSE; - } -} - - /*********************************************************************** * check_invalid_gs * @@ -1956,21 +1932,6 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context } } break; - case EXCEPTION_BREAKPOINT: - if (!is_wow64) - { - /* On Wow64, the upper DWORD of Rax contains garbage, and the debug - * service is usually not recognized when called from usermode. */ - 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 = NtRaiseException( rec, context, TRUE ); raise_status( status, rec ); @@ -1993,6 +1954,45 @@ static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *cont }
+/*********************************************************************** + * handle_interrupt + * + * Handle an interrupt. + */ +static BOOL handle_interrupt( unsigned int interrupt, ucontext_t *sigcontext, struct stack_layout *stack ) +{ + switch(interrupt) + { + case 0x2d: + if (!is_wow64) + { + /* On Wow64, the upper DWORD of Rax contains garbage, and the debug + * service is usually not recognized when called from usermode. */ + switch (stack->context.Eax) + { + case 1: /* BREAKPOINT_PRINT */ + case 3: /* BREAKPOINT_LOAD_SYMBOLS */ + case 4: /* BREAKPOINT_UNLOAD_SYMBOLS */ + case 5: /* BREAKPOINT_COMMAND_STRING (>= Win2003) */ + EIP_sig(sigcontext) += 3; + return TRUE; + } + } + stack->context.Eip += 3; + stack->rec.ExceptionCode = EXCEPTION_BREAKPOINT; + stack->rec.ExceptionAddress = (void *)stack->context.Eip; + stack->rec.NumberParameters = is_wow64 ? 1 : 3; + stack->rec.ExceptionInformation[0] = stack->context.Eax; + stack->rec.ExceptionInformation[1] = stack->context.Ecx; + stack->rec.ExceptionInformation[2] = stack->context.Edx; + setup_raise_exception( sigcontext, stack, raise_generic_exception ); + return TRUE; + default: + return FALSE; + } +} + + /********************************************************************** * segv_handler * @@ -2051,7 +2051,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { WORD err = get_error_code(context); if (!err && (stack->rec.ExceptionCode = is_privileged_instr( &stack->context ))) break; - if ((err & 7) == 2 && handle_interrupt( err >> 3, &stack->rec, &stack->context )) break; + if ((err & 7) == 2 && handle_interrupt( err >> 3, context, stack )) return; stack->rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION; stack->rec.NumberParameters = 2; stack->rec.ExceptionInformation[0] = 0;