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