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