sunos_syscall.c revision 1.6
11.6Sagc/* $NetBSD: sunos_syscall.c,v 1.6 2003/08/07 16:28:19 agc Exp $ */ 21.1Sscw 31.1Sscw/*- 41.1Sscw * Portions Copyright (c) 2000 The NetBSD Foundation, Inc. 51.1Sscw * All rights reserved. 61.1Sscw * 71.1Sscw * Redistribution and use in source and binary forms, with or without 81.1Sscw * modification, are permitted provided that the following conditions 91.1Sscw * are met: 101.1Sscw * 1. Redistributions of source code must retain the above copyright 111.1Sscw * notice, this list of conditions and the following disclaimer. 121.1Sscw * 2. Redistributions in binary form must reproduce the above copyright 131.1Sscw * notice, this list of conditions and the following disclaimer in the 141.1Sscw * documentation and/or other materials provided with the distribution. 151.1Sscw * 3. All advertising materials mentioning features or use of this software 161.1Sscw * must display the following acknowledgement: 171.1Sscw * This product includes software developed by the NetBSD 181.1Sscw * Foundation, Inc. and its contributors. 191.1Sscw * 4. Neither the name of The NetBSD Foundation nor the names of its 201.1Sscw * contributors may be used to endorse or promote products derived 211.1Sscw * from this software without specific prior written permission. 221.1Sscw * 231.1Sscw * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 241.1Sscw * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 251.1Sscw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 261.1Sscw * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 271.1Sscw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 281.1Sscw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 291.1Sscw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 301.1Sscw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 311.1Sscw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 321.1Sscw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 331.1Sscw * POSSIBILITY OF SUCH DAMAGE. 341.1Sscw */ 351.1Sscw 361.1Sscw/* 371.1Sscw * Copyright (c) 1982, 1986, 1990, 1993 381.1Sscw * The Regents of the University of California. All rights reserved. 391.1Sscw * 401.1Sscw * This code is derived from software contributed to Berkeley by 411.1Sscw * the Systems Programming Group of the University of Utah Computer 421.1Sscw * Science Department. 431.1Sscw * 441.1Sscw * Redistribution and use in source and binary forms, with or without 451.1Sscw * modification, are permitted provided that the following conditions 461.1Sscw * are met: 471.1Sscw * 1. Redistributions of source code must retain the above copyright 481.1Sscw * notice, this list of conditions and the following disclaimer. 491.1Sscw * 2. Redistributions in binary form must reproduce the above copyright 501.1Sscw * notice, this list of conditions and the following disclaimer in the 511.1Sscw * documentation and/or other materials provided with the distribution. 521.6Sagc * 3. Neither the name of the University nor the names of its contributors 531.6Sagc * may be used to endorse or promote products derived from this software 541.6Sagc * without specific prior written permission. 551.6Sagc * 561.6Sagc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 571.6Sagc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 581.6Sagc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 591.6Sagc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 601.6Sagc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 611.6Sagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 621.6Sagc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 631.6Sagc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 641.6Sagc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 651.6Sagc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 661.6Sagc * SUCH DAMAGE. 671.6Sagc * 681.6Sagc * from: Utah $Hdr: trap.c 1.37 92/12/20$ 691.6Sagc * 701.6Sagc * @(#)trap.c 8.5 (Berkeley) 1/4/94 711.6Sagc */ 721.6Sagc/* 731.6Sagc * Copyright (c) 1988 University of Utah. 741.6Sagc * 751.6Sagc * This code is derived from software contributed to Berkeley by 761.6Sagc * the Systems Programming Group of the University of Utah Computer 771.6Sagc * Science Department. 781.6Sagc * 791.6Sagc * Redistribution and use in source and binary forms, with or without 801.6Sagc * modification, are permitted provided that the following conditions 811.6Sagc * are met: 821.6Sagc * 1. Redistributions of source code must retain the above copyright 831.6Sagc * notice, this list of conditions and the following disclaimer. 841.6Sagc * 2. Redistributions in binary form must reproduce the above copyright 851.6Sagc * notice, this list of conditions and the following disclaimer in the 861.6Sagc * documentation and/or other materials provided with the distribution. 871.1Sscw * 3. All advertising materials mentioning features or use of this software 881.1Sscw * must display the following acknowledgement: 891.1Sscw * This product includes software developed by the University of 901.1Sscw * California, Berkeley and its contributors. 911.1Sscw * 4. Neither the name of the University nor the names of its contributors 921.1Sscw * may be used to endorse or promote products derived from this software 931.1Sscw * without specific prior written permission. 941.1Sscw * 951.1Sscw * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 961.1Sscw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 971.1Sscw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 981.1Sscw * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 991.1Sscw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1001.1Sscw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1011.1Sscw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1021.1Sscw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1031.1Sscw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1041.1Sscw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1051.1Sscw * SUCH DAMAGE. 1061.1Sscw * 1071.1Sscw * from: Utah $Hdr: trap.c 1.37 92/12/20$ 1081.1Sscw * 1091.1Sscw * @(#)trap.c 8.5 (Berkeley) 1/4/94 1101.1Sscw */ 1111.5Slukem 1121.5Slukem#include <sys/cdefs.h> 1131.6Sagc__KERNEL_RCSID(0, "$NetBSD: sunos_syscall.c,v 1.6 2003/08/07 16:28:19 agc Exp $"); 1141.1Sscw 1151.1Sscw#include "opt_syscall_debug.h" 1161.1Sscw#include "opt_execfmt.h" 1171.1Sscw#include "opt_ktrace.h" 1181.1Sscw#include "opt_systrace.h" 1191.1Sscw 1201.1Sscw#include <sys/param.h> 1211.1Sscw#include <sys/systm.h> 1221.1Sscw#include <sys/proc.h> 1231.1Sscw#include <sys/acct.h> 1241.1Sscw#include <sys/kernel.h> 1251.1Sscw#include <sys/syscall.h> 1261.1Sscw#include <sys/syslog.h> 1271.1Sscw#include <sys/user.h> 1281.1Sscw#ifdef KTRACE 1291.1Sscw#include <sys/ktrace.h> 1301.1Sscw#endif 1311.1Sscw#ifdef SYSTRACE 1321.1Sscw#include <sys/systrace.h> 1331.1Sscw#endif 1341.1Sscw 1351.1Sscw#include <machine/psl.h> 1361.1Sscw#include <machine/cpu.h> 1371.1Sscw#include <machine/reg.h> 1381.1Sscw 1391.1Sscw#include <uvm/uvm_extern.h> 1401.1Sscw 1411.1Sscw#include <compat/sunos/sunos_syscall.h> 1421.1Sscw#include <compat/sunos/sunos_exec.h> 1431.1Sscw 1441.1Sscwvoid sunos_syscall_intern(struct proc *); 1451.4Sthorpejstatic void sunos_syscall_plain(register_t, struct lwp *, struct frame *); 1461.4Sthorpejstatic void sunos_syscall_fancy(register_t, struct lwp *, struct frame *); 1471.1Sscw 1481.1Sscwvoid 1491.1Sscwsunos_syscall_intern(struct proc *p) 1501.1Sscw{ 1511.1Sscw 1521.1Sscw#ifdef KTRACE 1531.1Sscw if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET)) 1541.1Sscw p->p_md.md_syscall = sunos_syscall_fancy; 1551.1Sscw else 1561.1Sscw#endif 1571.1Sscw#ifdef SYSTRACE 1581.1Sscw if (ISSET(p->p_flag, P_SYSTRACE)) 1591.1Sscw p->p_md.md_syscall = sunos_syscall_fancy; 1601.1Sscw else 1611.1Sscw#endif 1621.1Sscw p->p_md.md_syscall = sunos_syscall_plain; 1631.1Sscw} 1641.1Sscw 1651.1Sscwstatic void 1661.4Sthorpejsunos_syscall_plain(register_t code, struct lwp *l, struct frame *frame) 1671.1Sscw{ 1681.4Sthorpej struct proc *p = l->l_proc; 1691.1Sscw caddr_t params; 1701.1Sscw const struct sysent *callp; 1711.1Sscw int error, nsys; 1721.1Sscw size_t argsize; 1731.1Sscw register_t args[16], rval[2]; 1741.1Sscw 1751.1Sscw nsys = p->p_emul->e_nsysent; 1761.1Sscw callp = p->p_emul->e_sysent; 1771.1Sscw 1781.1Sscw /* 1791.1Sscw * SunOS passes the syscall-number on the stack, whereas 1801.1Sscw * BSD passes it in D0. So, we have to get the real "code" 1811.1Sscw * from the stack, and clean up the stack, as SunOS glue 1821.1Sscw * code assumes the kernel pops the syscall argument the 1831.1Sscw * glue pushed on the stack. Sigh... 1841.1Sscw */ 1851.1Sscw code = fuword((caddr_t)frame->f_regs[SP]); 1861.1Sscw 1871.1Sscw /* 1881.1Sscw * XXX 1891.1Sscw * Don't do this for sunos_sigreturn, as there's no stored pc 1901.1Sscw * on the stack to skip, the argument follows the syscall 1911.1Sscw * number without a gap. 1921.1Sscw */ 1931.1Sscw if (code != SUNOS_SYS_sigreturn) { 1941.1Sscw frame->f_regs[SP] += sizeof (int); 1951.1Sscw /* 1961.1Sscw * remember that we adjusted the SP, 1971.1Sscw * might have to undo this if the system call 1981.1Sscw * returns ERESTART. 1991.1Sscw */ 2001.4Sthorpej l->l_md.md_flags |= MDL_STACKADJ; 2011.1Sscw } else 2021.4Sthorpej l->l_md.md_flags &= ~MDL_STACKADJ; 2031.1Sscw 2041.1Sscw params = (caddr_t)frame->f_regs[SP] + sizeof(int); 2051.1Sscw 2061.1Sscw switch (code) { 2071.1Sscw case SUNOS_SYS_syscall: 2081.1Sscw /* 2091.1Sscw * Code is first argument, followed by actual args. 2101.1Sscw */ 2111.1Sscw code = fuword(params); 2121.1Sscw params += sizeof(int); 2131.1Sscw break; 2141.1Sscw default: 2151.1Sscw break; 2161.1Sscw } 2171.1Sscw 2181.1Sscw if (code < 0 || code >= nsys) 2191.1Sscw callp += p->p_emul->e_nosys; /* illegal */ 2201.1Sscw else 2211.1Sscw callp += code; 2221.1Sscw 2231.1Sscw argsize = callp->sy_argsize; 2241.1Sscw if (argsize) { 2251.1Sscw error = copyin(params, (caddr_t)args, argsize); 2261.1Sscw if (error) 2271.1Sscw goto bad; 2281.1Sscw } 2291.1Sscw 2301.1Sscw#ifdef SYSCALL_DEBUG 2311.4Sthorpej scdebug_call(l, code, args); 2321.1Sscw#endif 2331.1Sscw 2341.1Sscw rval[0] = 0; 2351.1Sscw rval[1] = frame->f_regs[D1]; 2361.4Sthorpej error = (*callp->sy_call)(l, args, rval); 2371.1Sscw 2381.1Sscw switch (error) { 2391.1Sscw case 0: 2401.1Sscw /* 2411.1Sscw * Reinitialize proc pointer `p' as it may be different 2421.1Sscw * if this is a child returning from fork syscall. 2431.1Sscw */ 2441.1Sscw p = curproc; 2451.1Sscw frame->f_regs[D0] = rval[0]; 2461.1Sscw frame->f_regs[D1] = rval[1]; 2471.1Sscw frame->f_sr &= ~PSL_C; /* carry bit */ 2481.1Sscw break; 2491.1Sscw case ERESTART: 2501.1Sscw /* 2511.1Sscw * We always enter through a `trap' instruction, which is 2 2521.1Sscw * bytes, so adjust the pc by that amount. 2531.1Sscw */ 2541.1Sscw frame->f_pc = frame->f_pc - 2; 2551.1Sscw break; 2561.1Sscw case EJUSTRETURN: 2571.1Sscw /* nothing to do */ 2581.1Sscw break; 2591.1Sscw default: 2601.1Sscw bad: 2611.1Sscw frame->f_regs[D0] = error; 2621.1Sscw frame->f_sr |= PSL_C; /* carry bit */ 2631.1Sscw break; 2641.1Sscw } 2651.1Sscw 2661.1Sscw /* need new p-value for this */ 2671.4Sthorpej if (l->l_md.md_flags & MDL_STACKADJ) { 2681.4Sthorpej l->l_md.md_flags &= ~MDL_STACKADJ; 2691.1Sscw if (error == ERESTART) 2701.1Sscw frame->f_regs[SP] -= sizeof (int); 2711.1Sscw } 2721.1Sscw 2731.1Sscw#ifdef SYSCALL_DEBUG 2741.1Sscw scdebug_ret(p, code, error, rval) 2751.1Sscw#endif 2761.1Sscw} 2771.1Sscw 2781.1Sscwstatic void 2791.4Sthorpejsunos_syscall_fancy(register_t code, struct lwp *l, struct frame *frame) 2801.1Sscw{ 2811.4Sthorpej struct proc *p = l->l_proc; 2821.1Sscw caddr_t params; 2831.1Sscw const struct sysent *callp; 2841.1Sscw int error, nsys; 2851.1Sscw size_t argsize; 2861.1Sscw register_t args[16], rval[2]; 2871.1Sscw 2881.1Sscw nsys = p->p_emul->e_nsysent; 2891.1Sscw callp = p->p_emul->e_sysent; 2901.1Sscw 2911.1Sscw /* 2921.1Sscw * SunOS passes the syscall-number on the stack, whereas 2931.1Sscw * BSD passes it in D0. So, we have to get the real "code" 2941.1Sscw * from the stack, and clean up the stack, as SunOS glue 2951.1Sscw * code assumes the kernel pops the syscall argument the 2961.1Sscw * glue pushed on the stack. Sigh... 2971.1Sscw */ 2981.1Sscw code = fuword((caddr_t)frame->f_regs[SP]); 2991.1Sscw 3001.1Sscw /* 3011.1Sscw * XXX 3021.1Sscw * Don't do this for sunos_sigreturn, as there's no stored pc 3031.1Sscw * on the stack to skip, the argument follows the syscall 3041.1Sscw * number without a gap. 3051.1Sscw */ 3061.1Sscw if (code != SUNOS_SYS_sigreturn) { 3071.1Sscw frame->f_regs[SP] += sizeof (int); 3081.1Sscw /* 3091.1Sscw * remember that we adjusted the SP, 3101.1Sscw * might have to undo this if the system call 3111.1Sscw * returns ERESTART. 3121.1Sscw */ 3131.4Sthorpej l->l_md.md_flags |= MDL_STACKADJ; 3141.1Sscw } else 3151.4Sthorpej l->l_md.md_flags &= ~MDL_STACKADJ; 3161.1Sscw 3171.1Sscw params = (caddr_t)frame->f_regs[SP] + sizeof(int); 3181.1Sscw 3191.1Sscw switch (code) { 3201.1Sscw case SUNOS_SYS_syscall: 3211.1Sscw /* 3221.1Sscw * Code is first argument, followed by actual args. 3231.1Sscw */ 3241.1Sscw code = fuword(params); 3251.1Sscw params += sizeof(int); 3261.1Sscw break; 3271.1Sscw default: 3281.1Sscw break; 3291.1Sscw } 3301.1Sscw 3311.1Sscw if (code < 0 || code >= nsys) 3321.1Sscw callp += p->p_emul->e_nosys; /* illegal */ 3331.1Sscw else 3341.1Sscw callp += code; 3351.1Sscw 3361.1Sscw argsize = callp->sy_argsize; 3371.1Sscw if (argsize) { 3381.1Sscw error = copyin(params, (caddr_t)args, argsize); 3391.1Sscw if (error) 3401.1Sscw goto bad; 3411.1Sscw } 3421.1Sscw 3431.4Sthorpej if ((error = trace_enter(l, code, code, NULL, args, rval)) != 0) 3441.1Sscw goto bad; 3451.1Sscw 3461.1Sscw rval[0] = 0; 3471.1Sscw rval[1] = frame->f_regs[D1]; 3481.4Sthorpej error = (*callp->sy_call)(l, args, rval); 3491.1Sscw 3501.1Sscw switch (error) { 3511.1Sscw case 0: 3521.1Sscw /* 3531.1Sscw * Reinitialize proc pointer `p' as it may be different 3541.1Sscw * if this is a child returning from fork syscall. 3551.1Sscw */ 3561.1Sscw p = curproc; 3571.1Sscw frame->f_regs[D0] = rval[0]; 3581.1Sscw frame->f_regs[D1] = rval[1]; 3591.1Sscw frame->f_sr &= ~PSL_C; /* carry bit */ 3601.1Sscw break; 3611.1Sscw case ERESTART: 3621.1Sscw /* 3631.1Sscw * We always enter through a `trap' instruction, which is 2 3641.1Sscw * bytes, so adjust the pc by that amount. 3651.1Sscw */ 3661.1Sscw frame->f_pc = frame->f_pc - 2; 3671.1Sscw break; 3681.1Sscw case EJUSTRETURN: 3691.1Sscw /* nothing to do */ 3701.1Sscw break; 3711.1Sscw default: 3721.1Sscw bad: 3731.1Sscw frame->f_regs[D0] = error; 3741.1Sscw frame->f_sr |= PSL_C; /* carry bit */ 3751.1Sscw break; 3761.1Sscw } 3771.1Sscw 3781.1Sscw /* need new p-value for this */ 3791.4Sthorpej if (l->l_md.md_flags & MDL_STACKADJ) { 3801.4Sthorpej l->l_md.md_flags &= ~MDL_STACKADJ; 3811.1Sscw if (error == ERESTART) 3821.1Sscw frame->f_regs[SP] -= sizeof (int); 3831.1Sscw } 3841.1Sscw 3851.4Sthorpej trace_exit(l, code, args, rval, error); 3861.1Sscw} 387