diff --git a/reactos/include/asm/ks386.template.h b/reactos/include/asm/ks386.template.h index 77085d1bcc4..77ac3f8c306 100644 --- a/reactos/include/asm/ks386.template.h +++ b/reactos/include/asm/ks386.template.h @@ -347,7 +347,7 @@ OFFSET(CONTEXT_SEGSS, CONTEXT, SegSs), //OFFSET(CONTEXT_FLOAT_SAVE_STATUS_WORD CONTEXT_FLOAT_SAVE + FP_STATUS_WORD //OFFSET(CONTEXT_FLOAT_SAVE_TAG_WORD CONTEXT_FLOAT_SAVE + FP_TAG_WORD //OFFSET(CONTEXT_FRAME_LENGTH 0x2D0 -SIZE(CONTEXT_FRAME_LENGTH, CONTEXT), +SIZE(CONTEXT_FRAME_LENGTH, CONTEXT), HEADER("FIBER"), OFFSET(FIBER_PARAMETER, FIBER, Parameter), @@ -387,7 +387,7 @@ OFFSET(EXCEPTION_RECORD_NUMBER_PARAMETERS, EXCEPTION_RECORD, NumberParameters), OFFSET(EXCEPTION_RECORD_EXCEPTION_ADDRESS, EXCEPTION_RECORD, ExceptionAddress), SIZE(SIZEOF_EXCEPTION_RECORD, EXCEPTION_RECORD), CONSTANT(EXCEPTION_RECORD_LENGTH), - + //#define EXCEPTION_RECORD_LENGTH 0x50 HEADER("KTHREAD"), @@ -463,6 +463,5 @@ CONSTANT(EXCEPTION_EXECUTE_HANDLER), CONSTANT(STATUS_CALLBACK_POP_STACK), CONSTANT(CONTEXT_ALIGNED_SIZE), CONSTANT(PROCESSOR_FEATURE_FXSR), - - +CONSTANT(KUSER_SHARED_SYSCALL_RET), diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index 2ab3bdfd6ff..4a6b009d5fc 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -83,7 +83,7 @@ MACRO(KiEnterTrap, Flags) if (Flags AND KI_FAST_SYSTEM_CALL) /* SYSENTER requires us to build a complete ring transition trap frame */ - FrameSize = KTRAP_FRAME_V86_ES + FrameSize = KTRAP_FRAME_EIP /* Fixup fs. cx is free to clobber */ mov cx, KGDT_R0_PCR @@ -95,6 +95,13 @@ MACRO(KiEnterTrap, Flags) /* Get a stack pointer */ mov esp, [ecx + KTSS_ESP0] + /* Set up a fake hardware trap frame */ + push KGDT_R3_DATA or RPL_MASK + push edx + pushfd + push KGDT_R3_CODE or RPL_MASK + push dword ptr ds:[KUSER_SHARED_SYSCALL_RET] + elseif (Flags AND KI_SOFTWARE_TRAP) /* Software traps need a complete non-ring transition trap frame */ @@ -183,7 +190,19 @@ set_sane_segs: mov es, ax /* Fast system calls have fs already fixed */ - if (NOT (Flags AND KI_FAST_SYSTEM_CALL)) + if (Flags AND KI_FAST_SYSTEM_CALL) + + /* Enable interrupts and set a sane FS value */ + or dword ptr [esp + KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK + mov dword ptr [esp + KTRAP_FRAME_FS], KGDT_R3_TEB or RPL_MASK + + /* Set sane active EFLAGS */ + push 2 + popfd + + /* Point edx to the usermode parameters */ + add edx, 8 + else /* Otherwise fix fs now */ mov ax, KGDT_R0_PCR mov fs, ax diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 272886d4891..733451d7db3 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -142,14 +142,20 @@ PUBLIC _KiSystemService KiCallHandler @KiSystemServiceHandler@8 .ENDP -EXTERN @KiFastCallEntryHandler@8:PROC PUBLIC _KiFastCallEntry .PROC _KiFastCallEntry FPO 0, 0, 0, 0, 1, FRAME_TRAP KiEnterTrap (KI_FAST_SYSTEM_CALL OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS) - KiCallHandler @KiFastCallEntryHandler@8 + KiCallHandler @KiSystemServiceHandler@8 .ENDP +PUBLIC _KiFastCallEntryWithSingleStep +.PROC _KiFastCallEntryWithSingleStep + FPO 0, 0, 0, 0, 1, FRAME_TRAP + KiEnterTrap (KI_FAST_SYSTEM_CALL OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS) + or dword ptr [ecx + KTRAP_FRAME_EFLAGS], EFLAGS_TF + KiCallHandler @KiSystemServiceHandler@8 +.ENDP PUBLIC _KiEndUnexpectedRange@0 _KiEndUnexpectedRange@0: diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index d98109a21ac..568c4892d42 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -12,6 +12,9 @@ #define NDEBUG #include +VOID KiFastCallEntry(VOID); +VOID KiFastCallEntryWithSingleStep(VOID); + /* GLOBALS ********************************************************************/ UCHAR KiTrapPrefixTable[] = @@ -417,13 +420,26 @@ KiTrap01Handler(IN PKTRAP_FRAME TrapFrame) { /* Save trap frame */ KiEnterTrap(TrapFrame); - + /* Check for VDM trap */ ASSERT((KiVdmTrap(TrapFrame)) == FALSE); + /* Check if this was a single step after sysenter */ + if (TrapFrame->Eip == (ULONG)KiFastCallEntry) + { + /* Disable single stepping */ + TrapFrame->EFlags &= ~EFLAGS_TF; + + /* Re-enter at the alternative sysenter entry point */ + TrapFrame->Eip = (ULONG)KiFastCallEntryWithSingleStep; + + /* End this trap */ + KiEoiHelper(TrapFrame); + } + /* Enable interrupts if the trap came from user-mode */ if (KiUserTrap(TrapFrame)) _enable(); - + /* Mask out trap flag and dispatch the exception */ TrapFrame->EFlags &= ~EFLAGS_TF; KiDispatchException0Args(STATUS_SINGLE_STEP, @@ -1521,11 +1537,11 @@ KiDbgPostServiceHook(ULONG SystemCallNumber, ULONG_PTR Result) return Result; } -FORCEINLINE DECLSPEC_NORETURN VOID -KiSystemCall(IN PKTRAP_FRAME TrapFrame, - IN PVOID Arguments) +FASTCALL +KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame, + IN PVOID Arguments) { PKTHREAD Thread; PKSERVICE_TABLE_DESCRIPTOR DescriptorTable; @@ -1658,38 +1674,6 @@ ExitCall: KiServiceExit(TrapFrame, Result); } -DECLSPEC_NORETURN -VOID -FASTCALL -KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame, - IN PVOID Arguments) -{ - /* Call the shared handler (inline) */ - KiSystemCall(TrapFrame, Arguments); -} - -DECLSPEC_NORETURN -VOID -FASTCALL -KiFastCallEntryHandler(IN PKTRAP_FRAME TrapFrame, - IN PVOID Arguments) -{ - /* Set up a fake INT Stack and enable interrupts */ - TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK; - TrapFrame->HardwareEsp = (ULONG_PTR)Arguments; - TrapFrame->EFlags = __readeflags() | EFLAGS_INTERRUPT_MASK; - TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK; - TrapFrame->Eip = SharedUserData->SystemCallReturn; - TrapFrame->SegFs = KGDT_R3_TEB | RPL_MASK; - __writeeflags(0x2); - - /* Arguments are actually 2 frames down (because of the double indirection) */ - Arguments = (PVOID)(TrapFrame->HardwareEsp + 8); - - /* Call the shared handler (inline) */ - KiSystemCall(TrapFrame, Arguments); -} - /* * @implemented */