mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 05:35:06 +00:00
- 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:
parent
57bd950d25
commit
4365775be6
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue