From: Jinoh Kang jinoh.kang.kr@gmail.com
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/ntdll/tests/exception.c | 2 -- dlls/ntdll/unix/signal_i386.c | 2 +- dlls/ntdll/unix/signal_x86_64.c | 4 ++-- dlls/ntdll/unix/thread.c | 27 ++++++++++++++++++++++++++- dlls/ntdll/unix/unix_private.h | 17 +++++++++++++++++ 5 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 250638f868f..2e3bd135b21 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -11648,7 +11648,6 @@ static void test_eflags_sanitization(void) ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); status = pNtGetContextThread(thread, &context); ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); - todo_wine ok(context.EFlags == min_eflags, "Expected EFlags to be %#lx, got %#lx\n", min_eflags, context.EFlags);
context.EFlags = -1; @@ -11656,7 +11655,6 @@ static void test_eflags_sanitization(void) ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); status = pNtGetContextThread(thread, &context); ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); - todo_wine ok(context.EFlags == max_eflags || broken(context.EFlags == max_eflags_broken), "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags);
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index e07896b962b..76ef87b9efe 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -976,7 +976,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) frame->esp = context->Esp; frame->ebp = context->Ebp; frame->eip = context->Eip; - frame->eflags = context->EFlags; + frame->eflags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_I386 ); frame->cs = context->SegCs; frame->ss = context->SegSs; } diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 64494de55f4..c8f9c507e7b 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1073,7 +1073,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) frame->rsp = context->Rsp; frame->rbp = context->Rbp; frame->rip = context->Rip; - frame->eflags = context->EFlags; + frame->eflags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_AMD64 ); } if (flags & CONTEXT_FLOATING_POINT) { @@ -1281,7 +1281,7 @@ NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size ) wow_frame->Esp = context->Esp; wow_frame->Ebp = context->Ebp; wow_frame->Eip = context->Eip; - wow_frame->EFlags = context->EFlags; + wow_frame->EFlags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_I386 ); wow_frame->SegCs = cs32_sel; wow_frame->SegSs = ds64_sel; cpu->Flags |= WOW64_CPURESERVED_FLAG_RESET_STATE; diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index c4086fdf20d..57fc07ee78f 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1753,13 +1753,38 @@ NTSTATUS WINAPI NtQueueApcThreadEx( HANDLE handle, HANDLE reserve_handle, PNTAPC NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USHORT machine ) { struct context_data server_contexts[2]; - unsigned int count = 0; + unsigned int count = 0, i; unsigned int ret;
context_to_server( &server_contexts[count++], native_machine, context, machine ); if (machine != native_machine) context_to_server( &server_contexts[count++], machine, context, machine );
+ for (i = 0; i < count; i++) + { + unsigned int *flags_ptr; + + if (!(server_contexts[i].flags & SERVER_CTX_CONTROL)) continue; + + switch (server_contexts[i].machine) + { + case IMAGE_FILE_MACHINE_I386: + flags_ptr = &server_contexts[i].ctl.i386_regs.eflags; + break; + case IMAGE_FILE_MACHINE_AMD64: + flags_ptr = &server_contexts[i].ctl.x86_64_regs.flags; + break; + default: + flags_ptr = NULL; + break; + } + + if (flags_ptr) + { + *flags_ptr = arch_flags_reg_from_user( *flags_ptr, machine ); + } + } + SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 2e80c8bd02b..a41b5a414e7 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -574,4 +574,21 @@ static inline NTSTATUS map_section( HANDLE mapping, void **ptr, SIZE_T *size, UL 0, NULL, size, ViewShare, 0, protect ); }
+static inline DWORD arch_flags_reg_from_user( DWORD flags, USHORT machine ) +{ + switch (machine) + { + case IMAGE_FILE_MACHINE_I386: + if (machine == native_machine) + { + return (flags & 0x003f4fd7) | 0x00000200; + } + return (flags & 0x003f0fd7) | 0x00000202; + case IMAGE_FILE_MACHINE_AMD64: + return (flags & 0x00210fd5) | 0x00000200; + default: + return flags; + } +} + #endif /* __NTDLL_UNIX_PRIVATE_H */