ntdll: Implement RtlRaiseException on ARM64EC.
This commit is contained in:
parent
462b27d87f
commit
f35e2d513d
2 changed files with 57 additions and 13 deletions
|
@ -1794,9 +1794,33 @@ void __attribute__((naked)) __chkstk_arm64ec(void)
|
|||
/***********************************************************************
|
||||
* RtlRaiseException (NTDLL.@)
|
||||
*/
|
||||
void WINAPI RtlRaiseException( struct _EXCEPTION_RECORD * rec)
|
||||
void __attribute((naked)) RtlRaiseException( EXCEPTION_RECORD *rec )
|
||||
{
|
||||
FIXME( "not implemented\n" );
|
||||
asm( ".seh_proc RtlRaiseException\n\t"
|
||||
"sub sp, sp, #0x4d0\n\t" /* sizeof(context) */
|
||||
".seh_stackalloc 0x4d0\n\t"
|
||||
"stp x29, x30, [sp, #-0x20]!\n\t"
|
||||
".seh_save_fplr_x 0x20\n\t"
|
||||
"str x0, [sp, #0x10]\n\t"
|
||||
".seh_save_any_reg x0, 0x10\n\t"
|
||||
".seh_endprologue\n\t"
|
||||
"add x0, sp, #0x20\n\t"
|
||||
"bl RtlCaptureContext\n\t"
|
||||
"add x1, sp, #0x20\n\t" /* context pointer */
|
||||
"ldr x0, [sp, #0x10]\n\t" /* rec */
|
||||
"ldr x2, [x1, #0xf8]\n\t" /* context->Rip */
|
||||
"str x2, [x0, #0x10]\n\t" /* rec->ExceptionAddress */
|
||||
"ldr w2, [x1, #0x30]\n\t" /* context->ContextFlags */
|
||||
"orr w2, w2, #0x20000000\n\t" /* CONTEXT_UNWOUND_TO_CALL */
|
||||
"str w2, [x1, #0x30]\n\t"
|
||||
"ldr x3, [x18, #0x60]\n\t" /* peb */
|
||||
"ldrb w2, [x3, #2]\n\t" /* peb->BeingDebugged */
|
||||
"cbnz w2, 1f\n\t"
|
||||
"bl dispatch_exception\n"
|
||||
"1:\tmov w2, #1\n\t"
|
||||
"bl NtRaiseException\n\t"
|
||||
"b RtlRaiseStatus\n\t" /* does not return */
|
||||
".seh_endproc" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3218,13 +3218,23 @@ static void rtlraiseexception_handler_( EXCEPTION_RECORD *rec, void *frame, CONT
|
|||
trace( "exception: %08lx flags:%lx addr:%p context: Rip:%p\n",
|
||||
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, (void *)context->Rip );
|
||||
|
||||
ok( addr == (char *)code_mem + 0x0c || broken( addr == code_mem || !addr ) /* 2008 */,
|
||||
"ExceptionAddress at %p instead of %p\n", addr, (char *)code_mem + 0x0c );
|
||||
|
||||
ok( context->ContextFlags == CONTEXT_ALL || context->ContextFlags == (CONTEXT_ALL | CONTEXT_XSTATE)
|
||||
|| context->ContextFlags == (CONTEXT_FULL | CONTEXT_SEGMENTS)
|
||||
|| context->ContextFlags == (CONTEXT_FULL | CONTEXT_SEGMENTS | CONTEXT_XSTATE),
|
||||
"wrong context flags %lx\n", context->ContextFlags );
|
||||
if (is_arm64ec) /* addr points to RtlRaiseException entry thunk */
|
||||
{
|
||||
ok( ((ULONG *)addr)[-1] == 0xd63f0120 /* blr x9 */,
|
||||
"ExceptionAddress not in entry thunk %p (ntdll+%Ix)\n",
|
||||
addr, (char *)addr - (char *)hntdll );
|
||||
ok( context->ContextFlags == (CONTEXT_FULL | CONTEXT_UNWOUND_TO_CALL),
|
||||
"wrong context flags %lx\n", context->ContextFlags );
|
||||
}
|
||||
else
|
||||
{
|
||||
ok( addr == (char *)code_mem + 0x0c || broken( addr == code_mem || !addr ) /* 2008 */,
|
||||
"ExceptionAddress at %p instead of %p\n", addr, (char *)code_mem + 0x0c );
|
||||
ok( context->ContextFlags == CONTEXT_ALL || context->ContextFlags == (CONTEXT_ALL | CONTEXT_XSTATE)
|
||||
|| context->ContextFlags == (CONTEXT_FULL | CONTEXT_SEGMENTS)
|
||||
|| context->ContextFlags == (CONTEXT_FULL | CONTEXT_SEGMENTS | CONTEXT_XSTATE),
|
||||
"wrong context flags %lx\n", context->ContextFlags );
|
||||
}
|
||||
|
||||
/* check that pc is fixed up only for EXCEPTION_BREAKPOINT
|
||||
* even if raised by RtlRaiseException
|
||||
|
@ -3278,8 +3288,13 @@ static LONG CALLBACK rtlraiseexception_vectored_handler(EXCEPTION_POINTERS *Exce
|
|||
PEXCEPTION_RECORD rec = ExceptionInfo->ExceptionRecord;
|
||||
void *addr = rec->ExceptionAddress;
|
||||
|
||||
ok( addr == (char *)code_mem + 0xc || broken(addr == code_mem || !addr ) /* 2008 */,
|
||||
"ExceptionAddress at %p instead of %p\n", addr, (char *)code_mem + 0xc );
|
||||
if (is_arm64ec) /* addr points to RtlRaiseException entry thunk */
|
||||
ok( ((ULONG *)addr)[-1] == 0xd63f0120 /* blr x9 */,
|
||||
"ExceptionAddress not in entry thunk %p (ntdll+%Ix)\n",
|
||||
addr, (char *)addr - (char *)hntdll );
|
||||
else
|
||||
ok( addr == (char *)code_mem + 0xc || broken(addr == code_mem || !addr ) /* 2008 */,
|
||||
"ExceptionAddress at %p instead of %p\n", addr, (char *)code_mem + 0xc );
|
||||
|
||||
/* check that Rip is fixed up only for EXCEPTION_BREAKPOINT
|
||||
* even if raised by RtlRaiseException
|
||||
|
@ -3355,8 +3370,13 @@ static void run_rtlraiseexception_test(DWORD exceptioncode)
|
|||
rtlraiseexception_teb_handler_called = 0;
|
||||
rtlraiseexception_unhandled_handler_called = 0;
|
||||
func(pRtlRaiseException, &record);
|
||||
ok( record.ExceptionAddress == (char *)code_mem + 0x0c,
|
||||
"address set to %p instead of %p\n", record.ExceptionAddress, (char *)code_mem + 0x0c );
|
||||
if (is_arm64ec) /* addr points to RtlRaiseException entry thunk */
|
||||
ok( ((ULONG *)record.ExceptionAddress)[-1] == 0xd63f0120 /* blr x9 */,
|
||||
"ExceptionAddress not in entry thunk %p (ntdll+%Ix)\n",
|
||||
record.ExceptionAddress, (char *)record.ExceptionAddress - (char *)hntdll );
|
||||
else
|
||||
ok( record.ExceptionAddress == (char *)code_mem + 0x0c,
|
||||
"address set to %p instead of %p\n", record.ExceptionAddress, (char *)code_mem + 0x0c );
|
||||
|
||||
todo_wine
|
||||
ok( !rtlraiseexception_teb_handler_called, "Frame TEB handler called\n" );
|
||||
|
|
Loading…
Add table
Reference in a new issue