Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_compat_43.c revision 1.19
      1 /*	$NetBSD: netbsd32_compat_43.c,v 1.19 2001/08/25 15:06:02 mrg Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1998, 2001 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_OPT)
     32 #include "opt_compat_43.h"
     33 #endif
     34 
     35 #include <sys/param.h>
     36 #include <sys/systm.h>
     37 #include <sys/fcntl.h>
     38 #include <sys/malloc.h>
     39 #include <sys/mount.h>
     40 #include <sys/proc.h>
     41 #include <sys/stat.h>
     42 #include <sys/syscallargs.h>
     43 #include <sys/time.h>
     44 #include <sys/ucred.h>
     45 #include <uvm/uvm_extern.h>
     46 #include <sys/sysctl.h>
     47 #include <sys/swap.h>
     48 
     49 #include <compat/netbsd32/netbsd32.h>
     50 #include <compat/netbsd32/netbsd32_syscallargs.h>
     51 
     52 int compat_43_netbsd32_sethostid __P((struct proc *, void *, register_t *));
     53 int compat_43_netbsd32_killpg __P((struct proc *, void *, register_t *retval));
     54 int compat_43_netbsd32_sigblock __P((struct proc *, void *, register_t *retval));
     55 int compat_43_netbsd32_sigblock __P((struct proc *, void *, register_t *retval));
     56 
     57 void
     58 netbsd32_from_stat43(sp43, sp32)
     59 	struct stat43 *sp43;
     60 	struct netbsd32_stat43 *sp32;
     61 {
     62 
     63 	sp32->st_dev = sp43->st_dev;
     64 	sp32->st_ino = sp43->st_ino;
     65 	sp32->st_mode = sp43->st_mode;
     66 	sp32->st_nlink = sp43->st_nlink;
     67 	sp32->st_uid = sp43->st_uid;
     68 	sp32->st_gid = sp43->st_gid;
     69 	sp32->st_rdev = sp43->st_rdev;
     70 	sp32->st_size = sp43->st_size;
     71 	sp32->st_atimespec.tv_sec = sp43->st_atimespec.tv_sec;
     72 	sp32->st_atimespec.tv_nsec = sp43->st_atimespec.tv_nsec;
     73 	sp32->st_mtimespec.tv_sec = sp43->st_mtimespec.tv_sec;
     74 	sp32->st_mtimespec.tv_nsec = sp43->st_mtimespec.tv_nsec;
     75 	sp32->st_ctimespec.tv_sec = sp43->st_ctimespec.tv_sec;
     76 	sp32->st_ctimespec.tv_nsec = sp43->st_ctimespec.tv_nsec;
     77 	sp32->st_blksize = sp43->st_blksize;
     78 	sp32->st_blocks = sp43->st_blocks;
     79 	sp32->st_flags = sp43->st_flags;
     80 	sp32->st_gen = sp43->st_gen;
     81 }
     82 
     83 /* file system syscalls */
     84 int
     85 compat_43_netbsd32_ocreat(p, v, retval)
     86 	struct proc *p;
     87 	void *v;
     88 	register_t *retval;
     89 {
     90 	struct compat_43_netbsd32_ocreat_args /* {
     91 		syscallarg(const netbsd32_charp) path;
     92 		syscallarg(mode_t) mode;
     93 	} */ *uap = v;
     94 	struct sys_open_args  ua;
     95 	caddr_t sg;
     96 
     97 	NETBSD32TOP_UAP(path, const char);
     98 	NETBSD32TO64_UAP(mode);
     99 	SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC;
    100 	sg = stackgap_init(p->p_emul);
    101 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
    102 
    103 	return (sys_open(p, &ua, retval));
    104 }
    105 
    106 int
    107 compat_43_netbsd32_olseek(p, v, retval)
    108 	struct proc *p;
    109 	void *v;
    110 	register_t *retval;
    111 {
    112 	struct compat_43_netbsd32_olseek_args /* {
    113 		syscallarg(int) fd;
    114 		syscallarg(netbsd32_long) offset;
    115 		syscallarg(int) whence;
    116 	} */ *uap = v;
    117 	struct sys_lseek_args ua;
    118 	int rv;
    119 	off_t rt;
    120 
    121 	SCARG(&ua, fd) = SCARG(uap, fd);
    122 	NETBSD32TOX_UAP(offset, long);
    123 	NETBSD32TO64_UAP(whence);
    124 	rv = sys_lseek(p, &ua, (register_t *)&rt);
    125 	*retval = rt;
    126 
    127 	return (rv);
    128 }
    129 
    130 int
    131 compat_43_netbsd32_stat43(p, v, retval)
    132 	struct proc *p;
    133 	void *v;
    134 	register_t *retval;
    135 {
    136 	struct compat_43_netbsd32_stat43_args /* {
    137 		syscallarg(const netbsd32_charp) path;
    138 		syscallarg(netbsd32_stat43p_t) ub;
    139 	} */ *uap = v;
    140 	struct stat43 sb43, *sgsbp;
    141 	struct netbsd32_stat43 sb32;
    142 	struct compat_43_sys_stat_args ua;
    143 	caddr_t sg = stackgap_init(p->p_emul);
    144 	int rv, error;
    145 
    146 	NETBSD32TOP_UAP(path, const char);
    147 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(&sg, sizeof(sb43));
    148 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
    149 	rv = compat_43_sys_stat(p, &ua, retval);
    150 
    151 	error = copyin(sgsbp, &sb43, sizeof(sb43));
    152 	if (error)
    153 		return error;
    154 	netbsd32_from_stat43(&sb43, &sb32);
    155 	error = copyout(&sb32, (char *)(u_long)SCARG(uap, ub), sizeof(sb32));
    156 	if (error)
    157 		return error;
    158 
    159 	return (rv);
    160 }
    161 
    162 int
    163 compat_43_netbsd32_lstat43(p, v, retval)
    164 	struct proc *p;
    165 	void *v;
    166 	register_t *retval;
    167 {
    168 	struct compat_43_netbsd32_lstat43_args /* {
    169 		syscallarg(const netbsd32_charp) path;
    170 		syscallarg(netbsd32_stat43p_t) ub;
    171 	} */ *uap = v;
    172 	struct stat43 sb43, *sgsbp;
    173 	struct netbsd32_stat43 sb32;
    174 	struct compat_43_sys_lstat_args ua;
    175 	caddr_t sg = stackgap_init(p->p_emul);
    176 	int rv, error;
    177 
    178 	NETBSD32TOP_UAP(path, const char);
    179 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(&sg, sizeof(sb43));
    180 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
    181 	rv = compat_43_sys_stat(p, &ua, retval);
    182 
    183 	error = copyin(sgsbp, &sb43, sizeof(sb43));
    184 	if (error)
    185 		return error;
    186 	netbsd32_from_stat43(&sb43, &sb32);
    187 	error = copyout(&sb32, (char *)(u_long)SCARG(uap, ub), sizeof(sb32));
    188 	if (error)
    189 		return error;
    190 
    191 	return (rv);
    192 }
    193 
    194 int
    195 compat_43_netbsd32_fstat43(p, v, retval)
    196 	struct proc *p;
    197 	void *v;
    198 	register_t *retval;
    199 {
    200 	struct compat_43_netbsd32_fstat43_args /* {
    201 		syscallarg(int) fd;
    202 		syscallarg(netbsd32_stat43p_t) sb;
    203 	} */ *uap = v;
    204 	struct stat43 sb43, *sgsbp;
    205 	struct netbsd32_stat43 sb32;
    206 	struct compat_43_sys_fstat_args ua;
    207 	caddr_t sg = stackgap_init(p->p_emul);
    208 	int rv, error;
    209 
    210 	NETBSD32TO64_UAP(fd);
    211 	SCARG(&ua, sb) = sgsbp = stackgap_alloc(&sg, sizeof(sb43));
    212 	rv = compat_43_sys_fstat(p, &ua, retval);
    213 
    214 	error = copyin(sgsbp, &sb43, sizeof(sb43));
    215 	if (error)
    216 		return error;
    217 	netbsd32_from_stat43(&sb43, &sb32);
    218 	error = copyout(&sb32, (char *)(u_long)SCARG(uap, sb), sizeof(sb32));
    219 	if (error)
    220 		return error;
    221 
    222 	return (rv);
    223 }
    224 
    225 int
    226 compat_43_netbsd32_otruncate(p, v, retval)
    227 	struct proc *p;
    228 	void *v;
    229 	register_t *retval;
    230 {
    231 	struct compat_43_netbsd32_otruncate_args /* {
    232 		syscallarg(const netbsd32_charp) path;
    233 		syscallarg(netbsd32_long) length;
    234 	} */ *uap = v;
    235 	struct sys_truncate_args ua;
    236 
    237 	NETBSD32TOP_UAP(path, const char);
    238 	NETBSD32TO64_UAP(length);
    239 	return (sys_ftruncate(p, &ua, retval));
    240 }
    241 
    242 int
    243 compat_43_netbsd32_oftruncate(p, v, retval)
    244 	struct proc *p;
    245 	void *v;
    246 	register_t *retval;
    247 {
    248 	struct compat_43_netbsd32_oftruncate_args /* {
    249 		syscallarg(int) fd;
    250 		syscallarg(netbsd32_long) length;
    251 	} */ *uap = v;
    252 	struct sys_ftruncate_args ua;
    253 
    254 	NETBSD32TO64_UAP(fd);
    255 	NETBSD32TO64_UAP(length);
    256 	return (sys_ftruncate(p, &ua, retval));
    257 }
    258 
    259 int
    260 compat_43_netbsd32_ogetdirentries(p, v, retval)
    261 	struct proc *p;
    262 	void *v;
    263 	register_t *retval;
    264 {
    265 	struct compat_43_netbsd32_ogetdirentries_args /* {
    266 		syscallarg(int) fd;
    267 		syscallarg(netbsd32_charp) buf;
    268 		syscallarg(u_int) count;
    269 		syscallarg(netbsd32_longp) basep;
    270 	} */ *uap = v;
    271 	struct compat_43_sys_getdirentries_args ua;
    272 
    273 	NETBSD32TO64_UAP(fd);
    274 	NETBSD32TOP_UAP(buf, char);
    275 	NETBSD32TO64_UAP(count);
    276 	NETBSD32TOP_UAP(basep, long);
    277 	return (compat_43_sys_getdirentries(p, &ua, retval));
    278 }
    279 
    280 /* kernel syscalls */
    281 int
    282 compat_43_netbsd32_ogetkerninfo(p, v, retval)
    283 	struct proc *p;
    284 	void *v;
    285 	register_t *retval;
    286 {
    287 	struct compat_43_netbsd32_ogetkerninfo_args /* {
    288 		syscallarg(int) op;
    289 		syscallarg(netbsd32_charp) where;
    290 		syscallarg(netbsd32_intp) size;
    291 		syscallarg(int) arg;
    292 	} */ *uap = v;
    293 	struct compat_43_sys_getkerninfo_args ua;
    294 
    295 	NETBSD32TO64_UAP(op);
    296 	NETBSD32TOP_UAP(where, char);
    297 	NETBSD32TOP_UAP(size, int);
    298 	NETBSD32TO64_UAP(arg);
    299 	return (compat_43_sys_getkerninfo(p, &ua, retval));
    300 }
    301 
    302 int
    303 compat_43_netbsd32_ogethostname(p, v, retval)
    304 	struct proc *p;
    305 	void *v;
    306 	register_t *retval;
    307 {
    308 	struct compat_43_netbsd32_ogethostname_args /* {
    309 		syscallarg(netbsd32_charp) hostname;
    310 		syscallarg(u_int) len;
    311 	} */ *uap = v;
    312 	int name;
    313 	size_t sz;
    314 
    315 	name = KERN_HOSTNAME;
    316 	sz = SCARG(uap, len);
    317 	return (kern_sysctl(&name, 1, (char *)(u_long)SCARG(uap, hostname),
    318 	    &sz, 0, 0, p));
    319 }
    320 
    321 int
    322 compat_43_netbsd32_osethostname(p, v, retval)
    323 	struct proc *p;
    324 	void *v;
    325 	register_t *retval;
    326 {
    327 	struct compat_43_netbsd32_osethostname_args /* {
    328 		syscallarg(netbsd32_charp) hostname;
    329 		syscallarg(u_int) len;
    330 	} */ *uap = v;
    331 	int name;
    332 	int error;
    333 
    334 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
    335 		return (error);
    336 	name = KERN_HOSTNAME;
    337 	return (kern_sysctl(&name, 1, 0, 0, (char *)(u_long)SCARG(uap,
    338 	    hostname), SCARG(uap, len), p));
    339 }
    340 
    341 int
    342 compat_43_netbsd32_sethostid(p, v, retval)
    343 	struct proc *p;
    344 	void *v;
    345 	register_t *retval;
    346 {
    347 	struct compat_43_netbsd32_sethostid_args /* {
    348 		syscallarg(int32_t) hostid;
    349 	} */ *uap = v;
    350 	struct compat_43_sys_sethostid_args ua;
    351 
    352 	NETBSD32TO64_UAP(hostid);
    353 	return (compat_43_sys_sethostid(p, &ua, retval));
    354 }
    355 
    356 int
    357 compat_43_netbsd32_ogetrlimit(p, v, retval)
    358 	struct proc *p;
    359 	void *v;
    360 	register_t *retval;
    361 {
    362 	struct compat_43_netbsd32_ogetrlimit_args /* {
    363 		syscallarg(int) which;
    364 		syscallarg(netbsd32_orlimitp_t) rlp;
    365 	} */ *uap = v;
    366 	struct compat_43_sys_getrlimit_args ua;
    367 
    368 	NETBSD32TO64_UAP(which);
    369 	NETBSD32TOP_UAP(rlp, struct orlimit);
    370 	return (compat_43_sys_getrlimit(p, &ua, retval));
    371 }
    372 
    373 int
    374 compat_43_netbsd32_osetrlimit(p, v, retval)
    375 	struct proc *p;
    376 	void *v;
    377 	register_t *retval;
    378 {
    379 	struct compat_43_netbsd32_osetrlimit_args /* {
    380 		syscallarg(int) which;
    381 		syscallarg(netbsd32_orlimitp_t) rlp;
    382 	} */ *uap = v;
    383 	struct compat_43_sys_setrlimit_args ua;
    384 
    385 	NETBSD32TO64_UAP(which);
    386 	NETBSD32TOP_UAP(rlp, struct orlimit);
    387 	return (compat_43_sys_setrlimit(p, &ua, retval));
    388 }
    389 
    390 int
    391 compat_43_netbsd32_killpg(p, v, retval)
    392 	struct proc *p;
    393 	void *v;
    394 	register_t *retval;
    395 {
    396 	struct compat_43_netbsd32_killpg_args /* {
    397 		syscallarg(int) pgid;
    398 		syscallarg(int) signum;
    399 	} */ *uap = v;
    400 	struct compat_43_sys_killpg_args ua;
    401 
    402 	NETBSD32TO64_UAP(pgid);
    403 	NETBSD32TO64_UAP(signum);
    404 	return (compat_43_sys_killpg(p, &ua, retval));
    405 }
    406 
    407 /* virtual memory syscalls */
    408 int
    409 compat_43_netbsd32_ommap(p, v, retval)
    410 	struct proc *p;
    411 	void *v;
    412 	register_t *retval;
    413 {
    414 	struct compat_43_netbsd32_ommap_args /* {
    415 		syscallarg(netbsd32_caddr_t) addr;
    416 		syscallarg(netbsd32_size_t) len;
    417 		syscallarg(int) prot;
    418 		syscallarg(int) flags;
    419 		syscallarg(int) fd;
    420 		syscallarg(netbsd32_long) pos;
    421 	} */ *uap = v;
    422 	struct compat_43_sys_mmap_args ua;
    423 
    424 	NETBSD32TOX64_UAP(addr, caddr_t);
    425 	NETBSD32TOX_UAP(len, size_t);
    426 	NETBSD32TO64_UAP(prot);
    427 	NETBSD32TO64_UAP(flags);
    428 	NETBSD32TO64_UAP(fd);
    429 	NETBSD32TOX_UAP(pos, long);
    430 	return (compat_43_sys_mmap(p, &ua, retval));
    431 }
    432 
    433 /* network syscalls */
    434 int
    435 compat_43_netbsd32_oaccept(p, v, retval)
    436 	struct proc *p;
    437 	void *v;
    438 	register_t *retval;
    439 {
    440 	struct compat_43_netbsd32_oaccept_args /* {
    441 		syscallarg(int) s;
    442 		syscallarg(netbsd32_caddr_t) name;
    443 		syscallarg(netbsd32_intp) anamelen;
    444 	} */ *uap = v;
    445 	struct compat_43_sys_accept_args ua;
    446 
    447 	NETBSD32TOX_UAP(s, int);
    448 	NETBSD32TOX64_UAP(name, caddr_t);
    449 	NETBSD32TOP_UAP(anamelen, int);
    450 	return (compat_43_sys_accept(p, &ua, retval));
    451 }
    452 
    453 int
    454 compat_43_netbsd32_osend(p, v, retval)
    455 	struct proc *p;
    456 	void *v;
    457 	register_t *retval;
    458 {
    459 	struct compat_43_netbsd32_osend_args /* {
    460 		syscallarg(int) s;
    461 		syscallarg(netbsd32_caddr_t) buf;
    462 		syscallarg(int) len;
    463 		syscallarg(int) flags;
    464 	} */ *uap = v;
    465 	struct compat_43_sys_send_args ua;
    466 
    467 	NETBSD32TO64_UAP(s);
    468 	NETBSD32TOX64_UAP(buf, caddr_t);
    469 	NETBSD32TO64_UAP(len);
    470 	NETBSD32TO64_UAP(flags);
    471 	return (compat_43_sys_send(p, &ua, retval));
    472 }
    473 
    474 int
    475 compat_43_netbsd32_orecv(p, v, retval)
    476 	struct proc *p;
    477 	void *v;
    478 	register_t *retval;
    479 {
    480 	struct compat_43_netbsd32_orecv_args /* {
    481 		syscallarg(int) s;
    482 		syscallarg(netbsd32_caddr_t) buf;
    483 		syscallarg(int) len;
    484 		syscallarg(int) flags;
    485 	} */ *uap = v;
    486 	struct compat_43_sys_recv_args ua;
    487 
    488 	NETBSD32TO64_UAP(s);
    489 	NETBSD32TOX64_UAP(buf, caddr_t);
    490 	NETBSD32TO64_UAP(len);
    491 	NETBSD32TO64_UAP(flags);
    492 	return (compat_43_sys_recv(p, &ua, retval));
    493 }
    494 
    495 /*
    496  * XXX convert these to use a common iovec code to the native
    497  * netbsd call.
    498  */
    499 int
    500 compat_43_netbsd32_orecvmsg(p, v, retval)
    501 	struct proc *p;
    502 	void *v;
    503 	register_t *retval;
    504 {
    505 	struct compat_43_netbsd32_orecvmsg_args /* {
    506 		syscallarg(int) s;
    507 		syscallarg(netbsd32_omsghdrp_t) msg;
    508 		syscallarg(int) flags;
    509 	} */ *uap = v;
    510 	struct compat_43_sys_recvmsg_args ua;
    511 	struct omsghdr omh, *sgsbp;
    512 	struct netbsd32_omsghdr omh32;
    513 	struct iovec iov, *sgsbp2;
    514 	struct netbsd32_iovec iov32, *iovec32p;
    515 	caddr_t sg = stackgap_init(p->p_emul);
    516 	int i, error, rv;
    517 
    518 	NETBSD32TO64_UAP(s);
    519 	NETBSD32TO64_UAP(flags);
    520 
    521 	/*
    522 	 * this is annoying:
    523 	 *	- copyin the msghdr32 struct
    524 	 *	- stackgap_alloc a msghdr struct
    525 	 *	- convert msghdr32 to msghdr:
    526 	 *		- stackgap_alloc enough space for iovec's
    527 	 *		- copy in each iov32, and convert to iov
    528 	 *		- copyout converted iov
    529 	 *	- copyout converted msghdr
    530 	 *	- do real syscall
    531 	 *	- copyin the msghdr struct
    532 	 *	- convert msghdr to msghdr32
    533 	 *		- copyin each iov and convert to iov32
    534 	 *		- copyout converted iov32
    535 	 *	- copyout converted msghdr32
    536 	 */
    537 	error = copyin((caddr_t)(u_long)SCARG(uap, msg), &omh32, sizeof(omh32));
    538 	if (error)
    539 		return (error);
    540 
    541 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(&sg, sizeof(omh));
    542 	omh.msg_name = (caddr_t)(u_long)omh32.msg_name;
    543 	omh.msg_namelen = omh32.msg_namelen;
    544 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
    545 	omh.msg_iov = sgsbp2 = stackgap_alloc(&sg, sizeof(struct iovec) * omh.msg_iovlen);
    546 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
    547 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    548 		error = copyin(iovec32p, &iov32, sizeof(iov32));
    549 		if (error)
    550 			return (error);
    551 		iov.iov_base = (struct iovec *)(u_long)iovec32p->iov_base;
    552 		iov.iov_len = (size_t)iovec32p->iov_len;
    553 		error = copyout(&iov, sgsbp2, sizeof(iov));
    554 		if (error)
    555 			return (error);
    556 	}
    557 	omh.msg_accrights = (caddr_t)(u_long)omh32.msg_accrights;
    558 	omh.msg_accrightslen = omh32.msg_accrightslen;
    559 	error = copyout(&omh, sgsbp, sizeof(omh));
    560 	if (error)
    561 		return (error);
    562 
    563 	rv = compat_43_sys_recvmsg(p, &ua, retval);
    564 
    565 	error = copyin(sgsbp, &omh, sizeof(omh));
    566 	if (error)
    567 		return error;
    568 	omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name;
    569 	omh32.msg_namelen = omh.msg_namelen;
    570 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
    571 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
    572 	sgsbp2 = omh.msg_iov;
    573 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    574 		error = copyin(sgsbp2, &iov, sizeof(iov));
    575 		if (error)
    576 			return (error);
    577 		iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base;
    578 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
    579 		error = copyout(&iov32, iovec32p, sizeof(iov32));
    580 		if (error)
    581 			return (error);
    582 	}
    583 	omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights;
    584 	omh32.msg_accrightslen = omh.msg_accrightslen;
    585 
    586 	error = copyout(&omh32, (char *)(u_long)SCARG(uap, msg), sizeof(omh32));
    587 	if (error)
    588 		return error;
    589 
    590 	return (rv);
    591 }
    592 
    593 int
    594 compat_43_netbsd32_osendmsg(p, v, retval)
    595 	struct proc *p;
    596 	void *v;
    597 	register_t *retval;
    598 {
    599 	struct compat_43_netbsd32_osendmsg_args /* {
    600 		syscallarg(int) s;
    601 		syscallarg(netbsd32_caddr_t) msg;
    602 		syscallarg(int) flags;
    603 	} */ *uap = v;
    604 	struct compat_43_sys_recvmsg_args ua;
    605 	struct omsghdr omh, *sgsbp;
    606 	struct netbsd32_omsghdr omh32;
    607 	struct iovec iov, *sgsbp2;
    608 	struct netbsd32_iovec iov32, *iovec32p;
    609 	caddr_t sg = stackgap_init(p->p_emul);
    610 	int i, error, rv;
    611 
    612 	NETBSD32TO64_UAP(s);
    613 	NETBSD32TO64_UAP(flags);
    614 
    615 	/*
    616 	 * this is annoying:
    617 	 *	- copyin the msghdr32 struct
    618 	 *	- stackgap_alloc a msghdr struct
    619 	 *	- convert msghdr32 to msghdr:
    620 	 *		- stackgap_alloc enough space for iovec's
    621 	 *		- copy in each iov32, and convert to iov
    622 	 *		- copyout converted iov
    623 	 *	- copyout converted msghdr
    624 	 *	- do real syscall
    625 	 *	- copyin the msghdr struct
    626 	 *	- convert msghdr to msghdr32
    627 	 *		- copyin each iov and convert to iov32
    628 	 *		- copyout converted iov32
    629 	 *	- copyout converted msghdr32
    630 	 */
    631 	error = copyin((caddr_t)(u_long)SCARG(uap, msg), &omh32, sizeof(omh32));
    632 	if (error)
    633 		return (error);
    634 
    635 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(&sg, sizeof(omh));
    636 	omh.msg_name = (caddr_t)(u_long)omh32.msg_name;
    637 	omh.msg_namelen = omh32.msg_namelen;
    638 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
    639 	omh.msg_iov = sgsbp2 = stackgap_alloc(&sg, sizeof(struct iovec) * omh.msg_iovlen);
    640 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
    641 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    642 		error = copyin(iovec32p, &iov32, sizeof(iov32));
    643 		if (error)
    644 			return (error);
    645 		iov.iov_base = (struct iovec *)(u_long)iovec32p->iov_base;
    646 		iov.iov_len = (size_t)iovec32p->iov_len;
    647 		error = copyout(&iov, sgsbp2, sizeof(iov));
    648 		if (error)
    649 			return (error);
    650 	}
    651 	omh.msg_accrights = (caddr_t)(u_long)omh32.msg_accrights;
    652 	omh.msg_accrightslen = omh32.msg_accrightslen;
    653 	error = copyout(&omh, sgsbp, sizeof(omh));
    654 	if (error)
    655 		return (error);
    656 
    657 	rv = compat_43_sys_sendmsg(p, &ua, retval);
    658 
    659 	error = copyin(sgsbp, &omh, sizeof(omh));
    660 	if (error)
    661 		return error;
    662 	omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name;
    663 	omh32.msg_namelen = omh.msg_namelen;
    664 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
    665 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
    666 	sgsbp2 = omh.msg_iov;
    667 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    668 		error = copyin(sgsbp2, &iov, sizeof(iov));
    669 		if (error)
    670 			return (error);
    671 		iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base;
    672 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
    673 		error = copyout(&iov32, iovec32p, sizeof(iov32));
    674 		if (error)
    675 			return (error);
    676 	}
    677 	omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights;
    678 	omh32.msg_accrightslen = omh.msg_accrightslen;
    679 
    680 	error = copyout(&omh32, (char *)(u_long)SCARG(uap, msg), sizeof(omh32));
    681 	if (error)
    682 		return error;
    683 
    684 	return (rv);
    685 }
    686 
    687 int
    688 compat_43_netbsd32_orecvfrom(p, v, retval)
    689 	struct proc *p;
    690 	void *v;
    691 	register_t *retval;
    692 {
    693 	struct compat_43_netbsd32_orecvfrom_args /* {
    694 		syscallarg(int) s;
    695 		syscallarg(netbsd32_caddr_t) buf;
    696 		syscallarg(netbsd32_size_t) len;
    697 		syscallarg(int) flags;
    698 		syscallarg(netbsd32_caddr_t) from;
    699 		syscallarg(netbsd32_intp) fromlenaddr;
    700 	} */ *uap = v;
    701 	struct compat_43_sys_recvfrom_args ua;
    702 
    703 	NETBSD32TO64_UAP(s);
    704 	NETBSD32TOX64_UAP(buf, caddr_t);
    705 	NETBSD32TOX_UAP(len, size_t);
    706 	NETBSD32TO64_UAP(flags);
    707 	NETBSD32TOX64_UAP(from, caddr_t);
    708 	NETBSD32TOP_UAP(fromlenaddr, int);
    709 	return (compat_43_sys_recvfrom(p, &ua, retval));
    710 }
    711 
    712 int
    713 compat_43_netbsd32_ogetsockname(p, v, retval)
    714 	struct proc *p;
    715 	void *v;
    716 	register_t *retval;
    717 {
    718 	struct compat_43_netbsd32_ogetsockname_args /* {
    719 		syscallarg(int) fdec;
    720 		syscallarg(netbsd32_caddr_t) asa;
    721 		syscallarg(netbsd32_intp) alen;
    722 	} */ *uap = v;
    723 	struct compat_43_sys_getsockname_args ua;
    724 
    725 	NETBSD32TO64_UAP(fdec);
    726 	NETBSD32TOX64_UAP(asa, caddr_t);
    727 	NETBSD32TOP_UAP(alen, int);
    728 	return (compat_43_sys_getsockname(p, &ua, retval));
    729 }
    730 
    731 int
    732 compat_43_netbsd32_ogetpeername(p, v, retval)
    733 	struct proc *p;
    734 	void *v;
    735 	register_t *retval;
    736 {
    737 	struct compat_43_netbsd32_ogetpeername_args /* {
    738 		syscallarg(int) fdes;
    739 		syscallarg(netbsd32_caddr_t) asa;
    740 		syscallarg(netbsd32_intp) alen;
    741 	} */ *uap = v;
    742 	struct compat_43_sys_getpeername_args ua;
    743 
    744 	NETBSD32TO64_UAP(fdes);
    745 	NETBSD32TOX64_UAP(asa, caddr_t);
    746 	NETBSD32TOP_UAP(alen, int);
    747 	return (compat_43_sys_getpeername(p, &ua, retval));
    748 }
    749 
    750 /* signal syscalls */
    751 int
    752 compat_43_netbsd32_osigvec(p, v, retval)
    753 	struct proc *p;
    754 	void *v;
    755 	register_t *retval;
    756 {
    757 	struct compat_43_netbsd32_osigvec_args /* {
    758 		syscallarg(int) signum;
    759 		syscallarg(netbsd32_sigvecp_t) nsv;
    760 		syscallarg(netbsd32_sigvecp_t) osv;
    761 	} */ *uap = v;
    762 	struct compat_43_sys_sigvec_args ua;
    763 	struct netbsd32_sigvec sv32;
    764 	struct sigvec sv, *sgnsvp, *sgosvp;
    765 	caddr_t sg = stackgap_init(p->p_emul);
    766 	int rv, error;
    767 
    768 	NETBSD32TO64_UAP(signum);
    769 	if (SCARG(uap, osv))
    770 		SCARG(&ua, osv) = sgosvp = stackgap_alloc(&sg, sizeof(sv));
    771 	else
    772 		SCARG(&ua, osv) = NULL;
    773 	if (SCARG(uap, nsv)) {
    774 		SCARG(&ua, nsv) = sgnsvp = stackgap_alloc(&sg, sizeof(sv));
    775 		error = copyin((caddr_t)(u_long)SCARG(uap, nsv), &sv32, sizeof(sv32));
    776 		if (error)
    777 			return (error);
    778 		sv.sv_handler = (void *)(u_long)sv32.sv_handler;
    779 		sv.sv_mask = sv32.sv_mask;
    780 		sv.sv_flags = sv32.sv_flags;
    781 		error = copyout(&sv, sgnsvp, sizeof(sv));
    782 		if (error)
    783 			return (error);
    784 	} else
    785 		SCARG(&ua, nsv) = NULL;
    786 	rv = compat_43_sys_sigvec(p, &ua, retval);
    787 	if (rv)
    788 		return (rv);
    789 
    790 	if (SCARG(uap, osv)) {
    791 		error = copyin(sgosvp, &sv, sizeof(sv));
    792 		if (error)
    793 			return (error);
    794 		sv32.sv_handler = (netbsd32_sigvecp_t)(u_long)sv.sv_handler;
    795 		sv32.sv_mask = sv.sv_mask;
    796 		sv32.sv_flags = sv.sv_flags;
    797 		error = copyout(&sv32, (caddr_t)(u_long)SCARG(uap, osv), sizeof(sv32));
    798 		if (error)
    799 			return (error);
    800 	}
    801 
    802 	return (0);
    803 }
    804 
    805 int
    806 compat_43_netbsd32_sigblock(p, v, retval)
    807 	struct proc *p;
    808 	void *v;
    809 	register_t *retval;
    810 {
    811 	struct compat_43_netbsd32_sigblock_args /* {
    812 		syscallarg(int) mask;
    813 	} */ *uap = v;
    814 	struct compat_43_sys_sigblock_args ua;
    815 
    816 	NETBSD32TO64_UAP(mask);
    817 	return (compat_43_sys_sigblock(p, &ua, retval));
    818 }
    819 
    820 int
    821 compat_43_netbsd32_sigsetmask(p, v, retval)
    822 	struct proc *p;
    823 	void *v;
    824 	register_t *retval;
    825 {
    826 	struct compat_43_netbsd32_sigsetmask_args /* {
    827 		syscallarg(int) mask;
    828 	} */ *uap = v;
    829 	struct compat_43_sys_sigsetmask_args ua;
    830 
    831 	NETBSD32TO64_UAP(mask);
    832 	return (compat_43_sys_sigsetmask(p, &ua, retval));
    833 }
    834 
    835 int
    836 compat_43_netbsd32_osigstack(p, v, retval)
    837 	struct proc *p;
    838 	void *v;
    839 	register_t *retval;
    840 {
    841 	struct compat_43_netbsd32_osigstack_args /* {
    842 		syscallarg(netbsd32_sigstackp_t) nss;
    843 		syscallarg(netbsd32_sigstackp_t) oss;
    844 	} */ *uap = v;
    845 	struct compat_43_sys_sigstack_args ua;
    846 	struct netbsd32_sigstack ss32;
    847 	struct sigstack ss, *sgossp, *sgnssp;
    848 	caddr_t sg = stackgap_init(p->p_emul);
    849 	int error, rv;
    850 
    851 	if (SCARG(uap, oss))
    852 		SCARG(&ua, oss) = sgossp = stackgap_alloc(&sg, sizeof(ss));
    853 	else
    854 		SCARG(&ua, oss) = NULL;
    855 	if (SCARG(uap, nss)) {
    856 		SCARG(&ua, nss) = sgnssp = stackgap_alloc(&sg, sizeof(ss));
    857 		error = copyin((caddr_t)(u_long)SCARG(uap, nss), &ss32, sizeof(ss32));
    858 		if (error)
    859 			return (error);
    860 		ss.ss_sp = (void *)(u_long)ss32.ss_sp;
    861 		ss.ss_onstack = ss32.ss_onstack;
    862 		error = copyout(&ss, sgnssp, sizeof(ss));
    863 		if (error)
    864 			return (error);
    865 	} else
    866 		SCARG(&ua, nss) = NULL;
    867 
    868 	rv = compat_43_sys_sigstack(p, &ua, retval);
    869 	if (rv)
    870 		return (rv);
    871 
    872 	if (SCARG(uap, oss)) {
    873 		error = copyin(sgossp, &ss, sizeof(ss));
    874 		if (error)
    875 			return (error);
    876 		ss32.ss_sp = (netbsd32_sigstackp_t)(u_long)ss.ss_sp;
    877 		ss32.ss_onstack = ss.ss_onstack;
    878 		error = copyout(&ss32, (caddr_t)(u_long)SCARG(uap, oss), sizeof(ss32));
    879 		if (error)
    880 			return (error);
    881 	}
    882 
    883 	return (0);
    884 }
    885