From: Jinoh Kang jinoh.kang.kr@gmail.com
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/ntdll/tests/exception.c | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 820e435bc1b..ee486380b8d 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -10673,6 +10673,90 @@ static void test_copy_context(void) dst_xs->Mask == 4, sizeof(dst_xs->YmmContext)); } } + +static DWORD WINAPI signal_and_wait_proc( void *arg ) +{ + HANDLE *events = arg; + /* Atomically signal and wait to put thread in blocking state */ + return SignalObjectAndWait(events[0], events[1], INFINITE, FALSE); +} + +static void test_eflags_sanitization(void) +{ +#if defined(__x86_64__) + static const DWORD max_eflags = 0x00210fd5; + static const DWORD min_eflags = 0x00000200; +#elif defined(__i386__) + static const DWORD max_eflags = 0x003f0fd7; + static const DWORD min_eflags = 0x00000202; +#endif + HANDLE event_in, event_out; + HANDLE thread; + HANDLE thread_args[2]; + HANDLE waits[2]; + NTSTATUS status; + CONTEXT context; + DWORD result, old_eflags; + int i; + + event_in = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(event_in != NULL, "CreateEventW failed with %#lx\n", GetLastError()); + event_out = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(event_out != NULL, "CreateEventW failed with %#lx\n", GetLastError()); + + thread_args[0] = event_in; + thread_args[1] = event_out; + thread = CreateThread(NULL, 0, signal_and_wait_proc, thread_args, CREATE_SUSPENDED, NULL); + ok(thread != NULL, "CreateThread failed with %#lx.\n", GetLastError()); + + for (i = 0; ; i++) + { + context.ContextFlags = CONTEXT_CONTROL; + status = pNtGetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); + old_eflags = context.EFlags; + + context.EFlags = -1; + status = pNtSetContextThread(thread, &context); + 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, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags); + + context.EFlags = 0; + status = pNtSetContextThread(thread, &context); + 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", max_eflags, context.EFlags); + + context.EFlags = old_eflags; + status = pNtSetContextThread(thread, &context); + ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); + + if (i == 1) break; + + ResumeThread(thread); + waits[0] = event_in; + waits[1] = thread; + result = WaitForMultipleObjects(2, waits, FALSE, INFINITE); + ok(result == WAIT_OBJECT_0, "Expected WAIT_OBJECT_0, got %#lx\n", result); + } + + ok(SetEvent(event_out), "SetEvent failed: %#lx\n", GetLastError()); + + result = WaitForSingleObject(thread, INFINITE); + ok(result == WAIT_OBJECT_0, "Expected WAIT_OBJECT_0, got %#lx\n", result); + + ok(GetExitCodeThread(thread, &result), "Failed to get thread exit code: %#lx\n", GetLastError()); + ok(result == WAIT_OBJECT_0, "Expected WAIT_OBJECT_0, got %#lx\n", result); + + CloseHandle(thread); + CloseHandle(event_in); + CloseHandle(event_out); +} #endif
START_TEST(exception) @@ -10847,6 +10931,7 @@ START_TEST(exception) test_kiuserexceptiondispatcher(); test_extended_context(); test_copy_context(); + test_eflags_sanitization();
#elif defined(__x86_64__)
@@ -10891,6 +10976,7 @@ START_TEST(exception) test_copy_context(); test_unwind_from_apc(); test_syscall_clobbered_regs(); + test_eflags_sanitization();
#elif defined(__aarch64__)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117296
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w7u_adm (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w7u_el (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w8 (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w8adm (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
On Mon, 20 Jun 2022, Marvin wrote: [...]
=== w7u_2qxl (32 bit report) === === w8 (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
As far as I can tell these are indeed new failures. So it looks like this patch needs to be tweaked to work on Windows 7 and 8.
On 6/21/22 00:34, Francois Gouget wrote:
On Mon, 20 Jun 2022, Marvin wrote: [...]
=== w7u_2qxl (32 bit report) === === w8 (32 bit report) ===
ntdll: exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10725: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10733: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
As far as I can tell these are indeed new failures. So it looks like this patch needs to be tweaked to work on Windows 7 and 8.
I have resolved that in v2.
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 | 20 +++++++++++++++++++- dlls/ntdll/unix/unix_private.h | 13 +++++++++++++ 5 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index ee486380b8d..169045bf5e6 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -10721,7 +10721,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, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags);
context.EFlags = 0; @@ -10729,7 +10728,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", max_eflags, context.EFlags);
context.EFlags = old_eflags; diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 7be0c39c424..9be0769904d 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -941,7 +941,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 6c87e347eac..c4f67a16cc9 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1788,7 +1788,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 ); frame->cs = context->SegCs; frame->ss = context->SegSs; } @@ -2002,7 +2002,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 ad47a5fce74..e0d44bb4a38 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1663,13 +1663,31 @@ 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; NTSTATUS 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: + continue; + } + *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 795fc148479..3558f898b36 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -458,4 +458,17 @@ 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: + return (flags & 0x003f0fd7) | 0x00000202; + case IMAGE_FILE_MACHINE_AMD64: + return (flags & 0x00210fd5) | 0x00000200; + default: + return flags; + } +} + #endif /* __NTDLL_UNIX_PRIVATE_H */
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117297
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntdll: exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w7u_adm (32 bit report) ===
ntdll: exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w7u_el (32 bit report) ===
ntdll: exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3f4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w8 (32 bit report) ===
ntdll: exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200
=== w8adm (32 bit report) ===
ntdll: exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200 exception.c:10724: Test failed: Expected EFlags to be 0x3f0fd7, got 0x3d4fd7 exception.c:10731: Test failed: Expected EFlags to be 0x3f0fd7, got 0x200