62#include <sys/syscallsubr.h> 63#include <sys/sysctl.h> 64#include <sys/sysent.h> 65#include <sys/sysproto.h> 66#include <sys/systm.h> 67#include <sys/unistd.h> 68#include <sys/vnode.h> 69#include <sys/wait.h> 70 71#include <vm/vm.h> 72#include <vm/vm_kern.h> 73#include <vm/vm_param.h> 74#include <vm/pmap.h> 75#include <vm/vm_map.h> 76#include <vm/vm_object.h> 77#include <vm/vm_extern.h> 78 79#include <compat/freebsd32/freebsd32_util.h> 80#include <compat/freebsd32/freebsd32.h> 81#include <compat/freebsd32/freebsd32_proto.h> 82 83CTASSERT(sizeof(struct timeval32) == 8); 84CTASSERT(sizeof(struct timespec32) == 8); 85CTASSERT(sizeof(struct statfs32) == 256); 86CTASSERT(sizeof(struct rusage32) == 72); 87 88int 89freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 90{ 91 int error, status; 92 struct rusage32 ru32; 93 struct rusage ru, *rup; 94 95 if (uap->rusage != NULL) 96 rup = &ru; 97 else 98 rup = NULL; 99 error = kern_wait(td, uap->pid, &status, uap->options, rup); 100 if (error) 101 return (error); 102 if (uap->status != NULL) 103 error = copyout(&status, uap->status, sizeof(status)); 104 if (uap->rusage != NULL && error == 0) { 105 TV_CP(ru, ru32, ru_utime); 106 TV_CP(ru, ru32, ru_stime); 107 CP(ru, ru32, ru_maxrss); 108 CP(ru, ru32, ru_ixrss); 109 CP(ru, ru32, ru_idrss); 110 CP(ru, ru32, ru_isrss); 111 CP(ru, ru32, ru_minflt); 112 CP(ru, ru32, ru_majflt); 113 CP(ru, ru32, ru_nswap); 114 CP(ru, ru32, ru_inblock); 115 CP(ru, ru32, ru_oublock); 116 CP(ru, ru32, ru_msgsnd); 117 CP(ru, ru32, ru_msgrcv); 118 CP(ru, ru32, ru_nsignals); 119 CP(ru, ru32, ru_nvcsw); 120 CP(ru, ru32, ru_nivcsw); 121 error = copyout(&ru32, uap->rusage, sizeof(ru32)); 122 } 123 return (error); 124} 125 126#ifdef COMPAT_FREEBSD4 127static void 128copy_statfs(struct statfs *in, struct statfs32 *out) 129{ 130 CP(*in, *out, f_bsize); 131 CP(*in, *out, f_iosize); 132 CP(*in, *out, f_blocks); 133 CP(*in, *out, f_bfree); 134 CP(*in, *out, f_bavail); 135 CP(*in, *out, f_files); 136 CP(*in, *out, f_ffree); 137 CP(*in, *out, f_fsid); 138 CP(*in, *out, f_owner); 139 CP(*in, *out, f_type); 140 CP(*in, *out, f_flags); 141 CP(*in, *out, f_flags); 142 CP(*in, *out, f_syncwrites); 143 CP(*in, *out, f_asyncwrites); 144 bcopy(in->f_fstypename, 145 out->f_fstypename, MFSNAMELEN); 146 bcopy(in->f_mntonname, 147 out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 148 CP(*in, *out, f_syncreads); 149 CP(*in, *out, f_asyncreads); 150 bcopy(in->f_mntfromname, 151 out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 152} 153#endif 154 155#ifdef COMPAT_FREEBSD4 156int 157freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 158{ 159 struct statfs *buf, *sp; 160 struct statfs32 stat32; 161 size_t count, size; 162 int error; 163 164 count = uap->bufsize / sizeof(struct statfs32); 165 size = count * sizeof(struct statfs); 166 error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 167 if (size > 0) { 168 count = td->td_retval[0]; 169 sp = buf; 170 while (count > 0 && error == 0) { 171 copy_statfs(sp, &stat32); 172 error = copyout(&stat32, uap->buf, sizeof(stat32)); 173 sp++; 174 uap->buf++; 175 count--; 176 } 177 free(buf, M_TEMP); 178 } 179 return (error); 180} 181#endif 182 183struct sigaltstack32 { 184 u_int32_t ss_sp; 185 u_int32_t ss_size; 186 int ss_flags; 187}; 188 189CTASSERT(sizeof(struct sigaltstack32) == 12); 190 191int 192freebsd32_sigaltstack(struct thread *td, 193 struct freebsd32_sigaltstack_args *uap) 194{ 195 struct sigaltstack32 s32; 196 struct sigaltstack ss, oss, *ssp; 197 int error; 198 199 if (uap->ss != NULL) { 200 error = copyin(uap->ss, &s32, sizeof(s32)); 201 if (error) 202 return (error); 203 PTRIN_CP(s32, ss, ss_sp); 204 CP(s32, ss, ss_size); 205 CP(s32, ss, ss_flags); 206 ssp = &ss; 207 } else 208 ssp = NULL; 209 error = kern_sigaltstack(td, ssp, &oss); 210 if (error == 0 && uap->oss != NULL) { 211 PTROUT_CP(oss, s32, ss_sp); 212 CP(oss, s32, ss_size); 213 CP(oss, s32, ss_flags); 214 error = copyout(&s32, uap->oss, sizeof(s32)); 215 } 216 return (error); 217} 218 219/* 220 * Custom version of exec_copyin_args() so that we can translate 221 * the pointers. 222 */ 223static int 224freebsd32_exec_copyin_args(struct image_args *args, char *fname, 225 enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 226{ 227 char *argp, *envp; 228 u_int32_t *p32, arg; 229 size_t length; 230 int error; 231 232 bzero(args, sizeof(*args)); 233 if (argv == NULL) 234 return (EFAULT); 235 236 /* 237 * Allocate temporary demand zeroed space for argument and 238 * environment strings 239 */ 240 args->buf = (char *) kmem_alloc_wait(exec_map, 241 PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 242 if (args->buf == NULL) 243 return (ENOMEM); 244 args->begin_argv = args->buf; 245 args->endp = args->begin_argv; 246 args->stringspace = ARG_MAX; 247 248 args->fname = args->buf + ARG_MAX; 249 250 /* 251 * Copy the file name. 252 */ 253 error = (segflg == UIO_SYSSPACE) ? 254 copystr(fname, args->fname, PATH_MAX, &length) : 255 copyinstr(fname, args->fname, PATH_MAX, &length); 256 if (error != 0) 257 return (error); 258 259 /* 260 * extract arguments first 261 */ 262 p32 = argv; 263 for (;;) { 264 error = copyin(p32++, &arg, sizeof(arg)); 265 if (error) 266 return (error); 267 if (arg == 0) 268 break; 269 argp = PTRIN(arg); 270 error = copyinstr(argp, args->endp, args->stringspace, &length); 271 if (error) { 272 if (error == ENAMETOOLONG) 273 return (E2BIG); 274 else 275 return (error); 276 } 277 args->stringspace -= length; 278 args->endp += length; 279 args->argc++; 280 } 281 282 args->begin_envv = args->endp; 283 284 /* 285 * extract environment strings 286 */ 287 if (envv) { 288 p32 = envv; 289 for (;;) { 290 error = copyin(p32++, &arg, sizeof(arg)); 291 if (error) 292 return (error); 293 if (arg == 0) 294 break; 295 envp = PTRIN(arg); 296 error = copyinstr(envp, args->endp, args->stringspace, 297 &length); 298 if (error) { 299 if (error == ENAMETOOLONG) 300 return (E2BIG); 301 else 302 return (error); 303 } 304 args->stringspace -= length; 305 args->endp += length; 306 args->envc++; 307 } 308 } 309 310 return (0); 311} 312 313int 314freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 315{ 316 struct image_args eargs; 317 int error; 318 319 error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 320 uap->argv, uap->envv); 321 if (error == 0) 322 error = kern_execve(td, &eargs, NULL); 323 exec_free_args(&eargs); 324 return (error); 325} 326 327#ifdef __ia64__ 328static int 329freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 330 int prot, int fd, off_t pos) 331{ 332 vm_map_t map; 333 vm_map_entry_t entry; 334 int rv; 335 336 map = &td->td_proc->p_vmspace->vm_map; 337 if (fd != -1) 338 prot |= VM_PROT_WRITE; 339 340 if (vm_map_lookup_entry(map, start, &entry)) { 341 if ((entry->protection & prot) != prot) { 342 rv = vm_map_protect(map, 343 trunc_page(start), 344 round_page(end), 345 entry->protection | prot, 346 FALSE); 347 if (rv != KERN_SUCCESS) 348 return (EINVAL); 349 } 350 } else { 351 vm_offset_t addr = trunc_page(start); 352 rv = vm_map_find(map, 0, 0, 353 &addr, PAGE_SIZE, FALSE, prot, 354 VM_PROT_ALL, 0); 355 if (rv != KERN_SUCCESS) 356 return (EINVAL); 357 } 358 359 if (fd != -1) { 360 struct pread_args r; 361 r.fd = fd; 362 r.buf = (void *) start; 363 r.nbyte = end - start; 364 r.offset = pos; 365 return (pread(td, &r)); 366 } else { 367 while (start < end) { 368 subyte((void *) start, 0); 369 start++; 370 } 371 return (0); 372 } 373} 374#endif 375 376int 377freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 378{ 379 struct mmap_args ap; 380 vm_offset_t addr = (vm_offset_t) uap->addr; 381 vm_size_t len = uap->len; 382 int prot = uap->prot; 383 int flags = uap->flags; 384 int fd = uap->fd; 385 off_t pos = (uap->poslo 386 | ((off_t)uap->poshi << 32)); 387#ifdef __ia64__ 388 vm_size_t pageoff; 389 int error; 390 391 /* 392 * Attempt to handle page size hassles. 393 */ 394 pageoff = (pos & PAGE_MASK); 395 if (flags & MAP_FIXED) { 396 vm_offset_t start, end; 397 start = addr; 398 end = addr + len; 399 400 mtx_lock(&Giant); 401 if (start != trunc_page(start)) { 402 error = freebsd32_mmap_partial(td, start, 403 round_page(start), prot, 404 fd, pos); 405 if (fd != -1) 406 pos += round_page(start) - start; 407 start = round_page(start); 408 } 409 if (end != round_page(end)) { 410 vm_offset_t t = trunc_page(end); 411 error = freebsd32_mmap_partial(td, t, end, 412 prot, fd, 413 pos + t - start); 414 end = trunc_page(end); 415 } 416 if (end > start && fd != -1 && (pos & PAGE_MASK)) { 417 /* 418 * We can't map this region at all. The specified 419 * address doesn't have the same alignment as the file 420 * position. Fake the mapping by simply reading the 421 * entire region into memory. First we need to make 422 * sure the region exists. 423 */ 424 vm_map_t map; 425 struct pread_args r; 426 int rv; 427 428 prot |= VM_PROT_WRITE; 429 map = &td->td_proc->p_vmspace->vm_map; 430 rv = vm_map_remove(map, start, end); 431 if (rv != KERN_SUCCESS) { 432 mtx_unlock(&Giant); 433 return (EINVAL); 434 } 435 rv = vm_map_find(map, 0, 0, 436 &start, end - start, FALSE, 437 prot, VM_PROT_ALL, 0); 438 mtx_unlock(&Giant); 439 if (rv != KERN_SUCCESS) 440 return (EINVAL); 441 r.fd = fd; 442 r.buf = (void *) start; 443 r.nbyte = end - start; 444 r.offset = pos; 445 error = pread(td, &r); 446 if (error) 447 return (error); 448 449 td->td_retval[0] = addr; 450 return (0); 451 } 452 mtx_unlock(&Giant); 453 if (end == start) { 454 /* 455 * After dealing with the ragged ends, there 456 * might be none left. 457 */ 458 td->td_retval[0] = addr; 459 return (0); 460 } 461 addr = start; 462 len = end - start; 463 } 464#endif 465 466 ap.addr = (void *) addr; 467 ap.len = len; 468 ap.prot = prot; 469 ap.flags = flags; 470 ap.fd = fd; 471 ap.pos = pos; 472 473 return (mmap(td, &ap)); 474} 475 476struct itimerval32 { 477 struct timeval32 it_interval; 478 struct timeval32 it_value; 479}; 480 481CTASSERT(sizeof(struct itimerval32) == 16); 482 483int 484freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 485{ 486 struct itimerval itv, oitv, *itvp; 487 struct itimerval32 i32; 488 int error; 489 490 if (uap->itv != NULL) { 491 error = copyin(uap->itv, &i32, sizeof(i32)); 492 if (error) 493 return (error); 494 TV_CP(i32, itv, it_interval); 495 TV_CP(i32, itv, it_value); 496 itvp = &itv; 497 } else 498 itvp = NULL; 499 error = kern_setitimer(td, uap->which, itvp, &oitv); 500 if (error || uap->oitv == NULL) 501 return (error); 502 TV_CP(oitv, i32, it_interval); 503 TV_CP(oitv, i32, it_value); 504 return (copyout(&i32, uap->oitv, sizeof(i32))); 505} 506 507int 508freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 509{ 510 struct itimerval itv; 511 struct itimerval32 i32; 512 int error; 513 514 error = kern_getitimer(td, uap->which, &itv); 515 if (error || uap->itv == NULL) 516 return (error); 517 TV_CP(itv, i32, it_interval); 518 TV_CP(itv, i32, it_value); 519 return (copyout(&i32, uap->itv, sizeof(i32))); 520} 521 522int 523freebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 524{ 525 struct timeval32 tv32; 526 struct timeval tv, *tvp; 527 int error; 528 529 if (uap->tv != NULL) { 530 error = copyin(uap->tv, &tv32, sizeof(tv32)); 531 if (error) 532 return (error); 533 CP(tv32, tv, tv_sec); 534 CP(tv32, tv, tv_usec); 535 tvp = &tv; 536 } else 537 tvp = NULL; 538 /* 539 * XXX big-endian needs to convert the fd_sets too. 540 * XXX Do pointers need PTRIN()? 541 */ 542 return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 543} 544 545struct kevent32 { 546 u_int32_t ident; /* identifier for this event */ 547 short filter; /* filter for event */ 548 u_short flags; 549 u_int fflags; 550 int32_t data; 551 u_int32_t udata; /* opaque user data identifier */ 552}; 553 554CTASSERT(sizeof(struct kevent32) == 20); 555static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 556static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 557 558/* 559 * Copy 'count' items into the destination list pointed to by uap->eventlist. 560 */ 561static int 562freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 563{ 564 struct freebsd32_kevent_args *uap; 565 struct kevent32 ks32[KQ_NEVENTS]; 566 int i, error = 0; 567 568 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 569 uap = (struct freebsd32_kevent_args *)arg; 570 571 for (i = 0; i < count; i++) { 572 CP(kevp[i], ks32[i], ident); 573 CP(kevp[i], ks32[i], filter); 574 CP(kevp[i], ks32[i], flags); 575 CP(kevp[i], ks32[i], fflags); 576 CP(kevp[i], ks32[i], data); 577 PTROUT_CP(kevp[i], ks32[i], udata); 578 } 579 error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 580 if (error == 0) 581 uap->eventlist += count; 582 return (error); 583} 584 585/* 586 * Copy 'count' items from the list pointed to by uap->changelist. 587 */ 588static int 589freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 590{ 591 struct freebsd32_kevent_args *uap; 592 struct kevent32 ks32[KQ_NEVENTS]; 593 int i, error = 0; 594 595 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 596 uap = (struct freebsd32_kevent_args *)arg; 597 598 error = copyin(uap->changelist, ks32, count * sizeof *ks32); 599 if (error) 600 goto done; 601 uap->changelist += count; 602 603 for (i = 0; i < count; i++) { 604 CP(ks32[i], kevp[i], ident); 605 CP(ks32[i], kevp[i], filter); 606 CP(ks32[i], kevp[i], flags); 607 CP(ks32[i], kevp[i], fflags); 608 CP(ks32[i], kevp[i], data); 609 PTRIN_CP(ks32[i], kevp[i], udata); 610 } 611done: 612 return (error); 613} 614 615int 616freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 617{ 618 struct timespec32 ts32; 619 struct timespec ts, *tsp; 620 struct kevent_copyops k_ops = { uap, 621 freebsd32_kevent_copyout, 622 freebsd32_kevent_copyin}; 623 int error; 624 625 626 if (uap->timeout) { 627 error = copyin(uap->timeout, &ts32, sizeof(ts32)); 628 if (error) 629 return (error); 630 CP(ts32, ts, tv_sec); 631 CP(ts32, ts, tv_nsec); 632 tsp = &ts; 633 } else 634 tsp = NULL; 635 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 636 &k_ops, tsp); 637 return (error); 638} 639 640int 641freebsd32_gettimeofday(struct thread *td, 642 struct freebsd32_gettimeofday_args *uap) 643{ 644 struct timeval atv; 645 struct timeval32 atv32; 646 struct timezone rtz; 647 int error = 0; 648 649 if (uap->tp) { 650 microtime(&atv); 651 CP(atv, atv32, tv_sec); 652 CP(atv, atv32, tv_usec); 653 error = copyout(&atv32, uap->tp, sizeof (atv32)); 654 } 655 if (error == 0 && uap->tzp != NULL) { 656 rtz.tz_minuteswest = tz_minuteswest; 657 rtz.tz_dsttime = tz_dsttime; 658 error = copyout(&rtz, uap->tzp, sizeof (rtz)); 659 } 660 return (error); 661} 662 663int 664freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 665{ 666 struct rusage32 s32; 667 struct rusage s; 668 int error; 669 670 error = kern_getrusage(td, uap->who, &s); 671 if (error) 672 return (error); 673 if (uap->rusage != NULL) { 674 TV_CP(s, s32, ru_utime); 675 TV_CP(s, s32, ru_stime); 676 CP(s, s32, ru_maxrss); 677 CP(s, s32, ru_ixrss); 678 CP(s, s32, ru_idrss); 679 CP(s, s32, ru_isrss); 680 CP(s, s32, ru_minflt); 681 CP(s, s32, ru_majflt); 682 CP(s, s32, ru_nswap); 683 CP(s, s32, ru_inblock); 684 CP(s, s32, ru_oublock); 685 CP(s, s32, ru_msgsnd); 686 CP(s, s32, ru_msgrcv); 687 CP(s, s32, ru_nsignals); 688 CP(s, s32, ru_nvcsw); 689 CP(s, s32, ru_nivcsw); 690 error = copyout(&s32, uap->rusage, sizeof(s32)); 691 } 692 return (error); 693} 694 695struct iovec32 { 696 u_int32_t iov_base; 697 int iov_len; 698}; 699 700CTASSERT(sizeof(struct iovec32) == 8); 701 702static int 703freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 704{ 705 struct iovec32 iov32; 706 struct iovec *iov; 707 struct uio *uio; 708 u_int iovlen; 709 int error, i; 710 711 *uiop = NULL; 712 if (iovcnt > UIO_MAXIOV) 713 return (EINVAL); 714 iovlen = iovcnt * sizeof(struct iovec); 715 uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 716 iov = (struct iovec *)(uio + 1); 717 for (i = 0; i < iovcnt; i++) { 718 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 719 if (error) { 720 free(uio, M_IOV); 721 return (error); 722 } 723 iov[i].iov_base = PTRIN(iov32.iov_base); 724 iov[i].iov_len = iov32.iov_len; 725 } 726 uio->uio_iov = iov; 727 uio->uio_iovcnt = iovcnt; 728 uio->uio_segflg = UIO_USERSPACE; 729 uio->uio_offset = -1; 730 uio->uio_resid = 0; 731 for (i = 0; i < iovcnt; i++) { 732 if (iov->iov_len > INT_MAX - uio->uio_resid) { 733 free(uio, M_IOV); 734 return (EINVAL); 735 } 736 uio->uio_resid += iov->iov_len; 737 iov++; 738 } 739 *uiop = uio; 740 return (0); 741} 742 743int 744freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 745{ 746 struct uio *auio; 747 int error; 748 749 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 750 if (error) 751 return (error); 752 error = kern_readv(td, uap->fd, auio); 753 free(auio, M_IOV); 754 return (error); 755} 756 757int 758freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 759{ 760 struct uio *auio; 761 int error; 762 763 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 764 if (error) 765 return (error); 766 error = kern_writev(td, uap->fd, auio); 767 free(auio, M_IOV); 768 return (error); 769} 770 771int 772freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 773{ 774 struct uio *auio; 775 int error; 776 777 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 778 if (error) 779 return (error); 780 error = kern_preadv(td, uap->fd, auio, uap->offset); 781 free(auio, M_IOV); 782 return (error); 783} 784 785int 786freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 787{ 788 struct uio *auio; 789 int error; 790 791 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 792 if (error) 793 return (error); 794 error = kern_pwritev(td, uap->fd, auio, uap->offset); 795 free(auio, M_IOV); 796 return (error); 797} 798 799int 800freebsd32_settimeofday(struct thread *td, 801 struct freebsd32_settimeofday_args *uap) 802{ 803 struct timeval32 tv32; 804 struct timeval tv, *tvp; 805 struct timezone tz, *tzp; 806 int error; 807 808 if (uap->tv) { 809 error = copyin(uap->tv, &tv32, sizeof(tv32)); 810 if (error) 811 return (error); 812 CP(tv32, tv, tv_sec); 813 CP(tv32, tv, tv_usec); 814 tvp = &tv; 815 } else 816 tvp = NULL; 817 if (uap->tzp) { 818 error = copyin(uap->tzp, &tz, sizeof(tz)); 819 if (error) 820 return (error); 821 tzp = &tz; 822 } else 823 tzp = NULL; 824 return (kern_settimeofday(td, tvp, tzp)); 825} 826 827int 828freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 829{ 830 struct timeval32 s32[2]; 831 struct timeval s[2], *sp; 832 int error; 833 834 if (uap->tptr != NULL) { 835 error = copyin(uap->tptr, s32, sizeof(s32)); 836 if (error) 837 return (error); 838 CP(s32[0], s[0], tv_sec); 839 CP(s32[0], s[0], tv_usec); 840 CP(s32[1], s[1], tv_sec); 841 CP(s32[1], s[1], tv_usec); 842 sp = s; 843 } else 844 sp = NULL; 845 return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 846} 847 848int 849freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 850{ 851 struct timeval32 tv32; 852 struct timeval delta, olddelta, *deltap; 853 int error; 854 855 if (uap->delta) { 856 error = copyin(uap->delta, &tv32, sizeof(tv32)); 857 if (error) 858 return (error); 859 CP(tv32, delta, tv_sec); 860 CP(tv32, delta, tv_usec); 861 deltap = δ 862 } else 863 deltap = NULL; 864 error = kern_adjtime(td, deltap, &olddelta); 865 if (uap->olddelta && error == 0) { 866 CP(olddelta, tv32, tv_sec); 867 CP(olddelta, tv32, tv_usec); 868 error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 869 } 870 return (error); 871} 872 873#ifdef COMPAT_FREEBSD4 874int 875freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 876{ 877 struct statfs32 s32; 878 struct statfs s; 879 int error; 880 881 error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 882 if (error) 883 return (error); 884 copy_statfs(&s, &s32); 885 return (copyout(&s32, uap->buf, sizeof(s32))); 886} 887#endif 888 889#ifdef COMPAT_FREEBSD4 890int 891freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 892{ 893 struct statfs32 s32; 894 struct statfs s; 895 int error; 896 897 error = kern_fstatfs(td, uap->fd, &s); 898 if (error) 899 return (error); 900 copy_statfs(&s, &s32); 901 return (copyout(&s32, uap->buf, sizeof(s32))); 902} 903#endif 904 905#ifdef COMPAT_FREEBSD4 906int 907freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 908{ 909 struct statfs32 s32; 910 struct statfs s; 911 fhandle_t fh; 912 int error; 913 914 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 915 return (error); 916 error = kern_fhstatfs(td, fh, &s); 917 if (error) 918 return (error); 919 copy_statfs(&s, &s32); 920 return (copyout(&s32, uap->buf, sizeof(s32))); 921} 922#endif 923 924int 925freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 926{ 927 /* 928 * Vector through to semsys if it is loaded. 929 */
| 63#include <sys/syscallsubr.h> 64#include <sys/sysctl.h> 65#include <sys/sysent.h> 66#include <sys/sysproto.h> 67#include <sys/systm.h> 68#include <sys/unistd.h> 69#include <sys/vnode.h> 70#include <sys/wait.h> 71 72#include <vm/vm.h> 73#include <vm/vm_kern.h> 74#include <vm/vm_param.h> 75#include <vm/pmap.h> 76#include <vm/vm_map.h> 77#include <vm/vm_object.h> 78#include <vm/vm_extern.h> 79 80#include <compat/freebsd32/freebsd32_util.h> 81#include <compat/freebsd32/freebsd32.h> 82#include <compat/freebsd32/freebsd32_proto.h> 83 84CTASSERT(sizeof(struct timeval32) == 8); 85CTASSERT(sizeof(struct timespec32) == 8); 86CTASSERT(sizeof(struct statfs32) == 256); 87CTASSERT(sizeof(struct rusage32) == 72); 88 89int 90freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 91{ 92 int error, status; 93 struct rusage32 ru32; 94 struct rusage ru, *rup; 95 96 if (uap->rusage != NULL) 97 rup = &ru; 98 else 99 rup = NULL; 100 error = kern_wait(td, uap->pid, &status, uap->options, rup); 101 if (error) 102 return (error); 103 if (uap->status != NULL) 104 error = copyout(&status, uap->status, sizeof(status)); 105 if (uap->rusage != NULL && error == 0) { 106 TV_CP(ru, ru32, ru_utime); 107 TV_CP(ru, ru32, ru_stime); 108 CP(ru, ru32, ru_maxrss); 109 CP(ru, ru32, ru_ixrss); 110 CP(ru, ru32, ru_idrss); 111 CP(ru, ru32, ru_isrss); 112 CP(ru, ru32, ru_minflt); 113 CP(ru, ru32, ru_majflt); 114 CP(ru, ru32, ru_nswap); 115 CP(ru, ru32, ru_inblock); 116 CP(ru, ru32, ru_oublock); 117 CP(ru, ru32, ru_msgsnd); 118 CP(ru, ru32, ru_msgrcv); 119 CP(ru, ru32, ru_nsignals); 120 CP(ru, ru32, ru_nvcsw); 121 CP(ru, ru32, ru_nivcsw); 122 error = copyout(&ru32, uap->rusage, sizeof(ru32)); 123 } 124 return (error); 125} 126 127#ifdef COMPAT_FREEBSD4 128static void 129copy_statfs(struct statfs *in, struct statfs32 *out) 130{ 131 CP(*in, *out, f_bsize); 132 CP(*in, *out, f_iosize); 133 CP(*in, *out, f_blocks); 134 CP(*in, *out, f_bfree); 135 CP(*in, *out, f_bavail); 136 CP(*in, *out, f_files); 137 CP(*in, *out, f_ffree); 138 CP(*in, *out, f_fsid); 139 CP(*in, *out, f_owner); 140 CP(*in, *out, f_type); 141 CP(*in, *out, f_flags); 142 CP(*in, *out, f_flags); 143 CP(*in, *out, f_syncwrites); 144 CP(*in, *out, f_asyncwrites); 145 bcopy(in->f_fstypename, 146 out->f_fstypename, MFSNAMELEN); 147 bcopy(in->f_mntonname, 148 out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 149 CP(*in, *out, f_syncreads); 150 CP(*in, *out, f_asyncreads); 151 bcopy(in->f_mntfromname, 152 out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 153} 154#endif 155 156#ifdef COMPAT_FREEBSD4 157int 158freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 159{ 160 struct statfs *buf, *sp; 161 struct statfs32 stat32; 162 size_t count, size; 163 int error; 164 165 count = uap->bufsize / sizeof(struct statfs32); 166 size = count * sizeof(struct statfs); 167 error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 168 if (size > 0) { 169 count = td->td_retval[0]; 170 sp = buf; 171 while (count > 0 && error == 0) { 172 copy_statfs(sp, &stat32); 173 error = copyout(&stat32, uap->buf, sizeof(stat32)); 174 sp++; 175 uap->buf++; 176 count--; 177 } 178 free(buf, M_TEMP); 179 } 180 return (error); 181} 182#endif 183 184struct sigaltstack32 { 185 u_int32_t ss_sp; 186 u_int32_t ss_size; 187 int ss_flags; 188}; 189 190CTASSERT(sizeof(struct sigaltstack32) == 12); 191 192int 193freebsd32_sigaltstack(struct thread *td, 194 struct freebsd32_sigaltstack_args *uap) 195{ 196 struct sigaltstack32 s32; 197 struct sigaltstack ss, oss, *ssp; 198 int error; 199 200 if (uap->ss != NULL) { 201 error = copyin(uap->ss, &s32, sizeof(s32)); 202 if (error) 203 return (error); 204 PTRIN_CP(s32, ss, ss_sp); 205 CP(s32, ss, ss_size); 206 CP(s32, ss, ss_flags); 207 ssp = &ss; 208 } else 209 ssp = NULL; 210 error = kern_sigaltstack(td, ssp, &oss); 211 if (error == 0 && uap->oss != NULL) { 212 PTROUT_CP(oss, s32, ss_sp); 213 CP(oss, s32, ss_size); 214 CP(oss, s32, ss_flags); 215 error = copyout(&s32, uap->oss, sizeof(s32)); 216 } 217 return (error); 218} 219 220/* 221 * Custom version of exec_copyin_args() so that we can translate 222 * the pointers. 223 */ 224static int 225freebsd32_exec_copyin_args(struct image_args *args, char *fname, 226 enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 227{ 228 char *argp, *envp; 229 u_int32_t *p32, arg; 230 size_t length; 231 int error; 232 233 bzero(args, sizeof(*args)); 234 if (argv == NULL) 235 return (EFAULT); 236 237 /* 238 * Allocate temporary demand zeroed space for argument and 239 * environment strings 240 */ 241 args->buf = (char *) kmem_alloc_wait(exec_map, 242 PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 243 if (args->buf == NULL) 244 return (ENOMEM); 245 args->begin_argv = args->buf; 246 args->endp = args->begin_argv; 247 args->stringspace = ARG_MAX; 248 249 args->fname = args->buf + ARG_MAX; 250 251 /* 252 * Copy the file name. 253 */ 254 error = (segflg == UIO_SYSSPACE) ? 255 copystr(fname, args->fname, PATH_MAX, &length) : 256 copyinstr(fname, args->fname, PATH_MAX, &length); 257 if (error != 0) 258 return (error); 259 260 /* 261 * extract arguments first 262 */ 263 p32 = argv; 264 for (;;) { 265 error = copyin(p32++, &arg, sizeof(arg)); 266 if (error) 267 return (error); 268 if (arg == 0) 269 break; 270 argp = PTRIN(arg); 271 error = copyinstr(argp, args->endp, args->stringspace, &length); 272 if (error) { 273 if (error == ENAMETOOLONG) 274 return (E2BIG); 275 else 276 return (error); 277 } 278 args->stringspace -= length; 279 args->endp += length; 280 args->argc++; 281 } 282 283 args->begin_envv = args->endp; 284 285 /* 286 * extract environment strings 287 */ 288 if (envv) { 289 p32 = envv; 290 for (;;) { 291 error = copyin(p32++, &arg, sizeof(arg)); 292 if (error) 293 return (error); 294 if (arg == 0) 295 break; 296 envp = PTRIN(arg); 297 error = copyinstr(envp, args->endp, args->stringspace, 298 &length); 299 if (error) { 300 if (error == ENAMETOOLONG) 301 return (E2BIG); 302 else 303 return (error); 304 } 305 args->stringspace -= length; 306 args->endp += length; 307 args->envc++; 308 } 309 } 310 311 return (0); 312} 313 314int 315freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 316{ 317 struct image_args eargs; 318 int error; 319 320 error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 321 uap->argv, uap->envv); 322 if (error == 0) 323 error = kern_execve(td, &eargs, NULL); 324 exec_free_args(&eargs); 325 return (error); 326} 327 328#ifdef __ia64__ 329static int 330freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 331 int prot, int fd, off_t pos) 332{ 333 vm_map_t map; 334 vm_map_entry_t entry; 335 int rv; 336 337 map = &td->td_proc->p_vmspace->vm_map; 338 if (fd != -1) 339 prot |= VM_PROT_WRITE; 340 341 if (vm_map_lookup_entry(map, start, &entry)) { 342 if ((entry->protection & prot) != prot) { 343 rv = vm_map_protect(map, 344 trunc_page(start), 345 round_page(end), 346 entry->protection | prot, 347 FALSE); 348 if (rv != KERN_SUCCESS) 349 return (EINVAL); 350 } 351 } else { 352 vm_offset_t addr = trunc_page(start); 353 rv = vm_map_find(map, 0, 0, 354 &addr, PAGE_SIZE, FALSE, prot, 355 VM_PROT_ALL, 0); 356 if (rv != KERN_SUCCESS) 357 return (EINVAL); 358 } 359 360 if (fd != -1) { 361 struct pread_args r; 362 r.fd = fd; 363 r.buf = (void *) start; 364 r.nbyte = end - start; 365 r.offset = pos; 366 return (pread(td, &r)); 367 } else { 368 while (start < end) { 369 subyte((void *) start, 0); 370 start++; 371 } 372 return (0); 373 } 374} 375#endif 376 377int 378freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 379{ 380 struct mmap_args ap; 381 vm_offset_t addr = (vm_offset_t) uap->addr; 382 vm_size_t len = uap->len; 383 int prot = uap->prot; 384 int flags = uap->flags; 385 int fd = uap->fd; 386 off_t pos = (uap->poslo 387 | ((off_t)uap->poshi << 32)); 388#ifdef __ia64__ 389 vm_size_t pageoff; 390 int error; 391 392 /* 393 * Attempt to handle page size hassles. 394 */ 395 pageoff = (pos & PAGE_MASK); 396 if (flags & MAP_FIXED) { 397 vm_offset_t start, end; 398 start = addr; 399 end = addr + len; 400 401 mtx_lock(&Giant); 402 if (start != trunc_page(start)) { 403 error = freebsd32_mmap_partial(td, start, 404 round_page(start), prot, 405 fd, pos); 406 if (fd != -1) 407 pos += round_page(start) - start; 408 start = round_page(start); 409 } 410 if (end != round_page(end)) { 411 vm_offset_t t = trunc_page(end); 412 error = freebsd32_mmap_partial(td, t, end, 413 prot, fd, 414 pos + t - start); 415 end = trunc_page(end); 416 } 417 if (end > start && fd != -1 && (pos & PAGE_MASK)) { 418 /* 419 * We can't map this region at all. The specified 420 * address doesn't have the same alignment as the file 421 * position. Fake the mapping by simply reading the 422 * entire region into memory. First we need to make 423 * sure the region exists. 424 */ 425 vm_map_t map; 426 struct pread_args r; 427 int rv; 428 429 prot |= VM_PROT_WRITE; 430 map = &td->td_proc->p_vmspace->vm_map; 431 rv = vm_map_remove(map, start, end); 432 if (rv != KERN_SUCCESS) { 433 mtx_unlock(&Giant); 434 return (EINVAL); 435 } 436 rv = vm_map_find(map, 0, 0, 437 &start, end - start, FALSE, 438 prot, VM_PROT_ALL, 0); 439 mtx_unlock(&Giant); 440 if (rv != KERN_SUCCESS) 441 return (EINVAL); 442 r.fd = fd; 443 r.buf = (void *) start; 444 r.nbyte = end - start; 445 r.offset = pos; 446 error = pread(td, &r); 447 if (error) 448 return (error); 449 450 td->td_retval[0] = addr; 451 return (0); 452 } 453 mtx_unlock(&Giant); 454 if (end == start) { 455 /* 456 * After dealing with the ragged ends, there 457 * might be none left. 458 */ 459 td->td_retval[0] = addr; 460 return (0); 461 } 462 addr = start; 463 len = end - start; 464 } 465#endif 466 467 ap.addr = (void *) addr; 468 ap.len = len; 469 ap.prot = prot; 470 ap.flags = flags; 471 ap.fd = fd; 472 ap.pos = pos; 473 474 return (mmap(td, &ap)); 475} 476 477struct itimerval32 { 478 struct timeval32 it_interval; 479 struct timeval32 it_value; 480}; 481 482CTASSERT(sizeof(struct itimerval32) == 16); 483 484int 485freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 486{ 487 struct itimerval itv, oitv, *itvp; 488 struct itimerval32 i32; 489 int error; 490 491 if (uap->itv != NULL) { 492 error = copyin(uap->itv, &i32, sizeof(i32)); 493 if (error) 494 return (error); 495 TV_CP(i32, itv, it_interval); 496 TV_CP(i32, itv, it_value); 497 itvp = &itv; 498 } else 499 itvp = NULL; 500 error = kern_setitimer(td, uap->which, itvp, &oitv); 501 if (error || uap->oitv == NULL) 502 return (error); 503 TV_CP(oitv, i32, it_interval); 504 TV_CP(oitv, i32, it_value); 505 return (copyout(&i32, uap->oitv, sizeof(i32))); 506} 507 508int 509freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 510{ 511 struct itimerval itv; 512 struct itimerval32 i32; 513 int error; 514 515 error = kern_getitimer(td, uap->which, &itv); 516 if (error || uap->itv == NULL) 517 return (error); 518 TV_CP(itv, i32, it_interval); 519 TV_CP(itv, i32, it_value); 520 return (copyout(&i32, uap->itv, sizeof(i32))); 521} 522 523int 524freebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 525{ 526 struct timeval32 tv32; 527 struct timeval tv, *tvp; 528 int error; 529 530 if (uap->tv != NULL) { 531 error = copyin(uap->tv, &tv32, sizeof(tv32)); 532 if (error) 533 return (error); 534 CP(tv32, tv, tv_sec); 535 CP(tv32, tv, tv_usec); 536 tvp = &tv; 537 } else 538 tvp = NULL; 539 /* 540 * XXX big-endian needs to convert the fd_sets too. 541 * XXX Do pointers need PTRIN()? 542 */ 543 return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 544} 545 546struct kevent32 { 547 u_int32_t ident; /* identifier for this event */ 548 short filter; /* filter for event */ 549 u_short flags; 550 u_int fflags; 551 int32_t data; 552 u_int32_t udata; /* opaque user data identifier */ 553}; 554 555CTASSERT(sizeof(struct kevent32) == 20); 556static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 557static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 558 559/* 560 * Copy 'count' items into the destination list pointed to by uap->eventlist. 561 */ 562static int 563freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 564{ 565 struct freebsd32_kevent_args *uap; 566 struct kevent32 ks32[KQ_NEVENTS]; 567 int i, error = 0; 568 569 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 570 uap = (struct freebsd32_kevent_args *)arg; 571 572 for (i = 0; i < count; i++) { 573 CP(kevp[i], ks32[i], ident); 574 CP(kevp[i], ks32[i], filter); 575 CP(kevp[i], ks32[i], flags); 576 CP(kevp[i], ks32[i], fflags); 577 CP(kevp[i], ks32[i], data); 578 PTROUT_CP(kevp[i], ks32[i], udata); 579 } 580 error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 581 if (error == 0) 582 uap->eventlist += count; 583 return (error); 584} 585 586/* 587 * Copy 'count' items from the list pointed to by uap->changelist. 588 */ 589static int 590freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 591{ 592 struct freebsd32_kevent_args *uap; 593 struct kevent32 ks32[KQ_NEVENTS]; 594 int i, error = 0; 595 596 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 597 uap = (struct freebsd32_kevent_args *)arg; 598 599 error = copyin(uap->changelist, ks32, count * sizeof *ks32); 600 if (error) 601 goto done; 602 uap->changelist += count; 603 604 for (i = 0; i < count; i++) { 605 CP(ks32[i], kevp[i], ident); 606 CP(ks32[i], kevp[i], filter); 607 CP(ks32[i], kevp[i], flags); 608 CP(ks32[i], kevp[i], fflags); 609 CP(ks32[i], kevp[i], data); 610 PTRIN_CP(ks32[i], kevp[i], udata); 611 } 612done: 613 return (error); 614} 615 616int 617freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 618{ 619 struct timespec32 ts32; 620 struct timespec ts, *tsp; 621 struct kevent_copyops k_ops = { uap, 622 freebsd32_kevent_copyout, 623 freebsd32_kevent_copyin}; 624 int error; 625 626 627 if (uap->timeout) { 628 error = copyin(uap->timeout, &ts32, sizeof(ts32)); 629 if (error) 630 return (error); 631 CP(ts32, ts, tv_sec); 632 CP(ts32, ts, tv_nsec); 633 tsp = &ts; 634 } else 635 tsp = NULL; 636 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 637 &k_ops, tsp); 638 return (error); 639} 640 641int 642freebsd32_gettimeofday(struct thread *td, 643 struct freebsd32_gettimeofday_args *uap) 644{ 645 struct timeval atv; 646 struct timeval32 atv32; 647 struct timezone rtz; 648 int error = 0; 649 650 if (uap->tp) { 651 microtime(&atv); 652 CP(atv, atv32, tv_sec); 653 CP(atv, atv32, tv_usec); 654 error = copyout(&atv32, uap->tp, sizeof (atv32)); 655 } 656 if (error == 0 && uap->tzp != NULL) { 657 rtz.tz_minuteswest = tz_minuteswest; 658 rtz.tz_dsttime = tz_dsttime; 659 error = copyout(&rtz, uap->tzp, sizeof (rtz)); 660 } 661 return (error); 662} 663 664int 665freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 666{ 667 struct rusage32 s32; 668 struct rusage s; 669 int error; 670 671 error = kern_getrusage(td, uap->who, &s); 672 if (error) 673 return (error); 674 if (uap->rusage != NULL) { 675 TV_CP(s, s32, ru_utime); 676 TV_CP(s, s32, ru_stime); 677 CP(s, s32, ru_maxrss); 678 CP(s, s32, ru_ixrss); 679 CP(s, s32, ru_idrss); 680 CP(s, s32, ru_isrss); 681 CP(s, s32, ru_minflt); 682 CP(s, s32, ru_majflt); 683 CP(s, s32, ru_nswap); 684 CP(s, s32, ru_inblock); 685 CP(s, s32, ru_oublock); 686 CP(s, s32, ru_msgsnd); 687 CP(s, s32, ru_msgrcv); 688 CP(s, s32, ru_nsignals); 689 CP(s, s32, ru_nvcsw); 690 CP(s, s32, ru_nivcsw); 691 error = copyout(&s32, uap->rusage, sizeof(s32)); 692 } 693 return (error); 694} 695 696struct iovec32 { 697 u_int32_t iov_base; 698 int iov_len; 699}; 700 701CTASSERT(sizeof(struct iovec32) == 8); 702 703static int 704freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 705{ 706 struct iovec32 iov32; 707 struct iovec *iov; 708 struct uio *uio; 709 u_int iovlen; 710 int error, i; 711 712 *uiop = NULL; 713 if (iovcnt > UIO_MAXIOV) 714 return (EINVAL); 715 iovlen = iovcnt * sizeof(struct iovec); 716 uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 717 iov = (struct iovec *)(uio + 1); 718 for (i = 0; i < iovcnt; i++) { 719 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 720 if (error) { 721 free(uio, M_IOV); 722 return (error); 723 } 724 iov[i].iov_base = PTRIN(iov32.iov_base); 725 iov[i].iov_len = iov32.iov_len; 726 } 727 uio->uio_iov = iov; 728 uio->uio_iovcnt = iovcnt; 729 uio->uio_segflg = UIO_USERSPACE; 730 uio->uio_offset = -1; 731 uio->uio_resid = 0; 732 for (i = 0; i < iovcnt; i++) { 733 if (iov->iov_len > INT_MAX - uio->uio_resid) { 734 free(uio, M_IOV); 735 return (EINVAL); 736 } 737 uio->uio_resid += iov->iov_len; 738 iov++; 739 } 740 *uiop = uio; 741 return (0); 742} 743 744int 745freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 746{ 747 struct uio *auio; 748 int error; 749 750 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 751 if (error) 752 return (error); 753 error = kern_readv(td, uap->fd, auio); 754 free(auio, M_IOV); 755 return (error); 756} 757 758int 759freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 760{ 761 struct uio *auio; 762 int error; 763 764 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 765 if (error) 766 return (error); 767 error = kern_writev(td, uap->fd, auio); 768 free(auio, M_IOV); 769 return (error); 770} 771 772int 773freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 774{ 775 struct uio *auio; 776 int error; 777 778 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 779 if (error) 780 return (error); 781 error = kern_preadv(td, uap->fd, auio, uap->offset); 782 free(auio, M_IOV); 783 return (error); 784} 785 786int 787freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 788{ 789 struct uio *auio; 790 int error; 791 792 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 793 if (error) 794 return (error); 795 error = kern_pwritev(td, uap->fd, auio, uap->offset); 796 free(auio, M_IOV); 797 return (error); 798} 799 800int 801freebsd32_settimeofday(struct thread *td, 802 struct freebsd32_settimeofday_args *uap) 803{ 804 struct timeval32 tv32; 805 struct timeval tv, *tvp; 806 struct timezone tz, *tzp; 807 int error; 808 809 if (uap->tv) { 810 error = copyin(uap->tv, &tv32, sizeof(tv32)); 811 if (error) 812 return (error); 813 CP(tv32, tv, tv_sec); 814 CP(tv32, tv, tv_usec); 815 tvp = &tv; 816 } else 817 tvp = NULL; 818 if (uap->tzp) { 819 error = copyin(uap->tzp, &tz, sizeof(tz)); 820 if (error) 821 return (error); 822 tzp = &tz; 823 } else 824 tzp = NULL; 825 return (kern_settimeofday(td, tvp, tzp)); 826} 827 828int 829freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 830{ 831 struct timeval32 s32[2]; 832 struct timeval s[2], *sp; 833 int error; 834 835 if (uap->tptr != NULL) { 836 error = copyin(uap->tptr, s32, sizeof(s32)); 837 if (error) 838 return (error); 839 CP(s32[0], s[0], tv_sec); 840 CP(s32[0], s[0], tv_usec); 841 CP(s32[1], s[1], tv_sec); 842 CP(s32[1], s[1], tv_usec); 843 sp = s; 844 } else 845 sp = NULL; 846 return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 847} 848 849int 850freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 851{ 852 struct timeval32 tv32; 853 struct timeval delta, olddelta, *deltap; 854 int error; 855 856 if (uap->delta) { 857 error = copyin(uap->delta, &tv32, sizeof(tv32)); 858 if (error) 859 return (error); 860 CP(tv32, delta, tv_sec); 861 CP(tv32, delta, tv_usec); 862 deltap = δ 863 } else 864 deltap = NULL; 865 error = kern_adjtime(td, deltap, &olddelta); 866 if (uap->olddelta && error == 0) { 867 CP(olddelta, tv32, tv_sec); 868 CP(olddelta, tv32, tv_usec); 869 error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 870 } 871 return (error); 872} 873 874#ifdef COMPAT_FREEBSD4 875int 876freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 877{ 878 struct statfs32 s32; 879 struct statfs s; 880 int error; 881 882 error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 883 if (error) 884 return (error); 885 copy_statfs(&s, &s32); 886 return (copyout(&s32, uap->buf, sizeof(s32))); 887} 888#endif 889 890#ifdef COMPAT_FREEBSD4 891int 892freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 893{ 894 struct statfs32 s32; 895 struct statfs s; 896 int error; 897 898 error = kern_fstatfs(td, uap->fd, &s); 899 if (error) 900 return (error); 901 copy_statfs(&s, &s32); 902 return (copyout(&s32, uap->buf, sizeof(s32))); 903} 904#endif 905 906#ifdef COMPAT_FREEBSD4 907int 908freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 909{ 910 struct statfs32 s32; 911 struct statfs s; 912 fhandle_t fh; 913 int error; 914 915 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 916 return (error); 917 error = kern_fhstatfs(td, fh, &s); 918 if (error) 919 return (error); 920 copy_statfs(&s, &s32); 921 return (copyout(&s32, uap->buf, sizeof(s32))); 922} 923#endif 924 925int 926freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 927{ 928 /* 929 * Vector through to semsys if it is loaded. 930 */
|
949} 950 951int 952freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 953{ 954 struct pread_args ap; 955 956 ap.fd = uap->fd; 957 ap.buf = uap->buf; 958 ap.nbyte = uap->nbyte; 959 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 960 return (pread(td, &ap)); 961} 962 963int 964freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 965{ 966 struct pwrite_args ap; 967 968 ap.fd = uap->fd; 969 ap.buf = uap->buf; 970 ap.nbyte = uap->nbyte; 971 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 972 return (pwrite(td, &ap)); 973} 974 975int 976freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 977{ 978 int error; 979 struct lseek_args ap; 980 off_t pos; 981 982 ap.fd = uap->fd; 983 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 984 ap.whence = uap->whence; 985 error = lseek(td, &ap); 986 /* Expand the quad return into two parts for eax and edx */ 987 pos = *(off_t *)(td->td_retval); 988 td->td_retval[0] = pos & 0xffffffff; /* %eax */ 989 td->td_retval[1] = pos >> 32; /* %edx */ 990 return error; 991} 992 993int 994freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 995{ 996 struct truncate_args ap; 997 998 ap.path = uap->path; 999 ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1000 return (truncate(td, &ap)); 1001} 1002 1003int 1004freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1005{ 1006 struct ftruncate_args ap; 1007 1008 ap.fd = uap->fd; 1009 ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1010 return (ftruncate(td, &ap)); 1011} 1012 1013#ifdef COMPAT_FREEBSD4 1014int 1015freebsd4_freebsd32_sendfile(struct thread *td, 1016 struct freebsd4_freebsd32_sendfile_args *uap) 1017{ 1018 struct freebsd4_sendfile_args ap; 1019 1020 ap.fd = uap->fd; 1021 ap.s = uap->s; 1022 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1023 ap.nbytes = uap->nbytes; /* XXX check */ 1024 ap.hdtr = uap->hdtr; /* XXX check */ 1025 ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1026 ap.flags = uap->flags; 1027 return (freebsd4_sendfile(td, &ap)); 1028} 1029#endif 1030 1031int 1032freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1033{ 1034 struct sendfile_args ap; 1035 1036 ap.fd = uap->fd; 1037 ap.s = uap->s; 1038 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1039 ap.nbytes = uap->nbytes; /* XXX check */ 1040 ap.hdtr = uap->hdtr; /* XXX check */ 1041 ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1042 ap.flags = uap->flags; 1043 return (sendfile(td, &ap)); 1044} 1045 1046struct stat32 { 1047 dev_t st_dev; 1048 ino_t st_ino; 1049 mode_t st_mode; 1050 nlink_t st_nlink; 1051 uid_t st_uid; 1052 gid_t st_gid; 1053 dev_t st_rdev; 1054 struct timespec32 st_atimespec; 1055 struct timespec32 st_mtimespec; 1056 struct timespec32 st_ctimespec; 1057 off_t st_size; 1058 int64_t st_blocks; 1059 u_int32_t st_blksize; 1060 u_int32_t st_flags; 1061 u_int32_t st_gen; 1062 struct timespec32 st_birthtimespec; 1063 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1064 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1065}; 1066 1067 1068CTASSERT(sizeof(struct stat32) == 96); 1069 1070static void 1071copy_stat( struct stat *in, struct stat32 *out) 1072{ 1073 CP(*in, *out, st_dev); 1074 CP(*in, *out, st_ino); 1075 CP(*in, *out, st_mode); 1076 CP(*in, *out, st_nlink); 1077 CP(*in, *out, st_uid); 1078 CP(*in, *out, st_gid); 1079 CP(*in, *out, st_rdev); 1080 TS_CP(*in, *out, st_atimespec); 1081 TS_CP(*in, *out, st_mtimespec); 1082 TS_CP(*in, *out, st_ctimespec); 1083 CP(*in, *out, st_size); 1084 CP(*in, *out, st_blocks); 1085 CP(*in, *out, st_blksize); 1086 CP(*in, *out, st_flags); 1087 CP(*in, *out, st_gen); 1088} 1089 1090int 1091freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1092{ 1093 struct stat sb; 1094 struct stat32 sb32; 1095 int error; 1096 1097 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1098 if (error) 1099 return (error); 1100 copy_stat(&sb, &sb32); 1101 error = copyout(&sb32, uap->ub, sizeof (sb32)); 1102 return (error); 1103} 1104 1105int 1106freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1107{ 1108 struct stat ub; 1109 struct stat32 ub32; 1110 int error; 1111 1112 error = kern_fstat(td, uap->fd, &ub); 1113 if (error) 1114 return (error); 1115 copy_stat(&ub, &ub32); 1116 error = copyout(&ub32, uap->ub, sizeof(ub32)); 1117 return (error); 1118} 1119 1120int 1121freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1122{ 1123 struct stat sb; 1124 struct stat32 sb32; 1125 int error; 1126 1127 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1128 if (error) 1129 return (error); 1130 copy_stat(&sb, &sb32); 1131 error = copyout(&sb32, uap->ub, sizeof (sb32)); 1132 return (error); 1133} 1134 1135/* 1136 * MPSAFE 1137 */ 1138int 1139freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1140{ 1141 int error, name[CTL_MAXNAME]; 1142 size_t j, oldlen; 1143 1144 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1145 return (EINVAL); 1146 error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1147 if (error) 1148 return (error); 1149 mtx_lock(&Giant); 1150 if (uap->oldlenp) 1151 oldlen = fuword32(uap->oldlenp); 1152 else 1153 oldlen = 0; 1154 error = userland_sysctl(td, name, uap->namelen, 1155 uap->old, &oldlen, 1, 1156 uap->new, uap->newlen, &j, SCTL_MASK32); 1157 if (error && error != ENOMEM) 1158 goto done2; 1159 if (uap->oldlenp) 1160 suword32(uap->oldlenp, j); 1161done2: 1162 mtx_unlock(&Giant); 1163 return (error); 1164} 1165 1166struct sigaction32 { 1167 u_int32_t sa_u; 1168 int sa_flags; 1169 sigset_t sa_mask; 1170}; 1171 1172CTASSERT(sizeof(struct sigaction32) == 24); 1173 1174int 1175freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1176{ 1177 struct sigaction32 s32; 1178 struct sigaction sa, osa, *sap; 1179 int error; 1180 1181 if (uap->act) { 1182 error = copyin(uap->act, &s32, sizeof(s32)); 1183 if (error) 1184 return (error); 1185 sa.sa_handler = PTRIN(s32.sa_u); 1186 CP(s32, sa, sa_flags); 1187 CP(s32, sa, sa_mask); 1188 sap = &sa; 1189 } else 1190 sap = NULL; 1191 error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1192 if (error == 0 && uap->oact != NULL) { 1193 s32.sa_u = PTROUT(osa.sa_handler); 1194 CP(osa, s32, sa_flags); 1195 CP(osa, s32, sa_mask); 1196 error = copyout(&s32, uap->oact, sizeof(s32)); 1197 } 1198 return (error); 1199} 1200 1201#ifdef COMPAT_FREEBSD4 1202int 1203freebsd4_freebsd32_sigaction(struct thread *td, 1204 struct freebsd4_freebsd32_sigaction_args *uap) 1205{ 1206 struct sigaction32 s32; 1207 struct sigaction sa, osa, *sap; 1208 int error; 1209 1210 if (uap->act) { 1211 error = copyin(uap->act, &s32, sizeof(s32)); 1212 if (error) 1213 return (error); 1214 sa.sa_handler = PTRIN(s32.sa_u); 1215 CP(s32, sa, sa_flags); 1216 CP(s32, sa, sa_mask); 1217 sap = &sa; 1218 } else 1219 sap = NULL; 1220 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1221 if (error == 0 && uap->oact != NULL) { 1222 s32.sa_u = PTROUT(osa.sa_handler); 1223 CP(osa, s32, sa_flags); 1224 CP(osa, s32, sa_mask); 1225 error = copyout(&s32, uap->oact, sizeof(s32)); 1226 } 1227 return (error); 1228} 1229#endif 1230 1231int 1232freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1233{ 1234 struct timespec32 rmt32, rqt32; 1235 struct timespec rmt, rqt; 1236 int error; 1237 1238 error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1239 if (error) 1240 return (error); 1241 1242 CP(rqt32, rqt, tv_sec); 1243 CP(rqt32, rqt, tv_nsec); 1244 1245 if (uap->rmtp && 1246 !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1247 return (EFAULT); 1248 error = kern_nanosleep(td, &rqt, &rmt); 1249 if (error && uap->rmtp) { 1250 int error2; 1251 1252 CP(rmt, rmt32, tv_sec); 1253 CP(rmt, rmt32, tv_nsec); 1254 1255 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1256 if (error2) 1257 error = error2; 1258 } 1259 return (error); 1260} 1261 1262#if 0 1263 1264int 1265freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1266{ 1267 int error; 1268 struct yyy32 *p32, s32; 1269 struct yyy *p = NULL, s; 1270 1271 if (uap->zzz) { 1272 error = copyin(uap->zzz, &s32, sizeof(s32)); 1273 if (error) 1274 return (error); 1275 /* translate in */ 1276 p = &s; 1277 } 1278 error = kern_xxx(td, p); 1279 if (error) 1280 return (error); 1281 if (uap->zzz) { 1282 /* translate out */ 1283 error = copyout(&s32, p32, sizeof(s32)); 1284 } 1285 return (error); 1286} 1287 1288#endif
| 950} 951 952int 953freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 954{ 955 struct pread_args ap; 956 957 ap.fd = uap->fd; 958 ap.buf = uap->buf; 959 ap.nbyte = uap->nbyte; 960 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 961 return (pread(td, &ap)); 962} 963 964int 965freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 966{ 967 struct pwrite_args ap; 968 969 ap.fd = uap->fd; 970 ap.buf = uap->buf; 971 ap.nbyte = uap->nbyte; 972 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 973 return (pwrite(td, &ap)); 974} 975 976int 977freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 978{ 979 int error; 980 struct lseek_args ap; 981 off_t pos; 982 983 ap.fd = uap->fd; 984 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 985 ap.whence = uap->whence; 986 error = lseek(td, &ap); 987 /* Expand the quad return into two parts for eax and edx */ 988 pos = *(off_t *)(td->td_retval); 989 td->td_retval[0] = pos & 0xffffffff; /* %eax */ 990 td->td_retval[1] = pos >> 32; /* %edx */ 991 return error; 992} 993 994int 995freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 996{ 997 struct truncate_args ap; 998 999 ap.path = uap->path; 1000 ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1001 return (truncate(td, &ap)); 1002} 1003 1004int 1005freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1006{ 1007 struct ftruncate_args ap; 1008 1009 ap.fd = uap->fd; 1010 ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1011 return (ftruncate(td, &ap)); 1012} 1013 1014#ifdef COMPAT_FREEBSD4 1015int 1016freebsd4_freebsd32_sendfile(struct thread *td, 1017 struct freebsd4_freebsd32_sendfile_args *uap) 1018{ 1019 struct freebsd4_sendfile_args ap; 1020 1021 ap.fd = uap->fd; 1022 ap.s = uap->s; 1023 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1024 ap.nbytes = uap->nbytes; /* XXX check */ 1025 ap.hdtr = uap->hdtr; /* XXX check */ 1026 ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1027 ap.flags = uap->flags; 1028 return (freebsd4_sendfile(td, &ap)); 1029} 1030#endif 1031 1032int 1033freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1034{ 1035 struct sendfile_args ap; 1036 1037 ap.fd = uap->fd; 1038 ap.s = uap->s; 1039 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1040 ap.nbytes = uap->nbytes; /* XXX check */ 1041 ap.hdtr = uap->hdtr; /* XXX check */ 1042 ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1043 ap.flags = uap->flags; 1044 return (sendfile(td, &ap)); 1045} 1046 1047struct stat32 { 1048 dev_t st_dev; 1049 ino_t st_ino; 1050 mode_t st_mode; 1051 nlink_t st_nlink; 1052 uid_t st_uid; 1053 gid_t st_gid; 1054 dev_t st_rdev; 1055 struct timespec32 st_atimespec; 1056 struct timespec32 st_mtimespec; 1057 struct timespec32 st_ctimespec; 1058 off_t st_size; 1059 int64_t st_blocks; 1060 u_int32_t st_blksize; 1061 u_int32_t st_flags; 1062 u_int32_t st_gen; 1063 struct timespec32 st_birthtimespec; 1064 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1065 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1066}; 1067 1068 1069CTASSERT(sizeof(struct stat32) == 96); 1070 1071static void 1072copy_stat( struct stat *in, struct stat32 *out) 1073{ 1074 CP(*in, *out, st_dev); 1075 CP(*in, *out, st_ino); 1076 CP(*in, *out, st_mode); 1077 CP(*in, *out, st_nlink); 1078 CP(*in, *out, st_uid); 1079 CP(*in, *out, st_gid); 1080 CP(*in, *out, st_rdev); 1081 TS_CP(*in, *out, st_atimespec); 1082 TS_CP(*in, *out, st_mtimespec); 1083 TS_CP(*in, *out, st_ctimespec); 1084 CP(*in, *out, st_size); 1085 CP(*in, *out, st_blocks); 1086 CP(*in, *out, st_blksize); 1087 CP(*in, *out, st_flags); 1088 CP(*in, *out, st_gen); 1089} 1090 1091int 1092freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1093{ 1094 struct stat sb; 1095 struct stat32 sb32; 1096 int error; 1097 1098 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1099 if (error) 1100 return (error); 1101 copy_stat(&sb, &sb32); 1102 error = copyout(&sb32, uap->ub, sizeof (sb32)); 1103 return (error); 1104} 1105 1106int 1107freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1108{ 1109 struct stat ub; 1110 struct stat32 ub32; 1111 int error; 1112 1113 error = kern_fstat(td, uap->fd, &ub); 1114 if (error) 1115 return (error); 1116 copy_stat(&ub, &ub32); 1117 error = copyout(&ub32, uap->ub, sizeof(ub32)); 1118 return (error); 1119} 1120 1121int 1122freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1123{ 1124 struct stat sb; 1125 struct stat32 sb32; 1126 int error; 1127 1128 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1129 if (error) 1130 return (error); 1131 copy_stat(&sb, &sb32); 1132 error = copyout(&sb32, uap->ub, sizeof (sb32)); 1133 return (error); 1134} 1135 1136/* 1137 * MPSAFE 1138 */ 1139int 1140freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1141{ 1142 int error, name[CTL_MAXNAME]; 1143 size_t j, oldlen; 1144 1145 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1146 return (EINVAL); 1147 error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1148 if (error) 1149 return (error); 1150 mtx_lock(&Giant); 1151 if (uap->oldlenp) 1152 oldlen = fuword32(uap->oldlenp); 1153 else 1154 oldlen = 0; 1155 error = userland_sysctl(td, name, uap->namelen, 1156 uap->old, &oldlen, 1, 1157 uap->new, uap->newlen, &j, SCTL_MASK32); 1158 if (error && error != ENOMEM) 1159 goto done2; 1160 if (uap->oldlenp) 1161 suword32(uap->oldlenp, j); 1162done2: 1163 mtx_unlock(&Giant); 1164 return (error); 1165} 1166 1167struct sigaction32 { 1168 u_int32_t sa_u; 1169 int sa_flags; 1170 sigset_t sa_mask; 1171}; 1172 1173CTASSERT(sizeof(struct sigaction32) == 24); 1174 1175int 1176freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1177{ 1178 struct sigaction32 s32; 1179 struct sigaction sa, osa, *sap; 1180 int error; 1181 1182 if (uap->act) { 1183 error = copyin(uap->act, &s32, sizeof(s32)); 1184 if (error) 1185 return (error); 1186 sa.sa_handler = PTRIN(s32.sa_u); 1187 CP(s32, sa, sa_flags); 1188 CP(s32, sa, sa_mask); 1189 sap = &sa; 1190 } else 1191 sap = NULL; 1192 error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1193 if (error == 0 && uap->oact != NULL) { 1194 s32.sa_u = PTROUT(osa.sa_handler); 1195 CP(osa, s32, sa_flags); 1196 CP(osa, s32, sa_mask); 1197 error = copyout(&s32, uap->oact, sizeof(s32)); 1198 } 1199 return (error); 1200} 1201 1202#ifdef COMPAT_FREEBSD4 1203int 1204freebsd4_freebsd32_sigaction(struct thread *td, 1205 struct freebsd4_freebsd32_sigaction_args *uap) 1206{ 1207 struct sigaction32 s32; 1208 struct sigaction sa, osa, *sap; 1209 int error; 1210 1211 if (uap->act) { 1212 error = copyin(uap->act, &s32, sizeof(s32)); 1213 if (error) 1214 return (error); 1215 sa.sa_handler = PTRIN(s32.sa_u); 1216 CP(s32, sa, sa_flags); 1217 CP(s32, sa, sa_mask); 1218 sap = &sa; 1219 } else 1220 sap = NULL; 1221 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1222 if (error == 0 && uap->oact != NULL) { 1223 s32.sa_u = PTROUT(osa.sa_handler); 1224 CP(osa, s32, sa_flags); 1225 CP(osa, s32, sa_mask); 1226 error = copyout(&s32, uap->oact, sizeof(s32)); 1227 } 1228 return (error); 1229} 1230#endif 1231 1232int 1233freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1234{ 1235 struct timespec32 rmt32, rqt32; 1236 struct timespec rmt, rqt; 1237 int error; 1238 1239 error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1240 if (error) 1241 return (error); 1242 1243 CP(rqt32, rqt, tv_sec); 1244 CP(rqt32, rqt, tv_nsec); 1245 1246 if (uap->rmtp && 1247 !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1248 return (EFAULT); 1249 error = kern_nanosleep(td, &rqt, &rmt); 1250 if (error && uap->rmtp) { 1251 int error2; 1252 1253 CP(rmt, rmt32, tv_sec); 1254 CP(rmt, rmt32, tv_nsec); 1255 1256 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1257 if (error2) 1258 error = error2; 1259 } 1260 return (error); 1261} 1262 1263#if 0 1264 1265int 1266freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1267{ 1268 int error; 1269 struct yyy32 *p32, s32; 1270 struct yyy *p = NULL, s; 1271 1272 if (uap->zzz) { 1273 error = copyin(uap->zzz, &s32, sizeof(s32)); 1274 if (error) 1275 return (error); 1276 /* translate in */ 1277 p = &s; 1278 } 1279 error = kern_xxx(td, p); 1280 if (error) 1281 return (error); 1282 if (uap->zzz) { 1283 /* translate out */ 1284 error = copyout(&s32, p32, sizeof(s32)); 1285 } 1286 return (error); 1287} 1288 1289#endif
|