Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_compat_43.c revision 1.43
      1 /*	$NetBSD: netbsd32_compat_43.c,v 1.43 2007/06/16 22:31:08 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.43 2007/06/16 22:31:08 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 	NETBSD32PTR32(omh32.msg_accrights, omh.msg_accrights);
    551 	omh32.msg_accrightslen = omh.msg_accrightslen;
    552 
    553 	error = copyout(&omh32, SCARG_P32(uap, msg), sizeof(omh32));
    554 	if (error)
    555 		return error;
    556 
    557 	return (rv);
    558 }
    559 
    560 int
    561 compat_43_netbsd32_osendmsg(l, v, retval)
    562 	struct lwp* l;
    563 	void *v;
    564 	register_t *retval;
    565 {
    566 	struct proc *p = l->l_proc;
    567 	struct compat_43_netbsd32_osendmsg_args /* {
    568 		syscallarg(int) s;
    569 		syscallarg(netbsd32_caddr_t) msg;
    570 		syscallarg(int) flags;
    571 	} */ *uap = v;
    572 	struct compat_43_sys_recvmsg_args ua;
    573 	struct omsghdr omh, *sgsbp;
    574 	struct netbsd32_omsghdr omh32;
    575 	struct iovec iov, *sgsbp2;
    576 	struct netbsd32_iovec iov32, *iovec32p;
    577 	void *sg = stackgap_init(p, 0);
    578 	int i, error;
    579 
    580 	NETBSD32TO64_UAP(s);
    581 	NETBSD32TO64_UAP(flags);
    582 
    583 	/*
    584 	 * this is annoying:
    585 	 *	- copyin the msghdr32 struct
    586 	 *	- stackgap_alloc a msghdr struct
    587 	 *	- convert msghdr32 to msghdr:
    588 	 *		- stackgap_alloc enough space for iovec's
    589 	 *		- copy in each iov32, and convert to iov
    590 	 *		- copyout converted iov
    591 	 *	- copyout converted msghdr
    592 	 *	- do real syscall
    593 	 *	- copyin the msghdr struct
    594 	 *	- convert msghdr to msghdr32
    595 	 *		- copyin each iov and convert to iov32
    596 	 *		- copyout converted iov32
    597 	 *	- copyout converted msghdr32
    598 	 */
    599 	error = copyin(SCARG_P32(uap, msg), &omh32, sizeof(omh32));
    600 	if (error)
    601 		return (error);
    602 
    603 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh));
    604 	omh.msg_name = NETBSD32PTR64(omh32.msg_name);
    605 	omh.msg_namelen = omh32.msg_namelen;
    606 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
    607 	omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen);
    608 	iovec32p = NETBSD32PTR64(omh32.msg_iov);
    609 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
    610 		error = copyin(iovec32p, &iov32, sizeof(iov32));
    611 		if (error)
    612 			return (error);
    613 		iov.iov_base = NETBSD32PTR64(iovec32p->iov_base);
    614 		iov.iov_len = (size_t)iovec32p->iov_len;
    615 		error = copyout(&iov, sgsbp2, sizeof(iov));
    616 		if (error)
    617 			return (error);
    618 	}
    619 	omh.msg_accrights = NETBSD32PTR64(omh32.msg_accrights);
    620 	omh.msg_accrightslen = omh32.msg_accrightslen;
    621 	error = copyout(&omh, sgsbp, sizeof(omh));
    622 	if (error)
    623 		return (error);
    624 
    625 	return compat_43_sys_sendmsg(l, &ua, retval);
    626 }
    627 
    628 int
    629 compat_43_netbsd32_orecvfrom(l, v, retval)
    630 	struct lwp* l;
    631 	void *v;
    632 	register_t *retval;
    633 {
    634 	struct compat_43_netbsd32_orecvfrom_args /* {
    635 		syscallarg(int) s;
    636 		syscallarg(netbsd32_caddr_t) buf;
    637 		syscallarg(netbsd32_size_t) len;
    638 		syscallarg(int) flags;
    639 		syscallarg(netbsd32_caddr_t) from;
    640 		syscallarg(netbsd32_intp) fromlenaddr;
    641 	} */ *uap = v;
    642 	struct compat_43_sys_recvfrom_args ua;
    643 
    644 	NETBSD32TO64_UAP(s);
    645 	NETBSD32TOP_UAP(buf, void *);
    646 	NETBSD32TOX_UAP(len, size_t);
    647 	NETBSD32TO64_UAP(flags);
    648 	NETBSD32TOP_UAP(from, void *);
    649 	NETBSD32TOP_UAP(fromlenaddr, int);
    650 	return (compat_43_sys_recvfrom(l, &ua, retval));
    651 }
    652 
    653 int
    654 compat_43_netbsd32_ogetsockname(l, v, retval)
    655 	struct lwp* l;
    656 	void *v;
    657 	register_t *retval;
    658 {
    659 	struct compat_43_netbsd32_ogetsockname_args /* {
    660 		syscallarg(int) fdec;
    661 		syscallarg(netbsd32_caddr_t) asa;
    662 		syscallarg(netbsd32_intp) alen;
    663 	} */ *uap = v;
    664 	struct compat_43_sys_getsockname_args ua;
    665 
    666 	NETBSD32TO64_UAP(fdec);
    667 	NETBSD32TOP_UAP(asa, void *);
    668 	NETBSD32TOP_UAP(alen, int *);
    669 	return (compat_43_sys_getsockname(l, &ua, retval));
    670 }
    671 
    672 int
    673 compat_43_netbsd32_ogetpeername(l, v, retval)
    674 	struct lwp* l;
    675 	void *v;
    676 	register_t *retval;
    677 {
    678 	struct compat_43_netbsd32_ogetpeername_args /* {
    679 		syscallarg(int) fdes;
    680 		syscallarg(netbsd32_caddr_t) asa;
    681 		syscallarg(netbsd32_intp) alen;
    682 	} */ *uap = v;
    683 	struct compat_43_sys_getpeername_args ua;
    684 
    685 	NETBSD32TO64_UAP(fdes);
    686 	NETBSD32TOP_UAP(asa, void *);
    687 	NETBSD32TOP_UAP(alen, int *);
    688 	return (compat_43_sys_getpeername(l, &ua, retval));
    689 }
    690 
    691 /* signal syscalls */
    692 int
    693 compat_43_netbsd32_osigvec(l, v, retval)
    694 	struct lwp* l;
    695 	void *v;
    696 	register_t *retval;
    697 {
    698 	struct compat_43_netbsd32_osigvec_args /* {
    699 		syscallarg(int) signum;
    700 		syscallarg(netbsd32_sigvecp_t) nsv;
    701 		syscallarg(netbsd32_sigvecp_t) osv;
    702 	} */ *uap = v;
    703 	struct netbsd32_sigvec sv32;
    704 	struct sigaction nsa, osa;
    705 	int error;
    706 
    707 	if (SCARG(uap, signum) >= 32)
    708 		return EINVAL;
    709 
    710 	if (SCARG_P32(uap, nsv)) {
    711 		error = copyin(SCARG_P32(uap, nsv), &sv32, sizeof(sv32));
    712 		if (error)
    713 			return error;
    714 		nsa.sa_handler = NETBSD32PTR64(sv32.sv_handler);
    715 		nsa.sa_mask.__bits[0] = sv32.sv_mask;
    716 		nsa.sa_mask.__bits[1] = 0;
    717 		nsa.sa_mask.__bits[2] = 0;
    718 		nsa.sa_mask.__bits[3] = 0;
    719 		nsa.sa_flags = sv32.sv_flags ^ SA_RESTART;
    720 		error = sigaction1(l, SCARG(uap, signum), &nsa, &osa, NULL, 0);
    721 	} else
    722 		error = sigaction1(l, SCARG(uap, signum), NULL, &osa, NULL, 0);
    723 	if (error)
    724 		return error;
    725 
    726 	if (SCARG_P32(uap, osv)) {
    727 		NETBSD32PTR32(sv32.sv_handler, osa.sa_handler);
    728 		sv32.sv_mask = osa.sa_mask.__bits[0];
    729 		sv32.sv_flags = osa.sa_flags ^ SA_RESTART;
    730 		error = copyout(&sv32, SCARG_P32(uap, osv), sizeof(sv32));
    731 	}
    732 
    733 	return error;
    734 }
    735 
    736 int
    737 compat_43_netbsd32_sigblock(l, v, retval)
    738 	struct lwp* l;
    739 	void *v;
    740 	register_t *retval;
    741 {
    742 	struct compat_43_netbsd32_sigblock_args /* {
    743 		syscallarg(int) mask;
    744 	} */ *uap = v;
    745 	struct compat_43_sys_sigblock_args ua;
    746 
    747 	NETBSD32TO64_UAP(mask);
    748 	return (compat_43_sys_sigblock(l, &ua, retval));
    749 }
    750 
    751 int
    752 compat_43_netbsd32_sigsetmask(l, v, retval)
    753 	struct lwp* l;
    754 	void *v;
    755 	register_t *retval;
    756 {
    757 	struct compat_43_netbsd32_sigsetmask_args /* {
    758 		syscallarg(int) mask;
    759 	} */ *uap = v;
    760 	struct compat_43_sys_sigsetmask_args ua;
    761 
    762 	NETBSD32TO64_UAP(mask);
    763 	return (compat_43_sys_sigsetmask(l, &ua, retval));
    764 }
    765 
    766 int
    767 compat_43_netbsd32_osigstack(l, v, retval)
    768 	struct lwp* l;
    769 	void *v;
    770 	register_t *retval;
    771 {
    772 	struct compat_43_netbsd32_osigstack_args /* {
    773 		syscallarg(netbsd32_sigstackp_t) nss;
    774 		syscallarg(netbsd32_sigstackp_t) oss;
    775 	} */ *uap = v;
    776 	struct netbsd32_sigstack ss32;
    777 	struct sigaltstack nsa, osa;
    778 	int error;
    779 
    780 	if (SCARG_P32(uap, nss)) {
    781 		error = copyin(SCARG_P32(uap, nss), &ss32, sizeof(ss32));
    782 		if (error)
    783 			return error;
    784 		nsa.ss_sp = NETBSD32PTR64(ss32.ss_sp);
    785 		nsa.ss_size = SIGSTKSZ; /* Use the recommended size */
    786 		nsa.ss_flags = ss32.ss_onstack ? SS_ONSTACK : 0;
    787 		error = sigaltstack1(l, &nsa, &osa);
    788 	} else
    789 		error = sigaltstack1(l, NULL, &osa);
    790 	if (error)
    791 		return error;
    792 
    793 	if (SCARG_P32(uap, oss)) {
    794 		NETBSD32PTR32(ss32.ss_sp, osa.ss_sp);
    795 		ss32.ss_onstack = (osa.ss_flags & SS_ONSTACK) != 0;
    796 		error = copyout(&ss32, SCARG_P32(uap, oss), sizeof(ss32));
    797 	}
    798 
    799 	return error;
    800 }
    801