ntdll: Copy the context contents instead of the pointer on collided unwind.
Similar to how it's done on ARM platforms.
This commit is contained in:
parent
8dec8cc96c
commit
47f94fcf5f
1 changed files with 12 additions and 32 deletions
|
@ -210,6 +210,7 @@ NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
|||
DISPATCHER_CONTEXT dispatch;
|
||||
CONTEXT context;
|
||||
NTSTATUS status;
|
||||
ULONG_PTR frame;
|
||||
|
||||
context = *orig_context;
|
||||
context.ContextFlags &= ~0x40; /* Clear xstate flag. */
|
||||
|
@ -246,16 +247,10 @@ NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
|||
rec->ExceptionFlags |= EXCEPTION_NESTED_CALL;
|
||||
TRACE( "nested exception\n" );
|
||||
break;
|
||||
case ExceptionCollidedUnwind: {
|
||||
ULONG64 frame;
|
||||
|
||||
context = *dispatch.ContextRecord;
|
||||
dispatch.ContextRecord = &context;
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, dispatch.ImageBase,
|
||||
dispatch.ControlPc, dispatch.FunctionEntry,
|
||||
&context, NULL, &frame, NULL );
|
||||
case ExceptionCollidedUnwind:
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, dispatch.ImageBase, dispatch.ControlPc,
|
||||
dispatch.FunctionEntry, &context, NULL, &frame, NULL );
|
||||
goto unwind_done;
|
||||
}
|
||||
default:
|
||||
return STATUS_INVALID_DISPOSITION;
|
||||
}
|
||||
|
@ -277,17 +272,11 @@ NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
|||
rec->ExceptionFlags |= EXCEPTION_NESTED_CALL;
|
||||
TRACE( "nested exception\n" );
|
||||
break;
|
||||
case ExceptionCollidedUnwind: {
|
||||
ULONG64 frame;
|
||||
|
||||
context = *dispatch.ContextRecord;
|
||||
dispatch.ContextRecord = &context;
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, dispatch.ImageBase,
|
||||
dispatch.ControlPc, dispatch.FunctionEntry,
|
||||
&context, NULL, &frame, NULL );
|
||||
case ExceptionCollidedUnwind:
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, dispatch.ImageBase, dispatch.ControlPc,
|
||||
dispatch.FunctionEntry, &context, NULL, &frame, NULL );
|
||||
teb_frame = teb_frame->Prev;
|
||||
goto unwind_done;
|
||||
}
|
||||
default:
|
||||
return STATUS_INVALID_DISPOSITION;
|
||||
}
|
||||
|
@ -447,11 +436,12 @@ DWORD __cdecl unwind_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTR
|
|||
dispatch->ImageBase = unwind_frame->dispatch->ImageBase;
|
||||
dispatch->FunctionEntry = unwind_frame->dispatch->FunctionEntry;
|
||||
dispatch->EstablisherFrame = unwind_frame->dispatch->EstablisherFrame;
|
||||
dispatch->ContextRecord = unwind_frame->dispatch->ContextRecord;
|
||||
dispatch->LanguageHandler = unwind_frame->dispatch->LanguageHandler;
|
||||
dispatch->HandlerData = unwind_frame->dispatch->HandlerData;
|
||||
dispatch->HistoryTable = unwind_frame->dispatch->HistoryTable;
|
||||
dispatch->ScopeIndex = unwind_frame->dispatch->ScopeIndex;
|
||||
*dispatch->ContextRecord = *unwind_frame->dispatch->ContextRecord;
|
||||
dispatch->ContextRecord->ContextFlags &= ~0x40;
|
||||
TRACE( "detected collided unwind\n" );
|
||||
return ExceptionCollidedUnwind;
|
||||
}
|
||||
|
@ -728,6 +718,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
DISPATCHER_CONTEXT dispatch;
|
||||
CONTEXT new_context;
|
||||
NTSTATUS status;
|
||||
ULONG_PTR frame;
|
||||
DWORD i;
|
||||
|
||||
RtlCaptureContext( context );
|
||||
|
@ -783,12 +774,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
if (dispatch.EstablisherFrame == (ULONG64)end_frame) rec->ExceptionFlags |= EXCEPTION_TARGET_UNWIND;
|
||||
if (call_unwind_handler( rec, &dispatch ) == ExceptionCollidedUnwind)
|
||||
{
|
||||
ULONG64 frame;
|
||||
|
||||
new_context = *dispatch.ContextRecord;
|
||||
new_context.ContextFlags &= ~0x40;
|
||||
*context = new_context;
|
||||
dispatch.ContextRecord = context;
|
||||
new_context = *context;
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, dispatch.ImageBase,
|
||||
dispatch.ControlPc, dispatch.FunctionEntry,
|
||||
&new_context, NULL, &frame, NULL );
|
||||
|
@ -808,14 +794,8 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
|||
dispatch.EstablisherFrame = (ULONG64)teb_frame;
|
||||
if (call_teb_unwind_handler( rec, &dispatch, teb_frame ) == ExceptionCollidedUnwind)
|
||||
{
|
||||
ULONG64 frame;
|
||||
|
||||
teb_frame = __wine_pop_frame( teb_frame );
|
||||
|
||||
new_context = *dispatch.ContextRecord;
|
||||
new_context.ContextFlags &= ~0x40;
|
||||
*context = new_context;
|
||||
dispatch.ContextRecord = context;
|
||||
new_context = *context;
|
||||
RtlVirtualUnwind( UNW_FLAG_NHANDLER, dispatch.ImageBase,
|
||||
dispatch.ControlPc, dispatch.FunctionEntry,
|
||||
&new_context, NULL, &frame, NULL );
|
||||
|
|
Loading…
Add table
Reference in a new issue