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