Commit 8b8ddffa authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ntdll: Preserve syscall frame when calling async IO system APC.

The frame can currently be reset from ws2_32.dll async IO callbacks which are still in the user part and are calling 'syscall' functions. If the user APC is processed after that during the same call to server_select(), the call_user_apc_dispatcher() faults. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49782Signed-off-by: 's avatarPaul Gofman <pgofman@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent a23c5428
......@@ -389,8 +389,24 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
{
IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb );
NTSTATUS (**user)(void *, IO_STATUS_BLOCK *, NTSTATUS) = wine_server_get_ptr( call->async_io.user );
void *saved_frame = get_syscall_frame();
void *frame;
result->type = call->type;
result->async_io.status = (*user)( user, iosb, call->async_io.status );
if ((frame = get_syscall_frame()) != saved_frame)
{
/* The frame can be altered by syscalls from ws2_32 async callbacks
* which are currently in the user part. */
static unsigned int once;
if (!once++)
FIXME( "syscall frame changed in APC function, frame %p, saved_frame %p.\n", frame, saved_frame );
set_syscall_frame( saved_frame );
}
if (result->async_io.status != STATUS_PENDING)
result->async_io.total = iosb->Information;
break;
......
......@@ -203,6 +203,15 @@ static inline struct arm_thread_data *arm_thread_data(void)
return (struct arm_thread_data *)ntdll_get_thread_data()->cpu_data;
}
void *get_syscall_frame(void)
{
return arm_thread_data()->syscall_frame;
}
void set_syscall_frame(void *frame)
{
arm_thread_data()->syscall_frame = frame;
}
/***********************************************************************
* unwind_builtin_dll
......
......@@ -157,6 +157,16 @@ static inline struct arm64_thread_data *arm64_thread_data(void)
return (struct arm64_thread_data *)ntdll_get_thread_data()->cpu_data;
}
void *get_syscall_frame(void)
{
return arm64_thread_data()->syscall_frame;
}
void set_syscall_frame(void *frame)
{
arm64_thread_data()->syscall_frame = frame;
}
extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, void *dispatcher );
/***********************************************************************
......
......@@ -495,6 +495,16 @@ static inline struct x86_thread_data *x86_thread_data(void)
return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data;
}
void *get_syscall_frame(void)
{
return x86_thread_data()->syscall_frame;
}
void set_syscall_frame(void *frame)
{
x86_thread_data()->syscall_frame = frame;
}
static inline WORD get_cs(void) { WORD res; __asm__( "movw %%cs,%0" : "=r" (res) ); return res; }
static inline WORD get_ds(void) { WORD res; __asm__( "movw %%ds,%0" : "=r" (res) ); return res; }
static inline WORD get_fs(void) { WORD res; __asm__( "movw %%fs,%0" : "=r" (res) ); return res; }
......
......@@ -306,6 +306,15 @@ static inline struct amd64_thread_data *amd64_thread_data(void)
return (struct amd64_thread_data *)ntdll_get_thread_data()->cpu_data;
}
void *get_syscall_frame(void)
{
return amd64_thread_data()->syscall_frame;
}
void set_syscall_frame(void *frame)
{
amd64_thread_data()->syscall_frame = frame;
}
/***********************************************************************
* Definitions for Dwarf unwind tables
......
......@@ -247,6 +247,9 @@ extern void WINAPI DECLSPEC_NORETURN call_user_exception_dispatcher( EXCEPTION_R
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN;
extern void WINAPI DECLSPEC_NORETURN call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) DECLSPEC_HIDDEN;
extern void *get_syscall_frame(void) DECLSPEC_HIDDEN;
extern void set_syscall_frame(void *frame) DECLSPEC_HIDDEN;
#define TICKSPERSEC 10000000
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment