- Transform TRAP_PROLOG into a GAS macro.

- Remove code in the page fault handler which was corrupting the trap frame.
- Remove some ROS hacks that dealt with the fact the trap frame was getting corrupted, since now it isn't anymore.
- Enable code that checks for Teb->GdiBatchCount during win32k system calls. The bugs that were mentionned in the #if 0 are fixed.

svn path=/trunk/; revision=23714
This commit is contained in:
Alex Ionescu 2006-08-26 06:14:32 +00:00
parent 9f5f1ce315
commit 617e78ebf0
4 changed files with 61 additions and 111 deletions

View file

@ -327,6 +327,7 @@ Author:
#define TEB_EXCEPTION_CODE 0x1A4 #define TEB_EXCEPTION_CODE 0x1A4
#define TEB_ACTIVATION_CONTEXT_STACK_POINTER 0x1A8 #define TEB_ACTIVATION_CONTEXT_STACK_POINTER 0x1A8
#define TEB_DEALLOCATION_STACK 0xE0C #define TEB_DEALLOCATION_STACK 0xE0C
#define TEB_GDI_BATCH_COUNT 0xF70
#define TEB_GUARANTEED_STACK_BYTES 0xF78 #define TEB_GUARANTEED_STACK_BYTES 0xF78
#define TEB_FLS_DATA 0xFB4 #define TEB_FLS_DATA 0xFB4

View file

@ -266,63 +266,64 @@ _KiUnexpectedInterrupt&Number:
// /* Handle trap */ // /* Handle trap */
// <Your Trap Code Here> // <Your Trap Code Here>
// //
#define TRAP_PROLOG(Label) \ .macro TRAP_PROLOG Label
/* Just to be safe, clear out the HIWORD, since it's reserved */ \ /* Just to be safe, clear out the HIWORD, since it's reserved */
mov word ptr [esp+2], 0; \ mov word ptr [esp+2], 0
\
/* Save the non-volatiles */ \ /* Save the non-volatiles */
push ebp; \ push ebp
push ebx; \ push ebx
push esi; \ push esi
push edi; \ push edi
\
/* Save FS and set it to PCR */ \ /* Save FS and set it to PCR */
push fs; \ push fs
mov ebx, KGDT_R0_PCR; \ mov ebx, KGDT_R0_PCR
mov fs, bx; \ mov fs, bx
\
/* Save exception list and bogus previous mode */ \ /* Save exception list and bogus previous mode */
push fs:[KPCR_EXCEPTION_LIST]; \ push fs:[KPCR_EXCEPTION_LIST]
push -1; \ push -1
\
/* Save volatiles and segment registers */ \ /* Save volatiles and segment registers */
push eax; \ push eax
push ecx; \ push ecx
push edx; \ push edx
push ds; \ push ds
push es; \ push es
push gs; \ push gs
\
/* Set the R3 data segment */ \ /* Set the R3 data segment */
mov ax, KGDT_R3_DATA + RPL_MASK; \ mov ax, KGDT_R3_DATA + RPL_MASK
\
/* Skip debug registers and debug stuff */ \ /* Skip debug registers and debug stuff */
sub esp, 0x30; \ sub esp, 0x30
\
/* Load the segment registers */ \ /* Load the segment registers */
mov ds, ax; \ mov ds, ax
mov es, ax; \ mov es, ax
\
/* Set up frame */ \ /* Set up frame */
mov ebp, esp; \ mov ebp, esp
\
/* Check if this was from V86 Mode */ \ /* Check if this was from V86 Mode */
/* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK; */ \ /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK; */
/* jnz V86_Label; */ \ /* jnz V86_Label; */
\
/* Get current thread */ \ /* Get current thread */
mov ecx, [fs:KPCR_CURRENT_THREAD]; \ mov ecx, [fs:KPCR_CURRENT_THREAD]
cld; \ cld
\
/* Flush DR7 */ \ /* Flush DR7 */
and dword ptr [ebp+KTRAP_FRAME_DR7], 0; \ and dword ptr [ebp+KTRAP_FRAME_DR7], 0
\
/* Check if the thread was being debugged */ \ /* Check if the thread was being debugged */
/* test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF; */ \ /* test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF; */
/* jnz Dr_Label; */ \ /* jnz Dr_Label; */
\
/* Set the Trap Frame Debug Header */ \ /* Set the Trap Frame Debug Header */
SET_TF_DEBUG_HEADER SET_TF_DEBUG_HEADER
.endm
// //
// @name INT_PROLOG // @name INT_PROLOG
@ -507,23 +508,6 @@ _KiUnexpectedInterrupt&Number:
/* Set the trap frame debug header */ /* Set the trap frame debug header */
SET_TF_DEBUG_HEADER SET_TF_DEBUG_HEADER
#ifdef DBG // FIXME: Is this for GDB? Can it be moved in the stub?
/*
* We want to know the address from where the syscall stub was called.
* If PrevMode is KernelMode, that address is stored in our own (kernel)
* stack, at location KTRAP_FRAME_ESP.
* If we're coming from UserMode, we load the usermode stack pointer
* and go back two frames (first frame is the syscall stub, second call
* is the caller of the stub).
*/
mov edi, [ebp+KTRAP_FRAME_ESP]
test byte ptr [esi+KTHREAD_PREVIOUS_MODE], 0x01
jz 0f
mov edi, [edi+4]
0:
mov [ebp+KTRAP_FRAME_DEBUGEIP], edi
#endif
/* Enable interrupts */ /* Enable interrupts */
sti sti
.endm .endm
@ -754,20 +738,9 @@ FastExit:
#if DBG #if DBG
0: 0:
#if 0
/* Print a message */
mov esi, [esp+KTRAP_FRAME_DEBUGARGMARK]
mov edi, [esp+KTRAP_FRAME_DEBUGARGMARK-4]
push edi
push esi
push offset Broken
call _DbgPrint
add esp, 12
#endif
jmp 2b // ros hack
/* Fix up the mask */ /* Fix up the mask */
add dword ptr [esp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00 add dword ptr [esp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
6: 6:
int 3 int 3
jmp 5b jmp 5b

View file

@ -187,23 +187,6 @@ _KiFastCallEntry:
/* Set the trap frame debug header */ /* Set the trap frame debug header */
SET_TF_DEBUG_HEADER SET_TF_DEBUG_HEADER
#ifdef DBG // FIXME: Is this for GDB? Can it be moved in the stub?
/*
* We want to know the address from where the syscall stub was called.
* If PrevMode is KernelMode, that address is stored in our own (kernel)
* stack, at location KTRAP_FRAME_ESP.
* If we're coming from UserMode, we load the usermode stack pointer
* and go back two frames (first frame is the syscall stub, second call
* is the caller of the stub).
*/
mov edi, [ebp+KTRAP_FRAME_ESP]
test byte ptr [esi+KTHREAD_PREVIOUS_MODE], 0x01
jz PrevWasKernelMode
mov edi, [edi+4]
PrevWasKernelMode:
mov [ebp+KTRAP_FRAME_DEBUGEIP], edi
#endif
/* Enable interrupts */ /* Enable interrupts */
sti sti
@ -229,9 +212,6 @@ SharedCode:
/* Invalid ID, try to load Win32K Table */ /* Invalid ID, try to load Win32K Table */
jnb KiBBTUnexpectedRange jnb KiBBTUnexpectedRange
#if 0 // <== Disabled for two reasons: We don't save TEB in 0x18, but KPCR.
// <== We don't have a KeGdiFlushUserBatch callback yet (needs to be
// sent through the PsInitializeWin32Callouts structure)
/* Check if this was Win32K */ /* Check if this was Win32K */
cmp ecx, SERVICE_TABLE_TEST cmp ecx, SERVICE_TABLE_TEST
jnz NotWin32K jnz NotWin32K
@ -242,15 +222,14 @@ SharedCode:
/* Check if we should flush the User Batch */ /* Check if we should flush the User Batch */
xor ebx, ebx xor ebx, ebx
or ebx, [ecx+TEB_GDI_BATCH_COUNT] or ebx, [ecx+TEB_GDI_BATCH_COUNT]
jz NoWin32K jz NotWin32K
/* Flush it */ /* Flush it */
push edx push edx
push eax push eax
call [_KeGdiFlushUserBatch] //call [_KeGdiFlushUserBatch]
pop eax pop eax
pop edx pop edx
#endif
NotWin32K: NotWin32K:
/* Increase total syscall count */ /* Increase total syscall count */

View file

@ -36,9 +36,6 @@ 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. */
Tf->DbgArgMark = 14;
/* get the faulting address */ /* get the faulting address */
cr2 = Ke386GetCr2(); cr2 = Ke386GetCr2();
Tf->DbgArgPointer = cr2; Tf->DbgArgPointer = cr2;