ntdll: Save unwind information in KiUserApcDispatcher() on x64.
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c72f52d7cc
commit
71a43335ab
|
@ -175,6 +175,17 @@ NTSTATUS WINAPI KiUserExceptionDispatcher( EXCEPTION_RECORD *rec, CONTEXT *conte
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserApcDispatcher (NTDLL.@)
|
||||
*/
|
||||
void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
|
||||
PNTAPCFUNC func )
|
||||
{
|
||||
func( ctx, arg1, arg2 );
|
||||
NtContinue( context, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlUnwind (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -523,6 +523,18 @@ NTSTATUS WINAPI KiUserExceptionDispatcher( EXCEPTION_RECORD *rec, CONTEXT *conte
|
|||
return NtRaiseException( rec, context, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserApcDispatcher (NTDLL.@)
|
||||
*/
|
||||
void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
|
||||
PNTAPCFUNC func )
|
||||
{
|
||||
func( ctx, arg1, arg2 );
|
||||
NtContinue( context, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Definitions for Win32 unwind tables
|
||||
*/
|
||||
|
|
|
@ -218,6 +218,18 @@ __ASM_STDCALL_FUNC( KiUserExceptionDispatcher, 8,
|
|||
"call " __ASM_STDCALL("dispatch_exception", 8) "\n\t"
|
||||
"int3" )
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserApcDispatcher (NTDLL.@)
|
||||
*/
|
||||
void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
|
||||
PNTAPCFUNC func )
|
||||
{
|
||||
func( ctx, arg1, arg2 );
|
||||
NtContinue( context, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* save_fpu
|
||||
*
|
||||
|
|
|
@ -590,6 +590,36 @@ __ASM_GLOBAL_FUNC( KiUserExceptionDispatcher,
|
|||
"call " __ASM_NAME("dispatch_exception") "\n\t"
|
||||
"int3")
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserApcDispatcher (NTDLL.@)
|
||||
*/
|
||||
void WINAPI dispatch_apc( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
|
||||
PNTAPCFUNC func )
|
||||
{
|
||||
func( ctx, arg1, arg2 );
|
||||
NtContinue( context, TRUE );
|
||||
}
|
||||
|
||||
__ASM_GLOBAL_FUNC( KiUserApcDispatcher,
|
||||
"addq $0x8,%rsp\n\t"
|
||||
"mov 0x98(%rcx),%r10\n\t" /* context->Rsp */
|
||||
"mov 0xf8(%rcx),%r11\n\t" /* context->Rip */
|
||||
"mov %r11,-0x8(%r10)\n\t"
|
||||
"mov %rbp,-0x10(%r10)\n\t"
|
||||
"lea -0x10(%r10),%rbp\n\t"
|
||||
__ASM_SEH(".seh_pushreg %rbp\n\t")
|
||||
__ASM_SEH(".seh_setframe %rbp,0\n\t")
|
||||
__ASM_SEH(".seh_endprologue\n\t")
|
||||
__ASM_CFI(".cfi_signal_frame\n\t")
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 0x10\n\t")
|
||||
__ASM_CFI(".cfi_def_cfa %rbp,0x10\n\t")
|
||||
__ASM_CFI(".cfi_rel_offset %rip,0x8\n\t")
|
||||
__ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
|
||||
"call " __ASM_NAME("dispatch_apc") "\n\t"
|
||||
"int3")
|
||||
|
||||
|
||||
static ULONG64 get_int_reg( CONTEXT *context, int reg )
|
||||
{
|
||||
return *(&context->Rax + reg);
|
||||
|
|
|
@ -37,6 +37,8 @@ static void *code_mem;
|
|||
|
||||
static NTSTATUS (WINAPI *pNtGetContextThread)(HANDLE,CONTEXT*);
|
||||
static NTSTATUS (WINAPI *pNtSetContextThread)(HANDLE,CONTEXT*);
|
||||
static NTSTATUS (WINAPI *pNtQueueApcThread)(HANDLE handle, PNTAPCFUNC func,
|
||||
ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3);
|
||||
static NTSTATUS (WINAPI *pRtlRaiseException)(EXCEPTION_RECORD *rec);
|
||||
static PVOID (WINAPI *pRtlUnwind)(PVOID, PVOID, PEXCEPTION_RECORD, PVOID);
|
||||
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
|
||||
|
@ -4061,6 +4063,55 @@ static void test_nested_exception(void)
|
|||
ok(got_prev_frame_exception, "Did not get nested exception in the previous frame.\n");
|
||||
}
|
||||
|
||||
static CONTEXT test_unwind_apc_context;
|
||||
static BOOL test_unwind_apc_called;
|
||||
|
||||
static void CALLBACK test_unwind_apc(ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3)
|
||||
{
|
||||
EXCEPTION_RECORD rec;
|
||||
|
||||
test_unwind_apc_called = TRUE;
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
pRtlUnwind((void *)test_unwind_apc_context.Rsp, (void *)test_unwind_apc_context.Rip, &rec, (void *)0xdeadbeef);
|
||||
ok(0, "Should not get here.\n");
|
||||
}
|
||||
|
||||
static void test_unwind_from_apc(void)
|
||||
{
|
||||
NTSTATUS status;
|
||||
int pass;
|
||||
|
||||
if (!pNtQueueApcThread)
|
||||
{
|
||||
win_skip("NtQueueApcThread is not available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pass = 0;
|
||||
InterlockedIncrement(&pass);
|
||||
RtlCaptureContext(&test_unwind_apc_context);
|
||||
InterlockedIncrement(&pass);
|
||||
|
||||
if (pass == 2)
|
||||
{
|
||||
test_unwind_apc_called = FALSE;
|
||||
status = pNtQueueApcThread(GetCurrentThread(), test_unwind_apc, 0, 0, 0);
|
||||
ok(!status, "Got unexpected status %#x.\n", status);
|
||||
SleepEx(0, TRUE);
|
||||
ok(0, "Should not get here.\n");
|
||||
}
|
||||
if (pass == 3)
|
||||
{
|
||||
ok(test_unwind_apc_called, "Test user APC was not called.\n");
|
||||
test_unwind_apc_called = FALSE;
|
||||
status = pNtQueueApcThread(GetCurrentThread(), test_unwind_apc, 0, 0, 0);
|
||||
ok(!status, "Got unexpected status %#x.\n", status);
|
||||
NtContinue(&test_unwind_apc_context, TRUE );
|
||||
ok(0, "Should not get here.\n");
|
||||
}
|
||||
ok(pass == 4, "Got unexpected pass %d.\n", pass);
|
||||
ok(test_unwind_apc_called, "Test user APC was not called.\n");
|
||||
}
|
||||
#elif defined(__arm__)
|
||||
|
||||
static void test_thread_context(void)
|
||||
|
@ -8073,6 +8124,7 @@ START_TEST(exception)
|
|||
#define X(f) p##f = (void*)GetProcAddress(hntdll, #f)
|
||||
X(NtGetContextThread);
|
||||
X(NtSetContextThread);
|
||||
X(NtQueueApcThread);
|
||||
X(NtReadVirtualMemory);
|
||||
X(NtClose);
|
||||
X(RtlUnwind);
|
||||
|
@ -8241,6 +8293,7 @@ START_TEST(exception)
|
|||
skip( "Dynamic unwind functions not found\n" );
|
||||
test_extended_context();
|
||||
test_copy_context();
|
||||
test_unwind_from_apc();
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
|
|
|
@ -75,17 +75,6 @@ int __cdecl __wine_dbg_output( const char *str )
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserApcDispatcher (NTDLL.@)
|
||||
*/
|
||||
void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
|
||||
PNTAPCFUNC func )
|
||||
{
|
||||
func( ctx, arg1, arg2 );
|
||||
NtContinue( context, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlExitUserThread (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -2073,9 +2073,28 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
|
|||
"movq %r14,%r9\n" /* arg2 */
|
||||
"movq $0,0x328(%rbx)\n\t" /* amd64_thread_data()->syscall_frame */
|
||||
"movq %rsi,0x20(%rsp)\n\t" /* func */
|
||||
"movq 0xa0(%rcx),%rbp\n\t" /* context.Rbp */
|
||||
"movq %rdi,%r10\n\t"
|
||||
/* Set nonvolatile regs from context. */
|
||||
"movq 0xa0(%rcx),%rbp\n\t"
|
||||
"movq 0x90(%rcx),%rbx\n\t"
|
||||
"movq 0xa8(%rcx),%rsi\n\t"
|
||||
"movq 0xb0(%rcx),%rdi\n\t"
|
||||
"movq 0xd8(%rcx),%r12\n\t"
|
||||
"movq 0xe0(%rcx),%r13\n\t"
|
||||
"movq 0xe8(%rcx),%r14\n\t"
|
||||
"movq 0xf0(%rcx),%r15\n\t"
|
||||
"movdqa 0x200(%rcx),%xmm6\n\t"
|
||||
"movdqa 0x210(%rcx),%xmm7\n\t"
|
||||
"movdqa 0x220(%rcx),%xmm8\n\t"
|
||||
"movdqa 0x230(%rcx),%xmm9\n\t"
|
||||
"movdqa 0x240(%rcx),%xmm10\n\t"
|
||||
"movdqa 0x250(%rcx),%xmm11\n\t"
|
||||
"movdqa 0x260(%rcx),%xmm12\n\t"
|
||||
"movdqa 0x270(%rcx),%xmm13\n\t"
|
||||
"movdqa 0x280(%rcx),%xmm14\n\t"
|
||||
"movdqa 0x290(%rcx),%xmm15\n\t"
|
||||
"pushq 0xf8(%rcx)\n\t" /* context.Rip */
|
||||
"jmp *%rdi" )
|
||||
"jmp *%r10" )
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
Loading…
Reference in New Issue