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