diff --git a/sdk/lib/rtl/amd64/except_asm.S b/sdk/lib/rtl/amd64/except_asm.S index e3fd67b852f..4b776b27974 100644 --- a/sdk/lib/rtl/amd64/except_asm.S +++ b/sdk/lib/rtl/amd64/except_asm.S @@ -107,22 +107,19 @@ PUBLIC RtlCaptureContext .ENDP /* - * VOID NTAPI - * RtlRestoreContext( - * _In_ PCONTEXT ContextRecord@, - * PEXCEPTION_RECORD *ExceptionRecord@); + * VOID + * RtlpRestoreContextInternal( + * _In_ PCONTEXT ContextRecord@); */ -PUBLIC RtlRestoreContext -.PROC RtlRestoreContext +PUBLIC RtlpRestoreContextInternal +.PROC RtlpRestoreContextInternal /* Allocate space */ sub rsp, HEX(8) .ALLOCSTACK 8 .ENDPROLOG - // TODO: Handle ExceptionRecord - - /* Restore legacy floating point registers (It's slow, so do it first) */ + /* Restore legacy floating point registers (It is slow, so do it first) */ ldmxcsr [rcx + CxMxCsr] fxrstor [rcx + CxFltSave] diff --git a/sdk/lib/rtl/amd64/unwind.c b/sdk/lib/rtl/amd64/unwind.c index 72e40860771..4a5903361b9 100644 --- a/sdk/lib/rtl/amd64/unwind.c +++ b/sdk/lib/rtl/amd64/unwind.c @@ -1131,3 +1131,26 @@ RtlSetUnwindContext( *ContextPointers.Xmm14 = Context->Xmm14; *ContextPointers.Xmm15 = Context->Xmm15; } + +VOID +RtlpRestoreContextInternal( + _In_ PCONTEXT ContextRecord); + +VOID +RtlRestoreContext( + _In_ PCONTEXT ContextRecord, + _In_ PEXCEPTION_RECORD ExceptionRecord) +{ + if (ExceptionRecord != NULL) + { + if ((ExceptionRecord->ExceptionCode == STATUS_UNWIND_CONSOLIDATE) && + (ExceptionRecord->NumberParameters >= 1)) + { + PVOID (*Consolidate)(EXCEPTION_RECORD*) = (PVOID)ExceptionRecord->ExceptionInformation[0]; + // FIXME: This should be called through an asm wrapper to allow handling recursive unwinding + ContextRecord->Rip = (ULONG64)Consolidate(ExceptionRecord); + } + } + + RtlpRestoreContextInternal(ContextRecord); +}