1 /*- 2 * Copyright (c) 2002 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/bus.h> 32 #include <sys/dkstat.h> 33 #include <sys/exec.h> 34 #include <sys/fcntl.h> 35 #include <sys/filedesc.h> 36 #include <sys/imgact.h> 37 #include <sys/kernel.h> 38 #include <sys/lock.h> 39 #include <sys/malloc.h> 40 #include <sys/file.h> /* Must come after sys/malloc.h */ 41 #include <sys/mman.h> 42 #include <sys/module.h> 43 #include <sys/mount.h> 44 #include <sys/mutex.h> 45 #include <sys/namei.h> 46 #include <sys/param.h> 47 #include <sys/proc.h> 48 #include <sys/reboot.h> 49 #include <sys/resource.h> 50 #include <sys/resourcevar.h> 51 #include <sys/selinfo.h> 52 #include <sys/pipe.h> /* Must come after sys/selinfo.h */ 53 #include <sys/signal.h> 54 #include <sys/signalvar.h> 55 #include <sys/socket.h> 56 #include <sys/socketvar.h> 57 #include <sys/stat.h> 58 #include <sys/sysctl.h> 59 #include <sys/sysent.h> 60 #include <sys/sysproto.h> 61 #include <sys/systm.h> 62 #include <sys/unistd.h> 63 #include <sys/user.h> 64 #include <sys/utsname.h> 65 #include <sys/vnode.h> 66 67 #include <vm/vm.h> 68 #include <vm/vm_kern.h> 69 #include <vm/vm_param.h> 70 #include <vm/pmap.h> 71 #include <vm/vm_map.h> 72 #include <vm/vm_object.h> 73 #include <vm/vm_extern.h> 74 75 #include <ia64/ia32/ia32_util.h> 76 #include <ia64/ia32/ia32.h> 77 #include <ia64/ia32/ia32_proto.h> 78 79 static const char ia32_emul_path[] = "/compat/ia32"; 80 /* 81 * [ taken from the linux emulator ] 82 * Search an alternate path before passing pathname arguments on 83 * to system calls. Useful for keeping a separate 'emulation tree'. 84 * 85 * If cflag is set, we check if an attempt can be made to create 86 * the named file, i.e. we check if the directory it should 87 * be in exists. 88 */ 89 int 90 ia32_emul_find(td, sgp, prefix, path, pbuf, cflag) 91 struct thread *td; 92 caddr_t *sgp; /* Pointer to stackgap memory */ 93 const char *prefix; 94 char *path; 95 char **pbuf; 96 int cflag; 97 { 98 int error; 99 size_t len, sz; 100 char *buf, *cp, *ptr; 101 struct ucred *ucred; 102 struct nameidata nd; 103 struct nameidata ndroot; 104 struct vattr vat; 105 struct vattr vatroot; 106 107 buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 108 *pbuf = path; 109 110 for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) 111 continue; 112 113 sz = MAXPATHLEN - (ptr - buf); 114 115 /* 116 * If sgp is not given then the path is already in kernel space 117 */ 118 if (sgp == NULL) 119 error = copystr(path, ptr, sz, &len); 120 else 121 error = copyinstr(path, ptr, sz, &len); 122 123 if (error) { 124 free(buf, M_TEMP); 125 return error; 126 } 127 128 if (*ptr != '/') { 129 free(buf, M_TEMP); 130 return EINVAL; 131 } 132 133 /* 134 * We know that there is a / somewhere in this pathname. 135 * Search backwards for it, to find the file's parent dir 136 * to see if it exists in the alternate tree. If it does, 137 * and we want to create a file (cflag is set). We don't 138 * need to worry about the root comparison in this case. 139 */ 140 141 if (cflag) { 142 for (cp = &ptr[len] - 1; *cp != '/'; cp--) 143 ; 144 *cp = '\0'; 145 146 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 147 148 if ((error = namei(&nd)) != 0) { 149 free(buf, M_TEMP); 150 return error; 151 } 152 153 *cp = '/'; 154 } else { 155 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 156 157 if ((error = namei(&nd)) != 0) { 158 free(buf, M_TEMP); 159 return error; 160 } 161 162 /* 163 * We now compare the vnode of the ia32_root to the one 164 * vnode asked. If they resolve to be the same, then we 165 * ignore the match so that the real root gets used. 166 * This avoids the problem of traversing "../.." to find the 167 * root directory and never finding it, because "/" resolves 168 * to the emulation root directory. This is expensive :-( 169 */ 170 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, ia32_emul_path, 171 td); 172 173 if ((error = namei(&ndroot)) != 0) { 174 /* Cannot happen! */ 175 free(buf, M_TEMP); 176 vrele(nd.ni_vp); 177 return error; 178 } 179 180 ucred = td->td_ucred; 181 if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) { 182 goto bad; 183 } 184 185 if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred, 186 td)) != 0) { 187 goto bad; 188 } 189 190 if (vat.va_fsid == vatroot.va_fsid && 191 vat.va_fileid == vatroot.va_fileid) { 192 error = ENOENT; 193 goto bad; 194 } 195 196 } 197 if (sgp == NULL) 198 *pbuf = buf; 199 else { 200 sz = &ptr[len] - buf; 201 *pbuf = stackgap_alloc(sgp, sz + 1); 202 error = copyout(buf, *pbuf, sz); 203 free(buf, M_TEMP); 204 } 205 206 vrele(nd.ni_vp); 207 if (!cflag) 208 vrele(ndroot.ni_vp); 209 210 return error; 211 212 bad: 213 vrele(ndroot.ni_vp); 214 vrele(nd.ni_vp); 215 free(buf, M_TEMP); 216 return error; 217 } 218 219 int 220 ia32_open(struct thread *td, struct ia32_open_args *uap) 221 { 222 caddr_t sg; 223 224 sg = stackgap_init(); 225 CHECKALTEXIST(td, &sg, uap->path); 226 227 return open(td, (struct open_args *) uap); 228 } 229 230 int 231 ia32_wait4(struct thread *td, struct ia32_wait4_args *uap) 232 { 233 int error; 234 caddr_t sg; 235 struct rusage32 *rusage32, ru32; 236 struct rusage *rusage = NULL, ru; 237 238 rusage32 = SCARG(uap, rusage); 239 if (rusage32) { 240 sg = stackgap_init(); 241 rusage = stackgap_alloc(&sg, sizeof(struct rusage)); 242 SCARG(uap, rusage) = (struct rusage32 *)rusage; 243 } 244 error = wait4(td, (struct wait_args *)uap); 245 if (error) 246 return (error); 247 if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { 248 TV_CP(ru, ru32, ru_utime); 249 TV_CP(ru, ru32, ru_stime); 250 CP(ru, ru32, ru_maxrss); 251 CP(ru, ru32, ru_ixrss); 252 CP(ru, ru32, ru_idrss); 253 CP(ru, ru32, ru_isrss); 254 CP(ru, ru32, ru_minflt); 255 CP(ru, ru32, ru_majflt); 256 CP(ru, ru32, ru_nswap); 257 CP(ru, ru32, ru_inblock); 258 CP(ru, ru32, ru_oublock); 259 CP(ru, ru32, ru_msgsnd); 260 CP(ru, ru32, ru_msgrcv); 261 CP(ru, ru32, ru_nsignals); 262 CP(ru, ru32, ru_nvcsw); 263 CP(ru, ru32, ru_nivcsw); 264 error = copyout(&ru32, rusage32, sizeof(ru32)); 265 } 266 return (error); 267 } 268 269 static void 270 copy_statfs(struct statfs *in, struct statfs32 *out) 271 { 272 CP(*in, *out, f_bsize); 273 CP(*in, *out, f_iosize); 274 CP(*in, *out, f_blocks); 275 CP(*in, *out, f_bfree); 276 CP(*in, *out, f_bavail); 277 CP(*in, *out, f_files); 278 CP(*in, *out, f_ffree); 279 CP(*in, *out, f_fsid); 280 CP(*in, *out, f_owner); 281 CP(*in, *out, f_type); 282 CP(*in, *out, f_flags); 283 CP(*in, *out, f_flags); 284 CP(*in, *out, f_syncwrites); 285 CP(*in, *out, f_asyncwrites); 286 bcopy(in->f_fstypename, 287 out->f_fstypename, MFSNAMELEN); 288 bcopy(in->f_mntonname, 289 out->f_mntonname, MNAMELEN); 290 CP(*in, *out, f_syncreads); 291 CP(*in, *out, f_asyncreads); 292 bcopy(in->f_mntfromname, 293 out->f_mntfromname, MNAMELEN); 294 } 295 296 int 297 ia32_getfsstat(struct thread *td, struct ia32_getfsstat_args *uap) 298 { 299 int error; 300 caddr_t sg; 301 struct statfs32 *sp32, stat32; 302 struct statfs *sp = NULL, stat; 303 int maxcount, count, i; 304 305 sp32 = SCARG(uap, buf); 306 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs32); 307 308 if (sp32) { 309 sg = stackgap_init(); 310 sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 311 SCARG(uap, buf) = (struct statfs32 *)sp; 312 } 313 error = getfsstat(td, (struct getfsstat_args *) uap); 314 if (sp32 && !error) { 315 count = td->td_retval[0]; 316 for (i = 0; i < count; i++) { 317 error = copyin(&sp[i], &stat, sizeof(stat)); 318 if (error) 319 return (error); 320 copy_statfs(&stat, &stat32); 321 error = copyout(&stat32, &sp32[i], sizeof(stat32)); 322 if (error) 323 return (error); 324 } 325 } 326 return (error); 327 } 328 329 int 330 ia32_access(struct thread *td, struct ia32_access_args *uap) 331 { 332 caddr_t sg; 333 334 sg = stackgap_init(); 335 CHECKALTEXIST(td, &sg, uap->path); 336 337 return access(td, (struct access_args *)uap); 338 } 339 340 int 341 ia32_chflags(struct thread *td, struct ia32_chflags_args *uap) 342 { 343 caddr_t sg; 344 345 sg = stackgap_init(); 346 CHECKALTEXIST(td, &sg, uap->path); 347 348 return chflags(td, (struct chflags_args *)uap); 349 } 350 351 struct sigaltstack32 { 352 u_int32_t ss_sp; 353 u_int32_t ss_size; 354 int ss_flags; 355 }; 356 357 int 358 ia32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap) 359 { 360 int error; 361 caddr_t sg; 362 struct sigaltstack32 *p32, *op32, s32; 363 struct sigaltstack *p = NULL, *op = NULL, s; 364 365 p32 = SCARG(uap, ss); 366 if (p32) { 367 sg = stackgap_init(); 368 p = stackgap_alloc(&sg, sizeof(struct sigaltstack)); 369 SCARG(uap, ss) = (struct sigaltstack32 *)p; 370 error = copyin(p32, &s32, sizeof(s32)); 371 if (error) 372 return (error); 373 PTRIN_CP(s32, s, ss_sp); 374 CP(s32, s, ss_size); 375 CP(s32, s, ss_flags); 376 error = copyout(&s, p, sizeof(s)); 377 if (error) 378 return (error); 379 } 380 op32 = SCARG(uap, oss); 381 if (op32) { 382 sg = stackgap_init(); 383 op = stackgap_alloc(&sg, sizeof(struct sigaltstack)); 384 SCARG(uap, oss) = (struct sigaltstack32 *)op; 385 } 386 error = sigaltstack(td, (struct sigaltstack_args *) uap); 387 if (error) 388 return (error); 389 if (op32) { 390 error = copyin(op, &s, sizeof(s)); 391 if (error) 392 return (error); 393 PTROUT_CP(s, s32, ss_sp); 394 CP(s, s32, ss_size); 395 CP(s, s32, ss_flags); 396 error = copyout(&s32, op32, sizeof(s32)); 397 } 398 return (error); 399 } 400 401 int 402 ia32_execve(struct thread *td, struct ia32_execve_args *uap) 403 { 404 int error; 405 caddr_t sg; 406 struct execve_args ap; 407 u_int32_t *p32, arg; 408 char **p; 409 int count; 410 411 sg = stackgap_init(); 412 CHECKALTEXIST(td, &sg, SCARG(uap, fname)); 413 SCARG(&ap, fname) = SCARG(uap, fname); 414 415 if (SCARG(uap, argv)) { 416 count = 0; 417 p32 = SCARG(uap, argv); 418 do { 419 error = copyin(p32++, &arg, sizeof(arg)); 420 if (error) 421 return error; 422 count++; 423 } while (arg != 0); 424 p = stackgap_alloc(&sg, count * sizeof(char *)); 425 SCARG(&ap, argv) = p; 426 p32 = SCARG(uap, argv); 427 do { 428 error = copyin(p32++, &arg, sizeof(arg)); 429 if (error) 430 return error; 431 *p++ = PTRIN(arg); 432 } while (arg != 0); 433 } 434 if (SCARG(uap, envv)) { 435 count = 0; 436 p32 = SCARG(uap, envv); 437 do { 438 error = copyin(p32++, &arg, sizeof(arg)); 439 if (error) 440 return error; 441 count++; 442 } while (arg != 0); 443 p = stackgap_alloc(&sg, count * sizeof(char *)); 444 SCARG(&ap, envv) = p; 445 p32 = SCARG(uap, envv); 446 do { 447 error = copyin(p32++, &arg, sizeof(arg)); 448 if (error) 449 return error; 450 *p++ = PTRIN(arg); 451 } while (arg != 0); 452 } 453 454 return execve(td, &ap); 455 } 456 457 static int 458 ia32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 459 int prot, int fd, off_t pos) 460 { 461 vm_map_t map; 462 vm_map_entry_t entry; 463 int rv; 464 465 map = &td->td_proc->p_vmspace->vm_map; 466 if (fd != -1) 467 prot |= VM_PROT_WRITE; 468 469 if (vm_map_lookup_entry(map, start, &entry)) { 470 if ((entry->protection & prot) != prot) { 471 rv = vm_map_protect(map, 472 trunc_page(start), 473 round_page(end), 474 entry->protection | prot, 475 FALSE); 476 if (rv != KERN_SUCCESS) 477 return (EINVAL); 478 } 479 } else { 480 vm_offset_t addr = trunc_page(start); 481 rv = vm_map_find(map, 0, 0, 482 &addr, PAGE_SIZE, FALSE, prot, 483 VM_PROT_ALL, 0); 484 if (rv != KERN_SUCCESS) 485 return (EINVAL); 486 } 487 488 if (fd != -1) { 489 struct pread_args r; 490 SCARG(&r, fd) = fd; 491 SCARG(&r, buf) = (void *) start; 492 SCARG(&r, nbyte) = end - start; 493 SCARG(&r, offset) = pos; 494 return (pread(td, &r)); 495 } else { 496 while (start < end) { 497 subyte((void *) start, 0); 498 start++; 499 } 500 return (0); 501 } 502 } 503 504 int 505 ia32_mmap(struct thread *td, struct ia32_mmap_args *uap) 506 { 507 struct mmap_args ap; 508 vm_offset_t addr = (vm_offset_t) SCARG(uap, addr); 509 vm_size_t len = SCARG(uap, len); 510 int prot = SCARG(uap, prot); 511 int flags = SCARG(uap, flags); 512 int fd = SCARG(uap, fd); 513 off_t pos = (SCARG(uap, poslo) 514 | ((off_t)SCARG(uap, poshi) << 32)); 515 vm_size_t pageoff; 516 int error; 517 518 /* 519 * Attempt to handle page size hassles. 520 */ 521 pageoff = (pos & PAGE_MASK); 522 if (flags & MAP_FIXED) { 523 vm_offset_t start, end; 524 start = addr; 525 end = addr + len; 526 527 if (start != trunc_page(start)) { 528 error = ia32_mmap_partial(td, start, round_page(start), 529 prot, fd, pos); 530 if (fd != -1) 531 pos += round_page(start) - start; 532 start = round_page(start); 533 } 534 if (end != round_page(end)) { 535 vm_offset_t t = trunc_page(end); 536 error = ia32_mmap_partial(td, t, end, 537 prot, fd, 538 pos + t - start); 539 end = trunc_page(end); 540 } 541 if (end > start && fd != -1 && (pos & PAGE_MASK)) { 542 /* 543 * We can't map this region at all. The specified 544 * address doesn't have the same alignment as the file 545 * position. Fake the mapping by simply reading the 546 * entire region into memory. First we need to make 547 * sure the region exists. 548 */ 549 vm_map_t map; 550 struct pread_args r; 551 int rv; 552 553 prot |= VM_PROT_WRITE; 554 map = &td->td_proc->p_vmspace->vm_map; 555 rv = vm_map_remove(map, start, end); 556 if (rv != KERN_SUCCESS) 557 return (EINVAL); 558 rv = vm_map_find(map, 0, 0, 559 &start, end - start, FALSE, 560 prot, VM_PROT_ALL, 0); 561 if (rv != KERN_SUCCESS) 562 return (EINVAL); 563 SCARG(&r, fd) = fd; 564 SCARG(&r, buf) = (void *) start; 565 SCARG(&r, nbyte) = end - start; 566 SCARG(&r, offset) = pos; 567 error = pread(td, &r); 568 if (error) 569 return (error); 570 571 td->td_retval[0] = addr; 572 return (0); 573 } 574 if (end == start) { 575 /* 576 * After dealing with the ragged ends, there 577 * might be none left. 578 */ 579 td->td_retval[0] = addr; 580 return (0); 581 } 582 addr = start; 583 len = end - start; 584 } 585 586 SCARG(&ap, addr) = (void *) addr; 587 SCARG(&ap, len) = len; 588 SCARG(&ap, prot) = prot; 589 SCARG(&ap, flags) = flags; 590 SCARG(&ap, fd) = fd; 591 SCARG(&ap, pos) = pos; 592 593 return (mmap(td, &ap)); 594 } 595 596 struct itimerval32 { 597 struct timeval32 it_interval; 598 struct timeval32 it_value; 599 }; 600 601 int 602 ia32_setitimer(struct thread *td, struct ia32_setitimer_args *uap) 603 { 604 int error; 605 caddr_t sg; 606 struct itimerval32 *p32, *op32, s32; 607 struct itimerval *p = NULL, *op = NULL, s; 608 609 p32 = SCARG(uap, itv); 610 if (p32) { 611 sg = stackgap_init(); 612 p = stackgap_alloc(&sg, sizeof(struct itimerval)); 613 SCARG(uap, itv) = (struct itimerval32 *)p; 614 error = copyin(p32, &s32, sizeof(s32)); 615 if (error) 616 return (error); 617 TV_CP(s32, s, it_interval); 618 TV_CP(s32, s, it_value); 619 error = copyout(&s, p, sizeof(s)); 620 if (error) 621 return (error); 622 } 623 op32 = SCARG(uap, oitv); 624 if (op32) { 625 sg = stackgap_init(); 626 op = stackgap_alloc(&sg, sizeof(struct itimerval)); 627 SCARG(uap, oitv) = (struct itimerval32 *)op; 628 } 629 error = setitimer(td, (struct setitimer_args *) uap); 630 if (error) 631 return (error); 632 if (op32) { 633 error = copyin(op, &s, sizeof(s)); 634 if (error) 635 return (error); 636 TV_CP(s, s32, it_interval); 637 TV_CP(s, s32, it_value); 638 error = copyout(&s32, op32, sizeof(s32)); 639 } 640 return (error); 641 } 642 643 int 644 ia32_select(struct thread *td, struct ia32_select_args *uap) 645 { 646 int error; 647 caddr_t sg; 648 struct timeval32 *p32, s32; 649 struct timeval *p = NULL, s; 650 651 p32 = SCARG(uap, tv); 652 if (p32) { 653 sg = stackgap_init(); 654 p = stackgap_alloc(&sg, sizeof(struct timeval)); 655 SCARG(uap, tv) = (struct timeval32 *)p; 656 error = copyin(p32, &s32, sizeof(s32)); 657 if (error) 658 return (error); 659 CP(s32, s, tv_sec); 660 CP(s32, s, tv_usec); 661 error = copyout(&s, p, sizeof(s)); 662 if (error) 663 return (error); 664 } 665 /* 666 * XXX big-endian needs to convert the fd_sets too. 667 */ 668 return (select(td, (struct select_args *) uap)); 669 } 670 671 int 672 ia32_gettimeofday(struct thread *td, struct ia32_gettimeofday_args *uap) 673 { 674 int error; 675 caddr_t sg; 676 struct timeval32 *p32, s32; 677 struct timeval *p = NULL, s; 678 679 p32 = SCARG(uap, tp); 680 if (p32) { 681 sg = stackgap_init(); 682 p = stackgap_alloc(&sg, sizeof(struct timeval)); 683 SCARG(uap, tp) = (struct timeval32 *)p; 684 } 685 error = gettimeofday(td, (struct gettimeofday_args *) uap); 686 if (error) 687 return (error); 688 if (p32) { 689 error = copyin(p, &s, sizeof(s)); 690 if (error) 691 return (error); 692 CP(s, s32, tv_sec); 693 CP(s, s32, tv_usec); 694 error = copyout(&s32, p32, sizeof(s32)); 695 if (error) 696 return (error); 697 } 698 return (error); 699 } 700 701 int 702 ia32_getrusage(struct thread *td, struct ia32_getrusage_args *uap) 703 { 704 int error; 705 caddr_t sg; 706 struct rusage32 *p32, s32; 707 struct rusage *p = NULL, s; 708 709 p32 = SCARG(uap, rusage); 710 if (p32) { 711 sg = stackgap_init(); 712 p = stackgap_alloc(&sg, sizeof(struct rusage)); 713 SCARG(uap, rusage) = (struct rusage32 *)p; 714 } 715 error = getrusage(td, (struct getrusage_args *) uap); 716 if (error) 717 return (error); 718 if (p32) { 719 error = copyin(p, &s, sizeof(s)); 720 if (error) 721 return (error); 722 TV_CP(s, s32, ru_utime); 723 TV_CP(s, s32, ru_stime); 724 CP(s, s32, ru_maxrss); 725 CP(s, s32, ru_ixrss); 726 CP(s, s32, ru_idrss); 727 CP(s, s32, ru_isrss); 728 CP(s, s32, ru_minflt); 729 CP(s, s32, ru_majflt); 730 CP(s, s32, ru_nswap); 731 CP(s, s32, ru_inblock); 732 CP(s, s32, ru_oublock); 733 CP(s, s32, ru_msgsnd); 734 CP(s, s32, ru_msgrcv); 735 CP(s, s32, ru_nsignals); 736 CP(s, s32, ru_nvcsw); 737 CP(s, s32, ru_nivcsw); 738 error = copyout(&s32, p32, sizeof(s32)); 739 } 740 return (error); 741 } 742 743 struct iovec32 { 744 u_int32_t iov_base; 745 int iov_len; 746 }; 747 #define STACKGAPLEN 400 748 749 int 750 ia32_readv(struct thread *td, struct ia32_readv_args *uap) 751 { 752 int error, osize, nsize, i; 753 caddr_t sg; 754 struct readv_args /* { 755 syscallarg(int) fd; 756 syscallarg(struct iovec *) iovp; 757 syscallarg(u_int) iovcnt; 758 } */ a; 759 struct iovec32 *oio; 760 struct iovec *nio; 761 762 sg = stackgap_init(); 763 764 if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec))) 765 return (EINVAL); 766 767 osize = SCARG(uap, iovcnt) * sizeof (struct iovec32); 768 nsize = SCARG(uap, iovcnt) * sizeof (struct iovec); 769 770 oio = malloc(osize, M_TEMP, M_WAITOK); 771 nio = malloc(nsize, M_TEMP, M_WAITOK); 772 773 error = 0; 774 if ((error = copyin(SCARG(uap, iovp), oio, osize))) 775 goto punt; 776 for (i = 0; i < SCARG(uap, iovcnt); i++) { 777 nio[i].iov_base = PTRIN(oio[i].iov_base); 778 nio[i].iov_len = oio[i].iov_len; 779 } 780 781 SCARG(&a, fd) = SCARG(uap, fd); 782 SCARG(&a, iovp) = stackgap_alloc(&sg, nsize); 783 SCARG(&a, iovcnt) = SCARG(uap, iovcnt); 784 785 if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize))) 786 goto punt; 787 error = readv(td, &a); 788 789 punt: 790 free(oio, M_TEMP); 791 free(nio, M_TEMP); 792 return (error); 793 } 794 795 int 796 ia32_writev(struct thread *td, struct ia32_writev_args *uap) 797 { 798 int error, i, nsize, osize; 799 caddr_t sg; 800 struct writev_args /* { 801 syscallarg(int) fd; 802 syscallarg(struct iovec *) iovp; 803 syscallarg(u_int) iovcnt; 804 } */ a; 805 struct iovec32 *oio; 806 struct iovec *nio; 807 808 sg = stackgap_init(); 809 810 if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec))) 811 return (EINVAL); 812 813 osize = SCARG(uap, iovcnt) * sizeof (struct iovec32); 814 nsize = SCARG(uap, iovcnt) * sizeof (struct iovec); 815 816 oio = malloc(osize, M_TEMP, M_WAITOK); 817 nio = malloc(nsize, M_TEMP, M_WAITOK); 818 819 error = 0; 820 if ((error = copyin(SCARG(uap, iovp), oio, osize))) 821 goto punt; 822 for (i = 0; i < SCARG(uap, iovcnt); i++) { 823 nio[i].iov_base = PTRIN(oio[i].iov_base); 824 nio[i].iov_len = oio[i].iov_len; 825 } 826 827 SCARG(&a, fd) = SCARG(uap, fd); 828 SCARG(&a, iovp) = stackgap_alloc(&sg, nsize); 829 SCARG(&a, iovcnt) = SCARG(uap, iovcnt); 830 831 if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize))) 832 goto punt; 833 error = writev(td, &a); 834 835 punt: 836 free(oio, M_TEMP); 837 free(nio, M_TEMP); 838 return (error); 839 } 840 841 int 842 ia32_settimeofday(struct thread *td, struct ia32_settimeofday_args *uap) 843 { 844 int error; 845 caddr_t sg; 846 struct timeval32 *p32, s32; 847 struct timeval *p = NULL, s; 848 849 p32 = SCARG(uap, tv); 850 if (p32) { 851 sg = stackgap_init(); 852 p = stackgap_alloc(&sg, sizeof(struct timeval)); 853 SCARG(uap, tv) = (struct timeval32 *)p; 854 error = copyin(p32, &s32, sizeof(s32)); 855 if (error) 856 return (error); 857 CP(s32, s, tv_sec); 858 CP(s32, s, tv_usec); 859 error = copyout(&s, p, sizeof(s)); 860 if (error) 861 return (error); 862 } 863 return (settimeofday(td, (struct settimeofday_args *) uap)); 864 } 865 866 int 867 ia32_utimes(struct thread *td, struct ia32_utimes_args *uap) 868 { 869 int error; 870 caddr_t sg; 871 struct timeval32 *p32, s32[2]; 872 struct timeval *p = NULL, s[2]; 873 874 p32 = SCARG(uap, tptr); 875 if (p32) { 876 sg = stackgap_init(); 877 p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 878 SCARG(uap, tptr) = (struct timeval32 *)p; 879 error = copyin(p32, s32, sizeof(s32)); 880 if (error) 881 return (error); 882 CP(s32[0], s[0], tv_sec); 883 CP(s32[0], s[0], tv_usec); 884 CP(s32[1], s[1], tv_sec); 885 CP(s32[1], s[1], tv_usec); 886 error = copyout(s, p, sizeof(s)); 887 if (error) 888 return (error); 889 } 890 return (utimes(td, (struct utimes_args *) uap)); 891 } 892 893 int 894 ia32_adjtime(struct thread *td, struct ia32_adjtime_args *uap) 895 { 896 int error; 897 caddr_t sg; 898 struct timeval32 *p32, *op32, s32; 899 struct timeval *p = NULL, *op = NULL, s; 900 901 p32 = SCARG(uap, delta); 902 if (p32) { 903 sg = stackgap_init(); 904 p = stackgap_alloc(&sg, sizeof(struct timeval)); 905 SCARG(uap, delta) = (struct timeval32 *)p; 906 error = copyin(p32, &s32, sizeof(s32)); 907 if (error) 908 return (error); 909 CP(s32, s, tv_sec); 910 CP(s32, s, tv_usec); 911 error = copyout(&s, p, sizeof(s)); 912 if (error) 913 return (error); 914 } 915 op32 = SCARG(uap, olddelta); 916 if (op32) { 917 sg = stackgap_init(); 918 op = stackgap_alloc(&sg, sizeof(struct timeval)); 919 SCARG(uap, olddelta) = (struct timeval32 *)op; 920 } 921 error = utimes(td, (struct utimes_args *) uap); 922 if (error) 923 return error; 924 if (op32) { 925 error = copyin(op, &s, sizeof(s)); 926 if (error) 927 return (error); 928 CP(s, s32, tv_sec); 929 CP(s, s32, tv_usec); 930 error = copyout(&s32, op32, sizeof(s32)); 931 } 932 return (error); 933 } 934 935 int 936 ia32_statfs(struct thread *td, struct ia32_statfs_args *uap) 937 { 938 int error; 939 caddr_t sg; 940 struct statfs32 *p32, s32; 941 struct statfs *p = NULL, s; 942 943 p32 = SCARG(uap, buf); 944 if (p32) { 945 sg = stackgap_init(); 946 p = stackgap_alloc(&sg, sizeof(struct statfs)); 947 SCARG(uap, buf) = (struct statfs32 *)p; 948 } 949 error = statfs(td, (struct statfs_args *) uap); 950 if (error) 951 return (error); 952 if (p32) { 953 error = copyin(p, &s, sizeof(s)); 954 if (error) 955 return (error); 956 copy_statfs(&s, &s32); 957 error = copyout(&s32, p32, sizeof(s32)); 958 } 959 return (error); 960 } 961 962 int 963 ia32_fstatfs(struct thread *td, struct ia32_fstatfs_args *uap) 964 { 965 int error; 966 caddr_t sg; 967 struct statfs32 *p32, s32; 968 struct statfs *p = NULL, s; 969 970 p32 = SCARG(uap, buf); 971 if (p32) { 972 sg = stackgap_init(); 973 p = stackgap_alloc(&sg, sizeof(struct statfs)); 974 SCARG(uap, buf) = (struct statfs32 *)p; 975 } 976 error = fstatfs(td, (struct fstatfs_args *) uap); 977 if (error) 978 return (error); 979 if (p32) { 980 error = copyin(p, &s, sizeof(s)); 981 if (error) 982 return (error); 983 copy_statfs(&s, &s32); 984 error = copyout(&s32, p32, sizeof(s32)); 985 } 986 return (error); 987 } 988 989 int 990 ia32_semsys(struct thread *td, struct ia32_semsys_args *uap) 991 { 992 /* 993 * Vector through to semsys if it is loaded. 994 */ 995 return sysent[169].sy_call(td, uap); 996 } 997 998 int 999 ia32_msgsys(struct thread *td, struct ia32_msgsys_args *uap) 1000 { 1001 /* 1002 * Vector through to msgsys if it is loaded. 1003 */ 1004 return sysent[170].sy_call(td, uap); 1005 } 1006 1007 int 1008 ia32_shmsys(struct thread *td, struct ia32_shmsys_args *uap) 1009 { 1010 /* 1011 * Vector through to shmsys if it is loaded. 1012 */ 1013 return sysent[171].sy_call(td, uap); 1014 } 1015 1016 int 1017 ia32_pread(struct thread *td, struct ia32_pread_args *uap) 1018 { 1019 struct pread_args ap; 1020 1021 SCARG(&ap, fd) = SCARG(uap, fd); 1022 SCARG(&ap, buf) = SCARG(uap, buf); 1023 SCARG(&ap, nbyte) = SCARG(uap, nbyte); 1024 SCARG(&ap, offset) = (SCARG(uap, offsetlo) 1025 | ((off_t)SCARG(uap, offsethi) << 32)); 1026 return (pread(td, &ap)); 1027 } 1028 1029 int 1030 ia32_pwrite(struct thread *td, struct ia32_pwrite_args *uap) 1031 { 1032 struct pwrite_args ap; 1033 1034 SCARG(&ap, fd) = SCARG(uap, fd); 1035 SCARG(&ap, buf) = SCARG(uap, buf); 1036 SCARG(&ap, nbyte) = SCARG(uap, nbyte); 1037 SCARG(&ap, offset) = (SCARG(uap, offsetlo) 1038 | ((off_t)SCARG(uap, offsethi) << 32)); 1039 return (pwrite(td, &ap)); 1040 } 1041 1042 int 1043 ia32_lseek(struct thread *td, struct ia32_lseek_args *uap) 1044 { 1045 int error; 1046 struct lseek_args ap; 1047 off_t pos; 1048 1049 SCARG(&ap, fd) = SCARG(uap, fd); 1050 SCARG(&ap, offset) = (SCARG(uap, offsetlo) 1051 | ((off_t)SCARG(uap, offsethi) << 32)); 1052 SCARG(&ap, whence) = SCARG(uap, whence); 1053 error = lseek(td, &ap); 1054 /* Expand the quad return into two parts for eax and edx */ 1055 pos = *(off_t *)(td->td_retval); 1056 td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1057 td->td_retval[1] = pos >> 32; /* %edx */ 1058 return error; 1059 } 1060 1061 int 1062 ia32_truncate(struct thread *td, struct ia32_truncate_args *uap) 1063 { 1064 struct truncate_args ap; 1065 1066 SCARG(&ap, path) = SCARG(uap, path); 1067 SCARG(&ap, length) = (SCARG(uap, lengthlo) 1068 | ((off_t)SCARG(uap, lengthhi) << 32)); 1069 return (truncate(td, &ap)); 1070 } 1071 1072 int 1073 ia32_ftruncate(struct thread *td, struct ia32_ftruncate_args *uap) 1074 { 1075 struct ftruncate_args ap; 1076 1077 SCARG(&ap, fd) = SCARG(uap, fd); 1078 SCARG(&ap, length) = (SCARG(uap, lengthlo) 1079 | ((off_t)SCARG(uap, lengthhi) << 32)); 1080 return (ftruncate(td, &ap)); 1081 } 1082 1083 int 1084 ia32_sendfile(struct thread *td, struct ia32_sendfile_args *uap) 1085 { 1086 struct sendfile_args ap; 1087 1088 SCARG(&ap, fd) = SCARG(uap, fd); 1089 SCARG(&ap, s) = SCARG(uap, s); 1090 SCARG(&ap, offset) = (SCARG(uap, offsetlo) 1091 | ((off_t)SCARG(uap, offsethi) << 32)); 1092 SCARG(&ap, nbytes) = SCARG(uap, nbytes); /* XXX check */ 1093 SCARG(&ap, hdtr) = SCARG(uap, hdtr); /* XXX check */ 1094 SCARG(&ap, sbytes) = SCARG(uap, sbytes); /* XXX FIXME!! */ 1095 SCARG(&ap, flags) = SCARG(uap, flags); 1096 return (sendfile(td, &ap)); 1097 } 1098 1099 struct stat32 { 1100 udev_t st_dev; 1101 ino_t st_ino; 1102 mode_t st_mode; 1103 nlink_t st_nlink; 1104 uid_t st_uid; 1105 gid_t st_gid; 1106 udev_t st_rdev; 1107 struct timespec32 st_atimespec; 1108 struct timespec32 st_mtimespec; 1109 struct timespec32 st_ctimespec; 1110 off_t st_size; 1111 int64_t st_blocks; 1112 u_int32_t st_blksize; 1113 u_int32_t st_flags; 1114 u_int32_t st_gen; 1115 }; 1116 1117 static void 1118 copy_stat( struct stat *in, struct stat32 *out) 1119 { 1120 CP(*in, *out, st_dev); 1121 CP(*in, *out, st_ino); 1122 CP(*in, *out, st_mode); 1123 CP(*in, *out, st_nlink); 1124 CP(*in, *out, st_uid); 1125 CP(*in, *out, st_gid); 1126 CP(*in, *out, st_rdev); 1127 TS_CP(*in, *out, st_atimespec); 1128 TS_CP(*in, *out, st_mtimespec); 1129 TS_CP(*in, *out, st_ctimespec); 1130 CP(*in, *out, st_size); 1131 CP(*in, *out, st_blocks); 1132 CP(*in, *out, st_blksize); 1133 CP(*in, *out, st_flags); 1134 CP(*in, *out, st_gen); 1135 } 1136 1137 int 1138 ia32_stat(struct thread *td, struct ia32_stat_args *uap) 1139 { 1140 int error; 1141 caddr_t sg; 1142 struct stat32 *p32, s32; 1143 struct stat *p = NULL, s; 1144 1145 p32 = SCARG(uap, ub); 1146 if (p32) { 1147 sg = stackgap_init(); 1148 p = stackgap_alloc(&sg, sizeof(struct stat)); 1149 SCARG(uap, ub) = (struct stat32 *)p; 1150 } 1151 error = stat(td, (struct stat_args *) uap); 1152 if (error) 1153 return (error); 1154 if (p32) { 1155 error = copyin(p, &s, sizeof(s)); 1156 if (error) 1157 return (error); 1158 copy_stat(&s, &s32); 1159 error = copyout(&s32, p32, sizeof(s32)); 1160 } 1161 return (error); 1162 } 1163 1164 int 1165 ia32_fstat(struct thread *td, struct ia32_fstat_args *uap) 1166 { 1167 int error; 1168 caddr_t sg; 1169 struct stat32 *p32, s32; 1170 struct stat *p = NULL, s; 1171 1172 p32 = SCARG(uap, ub); 1173 if (p32) { 1174 sg = stackgap_init(); 1175 p = stackgap_alloc(&sg, sizeof(struct stat)); 1176 SCARG(uap, ub) = (struct stat32 *)p; 1177 } 1178 error = fstat(td, (struct fstat_args *) uap); 1179 if (error) 1180 return (error); 1181 if (p32) { 1182 error = copyin(p, &s, sizeof(s)); 1183 if (error) 1184 return (error); 1185 copy_stat(&s, &s32); 1186 error = copyout(&s32, p32, sizeof(s32)); 1187 } 1188 return (error); 1189 } 1190 1191 int 1192 ia32_lstat(struct thread *td, struct ia32_lstat_args *uap) 1193 { 1194 int error; 1195 caddr_t sg; 1196 struct stat32 *p32, s32; 1197 struct stat *p = NULL, s; 1198 1199 p32 = SCARG(uap, ub); 1200 if (p32) { 1201 sg = stackgap_init(); 1202 p = stackgap_alloc(&sg, sizeof(struct stat)); 1203 SCARG(uap, ub) = (struct stat32 *)p; 1204 } 1205 error = lstat(td, (struct lstat_args *) uap); 1206 if (error) 1207 return (error); 1208 if (p32) { 1209 error = copyin(p, &s, sizeof(s)); 1210 if (error) 1211 return (error); 1212 copy_stat(&s, &s32); 1213 error = copyout(&s32, p32, sizeof(s32)); 1214 } 1215 return (error); 1216 } 1217 1218 /* 1219 * MPSAFE 1220 */ 1221 int 1222 ia32_sysctl(struct thread *td, struct ia32_sysctl_args *uap) 1223 { 1224 int error, name[CTL_MAXNAME]; 1225 size_t j, oldlen; 1226 1227 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1228 return (EINVAL); 1229 1230 error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1231 if (error) 1232 return (error); 1233 1234 mtx_lock(&Giant); 1235 1236 if (uap->oldlenp) 1237 oldlen = fuword32(uap->oldlenp); 1238 else 1239 oldlen = 0; 1240 error = userland_sysctl(td, name, uap->namelen, 1241 uap->old, &oldlen, 1, 1242 uap->new, uap->newlen, &j); 1243 if (error && error != ENOMEM) 1244 goto done2; 1245 if (uap->oldlenp) { 1246 suword32(uap->oldlenp, j); 1247 } 1248 done2: 1249 mtx_unlock(&Giant); 1250 return (error); 1251 } 1252 1253 struct sigaction32 { 1254 u_int32_t sa_u; 1255 int sa_flags; 1256 sigset_t sa_mask; 1257 }; 1258 1259 int 1260 ia32_sigaction(struct thread *td, struct ia32_sigaction_args *uap) 1261 { 1262 int error; 1263 caddr_t sg; 1264 struct sigaction32 *p32, *op32, s32; 1265 struct sigaction *p = NULL, *op = NULL, s; 1266 1267 p32 = SCARG(uap, act); 1268 if (p32) { 1269 sg = stackgap_init(); 1270 p = stackgap_alloc(&sg, sizeof(struct sigaction)); 1271 SCARG(uap, act) = (struct sigaction32 *)p; 1272 error = copyin(p32, &s32, sizeof(s32)); 1273 if (error) 1274 return (error); 1275 s.sa_handler = PTRIN(s32.sa_u); 1276 CP(s32, s, sa_flags); 1277 CP(s32, s, sa_mask); 1278 error = copyout(&s, p, sizeof(s)); 1279 if (error) 1280 return (error); 1281 } 1282 op32 = SCARG(uap, oact); 1283 if (op32) { 1284 sg = stackgap_init(); 1285 op = stackgap_alloc(&sg, sizeof(struct sigaction)); 1286 SCARG(uap, oact) = (struct sigaction32 *)op; 1287 } 1288 error = sigaction(td, (struct sigaction_args *) uap); 1289 if (error) 1290 return (error); 1291 if (op32) { 1292 error = copyin(op, &s, sizeof(s)); 1293 if (error) 1294 return (error); 1295 s32.sa_u = PTROUT(s.sa_handler); 1296 CP(s, s32, sa_flags); 1297 CP(s, s32, sa_mask); 1298 error = copyout(&s32, op32, sizeof(s32)); 1299 } 1300 return (error); 1301 } 1302 1303 #if 0 1304 1305 int 1306 ia32_xxx(struct thread *td, struct ia32_xxx_args *uap) 1307 { 1308 int error; 1309 caddr_t sg; 1310 struct yyy32 *p32, s32; 1311 struct yyy *p = NULL, s; 1312 1313 p32 = SCARG(uap, zzz); 1314 if (p32) { 1315 sg = stackgap_init(); 1316 p = stackgap_alloc(&sg, sizeof(struct yyy)); 1317 SCARG(uap, zzz) = (struct yyy32 *)p; 1318 error = copyin(p32, &s32, sizeof(s32)); 1319 if (error) 1320 return (error); 1321 /* translate in */ 1322 error = copyout(&s, p, sizeof(s)); 1323 if (error) 1324 return (error); 1325 } 1326 error = xxx(td, (struct xxx_args *) uap); 1327 if (error) 1328 return (error); 1329 if (p32) { 1330 error = copyin(p, &s, sizeof(s)); 1331 if (error) 1332 return (error); 1333 /* translate out */ 1334 error = copyout(&s32, p32, sizeof(s32)); 1335 } 1336 return (error); 1337 } 1338 1339 #endif 1340