2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A .file "syscall.s"
2N/A
2N/A#include "SYS.h"
2N/A#include <sys/trap.h>
2N/A
2N/A ANSI_PRAGMA_WEAK(syscall,function)
2N/A
2N/A/*
2N/A * See sparc/sys/syscall.s to understand why _syscall6() exists.
2N/A * On x86, the implementation of the two are the same, the only
2N/A * difference being that _syscall6 is not an exported symbol.
2N/A */
2N/A ENTRY2(syscall,_syscall6)
2N/A popl %edx / return address
2N/A popl %eax / system call number
2N/A pushl %edx
2N/A#if defined(_SYSC_INSN)
2N/A .byte 0xf, 0x5 /* syscall */
2N/A#elif defined(_SEP_INSN)
2N/A call 8f
2N/A8: popl %edx
2N/A movl %esp, %ecx
2N/A addl $[9f - 8b], %edx
2N/A sysenter
2N/A9:
2N/A#else
2N/A int $T_SYSCALLINT
2N/A#endif
2N/A movl 0(%esp), %edx
2N/A pushl %edx / restore the return address
2N/A SYSCERROR
2N/A ret
2N/A SET_SIZE(syscall)
2N/A SET_SIZE(_syscall6)
2N/A
2N/A/*
2N/A * See sparc/sys/syscall.s to understand why __systemcall6() exists.
2N/A * On x86, the implementation of the two are the same, the only
2N/A * difference being that __systemcall6 is not an exported symbol.
2N/A *
2N/A * WARNING WARNING WARNING:
2N/A * The int $T_SYSCALL instruction below is needed by /proc when it scans a
2N/A * controlled process's text for a syscall instruction. It must be present in
2N/A * all libc variants because /proc cannot use an optimized syscall instruction
2N/A * to enter the kernel; optimized syscalls could be disabled by private LDT use.
2N/A * We must leave at least one int $T_SYSCALLINT in the text for /proc to find
2N/A * (see the Pscantext() routine).
2N/A */
2N/A ENTRY2(__systemcall,__systemcall6)
2N/A popl %edx / return address
2N/A popl %ecx / structure return address
2N/A popl %eax / system call number
2N/A pushl %edx
2N/A int $T_SYSCALLINT
2N/A jae 1f
2N/A / error; clear syscall return values in the structure
2N/A movl $-1, 0(%ecx) / sys_rval1
2N/A movl $-1, 4(%ecx) / sys_rval2
2N/A jmp 2f / %eax contains the error number
2N/A1:
2N/A / no error; copy syscall return values to the structure
2N/A movl %eax, 0(%ecx) / sys_rval1
2N/A movl %edx, 4(%ecx) / sys_rval2
2N/A xorl %eax, %eax / no error, set %eax to zero
2N/A2:
2N/A movl 0(%esp), %edx / Restore the stack frame to original size
2N/A pushl %ecx
2N/A pushl %edx / restore the return address
2N/A ret
2N/A SET_SIZE(__systemcall)
2N/A SET_SIZE(__systemcall6)