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