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

Cache object: ab8625980f6f5a7adbc9f7af071218c5


[ 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.