Module: wine Branch: master Commit: 6b78bcff921826c9b490a88b6759f8c65f17fa3f URL: https://source.winehq.org/git/wine.git/?a=commit;h=6b78bcff921826c9b490a88b6...
Author: Paul Gofman pgofman@codeweavers.com Date: Tue Dec 21 16:09:25 2021 +0300
ntdll: Restore FP status words from MSVCRT_JUMP_BUFFER on x64.
Signed-off-by: Paul Gofman pgofman@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/signal_x86_64.c | 7 ++++++- dlls/ntdll/tests/exception.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index e0372b111fd..7e77329363c 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -64,7 +64,9 @@ struct MSVCRT_JUMP_BUFFER ULONG64 R14; ULONG64 R15; ULONG64 Rip; - ULONG64 Spare; + ULONG MxCsr; + USHORT FpCsr; + USHORT Spare; M128A Xmm6; M128A Xmm7; M128A Xmm8; @@ -1218,6 +1220,9 @@ void CDECL RtlRestoreContext( CONTEXT *context, EXCEPTION_RECORD *rec ) context->u.s.Xmm13 = jmp->Xmm13; context->u.s.Xmm14 = jmp->Xmm14; context->u.s.Xmm15 = jmp->Xmm15; + context->MxCsr = jmp->MxCsr; + context->u.FltSave.MxCsr = jmp->MxCsr; + context->u.FltSave.ControlWord = jmp->FpCsr; } else if (rec && rec->ExceptionCode == STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters >= 1) { diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 2bceca204be..4307016f149 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -2460,6 +2460,10 @@ static void test_restore_context(void) rec.NumberParameters = 1; rec.ExceptionInformation[0] = (DWORD64)&buf;
+ ok(buf.MxCsr == 0x1f80, "Got unexpected MxCsr %#x.\n", buf.MxCsr); + ok(buf.FpCsr == 0x27f, "Got unexpected FpCsr %#x.\n", buf.FpCsr); + buf.FpCsr = 0x7f; + buf.MxCsr = 0x3f80; /* uses buf.Rip instead of ctx.Rip */ pRtlRestoreContext(&ctx, &rec); ok(0, "shouldn't be reached\n"); @@ -2487,6 +2491,18 @@ static void test_restore_context(void) "longjmp failed for Xmm%d, expected %lx, got %lx\n", i + 6, fltsave[i].Part[1], ctx.FltSave.XmmRegisters[i + 6].High); } + ok(ctx.FltSave.ControlWord == 0x7f, "Got unexpected float control word %#x.\n", ctx.FltSave.ControlWord); + ok(ctx.MxCsr == 0x3f80, "Got unexpected MxCsr %#x.\n", ctx.MxCsr); + ok(ctx.FltSave.MxCsr == 0x3f80, "Got unexpected MxCsr %#x.\n", ctx.FltSave.MxCsr); + buf.FpCsr = 0x27f; + buf.MxCsr = 0x1f80; + pRtlRestoreContext(&ctx, &rec); + ok(0, "shouldn't be reached\n"); + } + else if (pass == 5) + { + ok(ctx.FltSave.ControlWord == 0x27f, "Got unexpected float control word %#x.\n", ctx.FltSave.ControlWord); + ok(ctx.FltSave.MxCsr == 0x1f80, "Got unexpected MxCsr %#x.\n", ctx.MxCsr); } else ok(0, "unexpected pass %d\n", pass);