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