mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
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:
parent
18ac7f07b6
commit
1928c25d73
4 changed files with 164 additions and 100 deletions
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue