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