From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_i386.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 9485ffe6a85..d62d966f7aa 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -466,9 +466,10 @@ struct syscall_frame * 32-bit mode, but some processors fault if they're not in writable memory. */ DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */ + UINT syscall_cfa; /* 380 */ };
-C_ASSERT( sizeof(struct syscall_frame) == 0x380 ); +C_ASSERT( sizeof(struct syscall_frame) == 0x3c0 );
struct x86_thread_data { @@ -1590,9 +1591,10 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, __ASM_CFI(".cfi_rel_offset %edi,-12\n\t") "movl 0x20(%ebp),%edx\n\t" /* teb */ "pushl 0(%edx)\n\t" /* teb->Tib.ExceptionList */ - "subl $0x384,%esp\n\t" /* sizeof(struct syscall_frame) + ebp */ + "subl $0x3c0,%esp\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%esp\n\t" - "movl %ebp,0x380(%esp)\n\t" + "leal 8(%ebp),%eax\n\t" + "movl %eax,0x380(%esp)\n\t" /* frame->syscall_cfa */ "movl 0x1f8(%edx),%ecx\n\t" /* x86_thread_data()->syscall_frame */ "movl (%ecx),%eax\n\t" /* frame->syscall_flags */ "movl %eax,(%esp)\n\t" @@ -1622,7 +1624,8 @@ __ASM_GLOBAL_FUNC( user_mode_callback_return, "movl 0x1f8(%edx),%eax\n\t" /* x86_thread_data()->syscall_frame */ "movl 0x3c(%eax),%ecx\n\t" /* frame->prev_frame */ "movl %ecx,0x1f8(%edx)\n\t" /* x86_thread_data()->syscall_frame */ - "movl 0x380(%eax),%ebp\n\t" /* call_user_mode_callback ebp */ + "movl 0x380(%eax),%ebp\n\t" /* frame->syscall_cfa */ + "subl $8,%ebp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") @@ -2420,6 +2423,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; struct syscall_frame *frame = thread_data->syscall_frame; CONTEXT *ctx, context = { CONTEXT_ALL }; + UINT syscall_cfa = frame->syscall_cfa; DWORD *stack;
ldt_set_fs( thread_data->fs, teb ); @@ -2461,6 +2465,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->syscall_flags = syscall_flags; frame->syscall_table = KeServiceDescriptorTable; frame->restore_flags |= LOWORD(CONTEXT_INTEGER); + frame->syscall_cfa = syscall_cfa;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); @@ -2489,11 +2494,13 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "movl 0x1f8(%ecx),%eax\n\t" /* x86_thread_data()->syscall_frame */ "orl %eax,%eax\n\t" "jnz 1f\n\t" - "leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ + "leal -0x3c0(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%eax\n\t" "movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */ /* switch to kernel stack */ "1:\tmovl %eax,%esp\n\t" + "leal 8(%ebp),%eax\n\t" + "movl %eax,0x380(%esp)\n\t" /* frame->syscall_cfa */ "pushl %ecx\n\t" /* teb */ "pushl 16(%ebp)\n\t" /* suspend */ "pushl 12(%ebp)\n\t" /* arg */