From 4365775be655f80bedaef9db5c687238efa9165e Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Sat, 5 Sep 2015 15:20:27 +0000 Subject: [PATCH] - Don't have two different implementation of KiConvertToGuiThread, first as inlined assembly gcc and second as a function call (for msvc). Always use the function call to be consistent with both compilers. svn path=/trunk/; revision=69032 --- reactos/ntoskrnl/include/internal/i386/ke.h | 55 +++------------------ reactos/ntoskrnl/ke/i386/trap.s | 22 +++++++-- 2 files changed, 25 insertions(+), 52 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 7c9cce3ffcc..5af888b7e07 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -526,6 +526,12 @@ KiDispatchExceptionFromTrapFrame( IN PKTRAP_FRAME TrapFrame ); +NTSTATUS +NTAPI +KiConvertToGuiThread( + VOID +); + // // Global x86 only Kernel data // @@ -776,55 +782,6 @@ KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame) } } -// -// Converts a base thread to a GUI thread -// -#ifdef __GNUC__ -FORCEINLINE -NTSTATUS -KiConvertToGuiThread(VOID) -{ - NTSTATUS NTAPI PsConvertToGuiThread(VOID); - NTSTATUS Result; - PVOID StackFrame; - - /* - * Converting to a GUI thread safely updates ESP in-place as well as the - * current Thread->TrapFrame and EBP when KeSwitchKernelStack is called. - * - * However, PsConvertToGuiThread "helpfully" restores EBP to the original - * caller's value, since it is considered a nonvolatile register. As such, - * as soon as we're back after the conversion and we try to store the result - * which will probably be in some stack variable (EBP-based), we'll crash as - * we are touching the de-allocated non-expanded stack. - * - * Thus we need a way to update our EBP before EBP is touched, and the only - * way to guarantee this is to do the call itself in assembly, use the EAX - * register to store the result, fixup EBP, and then let the C code continue - * on its merry way. - * - */ - __asm__ __volatile__ - ( - "movl %%ebp, %1\n\t" - "subl %%esp, %1\n\t" - "call _PsConvertToGuiThread@0\n\t" - "addl %%esp, %1\n\t" - "movl %1, %%ebp" - : "=a"(Result), "=r"(StackFrame) - : "p"(PsConvertToGuiThread) - : "%esp", "%ecx", "%edx", "memory" - ); - return Result; -} -#elif defined(_MSC_VER) -NTSTATUS -NTAPI -KiConvertToGuiThread(VOID); -#else -#error Unknown Compiler -#endif - // // Switches from boot loader to initial kernel stack // diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index d8533be0f6f..538ab6e6ad2 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -177,12 +177,29 @@ KiTrapExitStub KiTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_SE KiTrapExitStub KiTrapReturnNoSegments, (KI_RESTORE_VOLATILES OR KI_EXIT_IRET) KiTrapExitStub KiTrapReturnNoSegmentsRet8,(KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EXIT_RET8) -#ifdef _MSC_VER EXTERN _PsConvertToGuiThread@0:PROC PUBLIC _KiConvertToGuiThread@0 _KiConvertToGuiThread@0: - /* Safe ebx */ + + /* + * Converting to a GUI thread safely updates ESP in-place as well as the + * current Thread->TrapFrame and EBP when KeSwitchKernelStack is called. + * + * However, PsConvertToGuiThread "helpfully" restores EBP to the original + * caller's value, since it is considered a nonvolatile register. As such, + * as soon as we're back after the conversion and we try to store the result + * which will probably be in some stack variable (EBP-based), we'll crash as + * we are touching the de-allocated non-expanded stack. + * + * Thus we need a way to update our EBP before EBP is touched, and the only + * way to guarantee this is to do the call itself in assembly, use the EAX + * register to store the result, fixup EBP, and then let the C code continue + * on its merry way. + * + */ + + /* Save ebx */ push ebx /* Calculate the stack frame offset in ebx */ @@ -201,6 +218,5 @@ _KiConvertToGuiThread@0: /* return to the caller */ ret -#endif END