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