1 /* $NetBSD: netbsd32_compat_43.c,v 1.27 2003/06/29 22:29:36 fvdl 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.27 2003/06/29 22:29:36 fvdl 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; 325 size_t sz; 326 327 name = KERN_HOSTNAME; 328 sz = SCARG(uap, len); 329 return (kern_sysctl(&name, 1, 330 (char *)NETBSD32PTR64(SCARG(uap, hostname)), &sz, 0, 0, l->l_proc)); 331 } 332 333 int 334 compat_43_netbsd32_osethostname(l, v, retval) 335 struct lwp* l; 336 void *v; 337 register_t *retval; 338 { 339 struct proc *p = l->l_proc; 340 struct compat_43_netbsd32_osethostname_args /* { 341 syscallarg(netbsd32_charp) hostname; 342 syscallarg(u_int) len; 343 } */ *uap = v; 344 int name; 345 int error; 346 347 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 348 return (error); 349 name = KERN_HOSTNAME; 350 return (kern_sysctl(&name, 1, 0, 0, (char *)NETBSD32PTR64(SCARG(uap, 351 hostname)), SCARG(uap, len), p)); 352 } 353 354 int 355 compat_43_netbsd32_sethostid(l, v, retval) 356 struct lwp* l; 357 void *v; 358 register_t *retval; 359 { 360 struct compat_43_netbsd32_sethostid_args /* { 361 syscallarg(int32_t) hostid; 362 } */ *uap = v; 363 struct compat_43_sys_sethostid_args ua; 364 365 NETBSD32TO64_UAP(hostid); 366 return (compat_43_sys_sethostid(l, &ua, retval)); 367 } 368 369 int 370 compat_43_netbsd32_ogetrlimit(l, v, retval) 371 struct lwp* l; 372 void *v; 373 register_t *retval; 374 { 375 struct compat_43_netbsd32_ogetrlimit_args /* { 376 syscallarg(int) which; 377 syscallarg(netbsd32_orlimitp_t) rlp; 378 } */ *uap = v; 379 struct compat_43_sys_getrlimit_args ua; 380 381 NETBSD32TO64_UAP(which); 382 NETBSD32TOP_UAP(rlp, struct orlimit); 383 return (compat_43_sys_getrlimit(l, &ua, retval)); 384 } 385 386 int 387 compat_43_netbsd32_osetrlimit(l, v, retval) 388 struct lwp* l; 389 void *v; 390 register_t *retval; 391 { 392 struct compat_43_netbsd32_osetrlimit_args /* { 393 syscallarg(int) which; 394 syscallarg(netbsd32_orlimitp_t) rlp; 395 } */ *uap = v; 396 struct compat_43_sys_setrlimit_args ua; 397 398 NETBSD32TO64_UAP(which); 399 NETBSD32TOP_UAP(rlp, struct orlimit); 400 return (compat_43_sys_setrlimit(l, &ua, retval)); 401 } 402 403 int 404 compat_43_netbsd32_killpg(l, v, retval) 405 struct lwp* l; 406 void *v; 407 register_t *retval; 408 { 409 struct compat_43_netbsd32_killpg_args /* { 410 syscallarg(int) pgid; 411 syscallarg(int) signum; 412 } */ *uap = v; 413 struct compat_43_sys_killpg_args ua; 414 415 NETBSD32TO64_UAP(pgid); 416 NETBSD32TO64_UAP(signum); 417 return (compat_43_sys_killpg(l, &ua, retval)); 418 } 419 420 /* virtual memory syscalls */ 421 int 422 compat_43_netbsd32_ommap(l, v, retval) 423 struct lwp* l; 424 void *v; 425 register_t *retval; 426 { 427 struct compat_43_netbsd32_ommap_args /* { 428 syscallarg(netbsd32_caddr_t) addr; 429 syscallarg(netbsd32_size_t) len; 430 syscallarg(int) prot; 431 syscallarg(int) flags; 432 syscallarg(int) fd; 433 syscallarg(netbsd32_long) pos; 434 } */ *uap = v; 435 struct compat_43_sys_mmap_args ua; 436 437 NETBSD32TOX64_UAP(addr, caddr_t); 438 NETBSD32TOX_UAP(len, size_t); 439 NETBSD32TO64_UAP(prot); 440 NETBSD32TO64_UAP(flags); 441 NETBSD32TO64_UAP(fd); 442 NETBSD32TOX_UAP(pos, long); 443 return (compat_43_sys_mmap(l, &ua, retval)); 444 } 445 446 /* network syscalls */ 447 int 448 compat_43_netbsd32_oaccept(l, v, retval) 449 struct lwp* l; 450 void *v; 451 register_t *retval; 452 { 453 struct compat_43_netbsd32_oaccept_args /* { 454 syscallarg(int) s; 455 syscallarg(netbsd32_caddr_t) name; 456 syscallarg(netbsd32_intp) anamelen; 457 } */ *uap = v; 458 struct compat_43_sys_accept_args ua; 459 460 NETBSD32TOX_UAP(s, int); 461 NETBSD32TOX64_UAP(name, caddr_t); 462 NETBSD32TOP_UAP(anamelen, int); 463 return (compat_43_sys_accept(l, &ua, retval)); 464 } 465 466 int 467 compat_43_netbsd32_osend(l, v, retval) 468 struct lwp* l; 469 void *v; 470 register_t *retval; 471 { 472 struct compat_43_netbsd32_osend_args /* { 473 syscallarg(int) s; 474 syscallarg(netbsd32_caddr_t) buf; 475 syscallarg(int) len; 476 syscallarg(int) flags; 477 } */ *uap = v; 478 struct compat_43_sys_send_args ua; 479 480 NETBSD32TO64_UAP(s); 481 NETBSD32TOX64_UAP(buf, caddr_t); 482 NETBSD32TO64_UAP(len); 483 NETBSD32TO64_UAP(flags); 484 return (compat_43_sys_send(l, &ua, retval)); 485 } 486 487 int 488 compat_43_netbsd32_orecv(l, v, retval) 489 struct lwp* l; 490 void *v; 491 register_t *retval; 492 { 493 struct compat_43_netbsd32_orecv_args /* { 494 syscallarg(int) s; 495 syscallarg(netbsd32_caddr_t) buf; 496 syscallarg(int) len; 497 syscallarg(int) flags; 498 } */ *uap = v; 499 struct compat_43_sys_recv_args ua; 500 501 NETBSD32TO64_UAP(s); 502 NETBSD32TOX64_UAP(buf, caddr_t); 503 NETBSD32TO64_UAP(len); 504 NETBSD32TO64_UAP(flags); 505 return (compat_43_sys_recv(l, &ua, retval)); 506 } 507 508 /* 509 * XXX convert these to use a common iovec code to the native 510 * netbsd call. 511 */ 512 int 513 compat_43_netbsd32_orecvmsg(l, v, retval) 514 struct lwp* l; 515 void *v; 516 register_t *retval; 517 { 518 struct proc *p = l->l_proc; 519 struct compat_43_netbsd32_orecvmsg_args /* { 520 syscallarg(int) s; 521 syscallarg(netbsd32_omsghdrp_t) msg; 522 syscallarg(int) flags; 523 } */ *uap = v; 524 struct compat_43_sys_recvmsg_args ua; 525 struct omsghdr omh, *sgsbp; 526 struct netbsd32_omsghdr omh32; 527 struct iovec iov, *sgsbp2; 528 struct netbsd32_iovec iov32, *iovec32p; 529 caddr_t sg = stackgap_init(p, 0); 530 int i, error, rv; 531 532 NETBSD32TO64_UAP(s); 533 NETBSD32TO64_UAP(flags); 534 535 /* 536 * this is annoying: 537 * - copyin the msghdr32 struct 538 * - stackgap_alloc a msghdr struct 539 * - convert msghdr32 to msghdr: 540 * - stackgap_alloc enough space for iovec's 541 * - copy in each iov32, and convert to iov 542 * - copyout converted iov 543 * - copyout converted msghdr 544 * - do real syscall 545 * - copyin the msghdr struct 546 * - convert msghdr to msghdr32 547 * - copyin each iov and convert to iov32 548 * - copyout converted iov32 549 * - copyout converted msghdr32 550 */ 551 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, msg)), &omh32, 552 sizeof(omh32)); 553 if (error) 554 return (error); 555 556 SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh)); 557 omh.msg_name = (caddr_t)NETBSD32PTR64(omh32.msg_name); 558 omh.msg_namelen = omh32.msg_namelen; 559 omh.msg_iovlen = (size_t)omh32.msg_iovlen; 560 omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen); 561 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 562 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 563 error = copyin(iovec32p, &iov32, sizeof(iov32)); 564 if (error) 565 return (error); 566 iov.iov_base = 567 (struct iovec *)NETBSD32PTR64(iovec32p->iov_base); 568 iov.iov_len = (size_t)iovec32p->iov_len; 569 error = copyout(&iov, sgsbp2, sizeof(iov)); 570 if (error) 571 return (error); 572 } 573 omh.msg_accrights = (caddr_t)NETBSD32PTR64(omh32.msg_accrights); 574 omh.msg_accrightslen = omh32.msg_accrightslen; 575 error = copyout(&omh, sgsbp, sizeof(omh)); 576 if (error) 577 return (error); 578 579 rv = compat_43_sys_recvmsg(l, &ua, retval); 580 581 error = copyin(sgsbp, &omh, sizeof(omh)); 582 if (error) 583 return error; 584 omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name; 585 omh32.msg_namelen = omh.msg_namelen; 586 omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen; 587 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 588 sgsbp2 = omh.msg_iov; 589 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 590 error = copyin(sgsbp2, &iov, sizeof(iov)); 591 if (error) 592 return (error); 593 iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base; 594 iov32.iov_len = (netbsd32_size_t)iov.iov_len; 595 error = copyout(&iov32, iovec32p, sizeof(iov32)); 596 if (error) 597 return (error); 598 } 599 omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights; 600 omh32.msg_accrightslen = omh.msg_accrightslen; 601 602 error = copyout(&omh32, (char *)NETBSD32PTR64(SCARG(uap, msg)), 603 sizeof(omh32)); 604 if (error) 605 return error; 606 607 return (rv); 608 } 609 610 int 611 compat_43_netbsd32_osendmsg(l, v, retval) 612 struct lwp* l; 613 void *v; 614 register_t *retval; 615 { 616 struct proc *p = l->l_proc; 617 struct compat_43_netbsd32_osendmsg_args /* { 618 syscallarg(int) s; 619 syscallarg(netbsd32_caddr_t) msg; 620 syscallarg(int) flags; 621 } */ *uap = v; 622 struct compat_43_sys_recvmsg_args ua; 623 struct omsghdr omh, *sgsbp; 624 struct netbsd32_omsghdr omh32; 625 struct iovec iov, *sgsbp2; 626 struct netbsd32_iovec iov32, *iovec32p; 627 caddr_t sg = stackgap_init(p, 0); 628 int i, error, rv; 629 630 NETBSD32TO64_UAP(s); 631 NETBSD32TO64_UAP(flags); 632 633 /* 634 * this is annoying: 635 * - copyin the msghdr32 struct 636 * - stackgap_alloc a msghdr struct 637 * - convert msghdr32 to msghdr: 638 * - stackgap_alloc enough space for iovec's 639 * - copy in each iov32, and convert to iov 640 * - copyout converted iov 641 * - copyout converted msghdr 642 * - do real syscall 643 * - copyin the msghdr struct 644 * - convert msghdr to msghdr32 645 * - copyin each iov and convert to iov32 646 * - copyout converted iov32 647 * - copyout converted msghdr32 648 */ 649 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, msg)), &omh32, 650 sizeof(omh32)); 651 if (error) 652 return (error); 653 654 SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh)); 655 omh.msg_name = (caddr_t)NETBSD32PTR64(omh32.msg_name); 656 omh.msg_namelen = omh32.msg_namelen; 657 omh.msg_iovlen = (size_t)omh32.msg_iovlen; 658 omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen); 659 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 660 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 661 error = copyin(iovec32p, &iov32, sizeof(iov32)); 662 if (error) 663 return (error); 664 iov.iov_base = 665 (struct iovec *)NETBSD32PTR64(iovec32p->iov_base); 666 iov.iov_len = (size_t)iovec32p->iov_len; 667 error = copyout(&iov, sgsbp2, sizeof(iov)); 668 if (error) 669 return (error); 670 } 671 omh.msg_accrights = (caddr_t)NETBSD32PTR64(omh32.msg_accrights); 672 omh.msg_accrightslen = omh32.msg_accrightslen; 673 error = copyout(&omh, sgsbp, sizeof(omh)); 674 if (error) 675 return (error); 676 677 rv = compat_43_sys_sendmsg(l, &ua, retval); 678 679 error = copyin(sgsbp, &omh, sizeof(omh)); 680 if (error) 681 return error; 682 omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name; 683 omh32.msg_namelen = omh.msg_namelen; 684 omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen; 685 iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov); 686 sgsbp2 = omh.msg_iov; 687 for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) { 688 error = copyin(sgsbp2, &iov, sizeof(iov)); 689 if (error) 690 return (error); 691 iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base; 692 iov32.iov_len = (netbsd32_size_t)iov.iov_len; 693 error = copyout(&iov32, iovec32p, sizeof(iov32)); 694 if (error) 695 return (error); 696 } 697 omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights; 698 omh32.msg_accrightslen = omh.msg_accrightslen; 699 700 error = copyout(&omh32, (char *)NETBSD32PTR64(SCARG(uap, msg)), 701 sizeof(omh32)); 702 if (error) 703 return error; 704 705 return (rv); 706 } 707 708 int 709 compat_43_netbsd32_orecvfrom(l, v, retval) 710 struct lwp* l; 711 void *v; 712 register_t *retval; 713 { 714 struct compat_43_netbsd32_orecvfrom_args /* { 715 syscallarg(int) s; 716 syscallarg(netbsd32_caddr_t) buf; 717 syscallarg(netbsd32_size_t) len; 718 syscallarg(int) flags; 719 syscallarg(netbsd32_caddr_t) from; 720 syscallarg(netbsd32_intp) fromlenaddr; 721 } */ *uap = v; 722 struct compat_43_sys_recvfrom_args ua; 723 724 NETBSD32TO64_UAP(s); 725 NETBSD32TOX64_UAP(buf, caddr_t); 726 NETBSD32TOX_UAP(len, size_t); 727 NETBSD32TO64_UAP(flags); 728 NETBSD32TOX64_UAP(from, caddr_t); 729 NETBSD32TOP_UAP(fromlenaddr, int); 730 return (compat_43_sys_recvfrom(l, &ua, retval)); 731 } 732 733 int 734 compat_43_netbsd32_ogetsockname(l, v, retval) 735 struct lwp* l; 736 void *v; 737 register_t *retval; 738 { 739 struct compat_43_netbsd32_ogetsockname_args /* { 740 syscallarg(int) fdec; 741 syscallarg(netbsd32_caddr_t) asa; 742 syscallarg(netbsd32_intp) alen; 743 } */ *uap = v; 744 struct compat_43_sys_getsockname_args ua; 745 746 NETBSD32TO64_UAP(fdec); 747 NETBSD32TOX64_UAP(asa, caddr_t); 748 NETBSD32TOP_UAP(alen, int); 749 return (compat_43_sys_getsockname(l, &ua, retval)); 750 } 751 752 int 753 compat_43_netbsd32_ogetpeername(l, v, retval) 754 struct lwp* l; 755 void *v; 756 register_t *retval; 757 { 758 struct compat_43_netbsd32_ogetpeername_args /* { 759 syscallarg(int) fdes; 760 syscallarg(netbsd32_caddr_t) asa; 761 syscallarg(netbsd32_intp) alen; 762 } */ *uap = v; 763 struct compat_43_sys_getpeername_args ua; 764 765 NETBSD32TO64_UAP(fdes); 766 NETBSD32TOX64_UAP(asa, caddr_t); 767 NETBSD32TOP_UAP(alen, int); 768 return (compat_43_sys_getpeername(l, &ua, retval)); 769 } 770 771 /* signal syscalls */ 772 int 773 compat_43_netbsd32_osigvec(l, v, retval) 774 struct lwp* l; 775 void *v; 776 register_t *retval; 777 { 778 struct proc *p = l->l_proc; 779 struct compat_43_netbsd32_osigvec_args /* { 780 syscallarg(int) signum; 781 syscallarg(netbsd32_sigvecp_t) nsv; 782 syscallarg(netbsd32_sigvecp_t) osv; 783 } */ *uap = v; 784 struct compat_43_sys_sigvec_args ua; 785 struct netbsd32_sigvec sv32; 786 struct sigvec sv, *sgnsvp, *sgosvp; 787 caddr_t sg = stackgap_init(p, 0); 788 int rv, error; 789 790 NETBSD32TO64_UAP(signum); 791 if (SCARG(uap, osv)) 792 SCARG(&ua, osv) = sgosvp = stackgap_alloc(p, &sg, sizeof(sv)); 793 else 794 SCARG(&ua, osv) = NULL; 795 if (SCARG(uap, nsv)) { 796 SCARG(&ua, nsv) = sgnsvp = stackgap_alloc(p, &sg, sizeof(sv)); 797 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsv)), &sv32, 798 sizeof(sv32)); 799 if (error) 800 return (error); 801 sv.sv_handler = (void *)NETBSD32PTR64(sv32.sv_handler); 802 sv.sv_mask = sv32.sv_mask; 803 sv.sv_flags = sv32.sv_flags; 804 error = copyout(&sv, sgnsvp, sizeof(sv)); 805 if (error) 806 return (error); 807 } else 808 SCARG(&ua, nsv) = NULL; 809 rv = compat_43_sys_sigvec(l, &ua, retval); 810 if (rv) 811 return (rv); 812 813 if (SCARG(uap, osv)) { 814 error = copyin(sgosvp, &sv, sizeof(sv)); 815 if (error) 816 return (error); 817 sv32.sv_handler = (netbsd32_sigvecp_t)(u_long)sv.sv_handler; 818 sv32.sv_mask = sv.sv_mask; 819 sv32.sv_flags = sv.sv_flags; 820 error = copyout(&sv32, (caddr_t)NETBSD32PTR64(SCARG(uap, osv)), 821 sizeof(sv32)); 822 if (error) 823 return (error); 824 } 825 826 return (0); 827 } 828 829 int 830 compat_43_netbsd32_sigblock(l, v, retval) 831 struct lwp* l; 832 void *v; 833 register_t *retval; 834 { 835 struct compat_43_netbsd32_sigblock_args /* { 836 syscallarg(int) mask; 837 } */ *uap = v; 838 struct compat_43_sys_sigblock_args ua; 839 840 NETBSD32TO64_UAP(mask); 841 return (compat_43_sys_sigblock(l, &ua, retval)); 842 } 843 844 int 845 compat_43_netbsd32_sigsetmask(l, v, retval) 846 struct lwp* l; 847 void *v; 848 register_t *retval; 849 { 850 struct compat_43_netbsd32_sigsetmask_args /* { 851 syscallarg(int) mask; 852 } */ *uap = v; 853 struct compat_43_sys_sigsetmask_args ua; 854 855 NETBSD32TO64_UAP(mask); 856 return (compat_43_sys_sigsetmask(l, &ua, retval)); 857 } 858 859 int 860 compat_43_netbsd32_osigstack(l, v, retval) 861 struct lwp* l; 862 void *v; 863 register_t *retval; 864 { 865 struct proc *p = l->l_proc; 866 struct compat_43_netbsd32_osigstack_args /* { 867 syscallarg(netbsd32_sigstackp_t) nss; 868 syscallarg(netbsd32_sigstackp_t) oss; 869 } */ *uap = v; 870 struct compat_43_sys_sigstack_args ua; 871 struct netbsd32_sigstack ss32; 872 struct sigstack ss, *sgossp, *sgnssp; 873 caddr_t sg = stackgap_init(p, 0); 874 int error, rv; 875 876 if (SCARG(uap, oss)) 877 SCARG(&ua, oss) = sgossp = stackgap_alloc(p, &sg, sizeof(ss)); 878 else 879 SCARG(&ua, oss) = NULL; 880 if (SCARG(uap, nss)) { 881 SCARG(&ua, nss) = sgnssp = stackgap_alloc(p, &sg, sizeof(ss)); 882 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nss)), &ss32, 883 sizeof(ss32)); 884 if (error) 885 return (error); 886 ss.ss_sp = (void *)NETBSD32PTR64(ss32.ss_sp); 887 ss.ss_onstack = ss32.ss_onstack; 888 error = copyout(&ss, sgnssp, sizeof(ss)); 889 if (error) 890 return (error); 891 } else 892 SCARG(&ua, nss) = NULL; 893 894 rv = compat_43_sys_sigstack(l, &ua, retval); 895 if (rv) 896 return (rv); 897 898 if (SCARG(uap, oss)) { 899 error = copyin(sgossp, &ss, sizeof(ss)); 900 if (error) 901 return (error); 902 ss32.ss_sp = (netbsd32_sigstackp_t)(u_long)ss.ss_sp; 903 ss32.ss_onstack = ss.ss_onstack; 904 error = copyout(&ss32, (caddr_t)NETBSD32PTR64(SCARG(uap, oss)), 905 sizeof(ss32)); 906 if (error) 907 return (error); 908 } 909 910 return (0); 911 } 912