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 Modified: trunk/reactos/ntoskrnl/include/internal/ke.h Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c Modified: trunk/reactos/ntoskrnl/ke/i386/thread.c _____
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h --- trunk/reactos/ntoskrnl/include/internal/ke.h 2005-04-23 04:11:56 UTC (rev 14753) +++ trunk/reactos/ntoskrnl/include/internal/ke.h 2005-04-23 04:12:26 UTC (rev 14754) @@ -310,7 +310,7 @@
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); _____
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S --- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2005-04-23 04:11:56 UTC (rev 14753) +++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2005-04-23 04:12:26 UTC (rev 14754) @@ -115,9 +115,13 @@
*--*/ .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 @@
/* Restore exception list */ pop [ebx+KPCR_EXCEPTION_LIST] - - call @KeReleaseDispatcherDatabaseLockFromDpcLevel@0
/* Return */ + call @KeReleaseDispatcherDatabaseLockFromDpcLevel@0 ret
/*++ @@ -253,7 +256,6 @@ *--*/ .globl @KiSwapContext@4 @KiSwapContext@4: - /* Note, we CANNOT touch ebp */
/* Save 4 registers */ @@ -285,6 +287,92 @@
/* Clean stack */ add esp, 4 * 4 + ret
- 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 */ + + _____
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c --- trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-04-23 04:11:56 UTC (rev 14753) +++ trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-04-23 04:12:26 UTC (rev 14754) @@ -589,50 +589,55 @@
} }
-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 _____
Modified: trunk/reactos/ntoskrnl/ke/i386/thread.c --- trunk/reactos/ntoskrnl/ke/i386/thread.c 2005-04-23 04:11:56 UTC (rev 14753) +++ trunk/reactos/ntoskrnl/ke/i386/thread.c 2005-04-23 04:12:26 UTC (rev 14754) @@ -74,73 +74,48 @@
/* 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 @@
/* 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 @@ }
/* 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 @@ 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; }