From 5075f7d7462c30739f1391e0e1cc44415be6ee47 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 1 Mar 2018 14:13:01 +0100 Subject: [PATCH] [RTL] Move exception handling code to except.c --- sdk/lib/rtl/CMakeLists.txt | 1 + sdk/lib/rtl/amd64/except.c | 102 +++++++++++++++++++++++++++++++++++++ sdk/lib/rtl/amd64/stubs.c | 23 --------- sdk/lib/rtl/amd64/unwind.c | 65 ----------------------- 4 files changed, 103 insertions(+), 88 deletions(-) create mode 100644 sdk/lib/rtl/amd64/except.c diff --git a/sdk/lib/rtl/CMakeLists.txt b/sdk/lib/rtl/CMakeLists.txt index c2b2e5d1025..f250931846a 100644 --- a/sdk/lib/rtl/CMakeLists.txt +++ b/sdk/lib/rtl/CMakeLists.txt @@ -89,6 +89,7 @@ elseif(ARCH STREQUAL "amd64") list(APPEND SOURCE bitmap64.c byteswap.c + amd64/except.c amd64/unwind.c amd64/stubs.c mem.c) diff --git a/sdk/lib/rtl/amd64/except.c b/sdk/lib/rtl/amd64/except.c new file mode 100644 index 00000000000..9e7dcf87c0e --- /dev/null +++ b/sdk/lib/rtl/amd64/except.c @@ -0,0 +1,102 @@ +/* + * PROJECT: ReactOS Run-Time Library + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: User-mode exception support for AMD64 + * COPYRIGHT: Copyright 2018-2021 Timo Kreuzer + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +VOID +NTAPI +RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord) +{ + CONTEXT Context; + NTSTATUS Status = STATUS_INVALID_DISPOSITION; + ULONG64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; + PVOID HandlerData; + ULONG64 EstablisherFrame; + + /* Capture the context */ + RtlCaptureContext(&Context); + + /* Get the function entry for this function */ + FunctionEntry = RtlLookupFunctionEntry(Context.Rip, + &ImageBase, + NULL); + + /* Check if we found it */ + if (FunctionEntry) + { + /* Unwind to the caller of this function */ + RtlVirtualUnwind(UNW_FLAG_NHANDLER, + ImageBase, + Context.Rip, + FunctionEntry, + &Context, + &HandlerData, + &EstablisherFrame, + NULL); + + /* Save the exception address */ + ExceptionRecord->ExceptionAddress = (PVOID)Context.Rip; + + /* Write the context flag */ + Context.ContextFlags = CONTEXT_FULL; + + /* 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 +*/ +PVOID +NTAPI +RtlpGetExceptionAddress(VOID) +{ + UNIMPLEMENTED; + return NULL; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context) +{ + __debugbreak(); + UNIMPLEMENTED; + return FALSE; +} diff --git a/sdk/lib/rtl/amd64/stubs.c b/sdk/lib/rtl/amd64/stubs.c index 7eb61416c36..7ffc4fb9658 100644 --- a/sdk/lib/rtl/amd64/stubs.c +++ b/sdk/lib/rtl/amd64/stubs.c @@ -74,29 +74,6 @@ RtlInitializeContext( return; } -/* - * @unimplemented - */ -PVOID -NTAPI -RtlpGetExceptionAddress(VOID) -{ - UNIMPLEMENTED; - return NULL; -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context) -{ - UNIMPLEMENTED; - return FALSE; -} - NTSTATUS NTAPI RtlQueueApcWow64Thread( diff --git a/sdk/lib/rtl/amd64/unwind.c b/sdk/lib/rtl/amd64/unwind.c index 26a7610d250..6f3ce6efd51 100644 --- a/sdk/lib/rtl/amd64/unwind.c +++ b/sdk/lib/rtl/amd64/unwind.c @@ -622,71 +622,6 @@ RtlGetCallersAddress( return; } -// FIXME: move to different file -VOID -NTAPI -RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord) -{ - CONTEXT Context; - NTSTATUS Status = STATUS_INVALID_DISPOSITION; - ULONG64 ImageBase; - PRUNTIME_FUNCTION FunctionEntry; - PVOID HandlerData; - ULONG64 EstablisherFrame; - - /* Capture the context */ - RtlCaptureContext(&Context); - - /* Get the function entry for this function */ - FunctionEntry = RtlLookupFunctionEntry(Context.Rip, - &ImageBase, - NULL); - - /* Check if we found it */ - if (FunctionEntry) - { - /* Unwind to the caller of this function */ - RtlVirtualUnwind(UNW_FLAG_NHANDLER, - ImageBase, - Context.Rip, - FunctionEntry, - &Context, - &HandlerData, - &EstablisherFrame, - NULL); - - /* Save the exception address */ - ExceptionRecord->ExceptionAddress = (PVOID)Context.Rip; - - /* Write the context flag */ - Context.ContextFlags = CONTEXT_FULL; - - /* 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); -} - static VOID RtlpCaptureNonVolatileContextPointers(