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