 
            From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/thread.c | 9 +++++++++ dlls/ntdll/tests/exception.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c index 7f1a3f5b2fb..2ecc3bb5ed8 100644 --- a/dlls/kernel32/thread.c +++ b/dlls/kernel32/thread.c @@ -55,6 +55,15 @@ __ASM_FASTCALL_FUNC( BaseThreadInitThunk, 12, "call *%edx\n\t" "movl %eax,(%esp)\n\t" "call " __ASM_STDCALL( "RtlExitUserThread", 4 )) +#elif defined(__x86_64__) && defined(__WINE_PE_BUILD) && !defined(__arm64ec__) +__ASM_GLOBAL_FUNC( BaseThreadInitThunk, + "subq $0x28,%rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + "movq %r8,%rcx\n\t" + "call *%rdx\n\t" + "movl %eax,%ecx\n\t" + "call " __ASM_NAME( "RtlExitUserThread" )) #else void __fastcall BaseThreadInitThunk( DWORD unknown, LPTHREAD_START_ROUTINE entry, void *arg ) { diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index c071aa36f65..6d1b29860a1 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -6343,6 +6343,37 @@ static void test_user_callback_context(void) UnregisterClassA(cls.lpszClassName, GetModuleHandleA(0)); }
+static void test_base_init_thunk_unwind(void) +{ + static const BYTE thread_proc_code[] = + { + /* buffer offset 2 */ + 0x49, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, /* movabs imm64,%r8 */ + 0x48, 0x31, 0xc9, /* xor %rcx,%rcx */ + 0x48, 0xc7, 0xc2, 0x00, 0x01, 0x00, 0x00, /* mov $256,%rdx */ + 0x4d, 0x31, 0xc9, /* xor %r9,%r9 */ + 0x48, 0x31, 0xed, /* xor %rbp,%rbp */ + /* RtlCaptureStackBackTrace offset 28 */ + 0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, /* movabs RtlCaptureStackBackTrace, %rax */ + 0xff, 0xe0, /* jmpq *%rax */ + }; + static void *addrs[256]; + HANDLE thread; + BOOL bret; + DWORD count; + + memset( addrs, 0xcc, sizeof(addrs) ); + memcpy( code_mem, thread_proc_code, sizeof(thread_proc_code) ); + *(void **)((char *)code_mem + 2) = addrs; + *(void **)((char *)code_mem + 28) = RtlCaptureStackBackTrace; + thread = CreateThread( NULL, 0, code_mem, NULL, 0, NULL ); + WaitForSingleObject( thread, INFINITE ); + bret = GetExitCodeThread( thread, &count ); + CloseHandle( thread ); + ok( bret, "got error %lu.\n", GetLastError() ); + ok( count == 2, "got count %lu.\n", count ); +} + #elif defined(__arm__)
static void test_thread_context(void) @@ -12587,6 +12618,7 @@ START_TEST(exception) test_instrumentation_callback(); test_direct_syscalls(); test_single_step_address(); + test_base_init_thunk_unwind();
#elif defined(__aarch64__)