Brendan Shanks : ntdll: Ensure CONTEXT_EX on exception stack is initialized.
Module: wine Branch: master Commit: a906f13f774ca9fb575cd8cabb48fcb5ac4bf788 URL: https://source.winehq.org/git/wine.git/?a=commit;h=a906f13f774ca9fb575cd8cab... Author: Brendan Shanks <bshanks(a)codeweavers.com> Date: Thu Mar 3 10:24:22 2022 -0800 ntdll: Ensure CONTEXT_EX on exception stack is initialized. On non-AVX CPUs, CONTEXT_EX is not being initialized. In WOW64 mode, this results in invalid exception records when dispatch_wow_exception() uses RtlCopyContext(). Signed-off-by: Brendan Shanks <bshanks(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntdll/unix/signal_i386.c | 23 +++++++++++++++++++---- dlls/ntdll/unix/signal_x86_64.c | 23 +++++++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 6bb5649e2b5..e2a6148d609 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -581,12 +581,23 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer ) xctx->Legacy.Length = sizeof(CONTEXT); xctx->Legacy.Offset = -(LONG)sizeof(CONTEXT); - xctx->XState.Length = sizeof(XSTATE); - xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + if (xstate_buffer) + { + xctx->XState.Length = sizeof(XSTATE); + xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + context->ContextFlags |= CONTEXT_XSTATE; + + xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; + } + else + { + xctx->XState.Length = 25; + xctx->XState.Offset = 0; + + xctx->All.Length = sizeof(CONTEXT) + 24; /* sizeof(CONTEXT_EX) minus 8 alignment bytes on x64. */ + } - xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; xctx->All.Offset = -(LONG)sizeof(CONTEXT); - context->ContextFlags |= CONTEXT_XSTATE; } @@ -1456,6 +1467,10 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout)) memcpy( &dst_xs->YmmContext, &src_xs->YmmContext, sizeof(dst_xs->YmmContext) ); } } + else + { + context_init_xstate( &stack->context, NULL ); + } stack->rec_ptr = &stack->rec; stack->context_ptr = &stack->context; diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 68855dccacf..34334f72ff0 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -411,12 +411,23 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer ) xctx->Legacy.Length = sizeof(CONTEXT); xctx->Legacy.Offset = -(LONG)sizeof(CONTEXT); - xctx->XState.Length = sizeof(XSTATE); - xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + if (xstate_buffer) + { + xctx->XState.Length = sizeof(XSTATE); + xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + context->ContextFlags |= CONTEXT_XSTATE; + + xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; + } + else + { + xctx->XState.Length = 25; + xctx->XState.Offset = 0; + + xctx->All.Length = sizeof(CONTEXT) + 24; /* sizeof(CONTEXT_EX) minus 8 alignment bytes on x64. */ + } - xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; xctx->All.Offset = -(LONG)sizeof(CONTEXT); - context->ContextFlags |= CONTEXT_XSTATE; } static USHORT cs32_sel; /* selector for %cs in 32-bit mode */ @@ -2195,6 +2206,10 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec memcpy( &dst_xs->YmmContext, &src_xs->YmmContext, sizeof(dst_xs->YmmContext) ); } } + else + { + context_init_xstate( &stack->context, NULL ); + } CS_sig(sigcontext) = cs64_sel; RIP_sig(sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher;
participants (1)
-
Alexandre Julliard