The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/freebsd32/freebsd32_misc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2002 Doug Rabson
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "opt_inet.h"
   33 #include "opt_inet6.h"
   34 #include "opt_ktrace.h"
   35 
   36 #define __ELF_WORD_SIZE 32
   37 
   38 #ifdef COMPAT_FREEBSD11
   39 #define _WANT_FREEBSD11_KEVENT
   40 #endif
   41 
   42 #include <sys/param.h>
   43 #include <sys/bus.h>
   44 #include <sys/capsicum.h>
   45 #include <sys/clock.h>
   46 #include <sys/exec.h>
   47 #include <sys/fcntl.h>
   48 #include <sys/filedesc.h>
   49 #include <sys/imgact.h>
   50 #include <sys/jail.h>
   51 #include <sys/kernel.h>
   52 #include <sys/limits.h>
   53 #include <sys/linker.h>
   54 #include <sys/lock.h>
   55 #include <sys/malloc.h>
   56 #include <sys/file.h>           /* Must come after sys/malloc.h */
   57 #include <sys/imgact.h>
   58 #include <sys/mbuf.h>
   59 #include <sys/mman.h>
   60 #include <sys/module.h>
   61 #include <sys/mount.h>
   62 #include <sys/mutex.h>
   63 #include <sys/namei.h>
   64 #include <sys/proc.h>
   65 #include <sys/procctl.h>
   66 #include <sys/ptrace.h>
   67 #include <sys/reboot.h>
   68 #include <sys/resource.h>
   69 #include <sys/resourcevar.h>
   70 #include <sys/selinfo.h>
   71 #include <sys/eventvar.h>       /* Must come after sys/selinfo.h */
   72 #include <sys/pipe.h>           /* Must come after sys/selinfo.h */
   73 #include <sys/signal.h>
   74 #include <sys/signalvar.h>
   75 #include <sys/socket.h>
   76 #include <sys/socketvar.h>
   77 #include <sys/stat.h>
   78 #include <sys/syscall.h>
   79 #include <sys/syscallsubr.h>
   80 #include <sys/sysctl.h>
   81 #include <sys/sysent.h>
   82 #include <sys/sysproto.h>
   83 #include <sys/systm.h>
   84 #include <sys/thr.h>
   85 #include <sys/timex.h>
   86 #include <sys/unistd.h>
   87 #include <sys/ucontext.h>
   88 #include <sys/umtx.h>
   89 #include <sys/vnode.h>
   90 #include <sys/wait.h>
   91 #include <sys/ipc.h>
   92 #include <sys/msg.h>
   93 #include <sys/sem.h>
   94 #include <sys/shm.h>
   95 #ifdef KTRACE
   96 #include <sys/ktrace.h>
   97 #endif
   98 
   99 #ifdef INET
  100 #include <netinet/in.h>
  101 #endif
  102 
  103 #include <vm/vm.h>
  104 #include <vm/vm_param.h>
  105 #include <vm/pmap.h>
  106 #include <vm/vm_map.h>
  107 #include <vm/vm_object.h>
  108 #include <vm/vm_extern.h>
  109 
  110 #include <machine/cpu.h>
  111 #include <machine/elf.h>
  112 #ifdef __amd64__
  113 #include <machine/md_var.h>
  114 #endif
  115 
  116 #include <security/audit/audit.h>
  117 
  118 #include <compat/freebsd32/freebsd32_util.h>
  119 #include <compat/freebsd32/freebsd32.h>
  120 #include <compat/freebsd32/freebsd32_ipc.h>
  121 #include <compat/freebsd32/freebsd32_misc.h>
  122 #include <compat/freebsd32/freebsd32_signal.h>
  123 #include <compat/freebsd32/freebsd32_proto.h>
  124 
  125 FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD");
  126 
  127 struct ptrace_io_desc32 {
  128         int             piod_op;
  129         uint32_t        piod_offs;
  130         uint32_t        piod_addr;
  131         uint32_t        piod_len;
  132 };
  133 
  134 struct ptrace_sc_ret32 {
  135         uint32_t        sr_retval[2];
  136         int             sr_error;
  137 };
  138 
  139 struct ptrace_vm_entry32 {
  140         int             pve_entry;
  141         int             pve_timestamp;
  142         uint32_t        pve_start;
  143         uint32_t        pve_end;
  144         uint32_t        pve_offset;
  145         u_int           pve_prot;
  146         u_int           pve_pathlen;
  147         int32_t         pve_fileid;
  148         u_int           pve_fsid;
  149         uint32_t        pve_path;
  150 };
  151 
  152 #ifdef __amd64__
  153 CTASSERT(sizeof(struct timeval32) == 8);
  154 CTASSERT(sizeof(struct timespec32) == 8);
  155 CTASSERT(sizeof(struct itimerval32) == 16);
  156 CTASSERT(sizeof(struct bintime32) == 12);
  157 #endif
  158 CTASSERT(sizeof(struct statfs32) == 256);
  159 #ifdef __amd64__
  160 CTASSERT(sizeof(struct rusage32) == 72);
  161 #endif
  162 CTASSERT(sizeof(struct sigaltstack32) == 12);
  163 #ifdef __amd64__
  164 CTASSERT(sizeof(struct kevent32) == 56);
  165 #else
  166 CTASSERT(sizeof(struct kevent32) == 64);
  167 #endif
  168 CTASSERT(sizeof(struct iovec32) == 8);
  169 CTASSERT(sizeof(struct msghdr32) == 28);
  170 #ifdef __amd64__
  171 CTASSERT(sizeof(struct stat32) == 208);
  172 CTASSERT(sizeof(struct freebsd11_stat32) == 96);
  173 #endif
  174 CTASSERT(sizeof(struct sigaction32) == 24);
  175 
  176 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
  177 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
  178 static int freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
  179     int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp);
  180 
  181 void
  182 freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
  183 {
  184 
  185         TV_CP(*s, *s32, ru_utime);
  186         TV_CP(*s, *s32, ru_stime);
  187         CP(*s, *s32, ru_maxrss);
  188         CP(*s, *s32, ru_ixrss);
  189         CP(*s, *s32, ru_idrss);
  190         CP(*s, *s32, ru_isrss);
  191         CP(*s, *s32, ru_minflt);
  192         CP(*s, *s32, ru_majflt);
  193         CP(*s, *s32, ru_nswap);
  194         CP(*s, *s32, ru_inblock);
  195         CP(*s, *s32, ru_oublock);
  196         CP(*s, *s32, ru_msgsnd);
  197         CP(*s, *s32, ru_msgrcv);
  198         CP(*s, *s32, ru_nsignals);
  199         CP(*s, *s32, ru_nvcsw);
  200         CP(*s, *s32, ru_nivcsw);
  201 }
  202 
  203 int
  204 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
  205 {
  206         int error, status;
  207         struct rusage32 ru32;
  208         struct rusage ru, *rup;
  209 
  210         if (uap->rusage != NULL)
  211                 rup = &ru;
  212         else
  213                 rup = NULL;
  214         error = kern_wait(td, uap->pid, &status, uap->options, rup);
  215         if (error)
  216                 return (error);
  217         if (uap->status != NULL)
  218                 error = copyout(&status, uap->status, sizeof(status));
  219         if (uap->rusage != NULL && error == 0) {
  220                 freebsd32_rusage_out(&ru, &ru32);
  221                 error = copyout(&ru32, uap->rusage, sizeof(ru32));
  222         }
  223         return (error);
  224 }
  225 
  226 int
  227 freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
  228 {
  229         struct wrusage32 wru32;
  230         struct __wrusage wru, *wrup;
  231         struct siginfo32 si32;
  232         struct __siginfo si, *sip;
  233         int error, status;
  234 
  235         if (uap->wrusage != NULL)
  236                 wrup = &wru;
  237         else
  238                 wrup = NULL;
  239         if (uap->info != NULL) {
  240                 sip = &si;
  241                 bzero(sip, sizeof(*sip));
  242         } else
  243                 sip = NULL;
  244         error = kern_wait6(td, uap->idtype, PAIR32TO64(id_t, uap->id),
  245             &status, uap->options, wrup, sip);
  246         if (error != 0)
  247                 return (error);
  248         if (uap->status != NULL)
  249                 error = copyout(&status, uap->status, sizeof(status));
  250         if (uap->wrusage != NULL && error == 0) {
  251                 freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
  252                 freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
  253                 error = copyout(&wru32, uap->wrusage, sizeof(wru32));
  254         }
  255         if (uap->info != NULL && error == 0) {
  256                 siginfo_to_siginfo32 (&si, &si32);
  257                 error = copyout(&si32, uap->info, sizeof(si32));
  258         }
  259         return (error);
  260 }
  261 
  262 #ifdef COMPAT_FREEBSD4
  263 static void
  264 copy_statfs(struct statfs *in, struct statfs32 *out)
  265 {
  266 
  267         statfs_scale_blocks(in, INT32_MAX);
  268         bzero(out, sizeof(*out));
  269         CP(*in, *out, f_bsize);
  270         out->f_iosize = MIN(in->f_iosize, INT32_MAX);
  271         CP(*in, *out, f_blocks);
  272         CP(*in, *out, f_bfree);
  273         CP(*in, *out, f_bavail);
  274         out->f_files = MIN(in->f_files, INT32_MAX);
  275         out->f_ffree = MIN(in->f_ffree, INT32_MAX);
  276         CP(*in, *out, f_fsid);
  277         CP(*in, *out, f_owner);
  278         CP(*in, *out, f_type);
  279         CP(*in, *out, f_flags);
  280         out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX);
  281         out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX);
  282         strlcpy(out->f_fstypename,
  283               in->f_fstypename, MFSNAMELEN);
  284         strlcpy(out->f_mntonname,
  285               in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  286         out->f_syncreads = MIN(in->f_syncreads, INT32_MAX);
  287         out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX);
  288         strlcpy(out->f_mntfromname,
  289               in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  290 }
  291 #endif
  292 
  293 #ifdef COMPAT_FREEBSD4
  294 int
  295 freebsd4_freebsd32_getfsstat(struct thread *td,
  296     struct freebsd4_freebsd32_getfsstat_args *uap)
  297 {
  298         struct statfs *buf, *sp;
  299         struct statfs32 stat32;
  300         size_t count, size, copycount;
  301         int error;
  302 
  303         count = uap->bufsize / sizeof(struct statfs32);
  304         size = count * sizeof(struct statfs);
  305         error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode);
  306         if (size > 0) {
  307                 sp = buf;
  308                 copycount = count;
  309                 while (copycount > 0 && error == 0) {
  310                         copy_statfs(sp, &stat32);
  311                         error = copyout(&stat32, uap->buf, sizeof(stat32));
  312                         sp++;
  313                         uap->buf++;
  314                         copycount--;
  315                 }
  316                 free(buf, M_STATFS);
  317         }
  318         if (error == 0)
  319                 td->td_retval[0] = count;
  320         return (error);
  321 }
  322 #endif
  323 
  324 #ifdef COMPAT_FREEBSD10
  325 int
  326 freebsd10_freebsd32_pipe(struct thread *td,
  327     struct freebsd10_freebsd32_pipe_args *uap) {
  328         return (freebsd10_pipe(td, (struct freebsd10_pipe_args*)uap));
  329 }
  330 #endif
  331 
  332 int
  333 freebsd32_sigaltstack(struct thread *td,
  334                       struct freebsd32_sigaltstack_args *uap)
  335 {
  336         struct sigaltstack32 s32;
  337         struct sigaltstack ss, oss, *ssp;
  338         int error;
  339 
  340         if (uap->ss != NULL) {
  341                 error = copyin(uap->ss, &s32, sizeof(s32));
  342                 if (error)
  343                         return (error);
  344                 PTRIN_CP(s32, ss, ss_sp);
  345                 CP(s32, ss, ss_size);
  346                 CP(s32, ss, ss_flags);
  347                 ssp = &ss;
  348         } else
  349                 ssp = NULL;
  350         error = kern_sigaltstack(td, ssp, &oss);
  351         if (error == 0 && uap->oss != NULL) {
  352                 PTROUT_CP(oss, s32, ss_sp);
  353                 CP(oss, s32, ss_size);
  354                 CP(oss, s32, ss_flags);
  355                 error = copyout(&s32, uap->oss, sizeof(s32));
  356         }
  357         return (error);
  358 }
  359 
  360 /*
  361  * Custom version of exec_copyin_args() so that we can translate
  362  * the pointers.
  363  */
  364 int
  365 freebsd32_exec_copyin_args(struct image_args *args, const char *fname,
  366     enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
  367 {
  368         char *argp, *envp;
  369         u_int32_t *p32, arg;
  370         int error;
  371 
  372         bzero(args, sizeof(*args));
  373         if (argv == NULL)
  374                 return (EFAULT);
  375 
  376         /*
  377          * Allocate demand-paged memory for the file name, argument, and
  378          * environment strings.
  379          */
  380         error = exec_alloc_args(args);
  381         if (error != 0)
  382                 return (error);
  383 
  384         /*
  385          * Copy the file name.
  386          */
  387         error = exec_args_add_fname(args, fname, segflg);
  388         if (error != 0)
  389                 goto err_exit;
  390 
  391         /*
  392          * extract arguments first
  393          */
  394         p32 = argv;
  395         for (;;) {
  396                 error = copyin(p32++, &arg, sizeof(arg));
  397                 if (error)
  398                         goto err_exit;
  399                 if (arg == 0)
  400                         break;
  401                 argp = PTRIN(arg);
  402                 error = exec_args_add_arg(args, argp, UIO_USERSPACE);
  403                 if (error != 0)
  404                         goto err_exit;
  405         }
  406                         
  407         /*
  408          * extract environment strings
  409          */
  410         if (envv) {
  411                 p32 = envv;
  412                 for (;;) {
  413                         error = copyin(p32++, &arg, sizeof(arg));
  414                         if (error)
  415                                 goto err_exit;
  416                         if (arg == 0)
  417                                 break;
  418                         envp = PTRIN(arg);
  419                         error = exec_args_add_env(args, envp, UIO_USERSPACE);
  420                         if (error != 0)
  421                                 goto err_exit;
  422                 }
  423         }
  424 
  425         return (0);
  426 
  427 err_exit:
  428         exec_free_args(args);
  429         return (error);
  430 }
  431 
  432 int
  433 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
  434 {
  435         struct image_args eargs;
  436         struct vmspace *oldvmspace;
  437         int error;
  438 
  439         error = pre_execve(td, &oldvmspace);
  440         if (error != 0)
  441                 return (error);
  442         error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
  443             uap->argv, uap->envv);
  444         if (error == 0)
  445                 error = kern_execve(td, &eargs, NULL, oldvmspace);
  446         post_execve(td, error, oldvmspace);
  447         AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
  448         return (error);
  449 }
  450 
  451 int
  452 freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
  453 {
  454         struct image_args eargs;
  455         struct vmspace *oldvmspace;
  456         int error;
  457 
  458         error = pre_execve(td, &oldvmspace);
  459         if (error != 0)
  460                 return (error);
  461         error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE,
  462             uap->argv, uap->envv);
  463         if (error == 0) {
  464                 eargs.fd = uap->fd;
  465                 error = kern_execve(td, &eargs, NULL, oldvmspace);
  466         }
  467         post_execve(td, error, oldvmspace);
  468         AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
  469         return (error);
  470 }
  471 
  472 int
  473 freebsd32_mknodat(struct thread *td, struct freebsd32_mknodat_args *uap)
  474 {
  475 
  476         return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE,
  477             uap->mode, PAIR32TO64(dev_t, uap->dev)));
  478 }
  479 
  480 int
  481 freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
  482 {
  483         int prot;
  484 
  485         prot = uap->prot;
  486 #if defined(__amd64__)
  487         if (i386_read_exec && (prot & PROT_READ) != 0)
  488                 prot |= PROT_EXEC;
  489 #endif
  490         return (kern_mprotect(td, (uintptr_t)PTRIN(uap->addr), uap->len,
  491             prot));
  492 }
  493 
  494 int
  495 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
  496 {
  497         int prot;
  498 
  499         prot = uap->prot;
  500 #if defined(__amd64__)
  501         if (i386_read_exec && (prot & PROT_READ))
  502                 prot |= PROT_EXEC;
  503 #endif
  504 
  505         return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot,
  506             uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos)));
  507 }
  508 
  509 #ifdef COMPAT_FREEBSD6
  510 int
  511 freebsd6_freebsd32_mmap(struct thread *td,
  512     struct freebsd6_freebsd32_mmap_args *uap)
  513 {
  514         int prot;
  515 
  516         prot = uap->prot;
  517 #if defined(__amd64__)
  518         if (i386_read_exec && (prot & PROT_READ))
  519                 prot |= PROT_EXEC;
  520 #endif
  521 
  522         return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot,
  523             uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos)));
  524 }
  525 #endif
  526 
  527 int
  528 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
  529 {
  530         struct itimerval itv, oitv, *itvp;      
  531         struct itimerval32 i32;
  532         int error;
  533 
  534         if (uap->itv != NULL) {
  535                 error = copyin(uap->itv, &i32, sizeof(i32));
  536                 if (error)
  537                         return (error);
  538                 TV_CP(i32, itv, it_interval);
  539                 TV_CP(i32, itv, it_value);
  540                 itvp = &itv;
  541         } else
  542                 itvp = NULL;
  543         error = kern_setitimer(td, uap->which, itvp, &oitv);
  544         if (error || uap->oitv == NULL)
  545                 return (error);
  546         TV_CP(oitv, i32, it_interval);
  547         TV_CP(oitv, i32, it_value);
  548         return (copyout(&i32, uap->oitv, sizeof(i32)));
  549 }
  550 
  551 int
  552 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
  553 {
  554         struct itimerval itv;
  555         struct itimerval32 i32;
  556         int error;
  557 
  558         error = kern_getitimer(td, uap->which, &itv);
  559         if (error || uap->itv == NULL)
  560                 return (error);
  561         TV_CP(itv, i32, it_interval);
  562         TV_CP(itv, i32, it_value);
  563         return (copyout(&i32, uap->itv, sizeof(i32)));
  564 }
  565 
  566 int
  567 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
  568 {
  569         struct timeval32 tv32;
  570         struct timeval tv, *tvp;
  571         int error;
  572 
  573         if (uap->tv != NULL) {
  574                 error = copyin(uap->tv, &tv32, sizeof(tv32));
  575                 if (error)
  576                         return (error);
  577                 CP(tv32, tv, tv_sec);
  578                 CP(tv32, tv, tv_usec);
  579                 tvp = &tv;
  580         } else
  581                 tvp = NULL;
  582         /*
  583          * XXX Do pointers need PTRIN()?
  584          */
  585         return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
  586             sizeof(int32_t) * 8));
  587 }
  588 
  589 int
  590 freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
  591 {
  592         struct timespec32 ts32;
  593         struct timespec ts;
  594         struct timeval tv, *tvp;
  595         sigset_t set, *uset;
  596         int error;
  597 
  598         if (uap->ts != NULL) {
  599                 error = copyin(uap->ts, &ts32, sizeof(ts32));
  600                 if (error != 0)
  601                         return (error);
  602                 CP(ts32, ts, tv_sec);
  603                 CP(ts32, ts, tv_nsec);
  604                 TIMESPEC_TO_TIMEVAL(&tv, &ts);
  605                 tvp = &tv;
  606         } else
  607                 tvp = NULL;
  608         if (uap->sm != NULL) {
  609                 error = copyin(uap->sm, &set, sizeof(set));
  610                 if (error != 0)
  611                         return (error);
  612                 uset = &set;
  613         } else
  614                 uset = NULL;
  615         /*
  616          * XXX Do pointers need PTRIN()?
  617          */
  618         error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
  619             uset, sizeof(int32_t) * 8);
  620         return (error);
  621 }
  622 
  623 /*
  624  * Copy 'count' items into the destination list pointed to by uap->eventlist.
  625  */
  626 static int
  627 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
  628 {
  629         struct freebsd32_kevent_args *uap;
  630         struct kevent32 ks32[KQ_NEVENTS];
  631         uint64_t e;
  632         int i, j, error;
  633 
  634         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  635         uap = (struct freebsd32_kevent_args *)arg;
  636 
  637         for (i = 0; i < count; i++) {
  638                 CP(kevp[i], ks32[i], ident);
  639                 CP(kevp[i], ks32[i], filter);
  640                 CP(kevp[i], ks32[i], flags);
  641                 CP(kevp[i], ks32[i], fflags);
  642 #if BYTE_ORDER == LITTLE_ENDIAN
  643                 ks32[i].data1 = kevp[i].data;
  644                 ks32[i].data2 = kevp[i].data >> 32;
  645 #else
  646                 ks32[i].data1 = kevp[i].data >> 32;
  647                 ks32[i].data2 = kevp[i].data;
  648 #endif
  649                 PTROUT_CP(kevp[i], ks32[i], udata);
  650                 for (j = 0; j < nitems(kevp->ext); j++) {
  651                         e = kevp[i].ext[j];
  652 #if BYTE_ORDER == LITTLE_ENDIAN
  653                         ks32[i].ext64[2 * j] = e;
  654                         ks32[i].ext64[2 * j + 1] = e >> 32;
  655 #else
  656                         ks32[i].ext64[2 * j] = e >> 32;
  657                         ks32[i].ext64[2 * j + 1] = e;
  658 #endif
  659                 }
  660         }
  661         error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
  662         if (error == 0)
  663                 uap->eventlist += count;
  664         return (error);
  665 }
  666 
  667 /*
  668  * Copy 'count' items from the list pointed to by uap->changelist.
  669  */
  670 static int
  671 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
  672 {
  673         struct freebsd32_kevent_args *uap;
  674         struct kevent32 ks32[KQ_NEVENTS];
  675         uint64_t e;
  676         int i, j, error;
  677 
  678         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  679         uap = (struct freebsd32_kevent_args *)arg;
  680 
  681         error = copyin(uap->changelist, ks32, count * sizeof *ks32);
  682         if (error)
  683                 goto done;
  684         uap->changelist += count;
  685 
  686         for (i = 0; i < count; i++) {
  687                 CP(ks32[i], kevp[i], ident);
  688                 CP(ks32[i], kevp[i], filter);
  689                 CP(ks32[i], kevp[i], flags);
  690                 CP(ks32[i], kevp[i], fflags);
  691                 kevp[i].data = PAIR32TO64(uint64_t, ks32[i].data);
  692                 PTRIN_CP(ks32[i], kevp[i], udata);
  693                 for (j = 0; j < nitems(kevp->ext); j++) {
  694 #if BYTE_ORDER == LITTLE_ENDIAN
  695                         e = ks32[i].ext64[2 * j + 1];
  696                         e <<= 32;
  697                         e += ks32[i].ext64[2 * j];
  698 #else
  699                         e = ks32[i].ext64[2 * j];
  700                         e <<= 32;
  701                         e += ks32[i].ext64[2 * j + 1];
  702 #endif
  703                         kevp[i].ext[j] = e;
  704                 }
  705         }
  706 done:
  707         return (error);
  708 }
  709 
  710 int
  711 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
  712 {
  713         struct timespec32 ts32;
  714         struct timespec ts, *tsp;
  715         struct kevent_copyops k_ops = {
  716                 .arg = uap,
  717                 .k_copyout = freebsd32_kevent_copyout,
  718                 .k_copyin = freebsd32_kevent_copyin,
  719         };
  720 #ifdef KTRACE
  721         struct kevent32 *eventlist = uap->eventlist;
  722 #endif
  723         int error;
  724 
  725         if (uap->timeout) {
  726                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
  727                 if (error)
  728                         return (error);
  729                 CP(ts32, ts, tv_sec);
  730                 CP(ts32, ts, tv_nsec);
  731                 tsp = &ts;
  732         } else
  733                 tsp = NULL;
  734 #ifdef KTRACE
  735         if (KTRPOINT(td, KTR_STRUCT_ARRAY))
  736                 ktrstructarray("kevent32", UIO_USERSPACE, uap->changelist,
  737                     uap->nchanges, sizeof(struct kevent32));
  738 #endif
  739         error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
  740             &k_ops, tsp);
  741 #ifdef KTRACE
  742         if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY))
  743                 ktrstructarray("kevent32", UIO_USERSPACE, eventlist,
  744                     td->td_retval[0], sizeof(struct kevent32));
  745 #endif
  746         return (error);
  747 }
  748 
  749 #ifdef COMPAT_FREEBSD11
  750 static int
  751 freebsd32_kevent11_copyout(void *arg, struct kevent *kevp, int count)
  752 {
  753         struct freebsd11_freebsd32_kevent_args *uap;
  754         struct kevent32_freebsd11 ks32[KQ_NEVENTS];
  755         int i, error;
  756 
  757         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  758         uap = (struct freebsd11_freebsd32_kevent_args *)arg;
  759 
  760         for (i = 0; i < count; i++) {
  761                 CP(kevp[i], ks32[i], ident);
  762                 CP(kevp[i], ks32[i], filter);
  763                 CP(kevp[i], ks32[i], flags);
  764                 CP(kevp[i], ks32[i], fflags);
  765                 CP(kevp[i], ks32[i], data);
  766                 PTROUT_CP(kevp[i], ks32[i], udata);
  767         }
  768         error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
  769         if (error == 0)
  770                 uap->eventlist += count;
  771         return (error);
  772 }
  773 
  774 /*
  775  * Copy 'count' items from the list pointed to by uap->changelist.
  776  */
  777 static int
  778 freebsd32_kevent11_copyin(void *arg, struct kevent *kevp, int count)
  779 {
  780         struct freebsd11_freebsd32_kevent_args *uap;
  781         struct kevent32_freebsd11 ks32[KQ_NEVENTS];
  782         int i, j, error;
  783 
  784         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  785         uap = (struct freebsd11_freebsd32_kevent_args *)arg;
  786 
  787         error = copyin(uap->changelist, ks32, count * sizeof *ks32);
  788         if (error)
  789                 goto done;
  790         uap->changelist += count;
  791 
  792         for (i = 0; i < count; i++) {
  793                 CP(ks32[i], kevp[i], ident);
  794                 CP(ks32[i], kevp[i], filter);
  795                 CP(ks32[i], kevp[i], flags);
  796                 CP(ks32[i], kevp[i], fflags);
  797                 CP(ks32[i], kevp[i], data);
  798                 PTRIN_CP(ks32[i], kevp[i], udata);
  799                 for (j = 0; j < nitems(kevp->ext); j++)
  800                         kevp[i].ext[j] = 0;
  801         }
  802 done:
  803         return (error);
  804 }
  805 
  806 int
  807 freebsd11_freebsd32_kevent(struct thread *td,
  808     struct freebsd11_freebsd32_kevent_args *uap)
  809 {
  810         struct timespec32 ts32;
  811         struct timespec ts, *tsp;
  812         struct kevent_copyops k_ops = {
  813                 .arg = uap,
  814                 .k_copyout = freebsd32_kevent11_copyout,
  815                 .k_copyin = freebsd32_kevent11_copyin,
  816         };
  817 #ifdef KTRACE
  818         struct kevent32_freebsd11 *eventlist = uap->eventlist;
  819 #endif
  820         int error;
  821 
  822         if (uap->timeout) {
  823                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
  824                 if (error)
  825                         return (error);
  826                 CP(ts32, ts, tv_sec);
  827                 CP(ts32, ts, tv_nsec);
  828                 tsp = &ts;
  829         } else
  830                 tsp = NULL;
  831 #ifdef KTRACE
  832         if (KTRPOINT(td, KTR_STRUCT_ARRAY))
  833                 ktrstructarray("kevent32_freebsd11", UIO_USERSPACE,
  834                     uap->changelist, uap->nchanges,
  835                     sizeof(struct kevent32_freebsd11));
  836 #endif
  837         error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
  838             &k_ops, tsp);
  839 #ifdef KTRACE
  840         if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY))
  841                 ktrstructarray("kevent32_freebsd11", UIO_USERSPACE,
  842                     eventlist, td->td_retval[0],
  843                     sizeof(struct kevent32_freebsd11));
  844 #endif
  845         return (error);
  846 }
  847 #endif
  848 
  849 int
  850 freebsd32_gettimeofday(struct thread *td,
  851                        struct freebsd32_gettimeofday_args *uap)
  852 {
  853         struct timeval atv;
  854         struct timeval32 atv32;
  855         struct timezone rtz;
  856         int error = 0;
  857 
  858         if (uap->tp) {
  859                 microtime(&atv);
  860                 CP(atv, atv32, tv_sec);
  861                 CP(atv, atv32, tv_usec);
  862                 error = copyout(&atv32, uap->tp, sizeof (atv32));
  863         }
  864         if (error == 0 && uap->tzp != NULL) {
  865                 rtz.tz_minuteswest = 0;
  866                 rtz.tz_dsttime = 0;
  867                 error = copyout(&rtz, uap->tzp, sizeof (rtz));
  868         }
  869         return (error);
  870 }
  871 
  872 int
  873 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
  874 {
  875         struct rusage32 s32;
  876         struct rusage s;
  877         int error;
  878 
  879         error = kern_getrusage(td, uap->who, &s);
  880         if (error == 0) {
  881                 freebsd32_rusage_out(&s, &s32);
  882                 error = copyout(&s32, uap->rusage, sizeof(s32));
  883         }
  884         return (error);
  885 }
  886 
  887 static void
  888 ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
  889     struct ptrace_lwpinfo32 *pl32)
  890 {
  891 
  892         bzero(pl32, sizeof(*pl32));
  893         pl32->pl_lwpid = pl->pl_lwpid;
  894         pl32->pl_event = pl->pl_event;
  895         pl32->pl_flags = pl->pl_flags;
  896         pl32->pl_sigmask = pl->pl_sigmask;
  897         pl32->pl_siglist = pl->pl_siglist;
  898         siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
  899         strcpy(pl32->pl_tdname, pl->pl_tdname);
  900         pl32->pl_child_pid = pl->pl_child_pid;
  901         pl32->pl_syscall_code = pl->pl_syscall_code;
  902         pl32->pl_syscall_narg = pl->pl_syscall_narg;
  903 }
  904 
  905 static void
  906 ptrace_sc_ret_to32(const struct ptrace_sc_ret *psr,
  907     struct ptrace_sc_ret32 *psr32)
  908 {
  909 
  910         bzero(psr32, sizeof(*psr32));
  911         psr32->sr_retval[0] = psr->sr_retval[0];
  912         psr32->sr_retval[1] = psr->sr_retval[1];
  913         psr32->sr_error = psr->sr_error;
  914 }
  915 
  916 int
  917 freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
  918 {
  919         union {
  920                 struct ptrace_io_desc piod;
  921                 struct ptrace_lwpinfo pl;
  922                 struct ptrace_vm_entry pve;
  923                 struct dbreg32 dbreg;
  924                 struct fpreg32 fpreg;
  925                 struct reg32 reg;
  926                 register_t args[nitems(td->td_sa.args)];
  927                 struct ptrace_sc_ret psr;
  928                 int ptevents;
  929         } r;
  930         union {
  931                 struct ptrace_io_desc32 piod;
  932                 struct ptrace_lwpinfo32 pl;
  933                 struct ptrace_vm_entry32 pve;
  934                 uint32_t args[nitems(td->td_sa.args)];
  935                 struct ptrace_sc_ret32 psr;
  936         } r32;
  937         void *addr;
  938         int data, error = 0, i;
  939 
  940         AUDIT_ARG_PID(uap->pid);
  941         AUDIT_ARG_CMD(uap->req);
  942         AUDIT_ARG_VALUE(uap->data);
  943         addr = &r;
  944         data = uap->data;
  945         switch (uap->req) {
  946         case PT_GET_EVENT_MASK:
  947         case PT_GET_SC_ARGS:
  948         case PT_GET_SC_RET:
  949                 break;
  950         case PT_LWPINFO:
  951                 if (uap->data > sizeof(r32.pl))
  952                         return (EINVAL);
  953 
  954                 /*
  955                  * Pass size of native structure in 'data'.  Truncate
  956                  * if necessary to avoid siginfo.
  957                  */
  958                 data = sizeof(r.pl);
  959                 if (uap->data < offsetof(struct ptrace_lwpinfo32, pl_siginfo) +
  960                     sizeof(struct siginfo32))
  961                         data = offsetof(struct ptrace_lwpinfo, pl_siginfo);
  962                 break;
  963         case PT_GETREGS:
  964                 bzero(&r.reg, sizeof(r.reg));
  965                 break;
  966         case PT_GETFPREGS:
  967                 bzero(&r.fpreg, sizeof(r.fpreg));
  968                 break;
  969         case PT_GETDBREGS:
  970                 bzero(&r.dbreg, sizeof(r.dbreg));
  971                 break;
  972         case PT_SETREGS:
  973                 error = copyin(uap->addr, &r.reg, sizeof(r.reg));
  974                 break;
  975         case PT_SETFPREGS:
  976                 error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg));
  977                 break;
  978         case PT_SETDBREGS:
  979                 error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg));
  980                 break;
  981         case PT_SET_EVENT_MASK:
  982                 if (uap->data != sizeof(r.ptevents))
  983                         error = EINVAL;
  984                 else
  985                         error = copyin(uap->addr, &r.ptevents, uap->data);
  986                 break;
  987         case PT_IO:
  988                 error = copyin(uap->addr, &r32.piod, sizeof(r32.piod));
  989                 if (error)
  990                         break;
  991                 CP(r32.piod, r.piod, piod_op);
  992                 PTRIN_CP(r32.piod, r.piod, piod_offs);
  993                 PTRIN_CP(r32.piod, r.piod, piod_addr);
  994                 CP(r32.piod, r.piod, piod_len);
  995                 break;
  996         case PT_VM_ENTRY:
  997                 error = copyin(uap->addr, &r32.pve, sizeof(r32.pve));
  998                 if (error)
  999                         break;
 1000 
 1001                 CP(r32.pve, r.pve, pve_entry);
 1002                 CP(r32.pve, r.pve, pve_timestamp);
 1003                 CP(r32.pve, r.pve, pve_start);
 1004                 CP(r32.pve, r.pve, pve_end);
 1005                 CP(r32.pve, r.pve, pve_offset);
 1006                 CP(r32.pve, r.pve, pve_prot);
 1007                 CP(r32.pve, r.pve, pve_pathlen);
 1008                 CP(r32.pve, r.pve, pve_fileid);
 1009                 CP(r32.pve, r.pve, pve_fsid);
 1010                 PTRIN_CP(r32.pve, r.pve, pve_path);
 1011                 break;
 1012         default:
 1013                 addr = uap->addr;
 1014                 break;
 1015         }
 1016         if (error)
 1017                 return (error);
 1018 
 1019         error = kern_ptrace(td, uap->req, uap->pid, addr, data);
 1020         if (error)
 1021                 return (error);
 1022 
 1023         switch (uap->req) {
 1024         case PT_VM_ENTRY:
 1025                 CP(r.pve, r32.pve, pve_entry);
 1026                 CP(r.pve, r32.pve, pve_timestamp);
 1027                 CP(r.pve, r32.pve, pve_start);
 1028                 CP(r.pve, r32.pve, pve_end);
 1029                 CP(r.pve, r32.pve, pve_offset);
 1030                 CP(r.pve, r32.pve, pve_prot);
 1031                 CP(r.pve, r32.pve, pve_pathlen);
 1032                 CP(r.pve, r32.pve, pve_fileid);
 1033                 CP(r.pve, r32.pve, pve_fsid);
 1034                 error = copyout(&r32.pve, uap->addr, sizeof(r32.pve));
 1035                 break;
 1036         case PT_IO:
 1037                 CP(r.piod, r32.piod, piod_len);
 1038                 error = copyout(&r32.piod, uap->addr, sizeof(r32.piod));
 1039                 break;
 1040         case PT_GETREGS:
 1041                 error = copyout(&r.reg, uap->addr, sizeof(r.reg));
 1042                 break;
 1043         case PT_GETFPREGS:
 1044                 error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg));
 1045                 break;
 1046         case PT_GETDBREGS:
 1047                 error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg));
 1048                 break;
 1049         case PT_GET_EVENT_MASK:
 1050                 /* NB: The size in uap->data is validated in kern_ptrace(). */
 1051                 error = copyout(&r.ptevents, uap->addr, uap->data);
 1052                 break;
 1053         case PT_LWPINFO:
 1054                 ptrace_lwpinfo_to32(&r.pl, &r32.pl);
 1055                 error = copyout(&r32.pl, uap->addr, uap->data);
 1056                 break;
 1057         case PT_GET_SC_ARGS:
 1058                 for (i = 0; i < nitems(r.args); i++)
 1059                         r32.args[i] = (uint32_t)r.args[i];
 1060                 error = copyout(r32.args, uap->addr, MIN(uap->data,
 1061                     sizeof(r32.args)));
 1062                 break;
 1063         case PT_GET_SC_RET:
 1064                 ptrace_sc_ret_to32(&r.psr, &r32.psr);
 1065                 error = copyout(&r32.psr, uap->addr, MIN(uap->data,
 1066                     sizeof(r32.psr)));
 1067                 break;
 1068         }
 1069 
 1070         return (error);
 1071 }
 1072 
 1073 int
 1074 freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
 1075 {
 1076         struct iovec32 iov32;
 1077         struct iovec *iov;
 1078         struct uio *uio;
 1079         u_int iovlen;
 1080         int error, i;
 1081 
 1082         *uiop = NULL;
 1083         if (iovcnt > UIO_MAXIOV)
 1084                 return (EINVAL);
 1085         iovlen = iovcnt * sizeof(struct iovec);
 1086         uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
 1087         iov = (struct iovec *)(uio + 1);
 1088         for (i = 0; i < iovcnt; i++) {
 1089                 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
 1090                 if (error) {
 1091                         free(uio, M_IOV);
 1092                         return (error);
 1093                 }
 1094                 iov[i].iov_base = PTRIN(iov32.iov_base);
 1095                 iov[i].iov_len = iov32.iov_len;
 1096         }
 1097         uio->uio_iov = iov;
 1098         uio->uio_iovcnt = iovcnt;
 1099         uio->uio_segflg = UIO_USERSPACE;
 1100         uio->uio_offset = -1;
 1101         uio->uio_resid = 0;
 1102         for (i = 0; i < iovcnt; i++) {
 1103                 if (iov->iov_len > INT_MAX - uio->uio_resid) {
 1104                         free(uio, M_IOV);
 1105                         return (EINVAL);
 1106                 }
 1107                 uio->uio_resid += iov->iov_len;
 1108                 iov++;
 1109         }
 1110         *uiop = uio;
 1111         return (0);
 1112 }
 1113 
 1114 int
 1115 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
 1116 {
 1117         struct uio *auio;
 1118         int error;
 1119 
 1120         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 1121         if (error)
 1122                 return (error);
 1123         error = kern_readv(td, uap->fd, auio);
 1124         free(auio, M_IOV);
 1125         return (error);
 1126 }
 1127 
 1128 int
 1129 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
 1130 {
 1131         struct uio *auio;
 1132         int error;
 1133 
 1134         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 1135         if (error)
 1136                 return (error);
 1137         error = kern_writev(td, uap->fd, auio);
 1138         free(auio, M_IOV);
 1139         return (error);
 1140 }
 1141 
 1142 int
 1143 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
 1144 {
 1145         struct uio *auio;
 1146         int error;
 1147 
 1148         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 1149         if (error)
 1150                 return (error);
 1151         error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
 1152         free(auio, M_IOV);
 1153         return (error);
 1154 }
 1155 
 1156 int
 1157 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
 1158 {
 1159         struct uio *auio;
 1160         int error;
 1161 
 1162         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 1163         if (error)
 1164                 return (error);
 1165         error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
 1166         free(auio, M_IOV);
 1167         return (error);
 1168 }
 1169 
 1170 int
 1171 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
 1172     int error)
 1173 {
 1174         struct iovec32 iov32;
 1175         struct iovec *iov;
 1176         u_int iovlen;
 1177         int i;
 1178 
 1179         *iovp = NULL;
 1180         if (iovcnt > UIO_MAXIOV)
 1181                 return (error);
 1182         iovlen = iovcnt * sizeof(struct iovec);
 1183         iov = malloc(iovlen, M_IOV, M_WAITOK);
 1184         for (i = 0; i < iovcnt; i++) {
 1185                 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
 1186                 if (error) {
 1187                         free(iov, M_IOV);
 1188                         return (error);
 1189                 }
 1190                 iov[i].iov_base = PTRIN(iov32.iov_base);
 1191                 iov[i].iov_len = iov32.iov_len;
 1192         }
 1193         *iovp = iov;
 1194         return (0);
 1195 }
 1196 
 1197 static int
 1198 freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
 1199 {
 1200         struct msghdr32 m32;
 1201         int error;
 1202 
 1203         error = copyin(msg32, &m32, sizeof(m32));
 1204         if (error)
 1205                 return (error);
 1206         msg->msg_name = PTRIN(m32.msg_name);
 1207         msg->msg_namelen = m32.msg_namelen;
 1208         msg->msg_iov = PTRIN(m32.msg_iov);
 1209         msg->msg_iovlen = m32.msg_iovlen;
 1210         msg->msg_control = PTRIN(m32.msg_control);
 1211         msg->msg_controllen = m32.msg_controllen;
 1212         msg->msg_flags = m32.msg_flags;
 1213         return (0);
 1214 }
 1215 
 1216 static int
 1217 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
 1218 {
 1219         struct msghdr32 m32;
 1220         int error;
 1221 
 1222         m32.msg_name = PTROUT(msg->msg_name);
 1223         m32.msg_namelen = msg->msg_namelen;
 1224         m32.msg_iov = PTROUT(msg->msg_iov);
 1225         m32.msg_iovlen = msg->msg_iovlen;
 1226         m32.msg_control = PTROUT(msg->msg_control);
 1227         m32.msg_controllen = msg->msg_controllen;
 1228         m32.msg_flags = msg->msg_flags;
 1229         error = copyout(&m32, msg32, sizeof(m32));
 1230         return (error);
 1231 }
 1232 
 1233 #ifndef __mips__
 1234 #define FREEBSD32_ALIGNBYTES    (sizeof(int) - 1)
 1235 #else
 1236 #define FREEBSD32_ALIGNBYTES    (sizeof(long) - 1)
 1237 #endif
 1238 #define FREEBSD32_ALIGN(p)      \
 1239         (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
 1240 #define FREEBSD32_CMSG_SPACE(l) \
 1241         (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
 1242 
 1243 #define FREEBSD32_CMSG_DATA(cmsg)       ((unsigned char *)(cmsg) + \
 1244                                  FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
 1245 
 1246 static size_t
 1247 freebsd32_cmsg_convert(const struct cmsghdr *cm, void *data, socklen_t datalen)
 1248 {
 1249         size_t copylen;
 1250         union {
 1251                 struct timespec32 ts;
 1252                 struct timeval32 tv;
 1253                 struct bintime32 bt;
 1254         } tmp32;
 1255 
 1256         union {
 1257                 struct timespec ts;
 1258                 struct timeval tv;
 1259                 struct bintime bt;
 1260         } *in;
 1261 
 1262         in = data;
 1263         copylen = 0;
 1264         switch (cm->cmsg_level) {
 1265         case SOL_SOCKET:
 1266                 switch (cm->cmsg_type) {
 1267                 case SCM_TIMESTAMP:
 1268                         TV_CP(*in, tmp32, tv);
 1269                         copylen = sizeof(tmp32.tv);
 1270                         break;
 1271 
 1272                 case SCM_BINTIME:
 1273                         BT_CP(*in, tmp32, bt);
 1274                         copylen = sizeof(tmp32.bt);
 1275                         break;
 1276 
 1277                 case SCM_REALTIME:
 1278                 case SCM_MONOTONIC:
 1279                         TS_CP(*in, tmp32, ts);
 1280                         copylen = sizeof(tmp32.ts);
 1281                         break;
 1282 
 1283                 default:
 1284                         break;
 1285                 }
 1286 
 1287         default:
 1288                 break;
 1289         }
 1290 
 1291         if (copylen == 0)
 1292                 return (datalen);
 1293 
 1294         KASSERT((datalen >= copylen), ("corrupted cmsghdr"));
 1295 
 1296         bcopy(&tmp32, data, copylen);
 1297         return (copylen);
 1298 }
 1299 
 1300 static int
 1301 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
 1302 {
 1303         struct cmsghdr *cm;
 1304         void *data;
 1305         socklen_t clen, datalen, datalen_out, oldclen;
 1306         int error;
 1307         caddr_t ctlbuf;
 1308         int len, maxlen, copylen;
 1309         struct mbuf *m;
 1310         error = 0;
 1311 
 1312         len    = msg->msg_controllen;
 1313         maxlen = msg->msg_controllen;
 1314         msg->msg_controllen = 0;
 1315 
 1316         ctlbuf = msg->msg_control;
 1317         for (m = control; m != NULL && len > 0; m = m->m_next) {
 1318                 cm = mtod(m, struct cmsghdr *);
 1319                 clen = m->m_len;
 1320                 while (cm != NULL) {
 1321                         if (sizeof(struct cmsghdr) > clen ||
 1322                             cm->cmsg_len > clen) {
 1323                                 error = EINVAL;
 1324                                 break;
 1325                         }
 1326 
 1327                         data   = CMSG_DATA(cm);
 1328                         datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
 1329                         datalen_out = freebsd32_cmsg_convert(cm, data, datalen);
 1330 
 1331                         /*
 1332                          * Copy out the message header.  Preserve the native
 1333                          * message size in case we need to inspect the message
 1334                          * contents later.
 1335                          */
 1336                         copylen = sizeof(struct cmsghdr);
 1337                         if (len < copylen) {
 1338                                 msg->msg_flags |= MSG_CTRUNC;
 1339                                 m_dispose_extcontrolm(m);
 1340                                 goto exit;
 1341                         }
 1342                         oldclen = cm->cmsg_len;
 1343                         cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
 1344                             datalen_out;
 1345                         error = copyout(cm, ctlbuf, copylen);
 1346                         cm->cmsg_len = oldclen;
 1347                         if (error != 0)
 1348                                 goto exit;
 1349 
 1350                         ctlbuf += FREEBSD32_ALIGN(copylen);
 1351                         len    -= FREEBSD32_ALIGN(copylen);
 1352 
 1353                         copylen = datalen_out;
 1354                         if (len < copylen) {
 1355                                 msg->msg_flags |= MSG_CTRUNC;
 1356                                 m_dispose_extcontrolm(m);
 1357                                 break;
 1358                         }
 1359 
 1360                         /* Copy out the message data. */
 1361                         error = copyout(data, ctlbuf, copylen);
 1362                         if (error)
 1363                                 goto exit;
 1364 
 1365                         ctlbuf += FREEBSD32_ALIGN(copylen);
 1366                         len    -= FREEBSD32_ALIGN(copylen);
 1367 
 1368                         if (CMSG_SPACE(datalen) < clen) {
 1369                                 clen -= CMSG_SPACE(datalen);
 1370                                 cm = (struct cmsghdr *)
 1371                                     ((caddr_t)cm + CMSG_SPACE(datalen));
 1372                         } else {
 1373                                 clen = 0;
 1374                                 cm = NULL;
 1375                         }
 1376 
 1377                         msg->msg_controllen +=
 1378                             FREEBSD32_CMSG_SPACE(datalen_out);
 1379                 }
 1380         }
 1381         if (len == 0 && m != NULL) {
 1382                 msg->msg_flags |= MSG_CTRUNC;
 1383                 m_dispose_extcontrolm(m);
 1384         }
 1385 
 1386 exit:
 1387         return (error);
 1388 }
 1389 
 1390 int
 1391 freebsd32_recvmsg(td, uap)
 1392         struct thread *td;
 1393         struct freebsd32_recvmsg_args /* {
 1394                 int     s;
 1395                 struct  msghdr32 *msg;
 1396                 int     flags;
 1397         } */ *uap;
 1398 {
 1399         struct msghdr msg;
 1400         struct msghdr32 m32;
 1401         struct iovec *uiov, *iov;
 1402         struct mbuf *control = NULL;
 1403         struct mbuf **controlp;
 1404 
 1405         int error;
 1406         error = copyin(uap->msg, &m32, sizeof(m32));
 1407         if (error)
 1408                 return (error);
 1409         error = freebsd32_copyinmsghdr(uap->msg, &msg);
 1410         if (error)
 1411                 return (error);
 1412         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
 1413             EMSGSIZE);
 1414         if (error)
 1415                 return (error);
 1416         msg.msg_flags = uap->flags;
 1417         uiov = msg.msg_iov;
 1418         msg.msg_iov = iov;
 1419 
 1420         controlp = (msg.msg_control != NULL) ?  &control : NULL;
 1421         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
 1422         if (error == 0) {
 1423                 msg.msg_iov = uiov;
 1424 
 1425                 if (control != NULL)
 1426                         error = freebsd32_copy_msg_out(&msg, control);
 1427                 else
 1428                         msg.msg_controllen = 0;
 1429 
 1430                 if (error == 0)
 1431                         error = freebsd32_copyoutmsghdr(&msg, uap->msg);
 1432         }
 1433         free(iov, M_IOV);
 1434 
 1435         if (control != NULL) {
 1436                 if (error != 0)
 1437                         m_dispose_extcontrolm(control);
 1438                 m_freem(control);
 1439         }
 1440 
 1441         return (error);
 1442 }
 1443 
 1444 /*
 1445  * Copy-in the array of control messages constructed using alignment
 1446  * and padding suitable for a 32-bit environment and construct an
 1447  * mbuf using alignment and padding suitable for a 64-bit kernel.
 1448  * The alignment and padding are defined indirectly by CMSG_DATA(),
 1449  * CMSG_SPACE() and CMSG_LEN().
 1450  */
 1451 static int
 1452 freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
 1453 {
 1454         struct cmsghdr *cm;
 1455         struct mbuf *m;
 1456         void *in, *in1, *md;
 1457         u_int msglen, outlen;
 1458         int error;
 1459 
 1460         if (buflen > MCLBYTES)
 1461                 return (EINVAL);
 1462 
 1463         in = malloc(buflen, M_TEMP, M_WAITOK);
 1464         error = copyin(buf, in, buflen);
 1465         if (error != 0)
 1466                 goto out;
 1467 
 1468         /*
 1469          * Make a pass over the input buffer to determine the amount of space
 1470          * required for 64 bit-aligned copies of the control messages.
 1471          */
 1472         in1 = in;
 1473         outlen = 0;
 1474         while (buflen > 0) {
 1475                 if (buflen < sizeof(*cm)) {
 1476                         error = EINVAL;
 1477                         break;
 1478                 }
 1479                 cm = (struct cmsghdr *)in1;
 1480                 if (cm->cmsg_len < FREEBSD32_ALIGN(sizeof(*cm))) {
 1481                         error = EINVAL;
 1482                         break;
 1483                 }
 1484                 msglen = FREEBSD32_ALIGN(cm->cmsg_len);
 1485                 if (msglen > buflen || msglen < cm->cmsg_len) {
 1486                         error = EINVAL;
 1487                         break;
 1488                 }
 1489                 buflen -= msglen;
 1490 
 1491                 in1 = (char *)in1 + msglen;
 1492                 outlen += CMSG_ALIGN(sizeof(*cm)) +
 1493                     CMSG_ALIGN(msglen - FREEBSD32_ALIGN(sizeof(*cm)));
 1494         }
 1495         if (error == 0 && outlen > MCLBYTES) {
 1496                 /*
 1497                  * XXXMJ This implies that the upper limit on 32-bit aligned
 1498                  * control messages is less than MCLBYTES, and so we are not
 1499                  * perfectly compatible.  However, there is no platform
 1500                  * guarantee that mbuf clusters larger than MCLBYTES can be
 1501                  * allocated.
 1502                  */
 1503                 error = EINVAL;
 1504         }
 1505         if (error != 0)
 1506                 goto out;
 1507 
 1508         m = m_get2(outlen, M_WAITOK, MT_CONTROL, 0);
 1509         m->m_len = outlen;
 1510         md = mtod(m, void *);
 1511 
 1512         /*
 1513          * Make a second pass over input messages, copying them into the output
 1514          * buffer.
 1515          */
 1516         in1 = in;
 1517         while (outlen > 0) {
 1518                 /* Copy the message header and align the length field. */
 1519                 cm = md;
 1520                 memcpy(cm, in1, sizeof(*cm));
 1521                 msglen = cm->cmsg_len - FREEBSD32_ALIGN(sizeof(*cm));
 1522                 cm->cmsg_len = CMSG_ALIGN(sizeof(*cm)) + msglen;
 1523 
 1524                 /* Copy the message body. */
 1525                 in1 = (char *)in1 + FREEBSD32_ALIGN(sizeof(*cm));
 1526                 md = (char *)md + CMSG_ALIGN(sizeof(*cm));
 1527                 memcpy(md, in1, msglen);
 1528                 in1 = (char *)in1 + FREEBSD32_ALIGN(msglen);
 1529                 md = (char *)md + CMSG_ALIGN(msglen);
 1530                 KASSERT(outlen >= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen),
 1531                     ("outlen %u underflow, msglen %u", outlen, msglen));
 1532                 outlen -= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen);
 1533         }
 1534 
 1535         *mp = m;
 1536 out:
 1537         free(in, M_TEMP);
 1538         return (error);
 1539 }
 1540 
 1541 int
 1542 freebsd32_sendmsg(struct thread *td,
 1543                   struct freebsd32_sendmsg_args *uap)
 1544 {
 1545         struct msghdr msg;
 1546         struct msghdr32 m32;
 1547         struct iovec *iov;
 1548         struct mbuf *control = NULL;
 1549         struct sockaddr *to = NULL;
 1550         int error;
 1551 
 1552         error = copyin(uap->msg, &m32, sizeof(m32));
 1553         if (error)
 1554                 return (error);
 1555         error = freebsd32_copyinmsghdr(uap->msg, &msg);
 1556         if (error)
 1557                 return (error);
 1558         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
 1559             EMSGSIZE);
 1560         if (error)
 1561                 return (error);
 1562         msg.msg_iov = iov;
 1563         if (msg.msg_name != NULL) {
 1564                 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
 1565                 if (error) {
 1566                         to = NULL;
 1567                         goto out;
 1568                 }
 1569                 msg.msg_name = to;
 1570         }
 1571 
 1572         if (msg.msg_control) {
 1573                 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
 1574                         error = EINVAL;
 1575                         goto out;
 1576                 }
 1577 
 1578                 error = freebsd32_copyin_control(&control, msg.msg_control,
 1579                     msg.msg_controllen);
 1580                 if (error)
 1581                         goto out;
 1582 
 1583                 msg.msg_control = NULL;
 1584                 msg.msg_controllen = 0;
 1585         }
 1586 
 1587         error = kern_sendit(td, uap->s, &msg, uap->flags, control,
 1588             UIO_USERSPACE);
 1589 
 1590 out:
 1591         free(iov, M_IOV);
 1592         if (to)
 1593                 free(to, M_SONAME);
 1594         return (error);
 1595 }
 1596 
 1597 int
 1598 freebsd32_recvfrom(struct thread *td,
 1599                    struct freebsd32_recvfrom_args *uap)
 1600 {
 1601         struct msghdr msg;
 1602         struct iovec aiov;
 1603         int error;
 1604 
 1605         if (uap->fromlenaddr) {
 1606                 error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
 1607                     sizeof(msg.msg_namelen));
 1608                 if (error)
 1609                         return (error);
 1610         } else {
 1611                 msg.msg_namelen = 0;
 1612         }
 1613 
 1614         msg.msg_name = PTRIN(uap->from);
 1615         msg.msg_iov = &aiov;
 1616         msg.msg_iovlen = 1;
 1617         aiov.iov_base = PTRIN(uap->buf);
 1618         aiov.iov_len = uap->len;
 1619         msg.msg_control = NULL;
 1620         msg.msg_flags = uap->flags;
 1621         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
 1622         if (error == 0 && uap->fromlenaddr)
 1623                 error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
 1624                     sizeof (msg.msg_namelen));
 1625         return (error);
 1626 }
 1627 
 1628 int
 1629 freebsd32_settimeofday(struct thread *td,
 1630                        struct freebsd32_settimeofday_args *uap)
 1631 {
 1632         struct timeval32 tv32;
 1633         struct timeval tv, *tvp;
 1634         struct timezone tz, *tzp;
 1635         int error;
 1636 
 1637         if (uap->tv) {
 1638                 error = copyin(uap->tv, &tv32, sizeof(tv32));
 1639                 if (error)
 1640                         return (error);
 1641                 CP(tv32, tv, tv_sec);
 1642                 CP(tv32, tv, tv_usec);
 1643                 tvp = &tv;
 1644         } else
 1645                 tvp = NULL;
 1646         if (uap->tzp) {
 1647                 error = copyin(uap->tzp, &tz, sizeof(tz));
 1648                 if (error)
 1649                         return (error);
 1650                 tzp = &tz;
 1651         } else
 1652                 tzp = NULL;
 1653         return (kern_settimeofday(td, tvp, tzp));
 1654 }
 1655 
 1656 int
 1657 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
 1658 {
 1659         struct timeval32 s32[2];
 1660         struct timeval s[2], *sp;
 1661         int error;
 1662 
 1663         if (uap->tptr != NULL) {
 1664                 error = copyin(uap->tptr, s32, sizeof(s32));
 1665                 if (error)
 1666                         return (error);
 1667                 CP(s32[0], s[0], tv_sec);
 1668                 CP(s32[0], s[0], tv_usec);
 1669                 CP(s32[1], s[1], tv_sec);
 1670                 CP(s32[1], s[1], tv_usec);
 1671                 sp = s;
 1672         } else
 1673                 sp = NULL;
 1674         return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
 1675             sp, UIO_SYSSPACE));
 1676 }
 1677 
 1678 int
 1679 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
 1680 {
 1681         struct timeval32 s32[2];
 1682         struct timeval s[2], *sp;
 1683         int error;
 1684 
 1685         if (uap->tptr != NULL) {
 1686                 error = copyin(uap->tptr, s32, sizeof(s32));
 1687                 if (error)
 1688                         return (error);
 1689                 CP(s32[0], s[0], tv_sec);
 1690                 CP(s32[0], s[0], tv_usec);
 1691                 CP(s32[1], s[1], tv_sec);
 1692                 CP(s32[1], s[1], tv_usec);
 1693                 sp = s;
 1694         } else
 1695                 sp = NULL;
 1696         return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
 1697 }
 1698 
 1699 int
 1700 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
 1701 {
 1702         struct timeval32 s32[2];
 1703         struct timeval s[2], *sp;
 1704         int error;
 1705 
 1706         if (uap->tptr != NULL) {
 1707                 error = copyin(uap->tptr, s32, sizeof(s32));
 1708                 if (error)
 1709                         return (error);
 1710                 CP(s32[0], s[0], tv_sec);
 1711                 CP(s32[0], s[0], tv_usec);
 1712                 CP(s32[1], s[1], tv_sec);
 1713                 CP(s32[1], s[1], tv_usec);
 1714                 sp = s;
 1715         } else
 1716                 sp = NULL;
 1717         return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
 1718 }
 1719 
 1720 int
 1721 freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
 1722 {
 1723         struct timeval32 s32[2];
 1724         struct timeval s[2], *sp;
 1725         int error;
 1726 
 1727         if (uap->times != NULL) {
 1728                 error = copyin(uap->times, s32, sizeof(s32));
 1729                 if (error)
 1730                         return (error);
 1731                 CP(s32[0], s[0], tv_sec);
 1732                 CP(s32[0], s[0], tv_usec);
 1733                 CP(s32[1], s[1], tv_sec);
 1734                 CP(s32[1], s[1], tv_usec);
 1735                 sp = s;
 1736         } else
 1737                 sp = NULL;
 1738         return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
 1739                 sp, UIO_SYSSPACE));
 1740 }
 1741 
 1742 int
 1743 freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap)
 1744 {
 1745         struct timespec32 ts32[2];
 1746         struct timespec ts[2], *tsp;
 1747         int error;
 1748 
 1749         if (uap->times != NULL) {
 1750                 error = copyin(uap->times, ts32, sizeof(ts32));
 1751                 if (error)
 1752                         return (error);
 1753                 CP(ts32[0], ts[0], tv_sec);
 1754                 CP(ts32[0], ts[0], tv_nsec);
 1755                 CP(ts32[1], ts[1], tv_sec);
 1756                 CP(ts32[1], ts[1], tv_nsec);
 1757                 tsp = ts;
 1758         } else
 1759                 tsp = NULL;
 1760         return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE));
 1761 }
 1762 
 1763 int
 1764 freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap)
 1765 {
 1766         struct timespec32 ts32[2];
 1767         struct timespec ts[2], *tsp;
 1768         int error;
 1769 
 1770         if (uap->times != NULL) {
 1771                 error = copyin(uap->times, ts32, sizeof(ts32));
 1772                 if (error)
 1773                         return (error);
 1774                 CP(ts32[0], ts[0], tv_sec);
 1775                 CP(ts32[0], ts[0], tv_nsec);
 1776                 CP(ts32[1], ts[1], tv_sec);
 1777                 CP(ts32[1], ts[1], tv_nsec);
 1778                 tsp = ts;
 1779         } else
 1780                 tsp = NULL;
 1781         return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE,
 1782             tsp, UIO_SYSSPACE, uap->flag));
 1783 }
 1784 
 1785 int
 1786 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
 1787 {
 1788         struct timeval32 tv32;
 1789         struct timeval delta, olddelta, *deltap;
 1790         int error;
 1791 
 1792         if (uap->delta) {
 1793                 error = copyin(uap->delta, &tv32, sizeof(tv32));
 1794                 if (error)
 1795                         return (error);
 1796                 CP(tv32, delta, tv_sec);
 1797                 CP(tv32, delta, tv_usec);
 1798                 deltap = &delta;
 1799         } else
 1800                 deltap = NULL;
 1801         error = kern_adjtime(td, deltap, &olddelta);
 1802         if (uap->olddelta && error == 0) {
 1803                 CP(olddelta, tv32, tv_sec);
 1804                 CP(olddelta, tv32, tv_usec);
 1805                 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
 1806         }
 1807         return (error);
 1808 }
 1809 
 1810 #ifdef COMPAT_FREEBSD4
 1811 int
 1812 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
 1813 {
 1814         struct statfs32 s32;
 1815         struct statfs *sp;
 1816         int error;
 1817 
 1818         sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
 1819         error = kern_statfs(td, uap->path, UIO_USERSPACE, sp);
 1820         if (error == 0) {
 1821                 copy_statfs(sp, &s32);
 1822                 error = copyout(&s32, uap->buf, sizeof(s32));
 1823         }
 1824         free(sp, M_STATFS);
 1825         return (error);
 1826 }
 1827 #endif
 1828 
 1829 #ifdef COMPAT_FREEBSD4
 1830 int
 1831 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
 1832 {
 1833         struct statfs32 s32;
 1834         struct statfs *sp;
 1835         int error;
 1836 
 1837         sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
 1838         error = kern_fstatfs(td, uap->fd, sp);
 1839         if (error == 0) {
 1840                 copy_statfs(sp, &s32);
 1841                 error = copyout(&s32, uap->buf, sizeof(s32));
 1842         }
 1843         free(sp, M_STATFS);
 1844         return (error);
 1845 }
 1846 #endif
 1847 
 1848 #ifdef COMPAT_FREEBSD4
 1849 int
 1850 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
 1851 {
 1852         struct statfs32 s32;
 1853         struct statfs *sp;
 1854         fhandle_t fh;
 1855         int error;
 1856 
 1857         if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
 1858                 return (error);
 1859         sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
 1860         error = kern_fhstatfs(td, fh, sp);
 1861         if (error == 0) {
 1862                 copy_statfs(sp, &s32);
 1863                 error = copyout(&s32, uap->buf, sizeof(s32));
 1864         }
 1865         free(sp, M_STATFS);
 1866         return (error);
 1867 }
 1868 #endif
 1869 
 1870 int
 1871 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
 1872 {
 1873 
 1874         return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
 1875             PAIR32TO64(off_t, uap->offset)));
 1876 }
 1877 
 1878 int
 1879 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
 1880 {
 1881 
 1882         return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
 1883             PAIR32TO64(off_t, uap->offset)));
 1884 }
 1885 
 1886 #ifdef COMPAT_43
 1887 int
 1888 ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
 1889 {
 1890 
 1891         return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
 1892 }
 1893 #endif
 1894 
 1895 int
 1896 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
 1897 {
 1898         int error;
 1899         off_t pos;
 1900 
 1901         error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
 1902             uap->whence);
 1903         /* Expand the quad return into two parts for eax and edx */
 1904         pos = td->td_uretoff.tdu_off;
 1905         td->td_retval[RETVAL_LO] = pos & 0xffffffff;    /* %eax */
 1906         td->td_retval[RETVAL_HI] = pos >> 32;           /* %edx */
 1907         return error;
 1908 }
 1909 
 1910 int
 1911 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
 1912 {
 1913 
 1914         return (kern_truncate(td, uap->path, UIO_USERSPACE,
 1915             PAIR32TO64(off_t, uap->length)));
 1916 }
 1917 
 1918 int
 1919 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
 1920 {
 1921 
 1922         return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
 1923 }
 1924 
 1925 #ifdef COMPAT_43
 1926 int
 1927 ofreebsd32_getdirentries(struct thread *td,
 1928     struct ofreebsd32_getdirentries_args *uap)
 1929 {
 1930         struct ogetdirentries_args ap;
 1931         int error;
 1932         long loff;
 1933         int32_t loff_cut;
 1934 
 1935         ap.fd = uap->fd;
 1936         ap.buf = uap->buf;
 1937         ap.count = uap->count;
 1938         ap.basep = NULL;
 1939         error = kern_ogetdirentries(td, &ap, &loff);
 1940         if (error == 0) {
 1941                 loff_cut = loff;
 1942                 error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
 1943         }
 1944         return (error);
 1945 }
 1946 #endif
 1947 
 1948 #if defined(COMPAT_FREEBSD11)
 1949 int
 1950 freebsd11_freebsd32_getdirentries(struct thread *td,
 1951     struct freebsd11_freebsd32_getdirentries_args *uap)
 1952 {
 1953         long base;
 1954         int32_t base32;
 1955         int error;
 1956 
 1957         error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
 1958             &base, NULL);
 1959         if (error)
 1960                 return (error);
 1961         if (uap->basep != NULL) {
 1962                 base32 = base;
 1963                 error = copyout(&base32, uap->basep, sizeof(int32_t));
 1964         }
 1965         return (error);
 1966 }
 1967 
 1968 int
 1969 freebsd11_freebsd32_getdents(struct thread *td,
 1970     struct freebsd11_freebsd32_getdents_args *uap)
 1971 {
 1972         struct freebsd11_freebsd32_getdirentries_args ap;
 1973 
 1974         ap.fd = uap->fd;
 1975         ap.buf = uap->buf;
 1976         ap.count = uap->count;
 1977         ap.basep = NULL;
 1978         return (freebsd11_freebsd32_getdirentries(td, &ap));
 1979 }
 1980 #endif /* COMPAT_FREEBSD11 */
 1981 
 1982 #ifdef COMPAT_FREEBSD6
 1983 /* versions with the 'int pad' argument */
 1984 int
 1985 freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
 1986 {
 1987 
 1988         return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
 1989             PAIR32TO64(off_t, uap->offset)));
 1990 }
 1991 
 1992 int
 1993 freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
 1994 {
 1995 
 1996         return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
 1997             PAIR32TO64(off_t, uap->offset)));
 1998 }
 1999 
 2000 int
 2001 freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
 2002 {
 2003         int error;
 2004         off_t pos;
 2005 
 2006         error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
 2007             uap->whence);
 2008         /* Expand the quad return into two parts for eax and edx */
 2009         pos = *(off_t *)(td->td_retval);
 2010         td->td_retval[RETVAL_LO] = pos & 0xffffffff;    /* %eax */
 2011         td->td_retval[RETVAL_HI] = pos >> 32;           /* %edx */
 2012         return error;
 2013 }
 2014 
 2015 int
 2016 freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
 2017 {
 2018 
 2019         return (kern_truncate(td, uap->path, UIO_USERSPACE,
 2020             PAIR32TO64(off_t, uap->length)));
 2021 }
 2022 
 2023 int
 2024 freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
 2025 {
 2026 
 2027         return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
 2028 }
 2029 #endif /* COMPAT_FREEBSD6 */
 2030 
 2031 struct sf_hdtr32 {
 2032         uint32_t headers;
 2033         int hdr_cnt;
 2034         uint32_t trailers;
 2035         int trl_cnt;
 2036 };
 2037 
 2038 static int
 2039 freebsd32_do_sendfile(struct thread *td,
 2040     struct freebsd32_sendfile_args *uap, int compat)
 2041 {
 2042         struct sf_hdtr32 hdtr32;
 2043         struct sf_hdtr hdtr;
 2044         struct uio *hdr_uio, *trl_uio;
 2045         struct file *fp;
 2046         cap_rights_t rights;
 2047         struct iovec32 *iov32;
 2048         off_t offset, sbytes;
 2049         int error;
 2050 
 2051         offset = PAIR32TO64(off_t, uap->offset);
 2052         if (offset < 0)
 2053                 return (EINVAL);
 2054 
 2055         hdr_uio = trl_uio = NULL;
 2056 
 2057         if (uap->hdtr != NULL) {
 2058                 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
 2059                 if (error)
 2060                         goto out;
 2061                 PTRIN_CP(hdtr32, hdtr, headers);
 2062                 CP(hdtr32, hdtr, hdr_cnt);
 2063                 PTRIN_CP(hdtr32, hdtr, trailers);
 2064                 CP(hdtr32, hdtr, trl_cnt);
 2065 
 2066                 if (hdtr.headers != NULL) {
 2067                         iov32 = PTRIN(hdtr32.headers);
 2068                         error = freebsd32_copyinuio(iov32,
 2069                             hdtr32.hdr_cnt, &hdr_uio);
 2070                         if (error)
 2071                                 goto out;
 2072 #ifdef COMPAT_FREEBSD4
 2073                         /*
 2074                          * In FreeBSD < 5.0 the nbytes to send also included
 2075                          * the header.  If compat is specified subtract the
 2076                          * header size from nbytes.
 2077                          */
 2078                         if (compat) {
 2079                                 if (uap->nbytes > hdr_uio->uio_resid)
 2080                                         uap->nbytes -= hdr_uio->uio_resid;
 2081                                 else
 2082                                         uap->nbytes = 0;
 2083                         }
 2084 #endif
 2085                 }
 2086                 if (hdtr.trailers != NULL) {
 2087                         iov32 = PTRIN(hdtr32.trailers);
 2088                         error = freebsd32_copyinuio(iov32,
 2089                             hdtr32.trl_cnt, &trl_uio);
 2090                         if (error)
 2091                                 goto out;
 2092                 }
 2093         }
 2094 
 2095         AUDIT_ARG_FD(uap->fd);
 2096 
 2097         if ((error = fget_read(td, uap->fd,
 2098             cap_rights_init_one(&rights, CAP_PREAD), &fp)) != 0)
 2099                 goto out;
 2100 
 2101         error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset,
 2102             uap->nbytes, &sbytes, uap->flags, td);
 2103         fdrop(fp, td);
 2104 
 2105         if (uap->sbytes != NULL)
 2106                 copyout(&sbytes, uap->sbytes, sizeof(off_t));
 2107 
 2108 out:
 2109         if (hdr_uio)
 2110                 free(hdr_uio, M_IOV);
 2111         if (trl_uio)
 2112                 free(trl_uio, M_IOV);
 2113         return (error);
 2114 }
 2115 
 2116 #ifdef COMPAT_FREEBSD4
 2117 int
 2118 freebsd4_freebsd32_sendfile(struct thread *td,
 2119     struct freebsd4_freebsd32_sendfile_args *uap)
 2120 {
 2121         return (freebsd32_do_sendfile(td,
 2122             (struct freebsd32_sendfile_args *)uap, 1));
 2123 }
 2124 #endif
 2125 
 2126 int
 2127 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
 2128 {
 2129 
 2130         return (freebsd32_do_sendfile(td, uap, 0));
 2131 }
 2132 
 2133 static void
 2134 copy_stat(struct stat *in, struct stat32 *out)
 2135 {
 2136 
 2137         CP(*in, *out, st_dev);
 2138         CP(*in, *out, st_ino);
 2139         CP(*in, *out, st_mode);
 2140         CP(*in, *out, st_nlink);
 2141         CP(*in, *out, st_uid);
 2142         CP(*in, *out, st_gid);
 2143         CP(*in, *out, st_rdev);
 2144         TS_CP(*in, *out, st_atim);
 2145         TS_CP(*in, *out, st_mtim);
 2146         TS_CP(*in, *out, st_ctim);
 2147         CP(*in, *out, st_size);
 2148         CP(*in, *out, st_blocks);
 2149         CP(*in, *out, st_blksize);
 2150         CP(*in, *out, st_flags);
 2151         CP(*in, *out, st_gen);
 2152         TS_CP(*in, *out, st_birthtim);
 2153         out->st_padding0 = 0;
 2154         out->st_padding1 = 0;
 2155 #ifdef __STAT32_TIME_T_EXT
 2156         out->st_atim_ext = 0;
 2157         out->st_mtim_ext = 0;
 2158         out->st_ctim_ext = 0;
 2159         out->st_btim_ext = 0;
 2160 #endif
 2161         bzero(out->st_spare, sizeof(out->st_spare));
 2162 }
 2163 
 2164 #ifdef COMPAT_43
 2165 static void
 2166 copy_ostat(struct stat *in, struct ostat32 *out)
 2167 {
 2168 
 2169         bzero(out, sizeof(*out));
 2170         CP(*in, *out, st_dev);
 2171         CP(*in, *out, st_ino);
 2172         CP(*in, *out, st_mode);
 2173         CP(*in, *out, st_nlink);
 2174         CP(*in, *out, st_uid);
 2175         CP(*in, *out, st_gid);
 2176         CP(*in, *out, st_rdev);
 2177         out->st_size = MIN(in->st_size, INT32_MAX);
 2178         TS_CP(*in, *out, st_atim);
 2179         TS_CP(*in, *out, st_mtim);
 2180         TS_CP(*in, *out, st_ctim);
 2181         CP(*in, *out, st_blksize);
 2182         CP(*in, *out, st_blocks);
 2183         CP(*in, *out, st_flags);
 2184         CP(*in, *out, st_gen);
 2185 }
 2186 #endif
 2187 
 2188 #ifdef COMPAT_43
 2189 int
 2190 ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
 2191 {
 2192         struct stat sb;
 2193         struct ostat32 sb32;
 2194         int error;
 2195 
 2196         error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE,
 2197             &sb, NULL);
 2198         if (error)
 2199                 return (error);
 2200         copy_ostat(&sb, &sb32);
 2201         error = copyout(&sb32, uap->ub, sizeof (sb32));
 2202         return (error);
 2203 }
 2204 #endif
 2205 
 2206 int
 2207 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
 2208 {
 2209         struct stat ub;
 2210         struct stat32 ub32;
 2211         int error;
 2212 
 2213         error = kern_fstat(td, uap->fd, &ub);
 2214         if (error)
 2215                 return (error);
 2216         copy_stat(&ub, &ub32);
 2217         error = copyout(&ub32, uap->ub, sizeof(ub32));
 2218         return (error);
 2219 }
 2220 
 2221 #ifdef COMPAT_43
 2222 int
 2223 ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
 2224 {
 2225         struct stat ub;
 2226         struct ostat32 ub32;
 2227         int error;
 2228 
 2229         error = kern_fstat(td, uap->fd, &ub);
 2230         if (error)
 2231                 return (error);
 2232         copy_ostat(&ub, &ub32);
 2233         error = copyout(&ub32, uap->ub, sizeof(ub32));
 2234         return (error);
 2235 }
 2236 #endif
 2237 
 2238 int
 2239 freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
 2240 {
 2241         struct stat ub;
 2242         struct stat32 ub32;
 2243         int error;
 2244 
 2245         error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
 2246             &ub, NULL);
 2247         if (error)
 2248                 return (error);
 2249         copy_stat(&ub, &ub32);
 2250         error = copyout(&ub32, uap->buf, sizeof(ub32));
 2251         return (error);
 2252 }
 2253 
 2254 #ifdef COMPAT_43
 2255 int
 2256 ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
 2257 {
 2258         struct stat sb;
 2259         struct ostat32 sb32;
 2260         int error;
 2261 
 2262         error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
 2263             UIO_USERSPACE, &sb, NULL);
 2264         if (error)
 2265                 return (error);
 2266         copy_ostat(&sb, &sb32);
 2267         error = copyout(&sb32, uap->ub, sizeof (sb32));
 2268         return (error);
 2269 }
 2270 #endif
 2271 
 2272 int
 2273 freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap)
 2274 {
 2275         struct stat sb;
 2276         struct stat32 sb32;
 2277         struct fhandle fh;
 2278         int error;
 2279 
 2280         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
 2281         if (error != 0)
 2282                 return (error);
 2283         error = kern_fhstat(td, fh, &sb);
 2284         if (error != 0)
 2285                 return (error);
 2286         copy_stat(&sb, &sb32);
 2287         error = copyout(&sb32, uap->sb, sizeof (sb32));
 2288         return (error);
 2289 }
 2290 
 2291 #if defined(COMPAT_FREEBSD11)
 2292 extern int ino64_trunc_error;
 2293 
 2294 static int
 2295 freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
 2296 {
 2297 
 2298         CP(*in, *out, st_ino);
 2299         if (in->st_ino != out->st_ino) {
 2300                 switch (ino64_trunc_error) {
 2301                 default:
 2302                 case 0:
 2303                         break;
 2304                 case 1:
 2305                         return (EOVERFLOW);
 2306                 case 2:
 2307                         out->st_ino = UINT32_MAX;
 2308                         break;
 2309                 }
 2310         }
 2311         CP(*in, *out, st_nlink);
 2312         if (in->st_nlink != out->st_nlink) {
 2313                 switch (ino64_trunc_error) {
 2314                 default:
 2315                 case 0:
 2316                         break;
 2317                 case 1:
 2318                         return (EOVERFLOW);
 2319                 case 2:
 2320                         out->st_nlink = UINT16_MAX;
 2321                         break;
 2322                 }
 2323         }
 2324         out->st_dev = in->st_dev;
 2325         if (out->st_dev != in->st_dev) {
 2326                 switch (ino64_trunc_error) {
 2327                 default:
 2328                         break;
 2329                 case 1:
 2330                         return (EOVERFLOW);
 2331                 }
 2332         }
 2333         CP(*in, *out, st_mode);
 2334         CP(*in, *out, st_uid);
 2335         CP(*in, *out, st_gid);
 2336         out->st_rdev = in->st_rdev;
 2337         if (out->st_rdev != in->st_rdev) {
 2338                 switch (ino64_trunc_error) {
 2339                 default:
 2340                         break;
 2341                 case 1:
 2342                         return (EOVERFLOW);
 2343                 }
 2344         }
 2345         TS_CP(*in, *out, st_atim);
 2346         TS_CP(*in, *out, st_mtim);
 2347         TS_CP(*in, *out, st_ctim);
 2348         CP(*in, *out, st_size);
 2349         CP(*in, *out, st_blocks);
 2350         CP(*in, *out, st_blksize);
 2351         CP(*in, *out, st_flags);
 2352         CP(*in, *out, st_gen);
 2353         TS_CP(*in, *out, st_birthtim);
 2354         out->st_lspare = 0;
 2355         bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),
 2356             sizeof(*out) - offsetof(struct freebsd11_stat32,
 2357             st_birthtim) - sizeof(out->st_birthtim));
 2358         return (0);
 2359 }
 2360 
 2361 int
 2362 freebsd11_freebsd32_stat(struct thread *td,
 2363     struct freebsd11_freebsd32_stat_args *uap)
 2364 {
 2365         struct stat sb;
 2366         struct freebsd11_stat32 sb32;
 2367         int error;
 2368 
 2369         error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE,
 2370             &sb, NULL);
 2371         if (error != 0)
 2372                 return (error);
 2373         error = freebsd11_cvtstat32(&sb, &sb32);
 2374         if (error == 0)
 2375                 error = copyout(&sb32, uap->ub, sizeof (sb32));
 2376         return (error);
 2377 }
 2378 
 2379 int
 2380 freebsd11_freebsd32_fstat(struct thread *td,
 2381     struct freebsd11_freebsd32_fstat_args *uap)
 2382 {
 2383         struct stat sb;
 2384         struct freebsd11_stat32 sb32;
 2385         int error;
 2386 
 2387         error = kern_fstat(td, uap->fd, &sb);
 2388         if (error != 0)
 2389                 return (error);
 2390         error = freebsd11_cvtstat32(&sb, &sb32);
 2391         if (error == 0)
 2392                 error = copyout(&sb32, uap->ub, sizeof (sb32));
 2393         return (error);
 2394 }
 2395 
 2396 int
 2397 freebsd11_freebsd32_fstatat(struct thread *td,
 2398     struct freebsd11_freebsd32_fstatat_args *uap)
 2399 {
 2400         struct stat sb;
 2401         struct freebsd11_stat32 sb32;
 2402         int error;
 2403 
 2404         error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
 2405             &sb, NULL);
 2406         if (error != 0)
 2407                 return (error);
 2408         error = freebsd11_cvtstat32(&sb, &sb32);
 2409         if (error == 0)
 2410                 error = copyout(&sb32, uap->buf, sizeof (sb32));
 2411         return (error);
 2412 }
 2413 
 2414 int
 2415 freebsd11_freebsd32_lstat(struct thread *td,
 2416     struct freebsd11_freebsd32_lstat_args *uap)
 2417 {
 2418         struct stat sb;
 2419         struct freebsd11_stat32 sb32;
 2420         int error;
 2421 
 2422         error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
 2423             UIO_USERSPACE, &sb, NULL);
 2424         if (error != 0)
 2425                 return (error);
 2426         error = freebsd11_cvtstat32(&sb, &sb32);
 2427         if (error == 0)
 2428                 error = copyout(&sb32, uap->ub, sizeof (sb32));
 2429         return (error);
 2430 }
 2431 
 2432 int
 2433 freebsd11_freebsd32_fhstat(struct thread *td,
 2434     struct freebsd11_freebsd32_fhstat_args *uap)
 2435 {
 2436         struct stat sb;
 2437         struct freebsd11_stat32 sb32;
 2438         struct fhandle fh;
 2439         int error;
 2440 
 2441         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
 2442         if (error != 0)
 2443                 return (error);
 2444         error = kern_fhstat(td, fh, &sb);
 2445         if (error != 0)
 2446                 return (error);
 2447         error = freebsd11_cvtstat32(&sb, &sb32);
 2448         if (error == 0)
 2449                 error = copyout(&sb32, uap->sb, sizeof (sb32));
 2450         return (error);
 2451 }
 2452 #endif
 2453 
 2454 int
 2455 freebsd32___sysctl(struct thread *td, struct freebsd32___sysctl_args *uap)
 2456 {
 2457         int error, name[CTL_MAXNAME];
 2458         size_t j, oldlen;
 2459         uint32_t tmp;
 2460 
 2461         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
 2462                 return (EINVAL);
 2463         error = copyin(uap->name, name, uap->namelen * sizeof(int));
 2464         if (error)
 2465                 return (error);
 2466         if (uap->oldlenp) {
 2467                 error = fueword32(uap->oldlenp, &tmp);
 2468                 oldlen = tmp;
 2469         } else {
 2470                 oldlen = 0;
 2471         }
 2472         if (error != 0)
 2473                 return (EFAULT);
 2474         error = userland_sysctl(td, name, uap->namelen,
 2475                 uap->old, &oldlen, 1,
 2476                 uap->new, uap->newlen, &j, SCTL_MASK32);
 2477         if (error)
 2478                 return (error);
 2479         if (uap->oldlenp)
 2480                 suword32(uap->oldlenp, j);
 2481         return (0);
 2482 }
 2483 
 2484 int
 2485 freebsd32___sysctlbyname(struct thread *td,
 2486     struct freebsd32___sysctlbyname_args *uap)
 2487 {
 2488         size_t oldlen, rv;
 2489         int error;
 2490         uint32_t tmp;
 2491 
 2492         if (uap->oldlenp != NULL) {
 2493                 error = fueword32(uap->oldlenp, &tmp);
 2494                 oldlen = tmp;
 2495         } else {
 2496                 error = oldlen = 0;
 2497         }
 2498         if (error != 0)
 2499                 return (EFAULT);
 2500         error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
 2501             &oldlen, uap->new, uap->newlen, &rv, SCTL_MASK32, 1);
 2502         if (error != 0)
 2503                 return (error);
 2504         if (uap->oldlenp != NULL)
 2505                 error = suword32(uap->oldlenp, rv);
 2506 
 2507         return (error);
 2508 }
 2509 
 2510 int
 2511 freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
 2512 {
 2513         uint32_t version;
 2514         int error;
 2515         struct jail j;
 2516 
 2517         error = copyin(uap->jail, &version, sizeof(uint32_t));
 2518         if (error)
 2519                 return (error);
 2520 
 2521         switch (version) {
 2522         case 0:
 2523         {
 2524                 /* FreeBSD single IPv4 jails. */
 2525                 struct jail32_v0 j32_v0;
 2526 
 2527                 bzero(&j, sizeof(struct jail));
 2528                 error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
 2529                 if (error)
 2530                         return (error);
 2531                 CP(j32_v0, j, version);
 2532                 PTRIN_CP(j32_v0, j, path);
 2533                 PTRIN_CP(j32_v0, j, hostname);
 2534                 j.ip4s = htonl(j32_v0.ip_number);       /* jail_v0 is host order */
 2535                 break;
 2536         }
 2537 
 2538         case 1:
 2539                 /*
 2540                  * Version 1 was used by multi-IPv4 jail implementations
 2541                  * that never made it into the official kernel.
 2542                  */
 2543                 return (EINVAL);
 2544 
 2545         case 2: /* JAIL_API_VERSION */
 2546         {
 2547                 /* FreeBSD multi-IPv4/IPv6,noIP jails. */
 2548                 struct jail32 j32;
 2549 
 2550                 error = copyin(uap->jail, &j32, sizeof(struct jail32));
 2551                 if (error)
 2552                         return (error);
 2553                 CP(j32, j, version);
 2554                 PTRIN_CP(j32, j, path);
 2555                 PTRIN_CP(j32, j, hostname);
 2556                 PTRIN_CP(j32, j, jailname);
 2557                 CP(j32, j, ip4s);
 2558                 CP(j32, j, ip6s);
 2559                 PTRIN_CP(j32, j, ip4);
 2560                 PTRIN_CP(j32, j, ip6);
 2561                 break;
 2562         }
 2563 
 2564         default:
 2565                 /* Sci-Fi jails are not supported, sorry. */
 2566                 return (EINVAL);
 2567         }
 2568         return (kern_jail(td, &j));
 2569 }
 2570 
 2571 int
 2572 freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
 2573 {
 2574         struct uio *auio;
 2575         int error;
 2576 
 2577         /* Check that we have an even number of iovecs. */
 2578         if (uap->iovcnt & 1)
 2579                 return (EINVAL);
 2580 
 2581         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 2582         if (error)
 2583                 return (error);
 2584         error = kern_jail_set(td, auio, uap->flags);
 2585         free(auio, M_IOV);
 2586         return (error);
 2587 }
 2588 
 2589 int
 2590 freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
 2591 {
 2592         struct iovec32 iov32;
 2593         struct uio *auio;
 2594         int error, i;
 2595 
 2596         /* Check that we have an even number of iovecs. */
 2597         if (uap->iovcnt & 1)
 2598                 return (EINVAL);
 2599 
 2600         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 2601         if (error)
 2602                 return (error);
 2603         error = kern_jail_get(td, auio, uap->flags);
 2604         if (error == 0)
 2605                 for (i = 0; i < uap->iovcnt; i++) {
 2606                         PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
 2607                         CP(auio->uio_iov[i], iov32, iov_len);
 2608                         error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
 2609                         if (error != 0)
 2610                                 break;
 2611                 }
 2612         free(auio, M_IOV);
 2613         return (error);
 2614 }
 2615 
 2616 int
 2617 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
 2618 {
 2619         struct sigaction32 s32;
 2620         struct sigaction sa, osa, *sap;
 2621         int error;
 2622 
 2623         if (uap->act) {
 2624                 error = copyin(uap->act, &s32, sizeof(s32));
 2625                 if (error)
 2626                         return (error);
 2627                 sa.sa_handler = PTRIN(s32.sa_u);
 2628                 CP(s32, sa, sa_flags);
 2629                 CP(s32, sa, sa_mask);
 2630                 sap = &sa;
 2631         } else
 2632                 sap = NULL;
 2633         error = kern_sigaction(td, uap->sig, sap, &osa, 0);
 2634         if (error == 0 && uap->oact != NULL) {
 2635                 s32.sa_u = PTROUT(osa.sa_handler);
 2636                 CP(osa, s32, sa_flags);
 2637                 CP(osa, s32, sa_mask);
 2638                 error = copyout(&s32, uap->oact, sizeof(s32));
 2639         }
 2640         return (error);
 2641 }
 2642 
 2643 #ifdef COMPAT_FREEBSD4
 2644 int
 2645 freebsd4_freebsd32_sigaction(struct thread *td,
 2646                              struct freebsd4_freebsd32_sigaction_args *uap)
 2647 {
 2648         struct sigaction32 s32;
 2649         struct sigaction sa, osa, *sap;
 2650         int error;
 2651 
 2652         if (uap->act) {
 2653                 error = copyin(uap->act, &s32, sizeof(s32));
 2654                 if (error)
 2655                         return (error);
 2656                 sa.sa_handler = PTRIN(s32.sa_u);
 2657                 CP(s32, sa, sa_flags);
 2658                 CP(s32, sa, sa_mask);
 2659                 sap = &sa;
 2660         } else
 2661                 sap = NULL;
 2662         error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
 2663         if (error == 0 && uap->oact != NULL) {
 2664                 s32.sa_u = PTROUT(osa.sa_handler);
 2665                 CP(osa, s32, sa_flags);
 2666                 CP(osa, s32, sa_mask);
 2667                 error = copyout(&s32, uap->oact, sizeof(s32));
 2668         }
 2669         return (error);
 2670 }
 2671 #endif
 2672 
 2673 #ifdef COMPAT_43
 2674 struct osigaction32 {
 2675         u_int32_t       sa_u;
 2676         osigset_t       sa_mask;
 2677         int             sa_flags;
 2678 };
 2679 
 2680 #define ONSIG   32
 2681 
 2682 int
 2683 ofreebsd32_sigaction(struct thread *td,
 2684                              struct ofreebsd32_sigaction_args *uap)
 2685 {
 2686         struct osigaction32 s32;
 2687         struct sigaction sa, osa, *sap;
 2688         int error;
 2689 
 2690         if (uap->signum <= 0 || uap->signum >= ONSIG)
 2691                 return (EINVAL);
 2692 
 2693         if (uap->nsa) {
 2694                 error = copyin(uap->nsa, &s32, sizeof(s32));
 2695                 if (error)
 2696                         return (error);
 2697                 sa.sa_handler = PTRIN(s32.sa_u);
 2698                 CP(s32, sa, sa_flags);
 2699                 OSIG2SIG(s32.sa_mask, sa.sa_mask);
 2700                 sap = &sa;
 2701         } else
 2702                 sap = NULL;
 2703         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
 2704         if (error == 0 && uap->osa != NULL) {
 2705                 s32.sa_u = PTROUT(osa.sa_handler);
 2706                 CP(osa, s32, sa_flags);
 2707                 SIG2OSIG(osa.sa_mask, s32.sa_mask);
 2708                 error = copyout(&s32, uap->osa, sizeof(s32));
 2709         }
 2710         return (error);
 2711 }
 2712 
 2713 int
 2714 ofreebsd32_sigprocmask(struct thread *td,
 2715                                struct ofreebsd32_sigprocmask_args *uap)
 2716 {
 2717         sigset_t set, oset;
 2718         int error;
 2719 
 2720         OSIG2SIG(uap->mask, set);
 2721         error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD);
 2722         SIG2OSIG(oset, td->td_retval[0]);
 2723         return (error);
 2724 }
 2725 
 2726 int
 2727 ofreebsd32_sigpending(struct thread *td,
 2728                               struct ofreebsd32_sigpending_args *uap)
 2729 {
 2730         struct proc *p = td->td_proc;
 2731         sigset_t siglist;
 2732 
 2733         PROC_LOCK(p);
 2734         siglist = p->p_siglist;
 2735         SIGSETOR(siglist, td->td_siglist);
 2736         PROC_UNLOCK(p);
 2737         SIG2OSIG(siglist, td->td_retval[0]);
 2738         return (0);
 2739 }
 2740 
 2741 struct sigvec32 {
 2742         u_int32_t       sv_handler;
 2743         int             sv_mask;
 2744         int             sv_flags;
 2745 };
 2746 
 2747 int
 2748 ofreebsd32_sigvec(struct thread *td,
 2749                           struct ofreebsd32_sigvec_args *uap)
 2750 {
 2751         struct sigvec32 vec;
 2752         struct sigaction sa, osa, *sap;
 2753         int error;
 2754 
 2755         if (uap->signum <= 0 || uap->signum >= ONSIG)
 2756                 return (EINVAL);
 2757 
 2758         if (uap->nsv) {
 2759                 error = copyin(uap->nsv, &vec, sizeof(vec));
 2760                 if (error)
 2761                         return (error);
 2762                 sa.sa_handler = PTRIN(vec.sv_handler);
 2763                 OSIG2SIG(vec.sv_mask, sa.sa_mask);
 2764                 sa.sa_flags = vec.sv_flags;
 2765                 sa.sa_flags ^= SA_RESTART;
 2766                 sap = &sa;
 2767         } else
 2768                 sap = NULL;
 2769         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
 2770         if (error == 0 && uap->osv != NULL) {
 2771                 vec.sv_handler = PTROUT(osa.sa_handler);
 2772                 SIG2OSIG(osa.sa_mask, vec.sv_mask);
 2773                 vec.sv_flags = osa.sa_flags;
 2774                 vec.sv_flags &= ~SA_NOCLDWAIT;
 2775                 vec.sv_flags ^= SA_RESTART;
 2776                 error = copyout(&vec, uap->osv, sizeof(vec));
 2777         }
 2778         return (error);
 2779 }
 2780 
 2781 int
 2782 ofreebsd32_sigblock(struct thread *td,
 2783                             struct ofreebsd32_sigblock_args *uap)
 2784 {
 2785         sigset_t set, oset;
 2786 
 2787         OSIG2SIG(uap->mask, set);
 2788         kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0);
 2789         SIG2OSIG(oset, td->td_retval[0]);
 2790         return (0);
 2791 }
 2792 
 2793 int
 2794 ofreebsd32_sigsetmask(struct thread *td,
 2795                               struct ofreebsd32_sigsetmask_args *uap)
 2796 {
 2797         sigset_t set, oset;
 2798 
 2799         OSIG2SIG(uap->mask, set);
 2800         kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0);
 2801         SIG2OSIG(oset, td->td_retval[0]);
 2802         return (0);
 2803 }
 2804 
 2805 int
 2806 ofreebsd32_sigsuspend(struct thread *td,
 2807                               struct ofreebsd32_sigsuspend_args *uap)
 2808 {
 2809         sigset_t mask;
 2810 
 2811         OSIG2SIG(uap->mask, mask);
 2812         return (kern_sigsuspend(td, mask));
 2813 }
 2814 
 2815 struct sigstack32 {
 2816         u_int32_t       ss_sp;
 2817         int             ss_onstack;
 2818 };
 2819 
 2820 int
 2821 ofreebsd32_sigstack(struct thread *td,
 2822                             struct ofreebsd32_sigstack_args *uap)
 2823 {
 2824         struct sigstack32 s32;
 2825         struct sigstack nss, oss;
 2826         int error = 0, unss;
 2827 
 2828         if (uap->nss != NULL) {
 2829                 error = copyin(uap->nss, &s32, sizeof(s32));
 2830                 if (error)
 2831                         return (error);
 2832                 nss.ss_sp = PTRIN(s32.ss_sp);
 2833                 CP(s32, nss, ss_onstack);
 2834                 unss = 1;
 2835         } else {
 2836                 unss = 0;
 2837         }
 2838         oss.ss_sp = td->td_sigstk.ss_sp;
 2839         oss.ss_onstack = sigonstack(cpu_getstack(td));
 2840         if (unss) {
 2841                 td->td_sigstk.ss_sp = nss.ss_sp;
 2842                 td->td_sigstk.ss_size = 0;
 2843                 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
 2844                 td->td_pflags |= TDP_ALTSTACK;
 2845         }
 2846         if (uap->oss != NULL) {
 2847                 s32.ss_sp = PTROUT(oss.ss_sp);
 2848                 CP(oss, s32, ss_onstack);
 2849                 error = copyout(&s32, uap->oss, sizeof(s32));
 2850         }
 2851         return (error);
 2852 }
 2853 #endif
 2854 
 2855 int
 2856 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
 2857 {
 2858 
 2859         return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME,
 2860             TIMER_RELTIME, uap->rqtp, uap->rmtp));
 2861 }
 2862 
 2863 int
 2864 freebsd32_clock_nanosleep(struct thread *td,
 2865     struct freebsd32_clock_nanosleep_args *uap)
 2866 {
 2867         int error;
 2868 
 2869         error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags,
 2870             uap->rqtp, uap->rmtp);
 2871         return (kern_posix_error(td, error));
 2872 }
 2873 
 2874 static int
 2875 freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
 2876     int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp)
 2877 {
 2878         struct timespec32 rmt32, rqt32;
 2879         struct timespec rmt, rqt;
 2880         int error, error2;
 2881 
 2882         error = copyin(ua_rqtp, &rqt32, sizeof(rqt32));
 2883         if (error)
 2884                 return (error);
 2885 
 2886         CP(rqt32, rqt, tv_sec);
 2887         CP(rqt32, rqt, tv_nsec);
 2888 
 2889         error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt);
 2890         if (error == EINTR && ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0) {
 2891                 CP(rmt, rmt32, tv_sec);
 2892                 CP(rmt, rmt32, tv_nsec);
 2893 
 2894                 error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32));
 2895                 if (error2 != 0)
 2896                         error = error2;
 2897         }
 2898         return (error);
 2899 }
 2900 
 2901 int
 2902 freebsd32_clock_gettime(struct thread *td,
 2903                         struct freebsd32_clock_gettime_args *uap)
 2904 {
 2905         struct timespec ats;
 2906         struct timespec32 ats32;
 2907         int error;
 2908 
 2909         error = kern_clock_gettime(td, uap->clock_id, &ats);
 2910         if (error == 0) {
 2911                 CP(ats, ats32, tv_sec);
 2912                 CP(ats, ats32, tv_nsec);
 2913                 error = copyout(&ats32, uap->tp, sizeof(ats32));
 2914         }
 2915         return (error);
 2916 }
 2917 
 2918 int
 2919 freebsd32_clock_settime(struct thread *td,
 2920                         struct freebsd32_clock_settime_args *uap)
 2921 {
 2922         struct timespec ats;
 2923         struct timespec32 ats32;
 2924         int error;
 2925 
 2926         error = copyin(uap->tp, &ats32, sizeof(ats32));
 2927         if (error)
 2928                 return (error);
 2929         CP(ats32, ats, tv_sec);
 2930         CP(ats32, ats, tv_nsec);
 2931 
 2932         return (kern_clock_settime(td, uap->clock_id, &ats));
 2933 }
 2934 
 2935 int
 2936 freebsd32_clock_getres(struct thread *td,
 2937                        struct freebsd32_clock_getres_args *uap)
 2938 {
 2939         struct timespec ts;
 2940         struct timespec32 ts32;
 2941         int error;
 2942 
 2943         if (uap->tp == NULL)
 2944                 return (0);
 2945         error = kern_clock_getres(td, uap->clock_id, &ts);
 2946         if (error == 0) {
 2947                 CP(ts, ts32, tv_sec);
 2948                 CP(ts, ts32, tv_nsec);
 2949                 error = copyout(&ts32, uap->tp, sizeof(ts32));
 2950         }
 2951         return (error);
 2952 }
 2953 
 2954 int freebsd32_ktimer_create(struct thread *td,
 2955     struct freebsd32_ktimer_create_args *uap)
 2956 {
 2957         struct sigevent32 ev32;
 2958         struct sigevent ev, *evp;
 2959         int error, id;
 2960 
 2961         if (uap->evp == NULL) {
 2962                 evp = NULL;
 2963         } else {
 2964                 evp = &ev;
 2965                 error = copyin(uap->evp, &ev32, sizeof(ev32));
 2966                 if (error != 0)
 2967                         return (error);
 2968                 error = convert_sigevent32(&ev32, &ev);
 2969                 if (error != 0)
 2970                         return (error);
 2971         }
 2972         error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
 2973         if (error == 0) {
 2974                 error = copyout(&id, uap->timerid, sizeof(int));
 2975                 if (error != 0)
 2976                         kern_ktimer_delete(td, id);
 2977         }
 2978         return (error);
 2979 }
 2980 
 2981 int
 2982 freebsd32_ktimer_settime(struct thread *td,
 2983     struct freebsd32_ktimer_settime_args *uap)
 2984 {
 2985         struct itimerspec32 val32, oval32;
 2986         struct itimerspec val, oval, *ovalp;
 2987         int error;
 2988 
 2989         error = copyin(uap->value, &val32, sizeof(val32));
 2990         if (error != 0)
 2991                 return (error);
 2992         ITS_CP(val32, val);
 2993         ovalp = uap->ovalue != NULL ? &oval : NULL;
 2994         error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
 2995         if (error == 0 && uap->ovalue != NULL) {
 2996                 ITS_CP(oval, oval32);
 2997                 error = copyout(&oval32, uap->ovalue, sizeof(oval32));
 2998         }
 2999         return (error);
 3000 }
 3001 
 3002 int
 3003 freebsd32_ktimer_gettime(struct thread *td,
 3004     struct freebsd32_ktimer_gettime_args *uap)
 3005 {
 3006         struct itimerspec32 val32;
 3007         struct itimerspec val;
 3008         int error;
 3009 
 3010         error = kern_ktimer_gettime(td, uap->timerid, &val);
 3011         if (error == 0) {
 3012                 ITS_CP(val, val32);
 3013                 error = copyout(&val32, uap->value, sizeof(val32));
 3014         }
 3015         return (error);
 3016 }
 3017 
 3018 int
 3019 freebsd32_clock_getcpuclockid2(struct thread *td,
 3020     struct freebsd32_clock_getcpuclockid2_args *uap)
 3021 {
 3022         clockid_t clk_id;
 3023         int error;
 3024 
 3025         error = kern_clock_getcpuclockid2(td, PAIR32TO64(id_t, uap->id),
 3026             uap->which, &clk_id);
 3027         if (error == 0)
 3028                 error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
 3029         return (error);
 3030 }
 3031 
 3032 int
 3033 freebsd32_thr_new(struct thread *td,
 3034                   struct freebsd32_thr_new_args *uap)
 3035 {
 3036         struct thr_param32 param32;
 3037         struct thr_param param;
 3038         int error;
 3039 
 3040         if (uap->param_size < 0 ||
 3041             uap->param_size > sizeof(struct thr_param32))
 3042                 return (EINVAL);
 3043         bzero(&param, sizeof(struct thr_param));
 3044         bzero(&param32, sizeof(struct thr_param32));
 3045         error = copyin(uap->param, &param32, uap->param_size);
 3046         if (error != 0)
 3047                 return (error);
 3048         param.start_func = PTRIN(param32.start_func);
 3049         param.arg = PTRIN(param32.arg);
 3050         param.stack_base = PTRIN(param32.stack_base);
 3051         param.stack_size = param32.stack_size;
 3052         param.tls_base = PTRIN(param32.tls_base);
 3053         param.tls_size = param32.tls_size;
 3054         param.child_tid = PTRIN(param32.child_tid);
 3055         param.parent_tid = PTRIN(param32.parent_tid);
 3056         param.flags = param32.flags;
 3057         param.rtp = PTRIN(param32.rtp);
 3058         param.spare[0] = PTRIN(param32.spare[0]);
 3059         param.spare[1] = PTRIN(param32.spare[1]);
 3060         param.spare[2] = PTRIN(param32.spare[2]);
 3061 
 3062         return (kern_thr_new(td, &param));
 3063 }
 3064 
 3065 int
 3066 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
 3067 {
 3068         struct timespec32 ts32;
 3069         struct timespec ts, *tsp;
 3070         int error;
 3071 
 3072         error = 0;
 3073         tsp = NULL;
 3074         if (uap->timeout != NULL) {
 3075                 error = copyin((const void *)uap->timeout, (void *)&ts32,
 3076                     sizeof(struct timespec32));
 3077                 if (error != 0)
 3078                         return (error);
 3079                 ts.tv_sec = ts32.tv_sec;
 3080                 ts.tv_nsec = ts32.tv_nsec;
 3081                 tsp = &ts;
 3082         }
 3083         return (kern_thr_suspend(td, tsp));
 3084 }
 3085 
 3086 void
 3087 siginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst)
 3088 {
 3089         bzero(dst, sizeof(*dst));
 3090         dst->si_signo = src->si_signo;
 3091         dst->si_errno = src->si_errno;
 3092         dst->si_code = src->si_code;
 3093         dst->si_pid = src->si_pid;
 3094         dst->si_uid = src->si_uid;
 3095         dst->si_status = src->si_status;
 3096         dst->si_addr = (uintptr_t)src->si_addr;
 3097         dst->si_value.sival_int = src->si_value.sival_int;
 3098         dst->si_timerid = src->si_timerid;
 3099         dst->si_overrun = src->si_overrun;
 3100 }
 3101 
 3102 #ifndef _FREEBSD32_SYSPROTO_H_
 3103 struct freebsd32_sigqueue_args {
 3104         pid_t pid;
 3105         int signum;
 3106         /* union sigval32 */ int value;
 3107 };
 3108 #endif
 3109 int
 3110 freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap)
 3111 {
 3112         union sigval sv;
 3113 
 3114         /*
 3115          * On 32-bit ABIs, sival_int and sival_ptr are the same.
 3116          * On 64-bit little-endian ABIs, the low bits are the same.
 3117          * In 64-bit big-endian ABIs, sival_int overlaps with
 3118          * sival_ptr's HIGH bits.  We choose to support sival_int
 3119          * rather than sival_ptr in this case as it seems to be
 3120          * more common.
 3121          */
 3122         bzero(&sv, sizeof(sv));
 3123         sv.sival_int = uap->value;
 3124 
 3125         return (kern_sigqueue(td, uap->pid, uap->signum, &sv));
 3126 }
 3127 
 3128 int
 3129 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
 3130 {
 3131         struct timespec32 ts32;
 3132         struct timespec ts;
 3133         struct timespec *timeout;
 3134         sigset_t set;
 3135         ksiginfo_t ksi;
 3136         struct siginfo32 si32;
 3137         int error;
 3138 
 3139         if (uap->timeout) {
 3140                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
 3141                 if (error)
 3142                         return (error);
 3143                 ts.tv_sec = ts32.tv_sec;
 3144                 ts.tv_nsec = ts32.tv_nsec;
 3145                 timeout = &ts;
 3146         } else
 3147                 timeout = NULL;
 3148 
 3149         error = copyin(uap->set, &set, sizeof(set));
 3150         if (error)
 3151                 return (error);
 3152 
 3153         error = kern_sigtimedwait(td, set, &ksi, timeout);
 3154         if (error)
 3155                 return (error);
 3156 
 3157         if (uap->info) {
 3158                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
 3159                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
 3160         }
 3161 
 3162         if (error == 0)
 3163                 td->td_retval[0] = ksi.ksi_signo;
 3164         return (error);
 3165 }
 3166 
 3167 /*
 3168  * MPSAFE
 3169  */
 3170 int
 3171 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
 3172 {
 3173         ksiginfo_t ksi;
 3174         struct siginfo32 si32;
 3175         sigset_t set;
 3176         int error;
 3177 
 3178         error = copyin(uap->set, &set, sizeof(set));
 3179         if (error)
 3180                 return (error);
 3181 
 3182         error = kern_sigtimedwait(td, set, &ksi, NULL);
 3183         if (error)
 3184                 return (error);
 3185 
 3186         if (uap->info) {
 3187                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
 3188                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
 3189         }       
 3190         if (error == 0)
 3191                 td->td_retval[0] = ksi.ksi_signo;
 3192         return (error);
 3193 }
 3194 
 3195 int
 3196 freebsd32_cpuset_setid(struct thread *td,
 3197     struct freebsd32_cpuset_setid_args *uap)
 3198 {
 3199 
 3200         return (kern_cpuset_setid(td, uap->which,
 3201             PAIR32TO64(id_t, uap->id), uap->setid));
 3202 }
 3203 
 3204 int
 3205 freebsd32_cpuset_getid(struct thread *td,
 3206     struct freebsd32_cpuset_getid_args *uap)
 3207 {
 3208 
 3209         return (kern_cpuset_getid(td, uap->level, uap->which,
 3210             PAIR32TO64(id_t, uap->id), uap->setid));
 3211 }
 3212 
 3213 int
 3214 freebsd32_cpuset_getaffinity(struct thread *td,
 3215     struct freebsd32_cpuset_getaffinity_args *uap)
 3216 {
 3217 
 3218         return (kern_cpuset_getaffinity(td, uap->level, uap->which,
 3219             PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask));
 3220 }
 3221 
 3222 int
 3223 freebsd32_cpuset_setaffinity(struct thread *td,
 3224     struct freebsd32_cpuset_setaffinity_args *uap)
 3225 {
 3226 
 3227         return (kern_cpuset_setaffinity(td, uap->level, uap->which,
 3228             PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask));
 3229 }
 3230 
 3231 int
 3232 freebsd32_cpuset_getdomain(struct thread *td,
 3233     struct freebsd32_cpuset_getdomain_args *uap)
 3234 {
 3235 
 3236         return (kern_cpuset_getdomain(td, uap->level, uap->which,
 3237             PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy));
 3238 }
 3239 
 3240 int
 3241 freebsd32_cpuset_setdomain(struct thread *td,
 3242     struct freebsd32_cpuset_setdomain_args *uap)
 3243 {
 3244 
 3245         return (kern_cpuset_setdomain(td, uap->level, uap->which,
 3246             PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy));
 3247 }
 3248 
 3249 int
 3250 freebsd32_nmount(struct thread *td,
 3251     struct freebsd32_nmount_args /* {
 3252         struct iovec *iovp;
 3253         unsigned int iovcnt;
 3254         int flags;
 3255     } */ *uap)
 3256 {
 3257         struct uio *auio;
 3258         uint64_t flags;
 3259         int error;
 3260 
 3261         /*
 3262          * Mount flags are now 64-bits. On 32-bit archtectures only
 3263          * 32-bits are passed in, but from here on everything handles
 3264          * 64-bit flags correctly.
 3265          */
 3266         flags = uap->flags;
 3267 
 3268         AUDIT_ARG_FFLAGS(flags);
 3269 
 3270         /*
 3271          * Filter out MNT_ROOTFS.  We do not want clients of nmount() in
 3272          * userspace to set this flag, but we must filter it out if we want
 3273          * MNT_UPDATE on the root file system to work.
 3274          * MNT_ROOTFS should only be set by the kernel when mounting its
 3275          * root file system.
 3276          */
 3277         flags &= ~MNT_ROOTFS;
 3278 
 3279         /*
 3280          * check that we have an even number of iovec's
 3281          * and that we have at least two options.
 3282          */
 3283         if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
 3284                 return (EINVAL);
 3285 
 3286         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 3287         if (error)
 3288                 return (error);
 3289         error = vfs_donmount(td, flags, auio);
 3290 
 3291         free(auio, M_IOV);
 3292         return error;
 3293 }
 3294 
 3295 #if 0
 3296 int
 3297 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
 3298 {
 3299         struct yyy32 *p32, s32;
 3300         struct yyy *p = NULL, s;
 3301         struct xxx_arg ap;
 3302         int error;
 3303 
 3304         if (uap->zzz) {
 3305                 error = copyin(uap->zzz, &s32, sizeof(s32));
 3306                 if (error)
 3307                         return (error);
 3308                 /* translate in */
 3309                 p = &s;
 3310         }
 3311         error = kern_xxx(td, p);
 3312         if (error)
 3313                 return (error);
 3314         if (uap->zzz) {
 3315                 /* translate out */
 3316                 error = copyout(&s32, p32, sizeof(s32));
 3317         }
 3318         return (error);
 3319 }
 3320 #endif
 3321 
 3322 int
 3323 syscall32_module_handler(struct module *mod, int what, void *arg)
 3324 {
 3325 
 3326         return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg));
 3327 }
 3328 
 3329 int
 3330 syscall32_helper_register(struct syscall_helper_data *sd, int flags)
 3331 {
 3332 
 3333         return (kern_syscall_helper_register(freebsd32_sysent, sd, flags));
 3334 }
 3335 
 3336 int
 3337 syscall32_helper_unregister(struct syscall_helper_data *sd)
 3338 {
 3339 
 3340         return (kern_syscall_helper_unregister(freebsd32_sysent, sd));
 3341 }
 3342 
 3343 int
 3344 freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
 3345 {
 3346         int argc, envc, i;
 3347         u_int32_t *vectp;
 3348         char *stringp;
 3349         uintptr_t destp, ustringp;
 3350         struct freebsd32_ps_strings *arginfo;
 3351         char canary[sizeof(long) * 8];
 3352         int32_t pagesizes32[MAXPAGESIZES];
 3353         size_t execpath_len;
 3354         int error, szsigcode;
 3355 
 3356         /*
 3357          * Calculate string base and vector table pointers.
 3358          * Also deal with signal trampoline code for this exec type.
 3359          */
 3360         if (imgp->execpath != NULL && imgp->auxargs != NULL)
 3361                 execpath_len = strlen(imgp->execpath) + 1;
 3362         else
 3363                 execpath_len = 0;
 3364         arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent->
 3365             sv_psstrings;
 3366         imgp->ps_strings = arginfo;
 3367         if (imgp->proc->p_sysent->sv_sigcode_base == 0)
 3368                 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
 3369         else
 3370                 szsigcode = 0;
 3371         destp = (uintptr_t)arginfo;
 3372 
 3373         /*
 3374          * install sigcode
 3375          */
 3376         if (szsigcode != 0) {
 3377                 destp -= szsigcode;
 3378                 destp = rounddown2(destp, sizeof(uint32_t));
 3379                 error = copyout(imgp->proc->p_sysent->sv_sigcode, (void *)destp,
 3380                     szsigcode);
 3381                 if (error != 0)
 3382                         return (error);
 3383         }
 3384 
 3385         /*
 3386          * Copy the image path for the rtld.
 3387          */
 3388         if (execpath_len != 0) {
 3389                 destp -= execpath_len;
 3390                 imgp->execpathp = (void *)destp;
 3391                 error = copyout(imgp->execpath, imgp->execpathp, execpath_len);
 3392                 if (error != 0)
 3393                         return (error);
 3394         }
 3395 
 3396         /*
 3397          * Prepare the canary for SSP.
 3398          */
 3399         arc4rand(canary, sizeof(canary), 0);
 3400         destp -= sizeof(canary);
 3401         imgp->canary = (void *)destp;
 3402         error = copyout(canary, imgp->canary, sizeof(canary));
 3403         if (error != 0)
 3404                 return (error);
 3405         imgp->canarylen = sizeof(canary);
 3406 
 3407         /*
 3408          * Prepare the pagesizes array.
 3409          */
 3410         for (i = 0; i < MAXPAGESIZES; i++)
 3411                 pagesizes32[i] = (uint32_t)pagesizes[i];
 3412         destp -= sizeof(pagesizes32);
 3413         destp = rounddown2(destp, sizeof(uint32_t));
 3414         imgp->pagesizes = (void *)destp;
 3415         error = copyout(pagesizes32, imgp->pagesizes, sizeof(pagesizes32));
 3416         if (error != 0)
 3417                 return (error);
 3418         imgp->pagesizeslen = sizeof(pagesizes32);
 3419 
 3420         /*
 3421          * Allocate room for the argument and environment strings.
 3422          */
 3423         destp -= ARG_MAX - imgp->args->stringspace;
 3424         destp = rounddown2(destp, sizeof(uint32_t));
 3425         ustringp = destp;
 3426 
 3427         exec_stackgap(imgp, &destp);
 3428 
 3429         if (imgp->auxargs) {
 3430                 /*
 3431                  * Allocate room on the stack for the ELF auxargs
 3432                  * array.  It has up to AT_COUNT entries.
 3433                  */
 3434                 destp -= AT_COUNT * sizeof(Elf32_Auxinfo);
 3435                 destp = rounddown2(destp, sizeof(uint32_t));
 3436         }
 3437 
 3438         vectp = (uint32_t *)destp;
 3439 
 3440         /*
 3441          * Allocate room for the argv[] and env vectors including the
 3442          * terminating NULL pointers.
 3443          */
 3444         vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
 3445 
 3446         /*
 3447          * vectp also becomes our initial stack base
 3448          */
 3449         *stack_base = (uintptr_t)vectp;
 3450 
 3451         stringp = imgp->args->begin_argv;
 3452         argc = imgp->args->argc;
 3453         envc = imgp->args->envc;
 3454         /*
 3455          * Copy out strings - arguments and environment.
 3456          */
 3457         error = copyout(stringp, (void *)ustringp,
 3458             ARG_MAX - imgp->args->stringspace);
 3459         if (error != 0)
 3460                 return (error);
 3461 
 3462         /*
 3463          * Fill in "ps_strings" struct for ps, w, etc.
 3464          */
 3465         imgp->argv = vectp;
 3466         if (suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp) != 0 ||
 3467             suword32(&arginfo->ps_nargvstr, argc) != 0)
 3468                 return (EFAULT);
 3469 
 3470         /*
 3471          * Fill in argument portion of vector table.
 3472          */
 3473         for (; argc > 0; --argc) {
 3474                 if (suword32(vectp++, ustringp) != 0)
 3475                         return (EFAULT);
 3476                 while (*stringp++ != 0)
 3477                         ustringp++;
 3478                 ustringp++;
 3479         }
 3480 
 3481         /* a null vector table pointer separates the argp's from the envp's */
 3482         if (suword32(vectp++, 0) != 0)
 3483                 return (EFAULT);
 3484 
 3485         imgp->envv = vectp;
 3486         if (suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp) != 0 ||
 3487             suword32(&arginfo->ps_nenvstr, envc) != 0)
 3488                 return (EFAULT);
 3489 
 3490         /*
 3491          * Fill in environment portion of vector table.
 3492          */
 3493         for (; envc > 0; --envc) {
 3494                 if (suword32(vectp++, ustringp) != 0)
 3495                         return (EFAULT);
 3496                 while (*stringp++ != 0)
 3497                         ustringp++;
 3498                 ustringp++;
 3499         }
 3500 
 3501         /* end of vector table is a null pointer */
 3502         if (suword32(vectp, 0) != 0)
 3503                 return (EFAULT);
 3504 
 3505         if (imgp->auxargs) {
 3506                 vectp++;
 3507                 error = imgp->sysent->sv_copyout_auxargs(imgp,
 3508                     (uintptr_t)vectp);
 3509                 if (error != 0)
 3510                         return (error);
 3511         }
 3512 
 3513         return (0);
 3514 }
 3515 
 3516 int
 3517 freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
 3518 {
 3519         struct kld_file_stat *stat;
 3520         struct kld32_file_stat *stat32;
 3521         int error, version;
 3522 
 3523         if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
 3524             != 0)
 3525                 return (error);
 3526         if (version != sizeof(struct kld32_file_stat_1) &&
 3527             version != sizeof(struct kld32_file_stat))
 3528                 return (EINVAL);
 3529 
 3530         stat = malloc(sizeof(*stat), M_TEMP, M_WAITOK | M_ZERO);
 3531         stat32 = malloc(sizeof(*stat32), M_TEMP, M_WAITOK | M_ZERO);
 3532         error = kern_kldstat(td, uap->fileid, stat);
 3533         if (error == 0) {
 3534                 bcopy(&stat->name[0], &stat32->name[0], sizeof(stat->name));
 3535                 CP(*stat, *stat32, refs);
 3536                 CP(*stat, *stat32, id);
 3537                 PTROUT_CP(*stat, *stat32, address);
 3538                 CP(*stat, *stat32, size);
 3539                 bcopy(&stat->pathname[0], &stat32->pathname[0],
 3540                     sizeof(stat->pathname));
 3541                 stat32->version  = version;
 3542                 error = copyout(stat32, uap->stat, version);
 3543         }
 3544         free(stat, M_TEMP);
 3545         free(stat32, M_TEMP);
 3546         return (error);
 3547 }
 3548 
 3549 int
 3550 freebsd32_posix_fallocate(struct thread *td,
 3551     struct freebsd32_posix_fallocate_args *uap)
 3552 {
 3553         int error;
 3554 
 3555         error = kern_posix_fallocate(td, uap->fd,
 3556             PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len));
 3557         return (kern_posix_error(td, error));
 3558 }
 3559 
 3560 int
 3561 freebsd32_posix_fadvise(struct thread *td,
 3562     struct freebsd32_posix_fadvise_args *uap)
 3563 {
 3564         int error;
 3565 
 3566         error = kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
 3567             PAIR32TO64(off_t, uap->len), uap->advice);
 3568         return (kern_posix_error(td, error));
 3569 }
 3570 
 3571 int
 3572 convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
 3573 {
 3574 
 3575         CP(*sig32, *sig, sigev_notify);
 3576         switch (sig->sigev_notify) {
 3577         case SIGEV_NONE:
 3578                 break;
 3579         case SIGEV_THREAD_ID:
 3580                 CP(*sig32, *sig, sigev_notify_thread_id);
 3581                 /* FALLTHROUGH */
 3582         case SIGEV_SIGNAL:
 3583                 CP(*sig32, *sig, sigev_signo);
 3584                 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
 3585                 break;
 3586         case SIGEV_KEVENT:
 3587                 CP(*sig32, *sig, sigev_notify_kqueue);
 3588                 CP(*sig32, *sig, sigev_notify_kevent_flags);
 3589                 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
 3590                 break;
 3591         default:
 3592                 return (EINVAL);
 3593         }
 3594         return (0);
 3595 }
 3596 
 3597 int
 3598 freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap)
 3599 {
 3600         void *data;
 3601         union {
 3602                 struct procctl_reaper_status rs;
 3603                 struct procctl_reaper_pids rp;
 3604                 struct procctl_reaper_kill rk;
 3605         } x;
 3606         union {
 3607                 struct procctl_reaper_pids32 rp;
 3608         } x32;
 3609         int error, error1, flags, signum;
 3610 
 3611         if (uap->com >= PROC_PROCCTL_MD_MIN)
 3612                 return (cpu_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
 3613                     uap->com, PTRIN(uap->data)));
 3614 
 3615         switch (uap->com) {
 3616         case PROC_ASLR_CTL:
 3617         case PROC_PROTMAX_CTL:
 3618         case PROC_SPROTECT:
 3619         case PROC_STACKGAP_CTL:
 3620         case PROC_TRACE_CTL:
 3621         case PROC_TRAPCAP_CTL:
 3622                 error = copyin(PTRIN(uap->data), &flags, sizeof(flags));
 3623                 if (error != 0)
 3624                         return (error);
 3625                 data = &flags;
 3626                 break;
 3627         case PROC_REAP_ACQUIRE:
 3628         case PROC_REAP_RELEASE:
 3629                 if (uap->data != NULL)
 3630                         return (EINVAL);
 3631                 data = NULL;
 3632                 break;
 3633         case PROC_REAP_STATUS:
 3634                 data = &x.rs;
 3635                 break;
 3636         case PROC_REAP_GETPIDS:
 3637                 error = copyin(uap->data, &x32.rp, sizeof(x32.rp));
 3638                 if (error != 0)
 3639                         return (error);
 3640                 CP(x32.rp, x.rp, rp_count);
 3641                 PTRIN_CP(x32.rp, x.rp, rp_pids);
 3642                 data = &x.rp;
 3643                 break;
 3644         case PROC_REAP_KILL:
 3645                 error = copyin(uap->data, &x.rk, sizeof(x.rk));
 3646                 if (error != 0)
 3647                         return (error);
 3648                 data = &x.rk;
 3649                 break;
 3650         case PROC_ASLR_STATUS:
 3651         case PROC_PROTMAX_STATUS:
 3652         case PROC_STACKGAP_STATUS:
 3653         case PROC_TRACE_STATUS:
 3654         case PROC_TRAPCAP_STATUS:
 3655                 data = &flags;
 3656                 break;
 3657         case PROC_PDEATHSIG_CTL:
 3658                 error = copyin(uap->data, &signum, sizeof(signum));
 3659                 if (error != 0)
 3660                         return (error);
 3661                 data = &signum;
 3662                 break;
 3663         case PROC_PDEATHSIG_STATUS:
 3664                 data = &signum;
 3665                 break;
 3666         default:
 3667                 return (EINVAL);
 3668         }
 3669         error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
 3670             uap->com, data);
 3671         switch (uap->com) {
 3672         case PROC_REAP_STATUS:
 3673                 if (error == 0)
 3674                         error = copyout(&x.rs, uap->data, sizeof(x.rs));
 3675                 break;
 3676         case PROC_REAP_KILL:
 3677                 error1 = copyout(&x.rk, uap->data, sizeof(x.rk));
 3678                 if (error == 0)
 3679                         error = error1;
 3680                 break;
 3681         case PROC_ASLR_STATUS:
 3682         case PROC_PROTMAX_STATUS:
 3683         case PROC_STACKGAP_STATUS:
 3684         case PROC_TRACE_STATUS:
 3685         case PROC_TRAPCAP_STATUS:
 3686                 if (error == 0)
 3687                         error = copyout(&flags, uap->data, sizeof(flags));
 3688                 break;
 3689         case PROC_PDEATHSIG_STATUS:
 3690                 if (error == 0)
 3691                         error = copyout(&signum, uap->data, sizeof(signum));
 3692                 break;
 3693         }
 3694         return (error);
 3695 }
 3696 
 3697 int
 3698 freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap)
 3699 {
 3700         long tmp;
 3701 
 3702         switch (uap->cmd) {
 3703         /*
 3704          * Do unsigned conversion for arg when operation
 3705          * interprets it as flags or pointer.
 3706          */
 3707         case F_SETLK_REMOTE:
 3708         case F_SETLKW:
 3709         case F_SETLK:
 3710         case F_GETLK:
 3711         case F_SETFD:
 3712         case F_SETFL:
 3713         case F_OGETLK:
 3714         case F_OSETLK:
 3715         case F_OSETLKW:
 3716                 tmp = (unsigned int)(uap->arg);
 3717                 break;
 3718         default:
 3719                 tmp = uap->arg;
 3720                 break;
 3721         }
 3722         return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
 3723 }
 3724 
 3725 int
 3726 freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap)
 3727 {
 3728         struct timespec32 ts32;
 3729         struct timespec ts, *tsp;
 3730         sigset_t set, *ssp;
 3731         int error;
 3732 
 3733         if (uap->ts != NULL) {
 3734                 error = copyin(uap->ts, &ts32, sizeof(ts32));
 3735                 if (error != 0)
 3736                         return (error);
 3737                 CP(ts32, ts, tv_sec);
 3738                 CP(ts32, ts, tv_nsec);
 3739                 tsp = &ts;
 3740         } else
 3741                 tsp = NULL;
 3742         if (uap->set != NULL) {
 3743                 error = copyin(uap->set, &set, sizeof(set));
 3744                 if (error != 0)
 3745                         return (error);
 3746                 ssp = &set;
 3747         } else
 3748                 ssp = NULL;
 3749 
 3750         return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
 3751 }
 3752 
 3753 int
 3754 freebsd32_sched_rr_get_interval(struct thread *td,
 3755     struct freebsd32_sched_rr_get_interval_args *uap)
 3756 {
 3757         struct timespec ts;
 3758         struct timespec32 ts32;
 3759         int error;
 3760 
 3761         error = kern_sched_rr_get_interval(td, uap->pid, &ts);
 3762         if (error == 0) {
 3763                 CP(ts, ts32, tv_sec);
 3764                 CP(ts, ts32, tv_nsec);
 3765                 error = copyout(&ts32, uap->interval, sizeof(ts32));
 3766         }
 3767         return (error);
 3768 }
 3769 
 3770 static void
 3771 timex_to_32(struct timex32 *dst, struct timex *src)
 3772 {
 3773         CP(*src, *dst, modes);
 3774         CP(*src, *dst, offset);
 3775         CP(*src, *dst, freq);
 3776         CP(*src, *dst, maxerror);
 3777         CP(*src, *dst, esterror);
 3778         CP(*src, *dst, status);
 3779         CP(*src, *dst, constant);
 3780         CP(*src, *dst, precision);
 3781         CP(*src, *dst, tolerance);
 3782         CP(*src, *dst, ppsfreq);
 3783         CP(*src, *dst, jitter);
 3784         CP(*src, *dst, shift);
 3785         CP(*src, *dst, stabil);
 3786         CP(*src, *dst, jitcnt);
 3787         CP(*src, *dst, calcnt);
 3788         CP(*src, *dst, errcnt);
 3789         CP(*src, *dst, stbcnt);
 3790 }
 3791 
 3792 static void
 3793 timex_from_32(struct timex *dst, struct timex32 *src)
 3794 {
 3795         CP(*src, *dst, modes);
 3796         CP(*src, *dst, offset);
 3797         CP(*src, *dst, freq);
 3798         CP(*src, *dst, maxerror);
 3799         CP(*src, *dst, esterror);
 3800         CP(*src, *dst, status);
 3801         CP(*src, *dst, constant);
 3802         CP(*src, *dst, precision);
 3803         CP(*src, *dst, tolerance);
 3804         CP(*src, *dst, ppsfreq);
 3805         CP(*src, *dst, jitter);
 3806         CP(*src, *dst, shift);
 3807         CP(*src, *dst, stabil);
 3808         CP(*src, *dst, jitcnt);
 3809         CP(*src, *dst, calcnt);
 3810         CP(*src, *dst, errcnt);
 3811         CP(*src, *dst, stbcnt);
 3812 }
 3813 
 3814 int
 3815 freebsd32_ntp_adjtime(struct thread *td, struct freebsd32_ntp_adjtime_args *uap)
 3816 {
 3817         struct timex tx;
 3818         struct timex32 tx32;
 3819         int error, retval;
 3820 
 3821         error = copyin(uap->tp, &tx32, sizeof(tx32));
 3822         if (error == 0) {
 3823                 timex_from_32(&tx, &tx32);
 3824                 error = kern_ntp_adjtime(td, &tx, &retval);
 3825                 if (error == 0) {
 3826                         timex_to_32(&tx32, &tx);
 3827                         error = copyout(&tx32, uap->tp, sizeof(tx32));
 3828                         if (error == 0)
 3829                                 td->td_retval[0] = retval;
 3830                 }
 3831         }
 3832         return (error);
 3833 }

Cache object: 551bbffea2ebd0a66bf9443781aa15e9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.