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 */
|
/* capture context information; helper for RtlCaptureContext */
|
||||||
static void __attribute__((used)) capture_context( CONTEXT *context, UINT cpsr, UINT fpcr, UINT fpsr )
|
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 unwind_context;
|
||||||
|
|
||||||
context->ContextFlags = CONTEXT_AMD64_FULL;
|
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 one level to get register values from caller function */
|
||||||
unwind_context = *context;
|
unwind_context = *context;
|
||||||
pc = context->Rip - 4;
|
unwind_one_frame( &unwind_context );
|
||||||
func = RtlLookupFunctionEntry( pc, &base, NULL );
|
|
||||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, base, pc, func, &unwind_context, &handler_data, &frame, NULL );
|
|
||||||
memcpy( &context->Rax, &unwind_context.Rax, offsetof(CONTEXT,FltSave) - offsetof(CONTEXT,Rax) );
|
memcpy( &context->Rax, &unwind_context.Rax, offsetof(CONTEXT,FltSave) - offsetof(CONTEXT,Rax) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1826,6 +1831,67 @@ void __attribute__((naked)) RtlCaptureContext( CONTEXT *context )
|
||||||
".seh_endproc" );
|
".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.@)
|
* RtlRestoreContext (NTDLL.@)
|
||||||
|
|
Loading…
Add table
Reference in a new issue