Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_netbsd.c revision 1.56
      1 /*	$NetBSD: netbsd32_netbsd.c,v 1.56 2001/02/07 15:22:39 mrg Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1998 Matthew R. Green
      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. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  */
     30 
     31 #if defined(_KERNEL) && !defined(_LKM)
     32 #include "opt_ddb.h"
     33 #include "opt_ktrace.h"
     34 #include "opt_ntp.h"
     35 #include "opt_compat_netbsd.h"
     36 #include "opt_compat_43.h"
     37 #include "opt_sysv.h"
     38 
     39 #include "fs_lfs.h"
     40 #include "fs_nfs.h"
     41 #endif
     42 
     43 /*
     44  * Though COMPAT_OLDSOCK is needed only for COMPAT_43, SunOS, Linux,
     45  * HP-UX, FreeBSD, Ultrix, OSF1, we define it unconditionally so that
     46  * this would be LKM-safe.
     47  */
     48 #define COMPAT_OLDSOCK /* used by <sys/socket.h> */
     49 
     50 #include <sys/param.h>
     51 #include <sys/systm.h>
     52 #include <sys/filedesc.h>
     53 #include <sys/kernel.h>
     54 #include <sys/ipc.h>
     55 #include <sys/msg.h>
     56 #define msg __msg /* Don't ask me! */
     57 #include <sys/sem.h>
     58 #include <sys/shm.h>
     59 #include <sys/malloc.h>
     60 #include <sys/mount.h>
     61 #include <sys/socket.h>
     62 #include <sys/sockio.h>
     63 #include <sys/socketvar.h>
     64 #include <sys/mbuf.h>
     65 #include <sys/stat.h>
     66 #include <sys/time.h>
     67 #include <sys/timex.h>
     68 #include <sys/signalvar.h>
     69 #include <sys/wait.h>
     70 #include <sys/ptrace.h>
     71 #include <sys/ktrace.h>
     72 #include <sys/trace.h>
     73 #include <sys/resourcevar.h>
     74 #include <sys/pool.h>
     75 #include <sys/vnode.h>
     76 #include <sys/file.h>
     77 #include <sys/filedesc.h>
     78 #include <sys/namei.h>
     79 
     80 #include <uvm/uvm_extern.h>
     81 
     82 #include <sys/syscallargs.h>
     83 #include <sys/proc.h>
     84 #include <sys/acct.h>
     85 #include <sys/exec.h>
     86 #define	__SYSCTL_PRIVATE
     87 #include <sys/sysctl.h>
     88 
     89 #include <net/if.h>
     90 
     91 #include <compat/netbsd32/netbsd32.h>
     92 #include <compat/netbsd32/netbsd32_syscall.h>
     93 #include <compat/netbsd32/netbsd32_syscallargs.h>
     94 #include <compat/netbsd32/netbsd32_conv.h>
     95 
     96 #include <machine/frame.h>
     97 
     98 #if defined(DDB)
     99 #include <ddb/ddbvar.h>
    100 #endif
    101 
    102 /* this is provided by kern/kern_exec.c */
    103 extern int exec_maxhdrsz;
    104 extern struct lock exec_lock;
    105 
    106 
    107 /* note that the netbsd32_msghdr's iov really points to a struct iovec, not a netbsd32_iovec. */
    108 static int recvit32 __P((struct proc *, int, struct netbsd32_msghdr *, struct iovec *, caddr_t,
    109 			 register_t *));
    110 static int dofilereadv32 __P((struct proc *, int, struct file *, struct netbsd32_iovec *,
    111 			      int, off_t *, int, register_t *));
    112 static int dofilewritev32 __P((struct proc *, int, struct file *, struct netbsd32_iovec *,
    113 			       int,  off_t *, int, register_t *));
    114 static int change_utimes32 __P((struct vnode *, netbsd32_timevalp_t, struct proc *));
    115 
    116 extern char netbsd32_sigcode[], netbsd32_esigcode[];
    117 extern struct sysent netbsd32_sysent[];
    118 #ifdef SYSCALL_DEBUG
    119 extern const char * const netbsd32_syscallnames[];
    120 #endif
    121 #ifdef __HAVE_SYSCALL_INTERN
    122 void syscall_intern __P((struct proc *));
    123 #else
    124 void syscall __P((void));
    125 #endif
    126 
    127 const struct emul emul_netbsd32 = {
    128 	"netbsd32",
    129 	"/emul/netbsd32",
    130 #ifndef __HAVE_MINIMAL_EMUL
    131 	0,
    132 	NULL,
    133 	netbsd32_SYS_syscall,
    134 	netbsd32_SYS_MAXSYSCALL,
    135 #endif
    136 	netbsd32_sysent,
    137 #ifdef SYSCALL_DEBUG
    138 	netbsd32_syscallnames,
    139 #else
    140 	NULL,
    141 #endif
    142 	netbsd32_sendsig,
    143 	netbsd32_sigcode,
    144 	netbsd32_esigcode,
    145 	NULL,
    146 	NULL,
    147 	NULL,
    148 #ifdef __HAVE_SYSCALL_INTERN
    149 	syscall_intern,
    150 #else
    151 	syscall,
    152 #endif
    153 };
    154 
    155 /*
    156  * below are all the standard NetBSD system calls, in the 32bit
    157  * environment, with the necessary conversions to 64bit before
    158  * calling the real syscall, unless we need to inline the whole
    159  * syscall here, sigh.
    160  */
    161 
    162 int
    163 netbsd32_exit(p, v, retval)
    164 	struct proc *p;
    165 	void *v;
    166 	register_t *retval;
    167 {
    168 	struct netbsd32_exit_args /* {
    169 		syscallarg(int) rval;
    170 	} */ *uap = v;
    171 	struct sys_exit_args ua;
    172 
    173 	NETBSD32TO64_UAP(rval);
    174 	return sys_exit(p, &ua, retval);
    175 }
    176 
    177 int
    178 netbsd32_read(p, v, retval)
    179 	struct proc *p;
    180 	void *v;
    181 	register_t *retval;
    182 {
    183 	struct netbsd32_read_args /* {
    184 		syscallarg(int) fd;
    185 		syscallarg(netbsd32_voidp) buf;
    186 		syscallarg(netbsd32_size_t) nbyte;
    187 	} */ *uap = v;
    188 	struct sys_read_args ua;
    189 
    190 	NETBSD32TO64_UAP(fd);
    191 	NETBSD32TOP_UAP(buf, void *);
    192 	NETBSD32TOX_UAP(nbyte, size_t);
    193 	return sys_read(p, &ua, retval);
    194 }
    195 
    196 int
    197 netbsd32_write(p, v, retval)
    198 	struct proc *p;
    199 	void *v;
    200 	register_t *retval;
    201 {
    202 	struct netbsd32_write_args /* {
    203 		syscallarg(int) fd;
    204 		syscallarg(const netbsd32_voidp) buf;
    205 		syscallarg(netbsd32_size_t) nbyte;
    206 	} */ *uap = v;
    207 	struct sys_write_args ua;
    208 
    209 	NETBSD32TO64_UAP(fd);
    210 	NETBSD32TOP_UAP(buf, void *);
    211 	NETBSD32TOX_UAP(nbyte, size_t);
    212 	return sys_write(p, &ua, retval);
    213 }
    214 
    215 int
    216 netbsd32_close(p, v, retval)
    217 	struct proc *p;
    218 	void *v;
    219 	register_t *retval;
    220 {
    221 	struct netbsd32_close_args /* {
    222 		syscallarg(int) fd;
    223 	} */ *uap = v;
    224 	struct sys_close_args ua;
    225 
    226 	NETBSD32TO64_UAP(fd);
    227 	return sys_close(p, &ua, retval);
    228 }
    229 
    230 int
    231 netbsd32_open(p, v, retval)
    232 	struct proc *p;
    233 	void *v;
    234 	register_t *retval;
    235 {
    236 	struct netbsd32_open_args /* {
    237 		syscallarg(const netbsd32_charp) path;
    238 		syscallarg(int) flags;
    239 		syscallarg(mode_t) mode;
    240 	} */ *uap = v;
    241 	struct sys_open_args ua;
    242 	caddr_t sg;
    243 
    244 	NETBSD32TOP_UAP(path, const char);
    245 	NETBSD32TO64_UAP(flags);
    246 	NETBSD32TO64_UAP(mode);
    247 	sg = stackgap_init(p->p_emul);
    248 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
    249 
    250 	return (sys_open(p, &ua, retval));
    251 }
    252 
    253 /* XXX MOVE ME XXX */
    254 int
    255 netbsd32_wait4(q, v, retval)
    256 	struct proc *q;
    257 	void *v;
    258 	register_t *retval;
    259 {
    260 	struct netbsd32_wait4_args /* {
    261 		syscallarg(int) pid;
    262 		syscallarg(netbsd32_intp) status;
    263 		syscallarg(int) options;
    264 		syscallarg(netbsd32_rusagep_t) rusage;
    265 	} */ *uap = v;
    266 	struct netbsd32_rusage ru32;
    267 	int nfound;
    268 	struct proc *p, *t;
    269 	int status, error;
    270 
    271 	if (SCARG(uap, pid) == 0)
    272 		SCARG(uap, pid) = -q->p_pgid;
    273 	if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG))
    274 		return (EINVAL);
    275 
    276 loop:
    277 	nfound = 0;
    278 	for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
    279 		if (SCARG(uap, pid) != WAIT_ANY &&
    280 		    p->p_pid != SCARG(uap, pid) &&
    281 		    p->p_pgid != -SCARG(uap, pid))
    282 			continue;
    283 		nfound++;
    284 		if (p->p_stat == SZOMB) {
    285 			retval[0] = p->p_pid;
    286 
    287 			if (SCARG(uap, status)) {
    288 				status = p->p_xstat;	/* convert to int */
    289 				error = copyout((caddr_t)&status,
    290 						(caddr_t)(u_long)SCARG(uap, status),
    291 						sizeof(status));
    292 				if (error)
    293 					return (error);
    294 			}
    295 			if (SCARG(uap, rusage)) {
    296 				netbsd32_from_rusage(p->p_ru, &ru32);
    297 				if ((error = copyout((caddr_t)&ru32,
    298 						     (caddr_t)(u_long)SCARG(uap, rusage),
    299 						     sizeof(struct netbsd32_rusage))))
    300 					return (error);
    301 			}
    302 			/*
    303 			 * If we got the child via ptrace(2) or procfs, and
    304 			 * the parent is different (meaning the process was
    305 			 * attached, rather than run as a child), then we need
    306 			 * to give it back to the old parent, and send the
    307 			 * parent a SIGCHLD.  The rest of the cleanup will be
    308 			 * done when the old parent waits on the child.
    309 			 */
    310 			if ((p->p_flag & P_TRACED) &&
    311 			    p->p_oppid != p->p_pptr->p_pid) {
    312 				t = pfind(p->p_oppid);
    313 				proc_reparent(p, t ? t : initproc);
    314 				p->p_oppid = 0;
    315 				p->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE);
    316 				psignal(p->p_pptr, SIGCHLD);
    317 				wakeup((caddr_t)p->p_pptr);
    318 				return (0);
    319 			}
    320 			p->p_xstat = 0;
    321 			ruadd(&q->p_stats->p_cru, p->p_ru);
    322 			pool_put(&rusage_pool, p->p_ru);
    323 
    324 			/*
    325 			 * Finally finished with old proc entry.
    326 			 * Unlink it from its process group and free it.
    327 			 */
    328 			leavepgrp(p);
    329 
    330 			LIST_REMOVE(p, p_list);	/* off zombproc */
    331 
    332 			LIST_REMOVE(p, p_sibling);
    333 
    334 			/*
    335 			 * Decrement the count of procs running with this uid.
    336 			 */
    337 			(void)chgproccnt(p->p_cred->p_ruid, -1);
    338 
    339 			/*
    340 			 * Free up credentials.
    341 			 */
    342 			if (--p->p_cred->p_refcnt == 0) {
    343 				crfree(p->p_cred->pc_ucred);
    344 				pool_put(&pcred_pool, p->p_cred);
    345 			}
    346 
    347 			/*
    348 			 * Release reference to text vnode
    349 			 */
    350 			if (p->p_textvp)
    351 				vrele(p->p_textvp);
    352 
    353 			pool_put(&proc_pool, p);
    354 			nprocs--;
    355 			return (0);
    356 		}
    357 		if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
    358 		    (p->p_flag & P_TRACED || SCARG(uap, options) & WUNTRACED)) {
    359 			p->p_flag |= P_WAITED;
    360 			retval[0] = p->p_pid;
    361 
    362 			if (SCARG(uap, status)) {
    363 				status = W_STOPCODE(p->p_xstat);
    364 				error = copyout((caddr_t)&status,
    365 				    (caddr_t)(u_long)SCARG(uap, status),
    366 				    sizeof(status));
    367 			} else
    368 				error = 0;
    369 			return (error);
    370 		}
    371 	}
    372 	if (nfound == 0)
    373 		return (ECHILD);
    374 	if (SCARG(uap, options) & WNOHANG) {
    375 		retval[0] = 0;
    376 		return (0);
    377 	}
    378 	if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) != 0)
    379 		return (error);
    380 	goto loop;
    381 }
    382 
    383 int
    384 netbsd32_link(p, v, retval)
    385 	struct proc *p;
    386 	void *v;
    387 	register_t *retval;
    388 {
    389 	struct netbsd32_link_args /* {
    390 		syscallarg(const netbsd32_charp) path;
    391 		syscallarg(const netbsd32_charp) link;
    392 	} */ *uap = v;
    393 	struct sys_link_args ua;
    394 
    395 	NETBSD32TOP_UAP(path, const char);
    396 	NETBSD32TOP_UAP(link, const char);
    397 	return (sys_link(p, &ua, retval));
    398 }
    399 
    400 int
    401 netbsd32_unlink(p, v, retval)
    402 	struct proc *p;
    403 	void *v;
    404 	register_t *retval;
    405 {
    406 	struct netbsd32_unlink_args /* {
    407 		syscallarg(const netbsd32_charp) path;
    408 	} */ *uap = v;
    409 	struct sys_unlink_args ua;
    410 
    411 	NETBSD32TOP_UAP(path, const char);
    412 
    413 	return (sys_unlink(p, &ua, retval));
    414 }
    415 
    416 int
    417 netbsd32_chdir(p, v, retval)
    418 	struct proc *p;
    419 	void *v;
    420 	register_t *retval;
    421 {
    422 	struct netbsd32_chdir_args /* {
    423 		syscallarg(const netbsd32_charp) path;
    424 	} */ *uap = v;
    425 	struct sys_chdir_args ua;
    426 
    427 	NETBSD32TOP_UAP(path, const char);
    428 
    429 	return (sys_chdir(p, &ua, retval));
    430 }
    431 
    432 int
    433 netbsd32_fchdir(p, v, retval)
    434 	struct proc *p;
    435 	void *v;
    436 	register_t *retval;
    437 {
    438 	struct netbsd32_fchdir_args /* {
    439 		syscallarg(int) fd;
    440 	} */ *uap = v;
    441 	struct sys_fchdir_args ua;
    442 
    443 	NETBSD32TO64_UAP(fd);
    444 
    445 	return (sys_fchdir(p, &ua, retval));
    446 }
    447 
    448 int
    449 netbsd32_mknod(p, v, retval)
    450 	struct proc *p;
    451 	void *v;
    452 	register_t *retval;
    453 {
    454 	struct netbsd32_mknod_args /* {
    455 		syscallarg(const netbsd32_charp) path;
    456 		syscallarg(mode_t) mode;
    457 		syscallarg(dev_t) dev;
    458 	} */ *uap = v;
    459 	struct sys_mknod_args ua;
    460 
    461 	NETBSD32TOP_UAP(path, const char);
    462 	NETBSD32TO64_UAP(dev);
    463 	NETBSD32TO64_UAP(mode);
    464 
    465 	return (sys_mknod(p, &ua, retval));
    466 }
    467 
    468 int
    469 netbsd32_chmod(p, v, retval)
    470 	struct proc *p;
    471 	void *v;
    472 	register_t *retval;
    473 {
    474 	struct netbsd32_chmod_args /* {
    475 		syscallarg(const netbsd32_charp) path;
    476 		syscallarg(mode_t) mode;
    477 	} */ *uap = v;
    478 	struct sys_chmod_args ua;
    479 
    480 	NETBSD32TOP_UAP(path, const char);
    481 	NETBSD32TO64_UAP(mode);
    482 
    483 	return (sys_chmod(p, &ua, retval));
    484 }
    485 
    486 int
    487 netbsd32_chown(p, v, retval)
    488 	struct proc *p;
    489 	void *v;
    490 	register_t *retval;
    491 {
    492 	struct netbsd32_chown_args /* {
    493 		syscallarg(const netbsd32_charp) path;
    494 		syscallarg(uid_t) uid;
    495 		syscallarg(gid_t) gid;
    496 	} */ *uap = v;
    497 	struct sys_chown_args ua;
    498 
    499 	NETBSD32TOP_UAP(path, const char);
    500 	NETBSD32TO64_UAP(uid);
    501 	NETBSD32TO64_UAP(gid);
    502 
    503 	return (sys_chown(p, &ua, retval));
    504 }
    505 
    506 int
    507 netbsd32_break(p, v, retval)
    508 	struct proc *p;
    509 	void *v;
    510 	register_t *retval;
    511 {
    512 	struct netbsd32_break_args /* {
    513 		syscallarg(netbsd32_charp) nsize;
    514 	} */ *uap = v;
    515 	struct sys_obreak_args ua;
    516 
    517 	SCARG(&ua, nsize) = (char *)(u_long)SCARG(uap, nsize);
    518 	NETBSD32TOP_UAP(nsize, char);
    519 	return (sys_obreak(p, &ua, retval));
    520 }
    521 
    522 /* XXX MOVE ME XXX */
    523 int
    524 netbsd32_getfsstat(p, v, retval)
    525 	struct proc *p;
    526 	void *v;
    527 	register_t *retval;
    528 {
    529 	struct netbsd32_getfsstat_args /* {
    530 		syscallarg(netbsd32_statfsp_t) buf;
    531 		syscallarg(netbsd32_long) bufsize;
    532 		syscallarg(int) flags;
    533 	} */ *uap = v;
    534 	struct mount *mp, *nmp;
    535 	struct statfs *sp;
    536 	struct netbsd32_statfs sb32;
    537 	caddr_t sfsp;
    538 	long count, maxcount, error;
    539 
    540 	maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs);
    541 	sfsp = (caddr_t)(u_long)SCARG(uap, buf);
    542 	simple_lock(&mountlist_slock);
    543 	count = 0;
    544 	for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
    545 		if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock)) {
    546 			nmp = mp->mnt_list.cqe_next;
    547 			continue;
    548 		}
    549 		if (sfsp && count < maxcount) {
    550 			sp = &mp->mnt_stat;
    551 			/*
    552 			 * If MNT_NOWAIT or MNT_LAZY is specified, do not
    553 			 * refresh the fsstat cache. MNT_WAIT or MNT_LAXY
    554 			 * overrides MNT_NOWAIT.
    555 			 */
    556 			if (SCARG(uap, flags) != MNT_NOWAIT &&
    557 			    SCARG(uap, flags) != MNT_LAZY &&
    558 			    (SCARG(uap, flags) == MNT_WAIT ||
    559 			     SCARG(uap, flags) == 0) &&
    560 			    (error = VFS_STATFS(mp, sp, p)) != 0) {
    561 				simple_lock(&mountlist_slock);
    562 				nmp = mp->mnt_list.cqe_next;
    563 				vfs_unbusy(mp);
    564 				continue;
    565 			}
    566 			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
    567 			sp->f_oflags = sp->f_flags & 0xffff;
    568 			netbsd32_from_statfs(sp, &sb32);
    569 			error = copyout(&sb32, sfsp, sizeof(sb32));
    570 			if (error) {
    571 				vfs_unbusy(mp);
    572 				return (error);
    573 			}
    574 			sfsp += sizeof(sb32);
    575 		}
    576 		count++;
    577 		simple_lock(&mountlist_slock);
    578 		nmp = mp->mnt_list.cqe_next;
    579 		vfs_unbusy(mp);
    580 	}
    581 	simple_unlock(&mountlist_slock);
    582 	if (sfsp && count > maxcount)
    583 		*retval = maxcount;
    584 	else
    585 		*retval = count;
    586 	return (0);
    587 }
    588 
    589 int
    590 netbsd32_mount(p, v, retval)
    591 	struct proc *p;
    592 	void *v;
    593 	register_t *retval;
    594 {
    595 	struct netbsd32_mount_args /* {
    596 		syscallarg(const netbsd32_charp) type;
    597 		syscallarg(const netbsd32_charp) path;
    598 		syscallarg(int) flags;
    599 		syscallarg(netbsd32_voidp) data;
    600 	} */ *uap = v;
    601 	struct sys_mount_args ua;
    602 
    603 	NETBSD32TOP_UAP(type, const char);
    604 	NETBSD32TOP_UAP(path, const char);
    605 	NETBSD32TO64_UAP(flags);
    606 	NETBSD32TOP_UAP(data, void);
    607 	return (sys_mount(p, &ua, retval));
    608 }
    609 
    610 int
    611 netbsd32_unmount(p, v, retval)
    612 	struct proc *p;
    613 	void *v;
    614 	register_t *retval;
    615 {
    616 	struct netbsd32_unmount_args /* {
    617 		syscallarg(const netbsd32_charp) path;
    618 		syscallarg(int) flags;
    619 	} */ *uap = v;
    620 	struct sys_unmount_args ua;
    621 
    622 	NETBSD32TOP_UAP(path, const char);
    623 	NETBSD32TO64_UAP(flags);
    624 	return (sys_unmount(p, &ua, retval));
    625 }
    626 
    627 int
    628 netbsd32_setuid(p, v, retval)
    629 	struct proc *p;
    630 	void *v;
    631 	register_t *retval;
    632 {
    633 	struct netbsd32_setuid_args /* {
    634 		syscallarg(uid_t) uid;
    635 	} */ *uap = v;
    636 	struct sys_setuid_args ua;
    637 
    638 	NETBSD32TO64_UAP(uid);
    639 	return (sys_setuid(p, &ua, retval));
    640 }
    641 
    642 int
    643 netbsd32_ptrace(p, v, retval)
    644 	struct proc *p;
    645 	void *v;
    646 	register_t *retval;
    647 {
    648 	struct netbsd32_ptrace_args /* {
    649 		syscallarg(int) req;
    650 		syscallarg(pid_t) pid;
    651 		syscallarg(netbsd32_caddr_t) addr;
    652 		syscallarg(int) data;
    653 	} */ *uap = v;
    654 	struct sys_ptrace_args ua;
    655 
    656 	NETBSD32TO64_UAP(req);
    657 	NETBSD32TO64_UAP(pid);
    658 	NETBSD32TOX64_UAP(addr, caddr_t);
    659 	NETBSD32TO64_UAP(data);
    660 	return (sys_ptrace(p, &ua, retval));
    661 }
    662 
    663 /* XXX MOVE ME XXX */
    664 int
    665 netbsd32_recvmsg(p, v, retval)
    666 	struct proc *p;
    667 	void *v;
    668 	register_t *retval;
    669 {
    670 	struct netbsd32_recvmsg_args /* {
    671 		syscallarg(int) s;
    672 		syscallarg(netbsd32_msghdrp_t) msg;
    673 		syscallarg(int) flags;
    674 	} */ *uap = v;
    675 	struct netbsd32_msghdr msg;
    676 	struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
    677 	int error;
    678 
    679 	error = copyin((caddr_t)(u_long)SCARG(uap, msg), (caddr_t)&msg,
    680 		       sizeof(msg));
    681 		/* netbsd32_msghdr needs the iov pre-allocated */
    682 	if (error)
    683 		return (error);
    684 	if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
    685 		if ((u_int)msg.msg_iovlen > IOV_MAX)
    686 			return (EMSGSIZE);
    687 		MALLOC(iov, struct iovec *,
    688 		       sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
    689 		       M_WAITOK);
    690 	} else if ((u_int)msg.msg_iovlen > 0)
    691 		iov = aiov;
    692 	else
    693 		return (EMSGSIZE);
    694 #ifdef COMPAT_OLDSOCK
    695 	msg.msg_flags = SCARG(uap, flags) &~ MSG_COMPAT;
    696 #else
    697 	msg.msg_flags = SCARG(uap, flags);
    698 #endif
    699 	uiov = (struct iovec *)(u_long)msg.msg_iov;
    700 	error = netbsd32_to_iovecin((struct netbsd32_iovec *)uiov,
    701 				   iov, msg.msg_iovlen);
    702 	if (error)
    703 		goto done;
    704 	if ((error = recvit32(p, SCARG(uap, s), &msg, iov, (caddr_t)0, retval)) == 0) {
    705 		error = copyout((caddr_t)&msg, (caddr_t)(u_long)SCARG(uap, msg),
    706 		    sizeof(msg));
    707 	}
    708 done:
    709 	if (iov != aiov)
    710 		FREE(iov, M_IOV);
    711 	return (error);
    712 }
    713 
    714 /* XXX MOVE ME XXX */
    715 int
    716 recvit32(p, s, mp, iov, namelenp, retsize)
    717 	struct proc *p;
    718 	int s;
    719 	struct netbsd32_msghdr *mp;
    720 	struct iovec *iov;
    721 	caddr_t namelenp;
    722 	register_t *retsize;
    723 {
    724 	struct file *fp;
    725 	struct uio auio;
    726 	int i;
    727 	int len, error;
    728 	struct mbuf *from = 0, *control = 0;
    729 	struct socket *so;
    730 #ifdef KTRACE
    731 	struct iovec *ktriov = NULL;
    732 #endif
    733 
    734 	/* getsock() will use the descriptor for us */
    735 	if ((error = getsock(p->p_fd, s, &fp)) != 0)
    736 		return (error);
    737 	auio.uio_iov = iov;
    738 	auio.uio_iovcnt = mp->msg_iovlen;
    739 	auio.uio_segflg = UIO_USERSPACE;
    740 	auio.uio_rw = UIO_READ;
    741 	auio.uio_procp = p;
    742 	auio.uio_offset = 0;			/* XXX */
    743 	auio.uio_resid = 0;
    744 	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
    745 #if 0
    746 		/* cannot happen iov_len is unsigned */
    747 		if (iov->iov_len < 0) {
    748 			error = EINVAL;
    749 			goto out1;
    750 		}
    751 #endif
    752 		/*
    753 		 * Reads return ssize_t because -1 is returned on error.
    754 		 * Therefore we must restrict the length to SSIZE_MAX to
    755 		 * avoid garbage return values.
    756 		 */
    757 		auio.uio_resid += iov->iov_len;
    758 		if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
    759 			error = EINVAL;
    760 			goto out1;
    761 		}
    762 	}
    763 #ifdef KTRACE
    764 	if (KTRPOINT(p, KTR_GENIO)) {
    765 		int iovlen = auio.uio_iovcnt * sizeof(struct iovec);
    766 
    767 		MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
    768 		memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
    769 	}
    770 #endif
    771 	len = auio.uio_resid;
    772 	so = (struct socket *)fp->f_data;
    773 	error = (*so->so_receive)(so, &from, &auio, NULL,
    774 			  mp->msg_control ? &control : NULL, &mp->msg_flags);
    775 	if (error) {
    776 		if (auio.uio_resid != len && (error == ERESTART ||
    777 		    error == EINTR || error == EWOULDBLOCK))
    778 			error = 0;
    779 	}
    780 #ifdef KTRACE
    781 	if (ktriov != NULL) {
    782 		if (error == 0)
    783 			ktrgenio(p, s, UIO_READ, ktriov,
    784 			    len - auio.uio_resid, error);
    785 		FREE(ktriov, M_TEMP);
    786 	}
    787 #endif
    788 	if (error)
    789 		goto out;
    790 	*retsize = len - auio.uio_resid;
    791 	if (mp->msg_name) {
    792 		len = mp->msg_namelen;
    793 		if (len <= 0 || from == 0)
    794 			len = 0;
    795 		else {
    796 #ifdef COMPAT_OLDSOCK
    797 			if (mp->msg_flags & MSG_COMPAT)
    798 				mtod(from, struct osockaddr *)->sa_family =
    799 				    mtod(from, struct sockaddr *)->sa_family;
    800 #endif
    801 			if (len > from->m_len)
    802 				len = from->m_len;
    803 			/* else if len < from->m_len ??? */
    804 			error = copyout(mtod(from, caddr_t),
    805 					(caddr_t)(u_long)mp->msg_name, (unsigned)len);
    806 			if (error)
    807 				goto out;
    808 		}
    809 		mp->msg_namelen = len;
    810 		if (namelenp &&
    811 		    (error = copyout((caddr_t)&len, namelenp, sizeof(int)))) {
    812 #ifdef COMPAT_OLDSOCK
    813 			if (mp->msg_flags & MSG_COMPAT)
    814 				error = 0;	/* old recvfrom didn't check */
    815 			else
    816 #endif
    817 			goto out;
    818 		}
    819 	}
    820 	if (mp->msg_control) {
    821 #ifdef COMPAT_OLDSOCK
    822 		/*
    823 		 * We assume that old recvmsg calls won't receive access
    824 		 * rights and other control info, esp. as control info
    825 		 * is always optional and those options didn't exist in 4.3.
    826 		 * If we receive rights, trim the cmsghdr; anything else
    827 		 * is tossed.
    828 		 */
    829 		if (control && mp->msg_flags & MSG_COMPAT) {
    830 			if (mtod(control, struct cmsghdr *)->cmsg_level !=
    831 			    SOL_SOCKET ||
    832 			    mtod(control, struct cmsghdr *)->cmsg_type !=
    833 			    SCM_RIGHTS) {
    834 				mp->msg_controllen = 0;
    835 				goto out;
    836 			}
    837 			control->m_len -= sizeof(struct cmsghdr);
    838 			control->m_data += sizeof(struct cmsghdr);
    839 		}
    840 #endif
    841 		len = mp->msg_controllen;
    842 		if (len <= 0 || control == 0)
    843 			len = 0;
    844 		else {
    845 			struct mbuf *m = control;
    846 			caddr_t p = (caddr_t)(u_long)mp->msg_control;
    847 
    848 			do {
    849 				i = m->m_len;
    850 				if (len < i) {
    851 					mp->msg_flags |= MSG_CTRUNC;
    852 					i = len;
    853 				}
    854 				error = copyout(mtod(m, caddr_t), p,
    855 				    (unsigned)i);
    856 				if (m->m_next)
    857 					i = ALIGN(i);
    858 				p += i;
    859 				len -= i;
    860 				if (error != 0 || len <= 0)
    861 					break;
    862 			} while ((m = m->m_next) != NULL);
    863 			len = p - (caddr_t)(u_long)mp->msg_control;
    864 		}
    865 		mp->msg_controllen = len;
    866 	}
    867  out:
    868 	if (from)
    869 		m_freem(from);
    870 	if (control)
    871 		m_freem(control);
    872  out1:
    873 	FILE_UNUSE(fp, p);
    874 	return (error);
    875 }
    876 
    877 /* XXX MOVE ME XXX */
    878 int
    879 netbsd32_sendmsg(p, v, retval)
    880 	struct proc *p;
    881 	void *v;
    882 	register_t *retval;
    883 {
    884 	struct netbsd32_sendmsg_args /* {
    885 		syscallarg(int) s;
    886 		syscallarg(const netbsd32_msghdrp_t) msg;
    887 		syscallarg(int) flags;
    888 	} */ *uap = v;
    889 	struct msghdr msg;
    890 	struct netbsd32_msghdr msg32;
    891 	struct iovec aiov[UIO_SMALLIOV], *iov;
    892 	int error;
    893 
    894 	error = copyin((caddr_t)(u_long)SCARG(uap, msg),
    895 		       (caddr_t)&msg32, sizeof(msg32));
    896 	if (error)
    897 		return (error);
    898 	netbsd32_to_msghdr(&msg32, &msg);
    899 	if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
    900 		if ((u_int)msg.msg_iovlen > IOV_MAX)
    901 			return (EMSGSIZE);
    902 		MALLOC(iov, struct iovec *,
    903 		       sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
    904 		       M_WAITOK);
    905 	} else if ((u_int)msg.msg_iovlen > 0)
    906 		iov = aiov;
    907 	else
    908 		return (EMSGSIZE);
    909 	error = netbsd32_to_iovecin((struct netbsd32_iovec *)msg.msg_iov,
    910 				   iov, msg.msg_iovlen);
    911 	if (error)
    912 		goto done;
    913 	msg.msg_iov = iov;
    914 #ifdef COMPAT_OLDSOCK
    915 	msg.msg_flags = 0;
    916 #endif
    917 	/* Luckily we can use this directly */
    918 	error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
    919 done:
    920 	if (iov != aiov)
    921 		FREE(iov, M_IOV);
    922 	return (error);
    923 }
    924 
    925 /* XXX MOVE ME XXX */
    926 int
    927 netbsd32_recvfrom(p, v, retval)
    928 	struct proc *p;
    929 	void *v;
    930 	register_t *retval;
    931 {
    932 	struct netbsd32_recvfrom_args /* {
    933 		syscallarg(int) s;
    934 		syscallarg(netbsd32_voidp) buf;
    935 		syscallarg(netbsd32_size_t) len;
    936 		syscallarg(int) flags;
    937 		syscallarg(netbsd32_sockaddrp_t) from;
    938 		syscallarg(netbsd32_intp) fromlenaddr;
    939 	} */ *uap = v;
    940 	struct netbsd32_msghdr msg;
    941 	struct iovec aiov;
    942 	int error;
    943 
    944 	if (SCARG(uap, fromlenaddr)) {
    945 		error = copyin((caddr_t)(u_long)SCARG(uap, fromlenaddr),
    946 			       (caddr_t)&msg.msg_namelen,
    947 			       sizeof(msg.msg_namelen));
    948 		if (error)
    949 			return (error);
    950 	} else
    951 		msg.msg_namelen = 0;
    952 	msg.msg_name = SCARG(uap, from);
    953 	msg.msg_iov = NULL; /* ignored in recvit32(), uses iov */
    954 	msg.msg_iovlen = 1;
    955 	aiov.iov_base = (caddr_t)(u_long)SCARG(uap, buf);
    956 	aiov.iov_len = (u_long)SCARG(uap, len);
    957 	msg.msg_control = 0;
    958 	msg.msg_flags = SCARG(uap, flags);
    959 	return (recvit32(p, SCARG(uap, s), &msg, &aiov,
    960 		       (caddr_t)(u_long)SCARG(uap, fromlenaddr), retval));
    961 }
    962 
    963 /* XXX MOVE ME XXX */
    964 int
    965 netbsd32_sendto(p, v, retval)
    966 	struct proc *p;
    967 	void *v;
    968 	register_t *retval;
    969 {
    970 	struct netbsd32_sendto_args /* {
    971 		syscallarg(int) s;
    972 		syscallarg(const netbsd32_voidp) buf;
    973 		syscallarg(netbsd32_size_t) len;
    974 		syscallarg(int) flags;
    975 		syscallarg(const netbsd32_sockaddrp_t) to;
    976 		syscallarg(int) tolen;
    977 	} */ *uap = v;
    978 	struct msghdr msg;
    979 	struct iovec aiov;
    980 
    981 	msg.msg_name = (caddr_t)(u_long)SCARG(uap, to);		/* XXX kills const */
    982 	msg.msg_namelen = SCARG(uap, tolen);
    983 	msg.msg_iov = &aiov;
    984 	msg.msg_iovlen = 1;
    985 	msg.msg_control = 0;
    986 #ifdef COMPAT_OLDSOCK
    987 	msg.msg_flags = 0;
    988 #endif
    989 	aiov.iov_base = (char *)(u_long)SCARG(uap, buf);	/* XXX kills const */
    990 	aiov.iov_len = SCARG(uap, len);
    991 	return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
    992 }
    993 
    994 int
    995 netbsd32_accept(p, v, retval)
    996 	struct proc *p;
    997 	void *v;
    998 	register_t *retval;
    999 {
   1000 	struct netbsd32_accept_args /* {
   1001 		syscallarg(int) s;
   1002 		syscallarg(netbsd32_sockaddrp_t) name;
   1003 		syscallarg(netbsd32_intp) anamelen;
   1004 	} */ *uap = v;
   1005 	struct sys_accept_args ua;
   1006 
   1007 	NETBSD32TO64_UAP(s);
   1008 	NETBSD32TOP_UAP(name, struct sockaddr);
   1009 	NETBSD32TOP_UAP(anamelen, int);
   1010 	return (sys_accept(p, &ua, retval));
   1011 }
   1012 
   1013 int
   1014 netbsd32_getpeername(p, v, retval)
   1015 	struct proc *p;
   1016 	void *v;
   1017 	register_t *retval;
   1018 {
   1019 	struct netbsd32_getpeername_args /* {
   1020 		syscallarg(int) fdes;
   1021 		syscallarg(netbsd32_sockaddrp_t) asa;
   1022 		syscallarg(netbsd32_intp) alen;
   1023 	} */ *uap = v;
   1024 	struct sys_getpeername_args ua;
   1025 
   1026 	NETBSD32TO64_UAP(fdes);
   1027 	NETBSD32TOP_UAP(asa, struct sockaddr);
   1028 	NETBSD32TOP_UAP(alen, int);
   1029 /* NB: do the protocol specific sockaddrs need to be converted? */
   1030 	return (sys_getpeername(p, &ua, retval));
   1031 }
   1032 
   1033 int
   1034 netbsd32_getsockname(p, v, retval)
   1035 	struct proc *p;
   1036 	void *v;
   1037 	register_t *retval;
   1038 {
   1039 	struct netbsd32_getsockname_args /* {
   1040 		syscallarg(int) fdes;
   1041 		syscallarg(netbsd32_sockaddrp_t) asa;
   1042 		syscallarg(netbsd32_intp) alen;
   1043 	} */ *uap = v;
   1044 	struct sys_getsockname_args ua;
   1045 
   1046 	NETBSD32TO64_UAP(fdes);
   1047 	NETBSD32TOP_UAP(asa, struct sockaddr);
   1048 	NETBSD32TOP_UAP(alen, int);
   1049 	return (sys_getsockname(p, &ua, retval));
   1050 }
   1051 
   1052 int
   1053 netbsd32_access(p, v, retval)
   1054 	struct proc *p;
   1055 	void *v;
   1056 	register_t *retval;
   1057 {
   1058 	struct netbsd32_access_args /* {
   1059 		syscallarg(const netbsd32_charp) path;
   1060 		syscallarg(int) flags;
   1061 	} */ *uap = v;
   1062 	struct sys_access_args ua;
   1063 	caddr_t sg;
   1064 
   1065 	NETBSD32TOP_UAP(path, const char);
   1066 	NETBSD32TO64_UAP(flags);
   1067 	sg = stackgap_init(p->p_emul);
   1068 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
   1069 
   1070 	return (sys_access(p, &ua, retval));
   1071 }
   1072 
   1073 int
   1074 netbsd32_chflags(p, v, retval)
   1075 	struct proc *p;
   1076 	void *v;
   1077 	register_t *retval;
   1078 {
   1079 	struct netbsd32_chflags_args /* {
   1080 		syscallarg(const netbsd32_charp) path;
   1081 		syscallarg(netbsd32_u_long) flags;
   1082 	} */ *uap = v;
   1083 	struct sys_chflags_args ua;
   1084 
   1085 	NETBSD32TOP_UAP(path, const char);
   1086 	NETBSD32TO64_UAP(flags);
   1087 
   1088 	return (sys_chflags(p, &ua, retval));
   1089 }
   1090 
   1091 int
   1092 netbsd32_fchflags(p, v, retval)
   1093 	struct proc *p;
   1094 	void *v;
   1095 	register_t *retval;
   1096 {
   1097 	struct netbsd32_fchflags_args /* {
   1098 		syscallarg(int) fd;
   1099 		syscallarg(netbsd32_u_long) flags;
   1100 	} */ *uap = v;
   1101 	struct sys_fchflags_args ua;
   1102 
   1103 	NETBSD32TO64_UAP(fd);
   1104 	NETBSD32TO64_UAP(flags);
   1105 
   1106 	return (sys_fchflags(p, &ua, retval));
   1107 }
   1108 
   1109 int
   1110 netbsd32_lchflags(p, v, retval)
   1111 	struct proc *p;
   1112 	void *v;
   1113 	register_t *retval;
   1114 {
   1115 	struct netbsd32_lchflags_args /* {
   1116 		syscallarg(int) fd;
   1117 		syscallarg(netbsd32_u_long) flags;
   1118 	} */ *uap = v;
   1119 	struct sys_lchflags_args ua;
   1120 
   1121 	NETBSD32TOP_UAP(path, const char);
   1122 	NETBSD32TO64_UAP(flags);
   1123 
   1124 	return (sys_lchflags(p, &ua, retval));
   1125 }
   1126 
   1127 int
   1128 netbsd32_kill(p, v, retval)
   1129 	struct proc *p;
   1130 	void *v;
   1131 	register_t *retval;
   1132 {
   1133 	struct netbsd32_kill_args /* {
   1134 		syscallarg(int) pid;
   1135 		syscallarg(int) signum;
   1136 	} */ *uap = v;
   1137 	struct sys_kill_args ua;
   1138 
   1139 	NETBSD32TO64_UAP(pid);
   1140 	NETBSD32TO64_UAP(signum);
   1141 
   1142 	return (sys_kill(p, &ua, retval));
   1143 }
   1144 
   1145 int
   1146 netbsd32_dup(p, v, retval)
   1147 	struct proc *p;
   1148 	void *v;
   1149 	register_t *retval;
   1150 {
   1151 	struct netbsd32_dup_args /* {
   1152 		syscallarg(int) fd;
   1153 	} */ *uap = v;
   1154 	struct sys_dup_args ua;
   1155 
   1156 	NETBSD32TO64_UAP(fd);
   1157 
   1158 	return (sys_dup(p, &ua, retval));
   1159 }
   1160 
   1161 int
   1162 netbsd32_profil(p, v, retval)
   1163 	struct proc *p;
   1164 	void *v;
   1165 	register_t *retval;
   1166 {
   1167 	struct netbsd32_profil_args /* {
   1168 		syscallarg(netbsd32_caddr_t) samples;
   1169 		syscallarg(netbsd32_size_t) size;
   1170 		syscallarg(netbsd32_u_long) offset;
   1171 		syscallarg(u_int) scale;
   1172 	} */ *uap = v;
   1173 	struct sys_profil_args ua;
   1174 
   1175 	NETBSD32TOX64_UAP(samples, caddr_t);
   1176 	NETBSD32TOX_UAP(size, size_t);
   1177 	NETBSD32TOX_UAP(offset, u_long);
   1178 	NETBSD32TO64_UAP(scale);
   1179 	return (sys_profil(p, &ua, retval));
   1180 }
   1181 
   1182 #ifdef KTRACE
   1183 int
   1184 netbsd32_ktrace(p, v, retval)
   1185 	struct proc *p;
   1186 	void *v;
   1187 	register_t *retval;
   1188 {
   1189 	struct netbsd32_ktrace_args /* {
   1190 		syscallarg(const netbsd32_charp) fname;
   1191 		syscallarg(int) ops;
   1192 		syscallarg(int) facs;
   1193 		syscallarg(int) pid;
   1194 	} */ *uap = v;
   1195 	struct sys_ktrace_args ua;
   1196 
   1197 	NETBSD32TOP_UAP(fname, const char);
   1198 	NETBSD32TO64_UAP(ops);
   1199 	NETBSD32TO64_UAP(facs);
   1200 	NETBSD32TO64_UAP(pid);
   1201 	return (sys_ktrace(p, &ua, retval));
   1202 }
   1203 #endif /* KTRACE */
   1204 
   1205 int
   1206 netbsd32_utrace(p, v, retval)
   1207 	struct proc *p;
   1208 	void *v;
   1209 	register_t *retval;
   1210 {
   1211 	struct netbsd32_utrace_args /* {
   1212 		syscallarg(const netbsd32_charp) label;
   1213 		syscallarg(netbsd32_voidp) addr;
   1214 		syscallarg(netbsd32_size_t) len;
   1215 	} */ *uap = v;
   1216 	struct sys_utrace_args ua;
   1217 
   1218 	NETBSD32TOP_UAP(label, const char);
   1219 	NETBSD32TOP_UAP(addr, void);
   1220 	NETBSD32TO64_UAP(len);
   1221 	return (sys_utrace(p, &ua, retval));
   1222 }
   1223 
   1224 /* XXX MOVE ME XXX */
   1225 int
   1226 netbsd32_sigaction(p, v, retval)
   1227 	struct proc *p;
   1228 	void *v;
   1229 	register_t *retval;
   1230 {
   1231 	struct netbsd32_sigaction_args /* {
   1232 		syscallarg(int) signum;
   1233 		syscallarg(const netbsd32_sigactionp_t) nsa;
   1234 		syscallarg(netbsd32_sigactionp_t) osa;
   1235 	} */ *uap = v;
   1236 	struct sigaction nsa, osa;
   1237 	struct netbsd32_sigaction *sa32p, sa32;
   1238 	int error;
   1239 
   1240 	if (SCARG(uap, nsa)) {
   1241 		sa32p = (struct netbsd32_sigaction *)(u_long)SCARG(uap, nsa);
   1242 		if (copyin(sa32p, &sa32, sizeof(sa32)))
   1243 			return EFAULT;
   1244 		nsa.sa_handler = (void *)(u_long)sa32.sa_handler;
   1245 		nsa.sa_mask = sa32.sa_mask;
   1246 		nsa.sa_flags = sa32.sa_flags;
   1247 	}
   1248 	error = sigaction1(p, SCARG(uap, signum),
   1249 			   SCARG(uap, nsa) ? &nsa : 0,
   1250 			   SCARG(uap, osa) ? &osa : 0);
   1251 
   1252 	if (error)
   1253 		return (error);
   1254 
   1255 	if (SCARG(uap, osa)) {
   1256 		sa32.sa_handler = (netbsd32_sigactionp_t)(u_long)osa.sa_handler;
   1257 		sa32.sa_mask = osa.sa_mask;
   1258 		sa32.sa_flags = osa.sa_flags;
   1259 		sa32p = (struct netbsd32_sigaction *)(u_long)SCARG(uap, osa);
   1260 		if (copyout(&sa32, sa32p, sizeof(sa32)))
   1261 			return EFAULT;
   1262 	}
   1263 
   1264 	return (0);
   1265 }
   1266 
   1267 int
   1268 netbsd32___getlogin(p, v, retval)
   1269 	struct proc *p;
   1270 	void *v;
   1271 	register_t *retval;
   1272 {
   1273 	struct netbsd32___getlogin_args /* {
   1274 		syscallarg(netbsd32_charp) namebuf;
   1275 		syscallarg(u_int) namelen;
   1276 	} */ *uap = v;
   1277 	struct sys___getlogin_args ua;
   1278 
   1279 	NETBSD32TOP_UAP(namebuf, char);
   1280 	NETBSD32TO64_UAP(namelen);
   1281 	return (sys___getlogin(p, &ua, retval));
   1282 }
   1283 
   1284 int
   1285 netbsd32_setlogin(p, v, retval)
   1286 	struct proc *p;
   1287 	void *v;
   1288 	register_t *retval;
   1289 {
   1290 	struct netbsd32_setlogin_args /* {
   1291 		syscallarg(const netbsd32_charp) namebuf;
   1292 	} */ *uap = v;
   1293 	struct sys_setlogin_args ua;
   1294 
   1295 	NETBSD32TOP_UAP(namebuf, char);
   1296 	return (sys_setlogin(p, &ua, retval));
   1297 }
   1298 
   1299 int
   1300 netbsd32_acct(p, v, retval)
   1301 	struct proc *p;
   1302 	void *v;
   1303 	register_t *retval;
   1304 {
   1305 	struct netbsd32_acct_args /* {
   1306 		syscallarg(const netbsd32_charp) path;
   1307 	} */ *uap = v;
   1308 	struct sys_acct_args ua;
   1309 
   1310 	NETBSD32TOP_UAP(path, const char);
   1311 	return (sys_acct(p, &ua, retval));
   1312 }
   1313 
   1314 int
   1315 netbsd32_revoke(p, v, retval)
   1316 	struct proc *p;
   1317 	void *v;
   1318 	register_t *retval;
   1319 {
   1320 	struct netbsd32_revoke_args /* {
   1321 		syscallarg(const netbsd32_charp) path;
   1322 	} */ *uap = v;
   1323 	struct sys_revoke_args ua;
   1324 	caddr_t sg;
   1325 
   1326 	NETBSD32TOP_UAP(path, const char);
   1327 	sg = stackgap_init(p->p_emul);
   1328 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
   1329 
   1330 	return (sys_revoke(p, &ua, retval));
   1331 }
   1332 
   1333 int
   1334 netbsd32_symlink(p, v, retval)
   1335 	struct proc *p;
   1336 	void *v;
   1337 	register_t *retval;
   1338 {
   1339 	struct netbsd32_symlink_args /* {
   1340 		syscallarg(const netbsd32_charp) path;
   1341 		syscallarg(const netbsd32_charp) link;
   1342 	} */ *uap = v;
   1343 	struct sys_symlink_args ua;
   1344 
   1345 	NETBSD32TOP_UAP(path, const char);
   1346 	NETBSD32TOP_UAP(link, const char);
   1347 
   1348 	return (sys_symlink(p, &ua, retval));
   1349 }
   1350 
   1351 int
   1352 netbsd32_readlink(p, v, retval)
   1353 	struct proc *p;
   1354 	void *v;
   1355 	register_t *retval;
   1356 {
   1357 	struct netbsd32_readlink_args /* {
   1358 		syscallarg(const netbsd32_charp) path;
   1359 		syscallarg(netbsd32_charp) buf;
   1360 		syscallarg(netbsd32_size_t) count;
   1361 	} */ *uap = v;
   1362 	struct sys_readlink_args ua;
   1363 	caddr_t sg;
   1364 
   1365 	NETBSD32TOP_UAP(path, const char);
   1366 	NETBSD32TOP_UAP(buf, char);
   1367 	NETBSD32TOX_UAP(count, size_t);
   1368 	sg = stackgap_init(p->p_emul);
   1369 	CHECK_ALT_SYMLINK(p, &sg, SCARG(&ua, path));
   1370 
   1371 	return (sys_readlink(p, &ua, retval));
   1372 }
   1373 
   1374 /* XXX MOVE ME XXX */
   1375 /*
   1376  * Need to completly reimplement this syscall due to argument copying.
   1377  */
   1378 /* ARGSUSED */
   1379 int
   1380 netbsd32_execve(p, v, retval)
   1381 	struct proc *p;
   1382 	void *v;
   1383 	register_t *retval;
   1384 {
   1385 	struct netbsd32_execve_args /* {
   1386 		syscallarg(const netbsd32_charp) path;
   1387 		syscallarg(netbsd32_charpp) argp;
   1388 		syscallarg(netbsd32_charpp) envp;
   1389 	} */ *uap = v;
   1390 	struct sys_execve_args ua;
   1391 	caddr_t sg;
   1392 
   1393 	NETBSD32TOP_UAP(path, const char);
   1394 	NETBSD32TOP_UAP(argp, char *);
   1395 	NETBSD32TOP_UAP(envp, char *);
   1396 	sg = stackgap_init(p->p_emul);
   1397 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
   1398 
   1399 	return netbsd32_execve2(p, &ua, retval);
   1400 }
   1401 
   1402 /* XXX MOVE ME XXX */
   1403 int
   1404 netbsd32_execve2(p, uap, retval)
   1405 	struct proc *p;
   1406 	struct sys_execve_args *uap;
   1407 	register_t *retval;
   1408 {
   1409 	/* Function args */
   1410 	int error, i;
   1411 	struct exec_package pack;
   1412 	struct nameidata nid;
   1413 	struct vattr attr;
   1414 	struct ucred *cred = p->p_ucred;
   1415 	char *argp;
   1416 	netbsd32_charp const *cpp;
   1417 	char *dp;
   1418 	netbsd32_charp sp;
   1419 	long argc, envc;
   1420 	size_t len;
   1421 	char *stack;
   1422 	struct ps_strings arginfo;
   1423 	struct vmspace *vm;
   1424 	char **tmpfap;
   1425 	int szsigcode;
   1426 	struct exec_vmcmd *base_vcp = NULL;
   1427 
   1428 	/*
   1429 	 * Init the namei data to point the file user's program name.
   1430 	 * This is done here rather than in check_exec(), so that it's
   1431 	 * possible to override this settings if any of makecmd/probe
   1432 	 * functions call check_exec() recursively - for example,
   1433 	 * see exec_script_makecmds().
   1434 	 */
   1435 	NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
   1436 
   1437 	/*
   1438 	 * initialize the fields of the exec package.
   1439 	 */
   1440 	pack.ep_name = SCARG(uap, path);
   1441 	pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
   1442 	pack.ep_hdrlen = exec_maxhdrsz;
   1443 	pack.ep_hdrvalid = 0;
   1444 	pack.ep_ndp = &nid;
   1445 	pack.ep_emul_arg = NULL;
   1446 	pack.ep_vmcmds.evs_cnt = 0;
   1447 	pack.ep_vmcmds.evs_used = 0;
   1448 	pack.ep_vap = &attr;
   1449 	pack.ep_flags = 0;
   1450 
   1451 	lockmgr(&exec_lock, LK_SHARED, NULL);
   1452 
   1453 	/* see if we can run it. */
   1454 	if ((error = check_exec(p, &pack)) != 0)
   1455 		goto freehdr;
   1456 
   1457 	/* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
   1458 
   1459 	/* allocate an argument buffer */
   1460 	argp = (char *) uvm_km_valloc_wait(exec_map, NCARGS);
   1461 #ifdef DIAGNOSTIC
   1462 	if (argp == (vaddr_t) 0)
   1463 		panic("execve: argp == NULL");
   1464 #endif
   1465 	dp = argp;
   1466 	argc = 0;
   1467 
   1468 	/* copy the fake args list, if there's one, freeing it as we go */
   1469 	if (pack.ep_flags & EXEC_HASARGL) {
   1470 		tmpfap = pack.ep_fa;
   1471 		while (*tmpfap != NULL) {
   1472 			char *cp;
   1473 
   1474 			cp = *tmpfap;
   1475 			while (*cp)
   1476 				*dp++ = *cp++;
   1477 			dp++;
   1478 
   1479 			FREE(*tmpfap, M_EXEC);
   1480 			tmpfap++; argc++;
   1481 		}
   1482 		FREE(pack.ep_fa, M_EXEC);
   1483 		pack.ep_flags &= ~EXEC_HASARGL;
   1484 	}
   1485 
   1486 	/* Now get argv & environment */
   1487 	if (!(cpp = (netbsd32_charp *)SCARG(uap, argp))) {
   1488 		error = EINVAL;
   1489 		goto bad;
   1490 	}
   1491 
   1492 	if (pack.ep_flags & EXEC_SKIPARG)
   1493 		cpp++;
   1494 
   1495 	while (1) {
   1496 		len = argp + ARG_MAX - dp;
   1497 		if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
   1498 			goto bad;
   1499 		if (!sp)
   1500 			break;
   1501 		if ((error = copyinstr((char *)(u_long)sp, dp,
   1502 				       len, &len)) != 0) {
   1503 			if (error == ENAMETOOLONG)
   1504 				error = E2BIG;
   1505 			goto bad;
   1506 		}
   1507 		dp += len;
   1508 		cpp++;
   1509 		argc++;
   1510 	}
   1511 
   1512 	envc = 0;
   1513 	/* environment need not be there */
   1514 	if ((cpp = (netbsd32_charp *)SCARG(uap, envp)) != NULL ) {
   1515 		while (1) {
   1516 			len = argp + ARG_MAX - dp;
   1517 			if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
   1518 				goto bad;
   1519 			if (!sp)
   1520 				break;
   1521 			if ((error = copyinstr((char *)(u_long)sp,
   1522 					       dp, len, &len)) != 0) {
   1523 				if (error == ENAMETOOLONG)
   1524 					error = E2BIG;
   1525 				goto bad;
   1526 			}
   1527 			dp += len;
   1528 			cpp++;
   1529 			envc++;
   1530 		}
   1531 	}
   1532 
   1533 	dp = (char *) ALIGN(dp);
   1534 
   1535 	szsigcode = pack.ep_es->es_emul->e_esigcode -
   1536 	    pack.ep_es->es_emul->e_sigcode;
   1537 
   1538 	/* Now check if args & environ fit into new stack */
   1539 	if (pack.ep_flags & EXEC_32)
   1540 		len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
   1541 		    sizeof(int) + sizeof(int) + dp + STACKGAPLEN +
   1542 		    szsigcode + sizeof(struct ps_strings)) - argp;
   1543 	else
   1544 		len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
   1545 		    sizeof(char *) + sizeof(int) + dp + STACKGAPLEN +
   1546 		    szsigcode + sizeof(struct ps_strings)) - argp;
   1547 
   1548 	len = ALIGN(len);	/* make the stack "safely" aligned */
   1549 
   1550 	if (len > pack.ep_ssize) { /* in effect, compare to initial limit */
   1551 		error = ENOMEM;
   1552 		goto bad;
   1553 	}
   1554 
   1555 	/* adjust "active stack depth" for process VSZ */
   1556 	pack.ep_ssize = len;	/* maybe should go elsewhere, but... */
   1557 
   1558 	/*
   1559 	 * Do whatever is necessary to prepare the address space
   1560 	 * for remapping.  Note that this might replace the current
   1561 	 * vmspace with another!
   1562 	 */
   1563 	uvmspace_exec(p, VM_MIN_ADDRESS, (vaddr_t)pack.ep_minsaddr);
   1564 
   1565 	/* Now map address space */
   1566 	vm = p->p_vmspace;
   1567 	vm->vm_taddr = (char *) pack.ep_taddr;
   1568 	vm->vm_tsize = btoc(pack.ep_tsize);
   1569 	vm->vm_daddr = (char *) pack.ep_daddr;
   1570 	vm->vm_dsize = btoc(pack.ep_dsize);
   1571 	vm->vm_ssize = btoc(pack.ep_ssize);
   1572 	vm->vm_maxsaddr = (char *) pack.ep_maxsaddr;
   1573 	vm->vm_minsaddr = (char *) pack.ep_minsaddr;
   1574 
   1575 	/* create the new process's VM space by running the vmcmds */
   1576 #ifdef DIAGNOSTIC
   1577 	if (pack.ep_vmcmds.evs_used == 0)
   1578 		panic("execve: no vmcmds");
   1579 #endif
   1580 	for (i = 0; i < pack.ep_vmcmds.evs_used && !error; i++) {
   1581 		struct exec_vmcmd *vcp;
   1582 
   1583 		vcp = &pack.ep_vmcmds.evs_cmds[i];
   1584 		if (vcp->ev_flags & VMCMD_RELATIVE) {
   1585 #ifdef DIAGNOSTIC
   1586 			if (base_vcp == NULL)
   1587 				panic("execve: relative vmcmd with no base");
   1588 			if (vcp->ev_flags & VMCMD_BASE)
   1589 				panic("execve: illegal base & relative vmcmd");
   1590 #endif
   1591 			vcp->ev_addr += base_vcp->ev_addr;
   1592 		}
   1593 		error = (*vcp->ev_proc)(p, vcp);
   1594 #ifdef DEBUG
   1595 		if (error) {
   1596 			if (i > 0)
   1597 				printf("vmcmd[%d] = %#lx/%#lx @ %#lx\n", i-1,
   1598 				       vcp[-1].ev_addr, vcp[-1].ev_len,
   1599 				       vcp[-1].ev_offset);
   1600 			printf("vmcmd[%d] = %#lx/%#lx @ %#lx\n", i,
   1601 			       vcp->ev_addr, vcp->ev_len, vcp->ev_offset);
   1602 		}
   1603 #endif
   1604 		if (vcp->ev_flags & VMCMD_BASE)
   1605 			base_vcp = vcp;
   1606 	}
   1607 
   1608 	/* free the vmspace-creation commands, and release their references */
   1609 	kill_vmcmds(&pack.ep_vmcmds);
   1610 
   1611 	/* if an error happened, deallocate and punt */
   1612 	if (error) {
   1613 #ifdef DEBUG
   1614 		printf("execve: vmcmd %i failed: %d\n", i-1, error);
   1615 #endif
   1616 		goto exec_abort;
   1617 	}
   1618 
   1619 	/* remember information about the process */
   1620 	arginfo.ps_nargvstr = argc;
   1621 	arginfo.ps_nenvstr = envc;
   1622 
   1623 	stack = (char *) (vm->vm_minsaddr - len);
   1624 	/* Now copy argc, args & environ to new stack */
   1625 	if (!(*pack.ep_es->es_copyargs)(&pack, &arginfo, stack, argp)) {
   1626 #ifdef DEBUG
   1627 		printf("execve: copyargs failed\n");
   1628 #endif
   1629 		goto exec_abort;
   1630 	}
   1631 
   1632 	/* fill process ps_strings info */
   1633 	p->p_psstr = (struct ps_strings *)(stack - sizeof(struct ps_strings));
   1634 	p->p_psargv = offsetof(struct ps_strings, ps_argvstr);
   1635 	p->p_psnargv = offsetof(struct ps_strings, ps_nargvstr);
   1636 	p->p_psenv = offsetof(struct ps_strings, ps_envstr);
   1637 	p->p_psnenv = offsetof(struct ps_strings, ps_nenvstr);
   1638 
   1639 	/* copy out the process's ps_strings structure */
   1640 	if (copyout(&arginfo, (char *)p->p_psstr, sizeof(arginfo))) {
   1641 #ifdef DEBUG
   1642 		printf("execve: ps_strings copyout failed\n");
   1643 #endif
   1644 		goto exec_abort;
   1645 	}
   1646 
   1647 	/* copy out the process's signal trapoline code */
   1648 	if (szsigcode) {
   1649 		if (copyout((char *)pack.ep_es->es_emul->e_sigcode,
   1650 		    p->p_sigctx.ps_sigcode = (char *)p->p_psstr - szsigcode,
   1651 		    szsigcode)) {
   1652 #ifdef DEBUG
   1653 			printf("execve: sig trampoline copyout failed\n");
   1654 #endif
   1655 			goto exec_abort;
   1656 		}
   1657 #ifdef PMAP_NEED_PROCWR
   1658 		/* This is code. Let the pmap do what is needed. */
   1659 		pmap_procwr(p, (vaddr_t)p->p_sigacts->ps_sigcode, szsigcode);
   1660 #endif
   1661 	}
   1662 
   1663 	stopprofclock(p);	/* stop profiling */
   1664 	fdcloseexec(p);		/* handle close on exec */
   1665 	execsigs(p);		/* reset catched signals */
   1666 	p->p_ctxlink = NULL;	/* reset ucontext link */
   1667 
   1668 	/* set command name & other accounting info */
   1669 	len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
   1670 	memcpy(p->p_comm, nid.ni_cnd.cn_nameptr, len);
   1671 	p->p_comm[len] = 0;
   1672 	p->p_acflag &= ~AFORK;
   1673 
   1674 	/* record proc's vnode, for use by procfs and others */
   1675         if (p->p_textvp)
   1676                 vrele(p->p_textvp);
   1677 	VREF(pack.ep_vp);
   1678 	p->p_textvp = pack.ep_vp;
   1679 
   1680 	p->p_flag |= P_EXEC;
   1681 	if (p->p_flag & P_PPWAIT) {
   1682 		p->p_flag &= ~P_PPWAIT;
   1683 		wakeup((caddr_t) p->p_pptr);
   1684 	}
   1685 
   1686 	/*
   1687 	 * deal with set[ug]id.
   1688 	 * MNT_NOSUID and P_TRACED have already been used to disable s[ug]id.
   1689 	 */
   1690 	if (((attr.va_mode & S_ISUID) != 0 && p->p_ucred->cr_uid != attr.va_uid)
   1691 	 || ((attr.va_mode & S_ISGID) != 0 && p->p_ucred->cr_gid != attr.va_gid)){
   1692 		p->p_ucred = crcopy(cred);
   1693 #ifdef KTRACE
   1694 		/*
   1695 		 * If process is being ktraced, turn off - unless
   1696 		 * root set it.
   1697 		 */
   1698 		if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT))
   1699 			ktrderef(p);
   1700 #endif
   1701 		if (attr.va_mode & S_ISUID)
   1702 			p->p_ucred->cr_uid = attr.va_uid;
   1703 		if (attr.va_mode & S_ISGID)
   1704 			p->p_ucred->cr_gid = attr.va_gid;
   1705 		p_sugid(p);
   1706 	} else
   1707 		p->p_flag &= ~P_SUGID;
   1708 	p->p_cred->p_svuid = p->p_ucred->cr_uid;
   1709 	p->p_cred->p_svgid = p->p_ucred->cr_gid;
   1710 
   1711 	doexechooks(p);
   1712 
   1713 	uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
   1714 
   1715 	PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
   1716 	vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
   1717 	VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
   1718 	vput(pack.ep_vp);
   1719 
   1720 	/* setup new registers and do misc. setup. */
   1721 	(*pack.ep_es->es_setregs)(p, &pack, (u_long) stack);
   1722 
   1723 	if (p->p_flag & P_TRACED)
   1724 		psignal(p, SIGTRAP);
   1725 
   1726 	free(pack.ep_hdr, M_EXEC);
   1727 
   1728 	/*
   1729 	 * Call emulation specific exec hook. This can setup setup per-process
   1730 	 * p->p_emuldata or do any other per-process stuff an emulation needs.
   1731 	 *
   1732 	 * If we are executing process of different emulation than the
   1733 	 * original forked process, call e_proc_exit() of the old emulation
   1734 	 * first, then e_proc_exec() of new emulation. If the emulation is
   1735 	 * same, the exec hook code should deallocate any old emulation
   1736 	 * resources held previously by this process.
   1737 	 */
   1738 	if (p->p_emul && p->p_emul->e_proc_exit
   1739 	    && p->p_emul != pack.ep_es->es_emul)
   1740 		(*p->p_emul->e_proc_exit)(p);
   1741 
   1742 	/*
   1743 	 * Call exec hook. Emulation code may NOT store reference to anything
   1744 	 * from &pack.
   1745 	 */
   1746         if (pack.ep_es->es_emul->e_proc_exec)
   1747                 (*pack.ep_es->es_emul->e_proc_exec)(p, &pack);
   1748 
   1749 	/* update p_emul, the old value is no longer needed */
   1750 	p->p_emul = pack.ep_es->es_emul;
   1751 
   1752 #ifdef KTRACE
   1753 	if (KTRPOINT(p, KTR_EMUL))
   1754 		ktremul(p);
   1755 #endif
   1756 
   1757 	lockmgr(&exec_lock, LK_RELEASE, NULL);
   1758 
   1759 	return (EJUSTRETURN);
   1760 
   1761 bad:
   1762 	/* free the vmspace-creation commands, and release their references */
   1763 	kill_vmcmds(&pack.ep_vmcmds);
   1764 	/* kill any opened file descriptor, if necessary */
   1765 	if (pack.ep_flags & EXEC_HASFD) {
   1766 		pack.ep_flags &= ~EXEC_HASFD;
   1767 		(void) fdrelease(p, pack.ep_fd);
   1768 	}
   1769 	/* close and put the exec'd file */
   1770 	vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
   1771 	VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
   1772 	vput(pack.ep_vp);
   1773 	PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
   1774 	uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
   1775 
   1776 freehdr:
   1777 	lockmgr(&exec_lock, LK_RELEASE, NULL);
   1778 
   1779 	free(pack.ep_hdr, M_EXEC);
   1780 	return error;
   1781 
   1782 exec_abort:
   1783 	lockmgr(&exec_lock, LK_RELEASE, NULL);
   1784 
   1785 	/*
   1786 	 * the old process doesn't exist anymore.  exit gracefully.
   1787 	 * get rid of the (new) address space we have created, if any, get rid
   1788 	 * of our namei data and vnode, and exit noting failure
   1789 	 */
   1790 	uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,
   1791 		VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
   1792 	if (pack.ep_emul_arg)
   1793 		FREE(pack.ep_emul_arg, M_TEMP);
   1794 	PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
   1795 	vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
   1796 	VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
   1797 	vput(pack.ep_vp);
   1798 	uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
   1799 	free(pack.ep_hdr, M_EXEC);
   1800 	exit1(p, W_EXITCODE(0, SIGABRT));
   1801 	exit1(p, -1);
   1802 
   1803 	/* NOTREACHED */
   1804 	return 0;
   1805 }
   1806 
   1807 int
   1808 netbsd32_umask(p, v, retval)
   1809 	struct proc *p;
   1810 	void *v;
   1811 	register_t *retval;
   1812 {
   1813 	struct netbsd32_umask_args /* {
   1814 		syscallarg(mode_t) newmask;
   1815 	} */ *uap = v;
   1816 	struct sys_umask_args ua;
   1817 
   1818 	NETBSD32TO64_UAP(newmask);
   1819 	return (sys_umask(p, &ua, retval));
   1820 }
   1821 
   1822 int
   1823 netbsd32_chroot(p, v, retval)
   1824 	struct proc *p;
   1825 	void *v;
   1826 	register_t *retval;
   1827 {
   1828 	struct netbsd32_chroot_args /* {
   1829 		syscallarg(const netbsd32_charp) path;
   1830 	} */ *uap = v;
   1831 	struct sys_chroot_args ua;
   1832 
   1833 	NETBSD32TOP_UAP(path, const char);
   1834 	return (sys_chroot(p, &ua, retval));
   1835 }
   1836 
   1837 int
   1838 netbsd32_sbrk(p, v, retval)
   1839 	struct proc *p;
   1840 	void *v;
   1841 	register_t *retval;
   1842 {
   1843 	struct netbsd32_sbrk_args /* {
   1844 		syscallarg(int) incr;
   1845 	} */ *uap = v;
   1846 	struct sys_sbrk_args ua;
   1847 
   1848 	NETBSD32TO64_UAP(incr);
   1849 	return (sys_sbrk(p, &ua, retval));
   1850 }
   1851 
   1852 int
   1853 netbsd32_sstk(p, v, retval)
   1854 	struct proc *p;
   1855 	void *v;
   1856 	register_t *retval;
   1857 {
   1858 	struct netbsd32_sstk_args /* {
   1859 		syscallarg(int) incr;
   1860 	} */ *uap = v;
   1861 	struct sys_sstk_args ua;
   1862 
   1863 	NETBSD32TO64_UAP(incr);
   1864 	return (sys_sstk(p, &ua, retval));
   1865 }
   1866 
   1867 int
   1868 netbsd32_munmap(p, v, retval)
   1869 	struct proc *p;
   1870 	void *v;
   1871 	register_t *retval;
   1872 {
   1873 	struct netbsd32_munmap_args /* {
   1874 		syscallarg(netbsd32_voidp) addr;
   1875 		syscallarg(netbsd32_size_t) len;
   1876 	} */ *uap = v;
   1877 	struct sys_munmap_args ua;
   1878 
   1879 	NETBSD32TOP_UAP(addr, void);
   1880 	NETBSD32TOX_UAP(len, size_t);
   1881 	return (sys_munmap(p, &ua, retval));
   1882 }
   1883 
   1884 int
   1885 netbsd32_mprotect(p, v, retval)
   1886 	struct proc *p;
   1887 	void *v;
   1888 	register_t *retval;
   1889 {
   1890 	struct netbsd32_mprotect_args /* {
   1891 		syscallarg(netbsd32_voidp) addr;
   1892 		syscallarg(netbsd32_size_t) len;
   1893 		syscallarg(int) prot;
   1894 	} */ *uap = v;
   1895 	struct sys_mprotect_args ua;
   1896 
   1897 	NETBSD32TOP_UAP(addr, void);
   1898 	NETBSD32TOX_UAP(len, size_t);
   1899 	NETBSD32TO64_UAP(prot);
   1900 	return (sys_mprotect(p, &ua, retval));
   1901 }
   1902 
   1903 int
   1904 netbsd32_madvise(p, v, retval)
   1905 	struct proc *p;
   1906 	void *v;
   1907 	register_t *retval;
   1908 {
   1909 	struct netbsd32_madvise_args /* {
   1910 		syscallarg(netbsd32_voidp) addr;
   1911 		syscallarg(netbsd32_size_t) len;
   1912 		syscallarg(int) behav;
   1913 	} */ *uap = v;
   1914 	struct sys_madvise_args ua;
   1915 
   1916 	NETBSD32TOP_UAP(addr, void);
   1917 	NETBSD32TOX_UAP(len, size_t);
   1918 	NETBSD32TO64_UAP(behav);
   1919 	return (sys_madvise(p, &ua, retval));
   1920 }
   1921 
   1922 int
   1923 netbsd32_mincore(p, v, retval)
   1924 	struct proc *p;
   1925 	void *v;
   1926 	register_t *retval;
   1927 {
   1928 	struct netbsd32_mincore_args /* {
   1929 		syscallarg(netbsd32_caddr_t) addr;
   1930 		syscallarg(netbsd32_size_t) len;
   1931 		syscallarg(netbsd32_charp) vec;
   1932 	} */ *uap = v;
   1933 	struct sys_mincore_args ua;
   1934 
   1935 	NETBSD32TOX64_UAP(addr, caddr_t);
   1936 	NETBSD32TOX_UAP(len, size_t);
   1937 	NETBSD32TOP_UAP(vec, char);
   1938 	return (sys_mincore(p, &ua, retval));
   1939 }
   1940 
   1941 /* XXX MOVE ME XXX */
   1942 int
   1943 netbsd32_getgroups(p, v, retval)
   1944 	struct proc *p;
   1945 	void *v;
   1946 	register_t *retval;
   1947 {
   1948 	struct netbsd32_getgroups_args /* {
   1949 		syscallarg(int) gidsetsize;
   1950 		syscallarg(netbsd32_gid_tp) gidset;
   1951 	} */ *uap = v;
   1952 	struct pcred *pc = p->p_cred;
   1953 	int ngrp;
   1954 	int error;
   1955 
   1956 	ngrp = SCARG(uap, gidsetsize);
   1957 	if (ngrp == 0) {
   1958 		*retval = pc->pc_ucred->cr_ngroups;
   1959 		return (0);
   1960 	}
   1961 	if (ngrp < pc->pc_ucred->cr_ngroups)
   1962 		return (EINVAL);
   1963 	ngrp = pc->pc_ucred->cr_ngroups;
   1964 	/* Should convert gid_t to netbsd32_gid_t, but they're the same */
   1965 	error = copyout((caddr_t)pc->pc_ucred->cr_groups,
   1966 			(caddr_t)(u_long)SCARG(uap, gidset),
   1967 			ngrp * sizeof(gid_t));
   1968 	if (error)
   1969 		return (error);
   1970 	*retval = ngrp;
   1971 	return (0);
   1972 }
   1973 
   1974 int
   1975 netbsd32_setgroups(p, v, retval)
   1976 	struct proc *p;
   1977 	void *v;
   1978 	register_t *retval;
   1979 {
   1980 	struct netbsd32_setgroups_args /* {
   1981 		syscallarg(int) gidsetsize;
   1982 		syscallarg(const netbsd32_gid_tp) gidset;
   1983 	} */ *uap = v;
   1984 	struct sys_setgroups_args ua;
   1985 
   1986 	NETBSD32TO64_UAP(gidsetsize);
   1987 	NETBSD32TOP_UAP(gidset, gid_t);
   1988 	return (sys_setgroups(p, &ua, retval));
   1989 }
   1990 
   1991 int
   1992 netbsd32_setpgid(p, v, retval)
   1993 	struct proc *p;
   1994 	void *v;
   1995 	register_t *retval;
   1996 {
   1997 	struct netbsd32_setpgid_args /* {
   1998 		syscallarg(int) pid;
   1999 		syscallarg(int) pgid;
   2000 	} */ *uap = v;
   2001 	struct sys_setpgid_args ua;
   2002 
   2003 	NETBSD32TO64_UAP(pid);
   2004 	NETBSD32TO64_UAP(pgid);
   2005 	return (sys_setpgid(p, &ua, retval));
   2006 }
   2007 
   2008 /* XXX MOVE ME XXX */
   2009 int
   2010 netbsd32_setitimer(p, v, retval)
   2011 	struct proc *p;
   2012 	void *v;
   2013 	register_t *retval;
   2014 {
   2015 	struct netbsd32_setitimer_args /* {
   2016 		syscallarg(int) which;
   2017 		syscallarg(const netbsd32_itimervalp_t) itv;
   2018 		syscallarg(netbsd32_itimervalp_t) oitv;
   2019 	} */ *uap = v;
   2020 	struct netbsd32_itimerval s32it, *itvp;
   2021 	int which = SCARG(uap, which);
   2022 	struct netbsd32_getitimer_args getargs;
   2023 	struct itimerval aitv;
   2024 	int s, error;
   2025 
   2026 	if ((u_int)which > ITIMER_PROF)
   2027 		return (EINVAL);
   2028 	itvp = (struct netbsd32_itimerval *)(u_long)SCARG(uap, itv);
   2029 	if (itvp && (error = copyin(itvp, &s32it, sizeof(s32it))))
   2030 		return (error);
   2031 	netbsd32_to_itimerval(&s32it, &aitv);
   2032 	if (SCARG(uap, oitv) != NULL) {
   2033 		SCARG(&getargs, which) = which;
   2034 		SCARG(&getargs, itv) = SCARG(uap, oitv);
   2035 		if ((error = netbsd32_getitimer(p, &getargs, retval)) != 0)
   2036 			return (error);
   2037 	}
   2038 	if (itvp == 0)
   2039 		return (0);
   2040 	if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
   2041 		return (EINVAL);
   2042 	s = splclock();
   2043 	if (which == ITIMER_REAL) {
   2044 		callout_stop(&p->p_realit_ch);
   2045 		if (timerisset(&aitv.it_value)) {
   2046 			/*
   2047 			 * Don't need to check hzto() return value, here.
   2048 			 * callout_reset() does it for us.
   2049 			 */
   2050 			timeradd(&aitv.it_value, &time, &aitv.it_value);
   2051 			callout_reset(&p->p_realit_ch, hzto(&aitv.it_value),
   2052 			    realitexpire, p);
   2053 		}
   2054 		p->p_realtimer = aitv;
   2055 	} else
   2056 		p->p_stats->p_timer[which] = aitv;
   2057 	splx(s);
   2058 	return (0);
   2059 }
   2060 
   2061 /* XXX MOVE ME XXX */
   2062 int
   2063 netbsd32_getitimer(p, v, retval)
   2064 	struct proc *p;
   2065 	void *v;
   2066 	register_t *retval;
   2067 {
   2068 	struct netbsd32_getitimer_args /* {
   2069 		syscallarg(int) which;
   2070 		syscallarg(netbsd32_itimervalp_t) itv;
   2071 	} */ *uap = v;
   2072 	int which = SCARG(uap, which);
   2073 	struct netbsd32_itimerval s32it;
   2074 	struct itimerval aitv;
   2075 	int s;
   2076 
   2077 	if ((u_int)which > ITIMER_PROF)
   2078 		return (EINVAL);
   2079 	s = splclock();
   2080 	if (which == ITIMER_REAL) {
   2081 		/*
   2082 		 * Convert from absolute to relative time in .it_value
   2083 		 * part of real time timer.  If time for real time timer
   2084 		 * has passed return 0, else return difference between
   2085 		 * current time and time for the timer to go off.
   2086 		 */
   2087 		aitv = p->p_realtimer;
   2088 		if (timerisset(&aitv.it_value)) {
   2089 			if (timercmp(&aitv.it_value, &time, <))
   2090 				timerclear(&aitv.it_value);
   2091 			else
   2092 				timersub(&aitv.it_value, &time, &aitv.it_value);
   2093 		}
   2094 	} else
   2095 		aitv = p->p_stats->p_timer[which];
   2096 	splx(s);
   2097 	netbsd32_from_itimerval(&aitv, &s32it);
   2098 	return (copyout(&s32it, (caddr_t)(u_long)SCARG(uap, itv), sizeof(s32it)));
   2099 }
   2100 
   2101 int
   2102 netbsd32_fcntl(p, v, retval)
   2103 	struct proc *p;
   2104 	void *v;
   2105 	register_t *retval;
   2106 {
   2107 	struct netbsd32_fcntl_args /* {
   2108 		syscallarg(int) fd;
   2109 		syscallarg(int) cmd;
   2110 		syscallarg(netbsd32_voidp) arg;
   2111 	} */ *uap = v;
   2112 	struct sys_fcntl_args ua;
   2113 
   2114 	NETBSD32TO64_UAP(fd);
   2115 	NETBSD32TO64_UAP(cmd);
   2116 	NETBSD32TOP_UAP(arg, void);
   2117 	/* we can do this because `struct flock' doesn't change */
   2118 	return (sys_fcntl(p, &ua, retval));
   2119 }
   2120 
   2121 int
   2122 netbsd32_dup2(p, v, retval)
   2123 	struct proc *p;
   2124 	void *v;
   2125 	register_t *retval;
   2126 {
   2127 	struct netbsd32_dup2_args /* {
   2128 		syscallarg(int) from;
   2129 		syscallarg(int) to;
   2130 	} */ *uap = v;
   2131 	struct sys_dup2_args ua;
   2132 
   2133 	NETBSD32TO64_UAP(from);
   2134 	NETBSD32TO64_UAP(to);
   2135 	return (sys_dup2(p, &ua, retval));
   2136 }
   2137 
   2138 /* XXX MOVE ME XXX */
   2139 int
   2140 netbsd32_select(p, v, retval)
   2141 	struct proc *p;
   2142 	void *v;
   2143 	register_t *retval;
   2144 {
   2145 	struct netbsd32_select_args /* {
   2146 		syscallarg(int) nd;
   2147 		syscallarg(netbsd32_fd_setp_t) in;
   2148 		syscallarg(netbsd32_fd_setp_t) ou;
   2149 		syscallarg(netbsd32_fd_setp_t) ex;
   2150 		syscallarg(netbsd32_timevalp_t) tv;
   2151 	} */ *uap = v;
   2152 /* This one must be done in-line 'cause of the timeval */
   2153 	struct netbsd32_timeval tv32;
   2154 	caddr_t bits;
   2155 	char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6];
   2156 	struct timeval atv;
   2157 	int s, ncoll, error = 0, timo;
   2158 	size_t ni;
   2159 	extern int	selwait, nselcoll;
   2160 	extern int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *));
   2161 
   2162 	if (SCARG(uap, nd) < 0)
   2163 		return (EINVAL);
   2164 	if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
   2165 		/* forgiving; slightly wrong */
   2166 		SCARG(uap, nd) = p->p_fd->fd_nfiles;
   2167 	}
   2168 	ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
   2169 	if (ni * 6 > sizeof(smallbits))
   2170 		bits = malloc(ni * 6, M_TEMP, M_WAITOK);
   2171 	else
   2172 		bits = smallbits;
   2173 
   2174 #define	getbits(name, x) \
   2175 	if (SCARG(uap, name)) { \
   2176 		error = copyin((caddr_t)(u_long)SCARG(uap, name), bits + ni * x, ni); \
   2177 		if (error) \
   2178 			goto done; \
   2179 	} else \
   2180 		memset(bits + ni * x, 0, ni);
   2181 	getbits(in, 0);
   2182 	getbits(ou, 1);
   2183 	getbits(ex, 2);
   2184 #undef	getbits
   2185 
   2186 	if (SCARG(uap, tv)) {
   2187 		error = copyin((caddr_t)(u_long)SCARG(uap, tv), (caddr_t)&tv32,
   2188 			sizeof(tv32));
   2189 		if (error)
   2190 			goto done;
   2191 		netbsd32_to_timeval(&tv32, &atv);
   2192 		if (itimerfix(&atv)) {
   2193 			error = EINVAL;
   2194 			goto done;
   2195 		}
   2196 		s = splclock();
   2197 		timeradd(&atv, &time, &atv);
   2198 		splx(s);
   2199 	} else
   2200 		timo = 0;
   2201 retry:
   2202 	ncoll = nselcoll;
   2203 	p->p_flag |= P_SELECT;
   2204 	error = selscan(p, (fd_mask *)(bits + ni * 0),
   2205 			   (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
   2206 	if (error || *retval)
   2207 		goto done;
   2208 	if (SCARG(uap, tv)) {
   2209 		/*
   2210 		 * We have to recalculate the timeout on every retry.
   2211 		 */
   2212 		timo = hzto(&atv);
   2213 		if (timo <= 0)
   2214 			goto done;
   2215 	}
   2216 	s = splhigh();
   2217 	if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
   2218 		splx(s);
   2219 		goto retry;
   2220 	}
   2221 	p->p_flag &= ~P_SELECT;
   2222 	error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
   2223 	splx(s);
   2224 	if (error == 0)
   2225 		goto retry;
   2226 done:
   2227 	p->p_flag &= ~P_SELECT;
   2228 	/* select is not restarted after signals... */
   2229 	if (error == ERESTART)
   2230 		error = EINTR;
   2231 	if (error == EWOULDBLOCK)
   2232 		error = 0;
   2233 	if (error == 0) {
   2234 #define	putbits(name, x) \
   2235 		if (SCARG(uap, name)) { \
   2236 			error = copyout(bits + ni * x, (caddr_t)(u_long)SCARG(uap, name), ni); \
   2237 			if (error) \
   2238 				goto out; \
   2239 		}
   2240 		putbits(in, 3);
   2241 		putbits(ou, 4);
   2242 		putbits(ex, 5);
   2243 #undef putbits
   2244 	}
   2245 out:
   2246 	if (ni * 6 > sizeof(smallbits))
   2247 		free(bits, M_TEMP);
   2248 	return (error);
   2249 }
   2250 
   2251 int
   2252 netbsd32_fsync(p, v, retval)
   2253 	struct proc *p;
   2254 	void *v;
   2255 	register_t *retval;
   2256 {
   2257 	struct netbsd32_fsync_args /* {
   2258 		syscallarg(int) fd;
   2259 	} */ *uap = v;
   2260 	struct sys_fsync_args ua;
   2261 
   2262 	NETBSD32TO64_UAP(fd);
   2263 	return (sys_fsync(p, &ua, retval));
   2264 }
   2265 
   2266 int
   2267 netbsd32_setpriority(p, v, retval)
   2268 	struct proc *p;
   2269 	void *v;
   2270 	register_t *retval;
   2271 {
   2272 	struct netbsd32_setpriority_args /* {
   2273 		syscallarg(int) which;
   2274 		syscallarg(int) who;
   2275 		syscallarg(int) prio;
   2276 	} */ *uap = v;
   2277 	struct sys_setpriority_args ua;
   2278 
   2279 	NETBSD32TO64_UAP(which);
   2280 	NETBSD32TO64_UAP(who);
   2281 	NETBSD32TO64_UAP(prio);
   2282 	return (sys_setpriority(p, &ua, retval));
   2283 }
   2284 
   2285 int
   2286 netbsd32_socket(p, v, retval)
   2287 	struct proc *p;
   2288 	void *v;
   2289 	register_t *retval;
   2290 {
   2291 	struct netbsd32_socket_args /* {
   2292 		syscallarg(int) domain;
   2293 		syscallarg(int) type;
   2294 		syscallarg(int) protocol;
   2295 	} */ *uap = v;
   2296 	struct sys_socket_args ua;
   2297 
   2298 	NETBSD32TO64_UAP(domain);
   2299 	NETBSD32TO64_UAP(type);
   2300 	NETBSD32TO64_UAP(protocol);
   2301 	return (sys_socket(p, &ua, retval));
   2302 }
   2303 
   2304 int
   2305 netbsd32_connect(p, v, retval)
   2306 	struct proc *p;
   2307 	void *v;
   2308 	register_t *retval;
   2309 {
   2310 	struct netbsd32_connect_args /* {
   2311 		syscallarg(int) s;
   2312 		syscallarg(const netbsd32_sockaddrp_t) name;
   2313 		syscallarg(int) namelen;
   2314 	} */ *uap = v;
   2315 	struct sys_connect_args ua;
   2316 
   2317 	NETBSD32TO64_UAP(s);
   2318 	NETBSD32TOP_UAP(name, struct sockaddr);
   2319 	NETBSD32TO64_UAP(namelen);
   2320 	return (sys_connect(p, &ua, retval));
   2321 }
   2322 
   2323 int
   2324 netbsd32_getpriority(p, v, retval)
   2325 	struct proc *p;
   2326 	void *v;
   2327 	register_t *retval;
   2328 {
   2329 	struct netbsd32_getpriority_args /* {
   2330 		syscallarg(int) which;
   2331 		syscallarg(int) who;
   2332 	} */ *uap = v;
   2333 	struct sys_getpriority_args ua;
   2334 
   2335 	NETBSD32TO64_UAP(which);
   2336 	NETBSD32TO64_UAP(who);
   2337 	return (sys_getpriority(p, &ua, retval));
   2338 }
   2339 
   2340 int
   2341 netbsd32_bind(p, v, retval)
   2342 	struct proc *p;
   2343 	void *v;
   2344 	register_t *retval;
   2345 {
   2346 	struct netbsd32_bind_args /* {
   2347 		syscallarg(int) s;
   2348 		syscallarg(const netbsd32_sockaddrp_t) name;
   2349 		syscallarg(int) namelen;
   2350 	} */ *uap = v;
   2351 	struct sys_bind_args ua;
   2352 
   2353 	NETBSD32TO64_UAP(s);
   2354 	NETBSD32TOP_UAP(name, struct sockaddr);
   2355 	NETBSD32TO64_UAP(namelen);
   2356 	return (sys_bind(p, &ua, retval));
   2357 }
   2358 
   2359 int
   2360 netbsd32_setsockopt(p, v, retval)
   2361 	struct proc *p;
   2362 	void *v;
   2363 	register_t *retval;
   2364 {
   2365 	struct netbsd32_setsockopt_args /* {
   2366 		syscallarg(int) s;
   2367 		syscallarg(int) level;
   2368 		syscallarg(int) name;
   2369 		syscallarg(const netbsd32_voidp) val;
   2370 		syscallarg(int) valsize;
   2371 	} */ *uap = v;
   2372 	struct sys_setsockopt_args ua;
   2373 
   2374 	NETBSD32TO64_UAP(s);
   2375 	NETBSD32TO64_UAP(level);
   2376 	NETBSD32TO64_UAP(name);
   2377 	NETBSD32TOP_UAP(val, void);
   2378 	NETBSD32TO64_UAP(valsize);
   2379 	/* may be more efficient to do this inline. */
   2380 	return (sys_setsockopt(p, &ua, retval));
   2381 }
   2382 
   2383 int
   2384 netbsd32_listen(p, v, retval)
   2385 	struct proc *p;
   2386 	void *v;
   2387 	register_t *retval;
   2388 {
   2389 	struct netbsd32_listen_args /* {
   2390 		syscallarg(int) s;
   2391 		syscallarg(int) backlog;
   2392 	} */ *uap = v;
   2393 	struct sys_listen_args ua;
   2394 
   2395 	NETBSD32TO64_UAP(s);
   2396 	NETBSD32TO64_UAP(backlog);
   2397 	return (sys_listen(p, &ua, retval));
   2398 }
   2399 
   2400 /* XXX MOVE ME XXX */
   2401 int
   2402 netbsd32_gettimeofday(p, v, retval)
   2403 	struct proc *p;
   2404 	void *v;
   2405 	register_t *retval;
   2406 {
   2407 	struct netbsd32_gettimeofday_args /* {
   2408 		syscallarg(netbsd32_timevalp_t) tp;
   2409 		syscallarg(netbsd32_timezonep_t) tzp;
   2410 	} */ *uap = v;
   2411 	struct timeval atv;
   2412 	struct netbsd32_timeval tv32;
   2413 	int error = 0;
   2414 	struct netbsd32_timezone tzfake;
   2415 
   2416 	if (SCARG(uap, tp)) {
   2417 		microtime(&atv);
   2418 		netbsd32_from_timeval(&atv, &tv32);
   2419 		error = copyout(&tv32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(tv32));
   2420 		if (error)
   2421 			return (error);
   2422 	}
   2423 	if (SCARG(uap, tzp)) {
   2424 		/*
   2425 		 * NetBSD has no kernel notion of time zone, so we just
   2426 		 * fake up a timezone struct and return it if demanded.
   2427 		 */
   2428 		tzfake.tz_minuteswest = 0;
   2429 		tzfake.tz_dsttime = 0;
   2430 		error = copyout(&tzfake, (caddr_t)(u_long)SCARG(uap, tzp), sizeof(tzfake));
   2431 	}
   2432 	return (error);
   2433 }
   2434 
   2435 /* XXX MOVE ME XXX */
   2436 int
   2437 netbsd32_settimeofday(p, v, retval)
   2438 	struct proc *p;
   2439 	void *v;
   2440 	register_t *retval;
   2441 {
   2442 	struct netbsd32_settimeofday_args /* {
   2443 		syscallarg(const netbsd32_timevalp_t) tv;
   2444 		syscallarg(const netbsd32_timezonep_t) tzp;
   2445 	} */ *uap = v;
   2446 	struct netbsd32_timeval atv32;
   2447 	struct timeval atv;
   2448 	int error;
   2449 
   2450 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
   2451 		return (error);
   2452 	/* Verify all parameters before changing time. */
   2453 	if (SCARG(uap, tv) && (error = copyin((caddr_t)(u_long)SCARG(uap, tv),
   2454 	    &atv32, sizeof(atv32))))
   2455 		return (error);
   2456 	netbsd32_to_timeval(&atv32, &atv);
   2457 	if (SCARG(uap, tv))
   2458 		if ((error = settime(&atv)))
   2459 			return (error);
   2460 	/* don't bother copying the tz in, we don't use it. */
   2461 	/*
   2462 	 * NetBSD has no kernel notion of time zone, and only an
   2463 	 * obsolete program would try to set it, so we log a warning.
   2464 	 */
   2465 	if (SCARG(uap, tzp))
   2466 		printf("pid %d attempted to set the "
   2467 		    "(obsolete) kernel time zone\n", p->p_pid);
   2468 	return (0);
   2469 }
   2470 
   2471 int
   2472 netbsd32_fchown(p, v, retval)
   2473 	struct proc *p;
   2474 	void *v;
   2475 	register_t *retval;
   2476 {
   2477 	struct netbsd32_fchown_args /* {
   2478 		syscallarg(int) fd;
   2479 		syscallarg(uid_t) uid;
   2480 		syscallarg(gid_t) gid;
   2481 	} */ *uap = v;
   2482 	struct sys_fchown_args ua;
   2483 
   2484 	NETBSD32TO64_UAP(fd);
   2485 	NETBSD32TO64_UAP(uid);
   2486 	NETBSD32TO64_UAP(gid);
   2487 	return (sys_fchown(p, &ua, retval));
   2488 }
   2489 
   2490 int
   2491 netbsd32_fchmod(p, v, retval)
   2492 	struct proc *p;
   2493 	void *v;
   2494 	register_t *retval;
   2495 {
   2496 	struct netbsd32_fchmod_args /* {
   2497 		syscallarg(int) fd;
   2498 		syscallarg(mode_t) mode;
   2499 	} */ *uap = v;
   2500 	struct sys_fchmod_args ua;
   2501 
   2502 	NETBSD32TO64_UAP(fd);
   2503 	NETBSD32TO64_UAP(mode);
   2504 	return (sys_fchmod(p, &ua, retval));
   2505 }
   2506 
   2507 int
   2508 netbsd32_setreuid(p, v, retval)
   2509 	struct proc *p;
   2510 	void *v;
   2511 	register_t *retval;
   2512 {
   2513 	struct netbsd32_setreuid_args /* {
   2514 		syscallarg(uid_t) ruid;
   2515 		syscallarg(uid_t) euid;
   2516 	} */ *uap = v;
   2517 	struct sys_setreuid_args ua;
   2518 
   2519 	NETBSD32TO64_UAP(ruid);
   2520 	NETBSD32TO64_UAP(euid);
   2521 	return (sys_setreuid(p, &ua, retval));
   2522 }
   2523 
   2524 int
   2525 netbsd32_setregid(p, v, retval)
   2526 	struct proc *p;
   2527 	void *v;
   2528 	register_t *retval;
   2529 {
   2530 	struct netbsd32_setregid_args /* {
   2531 		syscallarg(gid_t) rgid;
   2532 		syscallarg(gid_t) egid;
   2533 	} */ *uap = v;
   2534 	struct sys_setregid_args ua;
   2535 
   2536 	NETBSD32TO64_UAP(rgid);
   2537 	NETBSD32TO64_UAP(egid);
   2538 	return (sys_setregid(p, &ua, retval));
   2539 }
   2540 
   2541 /* XXX MOVE ME XXX */
   2542 int
   2543 netbsd32_getrusage(p, v, retval)
   2544 	struct proc *p;
   2545 	void *v;
   2546 	register_t *retval;
   2547 {
   2548 	struct netbsd32_getrusage_args /* {
   2549 		syscallarg(int) who;
   2550 		syscallarg(netbsd32_rusagep_t) rusage;
   2551 	} */ *uap = v;
   2552 	struct rusage *rup;
   2553 	struct netbsd32_rusage ru;
   2554 
   2555 	switch (SCARG(uap, who)) {
   2556 
   2557 	case RUSAGE_SELF:
   2558 		rup = &p->p_stats->p_ru;
   2559 		calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
   2560 		break;
   2561 
   2562 	case RUSAGE_CHILDREN:
   2563 		rup = &p->p_stats->p_cru;
   2564 		break;
   2565 
   2566 	default:
   2567 		return (EINVAL);
   2568 	}
   2569 	netbsd32_from_rusage(rup, &ru);
   2570 	return (copyout(&ru, (caddr_t)(u_long)SCARG(uap, rusage), sizeof(ru)));
   2571 }
   2572 
   2573 int
   2574 netbsd32_getsockopt(p, v, retval)
   2575 	struct proc *p;
   2576 	void *v;
   2577 	register_t *retval;
   2578 {
   2579 	struct netbsd32_getsockopt_args /* {
   2580 		syscallarg(int) s;
   2581 		syscallarg(int) level;
   2582 		syscallarg(int) name;
   2583 		syscallarg(netbsd32_voidp) val;
   2584 		syscallarg(netbsd32_intp) avalsize;
   2585 	} */ *uap = v;
   2586 	struct sys_getsockopt_args ua;
   2587 
   2588 	NETBSD32TO64_UAP(s);
   2589 	NETBSD32TO64_UAP(level);
   2590 	NETBSD32TO64_UAP(name);
   2591 	NETBSD32TOP_UAP(val, void);
   2592 	NETBSD32TOP_UAP(avalsize, int);
   2593 	return (sys_getsockopt(p, &ua, retval));
   2594 }
   2595 
   2596 /* XXX MOVE ME XXX */
   2597 int
   2598 netbsd32_readv(p, v, retval)
   2599 	struct proc *p;
   2600 	void *v;
   2601 	register_t *retval;
   2602 {
   2603 	struct netbsd32_readv_args /* {
   2604 		syscallarg(int) fd;
   2605 		syscallarg(const netbsd32_iovecp_t) iovp;
   2606 		syscallarg(int) iovcnt;
   2607 	} */ *uap = v;
   2608 	int fd = SCARG(uap, fd);
   2609 	struct file *fp;
   2610 	struct filedesc *fdp = p->p_fd;
   2611 
   2612 	if ((u_int)fd >= fdp->fd_nfiles ||
   2613 	    (fp = fdp->fd_ofiles[fd]) == NULL ||
   2614 	    (fp->f_flag & FREAD) == 0)
   2615 		return (EBADF);
   2616 
   2617 	return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
   2618 			      SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
   2619 }
   2620 
   2621 /* XXX MOVE ME XXX */
   2622 /* Damn thing copies in the iovec! */
   2623 int
   2624 dofilereadv32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
   2625 	struct proc *p;
   2626 	int fd;
   2627 	struct file *fp;
   2628 	struct netbsd32_iovec *iovp;
   2629 	int iovcnt;
   2630 	off_t *offset;
   2631 	int flags;
   2632 	register_t *retval;
   2633 {
   2634 	struct uio auio;
   2635 	struct iovec *iov;
   2636 	struct iovec *needfree;
   2637 	struct iovec aiov[UIO_SMALLIOV];
   2638 	long i, cnt, error = 0;
   2639 	u_int iovlen;
   2640 #ifdef KTRACE
   2641 	struct iovec *ktriov = NULL;
   2642 #endif
   2643 
   2644 	/* note: can't use iovlen until iovcnt is validated */
   2645 	iovlen = iovcnt * sizeof(struct iovec);
   2646 	if ((u_int)iovcnt > UIO_SMALLIOV) {
   2647 		if ((u_int)iovcnt > IOV_MAX)
   2648 			return (EINVAL);
   2649 		MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
   2650 		needfree = iov;
   2651 	} else if ((u_int)iovcnt > 0) {
   2652 		iov = aiov;
   2653 		needfree = NULL;
   2654 	} else
   2655 		return (EINVAL);
   2656 
   2657 	auio.uio_iov = iov;
   2658 	auio.uio_iovcnt = iovcnt;
   2659 	auio.uio_rw = UIO_READ;
   2660 	auio.uio_segflg = UIO_USERSPACE;
   2661 	auio.uio_procp = p;
   2662 	error = netbsd32_to_iovecin(iovp, iov, iovcnt);
   2663 	if (error)
   2664 		goto done;
   2665 	auio.uio_resid = 0;
   2666 	for (i = 0; i < iovcnt; i++) {
   2667 		auio.uio_resid += iov->iov_len;
   2668 		/*
   2669 		 * Reads return ssize_t because -1 is returned on error.
   2670 		 * Therefore we must restrict the length to SSIZE_MAX to
   2671 		 * avoid garbage return values.
   2672 		 */
   2673 		if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
   2674 			error = EINVAL;
   2675 			goto done;
   2676 		}
   2677 		iov++;
   2678 	}
   2679 #ifdef KTRACE
   2680 	/*
   2681 	 * if tracing, save a copy of iovec
   2682 	 */
   2683 	if (KTRPOINT(p, KTR_GENIO))  {
   2684 		MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
   2685 		memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
   2686 	}
   2687 #endif
   2688 	cnt = auio.uio_resid;
   2689 	error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
   2690 	if (error)
   2691 		if (auio.uio_resid != cnt && (error == ERESTART ||
   2692 		    error == EINTR || error == EWOULDBLOCK))
   2693 			error = 0;
   2694 	cnt -= auio.uio_resid;
   2695 #ifdef KTRACE
   2696 	if (KTRPOINT(p, KTR_GENIO))
   2697 		if (error == 0) {
   2698 			ktrgenio(p, fd, UIO_READ, ktriov, cnt,
   2699 			    error);
   2700 		FREE(ktriov, M_TEMP);
   2701 	}
   2702 #endif
   2703 	*retval = cnt;
   2704 done:
   2705 	if (needfree)
   2706 		FREE(needfree, M_IOV);
   2707 	return (error);
   2708 }
   2709 
   2710 /* XXX MOVE ME XXX */
   2711 int
   2712 netbsd32_writev(p, v, retval)
   2713 	struct proc *p;
   2714 	void *v;
   2715 	register_t *retval;
   2716 {
   2717 	struct netbsd32_writev_args /* {
   2718 		syscallarg(int) fd;
   2719 		syscallarg(const netbsd32_iovecp_t) iovp;
   2720 		syscallarg(int) iovcnt;
   2721 	} */ *uap = v;
   2722 	int fd = SCARG(uap, fd);
   2723 	struct file *fp;
   2724 	struct filedesc *fdp = p->p_fd;
   2725 
   2726 	if ((u_int)fd >= fdp->fd_nfiles ||
   2727 	    (fp = fdp->fd_ofiles[fd]) == NULL ||
   2728 	    (fp->f_flag & FWRITE) == 0)
   2729 		return (EBADF);
   2730 
   2731 	return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
   2732 			       SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
   2733 }
   2734 
   2735 /* XXX MOVE ME XXX */
   2736 int
   2737 dofilewritev32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
   2738 	struct proc *p;
   2739 	int fd;
   2740 	struct file *fp;
   2741 	struct netbsd32_iovec *iovp;
   2742 	int iovcnt;
   2743 	off_t *offset;
   2744 	int flags;
   2745 	register_t *retval;
   2746 {
   2747 	struct uio auio;
   2748 	struct iovec *iov;
   2749 	struct iovec *needfree;
   2750 	struct iovec aiov[UIO_SMALLIOV];
   2751 	long i, cnt, error = 0;
   2752 	u_int iovlen;
   2753 #ifdef KTRACE
   2754 	struct iovec *ktriov = NULL;
   2755 #endif
   2756 
   2757 	/* note: can't use iovlen until iovcnt is validated */
   2758 	iovlen = iovcnt * sizeof(struct iovec);
   2759 	if ((u_int)iovcnt > UIO_SMALLIOV) {
   2760 		if ((u_int)iovcnt > IOV_MAX)
   2761 			return (EINVAL);
   2762 		MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
   2763 		needfree = iov;
   2764 	} else if ((u_int)iovcnt > 0) {
   2765 		iov = aiov;
   2766 		needfree = NULL;
   2767 	} else
   2768 		return (EINVAL);
   2769 
   2770 	auio.uio_iov = iov;
   2771 	auio.uio_iovcnt = iovcnt;
   2772 	auio.uio_rw = UIO_WRITE;
   2773 	auio.uio_segflg = UIO_USERSPACE;
   2774 	auio.uio_procp = p;
   2775 	error = netbsd32_to_iovecin(iovp, iov, iovcnt);
   2776 	if (error)
   2777 		goto done;
   2778 	auio.uio_resid = 0;
   2779 	for (i = 0; i < iovcnt; i++) {
   2780 		auio.uio_resid += iov->iov_len;
   2781 		/*
   2782 		 * Writes return ssize_t because -1 is returned on error.
   2783 		 * Therefore we must restrict the length to SSIZE_MAX to
   2784 		 * avoid garbage return values.
   2785 		 */
   2786 		if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
   2787 			error = EINVAL;
   2788 			goto done;
   2789 		}
   2790 		iov++;
   2791 	}
   2792 #ifdef KTRACE
   2793 	/*
   2794 	 * if tracing, save a copy of iovec
   2795 	 */
   2796 	if (KTRPOINT(p, KTR_GENIO))  {
   2797 		MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
   2798 		memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
   2799 	}
   2800 #endif
   2801 	cnt = auio.uio_resid;
   2802 	error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
   2803 	if (error) {
   2804 		if (auio.uio_resid != cnt && (error == ERESTART ||
   2805 		    error == EINTR || error == EWOULDBLOCK))
   2806 			error = 0;
   2807 		if (error == EPIPE)
   2808 			psignal(p, SIGPIPE);
   2809 	}
   2810 	cnt -= auio.uio_resid;
   2811 #ifdef KTRACE
   2812 	if (KTRPOINT(p, KTR_GENIO))
   2813 		if (error == 0) {
   2814 			ktrgenio(p, fd, UIO_WRITE, ktriov, cnt,
   2815 			    error);
   2816 		FREE(ktriov, M_TEMP);
   2817 	}
   2818 #endif
   2819 	*retval = cnt;
   2820 done:
   2821 	if (needfree)
   2822 		FREE(needfree, M_IOV);
   2823 	return (error);
   2824 }
   2825 
   2826 
   2827 int
   2828 netbsd32_rename(p, v, retval)
   2829 	struct proc *p;
   2830 	void *v;
   2831 	register_t *retval;
   2832 {
   2833 	struct netbsd32_rename_args /* {
   2834 		syscallarg(const netbsd32_charp) from;
   2835 		syscallarg(const netbsd32_charp) to;
   2836 	} */ *uap = v;
   2837 	struct sys_rename_args ua;
   2838 
   2839 	NETBSD32TOP_UAP(from, const char);
   2840 	NETBSD32TOP_UAP(to, const char)
   2841 
   2842 	return (sys_rename(p, &ua, retval));
   2843 }
   2844 
   2845 int
   2846 netbsd32_flock(p, v, retval)
   2847 	struct proc *p;
   2848 	void *v;
   2849 	register_t *retval;
   2850 {
   2851 	struct netbsd32_flock_args /* {
   2852 		syscallarg(int) fd;
   2853 		syscallarg(int) how;
   2854 	} */ *uap = v;
   2855 	struct sys_flock_args ua;
   2856 
   2857 	NETBSD32TO64_UAP(fd);
   2858 	NETBSD32TO64_UAP(how)
   2859 
   2860 	return (sys_flock(p, &ua, retval));
   2861 }
   2862 
   2863 int
   2864 netbsd32_mkfifo(p, v, retval)
   2865 	struct proc *p;
   2866 	void *v;
   2867 	register_t *retval;
   2868 {
   2869 	struct netbsd32_mkfifo_args /* {
   2870 		syscallarg(const netbsd32_charp) path;
   2871 		syscallarg(mode_t) mode;
   2872 	} */ *uap = v;
   2873 	struct sys_mkfifo_args ua;
   2874 
   2875 	NETBSD32TOP_UAP(path, const char)
   2876 	NETBSD32TO64_UAP(mode);
   2877 	return (sys_mkfifo(p, &ua, retval));
   2878 }
   2879 
   2880 int
   2881 netbsd32_shutdown(p, v, retval)
   2882 	struct proc *p;
   2883 	void *v;
   2884 	register_t *retval;
   2885 {
   2886 	struct netbsd32_shutdown_args /* {
   2887 		syscallarg(int) s;
   2888 		syscallarg(int) how;
   2889 	} */ *uap = v;
   2890 	struct sys_shutdown_args ua;
   2891 
   2892 	NETBSD32TO64_UAP(s)
   2893 	NETBSD32TO64_UAP(how);
   2894 	return (sys_shutdown(p, &ua, retval));
   2895 }
   2896 
   2897 int
   2898 netbsd32_socketpair(p, v, retval)
   2899 	struct proc *p;
   2900 	void *v;
   2901 	register_t *retval;
   2902 {
   2903 	struct netbsd32_socketpair_args /* {
   2904 		syscallarg(int) domain;
   2905 		syscallarg(int) type;
   2906 		syscallarg(int) protocol;
   2907 		syscallarg(netbsd32_intp) rsv;
   2908 	} */ *uap = v;
   2909 	struct sys_socketpair_args ua;
   2910 
   2911 	NETBSD32TO64_UAP(domain);
   2912 	NETBSD32TO64_UAP(type);
   2913 	NETBSD32TO64_UAP(protocol);
   2914 	NETBSD32TOP_UAP(rsv, int);
   2915 	/* Since we're just copying out two `int's we can do this */
   2916 	return (sys_socketpair(p, &ua, retval));
   2917 }
   2918 
   2919 int
   2920 netbsd32_mkdir(p, v, retval)
   2921 	struct proc *p;
   2922 	void *v;
   2923 	register_t *retval;
   2924 {
   2925 	struct netbsd32_mkdir_args /* {
   2926 		syscallarg(const netbsd32_charp) path;
   2927 		syscallarg(mode_t) mode;
   2928 	} */ *uap = v;
   2929 	struct sys_mkdir_args ua;
   2930 
   2931 	NETBSD32TOP_UAP(path, const char)
   2932 	NETBSD32TO64_UAP(mode);
   2933 	return (sys_mkdir(p, &ua, retval));
   2934 }
   2935 
   2936 int
   2937 netbsd32_rmdir(p, v, retval)
   2938 	struct proc *p;
   2939 	void *v;
   2940 	register_t *retval;
   2941 {
   2942 	struct netbsd32_rmdir_args /* {
   2943 		syscallarg(const netbsd32_charp) path;
   2944 	} */ *uap = v;
   2945 	struct sys_rmdir_args ua;
   2946 
   2947 	NETBSD32TOP_UAP(path, const char);
   2948 	return (sys_rmdir(p, &ua, retval));
   2949 }
   2950 
   2951 /* XXX MOVE ME XXX */
   2952 int
   2953 netbsd32_utimes(p, v, retval)
   2954 	struct proc *p;
   2955 	void *v;
   2956 	register_t *retval;
   2957 {
   2958 	struct netbsd32_utimes_args /* {
   2959 		syscallarg(const netbsd32_charp) path;
   2960 		syscallarg(const netbsd32_timevalp_t) tptr;
   2961 	} */ *uap = v;
   2962 	int error;
   2963 	struct nameidata nd;
   2964 
   2965 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
   2966 	if ((error = namei(&nd)) != 0)
   2967 		return (error);
   2968 
   2969 	error = change_utimes32(nd.ni_vp, SCARG(uap, tptr), p);
   2970 
   2971 	vrele(nd.ni_vp);
   2972 	return (error);
   2973 }
   2974 
   2975 /* XXX MOVE ME XXX */
   2976 /*
   2977  * Common routine to set access and modification times given a vnode.
   2978  */
   2979 static int
   2980 change_utimes32(vp, tptr, p)
   2981 	struct vnode *vp;
   2982 	netbsd32_timevalp_t tptr;
   2983 	struct proc *p;
   2984 {
   2985 	struct netbsd32_timeval tv32[2];
   2986 	struct timeval tv[2];
   2987 	struct vattr vattr;
   2988 	int error;
   2989 
   2990 	VATTR_NULL(&vattr);
   2991 	if (tptr == NULL) {
   2992 		microtime(&tv[0]);
   2993 		tv[1] = tv[0];
   2994 		vattr.va_vaflags |= VA_UTIMES_NULL;
   2995 	} else {
   2996 		error = copyin((caddr_t)(u_long)tptr, tv32, sizeof(tv32));
   2997 		if (error)
   2998 			return (error);
   2999 		netbsd32_to_timeval(&tv32[0], &tv[0]);
   3000 		netbsd32_to_timeval(&tv32[1], &tv[1]);
   3001 	}
   3002 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
   3003 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
   3004 	vattr.va_atime.tv_sec = tv[0].tv_sec;
   3005 	vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
   3006 	vattr.va_mtime.tv_sec = tv[1].tv_sec;
   3007 	vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
   3008 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
   3009 	VOP_UNLOCK(vp, 0);
   3010 	return (error);
   3011 }
   3012 
   3013 /* XXX MOVE ME XXX */
   3014 int
   3015 netbsd32_adjtime(p, v, retval)
   3016 	struct proc *p;
   3017 	void *v;
   3018 	register_t *retval;
   3019 {
   3020 	struct netbsd32_adjtime_args /* {
   3021 		syscallarg(const netbsd32_timevalp_t) delta;
   3022 		syscallarg(netbsd32_timevalp_t) olddelta;
   3023 	} */ *uap = v;
   3024 	struct netbsd32_timeval atv;
   3025 	int32_t ndelta, ntickdelta, odelta;
   3026 	int s, error;
   3027 	extern long bigadj, timedelta;
   3028 	extern int tickdelta;
   3029 
   3030 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
   3031 		return (error);
   3032 
   3033 	error = copyin((caddr_t)(u_long)SCARG(uap, delta), &atv, sizeof(struct timeval));
   3034 	if (error)
   3035 		return (error);
   3036 	/*
   3037 	 * Compute the total correction and the rate at which to apply it.
   3038 	 * Round the adjustment down to a whole multiple of the per-tick
   3039 	 * delta, so that after some number of incremental changes in
   3040 	 * hardclock(), tickdelta will become zero, lest the correction
   3041 	 * overshoot and start taking us away from the desired final time.
   3042 	 */
   3043 	ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
   3044 	if (ndelta > bigadj)
   3045 		ntickdelta = 10 * tickadj;
   3046 	else
   3047 		ntickdelta = tickadj;
   3048 	if (ndelta % ntickdelta)
   3049 		ndelta = ndelta / ntickdelta * ntickdelta;
   3050 
   3051 	/*
   3052 	 * To make hardclock()'s job easier, make the per-tick delta negative
   3053 	 * if we want time to run slower; then hardclock can simply compute
   3054 	 * tick + tickdelta, and subtract tickdelta from timedelta.
   3055 	 */
   3056 	if (ndelta < 0)
   3057 		ntickdelta = -ntickdelta;
   3058 	s = splclock();
   3059 	odelta = timedelta;
   3060 	timedelta = ndelta;
   3061 	tickdelta = ntickdelta;
   3062 	splx(s);
   3063 
   3064 	if (SCARG(uap, olddelta)) {
   3065 		atv.tv_sec = odelta / 1000000;
   3066 		atv.tv_usec = odelta % 1000000;
   3067 		(void) copyout(&atv, (caddr_t)(u_long)SCARG(uap, olddelta),
   3068 		    sizeof(atv));
   3069 	}
   3070 	return (0);
   3071 }
   3072 
   3073 int
   3074 netbsd32_quotactl(p, v, retval)
   3075 	struct proc *p;
   3076 	void *v;
   3077 	register_t *retval;
   3078 {
   3079 	struct netbsd32_quotactl_args /* {
   3080 		syscallarg(const netbsd32_charp) path;
   3081 		syscallarg(int) cmd;
   3082 		syscallarg(int) uid;
   3083 		syscallarg(netbsd32_caddr_t) arg;
   3084 	} */ *uap = v;
   3085 	struct sys_quotactl_args ua;
   3086 
   3087 	NETBSD32TOP_UAP(path, const char);
   3088 	NETBSD32TO64_UAP(cmd);
   3089 	NETBSD32TO64_UAP(uid);
   3090 	NETBSD32TOX64_UAP(arg, caddr_t);
   3091 	return (sys_quotactl(p, &ua, retval));
   3092 }
   3093 
   3094 #if defined(NFS) || defined(NFSSERVER)
   3095 int
   3096 netbsd32_nfssvc(p, v, retval)
   3097 	struct proc *p;
   3098 	void *v;
   3099 	register_t *retval;
   3100 {
   3101 #if 0
   3102 	struct netbsd32_nfssvc_args /* {
   3103 		syscallarg(int) flag;
   3104 		syscallarg(netbsd32_voidp) argp;
   3105 	} */ *uap = v;
   3106 	struct sys_nfssvc_args ua;
   3107 
   3108 	NETBSD32TO64_UAP(flag);
   3109 	NETBSD32TOP_UAP(argp, void);
   3110 	return (sys_nfssvc(p, &ua, retval));
   3111 #else
   3112 	/* Why would we want to support a 32-bit nfsd? */
   3113 	return (ENOSYS);
   3114 #endif
   3115 }
   3116 #endif
   3117 
   3118 /* XXX MOVE ME XXX */
   3119 int
   3120 netbsd32_statfs(p, v, retval)
   3121 	struct proc *p;
   3122 	void *v;
   3123 	register_t *retval;
   3124 {
   3125 	struct netbsd32_statfs_args /* {
   3126 		syscallarg(const netbsd32_charp) path;
   3127 		syscallarg(netbsd32_statfsp_t) buf;
   3128 	} */ *uap = v;
   3129 	struct mount *mp;
   3130 	struct statfs *sp;
   3131 	struct netbsd32_statfs s32;
   3132 	int error;
   3133 	struct nameidata nd;
   3134 
   3135 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
   3136 	if ((error = namei(&nd)) != 0)
   3137 		return (error);
   3138 	mp = nd.ni_vp->v_mount;
   3139 	sp = &mp->mnt_stat;
   3140 	vrele(nd.ni_vp);
   3141 	if ((error = VFS_STATFS(mp, sp, p)) != 0)
   3142 		return (error);
   3143 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
   3144 	netbsd32_from_statfs(sp, &s32);
   3145 	return (copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32)));
   3146 }
   3147 
   3148 /* XXX MOVE ME XXX */
   3149 int
   3150 netbsd32_fstatfs(p, v, retval)
   3151 	struct proc *p;
   3152 	void *v;
   3153 	register_t *retval;
   3154 {
   3155 	struct netbsd32_fstatfs_args /* {
   3156 		syscallarg(int) fd;
   3157 		syscallarg(netbsd32_statfsp_t) buf;
   3158 	} */ *uap = v;
   3159 	struct file *fp;
   3160 	struct mount *mp;
   3161 	struct statfs *sp;
   3162 	struct netbsd32_statfs s32;
   3163 	int error;
   3164 
   3165 	/* getvnode() will use the descriptor for us */
   3166 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
   3167 		return (error);
   3168 	mp = ((struct vnode *)fp->f_data)->v_mount;
   3169 	sp = &mp->mnt_stat;
   3170 	if ((error = VFS_STATFS(mp, sp, p)) != 0)
   3171 		goto out;
   3172 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
   3173 	netbsd32_from_statfs(sp, &s32);
   3174 	error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32));
   3175  out:
   3176 	FILE_UNUSE(fp, p);
   3177 	return (error);
   3178 }
   3179 
   3180 #if defined(NFS) || defined(NFSSERVER)
   3181 int
   3182 netbsd32_getfh(p, v, retval)
   3183 	struct proc *p;
   3184 	void *v;
   3185 	register_t *retval;
   3186 {
   3187 	struct netbsd32_getfh_args /* {
   3188 		syscallarg(const netbsd32_charp) fname;
   3189 		syscallarg(netbsd32_fhandlep_t) fhp;
   3190 	} */ *uap = v;
   3191 	struct sys_getfh_args ua;
   3192 
   3193 	NETBSD32TOP_UAP(fname, const char);
   3194 	NETBSD32TOP_UAP(fhp, struct fhandle);
   3195 	/* Lucky for us a fhandlep_t doesn't change sizes */
   3196 	return (sys_getfh(p, &ua, retval));
   3197 }
   3198 #endif
   3199 
   3200 int
   3201 netbsd32_sysarch(p, v, retval)
   3202 	struct proc *p;
   3203 	void *v;
   3204 	register_t *retval;
   3205 {
   3206 	struct netbsd32_sysarch_args /* {
   3207 		syscallarg(int) op;
   3208 		syscallarg(netbsd32_voidp) parms;
   3209 	} */ *uap = v;
   3210 
   3211 	switch (SCARG(uap, op)) {
   3212 	default:
   3213 		printf("(%s) netbsd32_sysarch(%d)\n", MACHINE, SCARG(uap, op));
   3214 		return EINVAL;
   3215 	}
   3216 }
   3217 
   3218 int
   3219 netbsd32_pread(p, v, retval)
   3220 	struct proc *p;
   3221 	void *v;
   3222 	register_t *retval;
   3223 {
   3224 	struct netbsd32_pread_args /* {
   3225 		syscallarg(int) fd;
   3226 		syscallarg(netbsd32_voidp) buf;
   3227 		syscallarg(netbsd32_size_t) nbyte;
   3228 		syscallarg(int) pad;
   3229 		syscallarg(off_t) offset;
   3230 	} */ *uap = v;
   3231 	struct sys_pread_args ua;
   3232 	ssize_t rt;
   3233 	int error;
   3234 
   3235 	NETBSD32TO64_UAP(fd);
   3236 	NETBSD32TOP_UAP(buf, void);
   3237 	NETBSD32TOX_UAP(nbyte, size_t);
   3238 	NETBSD32TO64_UAP(pad);
   3239 	NETBSD32TO64_UAP(offset);
   3240 	error = sys_pread(p, &ua, (register_t *)&rt);
   3241 	*retval = rt;
   3242 	return (error);
   3243 }
   3244 
   3245 int
   3246 netbsd32_pwrite(p, v, retval)
   3247 	struct proc *p;
   3248 	void *v;
   3249 	register_t *retval;
   3250 {
   3251 	struct netbsd32_pwrite_args /* {
   3252 		syscallarg(int) fd;
   3253 		syscallarg(const netbsd32_voidp) buf;
   3254 		syscallarg(netbsd32_size_t) nbyte;
   3255 		syscallarg(int) pad;
   3256 		syscallarg(off_t) offset;
   3257 	} */ *uap = v;
   3258 	struct sys_pwrite_args ua;
   3259 	ssize_t rt;
   3260 	int error;
   3261 
   3262 	NETBSD32TO64_UAP(fd);
   3263 	NETBSD32TOP_UAP(buf, void);
   3264 	NETBSD32TOX_UAP(nbyte, size_t);
   3265 	NETBSD32TO64_UAP(pad);
   3266 	NETBSD32TO64_UAP(offset);
   3267 	error = sys_pwrite(p, &ua, (register_t *)&rt);
   3268 	*retval = rt;
   3269 	return (error);
   3270 }
   3271 
   3272 /* XXX MOVE ME XXX */
   3273 /* XXX MOVE ME NTP START XXX */
   3274 #ifdef NTP
   3275 int
   3276 netbsd32_ntp_gettime(p, v, retval)
   3277 	struct proc *p;
   3278 	void *v;
   3279 	register_t *retval;
   3280 {
   3281 	struct netbsd32_ntp_gettime_args /* {
   3282 		syscallarg(netbsd32_ntptimevalp_t) ntvp;
   3283 	} */ *uap = v;
   3284 	struct netbsd32_ntptimeval ntv32;
   3285 	struct timeval atv;
   3286 	struct ntptimeval ntv;
   3287 	int error = 0;
   3288 	int s;
   3289 
   3290 	/* The following are NTP variables */
   3291 	extern long time_maxerror;
   3292 	extern long time_esterror;
   3293 	extern int time_status;
   3294 	extern int time_state;	/* clock state */
   3295 	extern int time_status;	/* clock status bits */
   3296 
   3297 	if (SCARG(uap, ntvp)) {
   3298 		s = splclock();
   3299 #ifdef EXT_CLOCK
   3300 		/*
   3301 		 * The microtime() external clock routine returns a
   3302 		 * status code. If less than zero, we declare an error
   3303 		 * in the clock status word and return the kernel
   3304 		 * (software) time variable. While there are other
   3305 		 * places that call microtime(), this is the only place
   3306 		 * that matters from an application point of view.
   3307 		 */
   3308 		if (microtime(&atv) < 0) {
   3309 			time_status |= STA_CLOCKERR;
   3310 			ntv.time = time;
   3311 		} else
   3312 			time_status &= ~STA_CLOCKERR;
   3313 #else /* EXT_CLOCK */
   3314 		microtime(&atv);
   3315 #endif /* EXT_CLOCK */
   3316 		ntv.time = atv;
   3317 		ntv.maxerror = time_maxerror;
   3318 		ntv.esterror = time_esterror;
   3319 		(void) splx(s);
   3320 
   3321 		netbsd32_from_timeval(&ntv.time, &ntv32.time);
   3322 		ntv32.maxerror = (netbsd32_long)ntv.maxerror;
   3323 		ntv32.esterror = (netbsd32_long)ntv.esterror;
   3324 		error = copyout((caddr_t)&ntv32, (caddr_t)(u_long)SCARG(uap, ntvp),
   3325 		    sizeof(ntv32));
   3326 	}
   3327 	if (!error) {
   3328 
   3329 		/*
   3330 		 * Status word error decode. If any of these conditions
   3331 		 * occur, an error is returned, instead of the status
   3332 		 * word. Most applications will care only about the fact
   3333 		 * the system clock may not be trusted, not about the
   3334 		 * details.
   3335 		 *
   3336 		 * Hardware or software error
   3337 		 */
   3338 		if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
   3339 
   3340 		/*
   3341 		 * PPS signal lost when either time or frequency
   3342 		 * synchronization requested
   3343 		 */
   3344 		    (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
   3345 		    !(time_status & STA_PPSSIGNAL)) ||
   3346 
   3347 		/*
   3348 		 * PPS jitter exceeded when time synchronization
   3349 		 * requested
   3350 		 */
   3351 		    (time_status & STA_PPSTIME &&
   3352 		    time_status & STA_PPSJITTER) ||
   3353 
   3354 		/*
   3355 		 * PPS wander exceeded or calibration error when
   3356 		 * frequency synchronization requested
   3357 		 */
   3358 		    (time_status & STA_PPSFREQ &&
   3359 		    time_status & (STA_PPSWANDER | STA_PPSERROR)))
   3360 			*retval = TIME_ERROR;
   3361 		else
   3362 			*retval = time_state;
   3363 	}
   3364 	return (error);
   3365 }
   3366 
   3367 int
   3368 netbsd32_ntp_adjtime(p, v, retval)
   3369 	struct proc *p;
   3370 	void *v;
   3371 	register_t *retval;
   3372 {
   3373 	struct netbsd32_ntp_adjtime_args /* {
   3374 		syscallarg(netbsd32_timexp_t) tp;
   3375 	} */ *uap = v;
   3376 	struct netbsd32_timex ntv32;
   3377 	struct timex ntv;
   3378 	int error = 0;
   3379 	int modes;
   3380 	int s;
   3381 	extern long time_freq;		/* frequency offset (scaled ppm) */
   3382 	extern long time_maxerror;
   3383 	extern long time_esterror;
   3384 	extern int time_state;	/* clock state */
   3385 	extern int time_status;	/* clock status bits */
   3386 	extern long time_constant;		/* pll time constant */
   3387 	extern long time_offset;		/* time offset (us) */
   3388 	extern long time_tolerance;	/* frequency tolerance (scaled ppm) */
   3389 	extern long time_precision;	/* clock precision (us) */
   3390 
   3391 	if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), (caddr_t)&ntv32,
   3392 			sizeof(ntv32))))
   3393 		return (error);
   3394 	netbsd32_to_timex(&ntv32, &ntv);
   3395 
   3396 	/*
   3397 	 * Update selected clock variables - only the superuser can
   3398 	 * change anything. Note that there is no error checking here on
   3399 	 * the assumption the superuser should know what it is doing.
   3400 	 */
   3401 	modes = ntv.modes;
   3402 	if (modes != 0 && (error = suser(p->p_ucred, &p->p_acflag)))
   3403 		return (error);
   3404 
   3405 	s = splclock();
   3406 	if (modes & MOD_FREQUENCY)
   3407 #ifdef PPS_SYNC
   3408 		time_freq = ntv.freq - pps_freq;
   3409 #else /* PPS_SYNC */
   3410 		time_freq = ntv.freq;
   3411 #endif /* PPS_SYNC */
   3412 	if (modes & MOD_MAXERROR)
   3413 		time_maxerror = ntv.maxerror;
   3414 	if (modes & MOD_ESTERROR)
   3415 		time_esterror = ntv.esterror;
   3416 	if (modes & MOD_STATUS) {
   3417 		time_status &= STA_RONLY;
   3418 		time_status |= ntv.status & ~STA_RONLY;
   3419 	}
   3420 	if (modes & MOD_TIMECONST)
   3421 		time_constant = ntv.constant;
   3422 	if (modes & MOD_OFFSET)
   3423 		hardupdate(ntv.offset);
   3424 
   3425 	/*
   3426 	 * Retrieve all clock variables
   3427 	 */
   3428 	if (time_offset < 0)
   3429 		ntv.offset = -(-time_offset >> SHIFT_UPDATE);
   3430 	else
   3431 		ntv.offset = time_offset >> SHIFT_UPDATE;
   3432 #ifdef PPS_SYNC
   3433 	ntv.freq = time_freq + pps_freq;
   3434 #else /* PPS_SYNC */
   3435 	ntv.freq = time_freq;
   3436 #endif /* PPS_SYNC */
   3437 	ntv.maxerror = time_maxerror;
   3438 	ntv.esterror = time_esterror;
   3439 	ntv.status = time_status;
   3440 	ntv.constant = time_constant;
   3441 	ntv.precision = time_precision;
   3442 	ntv.tolerance = time_tolerance;
   3443 #ifdef PPS_SYNC
   3444 	ntv.shift = pps_shift;
   3445 	ntv.ppsfreq = pps_freq;
   3446 	ntv.jitter = pps_jitter >> PPS_AVG;
   3447 	ntv.stabil = pps_stabil;
   3448 	ntv.calcnt = pps_calcnt;
   3449 	ntv.errcnt = pps_errcnt;
   3450 	ntv.jitcnt = pps_jitcnt;
   3451 	ntv.stbcnt = pps_stbcnt;
   3452 #endif /* PPS_SYNC */
   3453 	(void)splx(s);
   3454 
   3455 	netbsd32_from_timex(&ntv, &ntv32);
   3456 	error = copyout((caddr_t)&ntv32, (caddr_t)(u_long)SCARG(uap, tp),
   3457 	    sizeof(ntv32));
   3458 	if (!error) {
   3459 
   3460 		/*
   3461 		 * Status word error decode. See comments in
   3462 		 * ntp_gettime() routine.
   3463 		 */
   3464 		if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
   3465 		    (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
   3466 		    !(time_status & STA_PPSSIGNAL)) ||
   3467 		    (time_status & STA_PPSTIME &&
   3468 		    time_status & STA_PPSJITTER) ||
   3469 		    (time_status & STA_PPSFREQ &&
   3470 		    time_status & (STA_PPSWANDER | STA_PPSERROR)))
   3471 			*retval = TIME_ERROR;
   3472 		else
   3473 			*retval = time_state;
   3474 	}
   3475 	return error;
   3476 }
   3477 #else
   3478 int
   3479 netbsd32_ntp_gettime(p, v, retval)
   3480 	struct proc *p;
   3481 	void *v;
   3482 	register_t *retval;
   3483 {
   3484 
   3485 	return (ENOSYS);
   3486 }
   3487 
   3488 int
   3489 netbsd32_ntp_adjtime(p, v, retval)
   3490 	struct proc *p;
   3491 	void *v;
   3492 	register_t *retval;
   3493 {
   3494 
   3495 	return (ENOSYS);
   3496 }
   3497 #endif
   3498 /* XXX MOVE ME NTP END XXX */
   3499 
   3500 int
   3501 netbsd32_setgid(p, v, retval)
   3502 	struct proc *p;
   3503 	void *v;
   3504 	register_t *retval;
   3505 {
   3506 	struct netbsd32_setgid_args /* {
   3507 		syscallarg(gid_t) gid;
   3508 	} */ *uap = v;
   3509 	struct sys_setgid_args ua;
   3510 
   3511 	NETBSD32TO64_UAP(gid);
   3512 	return (sys_setgid(p, v, retval));
   3513 }
   3514 
   3515 int
   3516 netbsd32_setegid(p, v, retval)
   3517 	struct proc *p;
   3518 	void *v;
   3519 	register_t *retval;
   3520 {
   3521 	struct netbsd32_setegid_args /* {
   3522 		syscallarg(gid_t) egid;
   3523 	} */ *uap = v;
   3524 	struct sys_setegid_args ua;
   3525 
   3526 	NETBSD32TO64_UAP(egid);
   3527 	return (sys_setegid(p, v, retval));
   3528 }
   3529 
   3530 int
   3531 netbsd32_seteuid(p, v, retval)
   3532 	struct proc *p;
   3533 	void *v;
   3534 	register_t *retval;
   3535 {
   3536 	struct netbsd32_seteuid_args /* {
   3537 		syscallarg(gid_t) euid;
   3538 	} */ *uap = v;
   3539 	struct sys_seteuid_args ua;
   3540 
   3541 	NETBSD32TO64_UAP(euid);
   3542 	return (sys_seteuid(p, v, retval));
   3543 }
   3544 
   3545 #ifdef LFS
   3546 int
   3547 netbsd32_sys_lfs_bmapv(p, v, retval)
   3548 	struct proc *p;
   3549 	void *v;
   3550 	register_t *retval;
   3551 {
   3552 
   3553 	return (ENOSYS);	/* XXX */
   3554 }
   3555 
   3556 int
   3557 netbsd32_sys_lfs_markv(p, v, retval)
   3558 	struct proc *p;
   3559 	void *v;
   3560 	register_t *retval;
   3561 {
   3562 
   3563 	return (ENOSYS);	/* XXX */
   3564 }
   3565 
   3566 int
   3567 netbsd32_sys_lfs_segclean(p, v, retval)
   3568 	struct proc *p;
   3569 	void *v;
   3570 	register_t *retval;
   3571 {
   3572 
   3573 	return (ENOSYS);	/* XXX */
   3574 }
   3575 
   3576 int
   3577 netbsd32_sys_lfs_segwait(p, v, retval)
   3578 	struct proc *p;
   3579 	void *v;
   3580 	register_t *retval;
   3581 {
   3582 
   3583 	return (ENOSYS);	/* XXX */
   3584 }
   3585 #endif
   3586 
   3587 int
   3588 netbsd32_pathconf(p, v, retval)
   3589 	struct proc *p;
   3590 	void *v;
   3591 	register_t *retval;
   3592 {
   3593 	struct netbsd32_pathconf_args /* {
   3594 		syscallarg(int) fd;
   3595 		syscallarg(int) name;
   3596 	} */ *uap = v;
   3597 	struct sys_pathconf_args ua;
   3598 	long rt;
   3599 	int error;
   3600 
   3601 	NETBSD32TOP_UAP(path, const char);
   3602 	NETBSD32TO64_UAP(name);
   3603 	error = sys_pathconf(p, &ua, (register_t *)&rt);
   3604 	*retval = rt;
   3605 	return (error);
   3606 }
   3607 
   3608 int
   3609 netbsd32_fpathconf(p, v, retval)
   3610 	struct proc *p;
   3611 	void *v;
   3612 	register_t *retval;
   3613 {
   3614 	struct netbsd32_fpathconf_args /* {
   3615 		syscallarg(int) fd;
   3616 		syscallarg(int) name;
   3617 	} */ *uap = v;
   3618 	struct sys_fpathconf_args ua;
   3619 	long rt;
   3620 	int error;
   3621 
   3622 	NETBSD32TO64_UAP(fd);
   3623 	NETBSD32TO64_UAP(name);
   3624 	error = sys_fpathconf(p, &ua, (register_t *)&rt);
   3625 	*retval = rt;
   3626 	return (error);
   3627 }
   3628 
   3629 int
   3630 netbsd32_getrlimit(p, v, retval)
   3631 	struct proc *p;
   3632 	void *v;
   3633 	register_t *retval;
   3634 {
   3635 	struct netbsd32_getrlimit_args /* {
   3636 		syscallarg(int) which;
   3637 		syscallarg(netbsd32_rlimitp_t) rlp;
   3638 	} */ *uap = v;
   3639 	int which = SCARG(uap, which);
   3640 
   3641 	if ((u_int)which >= RLIM_NLIMITS)
   3642 		return (EINVAL);
   3643 	return (copyout(&p->p_rlimit[which], (caddr_t)(u_long)SCARG(uap, rlp),
   3644 	    sizeof(struct rlimit)));
   3645 }
   3646 
   3647 int
   3648 netbsd32_setrlimit(p, v, retval)
   3649 	struct proc *p;
   3650 	void *v;
   3651 	register_t *retval;
   3652 {
   3653 	struct netbsd32_setrlimit_args /* {
   3654 		syscallarg(int) which;
   3655 		syscallarg(const netbsd32_rlimitp_t) rlp;
   3656 	} */ *uap = v;
   3657 		int which = SCARG(uap, which);
   3658 	struct rlimit alim;
   3659 	int error;
   3660 
   3661 	error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
   3662 	if (error)
   3663 		return (error);
   3664 	return (dosetrlimit(p, p->p_cred, which, &alim));
   3665 }
   3666 
   3667 int
   3668 netbsd32_mmap(p, v, retval)
   3669 	struct proc *p;
   3670 	void *v;
   3671 	register_t *retval;
   3672 {
   3673 	struct netbsd32_mmap_args /* {
   3674 		syscallarg(netbsd32_voidp) addr;
   3675 		syscallarg(netbsd32_size_t) len;
   3676 		syscallarg(int) prot;
   3677 		syscallarg(int) flags;
   3678 		syscallarg(int) fd;
   3679 		syscallarg(netbsd32_long) pad;
   3680 		syscallarg(off_t) pos;
   3681 	} */ *uap = v;
   3682 	struct sys_mmap_args ua;
   3683 	void *rt;
   3684 	int error;
   3685 
   3686 	NETBSD32TOP_UAP(addr, void);
   3687 	NETBSD32TOX_UAP(len, size_t);
   3688 	NETBSD32TO64_UAP(prot);
   3689 	NETBSD32TO64_UAP(flags);
   3690 	NETBSD32TO64_UAP(fd);
   3691 	NETBSD32TOX_UAP(pad, long);
   3692 	NETBSD32TOX_UAP(pos, off_t);
   3693 	error = sys_mmap(p, &ua, (register_t *)&rt);
   3694 	if ((u_long)rt > (u_long)UINT_MAX) {
   3695 		printf("netbsd32_mmap: retval out of range: %p", rt);
   3696 		/* Should try to recover and return an error here. */
   3697 	}
   3698 	*retval = (netbsd32_voidp)(u_long)rt;
   3699 	return (error);
   3700 }
   3701 
   3702 int
   3703 netbsd32_lseek(p, v, retval)
   3704 	struct proc *p;
   3705 	void *v;
   3706 	register_t *retval;
   3707 {
   3708 	struct netbsd32_lseek_args /* {
   3709 		syscallarg(int) fd;
   3710 		syscallarg(int) pad;
   3711 		syscallarg(off_t) offset;
   3712 		syscallarg(int) whence;
   3713 	} */ *uap = v;
   3714 	struct sys_lseek_args ua;
   3715 
   3716 	NETBSD32TO64_UAP(fd);
   3717 	NETBSD32TO64_UAP(pad);
   3718 	NETBSD32TO64_UAP(offset);
   3719 	NETBSD32TO64_UAP(whence);
   3720 	return (sys_lseek(p, &ua, retval));
   3721 }
   3722 
   3723 int
   3724 netbsd32_truncate(p, v, retval)
   3725 	struct proc *p;
   3726 	void *v;
   3727 	register_t *retval;
   3728 {
   3729 	struct netbsd32_truncate_args /* {
   3730 		syscallarg(const netbsd32_charp) path;
   3731 		syscallarg(int) pad;
   3732 		syscallarg(off_t) length;
   3733 	} */ *uap = v;
   3734 	struct sys_truncate_args ua;
   3735 
   3736 	NETBSD32TOP_UAP(path, const char);
   3737 	NETBSD32TO64_UAP(pad);
   3738 	NETBSD32TO64_UAP(length);
   3739 	return (sys_truncate(p, &ua, retval));
   3740 }
   3741 
   3742 int
   3743 netbsd32_ftruncate(p, v, retval)
   3744 	struct proc *p;
   3745 	void *v;
   3746 	register_t *retval;
   3747 {
   3748 	struct netbsd32_ftruncate_args /* {
   3749 		syscallarg(int) fd;
   3750 		syscallarg(int) pad;
   3751 		syscallarg(off_t) length;
   3752 	} */ *uap = v;
   3753 	struct sys_ftruncate_args ua;
   3754 
   3755 	NETBSD32TO64_UAP(fd);
   3756 	NETBSD32TO64_UAP(pad);
   3757 	NETBSD32TO64_UAP(length);
   3758 	return (sys_ftruncate(p, &ua, retval));
   3759 }
   3760 
   3761 /* XXX MOVE ME XXX */
   3762 int uvm_sysctl32(int *, u_int, void *, size_t *, void *, size_t, struct proc *);
   3763 int kern_sysctl32(int *, u_int, void *, size_t *, void *, size_t, struct proc *);
   3764 
   3765 /*
   3766  * uvm_sysctl32: sysctl hook into UVM system, handling special 32-bit
   3767  * sensitive calls.
   3768  */
   3769 int
   3770 uvm_sysctl32(name, namelen, oldp, oldlenp, newp, newlen, p)
   3771 	int *name;
   3772 	u_int namelen;
   3773 	void *oldp;
   3774 	size_t *oldlenp;
   3775 	void *newp;
   3776 	size_t newlen;
   3777 	struct proc *p;
   3778 {
   3779 	struct netbsd32_loadavg av32;
   3780 
   3781 	/* all sysctl names at this level are terminal */
   3782 	if (namelen != 1)
   3783 		return (ENOTDIR);		/* overloaded */
   3784 
   3785 	switch (name[0]) {
   3786 	case VM_LOADAVG:
   3787 		netbsd32_from_loadavg(&av32, &averunnable);
   3788 		return (sysctl_rdstruct(oldp, oldlenp, newp, &av32,
   3789 		    sizeof(av32)));
   3790 
   3791 	default:
   3792 		return (EOPNOTSUPP);
   3793 	}
   3794 	/* NOTREACHED */
   3795 }
   3796 
   3797 /* XXX MOVE ME XXX */
   3798 /*
   3799  * kern_sysctl32: sysctl hook into KERN system, handling special 32-bit
   3800  * sensitive calls.
   3801  */
   3802 int
   3803 kern_sysctl32(name, namelen, oldp, oldlenp, newp, newlen, p)
   3804 	int *name;
   3805 	u_int namelen;
   3806 	void *oldp;
   3807 	size_t *oldlenp;
   3808 	void *newp;
   3809 	size_t newlen;
   3810 	struct proc *p;
   3811 {
   3812 	struct netbsd32_timeval bt32;
   3813 
   3814 	/* All sysctl names at this level, except for a few, are terminal. */
   3815 	switch (name[0]) {
   3816 #if 0
   3817 	case KERN_PROC:
   3818 	case KERN_PROC2:
   3819 	case KERN_PROF:
   3820 	case KERN_MBUF:
   3821 	case KERN_PROC_ARGS:
   3822 	case KERN_SYSVIPC_INFO:
   3823 		/* Not terminal. */
   3824 		break;
   3825 #endif
   3826 	default:
   3827 		if (namelen != 1)
   3828 			return (ENOTDIR);	/* overloaded */
   3829 	}
   3830 
   3831 	switch (name[0]) {
   3832 	case KERN_BOOTTIME:
   3833 		netbsd32_from_timeval(&boottime, &bt32);
   3834 		return (sysctl_rdstruct(oldp, oldlenp, newp, &bt32,
   3835 		    sizeof(struct netbsd32_timeval)));
   3836 
   3837 	default:
   3838 		return (EOPNOTSUPP);
   3839 	}
   3840 	/* NOTREACHED */
   3841 }
   3842 
   3843 /* XXX MOVE ME XXX */
   3844 int
   3845 netbsd32___sysctl(p, v, retval)
   3846 	struct proc *p;
   3847 	void *v;
   3848 	register_t *retval;
   3849 {
   3850 	struct netbsd32___sysctl_args /* {
   3851 		syscallarg(netbsd32_intp) name;
   3852 		syscallarg(u_int) namelen;
   3853 		syscallarg(netbsd32_voidp) old;
   3854 		syscallarg(netbsd32_size_tp) oldlenp;
   3855 		syscallarg(netbsd32_voidp) new;
   3856 		syscallarg(netbsd32_size_t) newlen;
   3857 	} */ *uap = v;
   3858 	int error;
   3859 	netbsd32_size_t savelen = 0;
   3860 	size_t oldlen = 0;
   3861 	sysctlfn *fn;
   3862 	int name[CTL_MAXNAME];
   3863 
   3864 /*
   3865  * Some of these sysctl functions do their own copyin/copyout.
   3866  * We need to disable or emulate the ones that need their
   3867  * arguments converted.
   3868  */
   3869 
   3870 	if (SCARG(uap, new) != NULL &&
   3871 	    (error = suser(p->p_ucred, &p->p_acflag)))
   3872 		return (error);
   3873 	/*
   3874 	 * all top-level sysctl names are non-terminal
   3875 	 */
   3876 	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
   3877 		return (EINVAL);
   3878 	error = copyin((caddr_t)(u_long)SCARG(uap, name), &name,
   3879 		       SCARG(uap, namelen) * sizeof(int));
   3880 	if (error)
   3881 		return (error);
   3882 
   3883 	switch (name[0]) {
   3884 	case CTL_KERN:
   3885 		switch (name[1]) {
   3886 #if 0
   3887 		case KERN_FILE:
   3888 		case KERN_NTPTIME:
   3889 		case KERN_SYSVIPC_INFO:
   3890 #endif
   3891 		case KERN_BOOTTIME:
   3892 			fn = kern_sysctl32;
   3893 			break;
   3894 		default:
   3895 			fn = kern_sysctl;
   3896 			break;
   3897 		}
   3898 		break;
   3899 	case CTL_HW:
   3900 		fn = hw_sysctl;
   3901 		break;
   3902 	case CTL_VM:
   3903 		switch (name[1]) {
   3904 		case VM_LOADAVG:
   3905 			fn = uvm_sysctl32;	/* need to convert a `long' */
   3906 			break;
   3907 		default:
   3908 			fn = uvm_sysctl;
   3909 			break;
   3910 		}
   3911 		break;
   3912 	case CTL_NET:
   3913 		fn = net_sysctl;
   3914 		break;
   3915 	case CTL_VFS:
   3916 		fn = vfs_sysctl;
   3917 		break;
   3918 	case CTL_MACHDEP:
   3919 		fn = cpu_sysctl;
   3920 		break;
   3921 #ifdef DEBUG
   3922 	case CTL_DEBUG:
   3923 		fn = debug_sysctl;
   3924 		break;
   3925 #endif
   3926 #ifdef DDB
   3927 	case CTL_DDB:
   3928 		fn = ddb_sysctl;
   3929 		break;
   3930 #endif
   3931 	case CTL_PROC:
   3932 		fn = proc_sysctl;
   3933 		break;
   3934 	default:
   3935 		return (EOPNOTSUPP);
   3936 	}
   3937 
   3938 	/*
   3939 	 * XXX Hey, we wire `old', but what about `new'?
   3940 	 */
   3941 
   3942 	if (SCARG(uap, oldlenp) &&
   3943 	    (error = copyin((caddr_t)(u_long)SCARG(uap, oldlenp), &savelen,
   3944 	     sizeof(savelen))))
   3945 		return (error);
   3946 	if (SCARG(uap, old) != NULL) {
   3947 		error = lockmgr(&sysctl_memlock, LK_EXCLUSIVE, NULL);
   3948 		if (error)
   3949 			return (error);
   3950 		if (uvm_vslock(p, (void *)(u_long)SCARG(uap, old), savelen,
   3951 		    VM_PROT_READ|VM_PROT_WRITE) != KERN_SUCCESS) {
   3952 			(void) lockmgr(&sysctl_memlock, LK_RELEASE, NULL);
   3953 			return (EFAULT);
   3954 		}
   3955 		oldlen = savelen;
   3956 	}
   3957 	error = (*fn)(name + 1, SCARG(uap, namelen) - 1,
   3958 		      (void *)(u_long)SCARG(uap, old), &oldlen,
   3959 		      (void *)(u_long)SCARG(uap, new), SCARG(uap, newlen), p);
   3960 	if (SCARG(uap, old) != NULL) {
   3961 		uvm_vsunlock(p, (void *)(u_long)SCARG(uap, old), savelen);
   3962 		(void) lockmgr(&sysctl_memlock, LK_RELEASE, NULL);
   3963 	}
   3964 	savelen = oldlen;
   3965 	if (error)
   3966 		return (error);
   3967 	if (SCARG(uap, oldlenp))
   3968 		error = copyout(&savelen,
   3969 		    (caddr_t)(u_long)SCARG(uap, oldlenp), sizeof(savelen));
   3970 	return (error);
   3971 }
   3972 
   3973 int
   3974 netbsd32_mlock(p, v, retval)
   3975 	struct proc *p;
   3976 	void *v;
   3977 	register_t *retval;
   3978 {
   3979 	struct netbsd32_mlock_args /* {
   3980 		syscallarg(const netbsd32_voidp) addr;
   3981 		syscallarg(netbsd32_size_t) len;
   3982 	} */ *uap = v;
   3983 	struct sys_mlock_args ua;
   3984 
   3985 	NETBSD32TOP_UAP(addr, const void);
   3986 	NETBSD32TO64_UAP(len);
   3987 	return (sys_mlock(p, &ua, retval));
   3988 }
   3989 
   3990 int
   3991 netbsd32_munlock(p, v, retval)
   3992 	struct proc *p;
   3993 	void *v;
   3994 	register_t *retval;
   3995 {
   3996 	struct netbsd32_munlock_args /* {
   3997 		syscallarg(const netbsd32_voidp) addr;
   3998 		syscallarg(netbsd32_size_t) len;
   3999 	} */ *uap = v;
   4000 	struct sys_munlock_args ua;
   4001 
   4002 	NETBSD32TOP_UAP(addr, const void);
   4003 	NETBSD32TO64_UAP(len);
   4004 	return (sys_munlock(p, &ua, retval));
   4005 }
   4006 
   4007 int
   4008 netbsd32_undelete(p, v, retval)
   4009 	struct proc *p;
   4010 	void *v;
   4011 	register_t *retval;
   4012 {
   4013 	struct netbsd32_undelete_args /* {
   4014 		syscallarg(const netbsd32_charp) path;
   4015 	} */ *uap = v;
   4016 	struct sys_undelete_args ua;
   4017 
   4018 	NETBSD32TOP_UAP(path, const char);
   4019 	return (sys_undelete(p, &ua, retval));
   4020 }
   4021 
   4022 /* XXX MOVE ME XXX */
   4023 int
   4024 netbsd32_futimes(p, v, retval)
   4025 	struct proc *p;
   4026 	void *v;
   4027 	register_t *retval;
   4028 {
   4029 	struct netbsd32_futimes_args /* {
   4030 		syscallarg(int) fd;
   4031 		syscallarg(const netbsd32_timevalp_t) tptr;
   4032 	} */ *uap = v;
   4033 	int error;
   4034 	struct file *fp;
   4035 
   4036 	/* getvnode() will use the descriptor for us */
   4037 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
   4038 		return (error);
   4039 
   4040 	error = change_utimes32((struct vnode *)fp->f_data,
   4041 				SCARG(uap, tptr), p);
   4042 	FILE_UNUSE(fp, p);
   4043 	return (error);
   4044 }
   4045 
   4046 int
   4047 netbsd32_getpgid(p, v, retval)
   4048 	struct proc *p;
   4049 	void *v;
   4050 	register_t *retval;
   4051 {
   4052 	struct netbsd32_getpgid_args /* {
   4053 		syscallarg(pid_t) pid;
   4054 	} */ *uap = v;
   4055 	struct sys_getpgid_args ua;
   4056 
   4057 	NETBSD32TO64_UAP(pid);
   4058 	return (sys_getpgid(p, &ua, retval));
   4059 }
   4060 
   4061 int
   4062 netbsd32_reboot(p, v, retval)
   4063 	struct proc *p;
   4064 	void *v;
   4065 	register_t *retval;
   4066 {
   4067 	struct netbsd32_reboot_args /* {
   4068 		syscallarg(int) opt;
   4069 		syscallarg(netbsd32_charp) bootstr;
   4070 	} */ *uap = v;
   4071 	struct sys_reboot_args ua;
   4072 
   4073 	NETBSD32TO64_UAP(opt);
   4074 	NETBSD32TOP_UAP(bootstr, char);
   4075 	return (sys_reboot(p, &ua, retval));
   4076 }
   4077 
   4078 int
   4079 netbsd32_poll(p, v, retval)
   4080 	struct proc *p;
   4081 	void *v;
   4082 	register_t *retval;
   4083 {
   4084 	struct netbsd32_poll_args /* {
   4085 		syscallarg(netbsd32_pollfdp_t) fds;
   4086 		syscallarg(u_int) nfds;
   4087 		syscallarg(int) timeout;
   4088 	} */ *uap = v;
   4089 	struct sys_poll_args ua;
   4090 
   4091 	NETBSD32TOP_UAP(fds, struct pollfd);
   4092 	NETBSD32TO64_UAP(nfds);
   4093 	NETBSD32TO64_UAP(timeout);
   4094 	return (sys_poll(p, &ua, retval));
   4095 }
   4096 
   4097 /* XXX MOVE ME XXX */
   4098 /* XXX MOVE ME IPC START */
   4099 #if defined(SYSVSEM)
   4100 /*
   4101  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
   4102  *
   4103  * This is BSD.  We won't support System V IPC.
   4104  * Too much work.
   4105  *
   4106  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
   4107  */
   4108 int
   4109 netbsd32___semctl14(p, v, retval)
   4110 	struct proc *p;
   4111 	void *v;
   4112 	register_t *retval;
   4113 {
   4114 #if 0
   4115 	struct netbsd32___semctl_args /* {
   4116 		syscallarg(int) semid;
   4117 		syscallarg(int) semnum;
   4118 		syscallarg(int) cmd;
   4119 		syscallarg(netbsd32_semunu_t *) arg;
   4120 	} */ *uap = v;
   4121 	union netbsd32_semun sem32;
   4122 	int semid = SCARG(uap, semid);
   4123 	int semnum = SCARG(uap, semnum);
   4124 	int cmd = SCARG(uap, cmd);
   4125 	union netbsd32_semun *arg = (void*)(u_long)SCARG(uap, arg);
   4126 	union netbsd32_semun real_arg;
   4127 	struct ucred *cred = p->p_ucred;
   4128 	int i, rval, eval;
   4129 	struct netbsd32_semid_ds sbuf;
   4130 	struct semid_ds *semaptr;
   4131 
   4132 	semlock(p);
   4133 
   4134 	semid = IPCID_TO_IX(semid);
   4135 	if (semid < 0 || semid >= seminfo.semmsl)
   4136 		return(EINVAL);
   4137 
   4138 	semaptr = &sema[semid];
   4139 	if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
   4140 	    semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
   4141 		return(EINVAL);
   4142 
   4143 	eval = 0;
   4144 	rval = 0;
   4145 
   4146 	switch (cmd) {
   4147 	case IPC_RMID:
   4148 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
   4149 			return(eval);
   4150 		semaptr->sem_perm.cuid = cred->cr_uid;
   4151 		semaptr->sem_perm.uid = cred->cr_uid;
   4152 		semtot -= semaptr->sem_nsems;
   4153 		for (i = semaptr->_sem_base - sem; i < semtot; i++)
   4154 			sem[i] = sem[i + semaptr->sem_nsems];
   4155 		for (i = 0; i < seminfo.semmni; i++) {
   4156 			if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
   4157 			    sema[i]._sem_base > semaptr->_sem_base)
   4158 				sema[i]._sem_base -= semaptr->sem_nsems;
   4159 		}
   4160 		semaptr->sem_perm.mode = 0;
   4161 		semundo_clear(semid, -1);
   4162 		wakeup((caddr_t)semaptr);
   4163 		break;
   4164 
   4165 	case IPC_SET:
   4166 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
   4167 			return(eval);
   4168 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
   4169 			return(eval);
   4170 		if ((eval = copyin((caddr_t)(u_long)real_arg.buf, (caddr_t)&sbuf,
   4171 		    sizeof(sbuf))) != 0)
   4172 			return(eval);
   4173 		semaptr->sem_perm.uid = sbuf.sem_perm.uid;
   4174 		semaptr->sem_perm.gid = sbuf.sem_perm.gid;
   4175 		semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
   4176 		    (sbuf.sem_perm.mode & 0777);
   4177 		semaptr->sem_ctime = time.tv_sec;
   4178 		break;
   4179 
   4180 	case IPC_STAT:
   4181 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
   4182 			return(eval);
   4183 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
   4184 			return(eval);
   4185 		eval = copyout((caddr_t)semaptr, (caddr_t)(u_long)real_arg.buf,
   4186 		    sizeof(struct semid_ds));
   4187 		break;
   4188 
   4189 	case GETNCNT:
   4190 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
   4191 			return(eval);
   4192 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
   4193 			return(EINVAL);
   4194 		rval = semaptr->_sem_base[semnum].semncnt;
   4195 		break;
   4196 
   4197 	case GETPID:
   4198 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
   4199 			return(eval);
   4200 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
   4201 			return(EINVAL);
   4202 		rval = semaptr->_sem_base[semnum].sempid;
   4203 		break;
   4204 
   4205 	case GETVAL:
   4206 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
   4207 			return(eval);
   4208 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
   4209 			return(EINVAL);
   4210 		rval = semaptr->_sem_base[semnum].semval;
   4211 		break;
   4212 
   4213 	case GETALL:
   4214 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
   4215 			return(eval);
   4216 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
   4217 			return(eval);
   4218 		for (i = 0; i < semaptr->sem_nsems; i++) {
   4219 			eval = copyout((caddr_t)&semaptr->_sem_base[i].semval,
   4220 			    &real_arg.array[i], sizeof(real_arg.array[0]));
   4221 			if (eval != 0)
   4222 				break;
   4223 		}
   4224 		break;
   4225 
   4226 	case GETZCNT:
   4227 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
   4228 			return(eval);
   4229 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
   4230 			return(EINVAL);
   4231 		rval = semaptr->_sem_base[semnum].semzcnt;
   4232 		break;
   4233 
   4234 	case SETVAL:
   4235 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
   4236 			return(eval);
   4237 		if (semnum < 0 || semnum >= semaptr->sem_nsems)
   4238 			return(EINVAL);
   4239 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
   4240 			return(eval);
   4241 		semaptr->_sem_base[semnum].semval = real_arg.val;
   4242 		semundo_clear(semid, semnum);
   4243 		wakeup((caddr_t)semaptr);
   4244 		break;
   4245 
   4246 	case SETALL:
   4247 		if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
   4248 			return(eval);
   4249 		if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
   4250 			return(eval);
   4251 		for (i = 0; i < semaptr->sem_nsems; i++) {
   4252 			eval = copyin(&real_arg.array[i],
   4253 			    (caddr_t)&semaptr->_sem_base[i].semval,
   4254 			    sizeof(real_arg.array[0]));
   4255 			if (eval != 0)
   4256 				break;
   4257 		}
   4258 		semundo_clear(semid, -1);
   4259 		wakeup((caddr_t)semaptr);
   4260 		break;
   4261 
   4262 	default:
   4263 		return(EINVAL);
   4264 	}
   4265 
   4266 	if (eval == 0)
   4267 		*retval = rval;
   4268 	return(eval);
   4269 #else
   4270 	return (ENOSYS);
   4271 #endif
   4272 }
   4273 
   4274 int
   4275 netbsd32_semget(p, v, retval)
   4276 	struct proc *p;
   4277 	void *v;
   4278 	register_t *retval;
   4279 {
   4280 	struct netbsd32_semget_args /* {
   4281 		syscallarg(netbsd32_key_t) key;
   4282 		syscallarg(int) nsems;
   4283 		syscallarg(int) semflg;
   4284 	} */ *uap = v;
   4285 	struct sys_semget_args ua;
   4286 
   4287 	NETBSD32TOX_UAP(key, key_t);
   4288 	NETBSD32TO64_UAP(nsems);
   4289 	NETBSD32TO64_UAP(semflg);
   4290 	return (sys_semget(p, &ua, retval));
   4291 }
   4292 
   4293 int
   4294 netbsd32_semop(p, v, retval)
   4295 	struct proc *p;
   4296 	void *v;
   4297 	register_t *retval;
   4298 {
   4299 	struct netbsd32_semop_args /* {
   4300 		syscallarg(int) semid;
   4301 		syscallarg(netbsd32_sembufp_t) sops;
   4302 		syscallarg(netbsd32_size_t) nsops;
   4303 	} */ *uap = v;
   4304 	struct sys_semop_args ua;
   4305 
   4306 	NETBSD32TO64_UAP(semid);
   4307 	NETBSD32TOP_UAP(sops, struct sembuf);
   4308 	NETBSD32TOX_UAP(nsops, size_t);
   4309 	return (sys_semop(p, &ua, retval));
   4310 }
   4311 
   4312 int
   4313 netbsd32_semconfig(p, v, retval)
   4314 	struct proc *p;
   4315 	void *v;
   4316 	register_t *retval;
   4317 {
   4318 	struct netbsd32_semconfig_args /* {
   4319 		syscallarg(int) flag;
   4320 	} */ *uap = v;
   4321 	struct sys_semconfig_args ua;
   4322 
   4323 	NETBSD32TO64_UAP(flag);
   4324 	return (sys_semconfig(p, &ua, retval));
   4325 }
   4326 #endif /* SYSVSEM */
   4327 
   4328 #if defined(SYSVMSG)
   4329 
   4330 int
   4331 netbsd32___msgctl13(p, v, retval)
   4332 	struct proc *p;
   4333 	void *v;
   4334 	register_t *retval;
   4335 {
   4336 #if 0
   4337 	struct netbsd32_msgctl_args /* {
   4338 		syscallarg(int) msqid;
   4339 		syscallarg(int) cmd;
   4340 		syscallarg(netbsd32_msqid_dsp_t) buf;
   4341 	} */ *uap = v;
   4342 	struct sys_msgctl_args ua;
   4343 	struct msqid_ds ds;
   4344 	struct netbsd32_msqid_ds *ds32p;
   4345 	int error;
   4346 
   4347 	NETBSD32TO64_UAP(msqid);
   4348 	NETBSD32TO64_UAP(cmd);
   4349 	ds32p = (struct netbsd32_msqid_ds *)(u_long)SCARG(uap, buf);
   4350 	if (ds32p) {
   4351 		SCARG(&ua, buf) = NULL;
   4352 		netbsd32_to_msqid_ds(ds32p, &ds);
   4353 	} else
   4354 		SCARG(&ua, buf) = NULL;
   4355 	error = sys_msgctl(p, &ua, retval);
   4356 	if (error)
   4357 		return (error);
   4358 
   4359 	if (ds32p)
   4360 		netbsd32_from_msqid_ds(&ds, ds32p);
   4361 	return (0);
   4362 #else
   4363 	return (ENOSYS);
   4364 #endif
   4365 }
   4366 
   4367 int
   4368 netbsd32_msgget(p, v, retval)
   4369 	struct proc *p;
   4370 	void *v;
   4371 	register_t *retval;
   4372 {
   4373 #if 0
   4374 	struct netbsd32_msgget_args /* {
   4375 		syscallarg(netbsd32_key_t) key;
   4376 		syscallarg(int) msgflg;
   4377 	} */ *uap = v;
   4378 	struct sys_msgget_args ua;
   4379 
   4380 	NETBSD32TOX_UAP(key, key_t);
   4381 	NETBSD32TO64_UAP(msgflg);
   4382 	return (sys_msgget(p, &ua, retval));
   4383 #else
   4384 	return (ENOSYS);
   4385 #endif
   4386 }
   4387 
   4388 int
   4389 netbsd32_msgsnd(p, v, retval)
   4390 	struct proc *p;
   4391 	void *v;
   4392 	register_t *retval;
   4393 {
   4394 #if 0
   4395 	struct netbsd32_msgsnd_args /* {
   4396 		syscallarg(int) msqid;
   4397 		syscallarg(const netbsd32_voidp) msgp;
   4398 		syscallarg(netbsd32_size_t) msgsz;
   4399 		syscallarg(int) msgflg;
   4400 	} */ *uap = v;
   4401 	struct sys_msgsnd_args ua;
   4402 
   4403 	NETBSD32TO64_UAP(msqid);
   4404 	NETBSD32TOP_UAP(msgp, void);
   4405 	NETBSD32TOX_UAP(msgsz, size_t);
   4406 	NETBSD32TO64_UAP(msgflg);
   4407 	return (sys_msgsnd(p, &ua, retval));
   4408 #else
   4409 	return (ENOSYS);
   4410 #endif
   4411 }
   4412 
   4413 int
   4414 netbsd32_msgrcv(p, v, retval)
   4415 	struct proc *p;
   4416 	void *v;
   4417 	register_t *retval;
   4418 {
   4419 #if 0
   4420 	struct netbsd32_msgrcv_args /* {
   4421 		syscallarg(int) msqid;
   4422 		syscallarg(netbsd32_voidp) msgp;
   4423 		syscallarg(netbsd32_size_t) msgsz;
   4424 		syscallarg(netbsd32_long) msgtyp;
   4425 		syscallarg(int) msgflg;
   4426 	} */ *uap = v;
   4427 	struct sys_msgrcv_args ua;
   4428 	ssize_t rt;
   4429 	int error;
   4430 
   4431 	NETBSD32TO64_UAP(msqid);
   4432 	NETBSD32TOP_UAP(msgp, void);
   4433 	NETBSD32TOX_UAP(msgsz, size_t);
   4434 	NETBSD32TOX_UAP(msgtyp, long);
   4435 	NETBSD32TO64_UAP(msgflg);
   4436 	error = sys_msgrcv(p, &ua, (register_t *)&rt);
   4437 	*retval = rt;
   4438 	return (error);
   4439 #else
   4440 	return (ENOSYS);
   4441 #endif
   4442 }
   4443 #endif /* SYSVMSG */
   4444 
   4445 #if defined(SYSVSHM)
   4446 
   4447 int
   4448 netbsd32_shmat(p, v, retval)
   4449 	struct proc *p;
   4450 	void *v;
   4451 	register_t *retval;
   4452 {
   4453 #if 0
   4454 	struct netbsd32_shmat_args /* {
   4455 		syscallarg(int) shmid;
   4456 		syscallarg(const netbsd32_voidp) shmaddr;
   4457 		syscallarg(int) shmflg;
   4458 	} */ *uap = v;
   4459 	struct sys_shmat_args ua;
   4460 	void *rt;
   4461 	int error;
   4462 
   4463 	NETBSD32TO64_UAP(shmid);
   4464 	NETBSD32TOP_UAP(shmaddr, void);
   4465 	NETBSD32TO64_UAP(shmflg);
   4466 	error = sys_shmat(p, &ua, (register_t *)&rt);
   4467 	*retval = rt;
   4468 	return (error);
   4469 #else
   4470 	return (ENOSYS);
   4471 #endif
   4472 }
   4473 
   4474 int
   4475 netbsd32___shmctl13(p, v, retval)
   4476 	struct proc *p;
   4477 	void *v;
   4478 	register_t *retval;
   4479 {
   4480 #if 0
   4481 	struct netbsd32_shmctl_args /* {
   4482 		syscallarg(int) shmid;
   4483 		syscallarg(int) cmd;
   4484 		syscallarg(netbsd32_shmid_dsp_t) buf;
   4485 	} */ *uap = v;
   4486 	struct sys_shmctl_args ua;
   4487 	struct shmid_ds ds;
   4488 	struct netbsd32_shmid_ds *ds32p;
   4489 	int error;
   4490 
   4491 	NETBSD32TO64_UAP(shmid);
   4492 	NETBSD32TO64_UAP(cmd);
   4493 	ds32p = (struct netbsd32_shmid_ds *)(u_long)SCARG(uap, buf);
   4494 	if (ds32p) {
   4495 		SCARG(&ua, buf) = NULL;
   4496 		netbsd32_to_shmid_ds(ds32p, &ds);
   4497 	} else
   4498 		SCARG(&ua, buf) = NULL;
   4499 	error = sys_shmctl(p, &ua, retval);
   4500 	if (error)
   4501 		return (error);
   4502 
   4503 	if (ds32p)
   4504 		netbsd32_from_shmid_ds(&ds, ds32p);
   4505 	return (0);
   4506 #else
   4507 	return (ENOSYS);
   4508 #endif
   4509 }
   4510 
   4511 int
   4512 netbsd32_shmdt(p, v, retval)
   4513 	struct proc *p;
   4514 	void *v;
   4515 	register_t *retval;
   4516 {
   4517 #if 0
   4518 	struct netbsd32_shmdt_args /* {
   4519 		syscallarg(const netbsd32_voidp) shmaddr;
   4520 	} */ *uap = v;
   4521 	struct sys_shmdt_args ua;
   4522 
   4523 	NETBSD32TOP_UAP(shmaddr, const char);
   4524 	return (sys_shmdt(p, &ua, retval));
   4525 #else
   4526 	return (ENOSYS);
   4527 #endif
   4528 }
   4529 
   4530 int
   4531 netbsd32_shmget(p, v, retval)
   4532 	struct proc *p;
   4533 	void *v;
   4534 	register_t *retval;
   4535 {
   4536 #if 0
   4537 	struct netbsd32_shmget_args /* {
   4538 		syscallarg(netbsd32_key_t) key;
   4539 		syscallarg(netbsd32_size_t) size;
   4540 		syscallarg(int) shmflg;
   4541 	} */ *uap = v;
   4542 	struct sys_shmget_args ua;
   4543 
   4544 	NETBSD32TOX_UAP(key, key_t)
   4545 	NETBSD32TOX_UAP(size, size_t)
   4546 	NETBSD32TO64_UAP(shmflg);
   4547 	return (sys_shmget(p, &ua, retval));
   4548 #else
   4549 	return (ENOSYS);
   4550 #endif
   4551 }
   4552 #endif /* SYSVSHM */
   4553 /* XXX MOVE ME IPC END */
   4554 
   4555 /* XXX MOVE ME XXX */
   4556 int
   4557 netbsd32_clock_gettime(p, v, retval)
   4558 	struct proc *p;
   4559 	void *v;
   4560 	register_t *retval;
   4561 {
   4562 	struct netbsd32_clock_gettime_args /* {
   4563 		syscallarg(netbsd32_clockid_t) clock_id;
   4564 		syscallarg(netbsd32_timespecp_t) tp;
   4565 	} */ *uap = v;
   4566 	clockid_t clock_id;
   4567 	struct timeval atv;
   4568 	struct timespec ats;
   4569 	struct netbsd32_timespec ts32;
   4570 
   4571 	clock_id = SCARG(uap, clock_id);
   4572 	if (clock_id != CLOCK_REALTIME)
   4573 		return (EINVAL);
   4574 
   4575 	microtime(&atv);
   4576 	TIMEVAL_TO_TIMESPEC(&atv,&ats);
   4577 	netbsd32_from_timespec(&ats, &ts32);
   4578 
   4579 	return copyout(&ts32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts32));
   4580 }
   4581 
   4582 /* XXX MOVE ME XXX */
   4583 int
   4584 netbsd32_clock_settime(p, v, retval)
   4585 	struct proc *p;
   4586 	void *v;
   4587 	register_t *retval;
   4588 {
   4589 	struct netbsd32_clock_settime_args /* {
   4590 		syscallarg(netbsd32_clockid_t) clock_id;
   4591 		syscallarg(const netbsd32_timespecp_t) tp;
   4592 	} */ *uap = v;
   4593 	struct netbsd32_timespec ts32;
   4594 	clockid_t clock_id;
   4595 	struct timeval atv;
   4596 	struct timespec ats;
   4597 	int error;
   4598 
   4599 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
   4600 		return (error);
   4601 
   4602 	clock_id = SCARG(uap, clock_id);
   4603 	if (clock_id != CLOCK_REALTIME)
   4604 		return (EINVAL);
   4605 
   4606 	if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), &ts32, sizeof(ts32))) != 0)
   4607 		return (error);
   4608 
   4609 	netbsd32_to_timespec(&ts32, &ats);
   4610 	TIMESPEC_TO_TIMEVAL(&atv,&ats);
   4611 	if ((error = settime(&atv)))
   4612 		return (error);
   4613 
   4614 	return 0;
   4615 }
   4616 
   4617 /* XXX MOVE ME XXX */
   4618 int
   4619 netbsd32_clock_getres(p, v, retval)
   4620 	struct proc *p;
   4621 	void *v;
   4622 	register_t *retval;
   4623 {
   4624 	struct netbsd32_clock_getres_args /* {
   4625 		syscallarg(netbsd32_clockid_t) clock_id;
   4626 		syscallarg(netbsd32_timespecp_t) tp;
   4627 	} */ *uap = v;
   4628 	struct netbsd32_timespec ts32;
   4629 	clockid_t clock_id;
   4630 	struct timespec ts;
   4631 	int error = 0;
   4632 
   4633 	clock_id = SCARG(uap, clock_id);
   4634 	if (clock_id != CLOCK_REALTIME)
   4635 		return (EINVAL);
   4636 
   4637 	if (SCARG(uap, tp)) {
   4638 		ts.tv_sec = 0;
   4639 		ts.tv_nsec = 1000000000 / hz;
   4640 
   4641 		netbsd32_from_timespec(&ts, &ts32);
   4642 		error = copyout(&ts, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts));
   4643 	}
   4644 
   4645 	return error;
   4646 }
   4647 
   4648 /* XXX MOVE ME XXX */
   4649 int
   4650 netbsd32_nanosleep(p, v, retval)
   4651 	struct proc *p;
   4652 	void *v;
   4653 	register_t *retval;
   4654 {
   4655 	struct netbsd32_nanosleep_args /* {
   4656 		syscallarg(const netbsd32_timespecp_t) rqtp;
   4657 		syscallarg(netbsd32_timespecp_t) rmtp;
   4658 	} */ *uap = v;
   4659 	static int nanowait;
   4660 	struct netbsd32_timespec ts32;
   4661 	struct timespec rqt;
   4662 	struct timespec rmt;
   4663 	struct timeval atv, utv;
   4664 	int error, s, timo;
   4665 
   4666 	error = copyin((caddr_t)(u_long)SCARG(uap, rqtp), (caddr_t)&ts32,
   4667 		       sizeof(ts32));
   4668 	if (error)
   4669 		return (error);
   4670 
   4671 	netbsd32_to_timespec(&ts32, &rqt);
   4672 	TIMESPEC_TO_TIMEVAL(&atv,&rqt)
   4673 	if (itimerfix(&atv))
   4674 		return (EINVAL);
   4675 
   4676 	s = splclock();
   4677 	timeradd(&atv,&time,&atv);
   4678 	timo = hzto(&atv);
   4679 	/*
   4680 	 * Avoid inadvertantly sleeping forever
   4681 	 */
   4682 	if (timo == 0)
   4683 		timo = 1;
   4684 	splx(s);
   4685 
   4686 	error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
   4687 	if (error == ERESTART)
   4688 		error = EINTR;
   4689 	if (error == EWOULDBLOCK)
   4690 		error = 0;
   4691 
   4692 	if (SCARG(uap, rmtp)) {
   4693 		int error;
   4694 
   4695 		s = splclock();
   4696 		utv = time;
   4697 		splx(s);
   4698 
   4699 		timersub(&atv, &utv, &utv);
   4700 		if (utv.tv_sec < 0)
   4701 			timerclear(&utv);
   4702 
   4703 		TIMEVAL_TO_TIMESPEC(&utv,&rmt);
   4704 		netbsd32_from_timespec(&rmt, &ts32);
   4705 		error = copyout((caddr_t)&ts32, (caddr_t)(u_long)SCARG(uap,rmtp),
   4706 			sizeof(ts32));
   4707 		if (error)
   4708 			return (error);
   4709 	}
   4710 
   4711 	return error;
   4712 }
   4713 
   4714 int
   4715 netbsd32_fdatasync(p, v, retval)
   4716 	struct proc *p;
   4717 	void *v;
   4718 	register_t *retval;
   4719 {
   4720 	struct netbsd32_fdatasync_args /* {
   4721 		syscallarg(int) fd;
   4722 	} */ *uap = v;
   4723 	struct sys_fdatasync_args ua;
   4724 
   4725 	NETBSD32TO64_UAP(fd);
   4726 	return (sys_fdatasync(p, &ua, retval));
   4727 }
   4728 
   4729 int
   4730 netbsd32___posix_rename(p, v, retval)
   4731 	struct proc *p;
   4732 	void *v;
   4733 	register_t *retval;
   4734 {
   4735 	struct netbsd32___posix_rename_args /* {
   4736 		syscallarg(const netbsd32_charp) from;
   4737 		syscallarg(const netbsd32_charp) to;
   4738 	} */ *uap = v;
   4739 	struct sys___posix_rename_args ua;
   4740 
   4741 	NETBSD32TOP_UAP(from, const char);
   4742 	NETBSD32TOP_UAP(to, const char);
   4743 	return (sys___posix_rename(p, &ua, retval));
   4744 }
   4745 
   4746 int
   4747 netbsd32_swapctl(p, v, retval)
   4748 	struct proc *p;
   4749 	void *v;
   4750 	register_t *retval;
   4751 {
   4752 	struct netbsd32_swapctl_args /* {
   4753 		syscallarg(int) cmd;
   4754 		syscallarg(const netbsd32_voidp) arg;
   4755 		syscallarg(int) misc;
   4756 	} */ *uap = v;
   4757 	struct sys_swapctl_args ua;
   4758 
   4759 	NETBSD32TO64_UAP(cmd);
   4760 	NETBSD32TOP_UAP(arg, const void);
   4761 	NETBSD32TO64_UAP(misc);
   4762 	return (sys_swapctl(p, &ua, retval));
   4763 }
   4764 
   4765 /* XXX MOVE ME XXX */
   4766 int
   4767 netbsd32_getdents(p, v, retval)
   4768 	struct proc *p;
   4769 	void *v;
   4770 	register_t *retval;
   4771 {
   4772 	struct netbsd32_getdents_args /* {
   4773 		syscallarg(int) fd;
   4774 		syscallarg(netbsd32_charp) buf;
   4775 		syscallarg(netbsd32_size_t) count;
   4776 	} */ *uap = v;
   4777 	struct file *fp;
   4778 	int error, done;
   4779 
   4780 	/* getvnode() will use the descriptor for us */
   4781 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
   4782 		return (error);
   4783 	if ((fp->f_flag & FREAD) == 0) {
   4784 		error = EBADF;
   4785 		goto out;
   4786 	}
   4787 	error = vn_readdir(fp, (caddr_t)(u_long)SCARG(uap, buf), UIO_USERSPACE,
   4788 			SCARG(uap, count), &done, p, 0, 0);
   4789 	*retval = done;
   4790  out:
   4791 	FILE_UNUSE(fp, p);
   4792 	return (error);
   4793 }
   4794 
   4795 
   4796 int
   4797 netbsd32_minherit(p, v, retval)
   4798 	struct proc *p;
   4799 	void *v;
   4800 	register_t *retval;
   4801 {
   4802 	struct netbsd32_minherit_args /* {
   4803 		syscallarg(netbsd32_voidp) addr;
   4804 		syscallarg(netbsd32_size_t) len;
   4805 		syscallarg(int) inherit;
   4806 	} */ *uap = v;
   4807 	struct sys_minherit_args ua;
   4808 
   4809 	NETBSD32TOP_UAP(addr, void);
   4810 	NETBSD32TOX_UAP(len, size_t);
   4811 	NETBSD32TO64_UAP(inherit);
   4812 	return (sys_minherit(p, &ua, retval));
   4813 }
   4814 
   4815 int
   4816 netbsd32_lchmod(p, v, retval)
   4817 	struct proc *p;
   4818 	void *v;
   4819 	register_t *retval;
   4820 {
   4821 	struct netbsd32_lchmod_args /* {
   4822 		syscallarg(const netbsd32_charp) path;
   4823 		syscallarg(mode_t) mode;
   4824 	} */ *uap = v;
   4825 	struct sys_lchmod_args ua;
   4826 
   4827 	NETBSD32TOP_UAP(path, const char);
   4828 	NETBSD32TO64_UAP(mode);
   4829 	return (sys_lchmod(p, &ua, retval));
   4830 }
   4831 
   4832 int
   4833 netbsd32_lchown(p, v, retval)
   4834 	struct proc *p;
   4835 	void *v;
   4836 	register_t *retval;
   4837 {
   4838 	struct netbsd32_lchown_args /* {
   4839 		syscallarg(const netbsd32_charp) path;
   4840 		syscallarg(uid_t) uid;
   4841 		syscallarg(gid_t) gid;
   4842 	} */ *uap = v;
   4843 	struct sys_lchown_args ua;
   4844 
   4845 	NETBSD32TOP_UAP(path, const char);
   4846 	NETBSD32TO64_UAP(uid);
   4847 	NETBSD32TO64_UAP(gid);
   4848 	return (sys_lchown(p, &ua, retval));
   4849 }
   4850 
   4851 int
   4852 netbsd32_lutimes(p, v, retval)
   4853 	struct proc *p;
   4854 	void *v;
   4855 	register_t *retval;
   4856 {
   4857 	struct netbsd32_lutimes_args /* {
   4858 		syscallarg(const netbsd32_charp) path;
   4859 		syscallarg(const netbsd32_timevalp_t) tptr;
   4860 	} */ *uap = v;
   4861 	int error;
   4862 	struct nameidata nd;
   4863 
   4864 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, (caddr_t)(u_long)SCARG(uap, path), p);
   4865 	if ((error = namei(&nd)) != 0)
   4866 		return (error);
   4867 
   4868 	error = change_utimes32(nd.ni_vp, SCARG(uap, tptr), p);
   4869 
   4870 	vrele(nd.ni_vp);
   4871 	return (error);
   4872 }
   4873 
   4874 
   4875 int
   4876 netbsd32___msync13(p, v, retval)
   4877 	struct proc *p;
   4878 	void *v;
   4879 	register_t *retval;
   4880 {
   4881 	struct netbsd32___msync13_args /* {
   4882 		syscallarg(netbsd32_voidp) addr;
   4883 		syscallarg(netbsd32_size_t) len;
   4884 		syscallarg(int) flags;
   4885 	} */ *uap = v;
   4886 	struct sys___msync13_args ua;
   4887 
   4888 	NETBSD32TOP_UAP(addr, void);
   4889 	NETBSD32TOX_UAP(len, size_t);
   4890 	NETBSD32TO64_UAP(flags);
   4891 	return (sys___msync13(p, &ua, retval));
   4892 }
   4893 
   4894 /* XXX MOVE ME XXX */
   4895 int
   4896 netbsd32___stat13(p, v, retval)
   4897 	struct proc *p;
   4898 	void *v;
   4899 	register_t *retval;
   4900 {
   4901 	struct netbsd32___stat13_args /* {
   4902 		syscallarg(const netbsd32_charp) path;
   4903 		syscallarg(netbsd32_statp_t) ub;
   4904 	} */ *uap = v;
   4905 	struct netbsd32_stat sb32;
   4906 	struct stat sb;
   4907 	int error;
   4908 	struct nameidata nd;
   4909 	caddr_t sg;
   4910 	const char *path;
   4911 
   4912 	path = (char *)(u_long)SCARG(uap, path);
   4913 	sg = stackgap_init(p->p_emul);
   4914 	CHECK_ALT_EXIST(p, &sg, path);
   4915 
   4916 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, path, p);
   4917 	if ((error = namei(&nd)) != 0)
   4918 		return (error);
   4919 	error = vn_stat(nd.ni_vp, &sb, p);
   4920 	vput(nd.ni_vp);
   4921 	if (error)
   4922 		return (error);
   4923 	netbsd32_from___stat13(&sb, &sb32);
   4924 	error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
   4925 	return (error);
   4926 }
   4927 
   4928 /* XXX MOVE ME XXX */
   4929 int
   4930 netbsd32___fstat13(p, v, retval)
   4931 	struct proc *p;
   4932 	void *v;
   4933 	register_t *retval;
   4934 {
   4935 	struct netbsd32___fstat13_args /* {
   4936 		syscallarg(int) fd;
   4937 		syscallarg(netbsd32_statp_t) sb;
   4938 	} */ *uap = v;
   4939 	int fd = SCARG(uap, fd);
   4940 	struct filedesc *fdp = p->p_fd;
   4941 	struct file *fp;
   4942 	struct netbsd32_stat sb32;
   4943 	struct stat ub;
   4944 	int error = 0;
   4945 
   4946 	if ((u_int)fd >= fdp->fd_nfiles ||
   4947 	    (fp = fdp->fd_ofiles[fd]) == NULL)
   4948 		return (EBADF);
   4949 	switch (fp->f_type) {
   4950 
   4951 	case DTYPE_VNODE:
   4952 		error = vn_stat((struct vnode *)fp->f_data, &ub, p);
   4953 		break;
   4954 
   4955 	case DTYPE_SOCKET:
   4956 		error = soo_stat((struct socket *)fp->f_data, &ub);
   4957 		break;
   4958 
   4959 	default:
   4960 		panic("fstat");
   4961 		/*NOTREACHED*/
   4962 	}
   4963 	if (error == 0) {
   4964 		netbsd32_from___stat13(&ub, &sb32);
   4965 		error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, sb), sizeof(sb32));
   4966 	}
   4967 	return (error);
   4968 }
   4969 
   4970 /* XXX MOVE ME XXX */
   4971 int
   4972 netbsd32___lstat13(p, v, retval)
   4973 	struct proc *p;
   4974 	void *v;
   4975 	register_t *retval;
   4976 {
   4977 	struct netbsd32___lstat13_args /* {
   4978 		syscallarg(const netbsd32_charp) path;
   4979 		syscallarg(netbsd32_statp_t) ub;
   4980 	} */ *uap = v;
   4981 	struct netbsd32_stat sb32;
   4982 	struct stat sb;
   4983 	int error;
   4984 	struct nameidata nd;
   4985 	caddr_t sg;
   4986 	const char *path;
   4987 
   4988 	path = (char *)(u_long)SCARG(uap, path);
   4989 	sg = stackgap_init(p->p_emul);
   4990 	CHECK_ALT_EXIST(p, &sg, path);
   4991 
   4992 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, path, p);
   4993 	if ((error = namei(&nd)) != 0)
   4994 		return (error);
   4995 	error = vn_stat(nd.ni_vp, &sb, p);
   4996 	vput(nd.ni_vp);
   4997 	if (error)
   4998 		return (error);
   4999 	netbsd32_from___stat13(&sb, &sb32);
   5000 	error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
   5001 	return (error);
   5002 }
   5003 
   5004 /* XXX MOVE ME XXX */
   5005 int
   5006 netbsd32___sigaltstack14(p, v, retval)
   5007 	struct proc *p;
   5008 	void *v;
   5009 	register_t *retval;
   5010 {
   5011 	struct netbsd32___sigaltstack14_args /* {
   5012 		syscallarg(const netbsd32_sigaltstackp_t) nss;
   5013 		syscallarg(netbsd32_sigaltstackp_t) oss;
   5014 	} */ *uap = v;
   5015 	struct netbsd32_sigaltstack s32;
   5016 	struct sigaltstack nss, oss;
   5017 	int error;
   5018 
   5019 	if (SCARG(uap, nss)) {
   5020 		error = copyin((caddr_t)(u_long)SCARG(uap, nss), &s32, sizeof(s32));
   5021 		if (error)
   5022 			return (error);
   5023 		nss.ss_sp = (void *)(u_long)s32.ss_sp;
   5024 		nss.ss_size = (size_t)s32.ss_size;
   5025 		nss.ss_flags = s32.ss_flags;
   5026 	}
   5027 	error = sigaltstack1(p,
   5028 	    SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
   5029 	if (error)
   5030 		return (error);
   5031 	if (SCARG(uap, oss)) {
   5032 		s32.ss_sp = (netbsd32_voidp)(u_long)oss.ss_sp;
   5033 		s32.ss_size = (netbsd32_size_t)oss.ss_size;
   5034 		s32.ss_flags = oss.ss_flags;
   5035 		error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, oss), sizeof(s32));
   5036 		if (error)
   5037 			return (error);
   5038 	}
   5039 	return (0);
   5040 }
   5041 
   5042 int
   5043 netbsd32___posix_chown(p, v, retval)
   5044 	struct proc *p;
   5045 	void *v;
   5046 	register_t *retval;
   5047 {
   5048 	struct netbsd32___posix_chown_args /* {
   5049 		syscallarg(const netbsd32_charp) path;
   5050 		syscallarg(uid_t) uid;
   5051 		syscallarg(gid_t) gid;
   5052 	} */ *uap = v;
   5053 	struct sys___posix_chown_args ua;
   5054 
   5055 	NETBSD32TOP_UAP(path, const char);
   5056 	NETBSD32TO64_UAP(uid);
   5057 	NETBSD32TO64_UAP(gid);
   5058 	return (sys___posix_chown(p, &ua, retval));
   5059 }
   5060 
   5061 int
   5062 netbsd32___posix_fchown(p, v, retval)
   5063 	struct proc *p;
   5064 	void *v;
   5065 	register_t *retval;
   5066 {
   5067 	struct netbsd32___posix_fchown_args /* {
   5068 		syscallarg(int) fd;
   5069 		syscallarg(uid_t) uid;
   5070 		syscallarg(gid_t) gid;
   5071 	} */ *uap = v;
   5072 	struct sys___posix_fchown_args ua;
   5073 
   5074 	NETBSD32TO64_UAP(fd);
   5075 	NETBSD32TO64_UAP(uid);
   5076 	NETBSD32TO64_UAP(gid);
   5077 	return (sys___posix_fchown(p, &ua, retval));
   5078 }
   5079 
   5080 int
   5081 netbsd32___posix_lchown(p, v, retval)
   5082 	struct proc *p;
   5083 	void *v;
   5084 	register_t *retval;
   5085 {
   5086 	struct netbsd32___posix_lchown_args /* {
   5087 		syscallarg(const netbsd32_charp) path;
   5088 		syscallarg(uid_t) uid;
   5089 		syscallarg(gid_t) gid;
   5090 	} */ *uap = v;
   5091 	struct sys___posix_lchown_args ua;
   5092 
   5093 	NETBSD32TOP_UAP(path, const char);
   5094 	NETBSD32TO64_UAP(uid);
   5095 	NETBSD32TO64_UAP(gid);
   5096 	return (sys___posix_lchown(p, &ua, retval));
   5097 }
   5098 
   5099 int
   5100 netbsd32_getsid(p, v, retval)
   5101 	struct proc *p;
   5102 	void *v;
   5103 	register_t *retval;
   5104 {
   5105 	struct netbsd32_getsid_args /* {
   5106 		syscallarg(pid_t) pid;
   5107 	} */ *uap = v;
   5108 	struct sys_getsid_args ua;
   5109 
   5110 	NETBSD32TO64_UAP(pid);
   5111 	return (sys_getsid(p, &ua, retval));
   5112 }
   5113 
   5114 #ifdef KTRACE
   5115 int
   5116 netbsd32_fktrace(p, v, retval)
   5117 	struct proc *p;
   5118 	void *v;
   5119 	register_t *retval;
   5120 {
   5121 	struct netbsd32_fktrace_args /* {
   5122 		syscallarg(const int) fd;
   5123 		syscallarg(int) ops;
   5124 		syscallarg(int) facs;
   5125 		syscallarg(int) pid;
   5126 	} */ *uap = v;
   5127 #if 0
   5128 	struct sys_fktrace_args ua;
   5129 #else
   5130 	/* XXXX */
   5131 	struct sys_fktrace_noconst_args {
   5132 		syscallarg(int) fd;
   5133 		syscallarg(int) ops;
   5134 		syscallarg(int) facs;
   5135 		syscallarg(int) pid;
   5136 	} ua;
   5137 #endif
   5138 
   5139 	NETBSD32TOX_UAP(fd, int);
   5140 	NETBSD32TO64_UAP(ops);
   5141 	NETBSD32TO64_UAP(facs);
   5142 	NETBSD32TO64_UAP(pid);
   5143 	return (sys_fktrace(p, &ua, retval));
   5144 }
   5145 #endif /* KTRACE */
   5146 
   5147 /* XXX MOVE ME XXX */
   5148 int
   5149 netbsd32_preadv(p, v, retval)
   5150 	struct proc *p;
   5151 	void *v;
   5152 	register_t *retval;
   5153 {
   5154 	struct netbsd32_preadv_args /* {
   5155 		syscallarg(int) fd;
   5156 		syscallarg(const netbsd32_iovecp_t) iovp;
   5157 		syscallarg(int) iovcnt;
   5158 		syscallarg(int) pad;
   5159 		syscallarg(off_t) offset;
   5160 	} */ *uap = v;
   5161 	struct filedesc *fdp = p->p_fd;
   5162 	struct file *fp;
   5163 	struct vnode *vp;
   5164 	off_t offset;
   5165 	int error, fd = SCARG(uap, fd);
   5166 
   5167 	if ((u_int)fd >= fdp->fd_nfiles ||
   5168 	    (fp = fdp->fd_ofiles[fd]) == NULL ||
   5169 	    (fp->f_flag & FREAD) == 0)
   5170 		return (EBADF);
   5171 
   5172 	vp = (struct vnode *)fp->f_data;
   5173 	if (fp->f_type != DTYPE_VNODE
   5174 	    || vp->v_type == VFIFO)
   5175 		return (ESPIPE);
   5176 
   5177 	offset = SCARG(uap, offset);
   5178 
   5179 	/*
   5180 	 * XXX This works because no file systems actually
   5181 	 * XXX take any action on the seek operation.
   5182 	 */
   5183 	if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
   5184 		return (error);
   5185 
   5186 	return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
   5187 	    &offset, 0, retval));
   5188 }
   5189 
   5190 /* XXX MOVE ME XXX */
   5191 int
   5192 netbsd32_pwritev(p, v, retval)
   5193 	struct proc *p;
   5194 	void *v;
   5195 	register_t *retval;
   5196 {
   5197 	struct netbsd32_pwritev_args /* {
   5198 		syscallarg(int) fd;
   5199 		syscallarg(const netbsd32_iovecp_t) iovp;
   5200 		syscallarg(int) iovcnt;
   5201 		syscallarg(int) pad;
   5202 		syscallarg(off_t) offset;
   5203 	} */ *uap = v;
   5204 	struct filedesc *fdp = p->p_fd;
   5205 	struct file *fp;
   5206 	struct vnode *vp;
   5207 	off_t offset;
   5208 	int error, fd = SCARG(uap, fd);
   5209 
   5210 	if ((u_int)fd >= fdp->fd_nfiles ||
   5211 	    (fp = fdp->fd_ofiles[fd]) == NULL ||
   5212 	    (fp->f_flag & FWRITE) == 0)
   5213 		return (EBADF);
   5214 
   5215 	vp = (struct vnode *)fp->f_data;
   5216 	if (fp->f_type != DTYPE_VNODE
   5217 	    || vp->v_type == VFIFO)
   5218 		return (ESPIPE);
   5219 
   5220 	offset = SCARG(uap, offset);
   5221 
   5222 	/*
   5223 	 * XXX This works because no file systems actually
   5224 	 * XXX take any action on the seek operation.
   5225 	 */
   5226 	if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
   5227 		return (error);
   5228 
   5229 	return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
   5230 	    &offset, 0, retval));
   5231 }
   5232 
   5233 /* XXX MOVE ME XXX */
   5234 /* ARGSUSED */
   5235 int
   5236 netbsd32___sigaction14(p, v, retval)
   5237 	struct proc *p;
   5238 	void *v;
   5239 	register_t *retval;
   5240 {
   5241 	struct netbsd32___sigaction14_args /* {
   5242 		syscallarg(int) signum;
   5243 		syscallarg(const struct sigaction *) nsa;
   5244 		syscallarg(struct sigaction *) osa;
   5245 	} */ *uap = v;
   5246 	struct netbsd32_sigaction sa32;
   5247 	struct sigaction nsa, osa;
   5248 	int error;
   5249 
   5250 	if (SCARG(uap, nsa)) {
   5251 		error = copyin((caddr_t)(u_long)SCARG(uap, nsa),
   5252 			       &sa32, sizeof(sa32));
   5253 		if (error)
   5254 			return (error);
   5255 		nsa.sa_handler = (void *)(u_long)sa32.sa_handler;
   5256 		nsa.sa_mask = sa32.sa_mask;
   5257 		nsa.sa_flags = sa32.sa_flags;
   5258 	}
   5259 	error = sigaction1(p, SCARG(uap, signum),
   5260 	    SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0);
   5261 	if (error)
   5262 		return (error);
   5263 	if (SCARG(uap, osa)) {
   5264 		sa32.sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler;
   5265 		sa32.sa_mask = osa.sa_mask;
   5266 		sa32.sa_flags = osa.sa_flags;
   5267 		error = copyout(&sa32, (caddr_t)(u_long)SCARG(uap, osa), sizeof(sa32));
   5268 		if (error)
   5269 			return (error);
   5270 	}
   5271 	return (0);
   5272 }
   5273 
   5274 int netbsd32___sigpending14(p, v, retval)
   5275 	struct proc *p;
   5276 	void   *v;
   5277 	register_t *retval;
   5278 {
   5279 	struct netbsd32___sigpending14_args /* {
   5280 		syscallarg(sigset_t *) set;
   5281 	} */ *uap = v;
   5282 	struct sys___sigpending14_args ua;
   5283 
   5284 	NETBSD32TOP_UAP(set, sigset_t);
   5285 	return (sys___sigpending14(p, &ua, retval));
   5286 }
   5287 
   5288 int netbsd32___sigprocmask14(p, v, retval)
   5289 	struct proc *p;
   5290 	void   *v;
   5291 	register_t *retval;
   5292 {
   5293 	struct netbsd32___sigprocmask14_args /* {
   5294 		syscallarg(int) how;
   5295 		syscallarg(const sigset_t *) set;
   5296 		syscallarg(sigset_t *) oset;
   5297 	} */ *uap = v;
   5298 	struct sys___sigprocmask14_args ua;
   5299 
   5300 	NETBSD32TO64_UAP(how);
   5301 	NETBSD32TOP_UAP(set, sigset_t);
   5302 	NETBSD32TOP_UAP(oset, sigset_t);
   5303 	return (sys___sigprocmask14(p, &ua, retval));
   5304 }
   5305 
   5306 int netbsd32___sigsuspend14(p, v, retval)
   5307 	struct proc *p;
   5308 	void   *v;
   5309 	register_t *retval;
   5310 {
   5311 	struct netbsd32___sigsuspend14_args /* {
   5312 		syscallarg(const sigset_t *) set;
   5313 	} */ *uap = v;
   5314 	struct sys___sigsuspend14_args ua;
   5315 
   5316 	NETBSD32TOP_UAP(set, sigset_t);
   5317 	return (sys___sigsuspend14(p, &ua, retval));
   5318 };
   5319 
   5320 /* XXX MOVE ME XXX */
   5321 /*
   5322  * Find pathname of process's current directory.
   5323  *
   5324  * Use vfs vnode-to-name reverse cache; if that fails, fall back
   5325  * to reading directory contents.
   5326  */
   5327 int
   5328 getcwd_common __P((struct vnode *, struct vnode *,
   5329 		   char **, char *, int, int, struct proc *));
   5330 
   5331 int netbsd32___getcwd(p, v, retval)
   5332 	struct proc *p;
   5333 	void   *v;
   5334 	register_t *retval;
   5335 {
   5336 	struct netbsd32___getcwd_args /* {
   5337 		syscallarg(char *) bufp;
   5338 		syscallarg(size_t) length;
   5339 	} */ *uap = v;
   5340 
   5341 	int     error;
   5342 	char   *path;
   5343 	char   *bp, *bend;
   5344 	int     len = (int)SCARG(uap, length);
   5345 	int	lenused;
   5346 
   5347 	if (len > MAXPATHLEN*4)
   5348 		len = MAXPATHLEN*4;
   5349 	else if (len < 2)
   5350 		return ERANGE;
   5351 
   5352 	path = (char *)malloc(len, M_TEMP, M_WAITOK);
   5353 	if (!path)
   5354 		return ENOMEM;
   5355 
   5356 	bp = &path[len];
   5357 	bend = bp;
   5358 	*(--bp) = '\0';
   5359 
   5360 	/*
   5361 	 * 5th argument here is "max number of vnodes to traverse".
   5362 	 * Since each entry takes up at least 2 bytes in the output buffer,
   5363 	 * limit it to N/2 vnodes for an N byte buffer.
   5364 	 */
   5365 #define GETCWD_CHECK_ACCESS 0x0001
   5366 	error = getcwd_common (p->p_cwdi->cwdi_cdir, NULL, &bp, path, len/2,
   5367 			       GETCWD_CHECK_ACCESS, p);
   5368 
   5369 	if (error)
   5370 		goto out;
   5371 	lenused = bend - bp;
   5372 	*retval = lenused;
   5373 	/* put the result into user buffer */
   5374 	error = copyout(bp, (caddr_t)(u_long)SCARG(uap, bufp), lenused);
   5375 
   5376 out:
   5377 	free(path, M_TEMP);
   5378 	return error;
   5379 }
   5380 
   5381 int netbsd32_fchroot(p, v, retval)
   5382 	struct proc *p;
   5383 	void *v;
   5384 	register_t *retval;
   5385 {
   5386 	struct netbsd32_fchroot_args /* {
   5387 		syscallarg(int) fd;
   5388 	} */ *uap = v;
   5389 	struct sys_fchroot_args ua;
   5390 
   5391 	NETBSD32TO64_UAP(fd);
   5392 	return (sys_fchroot(p, &ua, retval));
   5393 }
   5394 
   5395 /*
   5396  * Open a file given a file handle.
   5397  *
   5398  * Check permissions, allocate an open file structure,
   5399  * and call the device open routine if any.
   5400  */
   5401 int
   5402 netbsd32_fhopen(p, v, retval)
   5403 	struct proc *p;
   5404 	void *v;
   5405 	register_t *retval;
   5406 {
   5407 	struct netbsd32_fhopen_args /* {
   5408 		syscallarg(const fhandle_t *) fhp;
   5409 		syscallarg(int) flags;
   5410 	} */ *uap = v;
   5411 	struct sys_fhopen_args ua;
   5412 
   5413 	NETBSD32TOP_UAP(fhp, fhandle_t);
   5414 	NETBSD32TO64_UAP(flags);
   5415 	return (sys_fhopen(p, &ua, retval));
   5416 }
   5417 
   5418 int netbsd32_fhstat(p, v, retval)
   5419 	struct proc *p;
   5420 	void *v;
   5421 	register_t *retval;
   5422 {
   5423 	struct netbsd32_fhstat_args /* {
   5424 		syscallarg(const netbsd32_fhandlep_t) fhp;
   5425 		syscallarg(struct stat *) sb;
   5426 	} */ *uap = v;
   5427 	struct sys_fhstat_args ua;
   5428 
   5429 	NETBSD32TOP_UAP(fhp, const fhandle_t);
   5430 	NETBSD32TOP_UAP(sb, struct stat);
   5431 	return (sys_fhstat(p, &ua, retval));
   5432 }
   5433 
   5434 int netbsd32_fhstatfs(p, v, retval)
   5435 	struct proc *p;
   5436 	void *v;
   5437 	register_t *retval;
   5438 {
   5439 	struct netbsd32_fhstatfs_args /* {
   5440 		syscallarg(const netbsd32_fhandlep_t) fhp;
   5441 		syscallarg(struct statfs *) buf;
   5442 	} */ *uap = v;
   5443 	struct sys_fhstatfs_args ua;
   5444 
   5445 	NETBSD32TOP_UAP(fhp, const fhandle_t);
   5446 	NETBSD32TOP_UAP(buf, struct statfs);
   5447 	return (sys_fhstatfs(p, &ua, retval));
   5448 }
   5449 
   5450 /* virtual memory syscalls */
   5451 int
   5452 netbsd32_ovadvise(p, v, retval)
   5453 	struct proc *p;
   5454 	void *v;
   5455 	register_t *retval;
   5456 {
   5457 	struct netbsd32_ovadvise_args /* {
   5458 		syscallarg(int) anom;
   5459 	} */ *uap = v;
   5460 	struct sys_ovadvise_args ua;
   5461 
   5462 	NETBSD32TO64_UAP(anom);
   5463 	return (sys_ovadvise(p, &ua, retval));
   5464 }
   5465 
   5466