ntdll: Implement _setjmpex on ARM64EC.
This commit is contained in:
parent
e1d624a06f
commit
1edd53f00f
1 changed files with 72 additions and 6 deletions
|
@ -1755,12 +1755,19 @@ BOOLEAN WINAPI RtlIsEcCode( ULONG_PTR ptr )
|
|||
}
|
||||
|
||||
|
||||
/* unwind context by one call frame */
|
||||
static void unwind_one_frame( CONTEXT *context )
|
||||
{
|
||||
void *data;
|
||||
ULONG_PTR base, frame, pc = context->Rip - 4;
|
||||
RUNTIME_FUNCTION *func = RtlLookupFunctionEntry( pc, &base, NULL );
|
||||
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, base, pc, func, context, &data, &frame, NULL );
|
||||
}
|
||||
|
||||
/* capture context information; helper for RtlCaptureContext */
|
||||
static void __attribute__((used)) capture_context( CONTEXT *context, UINT cpsr, UINT fpcr, UINT fpsr )
|
||||
{
|
||||
RUNTIME_FUNCTION *func;
|
||||
void *handler_data;
|
||||
ULONG_PTR pc, base, frame;
|
||||
CONTEXT unwind_context;
|
||||
|
||||
context->ContextFlags = CONTEXT_AMD64_FULL;
|
||||
|
@ -1772,9 +1779,7 @@ static void __attribute__((used)) capture_context( CONTEXT *context, UINT cpsr,
|
|||
|
||||
/* unwind one level to get register values from caller function */
|
||||
unwind_context = *context;
|
||||
pc = context->Rip - 4;
|
||||
func = RtlLookupFunctionEntry( pc, &base, NULL );
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, base, pc, func, &unwind_context, &handler_data, &frame, NULL );
|
||||
unwind_one_frame( &unwind_context );
|
||||
memcpy( &context->Rax, &unwind_context.Rax, offsetof(CONTEXT,FltSave) - offsetof(CONTEXT,Rax) );
|
||||
}
|
||||
|
||||
|
@ -1826,6 +1831,67 @@ void __attribute__((naked)) RtlCaptureContext( CONTEXT *context )
|
|||
".seh_endproc" );
|
||||
}
|
||||
|
||||
/* fixup jump buffer information; helper for _setjmpex */
|
||||
static int __attribute__((used)) do_setjmpex( _JUMP_BUFFER *buf, UINT fpcr, UINT fpsr )
|
||||
{
|
||||
CONTEXT context = { .ContextFlags = CONTEXT_FULL };
|
||||
|
||||
buf->MxCsr = fpcsr_to_mxcsr( fpcr, fpsr );
|
||||
buf->FpCsr = 0x27f;
|
||||
|
||||
context.Rbx = buf->Rbx;
|
||||
context.Rsp = buf->Rsp;
|
||||
context.Rbp = buf->Rbp;
|
||||
context.Rsi = buf->Rsi;
|
||||
context.Rdi = buf->Rdi;
|
||||
context.R12 = buf->R12;
|
||||
context.R13 = buf->R13;
|
||||
context.R14 = buf->R14;
|
||||
context.R15 = buf->R15;
|
||||
context.Rip = buf->Rip;
|
||||
memcpy( &context.Xmm6, &buf->Xmm6, 10 * sizeof(context.Xmm6) );
|
||||
unwind_one_frame( &context );
|
||||
if (!RtlIsEcCode( context.Rip )) /* caller is x64, use its context instead of the ARM one */
|
||||
{
|
||||
buf->Rbx = context.Rbx;
|
||||
buf->Rsp = context.Rsp;
|
||||
buf->Rbp = context.Rbp;
|
||||
buf->Rsi = context.Rsi;
|
||||
buf->Rdi = context.Rdi;
|
||||
buf->R12 = context.R12;
|
||||
buf->R13 = context.R13;
|
||||
buf->R14 = context.R14;
|
||||
buf->R15 = context.R15;
|
||||
buf->Rip = context.Rip;
|
||||
memcpy( &buf->Xmm6, &context.Xmm6, 10 * sizeof(context.Xmm6) );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _setjmpex (NTDLL.@)
|
||||
*/
|
||||
int __attribute__((naked)) NTDLL__setjmpex( _JUMP_BUFFER *buf, void *frame )
|
||||
{
|
||||
asm( ".seh_proc NTDLL__setjmpex\n\t"
|
||||
".seh_endprologue\n\t"
|
||||
"stp x1, x27, [x0]\n\t" /* jmp_buf->Frame,Rbx */
|
||||
"mov x1, sp\n\t"
|
||||
"stp x1, x29, [x0, #0x10]\n\t" /* jmp_buf->Rsp,Rbp */
|
||||
"stp x25, x26, [x0, #0x20]\n\t" /* jmp_buf->Rsi,Rdi */
|
||||
"stp x19, x20, [x0, #0x30]\n\t" /* jmp_buf->R12,R13 */
|
||||
"stp x21, x22, [x0, #0x40]\n\t" /* jmp_buf->R14,R15 */
|
||||
"str x30, [x0, #0x50]\n\t" /* jmp_buf->Rip */
|
||||
"stp d8, d9, [x0, #0x80]\n\t" /* jmp_buf->Xmm8,Xmm9 */
|
||||
"stp d10, d11, [x0, #0xa0]\n\t" /* jmp_buf->Xmm10,Xmm11 */
|
||||
"stp d12, d13, [x0, #0xc0]\n\t" /* jmp_buf->Xmm12,Xmm13 */
|
||||
"stp d14, d15, [x0, #0xe0]\n\t" /* jmp_buf->Xmm14,Xmm15 */
|
||||
"mrs x1, fpcr\n\t"
|
||||
"mrs x2, fpsr\n\t"
|
||||
"b do_setjmpex\n\t"
|
||||
".seh_endproc" );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* RtlRestoreContext (NTDLL.@)
|
||||
|
|
Loading…
Add table
Reference in a new issue