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

Cache object: 0e0ad9a30e6867e4a53fd4de7454d8b0


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