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