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/6.0/sys/compat/freebsd32/freebsd32_misc.c 148133 2005-07-18 19:49:48Z jhb $");
   29 
   30 #include "opt_compat.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 #include <sys/exec.h>
   36 #include <sys/fcntl.h>
   37 #include <sys/filedesc.h>
   38 #include <sys/namei.h>
   39 #include <sys/imgact.h>
   40 #include <sys/kernel.h>
   41 #include <sys/lock.h>
   42 #include <sys/malloc.h>
   43 #include <sys/file.h>           /* Must come after sys/malloc.h */
   44 #include <sys/mman.h>
   45 #include <sys/module.h>
   46 #include <sys/mount.h>
   47 #include <sys/mutex.h>
   48 #include <sys/namei.h>
   49 #include <sys/param.h>
   50 #include <sys/proc.h>
   51 #include <sys/reboot.h>
   52 #include <sys/resource.h>
   53 #include <sys/resourcevar.h>
   54 #include <sys/selinfo.h>
   55 #include <sys/eventvar.h>       /* Must come after sys/selinfo.h */
   56 #include <sys/pipe.h>           /* Must come after sys/selinfo.h */
   57 #include <sys/signal.h>
   58 #include <sys/signalvar.h>
   59 #include <sys/socket.h>
   60 #include <sys/socketvar.h>
   61 #include <sys/stat.h>
   62 #include <sys/syscallsubr.h>
   63 #include <sys/sysctl.h>
   64 #include <sys/sysent.h>
   65 #include <sys/sysproto.h>
   66 #include <sys/systm.h>
   67 #include <sys/unistd.h>
   68 #include <sys/vnode.h>
   69 #include <sys/wait.h>
   70 
   71 #include <vm/vm.h>
   72 #include <vm/vm_kern.h>
   73 #include <vm/vm_param.h>
   74 #include <vm/pmap.h>
   75 #include <vm/vm_map.h>
   76 #include <vm/vm_object.h>
   77 #include <vm/vm_extern.h>
   78 
   79 #include <compat/freebsd32/freebsd32_util.h>
   80 #include <compat/freebsd32/freebsd32.h>
   81 #include <compat/freebsd32/freebsd32_proto.h>
   82 
   83 CTASSERT(sizeof(struct timeval32) == 8);
   84 CTASSERT(sizeof(struct timespec32) == 8);
   85 CTASSERT(sizeof(struct statfs32) == 256);
   86 CTASSERT(sizeof(struct rusage32) == 72);
   87 
   88 int
   89 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
   90 {
   91         int error, status;
   92         struct rusage32 ru32;
   93         struct rusage ru, *rup;
   94 
   95         if (uap->rusage != NULL)
   96                 rup = &ru;
   97         else
   98                 rup = NULL;
   99         error = kern_wait(td, uap->pid, &status, uap->options, rup);
  100         if (error)
  101                 return (error);
  102         if (uap->status != NULL)
  103                 error = copyout(&status, uap->status, sizeof(status));
  104         if (uap->rusage != NULL && error == 0) {
  105                 TV_CP(ru, ru32, ru_utime);
  106                 TV_CP(ru, ru32, ru_stime);
  107                 CP(ru, ru32, ru_maxrss);
  108                 CP(ru, ru32, ru_ixrss);
  109                 CP(ru, ru32, ru_idrss);
  110                 CP(ru, ru32, ru_isrss);
  111                 CP(ru, ru32, ru_minflt);
  112                 CP(ru, ru32, ru_majflt);
  113                 CP(ru, ru32, ru_nswap);
  114                 CP(ru, ru32, ru_inblock);
  115                 CP(ru, ru32, ru_oublock);
  116                 CP(ru, ru32, ru_msgsnd);
  117                 CP(ru, ru32, ru_msgrcv);
  118                 CP(ru, ru32, ru_nsignals);
  119                 CP(ru, ru32, ru_nvcsw);
  120                 CP(ru, ru32, ru_nivcsw);
  121                 error = copyout(&ru32, uap->rusage, sizeof(ru32));
  122         }
  123         return (error);
  124 }
  125 
  126 #ifdef COMPAT_FREEBSD4
  127 static void
  128 copy_statfs(struct statfs *in, struct statfs32 *out)
  129 {
  130         CP(*in, *out, f_bsize);
  131         CP(*in, *out, f_iosize);
  132         CP(*in, *out, f_blocks);
  133         CP(*in, *out, f_bfree);
  134         CP(*in, *out, f_bavail);
  135         CP(*in, *out, f_files);
  136         CP(*in, *out, f_ffree);
  137         CP(*in, *out, f_fsid);
  138         CP(*in, *out, f_owner);
  139         CP(*in, *out, f_type);
  140         CP(*in, *out, f_flags);
  141         CP(*in, *out, f_flags);
  142         CP(*in, *out, f_syncwrites);
  143         CP(*in, *out, f_asyncwrites);
  144         bcopy(in->f_fstypename,
  145               out->f_fstypename, MFSNAMELEN);
  146         bcopy(in->f_mntonname,
  147               out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  148         CP(*in, *out, f_syncreads);
  149         CP(*in, *out, f_asyncreads);
  150         bcopy(in->f_mntfromname,
  151               out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  152 }
  153 #endif
  154 
  155 #ifdef COMPAT_FREEBSD4
  156 int
  157 freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
  158 {
  159         struct statfs *buf, *sp;
  160         struct statfs32 stat32;
  161         size_t count, size;
  162         int error;
  163 
  164         count = uap->bufsize / sizeof(struct statfs32);
  165         size = count * sizeof(struct statfs);
  166         error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
  167         if (size > 0) {
  168                 count = td->td_retval[0];
  169                 sp = buf;
  170                 while (count > 0 && error == 0) {
  171                         copy_statfs(sp, &stat32);
  172                         error = copyout(&stat32, uap->buf, sizeof(stat32));
  173                         sp++;
  174                         uap->buf++;
  175                         count--;
  176                 }
  177                 free(buf, M_TEMP);
  178         }
  179         return (error);
  180 }
  181 #endif
  182 
  183 struct sigaltstack32 {
  184         u_int32_t       ss_sp;
  185         u_int32_t       ss_size;
  186         int             ss_flags;
  187 };
  188 
  189 CTASSERT(sizeof(struct sigaltstack32) == 12);
  190 
  191 int
  192 freebsd32_sigaltstack(struct thread *td,
  193                       struct freebsd32_sigaltstack_args *uap)
  194 {
  195         struct sigaltstack32 s32;
  196         struct sigaltstack ss, oss, *ssp;
  197         int error;
  198 
  199         if (uap->ss != NULL) {
  200                 error = copyin(uap->ss, &s32, sizeof(s32));
  201                 if (error)
  202                         return (error);
  203                 PTRIN_CP(s32, ss, ss_sp);
  204                 CP(s32, ss, ss_size);
  205                 CP(s32, ss, ss_flags);
  206                 ssp = &ss;
  207         } else
  208                 ssp = NULL;
  209         error = kern_sigaltstack(td, ssp, &oss);
  210         if (error == 0 && uap->oss != NULL) {
  211                 PTROUT_CP(oss, s32, ss_sp);
  212                 CP(oss, s32, ss_size);
  213                 CP(oss, s32, ss_flags);
  214                 error = copyout(&s32, uap->oss, sizeof(s32));
  215         }
  216         return (error);
  217 }
  218 
  219 /*
  220  * Custom version of exec_copyin_args() so that we can translate
  221  * the pointers.
  222  */
  223 static int
  224 freebsd32_exec_copyin_args(struct image_args *args, char *fname,
  225     enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
  226 {
  227         char *argp, *envp;
  228         u_int32_t *p32, arg;
  229         size_t length;
  230         int error;
  231 
  232         bzero(args, sizeof(*args));
  233         if (argv == NULL)
  234                 return (EFAULT);
  235 
  236         /*
  237          * Allocate temporary demand zeroed space for argument and
  238          *      environment strings
  239          */
  240         args->buf = (char *) kmem_alloc_wait(exec_map,
  241             PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
  242         if (args->buf == NULL)
  243                 return (ENOMEM);
  244         args->begin_argv = args->buf;
  245         args->endp = args->begin_argv;
  246         args->stringspace = ARG_MAX;
  247 
  248         args->fname = args->buf + ARG_MAX;
  249 
  250         /*
  251          * Copy the file name.
  252          */
  253         error = (segflg == UIO_SYSSPACE) ?
  254             copystr(fname, args->fname, PATH_MAX, &length) :
  255             copyinstr(fname, args->fname, PATH_MAX, &length);
  256         if (error != 0)
  257                 return (error);
  258 
  259         /*
  260          * extract arguments first
  261          */
  262         p32 = argv;
  263         for (;;) {
  264                 error = copyin(p32++, &arg, sizeof(arg));
  265                 if (error)
  266                         return (error);
  267                 if (arg == 0)
  268                         break;
  269                 argp = PTRIN(arg);
  270                 error = copyinstr(argp, args->endp, args->stringspace, &length);
  271                 if (error) {
  272                         if (error == ENAMETOOLONG)
  273                                 return (E2BIG);
  274                         else
  275                                 return (error);
  276                 }
  277                 args->stringspace -= length;
  278                 args->endp += length;
  279                 args->argc++;
  280         }
  281                         
  282         args->begin_envv = args->endp;
  283 
  284         /*
  285          * extract environment strings
  286          */
  287         if (envv) {
  288                 p32 = envv;
  289                 for (;;) {
  290                         error = copyin(p32++, &arg, sizeof(arg));
  291                         if (error)
  292                                 return (error);
  293                         if (arg == 0)
  294                                 break;
  295                         envp = PTRIN(arg);
  296                         error = copyinstr(envp, args->endp, args->stringspace,
  297                             &length);
  298                         if (error) {
  299                                 if (error == ENAMETOOLONG)
  300                                         return (E2BIG);
  301                                 else
  302                                         return (error);
  303                         }
  304                         args->stringspace -= length;
  305                         args->endp += length;
  306                         args->envc++;
  307                 }
  308         }
  309 
  310         return (0);
  311 }
  312 
  313 int
  314 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
  315 {
  316         struct image_args eargs;
  317         int error;
  318 
  319         error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
  320             uap->argv, uap->envv);
  321         if (error == 0)
  322                 error = kern_execve(td, &eargs, NULL);
  323         exec_free_args(&eargs);
  324         return (error);
  325 }
  326 
  327 #ifdef __ia64__
  328 static int
  329 freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
  330                        int prot, int fd, off_t pos)
  331 {
  332         vm_map_t map;
  333         vm_map_entry_t entry;
  334         int rv;
  335 
  336         map = &td->td_proc->p_vmspace->vm_map;
  337         if (fd != -1)
  338                 prot |= VM_PROT_WRITE;
  339 
  340         if (vm_map_lookup_entry(map, start, &entry)) {
  341                 if ((entry->protection & prot) != prot) {
  342                         rv = vm_map_protect(map,
  343                                             trunc_page(start),
  344                                             round_page(end),
  345                                             entry->protection | prot,
  346                                             FALSE);
  347                         if (rv != KERN_SUCCESS)
  348                                 return (EINVAL);
  349                 }
  350         } else {
  351                 vm_offset_t addr = trunc_page(start);
  352                 rv = vm_map_find(map, 0, 0,
  353                                  &addr, PAGE_SIZE, FALSE, prot,
  354                                  VM_PROT_ALL, 0);
  355                 if (rv != KERN_SUCCESS)
  356                         return (EINVAL);
  357         }
  358 
  359         if (fd != -1) {
  360                 struct pread_args r;
  361                 r.fd = fd;
  362                 r.buf = (void *) start;
  363                 r.nbyte = end - start;
  364                 r.offset = pos;
  365                 return (pread(td, &r));
  366         } else {
  367                 while (start < end) {
  368                         subyte((void *) start, 0);
  369                         start++;
  370                 }
  371                 return (0);
  372         }
  373 }
  374 #endif
  375 
  376 int
  377 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
  378 {
  379         struct mmap_args ap;
  380         vm_offset_t addr = (vm_offset_t) uap->addr;
  381         vm_size_t len    = uap->len;
  382         int prot         = uap->prot;
  383         int flags        = uap->flags;
  384         int fd           = uap->fd;
  385         off_t pos        = (uap->poslo
  386                             | ((off_t)uap->poshi << 32));
  387 #ifdef __ia64__
  388         vm_size_t pageoff;
  389         int error;
  390 
  391         /*
  392          * Attempt to handle page size hassles.
  393          */
  394         pageoff = (pos & PAGE_MASK);
  395         if (flags & MAP_FIXED) {
  396                 vm_offset_t start, end;
  397                 start = addr;
  398                 end = addr + len;
  399 
  400                 mtx_lock(&Giant);
  401                 if (start != trunc_page(start)) {
  402                         error = freebsd32_mmap_partial(td, start,
  403                                                        round_page(start), prot,
  404                                                        fd, pos);
  405                         if (fd != -1)
  406                                 pos += round_page(start) - start;
  407                         start = round_page(start);
  408                 }
  409                 if (end != round_page(end)) {
  410                         vm_offset_t t = trunc_page(end);
  411                         error = freebsd32_mmap_partial(td, t, end,
  412                                                   prot, fd,
  413                                                   pos + t - start);
  414                         end = trunc_page(end);
  415                 }
  416                 if (end > start && fd != -1 && (pos & PAGE_MASK)) {
  417                         /*
  418                          * We can't map this region at all. The specified
  419                          * address doesn't have the same alignment as the file
  420                          * position. Fake the mapping by simply reading the
  421                          * entire region into memory. First we need to make
  422                          * sure the region exists.
  423                          */
  424                         vm_map_t map;
  425                         struct pread_args r;
  426                         int rv;
  427 
  428                         prot |= VM_PROT_WRITE;
  429                         map = &td->td_proc->p_vmspace->vm_map;
  430                         rv = vm_map_remove(map, start, end);
  431                         if (rv != KERN_SUCCESS) {
  432                                 mtx_unlock(&Giant);
  433                                 return (EINVAL);
  434                         }
  435                         rv = vm_map_find(map, 0, 0,
  436                                          &start, end - start, FALSE,
  437                                          prot, VM_PROT_ALL, 0);
  438                         mtx_unlock(&Giant);
  439                         if (rv != KERN_SUCCESS)
  440                                 return (EINVAL);
  441                         r.fd = fd;
  442                         r.buf = (void *) start;
  443                         r.nbyte = end - start;
  444                         r.offset = pos;
  445                         error = pread(td, &r);
  446                         if (error)
  447                                 return (error);
  448 
  449                         td->td_retval[0] = addr;
  450                         return (0);
  451                 }
  452                 mtx_unlock(&Giant);
  453                 if (end == start) {
  454                         /*
  455                          * After dealing with the ragged ends, there
  456                          * might be none left.
  457                          */
  458                         td->td_retval[0] = addr;
  459                         return (0);
  460                 }
  461                 addr = start;
  462                 len = end - start;
  463         }
  464 #endif
  465 
  466         ap.addr = (void *) addr;
  467         ap.len = len;
  468         ap.prot = prot;
  469         ap.flags = flags;
  470         ap.fd = fd;
  471         ap.pos = pos;
  472 
  473         return (mmap(td, &ap));
  474 }
  475 
  476 struct itimerval32 {
  477         struct timeval32 it_interval;
  478         struct timeval32 it_value;
  479 };
  480 
  481 CTASSERT(sizeof(struct itimerval32) == 16);
  482 
  483 int
  484 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
  485 {
  486         struct itimerval itv, oitv, *itvp;      
  487         struct itimerval32 i32;
  488         int error;
  489 
  490         if (uap->itv != NULL) {
  491                 error = copyin(uap->itv, &i32, sizeof(i32));
  492                 if (error)
  493                         return (error);
  494                 TV_CP(i32, itv, it_interval);
  495                 TV_CP(i32, itv, it_value);
  496                 itvp = &itv;
  497         } else
  498                 itvp = NULL;
  499         error = kern_setitimer(td, uap->which, itvp, &oitv);
  500         if (error || uap->oitv == NULL)
  501                 return (error);
  502         TV_CP(oitv, i32, it_interval);
  503         TV_CP(oitv, i32, it_value);
  504         return (copyout(&i32, uap->oitv, sizeof(i32)));
  505 }
  506 
  507 int
  508 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
  509 {
  510         struct itimerval itv;
  511         struct itimerval32 i32;
  512         int error;
  513 
  514         error = kern_getitimer(td, uap->which, &itv);
  515         if (error || uap->itv == NULL)
  516                 return (error);
  517         TV_CP(itv, i32, it_interval);
  518         TV_CP(itv, i32, it_value);
  519         return (copyout(&i32, uap->itv, sizeof(i32)));
  520 }
  521 
  522 int
  523 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
  524 {
  525         struct timeval32 tv32;
  526         struct timeval tv, *tvp;
  527         int error;
  528 
  529         if (uap->tv != NULL) {
  530                 error = copyin(uap->tv, &tv32, sizeof(tv32));
  531                 if (error)
  532                         return (error);
  533                 CP(tv32, tv, tv_sec);
  534                 CP(tv32, tv, tv_usec);
  535                 tvp = &tv;
  536         } else
  537                 tvp = NULL;
  538         /*
  539          * XXX big-endian needs to convert the fd_sets too.
  540          * XXX Do pointers need PTRIN()?
  541          */
  542         return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
  543 }
  544 
  545 struct kevent32 {
  546         u_int32_t       ident;          /* identifier for this event */
  547         short           filter;         /* filter for event */
  548         u_short         flags;
  549         u_int           fflags;
  550         int32_t         data;
  551         u_int32_t       udata;          /* opaque user data identifier */
  552 };
  553 
  554 CTASSERT(sizeof(struct kevent32) == 20);
  555 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
  556 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
  557 
  558 /*
  559  * Copy 'count' items into the destination list pointed to by uap->eventlist.
  560  */
  561 static int
  562 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
  563 {
  564         struct freebsd32_kevent_args *uap;
  565         struct kevent32 ks32[KQ_NEVENTS];
  566         int i, error = 0;
  567 
  568         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  569         uap = (struct freebsd32_kevent_args *)arg;
  570 
  571         for (i = 0; i < count; i++) {
  572                 CP(kevp[i], ks32[i], ident);
  573                 CP(kevp[i], ks32[i], filter);
  574                 CP(kevp[i], ks32[i], flags);
  575                 CP(kevp[i], ks32[i], fflags);
  576                 CP(kevp[i], ks32[i], data);
  577                 PTROUT_CP(kevp[i], ks32[i], udata);
  578         }
  579         error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
  580         if (error == 0)
  581                 uap->eventlist += count;
  582         return (error);
  583 }
  584 
  585 /*
  586  * Copy 'count' items from the list pointed to by uap->changelist.
  587  */
  588 static int
  589 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
  590 {
  591         struct freebsd32_kevent_args *uap;
  592         struct kevent32 ks32[KQ_NEVENTS];
  593         int i, error = 0;
  594 
  595         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  596         uap = (struct freebsd32_kevent_args *)arg;
  597 
  598         error = copyin(uap->changelist, ks32, count * sizeof *ks32);
  599         if (error)
  600                 goto done;
  601         uap->changelist += count;
  602 
  603         for (i = 0; i < count; i++) {
  604                 CP(ks32[i], kevp[i], ident);
  605                 CP(ks32[i], kevp[i], filter);
  606                 CP(ks32[i], kevp[i], flags);
  607                 CP(ks32[i], kevp[i], fflags);
  608                 CP(ks32[i], kevp[i], data);
  609                 PTRIN_CP(ks32[i], kevp[i], udata);
  610         }
  611 done:
  612         return (error);
  613 }
  614 
  615 int
  616 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
  617 {
  618         struct timespec32 ts32;
  619         struct timespec ts, *tsp;
  620         struct kevent_copyops k_ops = { uap,
  621                                         freebsd32_kevent_copyout,
  622                                         freebsd32_kevent_copyin};
  623         int error;
  624 
  625 
  626         if (uap->timeout) {
  627                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
  628                 if (error)
  629                         return (error);
  630                 CP(ts32, ts, tv_sec);
  631                 CP(ts32, ts, tv_nsec);
  632                 tsp = &ts;
  633         } else
  634                 tsp = NULL;
  635         error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
  636             &k_ops, tsp);
  637         return (error);
  638 }
  639 
  640 int
  641 freebsd32_gettimeofday(struct thread *td,
  642                        struct freebsd32_gettimeofday_args *uap)
  643 {
  644         struct timeval atv;
  645         struct timeval32 atv32;
  646         struct timezone rtz;
  647         int error = 0;
  648 
  649         if (uap->tp) {
  650                 microtime(&atv);
  651                 CP(atv, atv32, tv_sec);
  652                 CP(atv, atv32, tv_usec);
  653                 error = copyout(&atv32, uap->tp, sizeof (atv32));
  654         }
  655         if (error == 0 && uap->tzp != NULL) {
  656                 rtz.tz_minuteswest = tz_minuteswest;
  657                 rtz.tz_dsttime = tz_dsttime;
  658                 error = copyout(&rtz, uap->tzp, sizeof (rtz));
  659         }
  660         return (error);
  661 }
  662 
  663 int
  664 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
  665 {
  666         struct rusage32 s32;
  667         struct rusage s;
  668         int error;
  669 
  670         error = kern_getrusage(td, uap->who, &s);
  671         if (error)
  672                 return (error);
  673         if (uap->rusage != NULL) {
  674                 TV_CP(s, s32, ru_utime);
  675                 TV_CP(s, s32, ru_stime);
  676                 CP(s, s32, ru_maxrss);
  677                 CP(s, s32, ru_ixrss);
  678                 CP(s, s32, ru_idrss);
  679                 CP(s, s32, ru_isrss);
  680                 CP(s, s32, ru_minflt);
  681                 CP(s, s32, ru_majflt);
  682                 CP(s, s32, ru_nswap);
  683                 CP(s, s32, ru_inblock);
  684                 CP(s, s32, ru_oublock);
  685                 CP(s, s32, ru_msgsnd);
  686                 CP(s, s32, ru_msgrcv);
  687                 CP(s, s32, ru_nsignals);
  688                 CP(s, s32, ru_nvcsw);
  689                 CP(s, s32, ru_nivcsw);
  690                 error = copyout(&s32, uap->rusage, sizeof(s32));
  691         }
  692         return (error);
  693 }
  694 
  695 struct iovec32 {
  696         u_int32_t iov_base;
  697         int     iov_len;
  698 };
  699 
  700 CTASSERT(sizeof(struct iovec32) == 8);
  701 
  702 static int
  703 freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
  704 {
  705         struct iovec32 iov32;
  706         struct iovec *iov;
  707         struct uio *uio;
  708         u_int iovlen;
  709         int error, i;
  710 
  711         *uiop = NULL;
  712         if (iovcnt > UIO_MAXIOV)
  713                 return (EINVAL);
  714         iovlen = iovcnt * sizeof(struct iovec);
  715         uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
  716         iov = (struct iovec *)(uio + 1);
  717         for (i = 0; i < iovcnt; i++) {
  718                 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
  719                 if (error) {
  720                         free(uio, M_IOV);
  721                         return (error);
  722                 }
  723                 iov[i].iov_base = PTRIN(iov32.iov_base);
  724                 iov[i].iov_len = iov32.iov_len;
  725         }
  726         uio->uio_iov = iov;
  727         uio->uio_iovcnt = iovcnt;
  728         uio->uio_segflg = UIO_USERSPACE;
  729         uio->uio_offset = -1;
  730         uio->uio_resid = 0;
  731         for (i = 0; i < iovcnt; i++) {
  732                 if (iov->iov_len > INT_MAX - uio->uio_resid) {
  733                         free(uio, M_IOV);
  734                         return (EINVAL);
  735                 }
  736                 uio->uio_resid += iov->iov_len;
  737                 iov++;
  738         }
  739         *uiop = uio;
  740         return (0);
  741 }
  742 
  743 int
  744 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
  745 {
  746         struct uio *auio;
  747         int error;
  748 
  749         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  750         if (error)
  751                 return (error);
  752         error = kern_readv(td, uap->fd, auio);
  753         free(auio, M_IOV);
  754         return (error);
  755 }
  756 
  757 int
  758 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
  759 {
  760         struct uio *auio;
  761         int error;
  762 
  763         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  764         if (error)
  765                 return (error);
  766         error = kern_writev(td, uap->fd, auio);
  767         free(auio, M_IOV);
  768         return (error);
  769 }
  770 
  771 int
  772 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
  773 {
  774         struct uio *auio;
  775         int error;
  776 
  777         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  778         if (error)
  779                 return (error);
  780         error = kern_preadv(td, uap->fd, auio, uap->offset);
  781         free(auio, M_IOV);
  782         return (error);
  783 }
  784 
  785 int
  786 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
  787 {
  788         struct uio *auio;
  789         int error;
  790 
  791         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  792         if (error)
  793                 return (error);
  794         error = kern_pwritev(td, uap->fd, auio, uap->offset);
  795         free(auio, M_IOV);
  796         return (error);
  797 }
  798 
  799 int
  800 freebsd32_settimeofday(struct thread *td,
  801                        struct freebsd32_settimeofday_args *uap)
  802 {
  803         struct timeval32 tv32;
  804         struct timeval tv, *tvp;
  805         struct timezone tz, *tzp;
  806         int error;
  807 
  808         if (uap->tv) {
  809                 error = copyin(uap->tv, &tv32, sizeof(tv32));
  810                 if (error)
  811                         return (error);
  812                 CP(tv32, tv, tv_sec);
  813                 CP(tv32, tv, tv_usec);
  814                 tvp = &tv;
  815         } else
  816                 tvp = NULL;
  817         if (uap->tzp) {
  818                 error = copyin(uap->tzp, &tz, sizeof(tz));
  819                 if (error)
  820                         return (error);
  821                 tzp = &tz;
  822         } else
  823                 tzp = NULL;
  824         return (kern_settimeofday(td, tvp, tzp));
  825 }
  826 
  827 int
  828 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
  829 {
  830         struct timeval32 s32[2];
  831         struct timeval s[2], *sp;
  832         int error;
  833 
  834         if (uap->tptr != NULL) {
  835                 error = copyin(uap->tptr, s32, sizeof(s32));
  836                 if (error)
  837                         return (error);
  838                 CP(s32[0], s[0], tv_sec);
  839                 CP(s32[0], s[0], tv_usec);
  840                 CP(s32[1], s[1], tv_sec);
  841                 CP(s32[1], s[1], tv_usec);
  842                 sp = s;
  843         } else
  844                 sp = NULL;
  845         return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
  846 }
  847 
  848 int
  849 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
  850 {
  851         struct timeval32 tv32;
  852         struct timeval delta, olddelta, *deltap;
  853         int error;
  854 
  855         if (uap->delta) {
  856                 error = copyin(uap->delta, &tv32, sizeof(tv32));
  857                 if (error)
  858                         return (error);
  859                 CP(tv32, delta, tv_sec);
  860                 CP(tv32, delta, tv_usec);
  861                 deltap = &delta;
  862         } else
  863                 deltap = NULL;
  864         error = kern_adjtime(td, deltap, &olddelta);
  865         if (uap->olddelta && error == 0) {
  866                 CP(olddelta, tv32, tv_sec);
  867                 CP(olddelta, tv32, tv_usec);
  868                 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
  869         }
  870         return (error);
  871 }
  872 
  873 #ifdef COMPAT_FREEBSD4
  874 int
  875 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
  876 {
  877         struct statfs32 s32;
  878         struct statfs s;
  879         int error;
  880 
  881         error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
  882         if (error)
  883                 return (error);
  884         copy_statfs(&s, &s32);
  885         return (copyout(&s32, uap->buf, sizeof(s32)));
  886 }
  887 #endif
  888 
  889 #ifdef COMPAT_FREEBSD4
  890 int
  891 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
  892 {
  893         struct statfs32 s32;
  894         struct statfs s;
  895         int error;
  896 
  897         error = kern_fstatfs(td, uap->fd, &s);
  898         if (error)
  899                 return (error);
  900         copy_statfs(&s, &s32);
  901         return (copyout(&s32, uap->buf, sizeof(s32)));
  902 }
  903 #endif
  904 
  905 #ifdef COMPAT_FREEBSD4
  906 int
  907 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
  908 {
  909         struct statfs32 s32;
  910         struct statfs s;
  911         fhandle_t fh;
  912         int error;
  913 
  914         if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
  915                 return (error);
  916         error = kern_fhstatfs(td, fh, &s);
  917         if (error)
  918                 return (error);
  919         copy_statfs(&s, &s32);
  920         return (copyout(&s32, uap->buf, sizeof(s32)));
  921 }
  922 #endif
  923 
  924 int
  925 freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
  926 {
  927         /*
  928          * Vector through to semsys if it is loaded.
  929          */
  930         return sysent[169].sy_call(td, uap);
  931 }
  932 
  933 int
  934 freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
  935 {
  936         /*
  937          * Vector through to msgsys if it is loaded.
  938          */
  939         return sysent[170].sy_call(td, uap);
  940 }
  941 
  942 int
  943 freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
  944 {
  945         /*
  946          * Vector through to shmsys if it is loaded.
  947          */
  948         return sysent[171].sy_call(td, uap);
  949 }
  950 
  951 int
  952 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
  953 {
  954         struct pread_args ap;
  955 
  956         ap.fd = uap->fd;
  957         ap.buf = uap->buf;
  958         ap.nbyte = uap->nbyte;
  959         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
  960         return (pread(td, &ap));
  961 }
  962 
  963 int
  964 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
  965 {
  966         struct pwrite_args ap;
  967 
  968         ap.fd = uap->fd;
  969         ap.buf = uap->buf;
  970         ap.nbyte = uap->nbyte;
  971         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
  972         return (pwrite(td, &ap));
  973 }
  974 
  975 int
  976 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
  977 {
  978         int error;
  979         struct lseek_args ap;
  980         off_t pos;
  981 
  982         ap.fd = uap->fd;
  983         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
  984         ap.whence = uap->whence;
  985         error = lseek(td, &ap);
  986         /* Expand the quad return into two parts for eax and edx */
  987         pos = *(off_t *)(td->td_retval);
  988         td->td_retval[0] = pos & 0xffffffff;    /* %eax */
  989         td->td_retval[1] = pos >> 32;           /* %edx */
  990         return error;
  991 }
  992 
  993 int
  994 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
  995 {
  996         struct truncate_args ap;
  997 
  998         ap.path = uap->path;
  999         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1000         return (truncate(td, &ap));
 1001 }
 1002 
 1003 int
 1004 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
 1005 {
 1006         struct ftruncate_args ap;
 1007 
 1008         ap.fd = uap->fd;
 1009         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1010         return (ftruncate(td, &ap));
 1011 }
 1012 
 1013 #ifdef COMPAT_FREEBSD4
 1014 int
 1015 freebsd4_freebsd32_sendfile(struct thread *td,
 1016     struct freebsd4_freebsd32_sendfile_args *uap)
 1017 {
 1018         struct freebsd4_sendfile_args ap;
 1019 
 1020         ap.fd = uap->fd;
 1021         ap.s = uap->s;
 1022         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1023         ap.nbytes = uap->nbytes;        /* XXX check */
 1024         ap.hdtr = uap->hdtr;            /* XXX check */
 1025         ap.sbytes = uap->sbytes;        /* XXX FIXME!! */
 1026         ap.flags = uap->flags;
 1027         return (freebsd4_sendfile(td, &ap));
 1028 }
 1029 #endif
 1030 
 1031 int
 1032 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
 1033 {
 1034         struct sendfile_args ap;
 1035 
 1036         ap.fd = uap->fd;
 1037         ap.s = uap->s;
 1038         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1039         ap.nbytes = uap->nbytes;        /* XXX check */
 1040         ap.hdtr = uap->hdtr;            /* XXX check */
 1041         ap.sbytes = uap->sbytes;        /* XXX FIXME!! */
 1042         ap.flags = uap->flags;
 1043         return (sendfile(td, &ap));
 1044 }
 1045 
 1046 struct stat32 {
 1047         dev_t   st_dev;
 1048         ino_t   st_ino;
 1049         mode_t  st_mode;
 1050         nlink_t st_nlink;
 1051         uid_t   st_uid;
 1052         gid_t   st_gid;
 1053         dev_t   st_rdev;
 1054         struct timespec32 st_atimespec;
 1055         struct timespec32 st_mtimespec;
 1056         struct timespec32 st_ctimespec;
 1057         off_t   st_size;
 1058         int64_t st_blocks;
 1059         u_int32_t st_blksize;
 1060         u_int32_t st_flags;
 1061         u_int32_t st_gen;
 1062         struct timespec32 st_birthtimespec;
 1063         unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
 1064         unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
 1065 };
 1066 
 1067 
 1068 CTASSERT(sizeof(struct stat32) == 96);
 1069 
 1070 static void
 1071 copy_stat( struct stat *in, struct stat32 *out)
 1072 {
 1073         CP(*in, *out, st_dev);
 1074         CP(*in, *out, st_ino);
 1075         CP(*in, *out, st_mode);
 1076         CP(*in, *out, st_nlink);
 1077         CP(*in, *out, st_uid);
 1078         CP(*in, *out, st_gid);
 1079         CP(*in, *out, st_rdev);
 1080         TS_CP(*in, *out, st_atimespec);
 1081         TS_CP(*in, *out, st_mtimespec);
 1082         TS_CP(*in, *out, st_ctimespec);
 1083         CP(*in, *out, st_size);
 1084         CP(*in, *out, st_blocks);
 1085         CP(*in, *out, st_blksize);
 1086         CP(*in, *out, st_flags);
 1087         CP(*in, *out, st_gen);
 1088 }
 1089 
 1090 int
 1091 freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
 1092 {
 1093         struct stat sb;
 1094         struct stat32 sb32;
 1095         int error;
 1096 
 1097         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
 1098         if (error)
 1099                 return (error);
 1100         copy_stat(&sb, &sb32);
 1101         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1102         return (error);
 1103 }
 1104 
 1105 int
 1106 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
 1107 {
 1108         struct stat ub;
 1109         struct stat32 ub32;
 1110         int error;
 1111 
 1112         error = kern_fstat(td, uap->fd, &ub);
 1113         if (error)
 1114                 return (error);
 1115         copy_stat(&ub, &ub32);
 1116         error = copyout(&ub32, uap->ub, sizeof(ub32));
 1117         return (error);
 1118 }
 1119 
 1120 int
 1121 freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
 1122 {
 1123         struct stat sb;
 1124         struct stat32 sb32;
 1125         int error;
 1126 
 1127         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
 1128         if (error)
 1129                 return (error);
 1130         copy_stat(&sb, &sb32);
 1131         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1132         return (error);
 1133 }
 1134 
 1135 /*
 1136  * MPSAFE
 1137  */
 1138 int
 1139 freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
 1140 {
 1141         int error, name[CTL_MAXNAME];
 1142         size_t j, oldlen;
 1143 
 1144         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
 1145                 return (EINVAL);
 1146         error = copyin(uap->name, name, uap->namelen * sizeof(int));
 1147         if (error)
 1148                 return (error);
 1149         mtx_lock(&Giant);
 1150         if (uap->oldlenp)
 1151                 oldlen = fuword32(uap->oldlenp);
 1152         else
 1153                 oldlen = 0;
 1154         error = userland_sysctl(td, name, uap->namelen,
 1155                 uap->old, &oldlen, 1,
 1156                 uap->new, uap->newlen, &j, SCTL_MASK32);
 1157         if (error && error != ENOMEM)
 1158                 goto done2;
 1159         if (uap->oldlenp)
 1160                 suword32(uap->oldlenp, j);
 1161 done2:
 1162         mtx_unlock(&Giant);
 1163         return (error);
 1164 }
 1165 
 1166 struct sigaction32 {
 1167         u_int32_t       sa_u;
 1168         int             sa_flags;
 1169         sigset_t        sa_mask;
 1170 };
 1171 
 1172 CTASSERT(sizeof(struct sigaction32) == 24);
 1173 
 1174 int
 1175 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
 1176 {
 1177         struct sigaction32 s32;
 1178         struct sigaction sa, osa, *sap;
 1179         int error;
 1180 
 1181         if (uap->act) {
 1182                 error = copyin(uap->act, &s32, sizeof(s32));
 1183                 if (error)
 1184                         return (error);
 1185                 sa.sa_handler = PTRIN(s32.sa_u);
 1186                 CP(s32, sa, sa_flags);
 1187                 CP(s32, sa, sa_mask);
 1188                 sap = &sa;
 1189         } else
 1190                 sap = NULL;
 1191         error = kern_sigaction(td, uap->sig, sap, &osa, 0);
 1192         if (error == 0 && uap->oact != NULL) {
 1193                 s32.sa_u = PTROUT(osa.sa_handler);
 1194                 CP(osa, s32, sa_flags);
 1195                 CP(osa, s32, sa_mask);
 1196                 error = copyout(&s32, uap->oact, sizeof(s32));
 1197         }
 1198         return (error);
 1199 }
 1200 
 1201 #ifdef COMPAT_FREEBSD4
 1202 int
 1203 freebsd4_freebsd32_sigaction(struct thread *td,
 1204                              struct freebsd4_freebsd32_sigaction_args *uap)
 1205 {
 1206         struct sigaction32 s32;
 1207         struct sigaction sa, osa, *sap;
 1208         int error;
 1209 
 1210         if (uap->act) {
 1211                 error = copyin(uap->act, &s32, sizeof(s32));
 1212                 if (error)
 1213                         return (error);
 1214                 sa.sa_handler = PTRIN(s32.sa_u);
 1215                 CP(s32, sa, sa_flags);
 1216                 CP(s32, sa, sa_mask);
 1217                 sap = &sa;
 1218         } else
 1219                 sap = NULL;
 1220         error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
 1221         if (error == 0 && uap->oact != NULL) {
 1222                 s32.sa_u = PTROUT(osa.sa_handler);
 1223                 CP(osa, s32, sa_flags);
 1224                 CP(osa, s32, sa_mask);
 1225                 error = copyout(&s32, uap->oact, sizeof(s32));
 1226         }
 1227         return (error);
 1228 }
 1229 #endif
 1230 
 1231 int
 1232 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
 1233 {
 1234         struct timespec32 rmt32, rqt32;
 1235         struct timespec rmt, rqt;
 1236         int error;
 1237 
 1238         error = copyin(uap->rqtp, &rqt32, sizeof(rqt));
 1239         if (error)
 1240                 return (error);
 1241 
 1242         CP(rqt32, rqt, tv_sec);
 1243         CP(rqt32, rqt, tv_nsec);
 1244 
 1245         if (uap->rmtp &&
 1246             !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
 1247                 return (EFAULT);
 1248         error = kern_nanosleep(td, &rqt, &rmt);
 1249         if (error && uap->rmtp) {
 1250                 int error2;
 1251 
 1252                 CP(rmt, rmt32, tv_sec);
 1253                 CP(rmt, rmt32, tv_nsec);
 1254 
 1255                 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt));
 1256                 if (error2)
 1257                         error = error2;
 1258         }
 1259         return (error);
 1260 }
 1261 
 1262 #if 0
 1263 
 1264 int
 1265 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
 1266 {
 1267         int error;
 1268         struct yyy32 *p32, s32;
 1269         struct yyy *p = NULL, s;
 1270 
 1271         if (uap->zzz) {
 1272                 error = copyin(uap->zzz, &s32, sizeof(s32));
 1273                 if (error)
 1274                         return (error);
 1275                 /* translate in */
 1276                 p = &s;
 1277         }
 1278         error = kern_xxx(td, p);
 1279         if (error)
 1280                 return (error);
 1281         if (uap->zzz) {
 1282                 /* translate out */
 1283                 error = copyout(&s32, p32, sizeof(s32));
 1284         }
 1285         return (error);
 1286 }
 1287 
 1288 #endif

Cache object: c55b379e5aa430fe4e2cf630c614c9f3


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