mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:23:05 +00:00
cleanup/reformat syscall code, save return value as soon as possible so that eax is freed up, which also simplifies the implementation of KiAfterSystemCallHook(), also removes a couple redundant instructions.
svn path=/trunk/; revision=9955
This commit is contained in:
parent
aa33e15965
commit
209e1d7692
2 changed files with 222 additions and 203 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: syscall.S,v 1.14 2004/04/07 15:35:14 ekohl Exp $
|
/* $Id: syscall.S,v 1.15 2004/07/01 01:52:37 royce Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/hal/x86/syscall.s
|
* FILE: ntoskrnl/hal/x86/syscall.s
|
||||||
* PURPOSE: 2E trap handler
|
* PURPOSE: 2E trap handler
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
#include <ddk/status.h>
|
#include <ddk/status.h>
|
||||||
#include <internal/i386/segment.h>
|
#include <internal/i386/segment.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
#include <internal/i386/ke.h>
|
||||||
#include <roscfg.h>
|
#include <roscfg.h>
|
||||||
|
|
||||||
#define KernelMode (0)
|
#define KernelMode (0)
|
||||||
|
@ -41,250 +42,266 @@
|
||||||
.globl _interrupt_handler2e
|
.globl _interrupt_handler2e
|
||||||
_interrupt_handler2e:
|
_interrupt_handler2e:
|
||||||
|
|
||||||
/* Construct a trap frame on the stack */
|
/* Construct a trap frame on the stack */
|
||||||
|
|
||||||
/* Error code */
|
/* Error code */
|
||||||
pushl $0
|
pushl $0
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
pushl %fs
|
pushl %fs
|
||||||
/* Load PCR selector into fs */
|
/* Load PCR selector into fs */
|
||||||
movl $PCR_SELECTOR, %ebx
|
movl $PCR_SELECTOR, %ebx
|
||||||
movl %ebx, %fs
|
movl %ebx, %fs
|
||||||
|
|
||||||
/* Save the old exception list */
|
/* Save the old exception list */
|
||||||
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
/* Set the exception handler chain terminator */
|
/* Set the exception handler chain terminator */
|
||||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||||
/* Get a pointer to the current thread */
|
/* Get a pointer to the current thread */
|
||||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||||
/* Save the old previous mode */
|
/* Save the old previous mode */
|
||||||
movl $0, %ebx
|
movl $0, %ebx
|
||||||
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
|
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
/* Set the new previous mode based on the saved CS selector */
|
/* Set the new previous mode based on the saved CS selector */
|
||||||
movl 0x24(%esp), %ebx
|
movl 0x24(%esp), %ebx
|
||||||
andl $0x0000FFFF, %ebx
|
andl $0x0000FFFF, %ebx
|
||||||
cmpl $KERNEL_CS, %ebx
|
cmpl $KERNEL_CS, %ebx
|
||||||
jne L1
|
jne L1
|
||||||
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||||
jmp L3
|
jmp L3
|
||||||
L1:
|
L1:
|
||||||
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||||
L3:
|
L3:
|
||||||
|
|
||||||
/* Save other registers */
|
/* Save other registers */
|
||||||
pushl %eax
|
pushl %eax
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
pushl %edx
|
pushl %edx
|
||||||
pushl %ds
|
pushl %ds
|
||||||
pushl %es
|
pushl %es
|
||||||
pushl %gs
|
pushl %gs
|
||||||
pushl $0 /* DR7 */
|
pushl $0 /* DR7 */
|
||||||
pushl $0 /* DR6 */
|
pushl $0 /* DR6 */
|
||||||
pushl $0 /* DR3 */
|
pushl $0 /* DR3 */
|
||||||
pushl $0 /* DR2 */
|
pushl $0 /* DR2 */
|
||||||
pushl $0 /* DR1 */
|
pushl $0 /* DR1 */
|
||||||
pushl $0 /* DR0 */
|
pushl $0 /* DR0 */
|
||||||
pushl $0 /* XXX: TempESP */
|
pushl $0 /* XXX: TempESP */
|
||||||
pushl $0 /* XXX: TempCS */
|
pushl $0 /* XXX: TempCS */
|
||||||
pushl $0 /* XXX: DebugPointer */
|
pushl $0 /* XXX: DebugPointer */
|
||||||
pushl $0 /* XXX: DebugArgMark */
|
pushl $0 /* XXX: DebugArgMark */
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* Trick gdb 6 into backtracing over the system call */
|
/* Trick gdb 6 into backtracing over the system call */
|
||||||
movl 4(%ebp), %ebx
|
movl 4(%ebp), %ebx
|
||||||
pushl %ebx /* DebugEIP */
|
pushl %ebx /* DebugEIP */
|
||||||
movl (%ebp), %ebx
|
movl (%ebp), %ebx
|
||||||
pushl %ebx /* DebugEBP */
|
pushl %ebx /* DebugEBP */
|
||||||
#else
|
#else
|
||||||
movl 0x60(%esp), %ebx
|
movl 0x60(%esp), %ebx
|
||||||
pushl %ebx /* DebugEIP */
|
pushl %ebx /* DebugEIP */
|
||||||
pushl %ebp /* DebugEBP */
|
pushl %ebp /* DebugEBP */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load the segment registers */
|
/* Load the segment registers */
|
||||||
movl $KERNEL_DS, %ebx
|
movl $KERNEL_DS, %ebx
|
||||||
movl %ebx, %ds
|
movl %ebx, %ds
|
||||||
movl %ebx, %es
|
movl %ebx, %es
|
||||||
movl %ebx, %gs
|
movl %ebx, %gs
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save the old trap frame pointer over where we would save the EDX
|
* Save the old trap frame pointer over where we would save the EDX
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
||||||
movl %ebx, 0x3C(%esp)
|
movl %ebx, KTRAP_FRAME_EDX(%esp)
|
||||||
|
|
||||||
/* Save a pointer to the trap frame in the TCB */
|
|
||||||
movl %esp, KTHREAD_TRAP_FRAME(%esi)
|
|
||||||
|
|
||||||
/* Set ES to kernel segment */
|
|
||||||
movw $KERNEL_DS,%bx
|
|
||||||
movw %bx,%es
|
|
||||||
|
|
||||||
/* Allocate new Kernel stack frame */
|
/* Allocate new Kernel stack frame */
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
|
|
||||||
/* Users's current stack frame pointer is source */
|
/* Save a pointer to the trap frame in the TCB */
|
||||||
movl %edx,%esi
|
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
|
||||||
|
|
||||||
/* Determine system service table to use */
|
/* Set ES to kernel segment */
|
||||||
cmpl $0x0fff, %eax
|
movw $KERNEL_DS,%bx
|
||||||
ja new_useShadowTable
|
movw %bx,%es
|
||||||
|
|
||||||
/* Check to see if EAX is valid/inrange */
|
/* Users's current stack frame pointer is source */
|
||||||
cmpl %es:_KeServiceDescriptorTable + 8, %eax
|
movl %edx,%esi
|
||||||
jbe new_serviceInRange
|
|
||||||
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
/* Determine system service table to use */
|
||||||
jmp KeReturnFromSystemCall
|
cmpl $0x0fff, %eax
|
||||||
|
ja new_useShadowTable
|
||||||
|
|
||||||
|
/* Check to see if EAX is valid/inrange */
|
||||||
|
cmpl %es:_KeServiceDescriptorTable + 8, %eax
|
||||||
|
jbe new_serviceInRange
|
||||||
|
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
||||||
|
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||||
|
jmp KeReturnFromSystemCall
|
||||||
|
|
||||||
new_serviceInRange:
|
new_serviceInRange:
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* GDB thinks the function starts here and
|
/* GDB thinks the function starts here and
|
||||||
wants a standard prolog, so let's give it */
|
wants a standard prolog, so let's give it */
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate room for argument list from kernel stack */
|
/* Allocate room for argument list from kernel stack */
|
||||||
movl %es:_KeServiceDescriptorTable + 12, %ecx
|
movl %es:_KeServiceDescriptorTable + 12, %ecx
|
||||||
movb %es:(%ecx, %eax), %cl
|
movb %es:(%ecx, %eax), %cl
|
||||||
movzx %cl, %ecx
|
movzx %cl, %ecx
|
||||||
subl %ecx, %esp
|
subl %ecx, %esp
|
||||||
|
|
||||||
/* Copy the arguments from the user stack to the kernel stack */
|
/* Copy the arguments from the user stack to the kernel stack */
|
||||||
movl %esp,%edi
|
movl %esp,%edi
|
||||||
cld
|
cld
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
/* DS is now also kernel segment */
|
/* DS is now also kernel segment */
|
||||||
movw %bx, %ds
|
movw %bx, %ds
|
||||||
|
|
||||||
/* Call system call hook */
|
|
||||||
pushl %eax
|
|
||||||
call _KiSystemCallHook
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
/* Make the system service call */
|
/* Call system call hook */
|
||||||
movl %es:_KeServiceDescriptorTable, %ecx
|
pushl %eax
|
||||||
movl %es:(%ecx, %eax, 4), %eax
|
call _KiSystemCallHook
|
||||||
call *%eax
|
popl %eax
|
||||||
|
|
||||||
|
/* Make the system service call */
|
||||||
|
movl %es:_KeServiceDescriptorTable, %ecx
|
||||||
|
movl %es:(%ecx, %eax, 4), %eax
|
||||||
|
call *%eax
|
||||||
|
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||||
|
|
||||||
#if CHECKED
|
#if CHECKED
|
||||||
/* Bump Service Counter */
|
/* Bump Service Counter */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deallocate the kernel stack frame */
|
jmp KeDeallocateStackAndReturnFromSystemCallWithHook
|
||||||
movl %ebp,%esp
|
|
||||||
|
|
||||||
/* Call the post system call hook and deliver any pending APCs */
|
|
||||||
pushl %ebp
|
|
||||||
pushl %eax
|
|
||||||
call _KiAfterSystemCallHook
|
|
||||||
addl $8,%esp
|
|
||||||
|
|
||||||
jmp KeReturnFromSystemCall
|
|
||||||
|
|
||||||
new_useShadowTable:
|
new_useShadowTable:
|
||||||
|
|
||||||
subl $0x1000, %eax
|
subl $0x1000, %eax
|
||||||
|
|
||||||
/* Check to see if EAX is valid/inrange */
|
/* Check to see if EAX is valid/inrange */
|
||||||
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
|
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
|
||||||
jbe new_shadowServiceInRange
|
jbe new_shadowServiceInRange
|
||||||
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
||||||
jmp KeReturnFromSystemCall
|
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||||
|
jmp KeReturnFromSystemCall
|
||||||
|
|
||||||
new_shadowServiceInRange:
|
new_shadowServiceInRange:
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* GDB thinks the function starts here and
|
/* GDB thinks the function starts here and
|
||||||
wants a standard prolog, so let's give it */
|
wants a standard prolog, so let's give it */
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate room for argument list from kernel stack */
|
/* Allocate room for argument list from kernel stack */
|
||||||
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
|
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
|
||||||
movb %es:(%ecx, %eax), %cl
|
movb %es:(%ecx, %eax), %cl
|
||||||
movzx %cl, %ecx
|
movzx %cl, %ecx
|
||||||
subl %ecx, %esp
|
subl %ecx, %esp
|
||||||
|
|
||||||
/* Copy the arguments from the user stack to the kernel stack */
|
/* Copy the arguments from the user stack to the kernel stack */
|
||||||
movl %esp,%edi
|
movl %esp,%edi
|
||||||
cld
|
cld
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
/* DS is now also kernel segment */
|
/* DS is now also kernel segment */
|
||||||
movw %bx,%ds
|
movw %bx,%ds
|
||||||
|
|
||||||
/* Call system call hook */
|
/* Call system call hook */
|
||||||
// pushl %eax
|
// pushl %eax
|
||||||
// call _KiSystemCallHook
|
// call _KiSystemCallHook
|
||||||
// popl %eax
|
// popl %eax
|
||||||
|
|
||||||
/* Call service check routine */
|
/* Call service check routine */
|
||||||
pushl %eax
|
pushl %eax
|
||||||
call _KiServiceCheck
|
call _KiServiceCheck
|
||||||
popl %eax
|
popl %eax
|
||||||
|
|
||||||
/* Make the system service call */
|
/* Make the system service call */
|
||||||
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
|
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
|
||||||
movl %es:(%ecx, %eax, 4), %eax
|
movl %es:(%ecx, %eax, 4), %eax
|
||||||
call *%eax
|
call *%eax
|
||||||
|
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||||
|
|
||||||
#if CHECKED
|
#if CHECKED
|
||||||
/* Bump Service Counter */
|
/* Bump Service Counter */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deallocate the kernel stack frame */
|
KeDeallocateStackAndReturnFromSystemCallWithHook:
|
||||||
movl %ebp,%esp
|
/* Deallocate the kernel stack frame */
|
||||||
|
movl %ebp,%esp
|
||||||
|
|
||||||
KeReturnFromSystemCallWithHook:
|
KeReturnFromSystemCallWithHook:
|
||||||
/* Call the post system call hook and deliver any pending APCs */
|
/* Call the post system call hook and deliver any pending APCs */
|
||||||
pushl %esp
|
pushl %esp
|
||||||
pushl %eax
|
call _KiAfterSystemCallHook
|
||||||
call _KiAfterSystemCallHook
|
addl $4,%esp
|
||||||
addl $8,%esp
|
|
||||||
|
|
||||||
KeReturnFromSystemCall:
|
KeReturnFromSystemCall:
|
||||||
|
|
||||||
/* Restore the user context */
|
|
||||||
/* Get a pointer to the current thread */
|
|
||||||
movl %fs:0x124, %esi
|
|
||||||
|
|
||||||
/* Restore the old trap frame pointer */
|
|
||||||
movl 0x3c(%esp), %ebx
|
|
||||||
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
|
|
||||||
|
|
||||||
/* Skip debug information and unsaved registers */
|
|
||||||
addl $0x30, %esp
|
|
||||||
popl %gs
|
|
||||||
popl %es
|
|
||||||
popl %ds
|
|
||||||
popl %edx
|
|
||||||
popl %ecx
|
|
||||||
addl $0x4, %esp /* Don't restore eax */
|
|
||||||
|
|
||||||
/* Restore the old previous mode */
|
/* Restore the user context */
|
||||||
popl %ebx
|
/* Get a pointer to the current thread */
|
||||||
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
movl %fs:0x124, %esi
|
||||||
|
|
||||||
/* Restore the old exception handler list */
|
/* Restore the old trap frame pointer */
|
||||||
popl %ebx
|
movl KTRAP_FRAME_EDX(%esp), %ebx
|
||||||
movl %ebx, %fs:KPCR_EXCEPTION_LIST
|
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
|
||||||
|
|
||||||
popl %fs
|
KiRosTrapReturn:
|
||||||
popl %edi
|
/* Skip debug information and unsaved registers */
|
||||||
popl %esi
|
addl $0x30, %esp
|
||||||
popl %ebx
|
popl %gs
|
||||||
popl %ebp
|
popl %es
|
||||||
addl $0x4, %esp /* Ignore error code */
|
popl %ds
|
||||||
|
popl %edx
|
||||||
iret
|
popl %ecx
|
||||||
|
popl %eax
|
||||||
|
|
||||||
|
/* Restore the old previous mode */
|
||||||
|
popl %ebx
|
||||||
|
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||||
|
|
||||||
|
/* Restore the old exception handler list */
|
||||||
|
popl %ebx
|
||||||
|
movl %ebx, %fs:KPCR_EXCEPTION_LIST
|
||||||
|
|
||||||
|
popl %fs
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
popl %ebx
|
||||||
|
popl %ebp
|
||||||
|
addl $0x4, %esp /* Ignore error code */
|
||||||
|
|
||||||
|
iret
|
||||||
|
|
||||||
|
/* R3: NOTE: This is part of my in-progress attempt at correcting NtContinue
|
||||||
|
* It is not being called, yet...
|
||||||
|
*/
|
||||||
|
.globl @KeRosTrapReturn@8
|
||||||
|
@KeRosTrapReturn@8:
|
||||||
|
/* Call the post system call hook and deliver any pending APCs */
|
||||||
|
pushl %esp
|
||||||
|
call _KiAfterSystemCallHook
|
||||||
|
addl $4,%esp
|
||||||
|
|
||||||
|
/* Restore the user context */
|
||||||
|
/* Get a pointer to the current thread */
|
||||||
|
movl %fs:0x124, %esi
|
||||||
|
/* Restore the old trap frame pointer */
|
||||||
|
movl %edx, KTHREAD_TRAP_FRAME(%esi)
|
||||||
|
|
||||||
|
/* point %esp to the trap frame to restore */
|
||||||
|
movl %ecx, %esp
|
||||||
|
jmp KiRosTrapReturn;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: usercall.c,v 1.26 2004/06/23 22:32:24 ion Exp $
|
/* $Id: usercall.c,v 1.27 2004/07/01 01:52:37 royce Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID KiSystemCallHook(ULONG Nr, ...)
|
VOID
|
||||||
|
KiSystemCallHook(ULONG Nr, ...)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -46,7 +47,8 @@ VOID KiSystemCallHook(ULONG Nr, ...)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
|
VOID
|
||||||
|
KiAfterSystemCallHook(PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
if (KeGetCurrentThread()->Alerted[1] != 0 && TrapFrame->Cs != KERNEL_CS)
|
if (KeGetCurrentThread()->Alerted[1] != 0 && TrapFrame->Cs != KERNEL_CS)
|
||||||
{
|
{
|
||||||
|
@ -56,11 +58,11 @@ ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
KiDeliverUserApc(TrapFrame);
|
KiDeliverUserApc(TrapFrame);
|
||||||
}
|
}
|
||||||
return(NtStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID KiServiceCheck (ULONG Nr)
|
VOID
|
||||||
|
KiServiceCheck (ULONG Nr)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue