diff --git a/sdk/lib/rtl/amd64/except.c b/sdk/lib/rtl/amd64/except.c index 1dc9b59c0cd..3a1c642012d 100644 --- a/sdk/lib/rtl/amd64/except.c +++ b/sdk/lib/rtl/amd64/except.c @@ -13,50 +13,6 @@ /* PUBLIC FUNCTIONS **********************************************************/ -VOID -NTAPI -RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord) -{ - CONTEXT Context; - NTSTATUS Status = STATUS_INVALID_DISPOSITION; - - /* Capture the current context */ - RtlCaptureContext(&Context); - - /* Fix up Context.Rip for the caller */ - Context.Rip = (ULONG64)_ReturnAddress(); - - /* Fix up Context.Rsp for the caller */ - Context.Rsp = (ULONG64)_AddressOfReturnAddress() + 8; - - /* Save the exception address */ - ExceptionRecord->ExceptionAddress = (PVOID)Context.Rip; - - /* Check if user mode debugger is active */ - if (RtlpCheckForActiveDebugger()) - { - /* Raise an exception immediately */ - Status = ZwRaiseException(ExceptionRecord, &Context, TRUE); - } - else - { - /* Dispatch the exception and check if we should continue */ - if (!RtlDispatchException(ExceptionRecord, &Context)) - { - /* Raise the exception */ - Status = ZwRaiseException(ExceptionRecord, &Context, FALSE); - } - else - { - /* Continue, go back to previous context */ - Status = ZwContinue(&Context, FALSE); - } - } - - /* If we returned, raise a status */ - RtlRaiseStatus(Status); -} - /* * @unimplemented */ diff --git a/sdk/lib/rtl/amd64/except_asm.S b/sdk/lib/rtl/amd64/except_asm.S index 4b776b27974..52bac1602a7 100644 --- a/sdk/lib/rtl/amd64/except_asm.S +++ b/sdk/lib/rtl/amd64/except_asm.S @@ -233,6 +233,81 @@ ReturnFar: .ENDP +EXTERN RtlpCheckForActiveDebugger:PROC +EXTERN RtlDispatchException:PROC +EXTERN ZwContinue:PROC +EXTERN ZwRaiseException:PROC +EXTERN RtlRaiseStatus:PROC + +/* + * VOID + * RtlRaiseException ( + * _In_ PEXCEPTION_RECORD ExceptionRecord); + */ +PUBLIC RtlRaiseException +.PROC RtlRaiseException + + /* Allocate stack space for a CONTEXT record */ + sub rsp, CONTEXT_FRAME_LENGTH + 8 + .allocstack CONTEXT_FRAME_LENGTH + 8 + + /* Save the ExceptionRecord pointer */ + mov [rsp + CONTEXT_FRAME_LENGTH + 8 + P1Home], rcx + + .endprolog + + /* Save the return address in EXCEPTION_RECORD.ExceptionAddress */ + mov rdx, [rsp + CONTEXT_FRAME_LENGTH + 8] + mov [rcx + ErExceptionAddress], rdx + + /* Capture the current context */ + mov rcx, rsp + call RtlCaptureContext + + /* Fix up CONTEXT.Rip for the caller (RtlCaptureContext doesn't change rdx!) */ + mov [rsp + CxRip], rdx + + /* Fix up CONTEXT.Rsp for the caller (+8 for the return address) */ + lea rdx, [rsp + CONTEXT_FRAME_LENGTH + 8 + 8] + mov [rsp + CxRsp], rdx + + /* Check if a user mode debugger is active */ + call RtlpCheckForActiveDebugger + test al, al + mov r8b, 1 + jnz RaiseException + + /* Dispatch the exception */ + mov rcx, [rsp + CONTEXT_FRAME_LENGTH + 8 + P1Home] + mov rdx, rsp + call RtlDispatchException + + /* Check if it was handled */ + test al, al + mov r8b, 0 + jz RaiseException + + /* It was handled, continue with the updated context */ + mov rcx, rsp + mov dl, 0 + call ZwContinue + jmp RaiseStatus + +RaiseException: + + mov rcx, [rsp + CxP1Home] + mov rdx, rsp + call ZwRaiseException + +RaiseStatus: + + mov rcx, rax + mov rdx, rsp + call RtlRaiseStatus + +.ENDP + + END