Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 	.file	"syscall.s"
     28 
     29 #include "SYS.h"
     30 #include <sys/trap.h>
     31 
     32 	ANSI_PRAGMA_WEAK(syscall,function)
     33 
     34 /*
     35  * See sparc/sys/syscall.s to understand why _syscall6() exists.
     36  * On x86, the implementation of the two are the same, the only
     37  * difference being that _syscall6 is not an exported symbol.
     38  */
     39 	ENTRY2(syscall,_syscall6)
     40 	popl	%edx		/ return address
     41 	popl	%eax		/ system call number
     42 	pushl	%edx
     43 #if defined(_SYSC_INSN)
     44 	.byte	0xf, 0x5	/* syscall */
     45 #elif defined(_SEP_INSN)
     46 	call	8f
     47 8:	popl	%edx
     48 	movl	%esp, %ecx
     49 	addl	$[9f - 8b], %edx
     50 	sysenter
     51 9:
     52 #else
     53 	int	$T_SYSCALLINT
     54 #endif
     55 	movl	0(%esp), %edx
     56 	pushl	%edx		/ restore the return address
     57 	SYSCERROR
     58 	ret
     59 	SET_SIZE(syscall)
     60 	SET_SIZE(_syscall6)
     61 
     62 /*
     63  * See sparc/sys/syscall.s to understand why __systemcall6() exists.
     64  * On x86, the implementation of the two are the same, the only
     65  * difference being that __systemcall6 is not an exported symbol.
     66  *
     67  * WARNING WARNING WARNING:
     68  * The int $T_SYSCALL instruction below is needed by /proc when it scans a
     69  * controlled process's text for a syscall instruction.  It must be present in
     70  * all libc variants because /proc cannot use an optimized syscall instruction
     71  * to enter the kernel; optimized syscalls could be disabled by private LDT use.
     72  * We must leave at least one int $T_SYSCALLINT in the text for /proc to find
     73  * (see the Pscantext() routine).
     74  */
     75 	ENTRY2(__systemcall,__systemcall6)
     76 	popl	%edx		/ return address
     77 	popl	%ecx		/ structure return address
     78 	popl	%eax		/ system call number
     79 	pushl	%edx
     80 	int	$T_SYSCALLINT
     81 	jae	1f
     82 	/ error; clear syscall return values in the structure
     83 	movl	$-1, 0(%ecx)	/ sys_rval1
     84 	movl	$-1, 4(%ecx)	/ sys_rval2
     85 	jmp	2f		/ %eax contains the error number
     86 1:
     87 	/ no error; copy syscall return values to the structure
     88 	movl	%eax, 0(%ecx)	/ sys_rval1
     89 	movl	%edx, 4(%ecx)	/ sys_rval2
     90 	xorl	%eax, %eax	/ no error, set %eax to zero
     91 2:
     92 	movl	0(%esp), %edx	/ Restore the stack frame to original size
     93 	pushl	%ecx
     94 	pushl	%edx		/ restore the return address
     95 	ret
     96 	SET_SIZE(__systemcall)
     97 	SET_SIZE(__systemcall6)
     98