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

📄 scall32-o32.s

📁 linux 内核源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org> * Copyright (C) 2001 MIPS Technologies, Inc. * Copyright (C) 2004 Thiemo Seufer */#include <linux/errno.h>#include <asm/asm.h>#include <asm/asmmacro.h>#include <asm/irqflags.h>#include <asm/mipsregs.h>#include <asm/regdef.h>#include <asm/stackframe.h>#include <asm/isadep.h>#include <asm/sysmips.h>#include <asm/thread_info.h>#include <asm/unistd.h>#include <asm/war.h>#include <asm/asm-offsets.h>/* Highest syscall used of any syscall flavour */#define MAX_SYSCALL_NO	__NR_O32_Linux + __NR_O32_Linux_syscalls	.align  5NESTED(handle_sys, PT_SIZE, sp)	.set	noat	SAVE_SOME	TRACE_IRQS_ON_RELOAD	STI	.set	at	lw	t1, PT_EPC(sp)		# skip syscall on return#if defined(CONFIG_BINFMT_IRIX)	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number#else	subu	v0, v0, __NR_O32_Linux	# check syscall number	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1#endif	addiu	t1, 4			# skip to next instruction	sw	t1, PT_EPC(sp)	beqz	t0, illegal_syscall	sll	t0, v0, 3	la	t1, sys_call_table	addu	t1, t0	lw	t2, (t1)		# syscall routine	lw	t3, 4(t1)		# >= 0 if we need stack arguments	beqz	t2, illegal_syscall	sw	a3, PT_R26(sp)		# save a3 for syscall restarting	bgez	t3, stackargsstack_done:	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT	and	t0, t1	bnez	t0, syscall_trace_entry	# -> yes	jalr	t2			# Do The Real Thing (TM)	li	t0, -EMAXERRNO - 1	# error?	sltu	t0, t0, v0	sw	t0, PT_R7(sp)		# set error flag	beqz	t0, 1f	negu	v0			# error	sw	v0, PT_R0(sp)		# set flag for syscall					# restarting1:	sw	v0, PT_R2(sp)		# resulto32_syscall_exit:	local_irq_disable		# make sure need_resched and					# signals dont change between					# sampling and return	lw	a2, TI_FLAGS($28)	# current->work	li	t0, _TIF_ALLWORK_MASK	and	t0, a2	bnez	t0, o32_syscall_exit_work	j	restore_partialo32_syscall_exit_work:	j	syscall_exit_work_partial/* ------------------------------------------------------------------------ */syscall_trace_entry:	SAVE_STATIC	move	s0, t2	move	a0, sp	li	a1, 0	jal	do_syscall_trace	move	t0, s0	RESTORE_STATIC	lw	a0, PT_R4(sp)		# Restore argument registers	lw	a1, PT_R5(sp)	lw	a2, PT_R6(sp)	lw	a3, PT_R7(sp)	jalr	t0	li	t0, -EMAXERRNO - 1	# error?	sltu	t0, t0, v0	sw	t0, PT_R7(sp)		# set error flag	beqz	t0, 1f	negu	v0			# error	sw	v0, PT_R0(sp)		# set flag for syscall					# restarting1:	sw	v0, PT_R2(sp)		# result	j	syscall_exit/* ------------------------------------------------------------------------ */	/*	 * More than four arguments.  Try to deal with it by copying the	 * stack arguments from the user stack to the kernel stack.	 * This Sucks (TM).	 */stackargs:	lw	t0, PT_R29(sp)		# get old user stack pointer	/*	 * We intentionally keep the kernel stack a little below the top of	 * userspace so we don't have to do a slower byte accurate check here.	 */	lw	t5, TI_ADDR_LIMIT($28)	addu	t4, t0, 32	and	t5, t4	bltz	t5, bad_stack		# -> sp is bad	/* Ok, copy the args from the luser stack to the kernel stack.	 * t3 is the precomputed number of instruction bytes needed to	 * load or store arguments 6-8.	 */	la	t1, 5f			# load up to 3 arguments	subu	t1, t31:	lw	t5, 16(t0)		# argument #5 from usp	.set    push	.set    noreorder	.set	nomacro	jr	t1	 addiu	t1, 6f - 5f2:	lw	t8, 28(t0)		# argument #8 from usp3:	lw	t7, 24(t0)		# argument #7 from usp4:	lw	t6, 20(t0)		# argument #6 from usp5:	jr	t1	 sw	t5, 16(sp)		# argument #5 to ksp	sw	t8, 28(sp)		# argument #8 to ksp	sw	t7, 24(sp)		# argument #7 to ksp	sw	t6, 20(sp)		# argument #6 to ksp6:	j	stack_done		# go back	 nop	.set	pop	.section __ex_table,"a"	PTR	1b,bad_stack	PTR	2b,bad_stack	PTR	3b,bad_stack	PTR	4b,bad_stack	.previous	/*	 * The stackpointer for a call with more than 4 arguments is bad.	 * We probably should handle this case a bit more drastic.	 */bad_stack:	negu	v0				# error	sw	v0, PT_R0(sp)	sw	v0, PT_R2(sp)	li	t0, 1				# set error flag	sw	t0, PT_R7(sp)	j	o32_syscall_exit	/*	 * The system call does not exist in this kernel	 */illegal_syscall:	li	v0, -ENOSYS			# error	sw	v0, PT_R2(sp)	li	t0, 1				# set error flag	sw	t0, PT_R7(sp)	j	o32_syscall_exit	END(handle_sys)	LEAF(mips_atomic_set)	andi	v0, a1, 3			# must be word aligned	bnez	v0, bad_alignment	lw	v1, TI_ADDR_LIMIT($28)		# in legal address range?	addiu	a0, a1, 4	or	a0, a0, a1	and	a0, a0, v1	bltz	a0, bad_address#ifdef CONFIG_CPU_HAS_LLSC	/* Ok, this is the ll/sc case.  World is sane :-)  */1:	ll	v0, (a1)	move	a0, a22:	sc	a0, (a1)#if R10000_LLSC_WAR	beqzl	a0, 1b#else	beqz	a0, 1b#endif	.section __ex_table,"a"	PTR	1b, bad_stack	PTR	2b, bad_stack	.previous#else	sw	a1, 16(sp)	sw	a2, 20(sp)	move	a0, sp	move	a2, a1	li	a1, 1	jal	do_page_fault	lw	a1, 16(sp)	lw	a2, 20(sp)	/*	 * At this point the page should be readable and writable unless	 * there was no more memory available.	 */1:	lw	v0, (a1)2:	sw	a2, (a1)	.section __ex_table,"a"	PTR	1b, no_mem	PTR	2b, no_mem	.previous#endif	sw	zero, PT_R7(sp)		# success	sw	v0, PT_R2(sp)		# result	j	o32_syscall_exit	# continue like a normal syscallno_mem:	li	v0, -ENOMEM	jr	rabad_address:	li	v0, -EFAULT	jr	rabad_alignment:	li	v0, -EINVAL	jr	ra	END(mips_atomic_set)	LEAF(sys_sysmips)	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set	j	_sys_sysmips	END(sys_sysmips)	LEAF(sys_syscall)#if defined(CONFIG_BINFMT_IRIX)	sltiu	v0, a0, MAX_SYSCALL_NO + 1 # check syscall number#else	subu	t0, a0, __NR_O32_Linux	# check syscall number	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1#endif	sll	t1, t0, 3	beqz	v0, einval	lw	t2, sys_call_table(t1)		# syscall routine#if defined(CONFIG_BINFMT_IRIX)	li	v1, 4000			# nr of sys_syscall#else	li	v1, 4000 - __NR_O32_Linux	# index of sys_syscall#endif	beq	t0, v1, einval			# do not recurse	/* Some syscalls like execve get their arguments from struct pt_regs	   and claim zero arguments in the syscall table. Thus we have to	   assume the worst case and shuffle around all potential arguments.	   If you want performance, don't use indirect syscalls. */	move	a0, a1				# shift argument registers	move	a1, a2	move	a2, a3	lw	a3, 16(sp)	lw	t4, 20(sp)	lw	t5, 24(sp)	lw	t6, 28(sp)	sw	t4, 16(sp)	sw	t5, 20(sp)	sw	t6, 24(sp)	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some	sw	a1, PT_R5(sp)			# syscalls expect them there	sw	a2, PT_R6(sp)	sw	a3, PT_R7(sp)	sw	a3, PT_R26(sp)			# update a3 for syscall restarting	jr	t2	/* Unreached */einval:	li	v0, -EINVAL	jr	ra	END(sys_syscall)	.macro	fifty ptr, nargs, from=1, to=50	sys	\ptr		\nargs	.if	\to-\from	fifty	\ptr,\nargs,"(\from+1)",\to	.endif	.endm	.macro	mille ptr, nargs, from=1, to=20	fifty	\ptr,\nargs	.if	\to-\from	mille	\ptr,\nargs,"(\from+1)",\to	.endif	.endm	.macro	syscalltable#if defined(CONFIG_BINFMT_IRIX)	mille	sys_ni_syscall		0	/*    0 -  999 SVR4 flavour */	mille	sys_ni_syscall		0	/* 1000 - 1999 32-bit IRIX */	mille	sys_ni_syscall		0	/* 2000 - 2999 BSD43 flavour */	mille	sys_ni_syscall		0	/* 3000 - 3999 POSIX flavour */#endif	sys	sys_syscall		8	/* 4000 */	sys	sys_exit		1	sys	sys_fork		0	sys	sys_read		3	sys	sys_write		3	sys	sys_open		3	/* 4005 */	sys	sys_close		1	sys	sys_waitpid		3

⌨️ 快捷键说明

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