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