1 /* 2 * PROJECT: ReactOS Run-Time Library 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: User-mode exception support for AMD64 5 * COPYRIGHT: Copyright 2018-2021 Timo Kreuzer <timo.kreuzer@reactos.org> 6 */ 7 8 /* INCLUDES *****************************************************************/ 9 10 #include <rtl.h> 11 #define NDEBUG 12 #include <debug.h> 13 14 /* PUBLIC FUNCTIONS **********************************************************/ 15 16 VOID 17 NTAPI 18 RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord) 19 { 20 CONTEXT Context; 21 NTSTATUS Status = STATUS_INVALID_DISPOSITION; 22 23 /* Capture the current context */ 24 RtlCaptureContext(&Context); 25 26 /* Fix up Context.Rip for the caller */ 27 Context.Rip = (ULONG64)_ReturnAddress(); 28 29 /* Fix up Context.Rsp for the caller */ 30 Context.Rsp = (ULONG64)_AddressOfReturnAddress() + 8; 31 32 /* Save the exception address */ 33 ExceptionRecord->ExceptionAddress = (PVOID)Context.Rip; 34 35 /* Check if user mode debugger is active */ 36 if (RtlpCheckForActiveDebugger()) 37 { 38 /* Raise an exception immediately */ 39 Status = ZwRaiseException(ExceptionRecord, &Context, TRUE); 40 } 41 else 42 { 43 /* Dispatch the exception and check if we should continue */ 44 if (!RtlDispatchException(ExceptionRecord, &Context)) 45 { 46 /* Raise the exception */ 47 Status = ZwRaiseException(ExceptionRecord, &Context, FALSE); 48 } 49 else 50 { 51 /* Continue, go back to previous context */ 52 Status = ZwContinue(&Context, FALSE); 53 } 54 } 55 56 /* If we returned, raise a status */ 57 RtlRaiseStatus(Status); 58 } 59 60 /* 61 * @unimplemented 62 */ 63 PVOID 64 NTAPI 65 RtlpGetExceptionAddress(VOID) 66 { 67 UNIMPLEMENTED; 68 return NULL; 69 } 70 71 BOOLEAN 72 NTAPI 73 RtlpUnwindInternal( 74 _In_opt_ PVOID TargetFrame, 75 _In_opt_ PVOID TargetIp, 76 _In_ PEXCEPTION_RECORD ExceptionRecord, 77 _In_ PVOID ReturnValue, 78 _In_ PCONTEXT ContextRecord, 79 _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable, 80 _In_ ULONG Flags); 81 82 /* 83 * @unimplemented 84 */ 85 BOOLEAN 86 NTAPI 87 RtlDispatchException( 88 _In_ PEXCEPTION_RECORD ExceptionRecord, 89 _In_ PCONTEXT ContextRecord) 90 { 91 BOOLEAN Handled; 92 93 /* Perform vectored exception handling for user mode */ 94 if (RtlCallVectoredExceptionHandlers(ExceptionRecord, ContextRecord)) 95 { 96 /* Exception handled, now call vectored continue handlers */ 97 RtlCallVectoredContinueHandlers(ExceptionRecord, ContextRecord); 98 99 /* Continue execution */ 100 return TRUE; 101 } 102 103 /* Call the internal unwind routine */ 104 Handled = RtlpUnwindInternal(NULL, // TargetFrame 105 NULL, // TargetIp 106 ExceptionRecord, 107 0, // ReturnValue 108 ContextRecord, 109 NULL, // HistoryTable 110 UNW_FLAG_EHANDLER); 111 112 /* In user mode, call any registered vectored continue handlers */ 113 RtlCallVectoredContinueHandlers(ExceptionRecord, ContextRecord); 114 115 return Handled; 116 } 117