/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
+#ifndef LIBCAPTIVE
#include <reactos/bugcodes.h>
+#endif /* LIBCAPTIVE */
#include <roscfg.h>
#include <internal/ke.h>
#include <internal/ldr.h>
BOOLEAN SearchFrames)
{
EXCEPTION_DISPOSITION Value;
+#ifndef LIBCAPTIVE
CONTEXT TContext;
+#endif /* LIBCAPTIVE */
DPRINT("KiDispatchException() called\n");
/* PCR->KeExceptionDispatchCount++; */
+#ifndef LIBCAPTIVE
if (Context == NULL)
{
TContext.ContextFlags = CONTEXT_FULL;
Context = &TContext;
}
+#endif /* LIBCAPTIVE */
#if 0
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
#endif
if (PreviousMode == UserMode)
{
+#ifdef LIBCAPTIVE
+ KeBugCheck(0);
+#else /* !LIBCAPTIVE */
if (SearchFrames)
{
PULONG Stack;
/* If that fails then bugcheck */
DbgPrint("Could not terminate thread\n");
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
+#endif /* LIBCAPTIVE */
}
else
{
/* PreviousMode == KernelMode */
+#ifndef LIBCAPTIVE
if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
{
Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
}
#endif /* KDBG */
+#endif /* LIBCAPTIVE */
if (Action != kdHandleException)
{
Value = RtlpDispatchException (ExceptionRecord, Context);
*/
if (Value != ExceptionContinueExecution)
{
+#ifndef LIBCAPTIVE
KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED);
+#else /* !LIBCAPTIVE */
+ KeBugCheck (0);
+#endif /* LIBCAPTIVE */
}
}
else
{
+#ifndef LIBCAPTIVE
KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
+#else /* !LIBCAPTIVE */
+ KeBugCheck(0);
+#endif /* LIBCAPTIVE */
}
}
}
+#ifndef LIBCAPTIVE
+
VOID STDCALL
ExRaiseAccessViolation (VOID)
{
ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
}
+#endif /* LIBCAPTIVE */
+
VOID STDCALL
ExRaiseStatus (IN NTSTATUS Status)
{
KiDispatchException(ExceptionRecord,
Context,
PsGetCurrentThread()->Tcb.TrapFrame,
+#ifndef LIBCAPTIVE
ExGetPreviousMode(),
+#else /* !LIBCAPTIVE */
+ KernelMode,
+#endif /* LIBCAPTIVE */
SearchFrames);
return(STATUS_SUCCESS);
}
VOID STDCALL
RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
{
+#ifndef LIBCAPTIVE
ZwRaiseException(ExceptionRecord, NULL, TRUE);
+#else /* !LIBCAPTIVE */
+CONTEXT *LocalContext;
+
+ /* Do not use local variable to benefit from ElectricFence boundary checks */
+ LocalContext=ExAllocatePool(PagedPool,sizeof(LocalContext->ContextFlags));
+ LocalContext->ContextFlags=0;
+
+ NtRaiseException(ExceptionRecord, LocalContext, TRUE);
+
+ ExFreePool(LocalContext);
+#endif /* LIBCAPTIVE */
}
/* EOF */
/* FUNCTIONS ***************************************************************/
+#ifndef LIBCAPTIVE
+
#if 1
VOID STDCALL
MsvcrtDebug(ULONG Value)
return (EXCEPTION_DISPOSITION)0;
}
-void __cdecl
+#endif /* LIBCAPTIVE */
+
+void
+#ifndef LIBCAPTIVE
+__cdecl
+#endif /* LIBCAPTIVE */
_global_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame)
{
RtlUnwind(RegistrationFrame, &&__ret_label, NULL, 0);
return;
}
+#ifndef LIBCAPTIVE
/* Implemented in except.s */
(*(StackLimit)) = KeGetCurrentKPCR()->StackLimit; \
}
+#endif /* LIBCAPTIVE */
+
+#ifndef LIBCAPTIVE
+
#define SehpGetExceptionList() \
(PEXCEPTION_REGISTRATION)(KeGetCurrentThread()->TrapFrame ->ExceptionList)
#define SehpSetExceptionList(NewExceptionList) \
KeGetCurrentThread()->TrapFrame->ExceptionList = (PVOID)(NewExceptionList)
+#else /* !LIBCAPTIVE */
+
+extern guint32 fs_KPCR_ExceptionList;
+
+#define SehpGetExceptionList() \
+ (PEXCEPTION_REGISTRATION)(fs_KPCR_ExceptionList)
+
+#define SehpSetExceptionList(NewExceptionList) \
+ fs_KPCR_ExceptionList = (guint32)(PVOID)(NewExceptionList)
+
+#endif /* LIBCAPTIVE */
+
+#ifndef LIBCAPTIVE
+
#define SehpCaptureContext(Context) \
{ \
KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, (Context)); \
/* Declare a few prototypes for the functions in except.s */
+#endif /* LIBCAPTIVE */
+
EXCEPTION_DISPOSITION
RtlpExecuteHandlerForException(
PEXCEPTION_RECORD ExceptionRecord,
PVOID DispatcherContext,
PEXCEPTION_HANDLER ExceptionHandler);
+#ifndef LIBCAPTIVE
#ifndef NDEBUG
#endif /* NDEBUG */
+#endif /* LIBCAPTIVE */
+
ULONG
RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context)
else
{
/* Copy the (possibly changed) context back to the trap frame and return */
+#ifndef LIBCAPTIVE
NtContinue(Context, FALSE);
+#else /* !LIBCAPTIVE */
+ KeBugCheck(0);
+#endif /* LIBCAPTIVE */
return ExceptionContinueExecution;
}
}
return ExceptionContinueExecution;
}
+#ifndef LIBCAPTIVE
+
VOID STDCALL
RtlRaiseStatus(NTSTATUS Status)
{
RtlRaiseException (& ExceptionRecord);
}
+#endif /* LIBCAPTIVE */
+
VOID STDCALL
RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
PVOID ReturnAddress,
PEXCEPTION_REGISTRATION ERHead;
PEXCEPTION_RECORD pExceptRec;
EXCEPTION_RECORD TempER;
+#ifndef LIBCAPTIVE
CONTEXT Context;
+#endif /* LIBCAPTIVE */
DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame);
}
#endif /* NDEBUG */
+#ifndef LIBCAPTIVE
Context.ContextFlags =
(CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
Context.Esp += 0x10;
Context.Eax = EaxValue;
+#endif /* LIBCAPTIVE */
// Begin traversing the list of EXCEPTION_REGISTRATION
while ((ULONG_PTR)ERHead != (ULONG_PTR)-1)
if (ERHead == RegistrationFrame)
{
DPRINT("Continueing execution\n");
+#ifndef LIBCAPTIVE
NtContinue(&Context, FALSE);
+#else /* !LIBCAPTIVE */
+ /* FIXME: What to do there? */
+#endif /* LIBCAPTIVE */
return;
}
else
ReturnValue = RtlpExecuteHandlerForUnwind(
pExceptRec,
ERHead,
+#ifndef LIBCAPTIVE
&Context,
+#else /* !LIBCAPTIVE */
+ NULL,
+#endif /* LIBCAPTIVE */
&NewERHead,
ERHead->handler);
DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n",
RegistrationFrame);
+#ifndef LIBCAPTIVE
if ((ULONG_PTR)RegistrationFrame == (ULONG_PTR)-1)
NtContinue(&Context, FALSE);
else
NtRaiseException(pExceptRec, &Context, 0);
+#else /* !LIBCAPTIVE */
+ KeBugCheck(0);
+#endif /* LIBCAPTIVE */
}
/* EOF */
#define CONTEXT_EBX 0xA4
#define CONTEXT_EIP 0xB8
+#define __local_unwind2 _local_unwind2 /* LIBCAPTIVE */
+#define __except_handler3 _except_handler3 /* LIBCAPTIVE */
+#define __global_unwind2 _global_unwind2 /* LIBCAPTIVE */
+
+#if 0 /* LIBCAPTIVE */
.globl __local_unwind2
+#endif /* LIBCAPTIVE */
.globl __except_handler3
+#if 0 /* LIBCAPTIVE */
+
// EAX = value to print
_do_debug:
pushal
popal
ret
+#endif /* LIBCAPTIVE */
+
#define LU2_TRYLEVEL 0x08
#define LU2_REGFRAME 0x04
//
// void
-// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,
-// LONG TryLevel)
+// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,LONG TryLevel)
//
// Parameters:
-// [EDX+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
-// [EDX+04h] - LONG TryLevel
+// [EDX+08h] - LONG TryLevel
+// [EDX+04h] - PEXCEPTION_REGISTRATION RegistrationFrame
// Registers:
// EBP - EBP of call frame we are unwinding
// Returns:
// Notes:
// Run all termination handlers for a call frame from the current
// try-level up to (but not including) the given stop try-level.
+#if 0
__local_unwind2:
// Setup our call frame so we can access parameters using EDX
//pushl %ebp
//movl %esi, %esp
//popl %ebp
ret
+#endif
#define EH3_DISPCONTEXT 0x14
#define EH3_CONTEXT 0x10
// Setup our call frame so we can access parameters using EBP
pushl %ebp // Standard ESP in frame (considered part of EXCEPTION_REGISTRATION)
movl %esp, %ebp
+ pushl %ebx /* LIBCAPTIVE */
+ pushl %esi /* LIBCAPTIVE */
+ pushl %edi /* LIBCAPTIVE */
// Don't trust the direction flag to be cleared
cld
+ // Keep a pointer to the exception registration in EBX
+ movl EH3_REGFRAME(%ebp), %ebx
+
// Either we're called to handle an exception or we're called to unwind
movl EH3_ERECORD(%ebp), %eax
testl $EXCEPTION_UNWIND_MODE, EREC_FLAGS(%eax)
jnz .eh3_unwind
- // Keep a pointer to the exception registration in EBX
- movl EH3_REGFRAME(%ebp), %ebx
-
// Build an EXCEPTION_POINTERS structure on the stack and store it's
// address in the EXCEPTION_REGISTRATION structure
- movl EH3_CONTEXT(%esp), %eax
+ movl EH3_CONTEXT(%ebp), %eax
pushl %ebx // Registration frame
pushl %eax // Context
movl %esp, ER_EPOINTERS(%ebx) // Pointer to EXCEPTION_REGISTRATION on the stack
// Change the context structure so _except_finish is called in the
// correct context since we return ExceptionContinueExecution.
+#if 0 /* LIBCAPTIVE */
movl EH3_CONTEXT(%ebp), %eax
movl %edi, CONTEXT_EDI(%eax) // Stop try-level
movl $ExceptionContinueExecution, %eax
jmp .eh3_return
+#else /* !LIBCAPTIVE */
+ // pass %edi
+ // pass %ebx
+ jmp _except_finish
+#endif /* LIBCAPTIVE */
// Filter returned: EXCEPTION_CONTINUE_SEARCH
.eh3_continue:
// Perform local unwinding
.eh3_unwind:
- movl $ExceptionContinueSearch, %eax
testl $EXCEPTION_TARGET_UNWIND, EREC_FLAGS(%eax)
+ movl $ExceptionContinueSearch, %eax
jnz .eh3_return
// Save some important registers
lea ER_EBP(%ebx), %ebp
pushl $-1
pushl %ebx
+
+#if 0 /* LIBCAPTIVE */
call __local_unwind2
+#else /* !LIBCAPTIVE */
+ .extern _local_unwind2_addr
+ movl _local_unwind2_addr,%eax
+ call *%eax
+#endif /* LIBCAPTIVE */
+
addl $8, %esp
// Restore some important registers
// Get me out of here
.eh3_return:
- movl %ebp, %esp
+ lea -3*4(%ebp),%esp /* LIBCAPTIVE */
+ popl %edi /* LIBCAPTIVE */
+ popl %esi /* LIBCAPTIVE */
+ popl %ebx /* LIBCAPTIVE */
+#if 0 /* LIBCAPTIVE */
+ movl %ebp, %esp
+#endif /* LIBCAPTIVE */
popl %ebp
ret
// Pointer to exception registration structure
pushl %ebx
+
+#if 0 /* LIBCAPTIVE */
call __local_unwind2
+#else /* !LIBCAPTIVE */
+ .extern _local_unwind2_addr
+ movl _local_unwind2_addr,%eax
+ call *%eax
+#endif /* LIBCAPTIVE */
+
addl $8, %esp
// Restore some important registers
call *%eax
// We should never get here
+ hlt
ret