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