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