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