ntdll: Use the correct structure for non-volatile registers on ARM.
This commit is contained in:
parent
42cebcca3c
commit
0c35e9adce
2 changed files with 35 additions and 6 deletions
|
@ -69,6 +69,18 @@ static void dump_scope_table( ULONG base, const SCOPE_TABLE *table )
|
|||
base + table->ScopeRecord[i].JumpTarget );
|
||||
}
|
||||
|
||||
/* undocumented, copied from the corresponding ARM64 structure */
|
||||
typedef union _DISPATCHER_CONTEXT_NONVOLREG_ARM
|
||||
{
|
||||
BYTE Buffer[8 * sizeof(DWORD) + 8 * sizeof(double)];
|
||||
struct
|
||||
{
|
||||
DWORD GpNvRegs[8];
|
||||
double FpNvRegs[8];
|
||||
} DUMMYSTRUCTNAME;
|
||||
} DISPATCHER_CONTEXT_NONVOLREG_ARM;
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* syscalls
|
||||
*/
|
||||
|
@ -116,6 +128,7 @@ __ASM_GLOBAL_FUNC( RtlCaptureContext,
|
|||
*/
|
||||
static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEXT *context )
|
||||
{
|
||||
DISPATCHER_CONTEXT_NONVOLREG_ARM *nonvol_regs;
|
||||
DWORD pc = context->Pc;
|
||||
|
||||
dispatch->ScopeIndex = 0;
|
||||
|
@ -123,6 +136,10 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
|
|||
dispatch->ControlPcIsUnwound = (context->ContextFlags & CONTEXT_UNWOUND_TO_CALL) != 0;
|
||||
if (dispatch->ControlPcIsUnwound) pc -= 2;
|
||||
|
||||
nonvol_regs = (DISPATCHER_CONTEXT_NONVOLREG_ARM *)dispatch->NonVolatileRegisters;
|
||||
memcpy( nonvol_regs->GpNvRegs, &context->R4, sizeof(nonvol_regs->GpNvRegs) );
|
||||
memcpy( nonvol_regs->FpNvRegs, &context->D[8], sizeof(nonvol_regs->FpNvRegs) );
|
||||
|
||||
dispatch->FunctionEntry = RtlLookupFunctionEntry( pc, (DWORD_PTR *)&dispatch->ImageBase,
|
||||
dispatch->HistoryTable );
|
||||
if (RtlVirtualUnwind2( type, dispatch->ImageBase, pc, dispatch->FunctionEntry, context,
|
||||
|
@ -297,17 +314,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_ARM 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.R4;
|
||||
dispatch.NonVolatileRegisters = nonvol_regs.Buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -387,7 +404,6 @@ NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
|||
}
|
||||
|
||||
if (context.Sp == (DWORD)NtCurrentTeb()->Tib.StackBase) break;
|
||||
prev_context = context;
|
||||
}
|
||||
return STATUS_UNHANDLED_EXCEPTION;
|
||||
}
|
||||
|
@ -541,6 +557,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_ARM nonvol_regs;
|
||||
EXCEPTION_RECORD record;
|
||||
DISPATCHER_CONTEXT dispatch;
|
||||
CONTEXT new_context;
|
||||
|
@ -572,7 +589,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
dispatch.TargetPc = (ULONG_PTR)target_ip;
|
||||
dispatch.ContextRecord = context;
|
||||
dispatch.HistoryTable = table;
|
||||
dispatch.NonVolatileRegisters = (BYTE *)&context->R4;
|
||||
dispatch.NonVolatileRegisters = nonvol_regs.Buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
|
|
@ -6037,8 +6037,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 )
|
||||
{
|
||||
ULONG *nonvol_regs = (void *)dispatcher->NonVolatileRegisters;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ok( nonvol_regs[i] == ((ULONG *)&context->R4)[i],
|
||||
"wrong non volatile reg r%u %lx / %lx\n", i + 4,
|
||||
nonvol_regs[i], ((ULONG *)&context->R4)[i] );
|
||||
for (i = 0; i < 8; i++)
|
||||
ok( ((ULONGLONG *)(nonvol_regs + 8))[i] == context->D[i + 8],
|
||||
"wrong non volatile reg d%u %I64x / %I64x\n", i + 8,
|
||||
((ULONGLONG *)(nonvol_regs + 8))[i], context->D[i + 8] );
|
||||
|
||||
rtlraiseexception_handler_called = 1;
|
||||
rtlraiseexception_handler_(rec, frame, context, dispatcher, FALSE);
|
||||
return ExceptionContinueSearch;
|
||||
|
|
Loading…
Add table
Reference in a new issue