⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w32entry.s

📁 linux unified kernel test
💻 S
字号:
/* * w32entry.S * * Copyright (C) 2006  Insigme Co., Ltd * * Authors:  * - Decao Mao, Chenzhan Hu, Lixing Chu, Zhiqiang Jiao  * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute,   * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). *  * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * This program is free software; you can redistribute it and/or modify it * under the terms of  the GNU General  Public License as published by the * Free Software Foundation; either version 2 of the  License, or (at your * option) any later version. * * Revision History: *   Jan 2006 - Created. */  /*  * Implements the w32 system call mechanism. The code is basically  * a merge of the related code in entry.S from Linux 2.6.13 and  * in syscall.S from Reactos 0.2.6. It is for i386 only.  */#include "config.h"#include <linux/linkage.h>#include <asm/thread_info.h>#include <asm/errno.h>#include <asm/segment.h>#include <asm/smp.h>#include <asm/page.h>#include <asm/desc.h>#include "irq_vectors.h"#ifndef TI_flags#define TI_flags 8#endif#define nr_syscalls ((syscall_table_size)/4)EBX		= 0x00ECX		= 0x04EDX		= 0x08ESI		= 0x0CEDI		= 0x10EBP		= 0x14EAX		= 0x18DS		= 0x1CES		= 0x20ORIG_EAX	= 0x24EIP		= 0x28CS		= 0x2CEFLAGS		= 0x30OLDESP		= 0x34OLDSS		= 0x38CF_MASK		= 0x00000001TF_MASK		= 0x00000100IF_MASK		= 0x00000200DF_MASK		= 0x00000400 NT_MASK		= 0x00004000VM_MASK		= 0x00020000#ifdef CONFIG_PREEMPT#define preempt_stop		cli#else#define preempt_stop#define resume_kernel		restore_nocheck#endif#define SAVE_ALL \	cld; \	pushl %es; \	pushl %ds; \	pushl %eax; \	pushl %ebp; \	pushl %edi; \	pushl %esi; \	pushl %edx; \	pushl %ecx; \	pushl %ebx; \	movl $(__USER_DS), %ecx; \	movl %ecx, %ds; \	movl %ecx, %es;#define RESTORE_INT_REGS \	popl %ebx;	\	popl %ecx;	\	popl %edx;	\	popl %esi;	\	popl %edi;	\	popl %ebp;	\	popl %eax#define RESTORE_REGS	\	RESTORE_INT_REGS; \1:	popl %ds;	\2:	popl %es;	\.section .fixup,"ax";	\3:	movl $0,(%esp);	\	jmp 1b;		\4:	movl $0,(%esp);	\	jmp 2b;		\.previous;		\.section __ex_table,"a";\	.align 4;	\	.long 1b,3b;	\	.long 2b,4b;	\.previous#ifdef CONFIG_UNIFIED_KERNELENTRY(w32system_call)	pushl %eax			# save orig_eax	SAVE_ALL	GET_THREAD_INFO(%ebp)    # previous mode tracing to be implemented	# system call tracing in operation / emulation    /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */	testw $(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)	jnz w32syscall_trace_entry	    /*     * Find out which syscall table (basic or extended) to use,      * and get the offset to the table.      * The offset is related to the Table Index as such:      *   offset = TableIndex x 0x10.   (see the typedef for SSDT_ENTRY)     * For example, if %eax is 0x1124, then the offset is 0x10.     */    		movl %eax, %edi	shrl $8, %edi	andl $0x10, %edi           /* Now add the base system table to the offset */    	addl $(KeServiceDescriptorTable), %edi        /* Get the true syscall ID and check it */	andl $0x0FFF, %eax	cmpl 8(%edi), %eax	    /* Invalid ID, try to load Win32K Table */	jnb w32syscall_badsys	w32syscall_call:    /* For w32syscall_trace_back */     /* Users's current stack frame pointer is source */	#movl OLDESP(%esp), %edx	#addl $8, %edx				#for parameters on the user space stack    movl %edx, %esi	           /* Allocate room for argument list from kernel stack */	movl 12(%edi), %ecx	movb (%ecx, %eax), %cl	movzx %cl, %ecx	shll $2,%ecx/*get actually byte size*/    /* Allocate new Kernel stack frame */	pushl %ebp					movl %esp,%ebp       /* Allocate space on our stack ,ecx is the size of stack buffer to copy*/    subl %ecx, %esp	       /* Get pointer to function */    movl (%edi), %edi    movl (%edi, %eax, 4), %eax    /* Copy the arguments from the user stack to kernel stack */    shr $2, %ecx/*count of dword vaule to copy ecx = ecx/4 */    movl %esp, %edi    cld    rep movsd		#movl %esp,%edi	#addl $8,%esp 	/*pushl %eax; 	pushl %ebp; 	pushl %edi; 	pushl %esi; 	pushl %edx; 	pushl %ecx; 	pushl %ebx; 	mov %ecx,%esi    call check_kernel        popl %ebx;		popl %ecx;		popl %edx;		popl %esi;		popl %edi;		popl %ebp;		popl %eax*/		    /* Do the System Call */    call *%eax    /* Deallocate the kernel stack frame  */    movl %ebp, %esp	popl %ebp					movl %eax,EAX(%esp)		# store the return valuew32syscall_exit:	cli				# make sure we don't miss an interrupt					# setting need_resched or sigpending					# between sampling and the iret	movl TI_flags(%ebp), %ecx	testw $_TIF_ALLWORK_MASK, %cx	# current->work	jne w32syscall_exit_workw32restore_all:	movl EFLAGS(%esp), %eax		# mix EFLAGS, SS and CS	# Warning: OLDSS(%esp) contains the wrong/random values if we	# are returning to the kernel.	# See comments in process.c:copy_thread() for details.	movb OLDSS(%esp), %ah	movb CS(%esp), %al	andl $(VM_MASK | (4 << 8) | 3), %eax	cmpl $((4 << 8) | 3), %eax	je w32ldt_ss			# returning to user-space with LDT SS	w32restore_nocheck:	RESTORE_REGS	addl $4, %esp	iretw32ldt_ss:	larl OLDSS(%esp), %eax	jnz w32restore_nocheck	testl $0x00400000, %eax		# returning to 32bit stack?	jnz w32restore_nocheck		# allright, normal return		/* If returning to userspace with 16bit stack,	 * try to fix the higher word of ESP, as the CPU	 * won't restore it.	 * This is an "official" bug of all the x86-compatible	 * CPUs, which we can try to work around to make	 * dosemu and wine happy. */	subl $8, %esp		# reserve space for switch16 pointer	cli	movl %esp, %eax	/* Set up the 16bit stack frame with switch32 pointer on top,	 * and a switch16 pointer on top of the current frame. */	#call setup_x86_bogus_stack	RESTORE_REGS	lss 20+4(%esp), %esp	# switch to 16bit stack	iret	# perform work that needs to be done immediately before resumption	ALIGN	w32work_pending:	testb $_TIF_NEED_RESCHED, %cl	jz w32work_notifysig	w32work_resched:	call schedule	cli				# make sure we don't miss an interrupt					# setting need_resched or sigpending					# between sampling and the iret	movl TI_flags(%ebp), %ecx	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done other					# than syscall tracing?	jz w32restore_all	testb $_TIF_NEED_RESCHED, %cl	jnz w32work_resched	w32work_notifysig:				# deal with pending signals and					            # notify-resume requests	testl $VM_MASK, EFLAGS(%esp)    # user-space or vm86-space	movl %esp, %eax	jne w32work_notifysig_v86	xorl %edx, %edx	call do_apc                 # for Windows APC	call do_notify_resume       # for Linux signals	jmp w32resume_userspace	ALIGN	w32work_notifysig_v86:	pushl %ecx	call save_v86_state	popl %ecx	movl %eax,%esp	xorl %edx,%edx	call do_apc	call do_notify_resume	jmp w32resume_userspace	#perform syscall exit tracing	ALIGN	w32syscall_trace_entry:	movl $-ENOSYS,EAX(%esp)	movl %esp, %eax	xorl %edx,%edx	call do_syscall_trace	cmpl $0, %eax	jne w32resume_userspace		# ret != 0 -> running under PTRACE_SYSEMU,					# so must skip actual syscall	movl ORIG_EAX(%esp), %eax	    /* back to w32syscall_call */	movl %eax, %edi	shrl $8, %edi	andl $0x10, %edi		addl $(KeServiceDescriptorTable), %edi	andl $0x0FFF, %eax	cmpl 8(%edi), %eax		jb w32syscall_call		jmp w32syscall_exit# perform syscall exit tracing	ALIGN	w32syscall_exit_work:	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl	jz w32work_pending	sti				# could let do_syscall_trace() call					# schedule() instead	movl %esp, %eax	movl $1, %edx	call do_syscall_trace	jmp w32resume_userspace	ENTRY(w32resume_userspace)	cli				# make sure we don't miss an interrupt					# setting need_resched or sigpending					# between sampling and the iret	movl TI_flags(%ebp), %ecx	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done on					# int/exception return?	jne w32work_pending    	# previous mode restoration to be implemented	jmp w32restore_all	ALIGN	w32syscall_badsys:	movl $-ENOSYS,EAX(%esp)	jmp w32resume_userspace	#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -