- 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
This commit is contained in:
Stefan Ginsberg 2015-09-05 15:20:27 +00:00
parent 57bd950d25
commit 4365775be6
2 changed files with 25 additions and 52 deletions

View file

@ -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
//

View file

@ -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