sunos_syscall.c revision 1.12
1/* $NetBSD: sunos_syscall.c,v 1.12 2006/03/07 03:32:05 thorpej 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.12 2006/03/07 03:32:05 thorpej Exp $"); 114 115#include "opt_syscall_debug.h" 116#include "opt_execfmt.h" 117 118#include <sys/param.h> 119#include <sys/systm.h> 120#include <sys/proc.h> 121#include <sys/acct.h> 122#include <sys/kernel.h> 123#include <sys/syscall.h> 124#include <sys/syslog.h> 125#include <sys/user.h> 126 127#include <machine/psl.h> 128#include <machine/cpu.h> 129#include <machine/reg.h> 130 131#include <uvm/uvm_extern.h> 132 133#include <compat/sunos/sunos_syscall.h> 134#include <compat/sunos/sunos_exec.h> 135 136void sunos_syscall_intern(struct proc *); 137static void sunos_syscall_plain(register_t, struct lwp *, struct frame *); 138static void sunos_syscall_fancy(register_t, struct lwp *, struct frame *); 139 140void 141sunos_syscall_intern(struct proc *p) 142{ 143 144 if (trace_is_enabled(p)) 145 p->p_md.md_syscall = sunos_syscall_fancy; 146 else 147 p->p_md.md_syscall = sunos_syscall_plain; 148} 149 150static void 151sunos_syscall_plain(register_t code, struct lwp *l, struct frame *frame) 152{ 153 struct proc *p = l->l_proc; 154 caddr_t params; 155 const struct sysent *callp; 156 int error, nsys; 157 size_t argsize; 158 register_t args[16], rval[2]; 159 160 nsys = p->p_emul->e_nsysent; 161 callp = p->p_emul->e_sysent; 162 163 /* 164 * SunOS passes the syscall-number on the stack, whereas 165 * BSD passes it in D0. So, we have to get the real "code" 166 * from the stack, and clean up the stack, as SunOS glue 167 * code assumes the kernel pops the syscall argument the 168 * glue pushed on the stack. Sigh... 169 */ 170 code = fuword((caddr_t)frame->f_regs[SP]); 171 172 /* 173 * XXX 174 * Don't do this for sunos_sigreturn, as there's no stored pc 175 * on the stack to skip, the argument follows the syscall 176 * number without a gap. 177 */ 178 if (code != SUNOS_SYS_sigreturn) { 179 frame->f_regs[SP] += sizeof (int); 180 /* 181 * remember that we adjusted the SP, 182 * might have to undo this if the system call 183 * returns ERESTART. 184 */ 185 l->l_md.md_flags |= MDL_STACKADJ; 186 } else 187 l->l_md.md_flags &= ~MDL_STACKADJ; 188 189 params = (caddr_t)frame->f_regs[SP] + sizeof(int); 190 191 switch (code) { 192 case SUNOS_SYS_syscall: 193 /* 194 * Code is first argument, followed by actual args. 195 */ 196 code = fuword(params); 197 params += sizeof(int); 198 break; 199 default: 200 break; 201 } 202 203 if (code < 0 || code >= nsys) 204 callp += p->p_emul->e_nosys; /* illegal */ 205 else 206 callp += code; 207 208 argsize = callp->sy_argsize; 209 if (argsize) { 210 error = copyin(params, (caddr_t)args, argsize); 211 if (error) 212 goto bad; 213 } 214 215#ifdef SYSCALL_DEBUG 216 scdebug_call(l, code, args); 217#endif 218 219 rval[0] = 0; 220 rval[1] = frame->f_regs[D1]; 221 error = (*callp->sy_call)(l, args, rval); 222 223 switch (error) { 224 case 0: 225 /* 226 * Reinitialize proc pointer `p' as it may be different 227 * if this is a child returning from fork syscall. 228 */ 229 p = curproc; 230 frame->f_regs[D0] = rval[0]; 231 frame->f_regs[D1] = rval[1]; 232 frame->f_sr &= ~PSL_C; /* carry bit */ 233 break; 234 case ERESTART: 235 /* 236 * We always enter through a `trap' instruction, which is 2 237 * bytes, so adjust the pc by that amount. 238 */ 239 frame->f_pc = frame->f_pc - 2; 240 break; 241 case EJUSTRETURN: 242 /* nothing to do */ 243 break; 244 default: 245 bad: 246 frame->f_regs[D0] = error; 247 frame->f_sr |= PSL_C; /* carry bit */ 248 break; 249 } 250 251 /* need new p-value for this */ 252 if (l->l_md.md_flags & MDL_STACKADJ) { 253 l->l_md.md_flags &= ~MDL_STACKADJ; 254 if (error == ERESTART) 255 frame->f_regs[SP] -= sizeof (int); 256 } 257 258#ifdef SYSCALL_DEBUG 259 scdebug_ret(p, code, error, rval) 260#endif 261} 262 263static void 264sunos_syscall_fancy(register_t code, struct lwp *l, struct frame *frame) 265{ 266 struct proc *p = l->l_proc; 267 caddr_t params; 268 const struct sysent *callp; 269 int error, nsys; 270 size_t argsize; 271 register_t args[16], rval[2]; 272 273 nsys = p->p_emul->e_nsysent; 274 callp = p->p_emul->e_sysent; 275 276 /* 277 * SunOS passes the syscall-number on the stack, whereas 278 * BSD passes it in D0. So, we have to get the real "code" 279 * from the stack, and clean up the stack, as SunOS glue 280 * code assumes the kernel pops the syscall argument the 281 * glue pushed on the stack. Sigh... 282 */ 283 code = fuword((caddr_t)frame->f_regs[SP]); 284 285 /* 286 * XXX 287 * Don't do this for sunos_sigreturn, as there's no stored pc 288 * on the stack to skip, the argument follows the syscall 289 * number without a gap. 290 */ 291 if (code != SUNOS_SYS_sigreturn) { 292 frame->f_regs[SP] += sizeof (int); 293 /* 294 * remember that we adjusted the SP, 295 * might have to undo this if the system call 296 * returns ERESTART. 297 */ 298 l->l_md.md_flags |= MDL_STACKADJ; 299 } else 300 l->l_md.md_flags &= ~MDL_STACKADJ; 301 302 params = (caddr_t)frame->f_regs[SP] + sizeof(int); 303 304 switch (code) { 305 case SUNOS_SYS_syscall: 306 /* 307 * Code is first argument, followed by actual args. 308 */ 309 code = fuword(params); 310 params += sizeof(int); 311 break; 312 default: 313 break; 314 } 315 316 if (code < 0 || code >= nsys) 317 callp += p->p_emul->e_nosys; /* illegal */ 318 else 319 callp += code; 320 321 argsize = callp->sy_argsize; 322 if (argsize) { 323 error = copyin(params, (caddr_t)args, argsize); 324 if (error) 325 goto bad; 326 } 327 328 if ((error = trace_enter(l, code, code, NULL, args)) != 0) 329 goto out; 330 331 rval[0] = 0; 332 rval[1] = frame->f_regs[D1]; 333 error = (*callp->sy_call)(l, args, rval); 334out: 335 switch (error) { 336 case 0: 337 /* 338 * Reinitialize proc pointer `p' as it may be different 339 * if this is a child returning from fork syscall. 340 */ 341 p = curproc; 342 frame->f_regs[D0] = rval[0]; 343 frame->f_regs[D1] = rval[1]; 344 frame->f_sr &= ~PSL_C; /* carry bit */ 345 break; 346 case ERESTART: 347 /* 348 * We always enter through a `trap' instruction, which is 2 349 * bytes, so adjust the pc by that amount. 350 */ 351 frame->f_pc = frame->f_pc - 2; 352 break; 353 case EJUSTRETURN: 354 /* nothing to do */ 355 break; 356 default: 357 bad: 358 frame->f_regs[D0] = error; 359 frame->f_sr |= PSL_C; /* carry bit */ 360 break; 361 } 362 363 /* need new p-value for this */ 364 if (l->l_md.md_flags & MDL_STACKADJ) { 365 l->l_md.md_flags &= ~MDL_STACKADJ; 366 if (error == ERESTART) 367 frame->f_regs[SP] -= sizeof (int); 368 } 369 370 trace_exit(l, code, args, rval, error); 371} 372