1 /* $NetBSD: netbsd32_compat_43.c,v 1.29 2003/12/04 19:38:23 atatat Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2001 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.29 2003/12/04 19:38:23 atatat Exp $"); 33 34 #if defined(_KERNEL_OPT) 35 #include "opt_compat_43.h" 36 #endif 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/fcntl.h> 41 #include <sys/malloc.h> 42 #include <sys/mount.h> 43 #include <sys/proc.h> 44 #include <sys/stat.h> 45 #include <sys/sa.h> 46 #include <sys/syscallargs.h> 47 #include <sys/time.h> 48 #include <sys/ucred.h> 49 #include <uvm/uvm_extern.h> 50 #include <sys/sysctl.h> 51 #include <sys/swap.h> 52 53 #include <compat/netbsd32/netbsd32.h> 54 #include <compat/netbsd32/netbsd32_syscallargs.h> 55 56 int compat_43_netbsd32_sethostid __P((struct lwp *, void *, register_t *)); 57 int compat_43_netbsd32_killpg __P((struct lwp *, void *, register_t *retval)); 58 int compat_43_netbsd32_sigblock __P((struct lwp *, void *, register_t *retval)); 59 int compat_43_netbsd32_sigblock __P((struct lwp *, void *, register_t *retval)); 60 int compat_43_netbsd32_sigsetmask __P((struct lwp *, void *, register_t *retval)); 61 62 void 63 netbsd32_from_stat43(sp43, sp32) 64 struct stat43 *sp43; 65 struct netbsd32_stat43 *sp32; 66 { 67 68 sp32->st_dev = sp43->st_dev; 69 sp32->st_ino = sp43->st_ino; 70 sp32->st_mode = sp43->st_mode; 71 sp32->st_nlink = sp43->st_nlink; 72 sp32->st_uid = sp43->st_uid; 73 sp32->st_gid = sp43->st_gid; 74 sp32->st_rdev = sp43->st_rdev; 75 sp32->st_size = sp43->st_size; 76 sp32->st_atimespec.tv_sec = sp43->st_atimespec.tv_sec; 77 sp32->st_atimespec.tv_nsec = sp43->st_atimespec.tv_nsec; 78 sp32->st_mtimespec.tv_sec = sp43->st_mtimespec.tv_sec; 79 sp32->st_mtimespec.tv_nsec = sp43->st_mtimespec.tv_nsec; 80 sp32->st_ctimespec.tv_sec = sp43->st_ctimespec.tv_sec; 81 sp32->st_ctimespec.tv_nsec = sp43->st_ctimespec.tv_nsec; 82 sp32->st_blksize = sp43->st_blksize; 83 sp32->st_blocks = sp43->st_blocks; 84 sp32->st_flags = sp43->st_flags; 85 sp32->st_gen = sp43->st_gen; 86 } 87 88 /* file system syscalls */ 89 int 90 compat_43_netbsd32_ocreat(l, v, retval) 91 struct lwp *l; 92 void *v; 93 register_t *retval; 94 { 95 struct proc *p = l->l_proc; 96 struct compat_43_netbsd32_ocreat_args /* { 97 syscallarg(const netbsd32_charp) path; 98 syscallarg(mode_t) mode; 99 } */ *uap = v; 100 struct sys_open_args ua; 101 caddr_t sg; 102 103 NETBSD32TOP_UAP(path, const char); 104 NETBSD32TO64_UAP(mode); 105 SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC; 106 sg = stackgap_init(p, 0); 107 CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path)); 108 109 return (sys_open(l, &ua, retval)); 110 } 111 112 int 113 compat_43_netbsd32_olseek(l, v, retval) 114 struct lwp *l; 115 void *v; 116 register_t *retval; 117 { 118 struct compat_43_netbsd32_olseek_args /* { 119 syscallarg(int) fd; 120 syscallarg(netbsd32_long) offset; 121 syscallarg(int) whence; 122 } */ *uap = v; 123 struct sys_lseek_args ua; 124 int rv; 125 off_t rt; 126 127 SCARG(&ua, fd) = SCARG(uap, fd); 128 NETBSD32TOX_UAP(offset, long); 129 NETBSD32TO64_UAP(whence); 130 rv = sys_lseek(l, &ua, (register_t *)&rt); 131 *retval = rt; 132 133 return (rv); 134 } 135 136 int 137 compat_43_netbsd32_stat43(l, v, retval) 138 struct lwp *l; 139 void *v; 140 register_t *retval; 141 { 142 struct proc *p = l->l_proc; 143 struct compat_43_netbsd32_stat43_args /* { 144 syscallarg(const netbsd32_charp) path; 145 syscallarg(netbsd32_stat43p_t) ub; 146 } */ *uap = v; 147 struct stat43 sb43, *sgsbp; 148 struct netbsd32_stat43 sb32; 149 struct compat_43_sys_stat_args ua; 150 caddr_t sg = stackgap_init(p, 0); 151 int rv, error; 152 153 NETBSD32TOP_UAP(path, const char); 154 SCARG(&ua, ub) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43)); 155 CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path)); 156 rv = compat_43_sys_stat(l, &ua, retval); 157 158 error = copyin(sgsbp, &sb43, sizeof(sb43)); 159 if (error) 160 return error; 161 netbsd32_from_stat43(&sb43, &sb32); 162 error = copyout(&sb32, (char *)NETBSD32PTR64(SCARG(uap, ub)), 163 sizeof(sb32)); 164 if (error) 165 return error; 166 167 return (rv); 168 } 169 170 int 171 compat_43_netbsd32_lstat43(l, v, retval) 172 struct lwp *l; 173 void *v; 174 register_t *retval; 175 { 176 struct proc *p = l->l_proc; 177 struct compat_43_netbsd32_lstat43_args /* { 178 syscallarg(const netbsd32_charp) path; 179 syscallarg(netbsd32_stat43p_t) ub; 180 } */ *uap = v; 181 struct stat43 sb43, *sgsbp; 182 struct netbsd32_stat43 sb32; 183 struct compat_43_sys_lstat_args ua; 184 caddr_t sg = stackgap_init(p, 0); 185 int rv, error; 186 187 NETBSD32TOP_UAP(path, const char); 188 SCARG(&ua, ub) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43)); 189 CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path)); 190 rv = compat_43_sys_stat(l, &ua, retval); 191 192 error = copyin(sgsbp, &sb43, sizeof(sb43)); 193 if (error) 194 return error; 195 netbsd32_from_stat43(&sb43, &sb32); 196 error = copyout(&sb32, (char *)NETBSD32PTR64(SCARG(uap, ub)), 197 sizeof(sb32)); 198 if (error) 199 return error; 200 201 return (rv); 202 } 203 204 int 205 compat_43_netbsd32_fstat43(l, v, retval) 206 struct lwp *l; 207 void *v; 208 register_t *retval; 209 { 210 struct proc *p = l->l_proc; 211 struct compat_43_netbsd32_fstat43_args /* { 212 syscallarg(int) fd; 213 syscallarg(netbsd32_stat43p_t) sb; 214 } */ *uap = v; 215 struct stat43 sb43, *sgsbp; 216 struct netbsd32_stat43 sb32; 217 struct compat_43_sys_fstat_args ua; 218 caddr_t sg = stackgap_init(p, 0); 219 int rv, error; 220 221 NETBSD32TO64_UAP(fd); 222 SCARG(&ua, sb) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43)); 223 rv = compat_43_sys_fstat(l, &ua, retval); 224 225 error = copyin(sgsbp, &sb43, sizeof(sb43)); 226 if (error) 227 return error; 228 netbsd32_from_stat43(&sb43, &sb32); 229 error = copyout(&sb32, (char *)NETBSD32PTR64(SCARG(uap, sb)), 230 sizeof(sb32)); 231 if (error) 232 return error; 233 234 return (rv); 235 } 236 237 int 238 compat_43_netbsd32_otruncate(l, v, retval) 239 struct lwp *l; 240 void *v; 241 register_t *retval; 242 { 243 struct compat_43_netbsd32_otruncate_args /* { 244 syscallarg(const netbsd32_charp) path; 245 syscallarg(netbsd32_long) length; 246 } */ *uap = v; 247 struct sys_truncate_args ua; 248 249 NETBSD32TOP_UAP(path, const char); 250 NETBSD32TO64_UAP(length); 251 return (sys_ftruncate(l, &ua, retval)); 252 } 253 254 int 255 compat_43_netbsd32_oftruncate(l, v, retval) 256 struct lwp *l; 257 void *v; 258 register_t *retval; 259 { 260 struct compat_43_netbsd32_oftruncate_args /* { 261 syscallarg(int) fd; 262 syscallarg(netbsd32_long) length; 263 } */ *uap = v; 264 struct sys_ftruncate_args ua; 265 266 NETBSD32TO64_UAP(fd); 267 NETBSD32TO64_UAP(length); 268 return (sys_ftruncate(l, &ua, retval)); 269 } 270 271 int 272 compat_43_netbsd32_ogetdirentries(l, v, retval) 273 struct lwp *l; 274 void *v; 275 register_t *retval; 276 { 277 struct compat_43_netbsd32_ogetdirentries_args /* { 278 syscallarg(int) fd; 279 syscallarg(netbsd32_charp) buf; 280 syscallarg(u_int) count; 281 syscallarg(netbsd32_longp) basep; 282 } */ *uap = v; 283 struct compat_43_sys_getdirentries_args ua; 284 285 NETBSD32TO64_UAP(fd); 286 NETBSD32TOP_UAP(buf, char); 287 NETBSD32TO64_UAP(count); 288 NETBSD32TOP_UAP(basep, long); 289 return (compat_43_sys_getdirentries(l, &ua, retval)); 290 } 291 292 /* kernel syscalls */ 293 int 294 compat_43_netbsd32_ogetkerninfo(l, v, retval) 295 struct lwp *l; 296 void *v; 297 register_t *retval; 298 { 299 struct compat_43_netbsd32_ogetkerninfo_args /* { 300 syscallarg(int) op; 301 syscallarg(netbsd32_charp) where; 302 syscallarg(netbsd32_intp) size; 303 syscallarg(int) arg; 304 } */ *uap = v; 305 struct compat_43_sys_getkerninfo_args ua; 306 307 NETBSD32TO64_UAP(op); 308 NETBSD32TOP_UAP(where, char); 309 NETBSD32TOP_UAP(size, int); 310 NETBSD32TO64_UAP(arg); 311 return (compat_43_sys_getkerninfo(l, &ua, retval)); 312 } 313 314 int 315 compat_43_netbsd32_ogethostname(l, v, retval) 316 struct lwp* l; 317 void *v; 318 register_t *retval; 319 { 320 struct compat_43_netbsd32_ogethostname_args /* { 321 syscallarg(netbsd32_charp) hostname; 322 syscallarg(u_int) len; 323 } */ *uap = v; 324 int name[2]; 325 size_t sz; 326 327 name[0] = CTL_KERN; 328 name[1] = KERN_HOSTNAME; 329 sz = SCARG(uap, len); 330 return (old_sysctl(&name[0], 2, 331 (char *)NETBSD32PTR64(SCARG(uap, hostname)), &sz, 0, 0, l)); 332 } 333 334 int 335 compat_43_netbsd32_osethostname(l, v, retval) 336 struct lwp* l; 337 void *v; 338 register_t *retval; 339 { 340 struct compat_43_netbsd32_osethostname_args /* { 341 syscallarg(netbsd32_charp) hostname; 342 syscallarg(u_int) len; 343 } */ *uap = v; 344 int name[2]; 345 346 name[0] = CTL_KERN; 347 name[1] = KERN_HOSTNAME; 348 return (old_sysctl(&name[0], 2, 0, 0, (char *)NETBSD32PTR64(SCARG(uap, 349 hostname)), SCARG(uap, len), l)); 350 } 351 352 int 353 compat_43_netbsd32_sethostid(l, v, retval) 354 struct lwp* l; 355 void *v; 356 register_t *retval; 357 { 358 struct compat_43_netbsd32_sethostid_args /* { 359 syscallarg(int32_t) hostid; 360 } */ *uap = v; 361 struct compat_43_sys_sethostid_args ua; 362 363 NETBSD32TO64_UAP(hostid); 364 return (compat_43_sys_sethostid(l, &ua, retval)); 365 } 366 367 int 368 compat_43_netbsd32_ogetrlimit(l, v, retval) 369 struct lwp* l; 370 void *v; 371 register_t *retval; 372 { 373 struct compat_43_netbsd32_ogetrlimit_args /* { 374 syscallarg(int) which; 375 syscallarg(netbsd32_orlimitp_t) rlp; 376 } */ *uap = v; 377 struct compat_43_sys_getrlimit_args ua; 378 379 NETBSD32TO64_UAP(which); 380 NETBSD32TOP_UAP(rlp, struct orlimit); 381 return (compat_43_sys_getrlimit(l, &ua, retval)); 382 } 383 384 int 385 compat_43_netbsd32_osetrlimit(l, v, retval) 386 struct lwp* l; 387 void *v; 388 register_t *retval; 389 { 390 struct compat_43_netbsd32_osetrlimit_args /* { 391 syscallarg(int) which; 392 syscallarg(netbsd32_orlimitp_t) rlp; 393 } */ *uap = v; 394 struct compat_43_sys_setrlimit_args ua; 395 396 NETBSD32TO64_UAP(which); 397 NETBSD32TOP_UAP(rlp, struct orlimit); 398 return (compat_43_sys_setrlimit(l, &ua, retval)); 399 } 400 401 int 402 compat_43_netbsd32_killpg(l, v, retval) 403 struct lwp* l; 404 void *v; 405 register_t *retval; 406 { 407 struct compat_43_netbsd32_killpg_args /* { 408 syscallarg(int) pgid; 409 syscallarg(int) signum; 410 } */ *uap = v; 411 struct compat_43_sys_killpg_args ua; 412 413 NETBSD32TO64_UAP(pgid); 414 NETBSD32TO64_UAP(signum); 415 return (compat_43_sys_killpg(l, &ua, retval)); 416 } 417 418 /* virtual memory syscalls */ 419 int 420 compat_43_netbsd32_ommap(l, v, retval) 421 struct lwp* l; 422 void *v; 423 register_t *retval; 424 { 425 struct compat_43_netbsd32_ommap_args /* { 426 syscallarg(netbsd32_caddr_t) addr; 427 syscallarg(netbsd32_size_t) len; 428 syscallarg(int) prot; 429 syscallarg(int) flags; 430 syscallarg(int) fd; 431 syscallarg(netbsd32_long) pos; 432 } */ *uap = v; 433 struct compat_43_sys_mmap_args ua; 434 435 NETBSD32TOX64_UAP(addr, caddr_t); 436 NETBSD32TOX_UAP(len, size_t); 437 NETBSD32TO64_UAP(prot); 438 NETBSD32TO64_UAP(flags); 439 NETBSD32TO64_UAP(fd); 440 NETBSD32TOX_UAP(pos, long); 441 return (compat_43_sys_mmap(l, &ua, retval)); 442 } 443 444 /* network syscalls */ 445 int 446 compat_43_netbsd32_oaccept(l, v, retval) 447 struct lwp* l; 448 void *v; 449 register_t *retval; 450 { 451 struct compat_43_netbsd32_oaccept_args /* { 452 syscallarg(int) s; 453 syscallarg(netbsd32_caddr_t) name; 454 syscallarg(netbsd32_intp) anamelen; 455 } */ *uap = v; 456 struct compat_43_sys_accept_args ua; 457 458 NETBSD32TOX_UAP(s, int); 459 NETBSD32TOX64_UAP(name, caddr_t); 460 NETBSD32TOP_UAP(anamelen, int); 461 return (compat_43_sys_accept(l, &ua, retval)); 462 } 463 464 int 465 compat_43_netbsd32_osend(l, v, retval) 466 struct lwp* l; 467 void *v; 468 register_t *retval; 469 { 470 struct compat_43_netbsd32_osend_args /* { 471 syscallarg(int) s; 472 syscallarg(netbsd32_caddr_t) buf; 473 syscallarg(int) len; 474 syscallarg(int) flags; 475 } */ *uap = v; 476 struct compat_43_sys_send_args ua; 477 478 NETBSD32TO64_UAP(s); 479 NETBSD32TOX64_UAP(buf, caddr_t); 480 NETBSD32TO64_UAP(len); 481 NETBSD32TO64_UAP(flags); 482 return (compat_43_sys_send(l, &ua, retval)); 483 } 484 485 int 486 compat_43_netbsd32_orecv(l, v, retval) 487 struct lwp* l; 488 void *v; 489 register_t *retval; 490 { 491 struct compat_43_netbsd32_orecv_args /* { 492 syscallarg(int) s; 493 syscallarg(netbsd32_caddr_t) buf; 494 syscallarg(int) len; 495 syscallarg(int) flags; 496 } */ *uap = v; 497 struct compat_43_sys_recv_args ua; 498 499 NETBSD32TO64_UAP(s); 500 NETBSD32TOX64_UAP(buf, caddr_t); 501 NETBSD32TO64_UAP(len); 502 NETBSD32TO64_UAP(flags); 503 return (compat_43_sys_recv(l, &ua, retval)); 504 } 505 506 /* 507 * XXX convert these to use a common iovec code to the native 508 * netbsd call. 509 */ 510 int 511 compat_43_netbsd32_orecvmsg(l, v, retval) 512 struct lwp* l; 513 void *v; 514 register_t *retval; 515 { 516 struct proc *p = l->l_proc; 517 struct compat_43_netbsd32_orecvmsg_args /* { 518 syscallarg(int) s; 519 syscallarg(netbsd32_omsghdrp_t) msg; 520 syscallarg(int) flags; 521 } */ *uap = v; 522 struct compat_43_sys_recvmsg_args ua; 523 struct omsghdr omh, *sgsbp; 524 struct netbsd32_omsghdr omh32; 525 struct iovec iov, *sgsbp2; 526 struct netbsd32_iovec iov32, *iovec32p; 527 caddr_t sg = stackgap_init(p, 0); 528 int i, error, rv; 529 530 NETBSD32TO64_UAP(s); 531 NETBSD32TO64_UAP(flags); 532 533 /* 534 * this is annoying: 535 * - copyin the msghdr32 struct 536 * - stackgap_alloc a msghdr struct 537 * - convert msghdr32 to msghdr: 538 * - stackgap_alloc enough space for iovec's 539 * - copy in each iov32, and convert to iov 540 * - copyout converted iov 541 * - copyout converted msghdr 542 * - do real syscall 543 * - copyin the msghdr struct 544 * - convert msghdr to msghdr32 545 * - copyin each iov and convert to iov32 546 * - copyout converted iov32 547 * - copyout converted msghdr32 548 */ 549 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, msg)), &omh32, 550 sizeof(omh32)); 551 if (error) 552 return (error); 553 554 SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh)); 555 omh.msg_name = (caddr_t)NETBSD32PTR64(omh32.msg_name); 556 omh.msg_namelen = omh32.msg_namelen; 557 omh.msg_iovlen = (size_t)omh32.msg_iovlen; 558 omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen); 559 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 560 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 561 error = copyin(iovec32p, &iov32, sizeof(iov32)); 562 if (error) 563 return (error); 564 iov.iov_base = 565 (struct iovec *)NETBSD32PTR64(iovec32p->iov_base); 566 iov.iov_len = (size_t)iovec32p->iov_len; 567 error = copyout(&iov, sgsbp2, sizeof(iov)); 568 if (error) 569 return (error); 570 } 571 omh.msg_accrights = (caddr_t)NETBSD32PTR64(omh32.msg_accrights); 572 omh.msg_accrightslen = omh32.msg_accrightslen; 573 error = copyout(&omh, sgsbp, sizeof(omh)); 574 if (error) 575 return (error); 576 577 rv = compat_43_sys_recvmsg(l, &ua, retval); 578 579 error = copyin(sgsbp, &omh, sizeof(omh)); 580 if (error) 581 return error; 582 omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name; 583 omh32.msg_namelen = omh.msg_namelen; 584 omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen; 585 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 586 sgsbp2 = omh.msg_iov; 587 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 588 error = copyin(sgsbp2, &iov, sizeof(iov)); 589 if (error) 590 return (error); 591 iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base; 592 iov32.iov_len = (netbsd32_size_t)iov.iov_len; 593 error = copyout(&iov32, iovec32p, sizeof(iov32)); 594 if (error) 595 return (error); 596 } 597 omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights; 598 omh32.msg_accrightslen = omh.msg_accrightslen; 599 600 error = copyout(&omh32, (char *)NETBSD32PTR64(SCARG(uap, msg)), 601 sizeof(omh32)); 602 if (error) 603 return error; 604 605 return (rv); 606 } 607 608 int 609 compat_43_netbsd32_osendmsg(l, v, retval) 610 struct lwp* l; 611 void *v; 612 register_t *retval; 613 { 614 struct proc *p = l->l_proc; 615 struct compat_43_netbsd32_osendmsg_args /* { 616 syscallarg(int) s; 617 syscallarg(netbsd32_caddr_t) msg; 618 syscallarg(int) flags; 619 } */ *uap = v; 620 struct compat_43_sys_recvmsg_args ua; 621 struct omsghdr omh, *sgsbp; 622 struct netbsd32_omsghdr omh32; 623 struct iovec iov, *sgsbp2; 624 struct netbsd32_iovec iov32, *iovec32p; 625 caddr_t sg = stackgap_init(p, 0); 626 int i, error, rv; 627 628 NETBSD32TO64_UAP(s); 629 NETBSD32TO64_UAP(flags); 630 631 /* 632 * this is annoying: 633 * - copyin the msghdr32 struct 634 * - stackgap_alloc a msghdr struct 635 * - convert msghdr32 to msghdr: 636 * - stackgap_alloc enough space for iovec's 637 * - copy in each iov32, and convert to iov 638 * - copyout converted iov 639 * - copyout converted msghdr 640 * - do real syscall 641 * - copyin the msghdr struct 642 * - convert msghdr to msghdr32 643 * - copyin each iov and convert to iov32 644 * - copyout converted iov32 645 * - copyout converted msghdr32 646 */ 647 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, msg)), &omh32, 648 sizeof(omh32)); 649 if (error) 650 return (error); 651 652 SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh)); 653 omh.msg_name = (caddr_t)NETBSD32PTR64(omh32.msg_name); 654 omh.msg_namelen = omh32.msg_namelen; 655 omh.msg_iovlen = (size_t)omh32.msg_iovlen; 656 omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen); 657 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 658 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 659 error = copyin(iovec32p, &iov32, sizeof(iov32)); 660 if (error) 661 return (error); 662 iov.iov_base = 663 (struct iovec *)NETBSD32PTR64(iovec32p->iov_base); 664 iov.iov_len = (size_t)iovec32p->iov_len; 665 error = copyout(&iov, sgsbp2, sizeof(iov)); 666 if (error) 667 return (error); 668 } 669 omh.msg_accrights = (caddr_t)NETBSD32PTR64(omh32.msg_accrights); 670 omh.msg_accrightslen = omh32.msg_accrightslen; 671 error = copyout(&omh, sgsbp, sizeof(omh)); 672 if (error) 673 return (error); 674 675 rv = compat_43_sys_sendmsg(l, &ua, retval); 676 677 error = copyin(sgsbp, &omh, sizeof(omh)); 678 if (error) 679 return error; 680 omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name; 681 omh32.msg_namelen = omh.msg_namelen; 682 omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen; 683 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 684 sgsbp2 = omh.msg_iov; 685 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 686 error = copyin(sgsbp2, &iov, sizeof(iov)); 687 if (error) 688 return (error); 689 iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base; 690 iov32.iov_len = (netbsd32_size_t)iov.iov_len; 691 error = copyout(&iov32, iovec32p, sizeof(iov32)); 692 if (error) 693 return (error); 694 } 695 omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights; 696 omh32.msg_accrightslen = omh.msg_accrightslen; 697 698 error = copyout(&omh32, (char *)NETBSD32PTR64(SCARG(uap, msg)), 699 sizeof(omh32)); 700 if (error) 701 return error; 702 703 return (rv); 704 } 705 706 int 707 compat_43_netbsd32_orecvfrom(l, v, retval) 708 struct lwp* l; 709 void *v; 710 register_t *retval; 711 { 712 struct compat_43_netbsd32_orecvfrom_args /* { 713 syscallarg(int) s; 714 syscallarg(netbsd32_caddr_t) buf; 715 syscallarg(netbsd32_size_t) len; 716 syscallarg(int) flags; 717 syscallarg(netbsd32_caddr_t) from; 718 syscallarg(netbsd32_intp) fromlenaddr; 719 } */ *uap = v; 720 struct compat_43_sys_recvfrom_args ua; 721 722 NETBSD32TO64_UAP(s); 723 NETBSD32TOX64_UAP(buf, caddr_t); 724 NETBSD32TOX_UAP(len, size_t); 725 NETBSD32TO64_UAP(flags); 726 NETBSD32TOX64_UAP(from, caddr_t); 727 NETBSD32TOP_UAP(fromlenaddr, int); 728 return (compat_43_sys_recvfrom(l, &ua, retval)); 729 } 730 731 int 732 compat_43_netbsd32_ogetsockname(l, v, retval) 733 struct lwp* l; 734 void *v; 735 register_t *retval; 736 { 737 struct compat_43_netbsd32_ogetsockname_args /* { 738 syscallarg(int) fdec; 739 syscallarg(netbsd32_caddr_t) asa; 740 syscallarg(netbsd32_intp) alen; 741 } */ *uap = v; 742 struct compat_43_sys_getsockname_args ua; 743 744 NETBSD32TO64_UAP(fdec); 745 NETBSD32TOX64_UAP(asa, caddr_t); 746 NETBSD32TOP_UAP(alen, int); 747 return (compat_43_sys_getsockname(l, &ua, retval)); 748 } 749 750 int 751 compat_43_netbsd32_ogetpeername(l, v, retval) 752 struct lwp* l; 753 void *v; 754 register_t *retval; 755 { 756 struct compat_43_netbsd32_ogetpeername_args /* { 757 syscallarg(int) fdes; 758 syscallarg(netbsd32_caddr_t) asa; 759 syscallarg(netbsd32_intp) alen; 760 } */ *uap = v; 761 struct compat_43_sys_getpeername_args ua; 762 763 NETBSD32TO64_UAP(fdes); 764 NETBSD32TOX64_UAP(asa, caddr_t); 765 NETBSD32TOP_UAP(alen, int); 766 return (compat_43_sys_getpeername(l, &ua, retval)); 767 } 768 769 /* signal syscalls */ 770 int 771 compat_43_netbsd32_osigvec(l, v, retval) 772 struct lwp* l; 773 void *v; 774 register_t *retval; 775 { 776 struct proc *p = l->l_proc; 777 struct compat_43_netbsd32_osigvec_args /* { 778 syscallarg(int) signum; 779 syscallarg(netbsd32_sigvecp_t) nsv; 780 syscallarg(netbsd32_sigvecp_t) osv; 781 } */ *uap = v; 782 struct compat_43_sys_sigvec_args ua; 783 struct netbsd32_sigvec sv32; 784 struct sigvec sv; 785 caddr_t sg = stackgap_init(p, 0); 786 int rv, error; 787 788 NETBSD32TO64_UAP(signum); 789 if (SCARG(uap, osv)) 790 SCARG(&ua, osv) = stackgap_alloc(p, &sg, sizeof(sv)); 791 else 792 SCARG(&ua, osv) = NULL; 793 if (SCARG(uap, nsv)) { 794 SCARG(&ua, nsv) = stackgap_alloc(p, &sg, sizeof(sv)); 795 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsv)), &sv32, 796 sizeof(sv32)); 797 if (error) 798 return (error); 799 sv.sv_handler = (void *)NETBSD32PTR64(sv32.sv_handler); 800 sv.sv_mask = sv32.sv_mask; 801 sv.sv_flags = sv32.sv_flags; 802 error = copyout(&sv, SCARG(&ua, nsv), sizeof(sv)); 803 if (error) 804 return (error); 805 } else 806 SCARG(&ua, nsv) = NULL; 807 rv = compat_43_sys_sigvec(l, &ua, retval); 808 if (rv) 809 return (rv); 810 811 if (SCARG(uap, osv)) { 812 error = copyin(SCARG(&ua, osv), &sv, sizeof(sv)); 813 if (error) 814 return (error); 815 sv32.sv_handler = (netbsd32_sigvecp_t)(u_long)sv.sv_handler; 816 sv32.sv_mask = sv.sv_mask; 817 sv32.sv_flags = sv.sv_flags; 818 error = copyout(&sv32, (caddr_t)NETBSD32PTR64(SCARG(uap, osv)), 819 sizeof(sv32)); 820 if (error) 821 return (error); 822 } 823 824 return (0); 825 } 826 827 int 828 compat_43_netbsd32_sigblock(l, v, retval) 829 struct lwp* l; 830 void *v; 831 register_t *retval; 832 { 833 struct compat_43_netbsd32_sigblock_args /* { 834 syscallarg(int) mask; 835 } */ *uap = v; 836 struct compat_43_sys_sigblock_args ua; 837 838 NETBSD32TO64_UAP(mask); 839 return (compat_43_sys_sigblock(l, &ua, retval)); 840 } 841 842 int 843 compat_43_netbsd32_sigsetmask(l, v, retval) 844 struct lwp* l; 845 void *v; 846 register_t *retval; 847 { 848 struct compat_43_netbsd32_sigsetmask_args /* { 849 syscallarg(int) mask; 850 } */ *uap = v; 851 struct compat_43_sys_sigsetmask_args ua; 852 853 NETBSD32TO64_UAP(mask); 854 return (compat_43_sys_sigsetmask(l, &ua, retval)); 855 } 856 857 int 858 compat_43_netbsd32_osigstack(l, v, retval) 859 struct lwp* l; 860 void *v; 861 register_t *retval; 862 { 863 struct proc *p = l->l_proc; 864 struct compat_43_netbsd32_osigstack_args /* { 865 syscallarg(netbsd32_sigstackp_t) nss; 866 syscallarg(netbsd32_sigstackp_t) oss; 867 } */ *uap = v; 868 struct compat_43_sys_sigstack_args ua; 869 struct netbsd32_sigstack ss32; 870 struct sigstack ss; 871 caddr_t sg = stackgap_init(p, 0); 872 int error, rv; 873 874 if (SCARG(uap, oss)) 875 SCARG(&ua, oss) = stackgap_alloc(p, &sg, sizeof(ss)); 876 else 877 SCARG(&ua, oss) = NULL; 878 if (SCARG(uap, nss)) { 879 SCARG(&ua, nss) = stackgap_alloc(p, &sg, sizeof(ss)); 880 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nss)), &ss32, 881 sizeof(ss32)); 882 if (error) 883 return (error); 884 ss.ss_sp = (void *)NETBSD32PTR64(ss32.ss_sp); 885 ss.ss_onstack = ss32.ss_onstack; 886 error = copyout(&ss, SCARG(&ua, nss), sizeof(ss)); 887 if (error) 888 return (error); 889 } else 890 SCARG(&ua, nss) = NULL; 891 892 rv = compat_43_sys_sigstack(l, &ua, retval); 893 if (rv) 894 return (rv); 895 896 if (SCARG(uap, oss)) { 897 error = copyin(SCARG(&ua, oss), &ss, sizeof(ss)); 898 if (error) 899 return (error); 900 ss32.ss_sp = (netbsd32_sigstackp_t)(u_long)ss.ss_sp; 901 ss32.ss_onstack = ss.ss_onstack; 902 error = copyout(&ss32, (caddr_t)NETBSD32PTR64(SCARG(uap, oss)), 903 sizeof(ss32)); 904 if (error) 905 return (error); 906 } 907 908 return (0); 909 } 910