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