Add KDBG debugging hack from old code and convert it to fit new one. Not enabled yet because it underflows the stack after a while (researching why). Also complete KeContextToTrapFrame and have Ke386InitThreadWithContext call it to handle creating the Initial Trap Frame

svn path=/trunk/; revision=14754
This commit is contained in:
Alex Ionescu 2005-04-23 04:12:26 +00:00
parent 18ac7f07b6
commit 1928c25d73
4 changed files with 164 additions and 100 deletions

View file

@ -310,7 +310,7 @@ VOID inline FASTCALL KiSatisifyMultipleObjectWaits(PKWAIT_BLOCK WaitBlock);
VOID FASTCALL KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment);
PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
VOID KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame);
BOOLEAN STDCALL KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame);
VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode,
PVOID Reserved,
PKTRAP_FRAME TrapFrame);

View file

@ -115,9 +115,13 @@ BadThread:
*--*/
.globl @KiSwapContextInternal@0
@KiSwapContextInternal@0:
#ifdef KDBG
//jmp SaveTrapFrameForKDB
SaveTrapFrameForKDB_Return:
#endif
/* Get the PCR. It's faster to use ebx+offset then fs:offset */
mov ebx, [fs:0x1C]
mov ebx, [fs:KPCR_SELF]
/* Set the Thread to running */
mov byte ptr [esi+KTHREAD_STATE], Running
@ -224,10 +228,9 @@ SameProcess:
/* Restore exception list */
pop [ebx+KPCR_EXCEPTION_LIST]
call @KeReleaseDispatcherDatabaseLockFromDpcLevel@0
/* Return */
call @KeReleaseDispatcherDatabaseLockFromDpcLevel@0
ret
/*++
@ -253,7 +256,6 @@ SameProcess:
*--*/
.globl @KiSwapContext@4
@KiSwapContext@4:
/* Note, we CANNOT touch ebp */
/* Save 4 registers */
@ -285,6 +287,92 @@ SameProcess:
/* Clean stack */
add esp, 4 * 4
ret
#ifdef KDBG
SaveTrapFrameForKDB:
/* Set up a trap frame */
/* Fake Interrupt Stack */
push esp // 0x74
pushf // 0x70
push cs // 0x6C
push [esp+12] /* EIP */ // 0x68
mov [esp+16], ss // 0x78
/* Trap Frame */
push 0 /* Error Code */ // 0x64
push ebp // 0x60
push ebx
push esi
push edi
push fs
push -1 /* Exception List */ // 0x4C
push 0 /* Previous Mode */ // 0x48
push eax
push ecx
push edx
push ds
push es
push gs // 0x30
sub esp, 0x28 /* Debug Registers */ // 0x8
push [esp+60] /* Debug EIP */ // 0x4
push ebp /* Debug EBP */ // 0x0
/* Set Stack */
mov ebp, esp
/* Push old Trap Frame */
push [edi+KTHREAD_TRAP_FRAME]
/* Save new one */
mov [edi+KTHREAD_TRAP_FRAME], ebp
/* Return EIP */
push offset RestoreTrapFrameForKDB
/* Restore EBP */
mov ebp, [ebp+KTRAP_FRAME_EBP]
/* Jump to normal code */
jmp SaveTrapFrameForKDB_Return
RestoreTrapFrameForKDB:
/* Restore the old trapframe */
pop [edi+KTHREAD_TRAP_FRAME]
/* Pop unused portions of the trap frame */
add esp, 0x30
/* Restore registers from Trap frame */
pop gs
pop es
pop ds
pop edx
pop ecx
pop eax
add esp, 8
pop fs
pop edi
pop esi
pop ebx
/* Remove SS:ESP from the stack */
mov ebp, [esp+16]
mov [esp+24], ebp
mov ebp, [esp+12]
mov [esp+20], ebp
mov ebp, [esp+8]
mov [esp+16], ebp
/* Restore Fake INT Stack */
pop ebp
add esp, 12
/* Return to the caller. */
iret
#endif /* KDBG */

View file

@ -589,50 +589,55 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
}
}
VOID
BOOLEAN
STDCALL
KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
PKTRAP_FRAME TrapFrame)
{
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
{
TrapFrame->Esp = Context->Esp;
TrapFrame->Ss = Context->SegSs;
TrapFrame->Cs = Context->SegCs;
TrapFrame->Eip = Context->Eip;
TrapFrame->Eflags = Context->EFlags;
TrapFrame->Ebp = Context->Ebp;
}
if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
{
TrapFrame->Eax = Context->Eax;
TrapFrame->Ebx = Context->Ebx;
TrapFrame->Ecx = Context->Ecx;
TrapFrame->Edx = Context->Edx;
TrapFrame->Esi = Context->Esi;
TrapFrame->Edi = Context->Edi;
}
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
{
TrapFrame->Ds = Context->SegDs;
TrapFrame->Es = Context->SegEs;
TrapFrame->Fs = Context->SegFs;
TrapFrame->Gs = Context->SegGs;
}
if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
{
/*
* Not handled
*
* This should be handled separately I think.
* - blight
*/
}
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
/*
* Not handled
*/
}
/* Start with the basic Registers */
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
{
TrapFrame->Esp = Context->Esp;
TrapFrame->Ss = Context->SegSs;
TrapFrame->Cs = Context->SegCs;
TrapFrame->Eip = Context->Eip;
TrapFrame->Eflags = Context->EFlags;
TrapFrame->Ebp = Context->Ebp;
}
/* Process the Integer Registers */
if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
{
TrapFrame->Eax = Context->Eax;
TrapFrame->Ebx = Context->Ebx;
TrapFrame->Ecx = Context->Ecx;
TrapFrame->Edx = Context->Edx;
TrapFrame->Esi = Context->Esi;
TrapFrame->Edi = Context->Edi;
}
/* Process the Context Segments */
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
{
TrapFrame->Ds = Context->SegDs;
TrapFrame->Es = Context->SegEs;
TrapFrame->Fs = Context->SegFs;
TrapFrame->Gs = Context->SegGs;
}
/* Handle the Debug Registers */
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
TrapFrame->Dr0 = Context->Dr0;
TrapFrame->Dr1 = Context->Dr1;
TrapFrame->Dr2 = Context->Dr2;
TrapFrame->Dr3 = Context->Dr3;
TrapFrame->Dr6 = Context->Dr6;
TrapFrame->Dr7 = Context->Dr7;
}
/* Handle FPU and Extended Registers */
return KiContextToFxSaveArea((PFX_SAVE_AREA)(TrapFrame + 1), Context);
}
VOID

