1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

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:
Alexandre Julliard 2024-03-25 18:04:37 +01:00
parent 8dec8cc96c
commit 47f94fcf5f

View file

@ -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 );