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