View file

@ -74,73 +74,48 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
/* Check if this is a With-Context Thread */
DPRINT("Ke386InitThreadContext\n");
if (Context) {
if (Context)
{
/* Set up the Initial Frame */
PKUINIT_FRAME InitFrame;
InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KUINIT_FRAME));
DPRINT("Setting up a user-mode thread with the Frame at: %x\n", InitFrame);
/* Setup the Fx Area */
FxSaveArea = &InitFrame->FxSaveArea;
DPRINT("Fx Save Area: %x\n", FxSaveArea);
/* Setup the Initial Fx State */
if (KiContextToFxSaveArea(FxSaveArea, Context)) {
Thread->NpxState = NPX_STATE_VALID;
} else {
Thread->NpxState = NPX_STATE_INVALID;
}
/* Setup the Trap Frame */
TrapFrame = &InitFrame->TrapFrame;
DPRINT("TrapFrame: %x\n", TrapFrame);
/* Set up a trap frame from the context. */
TrapFrame->DebugEbp = (PVOID)Context->Ebp;
TrapFrame->DebugEip = (PVOID)Context->Eip;
TrapFrame->DebugArgMark = 0;
TrapFrame->DebugPointer = 0;
TrapFrame->TempCs = 0;
TrapFrame->TempEip = 0;
TrapFrame->Gs = (USHORT)Context->SegGs;
TrapFrame->Es = (USHORT)Context->SegEs;
TrapFrame->Ds = (USHORT)Context->SegDs;
TrapFrame->Edx = Context->Edx;
TrapFrame->Ecx = Context->Ecx;
TrapFrame->Eax = Context->Eax;
TrapFrame->PreviousMode = UserMode;
TrapFrame->ExceptionList = (PVOID)0xFFFFFFFF;
TrapFrame->Fs = TEB_SELECTOR;
TrapFrame->Edi = Context->Edi;
TrapFrame->Esi = Context->Esi;
TrapFrame->Ebx = Context->Ebx;
TrapFrame->Ebp = Context->Ebp;
TrapFrame->ErrorCode = 0;
TrapFrame->Cs = Context->SegCs;
TrapFrame->Eip = Context->Eip;
if (KeContextToTrapFrame(Context, TrapFrame))
{
Thread->NpxState = NPX_STATE_VALID;
}
else
{
Thread->NpxState = NPX_STATE_INVALID;
}
/* Enable Interrupts and disable some unsupported flags right now */
TrapFrame->Eflags = Context->EFlags | X86_EFLAGS_IF;
TrapFrame->Eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_NT | X86_EFLAGS_IOPL);
TrapFrame->Esp = Context->Esp;
TrapFrame->Ss = (USHORT)Context->SegSs;
/* Set the previous mode as user */
TrapFrame->PreviousMode = UserMode;
/* Terminate the Exception Handler List */
TrapFrame->ExceptionList = (PVOID)0xFFFFFFFF;
/* Setup the Stack for KiThreadStartup and Context Switching */
StartFrame = &InitFrame->StartFrame;
CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
DPRINT("StartFrame: %x\n", StartFrame);
DPRINT("CtxSwitchFrame: %x\n", CtxSwitchFrame);
/* Tell the thread it will run in User Mode */
Thread->PreviousMode = UserMode;
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = TRUE;
} else {
}
else
{
/* No context Thread, meaning System Thread */
/* Set up the Initial Frame */
@ -150,15 +125,12 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
/* Setup the Fx Area */
FxSaveArea = &InitFrame->FxSaveArea;
DPRINT("Fx Save Area: %x\n", FxSaveArea);
RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
Thread->NpxState = NPX_STATE_INVALID;
/* Setup the Stack for KiThreadStartup and Context Switching */
StartFrame = &InitFrame->StartFrame;
CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
DPRINT("StartFrame: %x\n", StartFrame);
DPRINT("CtxSwitchFrame: %x\n", CtxSwitchFrame);
/* Tell the thread it will run in Kernel Mode */
Thread->PreviousMode = KernelMode;
@ -168,7 +140,6 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
}
/* Now setup the remaining data for KiThreadStartup */
DPRINT("Settingup the Start and Context Frames\n");
StartFrame->StartContext = StartContext;
StartFrame->StartRoutine = StartRoutine;
StartFrame->SystemRoutine = SystemRoutine;
@ -179,8 +150,8 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
/* Save back the new value of the kernel stack. */
Thread->KernelStack = (PVOID)CtxSwitchFrame;
DPRINT("Final Kernel Stack: %x \n", CtxSwitchFrame);
Thread->KernelStack = (PVOID)CtxSwitchFrame;
return;
}