Module: wine Branch: master Commit: 62b7069fa941c6ac1c923f0a7986261e290862c0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=62b7069fa941c6ac1c923f0a79...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Oct 19 12:59:58 2011 +0200
ntdll: Unwind the stack before calling exit/abort_thread on i386 the same way we do on x86_64.
---
dlls/ntdll/ntdll_misc.h | 4 +++ dlls/ntdll/signal_i386.c | 49 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 4956537..20f1c45 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -224,6 +224,10 @@ struct ntdll_thread_data int wait_fd[2]; /* 1ec/300 fd for sleeping server requests */ BOOL wow64_redir; /* 1f4/308 Wow64 filesystem redirection flag */ pthread_t pthread_id; /* 1f8/310 pthread thread id */ +#ifdef __i386__ + WINE_VM86_TEB_INFO vm86; /* 1fc vm86 private data */ + void *exit_frame; /* 204 exit frame pointer */ +#endif };
static inline struct ntdll_thread_data *ntdll_get_thread_data(void) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 6c8e8e2..e839994 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2473,9 +2473,41 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, }
+extern void DECLSPEC_NORETURN call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ); +__ASM_GLOBAL_FUNC( call_thread_entry_point, + "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") + "pushl %esi\n\t" + __ASM_CFI(".cfi_rel_offset %esi,-8\n\t") + "pushl %edi\n\t" + __ASM_CFI(".cfi_rel_offset %edi,-12\n\t") + "pushl %ebp\n\t" + "pushl 12(%ebp)\n\t" + "pushl 8(%ebp)\n\t" + "call " __ASM_NAME("call_thread_func") ); + +extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), void *frame ); +__ASM_GLOBAL_FUNC( call_thread_exit_func, + "movl 4(%esp),%eax\n\t" + "movl 8(%esp),%ecx\n\t" + "movl 12(%esp),%ebp\n\t" + __ASM_CFI(".cfi_def_cfa %ebp,4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + __ASM_CFI(".cfi_rel_offset %ebx,-4\n\t") + __ASM_CFI(".cfi_rel_offset %esi,-8\n\t") + __ASM_CFI(".cfi_rel_offset %edi,-12\n\t") + "leal -20(%ebp),%esp\n\t" + "pushl %eax\n\t" + "call *%ecx" ); + /* wrapper for apps that don't declare the thread function correctly */ -extern void DECLSPEC_NORETURN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg ); -__ASM_GLOBAL_FUNC(call_thread_func, +extern void DECLSPEC_NORETURN call_thread_func_wrapper( LPTHREAD_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") @@ -2490,13 +2522,14 @@ __ASM_GLOBAL_FUNC(call_thread_func, "int $3" )
/*********************************************************************** - * call_thread_entry_point + * call_thread_func */ -void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) +void call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg, void *frame ) { + ntdll_get_thread_data()->exit_frame = frame; __TRY { - call_thread_func( entry, arg ); + call_thread_func_wrapper( entry, arg ); } __EXCEPT(unhandled_exception_filter) { @@ -2511,7 +2544,8 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) */ void WINAPI RtlExitUserThread( ULONG status ) { - exit_thread( status ); + if (!ntdll_get_thread_data()->exit_frame) exit_thread( status ); + call_thread_exit_func( status, exit_thread, ntdll_get_thread_data()->exit_frame ); }
/*********************************************************************** @@ -2519,7 +2553,8 @@ void WINAPI RtlExitUserThread( ULONG status ) */ void abort_thread( int status ) { - terminate_thread( status ); + if (!ntdll_get_thread_data()->exit_frame) terminate_thread( status ); + call_thread_exit_func( status, terminate_thread, ntdll_get_thread_data()->exit_frame ); }
/**********************************************************************