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  * Copyright (c) 2002 Doug Rabson
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/9.1/sys/compat/freebsd32/freebsd32_misc.c 237134 2012-06-15 10:38:14Z kib $");
   29 
   30 #include "opt_compat.h"
   31 #include "opt_inet.h"
   32 #include "opt_inet6.h"
   33 
   34 #define __ELF_WORD_SIZE 32
   35 
   36 #include <sys/param.h>
   37 #include <sys/bus.h>
   38 #include <sys/clock.h>
   39 #include <sys/exec.h>
   40 #include <sys/fcntl.h>
   41 #include <sys/filedesc.h>
   42 #include <sys/imgact.h>
   43 #include <sys/jail.h>
   44 #include <sys/kernel.h>
   45 #include <sys/limits.h>
   46 #include <sys/linker.h>
   47 #include <sys/lock.h>
   48 #include <sys/malloc.h>
   49 #include <sys/file.h>           /* Must come after sys/malloc.h */
   50 #include <sys/imgact.h>
   51 #include <sys/mbuf.h>
   52 #include <sys/mman.h>
   53 #include <sys/module.h>
   54 #include <sys/mount.h>
   55 #include <sys/mutex.h>
   56 #include <sys/namei.h>
   57 #include <sys/proc.h>
   58 #include <sys/reboot.h>
   59 #include <sys/resource.h>
   60 #include <sys/resourcevar.h>
   61 #include <sys/selinfo.h>
   62 #include <sys/eventvar.h>       /* Must come after sys/selinfo.h */
   63 #include <sys/pipe.h>           /* Must come after sys/selinfo.h */
   64 #include <sys/signal.h>
   65 #include <sys/signalvar.h>
   66 #include <sys/socket.h>
   67 #include <sys/socketvar.h>
   68 #include <sys/stat.h>
   69 #include <sys/syscall.h>
   70 #include <sys/syscallsubr.h>
   71 #include <sys/sysctl.h>
   72 #include <sys/sysent.h>
   73 #include <sys/sysproto.h>
   74 #include <sys/systm.h>
   75 #include <sys/thr.h>
   76 #include <sys/unistd.h>
   77 #include <sys/ucontext.h>
   78 #include <sys/vnode.h>
   79 #include <sys/wait.h>
   80 #include <sys/ipc.h>
   81 #include <sys/msg.h>
   82 #include <sys/sem.h>
   83 #include <sys/shm.h>
   84 
   85 #ifdef INET
   86 #include <netinet/in.h>
   87 #endif
   88 
   89 #include <vm/vm.h>
   90 #include <vm/vm_param.h>
   91 #include <vm/pmap.h>
   92 #include <vm/vm_map.h>
   93 #include <vm/vm_object.h>
   94 #include <vm/vm_extern.h>
   95 
   96 #include <machine/cpu.h>
   97 #include <machine/elf.h>
   98 
   99 #include <security/audit/audit.h>
  100 
  101 #include <compat/freebsd32/freebsd32_util.h>
  102 #include <compat/freebsd32/freebsd32.h>
  103 #include <compat/freebsd32/freebsd32_ipc.h>
  104 #include <compat/freebsd32/freebsd32_signal.h>
  105 #include <compat/freebsd32/freebsd32_proto.h>
  106 
  107 CTASSERT(sizeof(struct timeval32) == 8);
  108 CTASSERT(sizeof(struct timespec32) == 8);
  109 CTASSERT(sizeof(struct itimerval32) == 16);
  110 CTASSERT(sizeof(struct statfs32) == 256);
  111 CTASSERT(sizeof(struct rusage32) == 72);
  112 CTASSERT(sizeof(struct sigaltstack32) == 12);
  113 CTASSERT(sizeof(struct kevent32) == 20);
  114 CTASSERT(sizeof(struct iovec32) == 8);
  115 CTASSERT(sizeof(struct msghdr32) == 28);
  116 CTASSERT(sizeof(struct stat32) == 96);
  117 CTASSERT(sizeof(struct sigaction32) == 24);
  118 
  119 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
  120 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
  121 
  122 #if BYTE_ORDER == BIG_ENDIAN
  123 #define PAIR32TO64(type, name) ((name ## 2) | ((type)(name ## 1) << 32))
  124 #define RETVAL_HI 0     
  125 #define RETVAL_LO 1     
  126 #else
  127 #define PAIR32TO64(type, name) ((name ## 1) | ((type)(name ## 2) << 32))
  128 #define RETVAL_HI 1     
  129 #define RETVAL_LO 0     
  130 #endif
  131 
  132 void
  133 freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
  134 {
  135 
  136         TV_CP(*s, *s32, ru_utime);
  137         TV_CP(*s, *s32, ru_stime);
  138         CP(*s, *s32, ru_maxrss);
  139         CP(*s, *s32, ru_ixrss);
  140         CP(*s, *s32, ru_idrss);
  141         CP(*s, *s32, ru_isrss);
  142         CP(*s, *s32, ru_minflt);
  143         CP(*s, *s32, ru_majflt);
  144         CP(*s, *s32, ru_nswap);
  145         CP(*s, *s32, ru_inblock);
  146         CP(*s, *s32, ru_oublock);
  147         CP(*s, *s32, ru_msgsnd);
  148         CP(*s, *s32, ru_msgrcv);
  149         CP(*s, *s32, ru_nsignals);
  150         CP(*s, *s32, ru_nvcsw);
  151         CP(*s, *s32, ru_nivcsw);
  152 }
  153 
  154 int
  155 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
  156 {
  157         int error, status;
  158         struct rusage32 ru32;
  159         struct rusage ru, *rup;
  160 
  161         if (uap->rusage != NULL)
  162                 rup = &ru;
  163         else
  164                 rup = NULL;
  165         error = kern_wait(td, uap->pid, &status, uap->options, rup);
  166         if (error)
  167                 return (error);
  168         if (uap->status != NULL)
  169                 error = copyout(&status, uap->status, sizeof(status));
  170         if (uap->rusage != NULL && error == 0) {
  171                 freebsd32_rusage_out(&ru, &ru32);
  172                 error = copyout(&ru32, uap->rusage, sizeof(ru32));
  173         }
  174         return (error);
  175 }
  176 
  177 #ifdef COMPAT_FREEBSD4
  178 static void
  179 copy_statfs(struct statfs *in, struct statfs32 *out)
  180 {
  181 
  182         statfs_scale_blocks(in, INT32_MAX);
  183         bzero(out, sizeof(*out));
  184         CP(*in, *out, f_bsize);
  185         out->f_iosize = MIN(in->f_iosize, INT32_MAX);
  186         CP(*in, *out, f_blocks);
  187         CP(*in, *out, f_bfree);
  188         CP(*in, *out, f_bavail);
  189         out->f_files = MIN(in->f_files, INT32_MAX);
  190         out->f_ffree = MIN(in->f_ffree, INT32_MAX);
  191         CP(*in, *out, f_fsid);
  192         CP(*in, *out, f_owner);
  193         CP(*in, *out, f_type);
  194         CP(*in, *out, f_flags);
  195         out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX);
  196         out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX);
  197         strlcpy(out->f_fstypename,
  198               in->f_fstypename, MFSNAMELEN);
  199         strlcpy(out->f_mntonname,
  200               in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  201         out->f_syncreads = MIN(in->f_syncreads, INT32_MAX);
  202         out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX);
  203         strlcpy(out->f_mntfromname,
  204               in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  205 }
  206 #endif
  207 
  208 #ifdef COMPAT_FREEBSD4
  209 int
  210 freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
  211 {
  212         struct statfs *buf, *sp;
  213         struct statfs32 stat32;
  214         size_t count, size;
  215         int error;
  216 
  217         count = uap->bufsize / sizeof(struct statfs32);
  218         size = count * sizeof(struct statfs);
  219         error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
  220         if (size > 0) {
  221                 count = td->td_retval[0];
  222                 sp = buf;
  223                 while (count > 0 && error == 0) {
  224                         copy_statfs(sp, &stat32);
  225                         error = copyout(&stat32, uap->buf, sizeof(stat32));
  226                         sp++;
  227                         uap->buf++;
  228                         count--;
  229                 }
  230                 free(buf, M_TEMP);
  231         }
  232         return (error);
  233 }
  234 #endif
  235 
  236 int
  237 freebsd32_sigaltstack(struct thread *td,
  238                       struct freebsd32_sigaltstack_args *uap)
  239 {
  240         struct sigaltstack32 s32;
  241         struct sigaltstack ss, oss, *ssp;
  242         int error;
  243 
  244         if (uap->ss != NULL) {
  245                 error = copyin(uap->ss, &s32, sizeof(s32));
  246                 if (error)
  247                         return (error);
  248                 PTRIN_CP(s32, ss, ss_sp);
  249                 CP(s32, ss, ss_size);
  250                 CP(s32, ss, ss_flags);
  251                 ssp = &ss;
  252         } else
  253                 ssp = NULL;
  254         error = kern_sigaltstack(td, ssp, &oss);
  255         if (error == 0 && uap->oss != NULL) {
  256                 PTROUT_CP(oss, s32, ss_sp);
  257                 CP(oss, s32, ss_size);
  258                 CP(oss, s32, ss_flags);
  259                 error = copyout(&s32, uap->oss, sizeof(s32));
  260         }
  261         return (error);
  262 }
  263 
  264 /*
  265  * Custom version of exec_copyin_args() so that we can translate
  266  * the pointers.
  267  */
  268 int
  269 freebsd32_exec_copyin_args(struct image_args *args, char *fname,
  270     enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
  271 {
  272         char *argp, *envp;
  273         u_int32_t *p32, arg;
  274         size_t length;
  275         int error;
  276 
  277         bzero(args, sizeof(*args));
  278         if (argv == NULL)
  279                 return (EFAULT);
  280 
  281         /*
  282          * Allocate demand-paged memory for the file name, argument, and
  283          * environment strings.
  284          */
  285         error = exec_alloc_args(args);
  286         if (error != 0)
  287                 return (error);
  288 
  289         /*
  290          * Copy the file name.
  291          */
  292         if (fname != NULL) {
  293                 args->fname = args->buf;
  294                 error = (segflg == UIO_SYSSPACE) ?
  295                     copystr(fname, args->fname, PATH_MAX, &length) :
  296                     copyinstr(fname, args->fname, PATH_MAX, &length);
  297                 if (error != 0)
  298                         goto err_exit;
  299         } else
  300                 length = 0;
  301 
  302         args->begin_argv = args->buf + length;
  303         args->endp = args->begin_argv;
  304         args->stringspace = ARG_MAX;
  305 
  306         /*
  307          * extract arguments first
  308          */
  309         p32 = argv;
  310         for (;;) {
  311                 error = copyin(p32++, &arg, sizeof(arg));
  312                 if (error)
  313                         goto err_exit;
  314                 if (arg == 0)
  315                         break;
  316                 argp = PTRIN(arg);
  317                 error = copyinstr(argp, args->endp, args->stringspace, &length);
  318                 if (error) {
  319                         if (error == ENAMETOOLONG)
  320                                 error = E2BIG;
  321                         goto err_exit;
  322                 }
  323                 args->stringspace -= length;
  324                 args->endp += length;
  325                 args->argc++;
  326         }
  327                         
  328         args->begin_envv = args->endp;
  329 
  330         /*
  331          * extract environment strings
  332          */
  333         if (envv) {
  334                 p32 = envv;
  335                 for (;;) {
  336                         error = copyin(p32++, &arg, sizeof(arg));
  337                         if (error)
  338                                 goto err_exit;
  339                         if (arg == 0)
  340                                 break;
  341                         envp = PTRIN(arg);
  342                         error = copyinstr(envp, args->endp, args->stringspace,
  343                             &length);
  344                         if (error) {
  345                                 if (error == ENAMETOOLONG)
  346                                         error = E2BIG;
  347                                 goto err_exit;
  348                         }
  349                         args->stringspace -= length;
  350                         args->endp += length;
  351                         args->envc++;
  352                 }
  353         }
  354 
  355         return (0);
  356 
  357 err_exit:
  358         exec_free_args(args);
  359         return (error);
  360 }
  361 
  362 int
  363 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
  364 {
  365         struct image_args eargs;
  366         int error;
  367 
  368         error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
  369             uap->argv, uap->envv);
  370         if (error == 0)
  371                 error = kern_execve(td, &eargs, NULL);
  372         return (error);
  373 }
  374 
  375 int
  376 freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
  377 {
  378         struct image_args eargs;
  379         int error;
  380 
  381         error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE,
  382             uap->argv, uap->envv);
  383         if (error == 0) {
  384                 eargs.fd = uap->fd;
  385                 error = kern_execve(td, &eargs, NULL);
  386         }
  387         return (error);
  388 }
  389 
  390 #ifdef __ia64__
  391 static int
  392 freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
  393                        int prot, int fd, off_t pos)
  394 {
  395         vm_map_t map;
  396         vm_map_entry_t entry;
  397         int rv;
  398 
  399         map = &td->td_proc->p_vmspace->vm_map;
  400         if (fd != -1)
  401                 prot |= VM_PROT_WRITE;
  402 
  403         if (vm_map_lookup_entry(map, start, &entry)) {
  404                 if ((entry->protection & prot) != prot) {
  405                         rv = vm_map_protect(map,
  406                                             trunc_page(start),
  407                                             round_page(end),
  408                                             entry->protection | prot,
  409                                             FALSE);
  410                         if (rv != KERN_SUCCESS)
  411                                 return (EINVAL);
  412                 }
  413         } else {
  414                 vm_offset_t addr = trunc_page(start);
  415                 rv = vm_map_find(map, 0, 0,
  416                                  &addr, PAGE_SIZE, FALSE, prot,
  417                                  VM_PROT_ALL, 0);
  418                 if (rv != KERN_SUCCESS)
  419                         return (EINVAL);
  420         }
  421 
  422         if (fd != -1) {
  423                 struct pread_args r;
  424                 r.fd = fd;
  425                 r.buf = (void *) start;
  426                 r.nbyte = end - start;
  427                 r.offset = pos;
  428                 return (sys_pread(td, &r));
  429         } else {
  430                 while (start < end) {
  431                         subyte((void *) start, 0);
  432                         start++;
  433                 }
  434                 return (0);
  435         }
  436 }
  437 #endif
  438 
  439 int
  440 freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
  441 {
  442         struct mprotect_args ap;
  443 
  444         ap.addr = PTRIN(uap->addr);
  445         ap.len = uap->len;
  446         ap.prot = uap->prot;
  447 #if defined(__amd64__) || defined(__ia64__)
  448         if (i386_read_exec && (ap.prot & PROT_READ) != 0)
  449                 ap.prot |= PROT_EXEC;
  450 #endif
  451         return (sys_mprotect(td, &ap));
  452 }
  453 
  454 int
  455 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
  456 {
  457         struct mmap_args ap;
  458         vm_offset_t addr = (vm_offset_t) uap->addr;
  459         vm_size_t len    = uap->len;
  460         int prot         = uap->prot;
  461         int flags        = uap->flags;
  462         int fd           = uap->fd;
  463         off_t pos        = PAIR32TO64(off_t,uap->pos);
  464 #ifdef __ia64__
  465         vm_size_t pageoff;
  466         int error;
  467 
  468         /*
  469          * Attempt to handle page size hassles.
  470          */
  471         pageoff = (pos & PAGE_MASK);
  472         if (flags & MAP_FIXED) {
  473                 vm_offset_t start, end;
  474                 start = addr;
  475                 end = addr + len;
  476 
  477                 if (start != trunc_page(start)) {
  478                         error = freebsd32_mmap_partial(td, start,
  479                                                        round_page(start), prot,
  480                                                        fd, pos);
  481                         if (fd != -1)
  482                                 pos += round_page(start) - start;
  483                         start = round_page(start);
  484                 }
  485                 if (end != round_page(end)) {
  486                         vm_offset_t t = trunc_page(end);
  487                         error = freebsd32_mmap_partial(td, t, end,
  488                                                   prot, fd,
  489                                                   pos + t - start);
  490                         end = trunc_page(end);
  491                 }
  492                 if (end > start && fd != -1 && (pos & PAGE_MASK)) {
  493                         /*
  494                          * We can't map this region at all. The specified
  495                          * address doesn't have the same alignment as the file
  496                          * position. Fake the mapping by simply reading the
  497                          * entire region into memory. First we need to make
  498                          * sure the region exists.
  499                          */
  500                         vm_map_t map;
  501                         struct pread_args r;
  502                         int rv;
  503 
  504                         prot |= VM_PROT_WRITE;
  505                         map = &td->td_proc->p_vmspace->vm_map;
  506                         rv = vm_map_remove(map, start, end);
  507                         if (rv != KERN_SUCCESS)
  508                                 return (EINVAL);
  509                         rv = vm_map_find(map, 0, 0,
  510                                          &start, end - start, FALSE,
  511                                          prot, VM_PROT_ALL, 0);
  512                         if (rv != KERN_SUCCESS)
  513                                 return (EINVAL);
  514                         r.fd = fd;
  515                         r.buf = (void *) start;
  516                         r.nbyte = end - start;
  517                         r.offset = pos;
  518                         error = sys_pread(td, &r);
  519                         if (error)
  520                                 return (error);
  521 
  522                         td->td_retval[0] = addr;
  523                         return (0);
  524                 }
  525                 if (end == start) {
  526                         /*
  527                          * After dealing with the ragged ends, there
  528                          * might be none left.
  529                          */
  530                         td->td_retval[0] = addr;
  531                         return (0);
  532                 }
  533                 addr = start;
  534                 len = end - start;
  535         }
  536 #endif
  537 
  538 #if defined(__amd64__) || defined(__ia64__)
  539         if (i386_read_exec && (prot & PROT_READ))
  540                 prot |= PROT_EXEC;
  541 #endif
  542 
  543         ap.addr = (void *) addr;
  544         ap.len = len;
  545         ap.prot = prot;
  546         ap.flags = flags;
  547         ap.fd = fd;
  548         ap.pos = pos;
  549 
  550         return (sys_mmap(td, &ap));
  551 }
  552 
  553 #ifdef COMPAT_FREEBSD6
  554 int
  555 freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap)
  556 {
  557         struct freebsd32_mmap_args ap;
  558 
  559         ap.addr = uap->addr;
  560         ap.len = uap->len;
  561         ap.prot = uap->prot;
  562         ap.flags = uap->flags;
  563         ap.fd = uap->fd;
  564         ap.pos1 = uap->pos1;
  565         ap.pos2 = uap->pos2;
  566 
  567         return (freebsd32_mmap(td, &ap));
  568 }
  569 #endif
  570 
  571 int
  572 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
  573 {
  574         struct itimerval itv, oitv, *itvp;      
  575         struct itimerval32 i32;
  576         int error;
  577 
  578         if (uap->itv != NULL) {
  579                 error = copyin(uap->itv, &i32, sizeof(i32));
  580                 if (error)
  581                         return (error);
  582                 TV_CP(i32, itv, it_interval);
  583                 TV_CP(i32, itv, it_value);
  584                 itvp = &itv;
  585         } else
  586                 itvp = NULL;
  587         error = kern_setitimer(td, uap->which, itvp, &oitv);
  588         if (error || uap->oitv == NULL)
  589                 return (error);
  590         TV_CP(oitv, i32, it_interval);
  591         TV_CP(oitv, i32, it_value);
  592         return (copyout(&i32, uap->oitv, sizeof(i32)));
  593 }
  594 
  595 int
  596 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
  597 {
  598         struct itimerval itv;
  599         struct itimerval32 i32;
  600         int error;
  601 
  602         error = kern_getitimer(td, uap->which, &itv);
  603         if (error || uap->itv == NULL)
  604                 return (error);
  605         TV_CP(itv, i32, it_interval);
  606         TV_CP(itv, i32, it_value);
  607         return (copyout(&i32, uap->itv, sizeof(i32)));
  608 }
  609 
  610 int
  611 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
  612 {
  613         struct timeval32 tv32;
  614         struct timeval tv, *tvp;
  615         int error;
  616 
  617         if (uap->tv != NULL) {
  618                 error = copyin(uap->tv, &tv32, sizeof(tv32));
  619                 if (error)
  620                         return (error);
  621                 CP(tv32, tv, tv_sec);
  622                 CP(tv32, tv, tv_usec);
  623                 tvp = &tv;
  624         } else
  625                 tvp = NULL;
  626         /*
  627          * XXX Do pointers need PTRIN()?
  628          */
  629         return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
  630             sizeof(int32_t) * 8));
  631 }
  632 
  633 int
  634 freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
  635 {
  636         struct timespec32 ts32;
  637         struct timespec ts;
  638         struct timeval tv, *tvp;
  639         sigset_t set, *uset;
  640         int error;
  641 
  642         if (uap->ts != NULL) {
  643                 error = copyin(uap->ts, &ts32, sizeof(ts32));
  644                 if (error != 0)
  645                         return (error);
  646                 CP(ts32, ts, tv_sec);
  647                 CP(ts32, ts, tv_nsec);
  648                 TIMESPEC_TO_TIMEVAL(&tv, &ts);
  649                 tvp = &tv;
  650         } else
  651                 tvp = NULL;
  652         if (uap->sm != NULL) {
  653                 error = copyin(uap->sm, &set, sizeof(set));
  654                 if (error != 0)
  655                         return (error);
  656                 uset = &set;
  657         } else
  658                 uset = NULL;
  659         /*
  660          * XXX Do pointers need PTRIN()?
  661          */
  662         error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
  663             uset, sizeof(int32_t) * 8);
  664         return (error);
  665 }
  666 
  667 /*
  668  * Copy 'count' items into the destination list pointed to by uap->eventlist.
  669  */
  670 static int
  671 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
  672 {
  673         struct freebsd32_kevent_args *uap;
  674         struct kevent32 ks32[KQ_NEVENTS];
  675         int i, error = 0;
  676 
  677         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  678         uap = (struct freebsd32_kevent_args *)arg;
  679 
  680         for (i = 0; i < count; i++) {
  681                 CP(kevp[i], ks32[i], ident);
  682                 CP(kevp[i], ks32[i], filter);
  683                 CP(kevp[i], ks32[i], flags);
  684                 CP(kevp[i], ks32[i], fflags);
  685                 CP(kevp[i], ks32[i], data);
  686                 PTROUT_CP(kevp[i], ks32[i], udata);
  687         }
  688         error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
  689         if (error == 0)
  690                 uap->eventlist += count;
  691         return (error);
  692 }
  693 
  694 /*
  695  * Copy 'count' items from the list pointed to by uap->changelist.
  696  */
  697 static int
  698 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
  699 {
  700         struct freebsd32_kevent_args *uap;
  701         struct kevent32 ks32[KQ_NEVENTS];
  702         int i, error = 0;
  703 
  704         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  705         uap = (struct freebsd32_kevent_args *)arg;
  706 
  707         error = copyin(uap->changelist, ks32, count * sizeof *ks32);
  708         if (error)
  709                 goto done;
  710         uap->changelist += count;
  711 
  712         for (i = 0; i < count; i++) {
  713                 CP(ks32[i], kevp[i], ident);
  714                 CP(ks32[i], kevp[i], filter);
  715                 CP(ks32[i], kevp[i], flags);
  716                 CP(ks32[i], kevp[i], fflags);
  717                 CP(ks32[i], kevp[i], data);
  718                 PTRIN_CP(ks32[i], kevp[i], udata);
  719         }
  720 done:
  721         return (error);
  722 }
  723 
  724 int
  725 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
  726 {
  727         struct timespec32 ts32;
  728         struct timespec ts, *tsp;
  729         struct kevent_copyops k_ops = { uap,
  730                                         freebsd32_kevent_copyout,
  731                                         freebsd32_kevent_copyin};
  732         int error;
  733 
  734 
  735         if (uap->timeout) {
  736                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
  737                 if (error)
  738                         return (error);
  739                 CP(ts32, ts, tv_sec);
  740                 CP(ts32, ts, tv_nsec);
  741                 tsp = &ts;
  742         } else
  743                 tsp = NULL;
  744         error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
  745             &k_ops, tsp);
  746         return (error);
  747 }
  748 
  749 int
  750 freebsd32_gettimeofday(struct thread *td,
  751                        struct freebsd32_gettimeofday_args *uap)
  752 {
  753         struct timeval atv;
  754         struct timeval32 atv32;
  755         struct timezone rtz;
  756         int error = 0;
  757 
  758         if (uap->tp) {
  759                 microtime(&atv);
  760                 CP(atv, atv32, tv_sec);
  761                 CP(atv, atv32, tv_usec);
  762                 error = copyout(&atv32, uap->tp, sizeof (atv32));
  763         }
  764         if (error == 0 && uap->tzp != NULL) {
  765                 rtz.tz_minuteswest = tz_minuteswest;
  766                 rtz.tz_dsttime = tz_dsttime;
  767                 error = copyout(&rtz, uap->tzp, sizeof (rtz));
  768         }
  769         return (error);
  770 }
  771 
  772 int
  773 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
  774 {
  775         struct rusage32 s32;
  776         struct rusage s;
  777         int error;
  778 
  779         error = kern_getrusage(td, uap->who, &s);
  780         if (error)
  781                 return (error);
  782         if (uap->rusage != NULL) {
  783                 freebsd32_rusage_out(&s, &s32);
  784                 error = copyout(&s32, uap->rusage, sizeof(s32));
  785         }
  786         return (error);
  787 }
  788 
  789 static int
  790 freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
  791 {
  792         struct iovec32 iov32;
  793         struct iovec *iov;
  794         struct uio *uio;
  795         u_int iovlen;
  796         int error, i;
  797 
  798         *uiop = NULL;
  799         if (iovcnt > UIO_MAXIOV)
  800                 return (EINVAL);
  801         iovlen = iovcnt * sizeof(struct iovec);
  802         uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
  803         iov = (struct iovec *)(uio + 1);
  804         for (i = 0; i < iovcnt; i++) {
  805                 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
  806                 if (error) {
  807                         free(uio, M_IOV);
  808                         return (error);
  809                 }
  810                 iov[i].iov_base = PTRIN(iov32.iov_base);
  811                 iov[i].iov_len = iov32.iov_len;
  812         }
  813         uio->uio_iov = iov;
  814         uio->uio_iovcnt = iovcnt;
  815         uio->uio_segflg = UIO_USERSPACE;
  816         uio->uio_offset = -1;
  817         uio->uio_resid = 0;
  818         for (i = 0; i < iovcnt; i++) {
  819                 if (iov->iov_len > INT_MAX - uio->uio_resid) {
  820                         free(uio, M_IOV);
  821                         return (EINVAL);
  822                 }
  823                 uio->uio_resid += iov->iov_len;
  824                 iov++;
  825         }
  826         *uiop = uio;
  827         return (0);
  828 }
  829 
  830 int
  831 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
  832 {
  833         struct uio *auio;
  834         int error;
  835 
  836         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  837         if (error)
  838                 return (error);
  839         error = kern_readv(td, uap->fd, auio);
  840         free(auio, M_IOV);
  841         return (error);
  842 }
  843 
  844 int
  845 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
  846 {
  847         struct uio *auio;
  848         int error;
  849 
  850         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  851         if (error)
  852                 return (error);
  853         error = kern_writev(td, uap->fd, auio);
  854         free(auio, M_IOV);
  855         return (error);
  856 }
  857 
  858 int
  859 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
  860 {
  861         struct uio *auio;
  862         int error;
  863 
  864         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  865         if (error)
  866                 return (error);
  867         error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
  868         free(auio, M_IOV);
  869         return (error);
  870 }
  871 
  872 int
  873 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
  874 {
  875         struct uio *auio;
  876         int error;
  877 
  878         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  879         if (error)
  880                 return (error);
  881         error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
  882         free(auio, M_IOV);
  883         return (error);
  884 }
  885 
  886 int
  887 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
  888     int error)
  889 {
  890         struct iovec32 iov32;
  891         struct iovec *iov;
  892         u_int iovlen;
  893         int i;
  894 
  895         *iovp = NULL;
  896         if (iovcnt > UIO_MAXIOV)
  897                 return (error);
  898         iovlen = iovcnt * sizeof(struct iovec);
  899         iov = malloc(iovlen, M_IOV, M_WAITOK);
  900         for (i = 0; i < iovcnt; i++) {
  901                 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
  902                 if (error) {
  903                         free(iov, M_IOV);
  904                         return (error);
  905                 }
  906                 iov[i].iov_base = PTRIN(iov32.iov_base);
  907                 iov[i].iov_len = iov32.iov_len;
  908         }
  909         *iovp = iov;
  910         return (0);
  911 }
  912 
  913 static int
  914 freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
  915 {
  916         struct msghdr32 m32;
  917         int error;
  918 
  919         error = copyin(msg32, &m32, sizeof(m32));
  920         if (error)
  921                 return (error);
  922         msg->msg_name = PTRIN(m32.msg_name);
  923         msg->msg_namelen = m32.msg_namelen;
  924         msg->msg_iov = PTRIN(m32.msg_iov);
  925         msg->msg_iovlen = m32.msg_iovlen;
  926         msg->msg_control = PTRIN(m32.msg_control);
  927         msg->msg_controllen = m32.msg_controllen;
  928         msg->msg_flags = m32.msg_flags;
  929         return (0);
  930 }
  931 
  932 static int
  933 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
  934 {
  935         struct msghdr32 m32;
  936         int error;
  937 
  938         m32.msg_name = PTROUT(msg->msg_name);
  939         m32.msg_namelen = msg->msg_namelen;
  940         m32.msg_iov = PTROUT(msg->msg_iov);
  941         m32.msg_iovlen = msg->msg_iovlen;
  942         m32.msg_control = PTROUT(msg->msg_control);
  943         m32.msg_controllen = msg->msg_controllen;
  944         m32.msg_flags = msg->msg_flags;
  945         error = copyout(&m32, msg32, sizeof(m32));
  946         return (error);
  947 }
  948 
  949 #define FREEBSD32_ALIGNBYTES    (sizeof(int) - 1)
  950 #define FREEBSD32_ALIGN(p)      \
  951         (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
  952 #define FREEBSD32_CMSG_SPACE(l) \
  953         (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
  954 
  955 #define FREEBSD32_CMSG_DATA(cmsg)       ((unsigned char *)(cmsg) + \
  956                                  FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
  957 static int
  958 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
  959 {
  960         struct cmsghdr *cm;
  961         void *data;
  962         socklen_t clen, datalen;
  963         int error;
  964         caddr_t ctlbuf;
  965         int len, maxlen, copylen;
  966         struct mbuf *m;
  967         error = 0;
  968 
  969         len    = msg->msg_controllen;
  970         maxlen = msg->msg_controllen;
  971         msg->msg_controllen = 0;
  972 
  973         m = control;
  974         ctlbuf = msg->msg_control;
  975       
  976         while (m && len > 0) {
  977                 cm = mtod(m, struct cmsghdr *);
  978                 clen = m->m_len;
  979 
  980                 while (cm != NULL) {
  981 
  982                         if (sizeof(struct cmsghdr) > clen ||
  983                             cm->cmsg_len > clen) {
  984                                 error = EINVAL;
  985                                 break;
  986                         }       
  987 
  988                         data   = CMSG_DATA(cm);
  989                         datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
  990 
  991                         /* Adjust message length */
  992                         cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
  993                             datalen;
  994 
  995 
  996                         /* Copy cmsghdr */
  997                         copylen = sizeof(struct cmsghdr);
  998                         if (len < copylen) {
  999                                 msg->msg_flags |= MSG_CTRUNC;
 1000                                 copylen = len;
 1001                         }
 1002 
 1003                         error = copyout(cm,ctlbuf,copylen);
 1004                         if (error)
 1005                                 goto exit;
 1006 
 1007                         ctlbuf += FREEBSD32_ALIGN(copylen);
 1008                         len    -= FREEBSD32_ALIGN(copylen);
 1009 
 1010                         if (len <= 0)
 1011                                 break;
 1012 
 1013                         /* Copy data */
 1014                         copylen = datalen;
 1015                         if (len < copylen) {
 1016                                 msg->msg_flags |= MSG_CTRUNC;
 1017                                 copylen = len;
 1018                         }
 1019 
 1020                         error = copyout(data,ctlbuf,copylen);
 1021                         if (error)
 1022                                 goto exit;
 1023 
 1024                         ctlbuf += FREEBSD32_ALIGN(copylen);
 1025                         len    -= FREEBSD32_ALIGN(copylen);
 1026 
 1027                         if (CMSG_SPACE(datalen) < clen) {
 1028                                 clen -= CMSG_SPACE(datalen);
 1029                                 cm = (struct cmsghdr *)
 1030                                         ((caddr_t)cm + CMSG_SPACE(datalen));
 1031                         } else {
 1032                                 clen = 0;
 1033                                 cm = NULL;
 1034                         }
 1035                 }       
 1036                 m = m->m_next;
 1037         }
 1038 
 1039         msg->msg_controllen = (len <= 0) ? maxlen :  ctlbuf - (caddr_t)msg->msg_control;
 1040         
 1041 exit:
 1042         return (error);
 1043 
 1044 }
 1045 
 1046 int
 1047 freebsd32_recvmsg(td, uap)
 1048         struct thread *td;
 1049         struct freebsd32_recvmsg_args /* {
 1050                 int     s;
 1051                 struct  msghdr32 *msg;
 1052                 int     flags;
 1053         } */ *uap;
 1054 {
 1055         struct msghdr msg;
 1056         struct msghdr32 m32;
 1057         struct iovec *uiov, *iov;
 1058         struct mbuf *control = NULL;
 1059         struct mbuf **controlp;
 1060 
 1061         int error;
 1062         error = copyin(uap->msg, &m32, sizeof(m32));
 1063         if (error)
 1064                 return (error);
 1065         error = freebsd32_copyinmsghdr(uap->msg, &msg);
 1066         if (error)
 1067                 return (error);
 1068         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
 1069             EMSGSIZE);
 1070         if (error)
 1071                 return (error);
 1072         msg.msg_flags = uap->flags;
 1073         uiov = msg.msg_iov;
 1074         msg.msg_iov = iov;
 1075 
 1076         controlp = (msg.msg_control != NULL) ?  &control : NULL;
 1077         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
 1078         if (error == 0) {
 1079                 msg.msg_iov = uiov;
 1080                 
 1081                 if (control != NULL)
 1082                         error = freebsd32_copy_msg_out(&msg, control);
 1083                 else
 1084                         msg.msg_controllen = 0;
 1085                 
 1086                 if (error == 0)
 1087                         error = freebsd32_copyoutmsghdr(&msg, uap->msg);
 1088         }
 1089         free(iov, M_IOV);
 1090 
 1091         if (control != NULL)
 1092                 m_freem(control);
 1093 
 1094         return (error);
 1095 }
 1096 
 1097 
 1098 static int
 1099 freebsd32_convert_msg_in(struct mbuf **controlp)
 1100 {
 1101         struct mbuf *control = *controlp;
 1102         struct cmsghdr *cm = mtod(control, struct cmsghdr *);
 1103         void *data;
 1104         socklen_t clen = control->m_len, datalen;
 1105         int error;
 1106 
 1107         error = 0;
 1108         *controlp = NULL;
 1109 
 1110         while (cm != NULL) {
 1111                 if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) {
 1112                         error = EINVAL;
 1113                         break;
 1114                 }
 1115 
 1116                 data = FREEBSD32_CMSG_DATA(cm);
 1117                 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
 1118 
 1119                 *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type,
 1120                     cm->cmsg_level);
 1121                 controlp = &(*controlp)->m_next;
 1122 
 1123                 if (FREEBSD32_CMSG_SPACE(datalen) < clen) {
 1124                         clen -= FREEBSD32_CMSG_SPACE(datalen);
 1125                         cm = (struct cmsghdr *)
 1126                                 ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen));
 1127                 } else {
 1128                         clen = 0;
 1129                         cm = NULL;
 1130                 }
 1131         }
 1132 
 1133         m_freem(control);
 1134         return (error);
 1135 }
 1136 
 1137 
 1138 int
 1139 freebsd32_sendmsg(struct thread *td,
 1140                   struct freebsd32_sendmsg_args *uap)
 1141 {
 1142         struct msghdr msg;
 1143         struct msghdr32 m32;
 1144         struct iovec *iov;
 1145         struct mbuf *control = NULL;
 1146         struct sockaddr *to = NULL;
 1147         int error;
 1148 
 1149         error = copyin(uap->msg, &m32, sizeof(m32));
 1150         if (error)
 1151                 return (error);
 1152         error = freebsd32_copyinmsghdr(uap->msg, &msg);
 1153         if (error)
 1154                 return (error);
 1155         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
 1156             EMSGSIZE);
 1157         if (error)
 1158                 return (error);
 1159         msg.msg_iov = iov;
 1160         if (msg.msg_name != NULL) {
 1161                 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
 1162                 if (error) {
 1163                         to = NULL;
 1164                         goto out;
 1165                 }
 1166                 msg.msg_name = to;
 1167         }
 1168 
 1169         if (msg.msg_control) {
 1170                 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
 1171                         error = EINVAL;
 1172                         goto out;
 1173                 }
 1174 
 1175                 error = sockargs(&control, msg.msg_control,
 1176                     msg.msg_controllen, MT_CONTROL);
 1177                 if (error)
 1178                         goto out;
 1179                 
 1180                 error = freebsd32_convert_msg_in(&control);
 1181                 if (error)
 1182                         goto out;
 1183         }
 1184 
 1185         error = kern_sendit(td, uap->s, &msg, uap->flags, control,
 1186             UIO_USERSPACE);
 1187 
 1188 out:
 1189         free(iov, M_IOV);
 1190         if (to)
 1191                 free(to, M_SONAME);
 1192         return (error);
 1193 }
 1194 
 1195 int
 1196 freebsd32_recvfrom(struct thread *td,
 1197                    struct freebsd32_recvfrom_args *uap)
 1198 {
 1199         struct msghdr msg;
 1200         struct iovec aiov;
 1201         int error;
 1202 
 1203         if (uap->fromlenaddr) {
 1204                 error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
 1205                     sizeof(msg.msg_namelen));
 1206                 if (error)
 1207                         return (error);
 1208         } else {
 1209                 msg.msg_namelen = 0;
 1210         }
 1211 
 1212         msg.msg_name = PTRIN(uap->from);
 1213         msg.msg_iov = &aiov;
 1214         msg.msg_iovlen = 1;
 1215         aiov.iov_base = PTRIN(uap->buf);
 1216         aiov.iov_len = uap->len;
 1217         msg.msg_control = NULL;
 1218         msg.msg_flags = uap->flags;
 1219         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
 1220         if (error == 0 && uap->fromlenaddr)
 1221                 error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
 1222                     sizeof (msg.msg_namelen));
 1223         return (error);
 1224 }
 1225 
 1226 int
 1227 freebsd32_settimeofday(struct thread *td,
 1228                        struct freebsd32_settimeofday_args *uap)
 1229 {
 1230         struct timeval32 tv32;
 1231         struct timeval tv, *tvp;
 1232         struct timezone tz, *tzp;
 1233         int error;
 1234 
 1235         if (uap->tv) {
 1236                 error = copyin(uap->tv, &tv32, sizeof(tv32));
 1237                 if (error)
 1238                         return (error);
 1239                 CP(tv32, tv, tv_sec);
 1240                 CP(tv32, tv, tv_usec);
 1241                 tvp = &tv;
 1242         } else
 1243                 tvp = NULL;
 1244         if (uap->tzp) {
 1245                 error = copyin(uap->tzp, &tz, sizeof(tz));
 1246                 if (error)
 1247                         return (error);
 1248                 tzp = &tz;
 1249         } else
 1250                 tzp = NULL;
 1251         return (kern_settimeofday(td, tvp, tzp));
 1252 }
 1253 
 1254 int
 1255 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
 1256 {
 1257         struct timeval32 s32[2];
 1258         struct timeval s[2], *sp;
 1259         int error;
 1260 
 1261         if (uap->tptr != NULL) {
 1262                 error = copyin(uap->tptr, s32, sizeof(s32));
 1263                 if (error)
 1264                         return (error);
 1265                 CP(s32[0], s[0], tv_sec);
 1266                 CP(s32[0], s[0], tv_usec);
 1267                 CP(s32[1], s[1], tv_sec);
 1268                 CP(s32[1], s[1], tv_usec);
 1269                 sp = s;
 1270         } else
 1271                 sp = NULL;
 1272         return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
 1273 }
 1274 
 1275 int
 1276 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
 1277 {
 1278         struct timeval32 s32[2];
 1279         struct timeval s[2], *sp;
 1280         int error;
 1281 
 1282         if (uap->tptr != NULL) {
 1283                 error = copyin(uap->tptr, s32, sizeof(s32));
 1284                 if (error)
 1285                         return (error);
 1286                 CP(s32[0], s[0], tv_sec);
 1287                 CP(s32[0], s[0], tv_usec);
 1288                 CP(s32[1], s[1], tv_sec);
 1289                 CP(s32[1], s[1], tv_usec);
 1290                 sp = s;
 1291         } else
 1292                 sp = NULL;
 1293         return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
 1294 }
 1295 
 1296 int
 1297 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
 1298 {
 1299         struct timeval32 s32[2];
 1300         struct timeval s[2], *sp;
 1301         int error;
 1302 
 1303         if (uap->tptr != NULL) {
 1304                 error = copyin(uap->tptr, s32, sizeof(s32));
 1305                 if (error)
 1306                         return (error);
 1307                 CP(s32[0], s[0], tv_sec);
 1308                 CP(s32[0], s[0], tv_usec);
 1309                 CP(s32[1], s[1], tv_sec);
 1310                 CP(s32[1], s[1], tv_usec);
 1311                 sp = s;
 1312         } else
 1313                 sp = NULL;
 1314         return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
 1315 }
 1316 
 1317 int
 1318 freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
 1319 {
 1320         struct timeval32 s32[2];
 1321         struct timeval s[2], *sp;
 1322         int error;
 1323 
 1324         if (uap->times != NULL) {
 1325                 error = copyin(uap->times, s32, sizeof(s32));
 1326                 if (error)
 1327                         return (error);
 1328                 CP(s32[0], s[0], tv_sec);
 1329                 CP(s32[0], s[0], tv_usec);
 1330                 CP(s32[1], s[1], tv_sec);
 1331                 CP(s32[1], s[1], tv_usec);
 1332                 sp = s;
 1333         } else
 1334                 sp = NULL;
 1335         return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
 1336                 sp, UIO_SYSSPACE));
 1337 }
 1338 
 1339 int
 1340 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
 1341 {
 1342         struct timeval32 tv32;
 1343         struct timeval delta, olddelta, *deltap;
 1344         int error;
 1345 
 1346         if (uap->delta) {
 1347                 error = copyin(uap->delta, &tv32, sizeof(tv32));
 1348                 if (error)
 1349                         return (error);
 1350                 CP(tv32, delta, tv_sec);
 1351                 CP(tv32, delta, tv_usec);
 1352                 deltap = &delta;
 1353         } else
 1354                 deltap = NULL;
 1355         error = kern_adjtime(td, deltap, &olddelta);
 1356         if (uap->olddelta && error == 0) {
 1357                 CP(olddelta, tv32, tv_sec);
 1358                 CP(olddelta, tv32, tv_usec);
 1359                 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
 1360         }
 1361         return (error);
 1362 }
 1363 
 1364 #ifdef COMPAT_FREEBSD4
 1365 int
 1366 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
 1367 {
 1368         struct statfs32 s32;
 1369         struct statfs s;
 1370         int error;
 1371 
 1372         error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
 1373         if (error)
 1374                 return (error);
 1375         copy_statfs(&s, &s32);
 1376         return (copyout(&s32, uap->buf, sizeof(s32)));
 1377 }
 1378 #endif
 1379 
 1380 #ifdef COMPAT_FREEBSD4
 1381 int
 1382 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
 1383 {
 1384         struct statfs32 s32;
 1385         struct statfs s;
 1386         int error;
 1387 
 1388         error = kern_fstatfs(td, uap->fd, &s);
 1389         if (error)
 1390                 return (error);
 1391         copy_statfs(&s, &s32);
 1392         return (copyout(&s32, uap->buf, sizeof(s32)));
 1393 }
 1394 #endif
 1395 
 1396 #ifdef COMPAT_FREEBSD4
 1397 int
 1398 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
 1399 {
 1400         struct statfs32 s32;
 1401         struct statfs s;
 1402         fhandle_t fh;
 1403         int error;
 1404 
 1405         if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
 1406                 return (error);
 1407         error = kern_fhstatfs(td, fh, &s);
 1408         if (error)
 1409                 return (error);
 1410         copy_statfs(&s, &s32);
 1411         return (copyout(&s32, uap->buf, sizeof(s32)));
 1412 }
 1413 #endif
 1414 
 1415 int
 1416 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
 1417 {
 1418         struct pread_args ap;
 1419 
 1420         ap.fd = uap->fd;
 1421         ap.buf = uap->buf;
 1422         ap.nbyte = uap->nbyte;
 1423         ap.offset = PAIR32TO64(off_t,uap->offset);
 1424         return (sys_pread(td, &ap));
 1425 }
 1426 
 1427 int
 1428 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
 1429 {
 1430         struct pwrite_args ap;
 1431 
 1432         ap.fd = uap->fd;
 1433         ap.buf = uap->buf;
 1434         ap.nbyte = uap->nbyte;
 1435         ap.offset = PAIR32TO64(off_t,uap->offset);
 1436         return (sys_pwrite(td, &ap));
 1437 }
 1438 
 1439 #ifdef COMPAT_43
 1440 int
 1441 ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
 1442 {
 1443         struct lseek_args nuap;
 1444 
 1445         nuap.fd = uap->fd;
 1446         nuap.offset = uap->offset;
 1447         nuap.whence = uap->whence;
 1448         return (sys_lseek(td, &nuap));
 1449 }
 1450 #endif
 1451 
 1452 int
 1453 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
 1454 {
 1455         int error;
 1456         struct lseek_args ap;
 1457         off_t pos;
 1458 
 1459         ap.fd = uap->fd;
 1460         ap.offset = PAIR32TO64(off_t,uap->offset);
 1461         ap.whence = uap->whence;
 1462         error = sys_lseek(td, &ap);
 1463         /* Expand the quad return into two parts for eax and edx */
 1464         pos = *(off_t *)(td->td_retval);
 1465         td->td_retval[RETVAL_LO] = pos & 0xffffffff;    /* %eax */
 1466         td->td_retval[RETVAL_HI] = pos >> 32;           /* %edx */
 1467         return error;
 1468 }
 1469 
 1470 int
 1471 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
 1472 {
 1473         struct truncate_args ap;
 1474 
 1475         ap.path = uap->path;
 1476         ap.length = PAIR32TO64(off_t,uap->length);
 1477         return (sys_truncate(td, &ap));
 1478 }
 1479 
 1480 int
 1481 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
 1482 {
 1483         struct ftruncate_args ap;
 1484 
 1485         ap.fd = uap->fd;
 1486         ap.length = PAIR32TO64(off_t,uap->length);
 1487         return (sys_ftruncate(td, &ap));
 1488 }
 1489 
 1490 #ifdef COMPAT_43
 1491 int
 1492 ofreebsd32_getdirentries(struct thread *td,
 1493     struct ofreebsd32_getdirentries_args *uap)
 1494 {
 1495         struct ogetdirentries_args ap;
 1496         int error;
 1497         long loff;
 1498         int32_t loff_cut;
 1499 
 1500         ap.fd = uap->fd;
 1501         ap.buf = uap->buf;
 1502         ap.count = uap->count;
 1503         ap.basep = NULL;
 1504         error = kern_ogetdirentries(td, &ap, &loff);
 1505         if (error == 0) {
 1506                 loff_cut = loff;
 1507                 error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
 1508         }
 1509         return (error);
 1510 }
 1511 #endif
 1512 
 1513 int
 1514 freebsd32_getdirentries(struct thread *td,
 1515     struct freebsd32_getdirentries_args *uap)
 1516 {
 1517         long base;
 1518         int32_t base32;
 1519         int error;
 1520 
 1521         error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base);
 1522         if (error)
 1523                 return (error);
 1524         if (uap->basep != NULL) {
 1525                 base32 = base;
 1526                 error = copyout(&base32, uap->basep, sizeof(int32_t));
 1527         }
 1528         return (error);
 1529 }
 1530 
 1531 #ifdef COMPAT_FREEBSD6
 1532 /* versions with the 'int pad' argument */
 1533 int
 1534 freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
 1535 {
 1536         struct pread_args ap;
 1537 
 1538         ap.fd = uap->fd;
 1539         ap.buf = uap->buf;
 1540         ap.nbyte = uap->nbyte;
 1541         ap.offset = PAIR32TO64(off_t,uap->offset);
 1542         return (sys_pread(td, &ap));
 1543 }
 1544 
 1545 int
 1546 freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
 1547 {
 1548         struct pwrite_args ap;
 1549 
 1550         ap.fd = uap->fd;
 1551         ap.buf = uap->buf;
 1552         ap.nbyte = uap->nbyte;
 1553         ap.offset = PAIR32TO64(off_t,uap->offset);
 1554         return (sys_pwrite(td, &ap));
 1555 }
 1556 
 1557 int
 1558 freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
 1559 {
 1560         int error;
 1561         struct lseek_args ap;
 1562         off_t pos;
 1563 
 1564         ap.fd = uap->fd;
 1565         ap.offset = PAIR32TO64(off_t,uap->offset);
 1566         ap.whence = uap->whence;
 1567         error = sys_lseek(td, &ap);
 1568         /* Expand the quad return into two parts for eax and edx */
 1569         pos = *(off_t *)(td->td_retval);
 1570         td->td_retval[RETVAL_LO] = pos & 0xffffffff;    /* %eax */
 1571         td->td_retval[RETVAL_HI] = pos >> 32;           /* %edx */
 1572         return error;
 1573 }
 1574 
 1575 int
 1576 freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
 1577 {
 1578         struct truncate_args ap;
 1579 
 1580         ap.path = uap->path;
 1581         ap.length = PAIR32TO64(off_t,uap->length);
 1582         return (sys_truncate(td, &ap));
 1583 }
 1584 
 1585 int
 1586 freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
 1587 {
 1588         struct ftruncate_args ap;
 1589 
 1590         ap.fd = uap->fd;
 1591         ap.length = PAIR32TO64(off_t,uap->length);
 1592         return (sys_ftruncate(td, &ap));
 1593 }
 1594 #endif /* COMPAT_FREEBSD6 */
 1595 
 1596 struct sf_hdtr32 {
 1597         uint32_t headers;
 1598         int hdr_cnt;
 1599         uint32_t trailers;
 1600         int trl_cnt;
 1601 };
 1602 
 1603 static int
 1604 freebsd32_do_sendfile(struct thread *td,
 1605     struct freebsd32_sendfile_args *uap, int compat)
 1606 {
 1607         struct sendfile_args ap;
 1608         struct sf_hdtr32 hdtr32;
 1609         struct sf_hdtr hdtr;
 1610         struct uio *hdr_uio, *trl_uio;
 1611         struct iovec32 *iov32;
 1612         int error;
 1613 
 1614         hdr_uio = trl_uio = NULL;
 1615 
 1616         ap.fd = uap->fd;
 1617         ap.s = uap->s;
 1618         ap.offset = PAIR32TO64(off_t,uap->offset);
 1619         ap.nbytes = uap->nbytes;
 1620         ap.hdtr = (struct sf_hdtr *)uap->hdtr;          /* XXX not used */
 1621         ap.sbytes = uap->sbytes;
 1622         ap.flags = uap->flags;
 1623 
 1624         if (uap->hdtr != NULL) {
 1625                 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
 1626                 if (error)
 1627                         goto out;
 1628                 PTRIN_CP(hdtr32, hdtr, headers);
 1629                 CP(hdtr32, hdtr, hdr_cnt);
 1630                 PTRIN_CP(hdtr32, hdtr, trailers);
 1631                 CP(hdtr32, hdtr, trl_cnt);
 1632 
 1633                 if (hdtr.headers != NULL) {
 1634                         iov32 = PTRIN(hdtr32.headers);
 1635                         error = freebsd32_copyinuio(iov32,
 1636                             hdtr32.hdr_cnt, &hdr_uio);
 1637                         if (error)
 1638                                 goto out;
 1639                 }
 1640                 if (hdtr.trailers != NULL) {
 1641                         iov32 = PTRIN(hdtr32.trailers);
 1642                         error = freebsd32_copyinuio(iov32,
 1643                             hdtr32.trl_cnt, &trl_uio);
 1644                         if (error)
 1645                                 goto out;
 1646                 }
 1647         }
 1648 
 1649         error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat);
 1650 out:
 1651         if (hdr_uio)
 1652                 free(hdr_uio, M_IOV);
 1653         if (trl_uio)
 1654                 free(trl_uio, M_IOV);
 1655         return (error);
 1656 }
 1657 
 1658 #ifdef COMPAT_FREEBSD4
 1659 int
 1660 freebsd4_freebsd32_sendfile(struct thread *td,
 1661     struct freebsd4_freebsd32_sendfile_args *uap)
 1662 {
 1663         return (freebsd32_do_sendfile(td,
 1664             (struct freebsd32_sendfile_args *)uap, 1));
 1665 }
 1666 #endif
 1667 
 1668 int
 1669 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
 1670 {
 1671 
 1672         return (freebsd32_do_sendfile(td, uap, 0));
 1673 }
 1674 
 1675 static void
 1676 copy_stat(struct stat *in, struct stat32 *out)
 1677 {
 1678 
 1679         CP(*in, *out, st_dev);
 1680         CP(*in, *out, st_ino);
 1681         CP(*in, *out, st_mode);
 1682         CP(*in, *out, st_nlink);
 1683         CP(*in, *out, st_uid);
 1684         CP(*in, *out, st_gid);
 1685         CP(*in, *out, st_rdev);
 1686         TS_CP(*in, *out, st_atim);
 1687         TS_CP(*in, *out, st_mtim);
 1688         TS_CP(*in, *out, st_ctim);
 1689         CP(*in, *out, st_size);
 1690         CP(*in, *out, st_blocks);
 1691         CP(*in, *out, st_blksize);
 1692         CP(*in, *out, st_flags);
 1693         CP(*in, *out, st_gen);
 1694         TS_CP(*in, *out, st_birthtim);
 1695 }
 1696 
 1697 #ifdef COMPAT_43
 1698 static void
 1699 copy_ostat(struct stat *in, struct ostat32 *out)
 1700 {
 1701 
 1702         CP(*in, *out, st_dev);
 1703         CP(*in, *out, st_ino);
 1704         CP(*in, *out, st_mode);
 1705         CP(*in, *out, st_nlink);
 1706         CP(*in, *out, st_uid);
 1707         CP(*in, *out, st_gid);
 1708         CP(*in, *out, st_rdev);
 1709         CP(*in, *out, st_size);
 1710         TS_CP(*in, *out, st_atim);
 1711         TS_CP(*in, *out, st_mtim);
 1712         TS_CP(*in, *out, st_ctim);
 1713         CP(*in, *out, st_blksize);
 1714         CP(*in, *out, st_blocks);
 1715         CP(*in, *out, st_flags);
 1716         CP(*in, *out, st_gen);
 1717 }
 1718 #endif
 1719 
 1720 int
 1721 freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
 1722 {
 1723         struct stat sb;
 1724         struct stat32 sb32;
 1725         int error;
 1726 
 1727         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
 1728         if (error)
 1729                 return (error);
 1730         copy_stat(&sb, &sb32);
 1731         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1732         return (error);
 1733 }
 1734 
 1735 #ifdef COMPAT_43
 1736 int
 1737 ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
 1738 {
 1739         struct stat sb;
 1740         struct ostat32 sb32;
 1741         int error;
 1742 
 1743         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
 1744         if (error)
 1745                 return (error);
 1746         copy_ostat(&sb, &sb32);
 1747         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1748         return (error);
 1749 }
 1750 #endif
 1751 
 1752 int
 1753 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
 1754 {
 1755         struct stat ub;
 1756         struct stat32 ub32;
 1757         int error;
 1758 
 1759         error = kern_fstat(td, uap->fd, &ub);
 1760         if (error)
 1761                 return (error);
 1762         copy_stat(&ub, &ub32);
 1763         error = copyout(&ub32, uap->ub, sizeof(ub32));
 1764         return (error);
 1765 }
 1766 
 1767 #ifdef COMPAT_43
 1768 int
 1769 ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
 1770 {
 1771         struct stat ub;
 1772         struct ostat32 ub32;
 1773         int error;
 1774 
 1775         error = kern_fstat(td, uap->fd, &ub);
 1776         if (error)
 1777                 return (error);
 1778         copy_ostat(&ub, &ub32);
 1779         error = copyout(&ub32, uap->ub, sizeof(ub32));
 1780         return (error);
 1781 }
 1782 #endif
 1783 
 1784 int
 1785 freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
 1786 {
 1787         struct stat ub;
 1788         struct stat32 ub32;
 1789         int error;
 1790 
 1791         error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &ub);
 1792         if (error)
 1793                 return (error);
 1794         copy_stat(&ub, &ub32);
 1795         error = copyout(&ub32, uap->buf, sizeof(ub32));
 1796         return (error);
 1797 }
 1798 
 1799 int
 1800 freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
 1801 {
 1802         struct stat sb;
 1803         struct stat32 sb32;
 1804         int error;
 1805 
 1806         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
 1807         if (error)
 1808                 return (error);
 1809         copy_stat(&sb, &sb32);
 1810         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1811         return (error);
 1812 }
 1813 
 1814 #ifdef COMPAT_43
 1815 int
 1816 ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
 1817 {
 1818         struct stat sb;
 1819         struct ostat32 sb32;
 1820         int error;
 1821 
 1822         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
 1823         if (error)
 1824                 return (error);
 1825         copy_ostat(&sb, &sb32);
 1826         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1827         return (error);
 1828 }
 1829 #endif
 1830 
 1831 int
 1832 freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
 1833 {
 1834         int error, name[CTL_MAXNAME];
 1835         size_t j, oldlen;
 1836 
 1837         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
 1838                 return (EINVAL);
 1839         error = copyin(uap->name, name, uap->namelen * sizeof(int));
 1840         if (error)
 1841                 return (error);
 1842         if (uap->oldlenp)
 1843                 oldlen = fuword32(uap->oldlenp);
 1844         else
 1845                 oldlen = 0;
 1846         error = userland_sysctl(td, name, uap->namelen,
 1847                 uap->old, &oldlen, 1,
 1848                 uap->new, uap->newlen, &j, SCTL_MASK32);
 1849         if (error && error != ENOMEM)
 1850                 return (error);
 1851         if (uap->oldlenp)
 1852                 suword32(uap->oldlenp, j);
 1853         return (0);
 1854 }
 1855 
 1856 int
 1857 freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
 1858 {
 1859         uint32_t version;
 1860         int error;
 1861         struct jail j;
 1862 
 1863         error = copyin(uap->jail, &version, sizeof(uint32_t));
 1864         if (error)
 1865                 return (error);
 1866 
 1867         switch (version) {
 1868         case 0:
 1869         {
 1870                 /* FreeBSD single IPv4 jails. */
 1871                 struct jail32_v0 j32_v0;
 1872 
 1873                 bzero(&j, sizeof(struct jail));
 1874                 error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
 1875                 if (error)
 1876                         return (error);
 1877                 CP(j32_v0, j, version);
 1878                 PTRIN_CP(j32_v0, j, path);
 1879                 PTRIN_CP(j32_v0, j, hostname);
 1880                 j.ip4s = j32_v0.ip_number;
 1881                 break;
 1882         }
 1883 
 1884         case 1:
 1885                 /*
 1886                  * Version 1 was used by multi-IPv4 jail implementations
 1887                  * that never made it into the official kernel.
 1888                  */
 1889                 return (EINVAL);
 1890 
 1891         case 2: /* JAIL_API_VERSION */
 1892         {
 1893                 /* FreeBSD multi-IPv4/IPv6,noIP jails. */
 1894                 struct jail32 j32;
 1895 
 1896                 error = copyin(uap->jail, &j32, sizeof(struct jail32));
 1897                 if (error)
 1898                         return (error);
 1899                 CP(j32, j, version);
 1900                 PTRIN_CP(j32, j, path);
 1901                 PTRIN_CP(j32, j, hostname);
 1902                 PTRIN_CP(j32, j, jailname);
 1903                 CP(j32, j, ip4s);
 1904                 CP(j32, j, ip6s);
 1905                 PTRIN_CP(j32, j, ip4);
 1906                 PTRIN_CP(j32, j, ip6);
 1907                 break;
 1908         }
 1909 
 1910         default:
 1911                 /* Sci-Fi jails are not supported, sorry. */
 1912                 return (EINVAL);
 1913         }
 1914         return (kern_jail(td, &j));
 1915 }
 1916 
 1917 int
 1918 freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
 1919 {
 1920         struct uio *auio;
 1921         int error;
 1922 
 1923         /* Check that we have an even number of iovecs. */
 1924         if (uap->iovcnt & 1)
 1925                 return (EINVAL);
 1926 
 1927         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 1928         if (error)
 1929                 return (error);
 1930         error = kern_jail_set(td, auio, uap->flags);
 1931         free(auio, M_IOV);
 1932         return (error);
 1933 }
 1934 
 1935 int
 1936 freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
 1937 {
 1938         struct iovec32 iov32;
 1939         struct uio *auio;
 1940         int error, i;
 1941 
 1942         /* Check that we have an even number of iovecs. */
 1943         if (uap->iovcnt & 1)
 1944                 return (EINVAL);
 1945 
 1946         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 1947         if (error)
 1948                 return (error);
 1949         error = kern_jail_get(td, auio, uap->flags);
 1950         if (error == 0)
 1951                 for (i = 0; i < uap->iovcnt; i++) {
 1952                         PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
 1953                         CP(auio->uio_iov[i], iov32, iov_len);
 1954                         error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
 1955                         if (error != 0)
 1956                                 break;
 1957                 }
 1958         free(auio, M_IOV);
 1959         return (error);
 1960 }
 1961 
 1962 int
 1963 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
 1964 {
 1965         struct sigaction32 s32;
 1966         struct sigaction sa, osa, *sap;
 1967         int error;
 1968 
 1969         if (uap->act) {
 1970                 error = copyin(uap->act, &s32, sizeof(s32));
 1971                 if (error)
 1972                         return (error);
 1973                 sa.sa_handler = PTRIN(s32.sa_u);
 1974                 CP(s32, sa, sa_flags);
 1975                 CP(s32, sa, sa_mask);
 1976                 sap = &sa;
 1977         } else
 1978                 sap = NULL;
 1979         error = kern_sigaction(td, uap->sig, sap, &osa, 0);
 1980         if (error == 0 && uap->oact != NULL) {
 1981                 s32.sa_u = PTROUT(osa.sa_handler);
 1982                 CP(osa, s32, sa_flags);
 1983                 CP(osa, s32, sa_mask);
 1984                 error = copyout(&s32, uap->oact, sizeof(s32));
 1985         }
 1986         return (error);
 1987 }
 1988 
 1989 #ifdef COMPAT_FREEBSD4
 1990 int
 1991 freebsd4_freebsd32_sigaction(struct thread *td,
 1992                              struct freebsd4_freebsd32_sigaction_args *uap)
 1993 {
 1994         struct sigaction32 s32;
 1995         struct sigaction sa, osa, *sap;
 1996         int error;
 1997 
 1998         if (uap->act) {
 1999                 error = copyin(uap->act, &s32, sizeof(s32));
 2000                 if (error)
 2001                         return (error);
 2002                 sa.sa_handler = PTRIN(s32.sa_u);
 2003                 CP(s32, sa, sa_flags);
 2004                 CP(s32, sa, sa_mask);
 2005                 sap = &sa;
 2006         } else
 2007                 sap = NULL;
 2008         error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
 2009         if (error == 0 && uap->oact != NULL) {
 2010                 s32.sa_u = PTROUT(osa.sa_handler);
 2011                 CP(osa, s32, sa_flags);
 2012                 CP(osa, s32, sa_mask);
 2013                 error = copyout(&s32, uap->oact, sizeof(s32));
 2014         }
 2015         return (error);
 2016 }
 2017 #endif
 2018 
 2019 #ifdef COMPAT_43
 2020 struct osigaction32 {
 2021         u_int32_t       sa_u;
 2022         osigset_t       sa_mask;
 2023         int             sa_flags;
 2024 };
 2025 
 2026 #define ONSIG   32
 2027 
 2028 int
 2029 ofreebsd32_sigaction(struct thread *td,
 2030                              struct ofreebsd32_sigaction_args *uap)
 2031 {
 2032         struct osigaction32 s32;
 2033         struct sigaction sa, osa, *sap;
 2034         int error;
 2035 
 2036         if (uap->signum <= 0 || uap->signum >= ONSIG)
 2037                 return (EINVAL);
 2038 
 2039         if (uap->nsa) {
 2040                 error = copyin(uap->nsa, &s32, sizeof(s32));
 2041                 if (error)
 2042                         return (error);
 2043                 sa.sa_handler = PTRIN(s32.sa_u);
 2044                 CP(s32, sa, sa_flags);
 2045                 OSIG2SIG(s32.sa_mask, sa.sa_mask);
 2046                 sap = &sa;
 2047         } else
 2048                 sap = NULL;
 2049         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
 2050         if (error == 0 && uap->osa != NULL) {
 2051                 s32.sa_u = PTROUT(osa.sa_handler);
 2052                 CP(osa, s32, sa_flags);
 2053                 SIG2OSIG(osa.sa_mask, s32.sa_mask);
 2054                 error = copyout(&s32, uap->osa, sizeof(s32));
 2055         }
 2056         return (error);
 2057 }
 2058 
 2059 int
 2060 ofreebsd32_sigprocmask(struct thread *td,
 2061                                struct ofreebsd32_sigprocmask_args *uap)
 2062 {
 2063         sigset_t set, oset;
 2064         int error;
 2065 
 2066         OSIG2SIG(uap->mask, set);
 2067         error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD);
 2068         SIG2OSIG(oset, td->td_retval[0]);
 2069         return (error);
 2070 }
 2071 
 2072 int
 2073 ofreebsd32_sigpending(struct thread *td,
 2074                               struct ofreebsd32_sigpending_args *uap)
 2075 {
 2076         struct proc *p = td->td_proc;
 2077         sigset_t siglist;
 2078 
 2079         PROC_LOCK(p);
 2080         siglist = p->p_siglist;
 2081         SIGSETOR(siglist, td->td_siglist);
 2082         PROC_UNLOCK(p);
 2083         SIG2OSIG(siglist, td->td_retval[0]);
 2084         return (0);
 2085 }
 2086 
 2087 struct sigvec32 {
 2088         u_int32_t       sv_handler;
 2089         int             sv_mask;
 2090         int             sv_flags;
 2091 };
 2092 
 2093 int
 2094 ofreebsd32_sigvec(struct thread *td,
 2095                           struct ofreebsd32_sigvec_args *uap)
 2096 {
 2097         struct sigvec32 vec;
 2098         struct sigaction sa, osa, *sap;
 2099         int error;
 2100 
 2101         if (uap->signum <= 0 || uap->signum >= ONSIG)
 2102                 return (EINVAL);
 2103 
 2104         if (uap->nsv) {
 2105                 error = copyin(uap->nsv, &vec, sizeof(vec));
 2106                 if (error)
 2107                         return (error);
 2108                 sa.sa_handler = PTRIN(vec.sv_handler);
 2109                 OSIG2SIG(vec.sv_mask, sa.sa_mask);
 2110                 sa.sa_flags = vec.sv_flags;
 2111                 sa.sa_flags ^= SA_RESTART;
 2112                 sap = &sa;
 2113         } else
 2114                 sap = NULL;
 2115         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
 2116         if (error == 0 && uap->osv != NULL) {
 2117                 vec.sv_handler = PTROUT(osa.sa_handler);
 2118                 SIG2OSIG(osa.sa_mask, vec.sv_mask);
 2119                 vec.sv_flags = osa.sa_flags;
 2120                 vec.sv_flags &= ~SA_NOCLDWAIT;
 2121                 vec.sv_flags ^= SA_RESTART;
 2122                 error = copyout(&vec, uap->osv, sizeof(vec));
 2123         }
 2124         return (error);
 2125 }
 2126 
 2127 int
 2128 ofreebsd32_sigblock(struct thread *td,
 2129                             struct ofreebsd32_sigblock_args *uap)
 2130 {
 2131         sigset_t set, oset;
 2132 
 2133         OSIG2SIG(uap->mask, set);
 2134         kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0);
 2135         SIG2OSIG(oset, td->td_retval[0]);
 2136         return (0);
 2137 }
 2138 
 2139 int
 2140 ofreebsd32_sigsetmask(struct thread *td,
 2141                               struct ofreebsd32_sigsetmask_args *uap)
 2142 {
 2143         sigset_t set, oset;
 2144 
 2145         OSIG2SIG(uap->mask, set);
 2146         kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0);
 2147         SIG2OSIG(oset, td->td_retval[0]);
 2148         return (0);
 2149 }
 2150 
 2151 int
 2152 ofreebsd32_sigsuspend(struct thread *td,
 2153                               struct ofreebsd32_sigsuspend_args *uap)
 2154 {
 2155         sigset_t mask;
 2156 
 2157         OSIG2SIG(uap->mask, mask);
 2158         return (kern_sigsuspend(td, mask));
 2159 }
 2160 
 2161 struct sigstack32 {
 2162         u_int32_t       ss_sp;
 2163         int             ss_onstack;
 2164 };
 2165 
 2166 int
 2167 ofreebsd32_sigstack(struct thread *td,
 2168                             struct ofreebsd32_sigstack_args *uap)
 2169 {
 2170         struct sigstack32 s32;
 2171         struct sigstack nss, oss;
 2172         int error = 0, unss;
 2173 
 2174         if (uap->nss != NULL) {
 2175                 error = copyin(uap->nss, &s32, sizeof(s32));
 2176                 if (error)
 2177                         return (error);
 2178                 nss.ss_sp = PTRIN(s32.ss_sp);
 2179                 CP(s32, nss, ss_onstack);
 2180                 unss = 1;
 2181         } else {
 2182                 unss = 0;
 2183         }
 2184         oss.ss_sp = td->td_sigstk.ss_sp;
 2185         oss.ss_onstack = sigonstack(cpu_getstack(td));
 2186         if (unss) {
 2187                 td->td_sigstk.ss_sp = nss.ss_sp;
 2188                 td->td_sigstk.ss_size = 0;
 2189                 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
 2190                 td->td_pflags |= TDP_ALTSTACK;
 2191         }
 2192         if (uap->oss != NULL) {
 2193                 s32.ss_sp = PTROUT(oss.ss_sp);
 2194                 CP(oss, s32, ss_onstack);
 2195                 error = copyout(&s32, uap->oss, sizeof(s32));
 2196         }
 2197         return (error);
 2198 }
 2199 #endif
 2200 
 2201 int
 2202 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
 2203 {
 2204         struct timespec32 rmt32, rqt32;
 2205         struct timespec rmt, rqt;
 2206         int error;
 2207 
 2208         error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
 2209         if (error)
 2210                 return (error);
 2211 
 2212         CP(rqt32, rqt, tv_sec);
 2213         CP(rqt32, rqt, tv_nsec);
 2214 
 2215         if (uap->rmtp &&
 2216             !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
 2217                 return (EFAULT);
 2218         error = kern_nanosleep(td, &rqt, &rmt);
 2219         if (error && uap->rmtp) {
 2220                 int error2;
 2221 
 2222                 CP(rmt, rmt32, tv_sec);
 2223                 CP(rmt, rmt32, tv_nsec);
 2224 
 2225                 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
 2226                 if (error2)
 2227                         error = error2;
 2228         }
 2229         return (error);
 2230 }
 2231 
 2232 int
 2233 freebsd32_clock_gettime(struct thread *td,
 2234                         struct freebsd32_clock_gettime_args *uap)
 2235 {
 2236         struct timespec ats;
 2237         struct timespec32 ats32;
 2238         int error;
 2239 
 2240         error = kern_clock_gettime(td, uap->clock_id, &ats);
 2241         if (error == 0) {
 2242                 CP(ats, ats32, tv_sec);
 2243                 CP(ats, ats32, tv_nsec);
 2244                 error = copyout(&ats32, uap->tp, sizeof(ats32));
 2245         }
 2246         return (error);
 2247 }
 2248 
 2249 int
 2250 freebsd32_clock_settime(struct thread *td,
 2251                         struct freebsd32_clock_settime_args *uap)
 2252 {
 2253         struct timespec ats;
 2254         struct timespec32 ats32;
 2255         int error;
 2256 
 2257         error = copyin(uap->tp, &ats32, sizeof(ats32));
 2258         if (error)
 2259                 return (error);
 2260         CP(ats32, ats, tv_sec);
 2261         CP(ats32, ats, tv_nsec);
 2262 
 2263         return (kern_clock_settime(td, uap->clock_id, &ats));
 2264 }
 2265 
 2266 int
 2267 freebsd32_clock_getres(struct thread *td,
 2268                        struct freebsd32_clock_getres_args *uap)
 2269 {
 2270         struct timespec ts;
 2271         struct timespec32 ts32;
 2272         int error;
 2273 
 2274         if (uap->tp == NULL)
 2275                 return (0);
 2276         error = kern_clock_getres(td, uap->clock_id, &ts);
 2277         if (error == 0) {
 2278                 CP(ts, ts32, tv_sec);
 2279                 CP(ts, ts32, tv_nsec);
 2280                 error = copyout(&ts32, uap->tp, sizeof(ts32));
 2281         }
 2282         return (error);
 2283 }
 2284 
 2285 int
 2286 freebsd32_thr_new(struct thread *td,
 2287                   struct freebsd32_thr_new_args *uap)
 2288 {
 2289         struct thr_param32 param32;
 2290         struct thr_param param;
 2291         int error;
 2292 
 2293         if (uap->param_size < 0 ||
 2294             uap->param_size > sizeof(struct thr_param32))
 2295                 return (EINVAL);
 2296         bzero(&param, sizeof(struct thr_param));
 2297         bzero(&param32, sizeof(struct thr_param32));
 2298         error = copyin(uap->param, &param32, uap->param_size);
 2299         if (error != 0)
 2300                 return (error);
 2301         param.start_func = PTRIN(param32.start_func);
 2302         param.arg = PTRIN(param32.arg);
 2303         param.stack_base = PTRIN(param32.stack_base);
 2304         param.stack_size = param32.stack_size;
 2305         param.tls_base = PTRIN(param32.tls_base);
 2306         param.tls_size = param32.tls_size;
 2307         param.child_tid = PTRIN(param32.child_tid);
 2308         param.parent_tid = PTRIN(param32.parent_tid);
 2309         param.flags = param32.flags;
 2310         param.rtp = PTRIN(param32.rtp);
 2311         param.spare[0] = PTRIN(param32.spare[0]);
 2312         param.spare[1] = PTRIN(param32.spare[1]);
 2313         param.spare[2] = PTRIN(param32.spare[2]);
 2314 
 2315         return (kern_thr_new(td, &param));
 2316 }
 2317 
 2318 int
 2319 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
 2320 {
 2321         struct timespec32 ts32;
 2322         struct timespec ts, *tsp;
 2323         int error;
 2324 
 2325         error = 0;
 2326         tsp = NULL;
 2327         if (uap->timeout != NULL) {
 2328                 error = copyin((const void *)uap->timeout, (void *)&ts32,
 2329                     sizeof(struct timespec32));
 2330                 if (error != 0)
 2331                         return (error);
 2332                 ts.tv_sec = ts32.tv_sec;
 2333                 ts.tv_nsec = ts32.tv_nsec;
 2334                 tsp = &ts;
 2335         }
 2336         return (kern_thr_suspend(td, tsp));
 2337 }
 2338 
 2339 void
 2340 siginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst)
 2341 {
 2342         bzero(dst, sizeof(*dst));
 2343         dst->si_signo = src->si_signo;
 2344         dst->si_errno = src->si_errno;
 2345         dst->si_code = src->si_code;
 2346         dst->si_pid = src->si_pid;
 2347         dst->si_uid = src->si_uid;
 2348         dst->si_status = src->si_status;
 2349         dst->si_addr = (uintptr_t)src->si_addr;
 2350         dst->si_value.sigval_int = src->si_value.sival_int;
 2351         dst->si_timerid = src->si_timerid;
 2352         dst->si_overrun = src->si_overrun;
 2353 }
 2354 
 2355 int
 2356 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
 2357 {
 2358         struct timespec32 ts32;
 2359         struct timespec ts;
 2360         struct timespec *timeout;
 2361         sigset_t set;
 2362         ksiginfo_t ksi;
 2363         struct siginfo32 si32;
 2364         int error;
 2365 
 2366         if (uap->timeout) {
 2367                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
 2368                 if (error)
 2369                         return (error);
 2370                 ts.tv_sec = ts32.tv_sec;
 2371                 ts.tv_nsec = ts32.tv_nsec;
 2372                 timeout = &ts;
 2373         } else
 2374                 timeout = NULL;
 2375 
 2376         error = copyin(uap->set, &set, sizeof(set));
 2377         if (error)
 2378                 return (error);
 2379 
 2380         error = kern_sigtimedwait(td, set, &ksi, timeout);
 2381         if (error)
 2382                 return (error);
 2383 
 2384         if (uap->info) {
 2385                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
 2386                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
 2387         }
 2388 
 2389         if (error == 0)
 2390                 td->td_retval[0] = ksi.ksi_signo;
 2391         return (error);
 2392 }
 2393 
 2394 /*
 2395  * MPSAFE
 2396  */
 2397 int
 2398 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
 2399 {
 2400         ksiginfo_t ksi;
 2401         struct siginfo32 si32;
 2402         sigset_t set;
 2403         int error;
 2404 
 2405         error = copyin(uap->set, &set, sizeof(set));
 2406         if (error)
 2407                 return (error);
 2408 
 2409         error = kern_sigtimedwait(td, set, &ksi, NULL);
 2410         if (error)
 2411                 return (error);
 2412 
 2413         if (uap->info) {
 2414                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
 2415                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
 2416         }       
 2417         if (error == 0)
 2418                 td->td_retval[0] = ksi.ksi_signo;
 2419         return (error);
 2420 }
 2421 
 2422 int
 2423 freebsd32_cpuset_setid(struct thread *td,
 2424     struct freebsd32_cpuset_setid_args *uap)
 2425 {
 2426         struct cpuset_setid_args ap;
 2427 
 2428         ap.which = uap->which;
 2429         ap.id = PAIR32TO64(id_t,uap->id);
 2430         ap.setid = uap->setid;
 2431 
 2432         return (sys_cpuset_setid(td, &ap));
 2433 }
 2434 
 2435 int
 2436 freebsd32_cpuset_getid(struct thread *td,
 2437     struct freebsd32_cpuset_getid_args *uap)
 2438 {
 2439         struct cpuset_getid_args ap;
 2440 
 2441         ap.level = uap->level;
 2442         ap.which = uap->which;
 2443         ap.id = PAIR32TO64(id_t,uap->id);
 2444         ap.setid = uap->setid;
 2445 
 2446         return (sys_cpuset_getid(td, &ap));
 2447 }
 2448 
 2449 int
 2450 freebsd32_cpuset_getaffinity(struct thread *td,
 2451     struct freebsd32_cpuset_getaffinity_args *uap)
 2452 {
 2453         struct cpuset_getaffinity_args ap;
 2454 
 2455         ap.level = uap->level;
 2456         ap.which = uap->which;
 2457         ap.id = PAIR32TO64(id_t,uap->id);
 2458         ap.cpusetsize = uap->cpusetsize;
 2459         ap.mask = uap->mask;
 2460 
 2461         return (sys_cpuset_getaffinity(td, &ap));
 2462 }
 2463 
 2464 int
 2465 freebsd32_cpuset_setaffinity(struct thread *td,
 2466     struct freebsd32_cpuset_setaffinity_args *uap)
 2467 {
 2468         struct cpuset_setaffinity_args ap;
 2469 
 2470         ap.level = uap->level;
 2471         ap.which = uap->which;
 2472         ap.id = PAIR32TO64(id_t,uap->id);
 2473         ap.cpusetsize = uap->cpusetsize;
 2474         ap.mask = uap->mask;
 2475 
 2476         return (sys_cpuset_setaffinity(td, &ap));
 2477 }
 2478 
 2479 int
 2480 freebsd32_nmount(struct thread *td,
 2481     struct freebsd32_nmount_args /* {
 2482         struct iovec *iovp;
 2483         unsigned int iovcnt;
 2484         int flags;
 2485     } */ *uap)
 2486 {
 2487         struct uio *auio;
 2488         uint64_t flags;
 2489         int error;
 2490 
 2491         /*
 2492          * Mount flags are now 64-bits. On 32-bit archtectures only
 2493          * 32-bits are passed in, but from here on everything handles
 2494          * 64-bit flags correctly.
 2495          */
 2496         flags = uap->flags;
 2497 
 2498         AUDIT_ARG_FFLAGS(flags);
 2499 
 2500         /*
 2501          * Filter out MNT_ROOTFS.  We do not want clients of nmount() in
 2502          * userspace to set this flag, but we must filter it out if we want
 2503          * MNT_UPDATE on the root file system to work.
 2504          * MNT_ROOTFS should only be set by the kernel when mounting its
 2505          * root file system.
 2506          */
 2507         flags &= ~MNT_ROOTFS;
 2508 
 2509         /*
 2510          * check that we have an even number of iovec's
 2511          * and that we have at least two options.
 2512          */
 2513         if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
 2514                 return (EINVAL);
 2515 
 2516         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 2517         if (error)
 2518                 return (error);
 2519         error = vfs_donmount(td, flags, auio);
 2520 
 2521         free(auio, M_IOV);
 2522         return error;
 2523 }
 2524 
 2525 #if 0
 2526 int
 2527 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
 2528 {
 2529         struct yyy32 *p32, s32;
 2530         struct yyy *p = NULL, s;
 2531         struct xxx_arg ap;
 2532         int error;
 2533 
 2534         if (uap->zzz) {
 2535                 error = copyin(uap->zzz, &s32, sizeof(s32));
 2536                 if (error)
 2537                         return (error);
 2538                 /* translate in */
 2539                 p = &s;
 2540         }
 2541         error = kern_xxx(td, p);
 2542         if (error)
 2543                 return (error);
 2544         if (uap->zzz) {
 2545                 /* translate out */
 2546                 error = copyout(&s32, p32, sizeof(s32));
 2547         }
 2548         return (error);
 2549 }
 2550 #endif
 2551 
 2552 int
 2553 syscall32_register(int *offset, struct sysent *new_sysent,
 2554     struct sysent *old_sysent)
 2555 {
 2556         if (*offset == NO_SYSCALL) {
 2557                 int i;
 2558 
 2559                 for (i = 1; i < SYS_MAXSYSCALL; ++i)
 2560                         if (freebsd32_sysent[i].sy_call ==
 2561                             (sy_call_t *)lkmnosys)
 2562                                 break;
 2563                 if (i == SYS_MAXSYSCALL)
 2564                         return (ENFILE);
 2565                 *offset = i;
 2566         } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL)
 2567                 return (EINVAL);
 2568         else if (freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmnosys &&
 2569             freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmressys)
 2570                 return (EEXIST);
 2571 
 2572         *old_sysent = freebsd32_sysent[*offset];
 2573         freebsd32_sysent[*offset] = *new_sysent;
 2574         return 0;
 2575 }
 2576 
 2577 int
 2578 syscall32_deregister(int *offset, struct sysent *old_sysent)
 2579 {
 2580 
 2581         if (*offset)
 2582                 freebsd32_sysent[*offset] = *old_sysent;
 2583         return 0;
 2584 }
 2585 
 2586 int
 2587 syscall32_module_handler(struct module *mod, int what, void *arg)
 2588 {
 2589         struct syscall_module_data *data = (struct syscall_module_data*)arg;
 2590         modspecific_t ms;
 2591         int error;
 2592 
 2593         switch (what) {
 2594         case MOD_LOAD:
 2595                 error = syscall32_register(data->offset, data->new_sysent,
 2596                     &data->old_sysent);
 2597                 if (error) {
 2598                         /* Leave a mark so we know to safely unload below. */
 2599                         data->offset = NULL;
 2600                         return error;
 2601                 }
 2602                 ms.intval = *data->offset;
 2603                 MOD_XLOCK;
 2604                 module_setspecific(mod, &ms);
 2605                 MOD_XUNLOCK;
 2606                 if (data->chainevh)
 2607                         error = data->chainevh(mod, what, data->chainarg);
 2608                 return (error);
 2609         case MOD_UNLOAD:
 2610                 /*
 2611                  * MOD_LOAD failed, so just return without calling the
 2612                  * chained handler since we didn't pass along the MOD_LOAD
 2613                  * event.
 2614                  */
 2615                 if (data->offset == NULL)
 2616                         return (0);
 2617                 if (data->chainevh) {
 2618                         error = data->chainevh(mod, what, data->chainarg);
 2619                         if (error)
 2620                                 return (error);
 2621                 }
 2622                 error = syscall32_deregister(data->offset, &data->old_sysent);
 2623                 return (error);
 2624         default:
 2625                 error = EOPNOTSUPP;
 2626                 if (data->chainevh)
 2627                         error = data->chainevh(mod, what, data->chainarg);
 2628                 return (error);
 2629         }
 2630 }
 2631 
 2632 int
 2633 syscall32_helper_register(struct syscall_helper_data *sd)
 2634 {
 2635         struct syscall_helper_data *sd1;
 2636         int error;
 2637 
 2638         for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
 2639                 error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
 2640                     &sd1->old_sysent);
 2641                 if (error != 0) {
 2642                         syscall32_helper_unregister(sd);
 2643                         return (error);
 2644                 }
 2645                 sd1->registered = 1;
 2646         }
 2647         return (0);
 2648 }
 2649 
 2650 int
 2651 syscall32_helper_unregister(struct syscall_helper_data *sd)
 2652 {
 2653         struct syscall_helper_data *sd1;
 2654 
 2655         for (sd1 = sd; sd1->registered != 0; sd1++) {
 2656                 syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent);
 2657                 sd1->registered = 0;
 2658         }
 2659         return (0);
 2660 }
 2661 
 2662 register_t *
 2663 freebsd32_copyout_strings(struct image_params *imgp)
 2664 {
 2665         int argc, envc, i;
 2666         u_int32_t *vectp;
 2667         char *stringp, *destp;
 2668         u_int32_t *stack_base;
 2669         struct freebsd32_ps_strings *arginfo;
 2670         char canary[sizeof(long) * 8];
 2671         int32_t pagesizes32[MAXPAGESIZES];
 2672         size_t execpath_len;
 2673         int szsigcode;
 2674 
 2675         /*
 2676          * Calculate string base and vector table pointers.
 2677          * Also deal with signal trampoline code for this exec type.
 2678          */
 2679         if (imgp->execpath != NULL && imgp->auxargs != NULL)
 2680                 execpath_len = strlen(imgp->execpath) + 1;
 2681         else
 2682                 execpath_len = 0;
 2683         arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent->
 2684             sv_psstrings;
 2685         if (imgp->proc->p_sysent->sv_sigcode_base == 0)
 2686                 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
 2687         else
 2688                 szsigcode = 0;
 2689         destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
 2690             roundup(execpath_len, sizeof(char *)) -
 2691             roundup(sizeof(canary), sizeof(char *)) -
 2692             roundup(sizeof(pagesizes32), sizeof(char *)) -
 2693             roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
 2694 
 2695         /*
 2696          * install sigcode
 2697          */
 2698         if (szsigcode != 0)
 2699                 copyout(imgp->proc->p_sysent->sv_sigcode,
 2700                         ((caddr_t)arginfo - szsigcode), szsigcode);
 2701 
 2702         /*
 2703          * Copy the image path for the rtld.
 2704          */
 2705         if (execpath_len != 0) {
 2706                 imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len;
 2707                 copyout(imgp->execpath, (void *)imgp->execpathp,
 2708                     execpath_len);
 2709         }
 2710 
 2711         /*
 2712          * Prepare the canary for SSP.
 2713          */
 2714         arc4rand(canary, sizeof(canary), 0);
 2715         imgp->canary = (uintptr_t)arginfo - szsigcode - execpath_len -
 2716             sizeof(canary);
 2717         copyout(canary, (void *)imgp->canary, sizeof(canary));
 2718         imgp->canarylen = sizeof(canary);
 2719 
 2720         /*
 2721          * Prepare the pagesizes array.
 2722          */
 2723         for (i = 0; i < MAXPAGESIZES; i++)
 2724                 pagesizes32[i] = (uint32_t)pagesizes[i];
 2725         imgp->pagesizes = (uintptr_t)arginfo - szsigcode - execpath_len -
 2726             roundup(sizeof(canary), sizeof(char *)) - sizeof(pagesizes32);
 2727         copyout(pagesizes32, (void *)imgp->pagesizes, sizeof(pagesizes32));
 2728         imgp->pagesizeslen = sizeof(pagesizes32);
 2729 
 2730         /*
 2731          * If we have a valid auxargs ptr, prepare some room
 2732          * on the stack.
 2733          */
 2734         if (imgp->auxargs) {
 2735                 /*
 2736                  * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
 2737                  * lower compatibility.
 2738                  */
 2739                 imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
 2740                         : (AT_COUNT * 2);
 2741                 /*
 2742                  * The '+ 2' is for the null pointers at the end of each of
 2743                  * the arg and env vector sets,and imgp->auxarg_size is room
 2744                  * for argument of Runtime loader.
 2745                  */
 2746                 vectp = (u_int32_t *) (destp - (imgp->args->argc +
 2747                     imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
 2748                     sizeof(u_int32_t));
 2749         } else
 2750                 /*
 2751                  * The '+ 2' is for the null pointers at the end of each of
 2752                  * the arg and env vector sets
 2753                  */
 2754                 vectp = (u_int32_t *)
 2755                         (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
 2756 
 2757         /*
 2758          * vectp also becomes our initial stack base
 2759          */
 2760         stack_base = vectp;
 2761 
 2762         stringp = imgp->args->begin_argv;
 2763         argc = imgp->args->argc;
 2764         envc = imgp->args->envc;
 2765         /*
 2766          * Copy out strings - arguments and environment.
 2767          */
 2768         copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
 2769 
 2770         /*
 2771          * Fill in "ps_strings" struct for ps, w, etc.
 2772          */
 2773         suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
 2774         suword32(&arginfo->ps_nargvstr, argc);
 2775 
 2776         /*
 2777          * Fill in argument portion of vector table.
 2778          */
 2779         for (; argc > 0; --argc) {
 2780                 suword32(vectp++, (u_int32_t)(intptr_t)destp);
 2781                 while (*stringp++ != 0)
 2782                         destp++;
 2783                 destp++;
 2784         }
 2785 
 2786         /* a null vector table pointer separates the argp's from the envp's */
 2787         suword32(vectp++, 0);
 2788 
 2789         suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
 2790         suword32(&arginfo->ps_nenvstr, envc);
 2791 
 2792         /*
 2793          * Fill in environment portion of vector table.
 2794          */
 2795         for (; envc > 0; --envc) {
 2796                 suword32(vectp++, (u_int32_t)(intptr_t)destp);
 2797                 while (*stringp++ != 0)
 2798                         destp++;
 2799                 destp++;
 2800         }
 2801 
 2802         /* end of vector table is a null pointer */
 2803         suword32(vectp, 0);
 2804 
 2805         return ((register_t *)stack_base);
 2806 }
 2807 
 2808 int
 2809 freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
 2810 {
 2811         struct kld_file_stat stat;
 2812         struct kld32_file_stat stat32;
 2813         int error, version;
 2814 
 2815         if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
 2816             != 0)
 2817                 return (error);
 2818         if (version != sizeof(struct kld32_file_stat_1) &&
 2819             version != sizeof(struct kld32_file_stat))
 2820                 return (EINVAL);
 2821 
 2822         error = kern_kldstat(td, uap->fileid, &stat);
 2823         if (error != 0)
 2824                 return (error);
 2825 
 2826         bcopy(&stat.name[0], &stat32.name[0], sizeof(stat.name));
 2827         CP(stat, stat32, refs);
 2828         CP(stat, stat32, id);
 2829         PTROUT_CP(stat, stat32, address);
 2830         CP(stat, stat32, size);
 2831         bcopy(&stat.pathname[0], &stat32.pathname[0], sizeof(stat.pathname));
 2832         return (copyout(&stat32, uap->stat, version));
 2833 }
 2834 
 2835 int
 2836 freebsd32_posix_fallocate(struct thread *td,
 2837     struct freebsd32_posix_fallocate_args *uap)
 2838 {
 2839 
 2840         return (kern_posix_fallocate(td, uap->fd,
 2841             PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len)));
 2842 }
 2843 
 2844 int
 2845 freebsd32_posix_fadvise(struct thread *td,
 2846     struct freebsd32_posix_fadvise_args *uap)
 2847 {
 2848 
 2849         return (kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
 2850             PAIR32TO64(off_t, uap->len), uap->advice));
 2851 }

Cache object: 8cfce577873aa1648e80605e1152b98f


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