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