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

Cache object: c492c64ed5d294a5b07e2af7c81114c2


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