[RTL] Move exception handling code to except.c

This commit is contained in:
Timo Kreuzer 2018-03-01 14:13:01 +01:00
parent 65c3911ffc
commit 5075f7d746
4 changed files with 103 additions and 88 deletions

View file

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

102
sdk/lib/rtl/amd64/except.c Normal file
View file

@ -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 <timo.kreuzer@reactos.org>
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG
#include <debug.h>
/* 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;
}

View file

@ -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(

View file

@ -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(