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 b492ddd5e08..d6d609fc97d 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -11394,7 +11394,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; @@ -11402,7 +11401,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 293b8689c06..ba61c73a7fc 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -944,7 +944,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 71e23ae46fc..d817067215c 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1020,7 +1020,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) { @@ -1225,7 +1225,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 0c433fef4c2..fbd44f9a358 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1707,13 +1707,38 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1 NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USHORT machine ) { context_t 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 701ff58b066..0f6a112867e 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -521,4 +521,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 */