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