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