ntdll: Use the correct structure for non-volatile registers on ARM64.
This commit is contained in:
parent
a9671befc1
commit
42cebcca3c
3 changed files with 40 additions and 6 deletions
|
@ -147,13 +147,19 @@ __ASM_GLOBAL_FUNC( RtlCaptureContext,
|
|||
*/
|
||||
static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEXT *context )
|
||||
{
|
||||
DISPATCHER_CONTEXT_NONVOLREG_ARM64 *nonvol_regs;
|
||||
DWORD64 pc = context->Pc;
|
||||
int i;
|
||||
|
||||
dispatch->ScopeIndex = 0;
|
||||
dispatch->ControlPc = pc;
|
||||
dispatch->ControlPcIsUnwound = (context->ContextFlags & CONTEXT_UNWOUND_TO_CALL) != 0;
|
||||
if (dispatch->ControlPcIsUnwound) pc -= 4;
|
||||
|
||||
nonvol_regs = (DISPATCHER_CONTEXT_NONVOLREG_ARM64 *)dispatch->NonVolatileRegisters;
|
||||
memcpy( nonvol_regs->GpNvRegs, &context->X19, sizeof(nonvol_regs->GpNvRegs) );
|
||||
for (i = 0; i < 8; i++) nonvol_regs->FpNvRegs[i] = context->V[i + 8].D[0];
|
||||
|
||||
dispatch->FunctionEntry = RtlLookupFunctionEntry( pc, &dispatch->ImageBase, dispatch->HistoryTable );
|
||||
|
||||
if (RtlVirtualUnwind2( type, dispatch->ImageBase, pc, dispatch->FunctionEntry, context,
|
||||
|
@ -334,17 +340,17 @@ static DWORD call_teb_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCH
|
|||
NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||
DISPATCHER_CONTEXT_NONVOLREG_ARM64 nonvol_regs;
|
||||
UNWIND_HISTORY_TABLE table;
|
||||
DISPATCHER_CONTEXT dispatch;
|
||||
CONTEXT context, prev_context;
|
||||
CONTEXT context;
|
||||
NTSTATUS status;
|
||||
|
||||
context = *orig_context;
|
||||
dispatch.TargetPc = 0;
|
||||
dispatch.ContextRecord = &context;
|
||||
dispatch.HistoryTable = &table;
|
||||
prev_context = context;
|
||||
dispatch.NonVolatileRegisters = (BYTE *)&prev_context.X19;
|
||||
dispatch.NonVolatileRegisters = nonvol_regs.Buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -424,7 +430,6 @@ NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
|||
}
|
||||
|
||||
if (context.Sp == (ULONG64)NtCurrentTeb()->Tib.StackBase) break;
|
||||
prev_context = context;
|
||||
}
|
||||
return STATUS_UNHANDLED_EXCEPTION;
|
||||
}
|
||||
|
@ -628,6 +633,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
PVOID retval, CONTEXT *context, UNWIND_HISTORY_TABLE *table )
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||
DISPATCHER_CONTEXT_NONVOLREG_ARM64 nonvol_regs;
|
||||
EXCEPTION_RECORD record;
|
||||
DISPATCHER_CONTEXT dispatch;
|
||||
CONTEXT new_context;
|
||||
|
@ -659,7 +665,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
dispatch.TargetPc = (ULONG64)target_ip;
|
||||
dispatch.ContextRecord = context;
|
||||
dispatch.HistoryTable = table;
|
||||
dispatch.NonVolatileRegisters = (BYTE *)&context->X19;
|
||||
dispatch.NonVolatileRegisters = nonvol_regs.Buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
|
|
@ -7127,8 +7127,20 @@ static DWORD WINAPI rtlraiseexception_teb_handler( EXCEPTION_RECORD *rec,
|
|||
}
|
||||
|
||||
static DWORD WINAPI rtlraiseexception_handler( EXCEPTION_RECORD *rec, void *frame,
|
||||
CONTEXT *context, void *dispatcher )
|
||||
CONTEXT *context, DISPATCHER_CONTEXT *dispatcher )
|
||||
{
|
||||
DISPATCHER_CONTEXT_NONVOLREG_ARM64 *nonvol_regs = (void *)dispatcher->NonVolatileRegisters;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NONVOL_INT_NUMREG_ARM64; i++)
|
||||
ok( nonvol_regs->GpNvRegs[i] == ((DWORD64 *)&context->X19)[i],
|
||||
"wrong non volatile reg x%u %I64x / %I64x\n", i + 19,
|
||||
nonvol_regs->GpNvRegs[i] , ((DWORD64 *)&context->X19)[i] );
|
||||
for (i = 0; i < NONVOL_FP_NUMREG_ARM64; i++)
|
||||
ok( nonvol_regs->FpNvRegs[i] == context->V[i + 8].D[0],
|
||||
"wrong non volatile reg d%u %g / %g\n", i + 8,
|
||||
nonvol_regs->FpNvRegs[i] , context->V[i + 8].D[0] );
|
||||
|
||||
rtlraiseexception_handler_called = 1;
|
||||
rtlraiseexception_handler_(rec, frame, context, dispatcher, FALSE);
|
||||
return ExceptionContinueSearch;
|
||||
|
|
|
@ -2013,6 +2013,22 @@ typedef struct _DISPATCHER_CONTEXT_ARM64
|
|||
PBYTE NonVolatileRegisters;
|
||||
} DISPATCHER_CONTEXT_ARM64, *PDISPATCHER_CONTEXT_ARM64;
|
||||
|
||||
#define NONVOL_INT_NUMREG_ARM64 11
|
||||
#define NONVOL_FP_NUMREG_ARM64 8
|
||||
|
||||
#define NONVOL_INT_SIZE_ARM64 (NONVOL_INT_NUMREG_ARM64 * sizeof(DWORD64))
|
||||
#define NONVOL_FP_SIZE_ARM64 (NONVOL_FP_NUMREG_ARM64 * sizeof(double))
|
||||
|
||||
typedef union _DISPATCHER_CONTEXT_NONVOLREG_ARM64
|
||||
{
|
||||
BYTE Buffer[NONVOL_INT_SIZE_ARM64 + NONVOL_FP_SIZE_ARM64];
|
||||
struct
|
||||
{
|
||||
DWORD64 GpNvRegs[NONVOL_INT_NUMREG_ARM64];
|
||||
double FpNvRegs[NONVOL_FP_NUMREG_ARM64];
|
||||
} DUMMYSTRUCTNAME;
|
||||
} DISPATCHER_CONTEXT_NONVOLREG_ARM64;
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
typedef struct _DISPATCHER_CONTEXT
|
||||
|
|
Loading…
Add table
Reference in a new issue