ntdll: Call the thread entry point through BaseThreadInitThunk().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
81a08cea79
commit
1a9558cf9b
|
@ -182,7 +182,7 @@
|
|||
@ stub BaseProcessInitPostImport
|
||||
# @ stub BaseQueryModuleData
|
||||
# @ stub BaseSetLastNTError
|
||||
# @ stub BaseThreadInitThunk
|
||||
@ stdcall -fastcall BaseThreadInitThunk(long ptr ptr)
|
||||
@ stub BaseUpdateAppcompatCache
|
||||
# @ stub BaseVerifyUnicodeString
|
||||
# @ stub Basep8BitStringToDynamicUnicodeString
|
||||
|
|
|
@ -1176,10 +1176,24 @@ static void test_SetThreadContext(void)
|
|||
CloseHandle( thread );
|
||||
}
|
||||
|
||||
static DWORD WINAPI test_stack( void *arg )
|
||||
{
|
||||
DWORD *stack = (DWORD *)(((DWORD)&arg & ~0xfff) + 0x1000);
|
||||
|
||||
ok( stack == NtCurrentTeb()->Tib.StackBase, "wrong stack %p/%p\n",
|
||||
stack, NtCurrentTeb()->Tib.StackBase );
|
||||
ok( !stack[-1], "wrong data %p = %08x\n", stack - 1, stack[-1] );
|
||||
ok( stack[-2] == (DWORD)arg, "wrong data %p = %08x\n", stack - 2, stack[-2] );
|
||||
ok( stack[-3] == (DWORD)test_stack, "wrong data %p = %08x\n", stack - 3, stack[-3] );
|
||||
ok( !stack[-4], "wrong data %p = %08x\n", stack - 4, stack[-4] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_GetThreadContext(void)
|
||||
{
|
||||
CONTEXT ctx;
|
||||
BOOL ret;
|
||||
HANDLE thread;
|
||||
|
||||
memset(&ctx, 0xcc, sizeof(ctx));
|
||||
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||
|
@ -1188,6 +1202,10 @@ static void test_GetThreadContext(void)
|
|||
ok(ctx.ContextFlags == CONTEXT_DEBUG_REGISTERS, "ContextFlags = %x\n", ctx.ContextFlags);
|
||||
ok(!ctx.Dr0, "Dr0 = %x\n", ctx.Dr0);
|
||||
ok(!ctx.Dr1, "Dr0 = %x\n", ctx.Dr0);
|
||||
|
||||
thread = CreateThread( NULL, 0, test_stack, (void *)0x1234, 0, NULL );
|
||||
WaitForSingleObject( thread, 1000 );
|
||||
CloseHandle( thread );
|
||||
}
|
||||
|
||||
static void test_GetThreadSelectorEntry(void)
|
||||
|
|
|
@ -31,9 +31,38 @@
|
|||
#include "winerror.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "wine/asm.h"
|
||||
#include "kernel_private.h"
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
__ASM_STDCALL_FUNC( __fastcall_BaseThreadInitThunk, 12,
|
||||
"pushl %ebp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||
"movl %esp,%ebp\n\t"
|
||||
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||
"pushl %ebx\n\t"
|
||||
__ASM_CFI(".cfi_rel_offset %ebx,-4\n\t")
|
||||
"movl 8(%ebp),%ebx\n\t"
|
||||
/* deliberately mis-align the stack by 8, Doom 3 needs this */
|
||||
"pushl 4(%ebp)\n\t" /* Driller expects readable address at this offset */
|
||||
"pushl 4(%ebp)\n\t"
|
||||
"pushl %ebx\n\t"
|
||||
"call *%edx\n\t"
|
||||
"movl %eax,(%esp)\n\t"
|
||||
"call " __ASM_STDCALL( "RtlExitUserThread", 4 ))
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* BaseThreadInitThunk (KERNEL32.@)
|
||||
*/
|
||||
void __fastcall BaseThreadInitThunk( DWORD unknown, LPTHREAD_START_ROUTINE entry, void *arg )
|
||||
{
|
||||
RtlExitUserThread( entry( arg ) );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* FreeLibraryAndExitThread (KERNEL32.@)
|
||||
*/
|
||||
|
|
|
@ -58,6 +58,7 @@ WINE_DECLARE_DEBUG_CHANNEL(imports);
|
|||
typedef DWORD (CALLBACK *DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
|
||||
typedef void (CALLBACK *LDRENUMPROC)(LDR_DATA_TABLE_ENTRY *, void *, BOOLEAN *);
|
||||
|
||||
void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) = NULL;
|
||||
static void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void *);
|
||||
|
||||
const struct unix_funcs *unix_funcs = NULL;
|
||||
|
@ -4008,6 +4009,13 @@ static void process_init(void)
|
|||
MESSAGE( "wine: could not find __wine_start_process in kernel32.dll, status %x\n", status );
|
||||
NtTerminateProcess( GetCurrentProcess(), status );
|
||||
}
|
||||
RtlInitAnsiString( &func_name, "BaseThreadInitThunk" );
|
||||
if ((status = LdrGetProcedureAddress( wm->ldr.DllBase, &func_name,
|
||||
0, (void **)&pBaseThreadInitThunk )) != STATUS_SUCCESS)
|
||||
{
|
||||
MESSAGE( "wine: could not find BaseThreadInitThunk in kernel32.dll, status %x\n", status );
|
||||
NtTerminateProcess( GetCurrentProcess(), status );
|
||||
}
|
||||
|
||||
init_locale( wm->ldr.DllBase );
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ extern const WCHAR windows_dir[] DECLSPEC_HIDDEN;
|
|||
extern const WCHAR system_dir[] DECLSPEC_HIDDEN;
|
||||
extern const WCHAR syswow64_dir[] DECLSPEC_HIDDEN;
|
||||
|
||||
extern void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) DECLSPEC_HIDDEN;
|
||||
extern const struct unix_funcs *unix_funcs DECLSPEC_HIDDEN;
|
||||
|
||||
extern void init_directories(void) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -105,37 +105,32 @@ void WINAPI RtlExitUserThread( ULONG status )
|
|||
*/
|
||||
#ifdef __i386__
|
||||
__ASM_STDCALL_FUNC( RtlUserThreadStart, 8,
|
||||
"pushl %ebp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||
"movl %esp,%ebp\n\t"
|
||||
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||
"pushl %ebx\n\t" /* arg */
|
||||
"pushl %eax\n\t" /* entry */
|
||||
"call " __ASM_NAME("call_thread_func") )
|
||||
"movl %ebx,8(%esp)\n\t" /* arg */
|
||||
"movl %eax,4(%esp)\n\t" /* entry */
|
||||
"jmp " __ASM_NAME("call_thread_func") )
|
||||
|
||||
/* wrapper for apps that don't declare the thread function correctly */
|
||||
extern DWORD call_thread_func_wrapper( PRTL_THREAD_START_ROUTINE entry, void *arg );
|
||||
__ASM_GLOBAL_FUNC(call_thread_func_wrapper,
|
||||
/* wrapper to call BaseThreadInitThunk */
|
||||
extern void DECLSPEC_NORETURN call_thread_func_wrapper( void *thunk, PRTL_THREAD_START_ROUTINE entry, void *arg );
|
||||
__ASM_GLOBAL_FUNC( call_thread_func_wrapper,
|
||||
"pushl %ebp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||
"movl %esp,%ebp\n\t"
|
||||
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||
"subl $4,%esp\n\t"
|
||||
"pushl 12(%ebp)\n\t"
|
||||
"call *8(%ebp)\n\t"
|
||||
"leave\n\t"
|
||||
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
|
||||
__ASM_CFI(".cfi_same_value %ebp\n\t")
|
||||
"ret" )
|
||||
"subl $4,%esp\n\t"
|
||||
"andl $~0xf,%esp\n\t"
|
||||
"xorl %ecx,%ecx\n\t"
|
||||
"movl 12(%ebp),%edx\n\t"
|
||||
"movl 16(%ebp),%eax\n\t"
|
||||
"movl %eax,(%esp)\n\t"
|
||||
"call *8(%ebp)" )
|
||||
|
||||
void DECLSPEC_HIDDEN call_thread_func( PRTL_THREAD_START_ROUTINE entry, void *arg )
|
||||
{
|
||||
__TRY
|
||||
{
|
||||
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
||||
RtlExitUserThread( call_thread_func_wrapper( entry, arg ));
|
||||
call_thread_func_wrapper( pBaseThreadInitThunk, entry, arg );
|
||||
}
|
||||
__EXCEPT(call_unhandled_exception_filter)
|
||||
{
|
||||
|
@ -151,7 +146,7 @@ void WINAPI RtlUserThreadStart( PRTL_THREAD_START_ROUTINE entry, void *arg )
|
|||
__TRY
|
||||
{
|
||||
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
||||
RtlExitUserThread( ((LPTHREAD_START_ROUTINE)entry)( arg ));
|
||||
pBaseThreadInitThunk( 0, (LPTHREAD_START_ROUTINE)entry, arg );
|
||||
}
|
||||
__EXCEPT(call_unhandled_exception_filter)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue