1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

ntdll: Implement RtlRaiseException on ARM64EC.

This commit is contained in:
Alexandre Julliard 2024-03-01 13:37:29 +01:00
parent 462b27d87f
commit f35e2d513d
2 changed files with 57 additions and 13 deletions

View file

@ -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" );
}

View file

@ -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" );