Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_compat_43.c revision 1.40
      1 /*	$NetBSD: netbsd32_compat_43.c,v 1.40 2007/04/22 08:29:58 dsl 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.40 2007/04/22 08:29:58 dsl 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 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 
    106 	NETBSD32TOP_UAP(path, const char);
    107 	NETBSD32TO64_UAP(mode);
    108 	SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC;
    109 
    110 	return (sys_open(l, &ua, retval));
    111 }
    112 
    113 int
    114 compat_43_netbsd32_olseek(l, v, retval)
    115 	struct lwp *l;
    116 	void *v;
    117 	register_t *retval;
    118 {
    119 	struct compat_43_netbsd32_olseek_args /* {
    120 		syscallarg(int) fd;
    121 		syscallarg(netbsd32_long) offset;
    122 		syscallarg(int) whence;
    123 	} */ *uap = v;
    124 	struct sys_lseek_args ua;
    125 	int rv;
    126 	off_t rt;
    127 
    128 	SCARG(&ua, fd) = SCARG(uap, fd);
    129 	NETBSD32TOX_UAP(offset, long);
    130 	NETBSD32TO64_UAP(whence);
    131 	rv = sys_lseek(l, &ua, (register_t *)&rt);
    132 	*retval = rt;
    133 
    134 	return (rv);
    135 }
    136 
    137 int
    138 compat_43_netbsd32_stat43(l, v, retval)
    139 	struct lwp *l;
    140 	void *v;
    141 	register_t *retval;
    142 {
    143 	struct proc *p = l->l_proc;
    144 	struct compat_43_netbsd32_stat43_args /* {
    145 		syscallarg(const netbsd32_charp) path;
    146 		syscallarg(netbsd32_stat43p_t) ub;
    147 	} */ *uap = v;
    148 	struct stat43 sb43, *sgsbp;
    149 	struct netbsd32_stat43 sb32;
    150 	struct compat_43_sys_stat_args ua;
    151 	void *sg = stackgap_init(p, 0);
    152 	int rv, error;
    153 
    154 	NETBSD32TOP_UAP(path, const char);
    155 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43));
    156 	rv = compat_43_sys_stat(l, &ua, retval);
    157 
    158 	error = copyin(sgsbp, &sb43, sizeof(sb43));
    159 	if (error)
    160 		return error;
    161 	netbsd32_from_stat43(&sb43, &sb32);
    162 	error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
    163 	if (error)
    164 		return error;
    165 
    166 	return (rv);
    167 }
    168 
    169 int
    170 compat_43_netbsd32_lstat43(l, v, retval)
    171 	struct lwp *l;
    172 	void *v;
    173 	register_t *retval;
    174 {
    175 	struct proc *p = l->l_proc;
    176 	struct compat_43_netbsd32_lstat43_args /* {
    177 		syscallarg(const netbsd32_charp) path;
    178 		syscallarg(netbsd32_stat43p_t) ub;
    179 	} */ *uap = v;
    180 	struct stat43 sb43, *sgsbp;
    181 	struct netbsd32_stat43 sb32;
    182 	struct compat_43_sys_lstat_args ua;
    183 	void *sg = stackgap_init(p, 0);
    184 	int rv, error;
    185 
    186 	NETBSD32TOP_UAP(path, const char);
    187 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43));
    188 	rv = compat_43_sys_stat(l, &ua, retval);
    189 
    190 	error = copyin(sgsbp, &sb43, sizeof(sb43));
    191 	if (error)
    192 		return error;
    193 	netbsd32_from_stat43(&sb43, &sb32);
    194 	error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
    195 	if (error)
    196 		return error;
    197 
    198 	return (rv);
    199 }
    200 
    201 int
    202 compat_43_netbsd32_fstat43(l, v, retval)
    203 	struct lwp *l;
    204 	void *v;
    205 	register_t *retval;
    206 {
    207 	struct proc *p = l->l_proc;
    208 	struct compat_43_netbsd32_fstat43_args /* {
    209 		syscallarg(int) fd;
    210 		syscallarg(netbsd32_stat43p_t) sb;
    211 	} */ *uap = v;
    212 	struct stat43 sb43, *sgsbp;
    213 	struct netbsd32_stat43 sb32;
    214 	struct compat_43_sys_fstat_args ua;
    215 	void *sg = stackgap_init(p, 0);
    216 	int rv, error;
    217 
    218 	NETBSD32TO64_UAP(fd);
    219 	SCARG(&ua, sb) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43));
    220 	rv = compat_43_sys_fstat(l, &ua, retval);
    221 
    222 	error = copyin(sgsbp, &sb43, sizeof(sb43));
    223 	if (error)
    224 		return error;
    225 	netbsd32_from_stat43(&sb43, &sb32);
    226 	error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32));
    227 	if (error)
    228 		return error;
    229 
    230 	return (rv);
    231 }
    232 
    233 int
    234 compat_43_netbsd32_otruncate(l, v, retval)
    235 	struct lwp *l;
    236 	void *v;
    237 	register_t *retval;
    238 {
    239 	struct compat_43_netbsd32_otruncate_args /* {
    240 		syscallarg(const netbsd32_charp) path;
    241 		syscallarg(netbsd32_long) length;
    242 	} */ *uap = v;
    243 	struct sys_truncate_args ua;
    244 
    245 	NETBSD32TOP_UAP(path, const char);
    246 	NETBSD32TO64_UAP(length);
    247 	return (sys_ftruncate(l, &ua, retval));
    248 }
    249 
    250 int
    251 compat_43_netbsd32_oftruncate(l, v, retval)
    252 	struct lwp *l;
    253 	void *v;
    254 	register_t *retval;
    255 {
    256 	struct compat_43_netbsd32_oftruncate_args /* {
    257 		syscallarg(int) fd;
    258 		syscallarg(netbsd32_long) length;
    259 	} */ *uap = v;
    260 	struct sys_ftruncate_args ua;
    261 
    262 	NETBSD32TO64_UAP(fd);
    263 	NETBSD32TO64_UAP(length);
    264 	return (sys_ftruncate(l, &ua, retval));
    265 }
    266 
    267 int
    268 compat_43_netbsd32_ogetdirentries(l, v, retval)
    269 	struct lwp *l;
    270 	void *v;
    271 	register_t *retval;
    272 {
    273 	struct compat_43_netbsd32_ogetdirentries_args /* {
    274 		syscallarg(int) fd;
    275 		syscallarg(netbsd32_charp) buf;
    276 		syscallarg(u_int) count;
    277 		syscallarg(netbsd32_longp) basep;
    278 	} */ *uap = v;
    279 	struct compat_43_sys_getdirentries_args ua;
    280 
    281 	NETBSD32TO64_UAP(fd);
    282 	NETBSD32TOP_UAP(buf, char);
    283 	NETBSD32TO64_UAP(count);
    284 	NETBSD32TOP_UAP(basep, long);
    285 	return (compat_43_sys_getdirentries(l, &ua, retval));
    286 }
    287 
    288 /* kernel syscalls */
    289 int
    290 compat_43_netbsd32_ogetkerninfo(l, v, retval)
    291 	struct lwp *l;
    292 	void *v;
    293 	register_t *retval;
    294 {
    295 	struct compat_43_netbsd32_ogetkerninfo_args /* {
    296 		syscallarg(int) op;
    297 		syscallarg(netbsd32_charp) where;
    298 		syscallarg(netbsd32_intp) size;
    299 		syscallarg(int) arg;
    300 	} */ *uap = v;
    301 	struct compat_43_sys_getkerninfo_args ua;
    302 
    303 	NETBSD32TO64_UAP(op);
    304 	NETBSD32TOP_UAP(where, char);
    305 	NETBSD32TOP_UAP(size, int);
    306 	NETBSD32TO64_UAP(arg);
    307 	return (compat_43_sys_getkerninfo(l, &ua, retval));
    308 }
    309 
    310 int
    311 compat_43_netbsd32_ogethostname(l, v, retval)
    312 	struct lwp* l;
    313 	void *v;
    314 	register_t *retval;
    315 {
    316 	struct compat_43_netbsd32_ogethostname_args /* {
    317 		syscallarg(netbsd32_charp) hostname;
    318 		syscallarg(u_int) len;
    319 	} */ *uap = v;
    320 	int name[2];
    321 	size_t sz;
    322 
    323 	name[0] = CTL_KERN;
    324 	name[1] = KERN_HOSTNAME;
    325 	sz = SCARG(uap, len);
    326 	return (old_sysctl(&name[0], 2,
    327 	    SCARG_P32(uap, hostname), &sz, 0, 0, l));
    328 }
    329 
    330 int
    331 compat_43_netbsd32_osethostname(l, v, retval)
    332 	struct lwp* l;
    333 	void *v;
    334 	register_t *retval;
    335 {
    336 	struct compat_43_netbsd32_osethostname_args /* {
    337 		syscallarg(netbsd32_charp) hostname;
    338 		syscallarg(u_int) len;
    339 	} */ *uap = v;
    340 	int name[2];
    341 
    342 	name[0] = CTL_KERN;
    343 	name[1] = KERN_HOSTNAME;
    344 	return old_sysctl(&name[0], 2, 0, 0, (char *)SCARG_P32(uap,
    345 	    hostname), SCARG(uap, len), l);
    346 }
    347 
    348 int
    349 compat_43_netbsd32_sethostid(l, v, retval)
    350 	struct lwp* l;
    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(l, &ua, retval));
    361 }
    362 
    363 int
    364 compat_43_netbsd32_ogetrlimit(l, v, retval)
    365 	struct lwp* l;
    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(l, &ua, retval));
    378 }
    379 
    380 int
    381 compat_43_netbsd32_osetrlimit(l, v, retval)
    382 	struct lwp* l;
    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(l, &ua, retval));
    395 }
    396 
    397 int
    398 compat_43_netbsd32_killpg(l, v, retval)
    399 	struct lwp* l;
    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(l, &ua, retval));
    412 }
    413 
    414 /* virtual memory syscalls */
    415 int
    416 compat_43_netbsd32_ommap(l, v, retval)
    417 	struct lwp* l;
    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 	NETBSD32TOP_UAP(addr, void *);
    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(l, &ua, retval));
    438 }
    439 
    440 /* network syscalls */
    441 int
    442 compat_43_netbsd32_oaccept(l, v, retval)
    443 	struct lwp* l;
    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 	NETBSD32TOP_UAP(name, void *);
    456 	NETBSD32TOP_UAP(anamelen, int);
    457 	return (compat_43_sys_accept(l, &ua, retval));
    458 }
    459 
    460 int
    461 compat_43_netbsd32_osend(l, v, retval)
    462 	struct lwp* l;
    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 	NETBSD32TOP_UAP(buf, void *);
    476 	NETBSD32TO64_UAP(len);
    477 	NETBSD32TO64_UAP(flags);
    478 	return (compat_43_sys_send(l, &ua, retval));
    479 }
    480 
    481 int
    482 compat_43_netbsd32_orecv(l, v, retval)
    483 	struct lwp* l;
    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 	NETBSD32TOP_UAP(buf, void *);
    497 	NETBSD32TO64_UAP(len);
    498 	NETBSD32TO64_UAP(flags);
    499 	return (compat_43_sys_recv(l, &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(l, v, retval)
    508 	struct lwp* l;
    509 	void *v;
    510 	register_t *retval;
    511 {
    512 	struct proc *p = l->l_proc;
    513 	struct compat_43_netbsd32_orecvmsg_args /* {
    514 		syscallarg(int) s;
    515 		syscallarg(netbsd32_omsghdrp_t) msg;
    516 		syscallarg(int) flags;
    517 	} */ *uap = v;
    518 	struct compat_43_sys_recvmsg_args ua;
    519 	struct omsghdr omh, *sgsbp;
    520 	struct netbsd32_omsghdr omh32;
    521 	struct iovec iov, *sgsbp2;
    522 	struct netbsd32_iovec iov32, *iovec32p;
    523 	void *sg = stackgap_init(p, 0);
    524 	int i, error, rv;
    525 
    526 	NETBSD32TO64_UAP(s);
    527 	NETBSD32TO64_UAP(flags);
    528 
    529 	/*
    530 	 * this is annoying:
    531 	 *	- copyin the msghdr32 struct
    532 	 *	- stackgap_alloc a msghdr struct
    533 	 *	- convert msghdr32 to msghdr:
    534 	 *		- stackgap_alloc enough space for iovec's
    535 	 *		- copy in each iov32, and convert to iov
    536 	 *		- copyout converted iov
    537 	 *	- copyout converted msghdr
    538 	 *	- do real syscall
    539 	 *	- copyin the msghdr struct
    540 	 *	- convert msghdr to msghdr32
    541 	 *		- copyin each iov and convert to iov32
    542 	 *		- copyout converted iov32
    543 	 *	- copyout converted msghdr32
    544 	 */
    545 	error = copyin(SCARG_P32(uap, msg), &omh32, sizeof(omh32));
    546 	if (error)
    547 		return (error);
    548 
    549 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh));
    550 	omh.msg_name = (void *)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 = (void *)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(l, &ua, retval);
    573 
    574 	error = copyin(sgsbp, &omh, sizeof(omh));
    575 	if (error)
    576 		return error;
    577 	NETBSD32PTR32(omh32.msg_name, omh.msg_name);
    578 	omh32.msg_namelen = omh.msg_namelen;
    579 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
    580 	iovec32p = 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 		NETBSD32PTR32(iov32.iov_base, 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 	NETBSD32PTR32(omh32.msg_accrights, omh.msg_accrights);
    593 	omh32.msg_accrightslen = omh.msg_accrightslen;
    594 
    595 	error = copyout(&omh32, SCARG_P32(uap, msg), sizeof(omh32));
    596 	if (error)
    597 		return error;
    598 
    599 	return (rv);
    600 }
    601 
    602 int
    603 compat_43_netbsd32_osendmsg(l, v, retval)
    604 	struct lwp* l;
    605 	void *v;
    606 	register_t *retval;
    607 {
    608 	struct proc *p = l->l_proc;
    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 	void *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(SCARG_P32(uap, msg), &omh32, sizeof(omh32));
    642 	if (error)
    643 		return (error);
    644 
    645 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh));
    646 	omh.msg_name = NETBSD32PTR64(omh32.msg_name);
    647 	omh.msg_namelen = omh32.msg_namelen;
    648 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
    649 	omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen);
    650 	iovec32p = NETBSD32PTR64(omh32.msg_iov);
    651 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    652 		error = copyin(iovec32p, &iov32, sizeof(iov32));
    653 		if (error)
    654 			return (error);
    655 		iov.iov_base = NETBSD32PTR64(iovec32p->iov_base);
    656 		iov.iov_len = (size_t)iovec32p->iov_len;
    657 		error = copyout(&iov, sgsbp2, sizeof(iov));
    658 		if (error)
    659 			return (error);
    660 	}
    661 	omh.msg_accrights = NETBSD32PTR64(omh32.msg_accrights);
    662 	omh.msg_accrightslen = omh32.msg_accrightslen;
    663 	error = copyout(&omh, sgsbp, sizeof(omh));
    664 	if (error)
    665 		return (error);
    666 
    667 	rv = compat_43_sys_sendmsg(l, &ua, retval);
    668 
    669 	error = copyin(sgsbp, &omh, sizeof(omh));
    670 	if (error)
    671 		return error;
    672 	NETBSD32PTR32(omh32.msg_name, omh.msg_name);
    673 	omh32.msg_namelen = omh.msg_namelen;
    674 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
    675 	iovec32p = NETBSD32PTR64(omh32.msg_iov);
    676 	sgsbp2 = omh.msg_iov;
    677 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    678 		error = copyin(sgsbp2, &iov, sizeof(iov));
    679 		if (error)
    680 			return (error);
    681 		NETBSD32PTR32(iov32.iov_base, iov.iov_base);
    682 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
    683 		error = copyout(&iov32, iovec32p, sizeof(iov32));
    684 		if (error)
    685 			return (error);
    686 	}
    687 	NETBSD32PTR32(omh32.msg_accrights, omh.msg_accrights);
    688 	omh32.msg_accrightslen = omh.msg_accrightslen;
    689 
    690 	error = copyout(&omh32, SCARG_P32(uap, msg), sizeof(omh32));
    691 	if (error)
    692 		return error;
    693 
    694 	return (rv);
    695 }
    696 
    697 int
    698 compat_43_netbsd32_orecvfrom(l, v, retval)
    699 	struct lwp* l;
    700 	void *v;
    701 	register_t *retval;
    702 {
    703 	struct compat_43_netbsd32_orecvfrom_args /* {
    704 		syscallarg(int) s;
    705 		syscallarg(netbsd32_caddr_t) buf;
    706 		syscallarg(netbsd32_size_t) len;
    707 		syscallarg(int) flags;
    708 		syscallarg(netbsd32_caddr_t) from;
    709 		syscallarg(netbsd32_intp) fromlenaddr;
    710 	} */ *uap = v;
    711 	struct compat_43_sys_recvfrom_args ua;
    712 
    713 	NETBSD32TO64_UAP(s);
    714 	NETBSD32TOP_UAP(buf, void *);
    715 	NETBSD32TOX_UAP(len, size_t);
    716 	NETBSD32TO64_UAP(flags);
    717 	NETBSD32TOP_UAP(from, void *);
    718 	NETBSD32TOP_UAP(fromlenaddr, int);
    719 	return (compat_43_sys_recvfrom(l, &ua, retval));
    720 }
    721 
    722 int
    723 compat_43_netbsd32_ogetsockname(l, v, retval)
    724 	struct lwp* l;
    725 	void *v;
    726 	register_t *retval;
    727 {
    728 	struct compat_43_netbsd32_ogetsockname_args /* {
    729 		syscallarg(int) fdec;
    730 		syscallarg(netbsd32_caddr_t) asa;
    731 		syscallarg(netbsd32_intp) alen;
    732 	} */ *uap = v;
    733 	struct compat_43_sys_getsockname_args ua;
    734 
    735 	NETBSD32TO64_UAP(fdec);
    736 	NETBSD32TOP_UAP(asa, void *);
    737 	NETBSD32TOP_UAP(alen, int *);
    738 	return (compat_43_sys_getsockname(l, &ua, retval));
    739 }
    740 
    741 int
    742 compat_43_netbsd32_ogetpeername(l, v, retval)
    743 	struct lwp* l;
    744 	void *v;
    745 	register_t *retval;
    746 {
    747 	struct compat_43_netbsd32_ogetpeername_args /* {
    748 		syscallarg(int) fdes;
    749 		syscallarg(netbsd32_caddr_t) asa;
    750 		syscallarg(netbsd32_intp) alen;
    751 	} */ *uap = v;
    752 	struct compat_43_sys_getpeername_args ua;
    753 
    754 	NETBSD32TO64_UAP(fdes);
    755 	NETBSD32TOP_UAP(asa, void *);
    756 	NETBSD32TOP_UAP(alen, int *);
    757 	return (compat_43_sys_getpeername(l, &ua, retval));
    758 }
    759 
    760 /* signal syscalls */
    761 int
    762 compat_43_netbsd32_osigvec(l, v, retval)
    763 	struct lwp* l;
    764 	void *v;
    765 	register_t *retval;
    766 {
    767 	struct proc *p = l->l_proc;
    768 	struct compat_43_netbsd32_osigvec_args /* {
    769 		syscallarg(int) signum;
    770 		syscallarg(netbsd32_sigvecp_t) nsv;
    771 		syscallarg(netbsd32_sigvecp_t) osv;
    772 	} */ *uap = v;
    773 	struct compat_43_sys_sigvec_args ua;
    774 	struct netbsd32_sigvec sv32;
    775 	struct sigvec sv;
    776 	void *sg = stackgap_init(p, 0);
    777 	int rv, error;
    778 
    779 	NETBSD32TO64_UAP(signum);
    780 	if (SCARG_P32(uap, osv))
    781 		SCARG(&ua, osv) = stackgap_alloc(p, &sg, sizeof(sv));
    782 	else
    783 		SCARG(&ua, osv) = NULL;
    784 	if (SCARG_P32(uap, nsv)) {
    785 		SCARG(&ua, nsv) = stackgap_alloc(p, &sg, sizeof(sv));
    786 		error = copyin(SCARG_P32(uap, nsv), &sv32, sizeof(sv32));
    787 		if (error)
    788 			return (error);
    789 		sv.sv_handler = (void *)NETBSD32PTR64(sv32.sv_handler);
    790 		sv.sv_mask = sv32.sv_mask;
    791 		sv.sv_flags = sv32.sv_flags;
    792 		error = copyout(&sv, SCARG(&ua, nsv), sizeof(sv));
    793 		if (error)
    794 			return (error);
    795 	} else
    796 		SCARG(&ua, nsv) = NULL;
    797 	rv = compat_43_sys_sigvec(l, &ua, retval);
    798 	if (rv)
    799 		return (rv);
    800 
    801 	if (SCARG_P32(uap, osv)) {
    802 		error = copyin(SCARG(&ua, osv), &sv, sizeof(sv));
    803 		if (error)
    804 			return (error);
    805 		NETBSD32PTR32(sv32.sv_handler, sv.sv_handler);
    806 		sv32.sv_mask = sv.sv_mask;
    807 		sv32.sv_flags = sv.sv_flags;
    808 		error = copyout(&sv32, SCARG_P32(uap, osv), sizeof(sv32));
    809 		if (error)
    810 			return (error);
    811 	}
    812 
    813 	return (0);
    814 }
    815 
    816 int
    817 compat_43_netbsd32_sigblock(l, v, retval)
    818 	struct lwp* l;
    819 	void *v;
    820 	register_t *retval;
    821 {
    822 	struct compat_43_netbsd32_sigblock_args /* {
    823 		syscallarg(int) mask;
    824 	} */ *uap = v;
    825 	struct compat_43_sys_sigblock_args ua;
    826 
    827 	NETBSD32TO64_UAP(mask);
    828 	return (compat_43_sys_sigblock(l, &ua, retval));
    829 }
    830 
    831 int
    832 compat_43_netbsd32_sigsetmask(l, v, retval)
    833 	struct lwp* l;
    834 	void *v;
    835 	register_t *retval;
    836 {
    837 	struct compat_43_netbsd32_sigsetmask_args /* {
    838 		syscallarg(int) mask;
    839 	} */ *uap = v;
    840 	struct compat_43_sys_sigsetmask_args ua;
    841 
    842 	NETBSD32TO64_UAP(mask);
    843 	return (compat_43_sys_sigsetmask(l, &ua, retval));
    844 }
    845 
    846 int
    847 compat_43_netbsd32_osigstack(l, v, retval)
    848 	struct lwp* l;
    849 	void *v;
    850 	register_t *retval;
    851 {
    852 	struct proc *p = l->l_proc;
    853 	struct compat_43_netbsd32_osigstack_args /* {
    854 		syscallarg(netbsd32_sigstackp_t) nss;
    855 		syscallarg(netbsd32_sigstackp_t) oss;
    856 	} */ *uap = v;
    857 	struct compat_43_sys_sigstack_args ua;
    858 	struct netbsd32_sigstack ss32;
    859 	struct sigstack ss;
    860 	void *sg = stackgap_init(p, 0);
    861 	int error, rv;
    862 
    863 	if (SCARG_P32(uap, oss))
    864 		SCARG(&ua, oss) = stackgap_alloc(p, &sg, sizeof(ss));
    865 	else
    866 		SCARG(&ua, oss) = NULL;
    867 	if (SCARG_P32(uap, nss)) {
    868 		SCARG(&ua, nss) = stackgap_alloc(p, &sg, sizeof(ss));
    869 		error = copyin(SCARG_P32(uap, nss), &ss32, sizeof(ss32));
    870 		if (error)
    871 			return (error);
    872 		ss.ss_sp = NETBSD32PTR64(ss32.ss_sp);
    873 		ss.ss_onstack = ss32.ss_onstack;
    874 		error = copyout(&ss, SCARG(&ua, nss), sizeof(ss));
    875 		if (error)
    876 			return (error);
    877 	} else
    878 		SCARG(&ua, nss) = NULL;
    879 
    880 	rv = compat_43_sys_sigstack(l, &ua, retval);
    881 	if (rv)
    882 		return (rv);
    883 
    884 	if (SCARG_P32(uap, oss)) {
    885 		error = copyin(SCARG(&ua, oss), &ss, sizeof(ss));
    886 		if (error)
    887 			return (error);
    888 		NETBSD32PTR32(ss32.ss_sp, ss.ss_sp);
    889 		ss32.ss_onstack = ss.ss_onstack;
    890 		error = copyout(&ss32, SCARG_P32(uap, oss), sizeof(ss32));
    891 		if (error)
    892 			return (error);
    893 	}
    894 
    895 	return (0);
    896 }
    897