sunos_syscall.c revision 1.6
1/* $NetBSD: sunos_syscall.c,v 1.6 2003/08/07 16:28:19 agc Exp $ */ 2 3/*- 4 * Portions Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the NetBSD 18 * Foundation, Inc. and its contributors. 19 * 4. Neither the name of The NetBSD Foundation nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36/* 37 * Copyright (c) 1982, 1986, 1990, 1993 38 * The Regents of the University of California. All rights reserved. 39 * 40 * This code is derived from software contributed to Berkeley by 41 * the Systems Programming Group of the University of Utah Computer 42 * Science Department. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * from: Utah $Hdr: trap.c 1.37 92/12/20$ 69 * 70 * @(#)trap.c 8.5 (Berkeley) 1/4/94 71 */ 72/* 73 * Copyright (c) 1988 University of Utah. 74 * 75 * This code is derived from software contributed to Berkeley by 76 * the Systems Programming Group of the University of Utah Computer 77 * Science Department. 78 * 79 * Redistribution and use in source and binary forms, with or without 80 * modification, are permitted provided that the following conditions 81 * are met: 82 * 1. Redistributions of source code must retain the above copyright 83 * notice, this list of conditions and the following disclaimer. 84 * 2. Redistributions in binary form must reproduce the above copyright 85 * notice, this list of conditions and the following disclaimer in the 86 * documentation and/or other materials provided with the distribution. 87 * 3. All advertising materials mentioning features or use of this software 88 * must display the following acknowledgement: 89 * This product includes software developed by the University of 90 * California, Berkeley and its contributors. 91 * 4. Neither the name of the University nor the names of its contributors 92 * may be used to endorse or promote products derived from this software 93 * without specific prior written permission. 94 * 95 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 96 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 97 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 98 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 99 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 100 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 101 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 102 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 103 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 104 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 105 * SUCH DAMAGE. 106 * 107 * from: Utah $Hdr: trap.c 1.37 92/12/20$ 108 * 109 * @(#)trap.c 8.5 (Berkeley) 1/4/94 110 */ 111 112#include <sys/cdefs.h> 113__KERNEL_RCSID(0, "$NetBSD: sunos_syscall.c,v 1.6 2003/08/07 16:28:19 agc Exp $"); 114 115#include "opt_syscall_debug.h" 116#include "opt_execfmt.h" 117#include "opt_ktrace.h" 118#include "opt_systrace.h" 119 120#include <sys/param.h> 121#include <sys/systm.h> 122#include <sys/proc.h> 123#include <sys/acct.h> 124#include <sys/kernel.h> 125#include <sys/syscall.h> 126#include <sys/syslog.h> 127#include <sys/user.h> 128#ifdef KTRACE 129#include <sys/ktrace.h> 130#endif 131#ifdef SYSTRACE 132#include <sys/systrace.h> 133#endif 134 135#include <machine/psl.h> 136#include <machine/cpu.h> 137#include <machine/reg.h> 138 139#include <uvm/uvm_extern.h> 140 141#include <compat/sunos/sunos_syscall.h> 142#include <compat/sunos/sunos_exec.h> 143 144void sunos_syscall_intern(struct proc *); 145static void sunos_syscall_plain(register_t, struct lwp *, struct frame *); 146static void sunos_syscall_fancy(register_t, struct lwp *, struct frame *); 147 148void 149sunos_syscall_intern(struct proc *p) 150{ 151 152#ifdef KTRACE 153 if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET)) 154 p->p_md.md_syscall = sunos_syscall_fancy; 155 else 156#endif 157#ifdef SYSTRACE 158 if (ISSET(p->p_flag, P_SYSTRACE)) 159 p->p_md.md_syscall = sunos_syscall_fancy; 160 else 161#endif 162 p->p_md.md_syscall = sunos_syscall_plain; 163} 164 165static void 166sunos_syscall_plain(register_t code, struct lwp *l, struct frame *frame) 167{ 168 struct proc *p = l->l_proc; 169 caddr_t params; 170 const struct sysent *callp; 171 int error, nsys; 172 size_t argsize; 173 register_t args[16], rval[2]; 174 175 nsys = p->p_emul->e_nsysent; 176 callp = p->p_emul->e_sysent; 177 178 /* 179 * SunOS passes the syscall-number on the stack, whereas 180 * BSD passes it in D0. So, we have to get the real "code" 181 * from the stack, and clean up the stack, as SunOS glue 182 * code assumes the kernel pops the syscall argument the 183 * glue pushed on the stack. Sigh... 184 */ 185 code = fuword((caddr_t)frame->f_regs[SP]); 186 187 /* 188 * XXX 189 * Don't do this for sunos_sigreturn, as there's no stored pc 190 * on the stack to skip, the argument follows the syscall 191 * number without a gap. 192 */ 193 if (code != SUNOS_SYS_sigreturn) { 194 frame->f_regs[SP] += sizeof (int); 195 /* 196 * remember that we adjusted the SP, 197 * might have to undo this if the system call 198 * returns ERESTART. 199 */ 200 l->l_md.md_flags |= MDL_STACKADJ; 201 } else 202 l->l_md.md_flags &= ~MDL_STACKADJ; 203 204 params = (caddr_t)frame->f_regs[SP] + sizeof(int); 205 206 switch (code) { 207 case SUNOS_SYS_syscall: 208 /* 209 * Code is first argument, followed by actual args. 210 */ 211 code = fuword(params); 212 params += sizeof(int); 213 break; 214 default: 215 break; 216 } 217 218 if (code < 0 || code >= nsys) 219 callp += p->p_emul->e_nosys; /* illegal */ 220 else 221 callp += code; 222 223 argsize = callp->sy_argsize; 224 if (argsize) { 225 error = copyin(params, (caddr_t)args, argsize); 226 if (error) 227 goto bad; 228 } 229 230#ifdef SYSCALL_DEBUG 231 scdebug_call(l, code, args); 232#endif 233 234 rval[0] = 0; 235 rval[1] = frame->f_regs[D1]; 236 error = (*callp->sy_call)(l, args, rval); 237 238 switch (error) { 239 case 0: 240 /* 241 * Reinitialize proc pointer `p' as it may be different 242 * if this is a child returning from fork syscall. 243 */ 244 p = curproc; 245 frame->f_regs[D0] = rval[0]; 246 frame->f_regs[D1] = rval[1]; 247 frame->f_sr &= ~PSL_C; /* carry bit */ 248 break; 249 case ERESTART: 250 /* 251 * We always enter through a `trap' instruction, which is 2 252 * bytes, so adjust the pc by that amount. 253 */ 254 frame->f_pc = frame->f_pc - 2; 255 break; 256 case EJUSTRETURN: 257 /* nothing to do */ 258 break; 259 default: 260 bad: 261 frame->f_regs[D0] = error; 262 frame->f_sr |= PSL_C; /* carry bit */ 263 break; 264 } 265 266 /* need new p-value for this */ 267 if (l->l_md.md_flags & MDL_STACKADJ) { 268 l->l_md.md_flags &= ~MDL_STACKADJ; 269 if (error == ERESTART) 270 frame->f_regs[SP] -= sizeof (int); 271 } 272 273#ifdef SYSCALL_DEBUG 274 scdebug_ret(p, code, error, rval) 275#endif 276} 277 278static void 279sunos_syscall_fancy(register_t code, struct lwp *l, struct frame *frame) 280{ 281 struct proc *p = l->l_proc; 282 caddr_t params; 283 const struct sysent *callp; 284 int error, nsys; 285 size_t argsize; 286 register_t args[16], rval[2]; 287 288 nsys = p->p_emul->e_nsysent; 289 callp = p->p_emul->e_sysent; 290 291 /* 292 * SunOS passes the syscall-number on the stack, whereas 293 * BSD passes it in D0. So, we have to get the real "code" 294 * from the stack, and clean up the stack, as SunOS glue 295 * code assumes the kernel pops the syscall argument the 296 * glue pushed on the stack. Sigh... 297 */ 298 code = fuword((caddr_t)frame->f_regs[SP]); 299 300 /* 301 * XXX 302 * Don't do this for sunos_sigreturn, as there's no stored pc 303 * on the stack to skip, the argument follows the syscall 304 * number without a gap. 305 */ 306 if (code != SUNOS_SYS_sigreturn) { 307 frame->f_regs[SP] += sizeof (int); 308 /* 309 * remember that we adjusted the SP, 310 * might have to undo this if the system call 311 * returns ERESTART. 312 */ 313 l->l_md.md_flags |= MDL_STACKADJ; 314 } else 315 l->l_md.md_flags &= ~MDL_STACKADJ; 316 317 params = (caddr_t)frame->f_regs[SP] + sizeof(int); 318 319 switch (code) { 320 case SUNOS_SYS_syscall: 321 /* 322 * Code is first argument, followed by actual args. 323 */ 324 code = fuword(params); 325 params += sizeof(int); 326 break; 327 default: 328 break; 329 } 330 331 if (code < 0 || code >= nsys) 332 callp += p->p_emul->e_nosys; /* illegal */ 333 else 334 callp += code; 335 336 argsize = callp->sy_argsize; 337 if (argsize) { 338 error = copyin(params, (caddr_t)args, argsize); 339 if (error) 340 goto bad; 341 } 342 343 if ((error = trace_enter(l, code, code, NULL, args, rval)) != 0) 344 goto bad; 345 346 rval[0] = 0; 347 rval[1] = frame->f_regs[D1]; 348 error = (*callp->sy_call)(l, args, rval); 349 350 switch (error) { 351 case 0: 352 /* 353 * Reinitialize proc pointer `p' as it may be different 354 * if this is a child returning from fork syscall. 355 */ 356 p = curproc; 357 frame->f_regs[D0] = rval[0]; 358 frame->f_regs[D1] = rval[1]; 359 frame->f_sr &= ~PSL_C; /* carry bit */ 360 break; 361 case ERESTART: 362 /* 363 * We always enter through a `trap' instruction, which is 2 364 * bytes, so adjust the pc by that amount. 365 */ 366 frame->f_pc = frame->f_pc - 2; 367 break; 368 case EJUSTRETURN: 369 /* nothing to do */ 370 break; 371 default: 372 bad: 373 frame->f_regs[D0] = error; 374 frame->f_sr |= PSL_C; /* carry bit */ 375 break; 376 } 377 378 /* need new p-value for this */ 379 if (l->l_md.md_flags & MDL_STACKADJ) { 380 l->l_md.md_flags &= ~MDL_STACKADJ; 381 if (error == ERESTART) 382 frame->f_regs[SP] -= sizeof (int); 383 } 384 385 trace_exit(l, code, args, rval, error); 386} 387