mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Some work-in-progress improvements and rethought of system-level code...notable improvemnts till now are: -The KTHREAD alterted flag is now properly set to FALSE during APC delivery during traps, -More support for PKEXCEPTION_FRAME has been added for future PPC/IA64/etc compatibility -Context to/from TrapFrame functions have been greatly fixed to allow for edited frames, special cases, exceptions and also have the necessary support for supporting sanitation based on PreviousMode - KDBG now shows the proper CS/SS at all times, previous hack was removed. - Systemcall code was optimized a bit and the trap code was made a lot more generic so that in can be made into macros (it currently isn't, for debugging purposes). - V86 Mode trap frame bias has now been added to make trap code a lot more generic and shareable in the future. -More support and fixes for future Debugging capabilities have been added. - Random other scalability and stability code. This is still being worked on, syscall.S looks nasty for now (visually)
svn path=/trunk/; revision=17838
This commit is contained in:
parent
3b0cfca870
commit
7a5244c46d
18 changed files with 1124 additions and 374 deletions
|
@ -256,13 +256,13 @@ LdrpInit(PCONTEXT Context,
|
||||||
SYSTEM_BASIC_INFORMATION SystemInformation;
|
SYSTEM_BASIC_INFORMATION SystemInformation;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("LdrpInit()\n");
|
DPRINT1("LdrpInit()\n");
|
||||||
if (NtCurrentPeb()->Ldr == NULL || NtCurrentPeb()->Ldr->Initialized == FALSE)
|
if (NtCurrentPeb()->Ldr == NULL || NtCurrentPeb()->Ldr->Initialized == FALSE)
|
||||||
{
|
{
|
||||||
Peb = (PPEB)(PEB_BASE);
|
Peb = (PPEB)(PEB_BASE);
|
||||||
DPRINT("Peb %x\n", Peb);
|
DPRINT1("Peb %x\n", Peb);
|
||||||
ImageBase = Peb->ImageBaseAddress;
|
ImageBase = Peb->ImageBaseAddress;
|
||||||
DPRINT("ImageBase %x\n", ImageBase);
|
DPRINT1("ImageBase %x\n", ImageBase);
|
||||||
if (ImageBase <= (PVOID)0x1000)
|
if (ImageBase <= (PVOID)0x1000)
|
||||||
{
|
{
|
||||||
DPRINT("ImageBase is null\n");
|
DPRINT("ImageBase is null\n");
|
||||||
|
@ -271,7 +271,7 @@ LdrpInit(PCONTEXT Context,
|
||||||
|
|
||||||
/* If MZ header exists */
|
/* If MZ header exists */
|
||||||
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
|
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
|
||||||
DPRINT("PEDosHeader %x\n", PEDosHeader);
|
DPRINT1("PEDosHeader %x\n", PEDosHeader);
|
||||||
|
|
||||||
if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
|
if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
|
||||||
PEDosHeader->e_lfanew == 0L ||
|
PEDosHeader->e_lfanew == 0L ||
|
||||||
|
@ -294,10 +294,12 @@ LdrpInit(PCONTEXT Context,
|
||||||
NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
|
NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
|
||||||
|
|
||||||
/* Get number of processors */
|
/* Get number of processors */
|
||||||
|
DPRINT1("Here\n");
|
||||||
Status = ZwQuerySystemInformation(SystemBasicInformation,
|
Status = ZwQuerySystemInformation(SystemBasicInformation,
|
||||||
&SystemInformation,
|
&SystemInformation,
|
||||||
sizeof(SYSTEM_BASIC_INFORMATION),
|
sizeof(SYSTEM_BASIC_INFORMATION),
|
||||||
NULL);
|
NULL);
|
||||||
|
DPRINT1("Here2\n");
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ZwTerminateProcess(NtCurrentProcess(), Status);
|
ZwTerminateProcess(NtCurrentProcess(), Status);
|
||||||
|
|
|
@ -165,7 +165,7 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unhandled, return false */
|
/* Unhandled, return false */
|
||||||
DPRINT1("FALSE:(\n");
|
DPRINT1("FALSE\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,6 @@ ExecuteRuntimeAsserts(VOID)
|
||||||
ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
|
ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
|
||||||
ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
|
ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
|
||||||
ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
|
ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
|
||||||
ASSERT(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
|
|
||||||
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
|
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
|
||||||
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
|
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
|
||||||
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
|
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
|
||||||
|
|
|
@ -40,11 +40,15 @@
|
||||||
#define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */
|
#define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */
|
||||||
#define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present */
|
#define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present */
|
||||||
|
|
||||||
|
#define DR7_ACTIVE 0x00000055 /* If any of these bits are set, a Dr is active */
|
||||||
|
|
||||||
/* Possible values for KTHREAD's NpxState */
|
/* Possible values for KTHREAD's NpxState */
|
||||||
#define NPX_STATE_INVALID 0x01
|
#define NPX_STATE_INVALID 0x01
|
||||||
#define NPX_STATE_VALID 0x02
|
#define NPX_STATE_VALID 0x02
|
||||||
#define NPX_STATE_DIRTY 0x04
|
#define NPX_STATE_DIRTY 0x04
|
||||||
|
|
||||||
|
#define FRAME_EDITED 0xFFF8
|
||||||
|
|
||||||
#ifndef __ASM__
|
#ifndef __ASM__
|
||||||
|
|
||||||
typedef struct _KIRQ_TRAPFRAME
|
typedef struct _KIRQ_TRAPFRAME
|
||||||
|
|
|
@ -287,7 +287,10 @@ VOID inline FASTCALL KiSatisifyMultipleObjectWaits(PKWAIT_BLOCK WaitBlock);
|
||||||
VOID FASTCALL KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment);
|
VOID FASTCALL KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment);
|
||||||
|
|
||||||
PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
|
PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
|
||||||
BOOLEAN STDCALL KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame);
|
BOOLEAN STDCALL KeContextToTrapFrame(PCONTEXT Context,
|
||||||
|
PKEXCEPTION_FRAME ExeptionFrame,
|
||||||
|
PKTRAP_FRAME TrapFrame,
|
||||||
|
KPROCESSOR_MODE PreviousMode);
|
||||||
VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
||||||
PVOID Reserved,
|
PVOID Reserved,
|
||||||
PKTRAP_FRAME TrapFrame);
|
PKTRAP_FRAME TrapFrame);
|
||||||
|
@ -368,8 +371,11 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
PKTRAP_FRAME Tf,
|
PKTRAP_FRAME Tf,
|
||||||
KPROCESSOR_MODE PreviousMode,
|
KPROCESSOR_MODE PreviousMode,
|
||||||
BOOLEAN SearchFrames);
|
BOOLEAN SearchFrames);
|
||||||
VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
|
VOID
|
||||||
PCONTEXT Context);
|
NTAPI
|
||||||
|
KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||||
|
IN OUT PCONTEXT Context);
|
||||||
VOID
|
VOID
|
||||||
KeApplicationProcessorInit(VOID);
|
KeApplicationProcessorInit(VOID);
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -1321,7 +1321,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
#error Unknown compiler for inline assembler
|
#error Unknown compiler for inline assembler
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
KeContextToTrapFrame(Context, NULL, TrapFrame);
|
KeContextToTrapFrame(Context, NULL, TrapFrame, KernelMode);
|
||||||
return ((SigVal == 5) ? (kdContinue) : (kdHandleException));
|
return ((SigVal == 5) ? (kdContinue) : (kdHandleException));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1430,11 +1430,11 @@ GspBreakIn(PKINTERRUPT Interrupt,
|
||||||
|
|
||||||
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
|
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
|
||||||
|
|
||||||
KeTrapFrameToContext (TrapFrame, &Context);
|
KeTrapFrameToContext (TrapFrame, NULL, &Context);
|
||||||
|
|
||||||
KdpGdbEnterDebuggerException (NULL, &Context, TrapFrame);
|
KdpGdbEnterDebuggerException (NULL, &Context, TrapFrame);
|
||||||
|
|
||||||
KeContextToTrapFrame (&Context, NULL, TrapFrame);
|
KeContextToTrapFrame (&Context, NULL, TrapFrame, KernelMode);
|
||||||
|
|
||||||
KeLowerIrql (OldIrql);
|
KeLowerIrql (OldIrql);
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,6 @@
|
||||||
|
|
||||||
/* TYPES *********************************************************************/
|
/* TYPES *********************************************************************/
|
||||||
|
|
||||||
/* FIXME: NDK headers */
|
|
||||||
#define TempEsp TempEip
|
|
||||||
#define TempSegSs TempCs
|
|
||||||
|
|
||||||
/* DEFINES *******************************************************************/
|
/* DEFINES *******************************************************************/
|
||||||
|
|
||||||
#define KDB_STACK_SIZE (4096*3)
|
#define KDB_STACK_SIZE (4096*3)
|
||||||
|
@ -108,6 +104,24 @@ STATIC CONST PCHAR ExceptionNrToString[] =
|
||||||
"SIMD Fault"
|
"SIMD Fault"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Ss);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Esp);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
STATIC VOID
|
STATIC VOID
|
||||||
|
@ -125,20 +139,9 @@ KdbpTrapFrameToKdbTrapFrame(PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFram
|
||||||
: "=r"(KdbTrapFrame->Cr0), "=r"(KdbTrapFrame->Cr2),
|
: "=r"(KdbTrapFrame->Cr0), "=r"(KdbTrapFrame->Cr2),
|
||||||
"=r"(KdbTrapFrame->Cr3), "=r"(KdbTrapFrame->Cr4));
|
"=r"(KdbTrapFrame->Cr3), "=r"(KdbTrapFrame->Cr4));
|
||||||
|
|
||||||
if (TrapFrame->PreviousMode == KernelMode)
|
KdbTrapFrame->Tf.Esp = KiEspFromTrapFrame(TrapFrame);
|
||||||
{
|
KdbTrapFrame->Tf.Ss = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
|
||||||
/* If the trapframe is a kmode one use the temp ss:esp */
|
|
||||||
KdbTrapFrame->Tf.Esp = (ULONG)TrapFrame->TempEsp;
|
|
||||||
KdbTrapFrame->Tf.Ss = (USHORT)((ULONG)TrapFrame->TempSegSs & 0xFFFF);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise use ss:esp pushed by the CPU */
|
|
||||||
/* FIXME: maybe change all trapframes to always put ss:esp into tempss:tempesp so we
|
|
||||||
* can handle umode and kmode the same way */
|
|
||||||
KdbTrapFrame->Tf.Esp = TrapFrame->Esp;
|
|
||||||
KdbTrapFrame->Tf.Ss = TrapFrame->Ss;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
|
/* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
|
||||||
}
|
}
|
||||||
|
@ -151,20 +154,8 @@ KdbpKdbTrapFrameToTrapFrame(PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFram
|
||||||
|
|
||||||
/* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
|
/* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
|
||||||
|
|
||||||
if (TrapFrame->PreviousMode == KernelMode)
|
KiSsToTrapFrame(TrapFrame, KdbTrapFrame->Tf.Ss);
|
||||||
{
|
KiEspToTrapFrame(TrapFrame, KdbTrapFrame->Tf.Esp);
|
||||||
/* If the trapframe is a kmode one write to the temp ss:esp */
|
|
||||||
TrapFrame->TempEsp = (PVOID)KdbTrapFrame->Tf.Esp;
|
|
||||||
TrapFrame->TempSegSs = (PVOID)(((ULONG)TrapFrame->TempSegSs & ~0xffff) | KdbTrapFrame->Tf.Ss);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise write to ss:esp pushed by the CPU */
|
|
||||||
/* FIXME: maybe change all trap-epilogs to always put temp ss:esp into ss:esp so we
|
|
||||||
* can handle umode and kmode the same way */
|
|
||||||
TrapFrame->Esp = KdbTrapFrame->Tf.Esp;
|
|
||||||
TrapFrame->Ss = KdbTrapFrame->Tf.Ss;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
|
/* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,6 @@
|
||||||
|
|
||||||
/* DEFINES *******************************************************************/
|
/* DEFINES *******************************************************************/
|
||||||
|
|
||||||
/* FIXME: NDK headers */
|
|
||||||
#define TempEsp TempEip
|
|
||||||
#define TempSegSs TempCs
|
|
||||||
|
|
||||||
#define KEY_BS 8
|
#define KEY_BS 8
|
||||||
#define KEY_ESC 27
|
#define KEY_ESC 27
|
||||||
#define KEY_DEL 127
|
#define KEY_DEL 127
|
||||||
|
|
|
@ -812,7 +812,7 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||||
|
|
||||||
/* Save the full context */
|
/* Save the full context */
|
||||||
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||||
KeTrapFrameToContext(TrapFrame, &Context);
|
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
|
||||||
|
|
||||||
/* Protect with SEH */
|
/* Protect with SEH */
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
|
|
|
@ -28,7 +28,7 @@ KiContinuePreviousModeUser(IN PCONTEXT Context,
|
||||||
Context = &LocalContext;
|
Context = &LocalContext;
|
||||||
|
|
||||||
/* Convert the context into Exception/Trap Frames */
|
/* Convert the context into Exception/Trap Frames */
|
||||||
KeContextToTrapFrame(&LocalContext, ExceptionFrame, TrapFrame);
|
KeContextToTrapFrame(&LocalContext, ExceptionFrame, TrapFrame, UserMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -62,7 +62,7 @@ KiContinue(IN PCONTEXT Context,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Convert the context into Exception/Trap Frames */
|
/* Convert the context into Exception/Trap Frames */
|
||||||
KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame);
|
KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame, KernelMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
|
@ -142,7 +142,7 @@ KiRaiseException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Convert the context record */
|
/* Convert the context record */
|
||||||
KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame);
|
KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame, PreviousMode);
|
||||||
|
|
||||||
/* Dispatch the exception */
|
/* Dispatch the exception */
|
||||||
KiDispatchException(ExceptionRecord,
|
KiDispatchException(ExceptionRecord,
|
||||||
|
|
|
@ -114,7 +114,7 @@ BadThread:
|
||||||
.globl @KiSwapContextInternal@0
|
.globl @KiSwapContextInternal@0
|
||||||
@KiSwapContextInternal@0:
|
@KiSwapContextInternal@0:
|
||||||
#ifdef KDBG
|
#ifdef KDBG
|
||||||
jmp SaveTrapFrameForKDB
|
//jmp SaveTrapFrameForKDB
|
||||||
SaveTrapFrameForKDB_Return:
|
SaveTrapFrameForKDB_Return:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -130,12 +130,14 @@ SaveTrapFrameForKDB_Return:
|
||||||
/* Switching, disable interrupts now */
|
/* Switching, disable interrupts now */
|
||||||
cli
|
cli
|
||||||
|
|
||||||
|
/* Save the initial stack in EAX */
|
||||||
|
mov eax, [edi+KTHREAD_INITIAL_STACK]
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* Save FPU state if the thread has used it. */
|
/* Save FPU state if the thread has used it. */
|
||||||
mov dword ptr [ebx+KPCR_NPX_THREAD], 0
|
mov dword ptr [ebx+KPCR_NPX_THREAD], 0
|
||||||
test byte ptr [edi+KTHREAD_NPX_STATE], NPX_STATE_DIRTY
|
test byte ptr [edi+KTHREAD_NPX_STATE], NPX_STATE_DIRTY
|
||||||
jz 3f
|
jz 3f
|
||||||
mov eax, [edi+KTHREAD_INITIAL_STACK]
|
|
||||||
cmp dword ptr _FxsrSupport, 0
|
cmp dword ptr _FxsrSupport, 0
|
||||||
je 1f
|
je 1f
|
||||||
fxsave [eax-SIZEOF_FX_SAVE_AREA]
|
fxsave [eax-SIZEOF_FX_SAVE_AREA]
|
||||||
|
@ -149,6 +151,16 @@ SaveTrapFrameForKDB_Return:
|
||||||
|
|
||||||
/* Save the stack pointer in this processors TSS */
|
/* Save the stack pointer in this processors TSS */
|
||||||
mov ebp, [ebx+KPCR_TSS]
|
mov ebp, [ebx+KPCR_TSS]
|
||||||
|
|
||||||
|
/* Check if this isn't V86 Mode, so we can bias the Esp0 */
|
||||||
|
test dword ptr [eax - KTRAP_FRAME_SIZE + KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
|
||||||
|
jnz NoAdjust
|
||||||
|
|
||||||
|
/* Bias esp */
|
||||||
|
//sub dword ptr ss:[ebp+KTSS_ESP0], KTRAP_FRAME_V86_GS - KTRAP_FRAME_SS
|
||||||
|
|
||||||
|
NoAdjust:
|
||||||
|
/* Push ESP0 Value */
|
||||||
push ss:[ebp+KTSS_ESP0]
|
push ss:[ebp+KTSS_ESP0]
|
||||||
|
|
||||||
/* Check if address space switch is needed */
|
/* Check if address space switch is needed */
|
||||||
|
|
|
@ -17,14 +17,18 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXMES:
|
* FIXMES:
|
||||||
|
* - Put back VEH.
|
||||||
* - Clean up file.
|
* - Clean up file.
|
||||||
* - Add more exception frame support for non-i386 compatibility.
|
* - Sanitize some context fields.
|
||||||
* - Add PSEH handler when an exception occurs in an exception (KiCopyExceptionRecord).
|
* - Add PSEH handler when an exception occurs in an exception (KiCopyExceptionRecord).
|
||||||
* - Implement official stack trace functions (exported) and remove stuff here.
|
* - Implement official stack trace functions (exported) and remove stuff here.
|
||||||
* - Forward exceptions to user-mode debugger.
|
* - Forward exceptions to user-mode debugger.
|
||||||
* - Wrap Ki NTDLL callbacks in SEH.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
#define FLAG_IF (1<<9)
|
#define FLAG_IF (1<<9)
|
||||||
|
@ -485,14 +489,14 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
ASSERT(ExceptionNr != 14);
|
ASSERT(ExceptionNr != 14);
|
||||||
|
|
||||||
/* Store the exception number in an unused field in the trap frame. */
|
/* Store the exception number in an unused field in the trap frame. */
|
||||||
Tf->DebugArgMark = (PVOID)ExceptionNr;
|
Tf->DebugArgMark = ExceptionNr;
|
||||||
|
|
||||||
/* Use the address of the trap frame as approximation to the ring0 esp */
|
/* Use the address of the trap frame as approximation to the ring0 esp */
|
||||||
Esp0 = (ULONG)&Tf->Eip;
|
Esp0 = (ULONG)&Tf->Eip;
|
||||||
|
|
||||||
/* Get CR2 */
|
/* Get CR2 */
|
||||||
cr2 = Ke386GetCr2();
|
cr2 = Ke386GetCr2();
|
||||||
Tf->DebugPointer = (PVOID)cr2;
|
Tf->DebugPointer = cr2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this was a V86 mode exception then handle it specially
|
* If this was a V86 mode exception then handle it specially
|
||||||
|
@ -566,21 +570,172 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
ULONG
|
||||||
STDCALL
|
NTAPI
|
||||||
KeContextToTrapFrame(PCONTEXT Context,
|
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
|
||||||
PKEXCEPTION_FRAME ExceptionFrame,
|
|
||||||
PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
|
/* Check if this is user-mode or V86 */
|
||||||
|
if ((TrapFrame->Cs & 1) || (TrapFrame->Eflags & X86_EFLAGS_VM))
|
||||||
|
{
|
||||||
|
/* Return it directly */
|
||||||
|
return TrapFrame->Esp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Edited frame */
|
||||||
|
if (!(TrapFrame->Cs & FRAME_EDITED))
|
||||||
|
{
|
||||||
|
/* Return edited value */
|
||||||
|
return TrapFrame->TempEsp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Virgin frame, calculate */
|
||||||
|
return (ULONG)&TrapFrame->Esp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Esp)
|
||||||
|
{
|
||||||
|
ULONG Previous = KiEspFromTrapFrame(TrapFrame);
|
||||||
|
|
||||||
|
/* Check if this is user-mode or V86 */
|
||||||
|
if ((TrapFrame->Cs & 1) || (TrapFrame->Eflags & X86_EFLAGS_VM))
|
||||||
|
{
|
||||||
|
/* Write it directly */
|
||||||
|
TrapFrame->Esp = Esp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Don't allow ESP to be lowered, this is illegal */
|
||||||
|
if (Esp < Previous)
|
||||||
|
{
|
||||||
|
//KeBugCheck(SET_OF_INVALID_CONTEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create an edit frame, check if it was alrady */
|
||||||
|
if (!(TrapFrame->Cs & FRAME_EDITED))
|
||||||
|
{
|
||||||
|
/* Update the value */
|
||||||
|
TrapFrame->TempEsp = Esp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if ESP changed */
|
||||||
|
if (Previous != Esp)
|
||||||
|
{
|
||||||
|
/* Save CS */
|
||||||
|
TrapFrame->TempCs = TrapFrame->Cs;
|
||||||
|
TrapFrame->Cs &= ~FRAME_EDITED;
|
||||||
|
|
||||||
|
/* Save ESP */
|
||||||
|
TrapFrame->TempEsp = Esp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
/* If this was V86 Mode */
|
||||||
|
if (TrapFrame->Eflags & X86_EFLAGS_VM)
|
||||||
|
{
|
||||||
|
/* Just return it */
|
||||||
|
return TrapFrame->Ss;
|
||||||
|
}
|
||||||
|
else if (TrapFrame->Cs & 1)
|
||||||
|
{
|
||||||
|
/* Usermode, return the User SS */
|
||||||
|
return TrapFrame->Ss | 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Kernel mode */
|
||||||
|
return KERNEL_DS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Ss)
|
||||||
|
{
|
||||||
|
/* Remove the high-bits */
|
||||||
|
Ss &= 0xFFFF;
|
||||||
|
|
||||||
|
/* If this was V86 Mode */
|
||||||
|
if (TrapFrame->Eflags & X86_EFLAGS_VM)
|
||||||
|
{
|
||||||
|
/* Just write it */
|
||||||
|
TrapFrame->Ss = Ss;
|
||||||
|
}
|
||||||
|
else if (TrapFrame->Cs & 1)
|
||||||
|
{
|
||||||
|
/* Usermode, save the User SS */
|
||||||
|
TrapFrame->Ss = Ss | 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeContextToTrapFrame(IN PCONTEXT Context,
|
||||||
|
IN OUT PKEXCEPTION_FRAME ExceptionFrame,
|
||||||
|
IN OUT PKTRAP_FRAME TrapFrame,
|
||||||
|
IN KPROCESSOR_MODE PreviousMode)
|
||||||
|
{
|
||||||
|
BOOLEAN V86Switch = FALSE;
|
||||||
|
|
||||||
/* Start with the basic Registers */
|
/* Start with the basic Registers */
|
||||||
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
|
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
|
||||||
{
|
{
|
||||||
TrapFrame->Esp = Context->Esp;
|
/* Check if we went through a V86 switch */
|
||||||
TrapFrame->Ss = Context->SegSs;
|
if ((Context->EFlags & X86_EFLAGS_VM) !=
|
||||||
TrapFrame->Cs = Context->SegCs;
|
(TrapFrame->Eflags & X86_EFLAGS_VM))
|
||||||
TrapFrame->Eip = Context->Eip;
|
{
|
||||||
|
/* We did, remember this for later */
|
||||||
|
V86Switch = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy EFLAGS. FIXME: Needs to be sanitized */
|
||||||
TrapFrame->Eflags = Context->EFlags;
|
TrapFrame->Eflags = Context->EFlags;
|
||||||
|
|
||||||
|
/* Copy EBP and EIP */
|
||||||
TrapFrame->Ebp = Context->Ebp;
|
TrapFrame->Ebp = Context->Ebp;
|
||||||
|
TrapFrame->Eip = Context->Eip;
|
||||||
|
|
||||||
|
/* Check if we were in V86 Mode */
|
||||||
|
if (TrapFrame->Eflags & X86_EFLAGS_VM)
|
||||||
|
{
|
||||||
|
/* Simply copy the CS value */
|
||||||
|
TrapFrame->Cs = Context->SegCs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We weren't in V86, so sanitize the CS (FIXME!) */
|
||||||
|
TrapFrame->Cs = Context->SegCs;
|
||||||
|
|
||||||
|
/* Don't let it under 8, that's invalid */
|
||||||
|
if ((PreviousMode !=KernelMode) && (TrapFrame->Cs < 8))
|
||||||
|
{
|
||||||
|
/* Force it to User CS */
|
||||||
|
TrapFrame->Cs = USER_CS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle SS Specially for validation */
|
||||||
|
KiSsToTrapFrame(TrapFrame, Context->SegSs);
|
||||||
|
|
||||||
|
/* Write ESP back; take into account Edited Trap Frames */
|
||||||
|
KiEspToTrapFrame(TrapFrame, Context->Esp);
|
||||||
|
|
||||||
|
/* Handle our V86 Bias if we went through a switch */
|
||||||
|
if (V86Switch) Ki386AdjustEsp0(TrapFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the Integer Registers */
|
/* Process the Integer Registers */
|
||||||
|
@ -597,21 +752,62 @@ KeContextToTrapFrame(PCONTEXT Context,
|
||||||
/* Process the Context Segments */
|
/* Process the Context Segments */
|
||||||
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
|
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
|
||||||
{
|
{
|
||||||
|
/* Check if we were in V86 Mode */
|
||||||
|
if (TrapFrame->Eflags & X86_EFLAGS_VM)
|
||||||
|
{
|
||||||
|
/* Copy the V86 Segments directlry */
|
||||||
|
TrapFrame->V86_Ds = Context->SegDs;
|
||||||
|
TrapFrame->V86_Es = Context->SegEs;
|
||||||
|
TrapFrame->V86_Fs = Context->SegFs;
|
||||||
|
TrapFrame->V86_Gs = Context->SegGs;
|
||||||
|
}
|
||||||
|
else if (!(TrapFrame->Cs & 1))
|
||||||
|
{
|
||||||
|
/* For user mode, write the values directly */
|
||||||
|
TrapFrame->Ds = USER_DS;
|
||||||
|
TrapFrame->Es = USER_DS;
|
||||||
|
TrapFrame->Fs = Context->SegFs;
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
TrapFrame->Gs = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For kernel-mode, return the values */
|
||||||
TrapFrame->Ds = Context->SegDs;
|
TrapFrame->Ds = Context->SegDs;
|
||||||
TrapFrame->Es = Context->SegEs;
|
TrapFrame->Es = Context->SegEs;
|
||||||
TrapFrame->Fs = Context->SegFs;
|
TrapFrame->Fs = Context->SegFs;
|
||||||
|
|
||||||
|
/* Handle GS specially */
|
||||||
|
if (TrapFrame->Cs == USER_CS)
|
||||||
|
{
|
||||||
|
/* Don't use it, if user */
|
||||||
|
TrapFrame->Gs = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Copy it if kernel */
|
||||||
TrapFrame->Gs = Context->SegGs;
|
TrapFrame->Gs = Context->SegGs;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle the Debug Registers */
|
/* Handle the Debug Registers */
|
||||||
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
|
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
|
||||||
{
|
{
|
||||||
|
/* FIXME: All these should be sanitized */
|
||||||
TrapFrame->Dr0 = Context->Dr0;
|
TrapFrame->Dr0 = Context->Dr0;
|
||||||
TrapFrame->Dr1 = Context->Dr1;
|
TrapFrame->Dr1 = Context->Dr1;
|
||||||
TrapFrame->Dr2 = Context->Dr2;
|
TrapFrame->Dr2 = Context->Dr2;
|
||||||
TrapFrame->Dr3 = Context->Dr3;
|
TrapFrame->Dr3 = Context->Dr3;
|
||||||
TrapFrame->Dr6 = Context->Dr6;
|
TrapFrame->Dr6 = Context->Dr6;
|
||||||
TrapFrame->Dr7 = Context->Dr7;
|
TrapFrame->Dr7 = Context->Dr7;
|
||||||
|
|
||||||
|
/* Check if usermode */
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
/* Set the Debug Flag */
|
||||||
|
KeGetCurrentThread()->DebugActive = (Context->Dr7 & DR7_ACTIVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle FPU and Extended Registers */
|
/* Handle FPU and Extended Registers */
|
||||||
|
@ -619,42 +815,81 @@ KeContextToTrapFrame(PCONTEXT Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
|
NTAPI
|
||||||
PCONTEXT Context)
|
KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||||
|
IN OUT PCONTEXT Context)
|
||||||
{
|
{
|
||||||
|
/* Start with the Control flags */
|
||||||
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
|
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
|
||||||
{
|
{
|
||||||
Context->SegSs = TrapFrame->Ss;
|
/* EBP, EIP and EFLAGS */
|
||||||
Context->Esp = TrapFrame->Esp;
|
Context->Ebp = TrapFrame->Ebp;
|
||||||
Context->SegCs = TrapFrame->Cs;
|
|
||||||
Context->Eip = TrapFrame->Eip;
|
Context->Eip = TrapFrame->Eip;
|
||||||
Context->EFlags = TrapFrame->Eflags;
|
Context->EFlags = TrapFrame->Eflags;
|
||||||
Context->Ebp = TrapFrame->Ebp;
|
|
||||||
|
/* Return the correct CS */
|
||||||
|
if (!(TrapFrame->Cs & FRAME_EDITED) &&
|
||||||
|
!(TrapFrame->Eflags & X86_EFLAGS_VM))
|
||||||
|
{
|
||||||
|
/* Get it from the Temp location */
|
||||||
|
Context->SegCs = TrapFrame->TempCs & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Return it directly */
|
||||||
|
Context->SegCs = TrapFrame->Cs & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Ss and ESP */
|
||||||
|
Context->SegSs = KiSsFromTrapFrame(TrapFrame);
|
||||||
|
Context->Esp = KiEspFromTrapFrame(TrapFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the Segments */
|
||||||
|
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
|
||||||
|
{
|
||||||
|
/* Do V86 Mode first */
|
||||||
|
if (TrapFrame->Eflags & X86_EFLAGS_VM)
|
||||||
|
{
|
||||||
|
/* Return from the V86 location */
|
||||||
|
Context->SegGs = TrapFrame->V86_Gs & 0xFFFF;
|
||||||
|
Context->SegFs = TrapFrame->V86_Fs & 0xFFFF;
|
||||||
|
Context->SegEs = TrapFrame->V86_Es & 0xFFFF;
|
||||||
|
Context->SegDs = TrapFrame->V86_Ds & 0xFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if this was a Kernel Trap */
|
||||||
|
if (TrapFrame->Cs == KERNEL_CS)
|
||||||
|
{
|
||||||
|
/* Set valid selectors */
|
||||||
|
TrapFrame->Gs = 0;
|
||||||
|
TrapFrame->Fs = PCR_SELECTOR;
|
||||||
|
TrapFrame->Es = USER_DS;
|
||||||
|
TrapFrame->Ds = USER_DS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the segments */
|
||||||
|
Context->SegGs = TrapFrame->Gs & 0xFFFF;
|
||||||
|
Context->SegFs = TrapFrame->Fs & 0xFFFF;
|
||||||
|
Context->SegEs = TrapFrame->Es & 0xFFFF;
|
||||||
|
Context->SegDs = TrapFrame->Ds & 0xFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the simple registers */
|
||||||
if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
|
if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
|
||||||
{
|
{
|
||||||
|
/* Return them directly */
|
||||||
Context->Eax = TrapFrame->Eax;
|
Context->Eax = TrapFrame->Eax;
|
||||||
Context->Ebx = TrapFrame->Ebx;
|
Context->Ebx = TrapFrame->Ebx;
|
||||||
Context->Ecx = TrapFrame->Ecx;
|
Context->Ecx = TrapFrame->Ecx;
|
||||||
/*
|
|
||||||
* NOTE: In the trap frame which is built on entry to a system
|
|
||||||
* call TrapFrame->Edx will actually hold the address of the
|
|
||||||
* previous TrapFrame. I don't believe leaking this information
|
|
||||||
* has security implications. Also EDX holds the address of the
|
|
||||||
* arguments to the system call in progress so it isn't of much
|
|
||||||
* interest to the debugger.
|
|
||||||
*/
|
|
||||||
Context->Edx = TrapFrame->Edx;
|
Context->Edx = TrapFrame->Edx;
|
||||||
Context->Esi = TrapFrame->Esi;
|
Context->Esi = TrapFrame->Esi;
|
||||||
Context->Edi = TrapFrame->Edi;
|
Context->Edi = TrapFrame->Edi;
|
||||||
}
|
}
|
||||||
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
|
|
||||||
{
|
|
||||||
Context->SegDs = TrapFrame->Ds;
|
|
||||||
Context->SegEs = TrapFrame->Es;
|
|
||||||
Context->SegFs = TrapFrame->Fs;
|
|
||||||
Context->SegGs = TrapFrame->Gs;
|
|
||||||
}
|
|
||||||
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
|
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -931,7 +1166,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
ULONG_PTR Stack, NewStack;
|
ULONG_PTR Stack, NewStack;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
BOOLEAN UserDispatch = FALSE;
|
BOOLEAN UserDispatch = FALSE;
|
||||||
DPRINT1("KiDispatchException() called\n");
|
DPRINT("KiDispatchException() called\n");
|
||||||
|
|
||||||
/* Increase number of Exception Dispatches */
|
/* Increase number of Exception Dispatches */
|
||||||
KeGetCurrentPrcb()->KeExceptionDispatchCount++;
|
KeGetCurrentPrcb()->KeExceptionDispatchCount++;
|
||||||
|
@ -947,7 +1182,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a Context */
|
/* Get a Context */
|
||||||
KeTrapFrameToContext(TrapFrame, &Context);
|
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
|
||||||
|
|
||||||
/* Handle kernel-mode first, it's simpler */
|
/* Handle kernel-mode first, it's simpler */
|
||||||
if (PreviousMode == KernelMode)
|
if (PreviousMode == KernelMode)
|
||||||
|
@ -1017,7 +1252,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
/* Align context size and get stack pointer */
|
/* Align context size and get stack pointer */
|
||||||
Size = (sizeof(CONTEXT) + 3) & ~3;
|
Size = (sizeof(CONTEXT) + 3) & ~3;
|
||||||
Stack = (Context.Esp & ~3) - Size;
|
Stack = (Context.Esp & ~3) - Size;
|
||||||
DPRINT1("Stack: %lx\n", Stack);
|
DPRINT("Stack: %lx\n", Stack);
|
||||||
|
|
||||||
/* Probe stack and copy Context */
|
/* Probe stack and copy Context */
|
||||||
ProbeForWrite((PVOID)Stack, Size, sizeof(ULONG));
|
ProbeForWrite((PVOID)Stack, Size, sizeof(ULONG));
|
||||||
|
@ -1028,7 +1263,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
(EXCEPTION_MAXIMUM_PARAMETERS - ExceptionRecord->NumberParameters) *
|
(EXCEPTION_MAXIMUM_PARAMETERS - ExceptionRecord->NumberParameters) *
|
||||||
sizeof(ULONG) + 3) & ~3;
|
sizeof(ULONG) + 3) & ~3;
|
||||||
NewStack = Stack - Size;
|
NewStack = Stack - Size;
|
||||||
DPRINT1("NewStack: %lx\n", NewStack);
|
DPRINT("NewStack: %lx\n", NewStack);
|
||||||
|
|
||||||
/* Probe stack and copy exception record. Don't forget to add the two params */
|
/* Probe stack and copy exception record. Don't forget to add the two params */
|
||||||
ProbeForWrite((PVOID)(NewStack - 2 * sizeof(ULONG_PTR)),
|
ProbeForWrite((PVOID)(NewStack - 2 * sizeof(ULONG_PTR)),
|
||||||
|
@ -1041,7 +1276,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
*(PULONG_PTR)(NewStack - 2 * sizeof(ULONG_PTR)) = NewStack;
|
*(PULONG_PTR)(NewStack - 2 * sizeof(ULONG_PTR)) = NewStack;
|
||||||
|
|
||||||
/* Set new Stack Pointer */
|
/* Set new Stack Pointer */
|
||||||
TrapFrame->Esp = NewStack - 2 * sizeof(ULONG_PTR);
|
KiEspToTrapFrame(TrapFrame, NewStack - 2 * sizeof(ULONG_PTR));
|
||||||
|
|
||||||
/* Set EIP to the User-mode Dispathcer */
|
/* Set EIP to the User-mode Dispathcer */
|
||||||
TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
|
TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
|
||||||
|
@ -1073,7 +1308,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
|
||||||
Handled:
|
Handled:
|
||||||
/* Convert the context back into Trap/Exception Frames */
|
/* Convert the context back into Trap/Exception Frames */
|
||||||
KeContextToTrapFrame(&Context, NULL, TrapFrame);
|
KeContextToTrapFrame(&Context, NULL, TrapFrame, PreviousMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -528,7 +528,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
|
|
||||||
/* Fill the rest of the context */
|
/* Fill the rest of the context */
|
||||||
Context->ContextFlags = CONTEXT_FULL;
|
Context->ContextFlags = CONTEXT_FULL;
|
||||||
KeTrapFrameToContext(Tf, Context);
|
KeTrapFrameToContext(Tf, NULL, Context);
|
||||||
Context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
|
Context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
|
||||||
|
|
||||||
/* Determine exception code */
|
/* Determine exception code */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -85,7 +85,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
|
||||||
TrapFrame = &InitFrame->TrapFrame;
|
TrapFrame = &InitFrame->TrapFrame;
|
||||||
|
|
||||||
/* Set up a trap frame from the context. */
|
/* Set up a trap frame from the context. */
|
||||||
if (KeContextToTrapFrame(Context, NULL, TrapFrame))
|
if (KeContextToTrapFrame(Context, NULL, TrapFrame, UserMode))
|
||||||
{
|
{
|
||||||
Thread->NpxState = NPX_STATE_VALID;
|
Thread->NpxState = NPX_STATE_VALID;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,9 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
|
||||||
|
|
||||||
/* And set up the Context Switch Frame */
|
/* And set up the Context Switch Frame */
|
||||||
CtxSwitchFrame->RetEip = KiThreadStartup;
|
CtxSwitchFrame->RetEip = KiThreadStartup;
|
||||||
CtxSwitchFrame->Esp0 = (ULONG)Thread->InitialStack - sizeof(FX_SAVE_AREA);
|
CtxSwitchFrame->Esp0 = (ULONG_PTR)Thread->InitialStack -
|
||||||
|
sizeof(FX_SAVE_AREA) -
|
||||||
|
0x10;
|
||||||
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
|
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
|
||||||
|
|
||||||
/* Save back the new value of the kernel stack. */
|
/* Save back the new value of the kernel stack. */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <roscfg.h>
|
#include <roscfg.h>
|
||||||
#include <ndk/asm.h>
|
#include <ndk/asm.h>
|
||||||
|
#include <internal/i386/ke.h>
|
||||||
#include <ndk/i386/segment.h>
|
#include <ndk/i386/segment.h>
|
||||||
|
|
||||||
#define KernelMode 0
|
#define KernelMode 0
|
||||||
|
@ -374,4 +375,37 @@ _KiCoprocessorError@0:
|
||||||
/* Return to caller */
|
/* Return to caller */
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.globl _Ki386AdjustEsp0@4
|
||||||
|
_Ki386AdjustEsp0@4:
|
||||||
|
|
||||||
|
/* Get the current thread */
|
||||||
|
mov eax, [fs:KPCR_CURRENT_THREAD]
|
||||||
|
|
||||||
|
/* Get trap frame and stack */
|
||||||
|
mov edx, [esp+4]
|
||||||
|
mov eax, [eax+KTHREAD_INITIAL_STACK]
|
||||||
|
|
||||||
|
/* Check if V86 */
|
||||||
|
test dword ptr [edx+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
|
||||||
|
jnz NoAdjust
|
||||||
|
|
||||||
|
/* Bias the stack */
|
||||||
|
sub eax, KTRAP_FRAME_V86_GS - KTRAP_FRAME_SS
|
||||||
|
|
||||||
|
NoAdjust:
|
||||||
|
/* Skip FX Save Area */
|
||||||
|
sub eax, SIZEOF_FX_SAVE_AREA
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
pushf
|
||||||
|
cli
|
||||||
|
|
||||||
|
/* Adjust ESP0 */
|
||||||
|
mov edx, [fs:KPCR_TSS]
|
||||||
|
mov ss:[edx+KTSS_ESP0], eax
|
||||||
|
|
||||||
|
/* Enable interrupts and return */
|
||||||
|
popf
|
||||||
|
ret 4
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -36,11 +36,11 @@ ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
ASSERT(ExceptionNr == 14);
|
ASSERT(ExceptionNr == 14);
|
||||||
|
|
||||||
/* Store the exception number in an unused field in the trap frame. */
|
/* Store the exception number in an unused field in the trap frame. */
|
||||||
Tf->DebugArgMark = (PVOID)14;
|
Tf->DebugArgMark = 14;
|
||||||
|
|
||||||
/* get the faulting address */
|
/* get the faulting address */
|
||||||
cr2 = Ke386GetCr2();
|
cr2 = Ke386GetCr2();
|
||||||
Tf->DebugPointer = (PVOID)cr2;
|
Tf->DebugPointer = cr2;
|
||||||
|
|
||||||
/* it's safe to enable interrupts after cr2 has been saved */
|
/* it's safe to enable interrupts after cr2 has been saved */
|
||||||
if (Tf->Eflags & (X86_EFLAGS_VM|X86_EFLAGS_IF))
|
if (Tf->Eflags & (X86_EFLAGS_VM|X86_EFLAGS_IF))
|
||||||
|
|
|
@ -22,6 +22,7 @@ typedef struct _GET_SET_CTX_CONTEXT {
|
||||||
KAPC Apc;
|
KAPC Apc;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
CONTEXT Context;
|
CONTEXT Context;
|
||||||
|
KPROCESSOR_MODE Mode;
|
||||||
} GET_SET_CTX_CONTEXT, *PGET_SET_CTX_CONTEXT;
|
} GET_SET_CTX_CONTEXT, *PGET_SET_CTX_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,22 +43,24 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc,
|
||||||
PGET_SET_CTX_CONTEXT GetSetContext;
|
PGET_SET_CTX_CONTEXT GetSetContext;
|
||||||
PKEVENT Event;
|
PKEVENT Event;
|
||||||
PCONTEXT Context;
|
PCONTEXT Context;
|
||||||
|
KPROCESSOR_MODE Mode;
|
||||||
|
|
||||||
/* Get the Context Structure */
|
/* Get the Context Structure */
|
||||||
GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
|
GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
|
||||||
Context = &GetSetContext->Context;
|
Context = &GetSetContext->Context;
|
||||||
Event = &GetSetContext->Event;
|
Event = &GetSetContext->Event;
|
||||||
|
Mode = GetSetContext->Mode;
|
||||||
|
|
||||||
/* Check if it's a set or get */
|
/* Check if it's a set or get */
|
||||||
if (SystemArgument1) {
|
if (SystemArgument1) {
|
||||||
|
|
||||||
/* Get the Context */
|
/* Get the Context */
|
||||||
KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context);
|
KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, NULL, Context);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Set the Context */
|
/* Set the Context */
|
||||||
KeContextToTrapFrame(Context, NULL, KeGetCurrentThread()->TrapFrame);
|
KeContextToTrapFrame(Context, NULL, KeGetCurrentThread()->TrapFrame, Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify the Native API that we are done */
|
/* Notify the Native API that we are done */
|
||||||
|
@ -111,7 +114,7 @@ NtGetContextThread(IN HANDLE ThreadHandle,
|
||||||
* I don't know if trying to get your own context makes much
|
* I don't know if trying to get your own context makes much
|
||||||
* sense but we can handle it more efficently.
|
* sense but we can handle it more efficently.
|
||||||
*/
|
*/
|
||||||
KeTrapFrameToContext(Thread->Tcb.TrapFrame, &GetSetContext.Context);
|
KeTrapFrameToContext(Thread->Tcb.TrapFrame, NULL, &GetSetContext.Context);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -120,6 +123,9 @@ NtGetContextThread(IN HANDLE ThreadHandle,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
|
/* Set the previous mode */
|
||||||
|
GetSetContext.Mode = PreviousMode;
|
||||||
|
|
||||||
/* Initialize the APC */
|
/* Initialize the APC */
|
||||||
KeInitializeApc(&GetSetContext.Apc,
|
KeInitializeApc(&GetSetContext.Apc,
|
||||||
&Thread->Tcb,
|
&Thread->Tcb,
|
||||||
|
@ -221,7 +227,7 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
||||||
* I don't know if trying to get your own context makes much
|
* I don't know if trying to get your own context makes much
|
||||||
* sense but we can handle it more efficently.
|
* sense but we can handle it more efficently.
|
||||||
*/
|
*/
|
||||||
KeContextToTrapFrame(&GetSetContext.Context, NULL, Thread->Tcb.TrapFrame);
|
KeContextToTrapFrame(&GetSetContext.Context, NULL, Thread->Tcb.TrapFrame, PreviousMode);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -230,6 +236,9 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
|
/* Set the previous mode */
|
||||||
|
GetSetContext.Mode = PreviousMode;
|
||||||
|
|
||||||
/* Initialize the APC */
|
/* Initialize the APC */
|
||||||
KeInitializeApc(&GetSetContext.Apc,
|
KeInitializeApc(&GetSetContext.Apc,
|
||||||
&Thread->Tcb,
|
&Thread->Tcb,
|
||||||
|
|
Loading…
Reference in a new issue