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