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