xref: /freebsd/sys/compat/freebsd32/freebsd32_misc.c (revision 94942af266ac119ede0ca836f9aa5a5ac0582938)
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 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/clock.h>
36 #include <sys/exec.h>
37 #include <sys/fcntl.h>
38 #include <sys/filedesc.h>
39 #include <sys/namei.h>
40 #include <sys/imgact.h>
41 #include <sys/kernel.h>
42 #include <sys/limits.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/file.h>		/* Must come after sys/malloc.h */
46 #include <sys/mbuf.h>
47 #include <sys/mman.h>
48 #include <sys/module.h>
49 #include <sys/mount.h>
50 #include <sys/mutex.h>
51 #include <sys/namei.h>
52 #include <sys/param.h>
53 #include <sys/proc.h>
54 #include <sys/reboot.h>
55 #include <sys/resource.h>
56 #include <sys/resourcevar.h>
57 #include <sys/selinfo.h>
58 #include <sys/eventvar.h>	/* Must come after sys/selinfo.h */
59 #include <sys/pipe.h>		/* Must come after sys/selinfo.h */
60 #include <sys/signal.h>
61 #include <sys/signalvar.h>
62 #include <sys/socket.h>
63 #include <sys/socketvar.h>
64 #include <sys/stat.h>
65 #include <sys/syscall.h>
66 #include <sys/syscallsubr.h>
67 #include <sys/sysctl.h>
68 #include <sys/sysent.h>
69 #include <sys/sysproto.h>
70 #include <sys/systm.h>
71 #include <sys/thr.h>
72 #include <sys/unistd.h>
73 #include <sys/ucontext.h>
74 #include <sys/vnode.h>
75 #include <sys/wait.h>
76 #include <sys/ipc.h>
77 #include <sys/shm.h>
78 
79 #include <vm/vm.h>
80 #include <vm/vm_kern.h>
81 #include <vm/vm_param.h>
82 #include <vm/pmap.h>
83 #include <vm/vm_map.h>
84 #include <vm/vm_object.h>
85 #include <vm/vm_extern.h>
86 
87 #include <machine/cpu.h>
88 
89 #include <compat/freebsd32/freebsd32_util.h>
90 #include <compat/freebsd32/freebsd32.h>
91 #include <compat/freebsd32/freebsd32_signal.h>
92 #include <compat/freebsd32/freebsd32_proto.h>
93 
94 CTASSERT(sizeof(struct timeval32) == 8);
95 CTASSERT(sizeof(struct timespec32) == 8);
96 CTASSERT(sizeof(struct statfs32) == 256);
97 CTASSERT(sizeof(struct rusage32) == 72);
98 
99 int
100 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
101 {
102 	int error, status;
103 	struct rusage32 ru32;
104 	struct rusage ru, *rup;
105 
106 	if (uap->rusage != NULL)
107 		rup = &ru;
108 	else
109 		rup = NULL;
110 	error = kern_wait(td, uap->pid, &status, uap->options, rup);
111 	if (error)
112 		return (error);
113 	if (uap->status != NULL)
114 		error = copyout(&status, uap->status, sizeof(status));
115 	if (uap->rusage != NULL && error == 0) {
116 		TV_CP(ru, ru32, ru_utime);
117 		TV_CP(ru, ru32, ru_stime);
118 		CP(ru, ru32, ru_maxrss);
119 		CP(ru, ru32, ru_ixrss);
120 		CP(ru, ru32, ru_idrss);
121 		CP(ru, ru32, ru_isrss);
122 		CP(ru, ru32, ru_minflt);
123 		CP(ru, ru32, ru_majflt);
124 		CP(ru, ru32, ru_nswap);
125 		CP(ru, ru32, ru_inblock);
126 		CP(ru, ru32, ru_oublock);
127 		CP(ru, ru32, ru_msgsnd);
128 		CP(ru, ru32, ru_msgrcv);
129 		CP(ru, ru32, ru_nsignals);
130 		CP(ru, ru32, ru_nvcsw);
131 		CP(ru, ru32, ru_nivcsw);
132 		error = copyout(&ru32, uap->rusage, sizeof(ru32));
133 	}
134 	return (error);
135 }
136 
137 #ifdef COMPAT_FREEBSD4
138 static void
139 copy_statfs(struct statfs *in, struct statfs32 *out)
140 {
141 
142 	bzero(out, sizeof(*out));
143 	CP(*in, *out, f_bsize);
144 	CP(*in, *out, f_iosize);
145 	CP(*in, *out, f_blocks);
146 	CP(*in, *out, f_bfree);
147 	CP(*in, *out, f_bavail);
148 	CP(*in, *out, f_files);
149 	CP(*in, *out, f_ffree);
150 	CP(*in, *out, f_fsid);
151 	CP(*in, *out, f_owner);
152 	CP(*in, *out, f_type);
153 	CP(*in, *out, f_flags);
154 	CP(*in, *out, f_flags);
155 	CP(*in, *out, f_syncwrites);
156 	CP(*in, *out, f_asyncwrites);
157 	strlcpy(out->f_fstypename,
158 	      in->f_fstypename, MFSNAMELEN);
159 	strlcpy(out->f_mntonname,
160 	      in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
161 	CP(*in, *out, f_syncreads);
162 	CP(*in, *out, f_asyncreads);
163 	strlcpy(out->f_mntfromname,
164 	      in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
165 }
166 #endif
167 
168 #ifdef COMPAT_FREEBSD4
169 int
170 freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
171 {
172 	struct statfs *buf, *sp;
173 	struct statfs32 stat32;
174 	size_t count, size;
175 	int error;
176 
177 	count = uap->bufsize / sizeof(struct statfs32);
178 	size = count * sizeof(struct statfs);
179 	error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
180 	if (size > 0) {
181 		count = td->td_retval[0];
182 		sp = buf;
183 		while (count > 0 && error == 0) {
184 			copy_statfs(sp, &stat32);
185 			error = copyout(&stat32, uap->buf, sizeof(stat32));
186 			sp++;
187 			uap->buf++;
188 			count--;
189 		}
190 		free(buf, M_TEMP);
191 	}
192 	return (error);
193 }
194 #endif
195 
196 CTASSERT(sizeof(struct sigaltstack32) == 12);
197 
198 int
199 freebsd32_sigaltstack(struct thread *td,
200 		      struct freebsd32_sigaltstack_args *uap)
201 {
202 	struct sigaltstack32 s32;
203 	struct sigaltstack ss, oss, *ssp;
204 	int error;
205 
206 	if (uap->ss != NULL) {
207 		error = copyin(uap->ss, &s32, sizeof(s32));
208 		if (error)
209 			return (error);
210 		PTRIN_CP(s32, ss, ss_sp);
211 		CP(s32, ss, ss_size);
212 		CP(s32, ss, ss_flags);
213 		ssp = &ss;
214 	} else
215 		ssp = NULL;
216 	error = kern_sigaltstack(td, ssp, &oss);
217 	if (error == 0 && uap->oss != NULL) {
218 		PTROUT_CP(oss, s32, ss_sp);
219 		CP(oss, s32, ss_size);
220 		CP(oss, s32, ss_flags);
221 		error = copyout(&s32, uap->oss, sizeof(s32));
222 	}
223 	return (error);
224 }
225 
226 /*
227  * Custom version of exec_copyin_args() so that we can translate
228  * the pointers.
229  */
230 static int
231 freebsd32_exec_copyin_args(struct image_args *args, char *fname,
232     enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
233 {
234 	char *argp, *envp;
235 	u_int32_t *p32, arg;
236 	size_t length;
237 	int error;
238 
239 	bzero(args, sizeof(*args));
240 	if (argv == NULL)
241 		return (EFAULT);
242 
243 	/*
244 	 * Allocate temporary demand zeroed space for argument and
245 	 *	environment strings
246 	 */
247 	args->buf = (char *) kmem_alloc_wait(exec_map,
248 	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
249 	if (args->buf == NULL)
250 		return (ENOMEM);
251 	args->begin_argv = args->buf;
252 	args->endp = args->begin_argv;
253 	args->stringspace = ARG_MAX;
254 
255 	args->fname = args->buf + ARG_MAX;
256 
257 	/*
258 	 * Copy the file name.
259 	 */
260 	error = (segflg == UIO_SYSSPACE) ?
261 	    copystr(fname, args->fname, PATH_MAX, &length) :
262 	    copyinstr(fname, args->fname, PATH_MAX, &length);
263 	if (error != 0)
264 		goto err_exit;
265 
266 	/*
267 	 * extract arguments first
268 	 */
269 	p32 = argv;
270 	for (;;) {
271 		error = copyin(p32++, &arg, sizeof(arg));
272 		if (error)
273 			goto err_exit;
274 		if (arg == 0)
275 			break;
276 		argp = PTRIN(arg);
277 		error = copyinstr(argp, args->endp, args->stringspace, &length);
278 		if (error) {
279 			if (error == ENAMETOOLONG)
280 				error = E2BIG;
281 			goto err_exit;
282 		}
283 		args->stringspace -= length;
284 		args->endp += length;
285 		args->argc++;
286 	}
287 
288 	args->begin_envv = args->endp;
289 
290 	/*
291 	 * extract environment strings
292 	 */
293 	if (envv) {
294 		p32 = envv;
295 		for (;;) {
296 			error = copyin(p32++, &arg, sizeof(arg));
297 			if (error)
298 				goto err_exit;
299 			if (arg == 0)
300 				break;
301 			envp = PTRIN(arg);
302 			error = copyinstr(envp, args->endp, args->stringspace,
303 			    &length);
304 			if (error) {
305 				if (error == ENAMETOOLONG)
306 					error = E2BIG;
307 				goto err_exit;
308 			}
309 			args->stringspace -= length;
310 			args->endp += length;
311 			args->envc++;
312 		}
313 	}
314 
315 	return (0);
316 
317 err_exit:
318 	kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
319 	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
320 	args->buf = NULL;
321 	return (error);
322 }
323 
324 int
325 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
326 {
327 	struct image_args eargs;
328 	int error;
329 
330 	error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
331 	    uap->argv, uap->envv);
332 	if (error == 0)
333 		error = kern_execve(td, &eargs, NULL);
334 	return (error);
335 }
336 
337 #ifdef __ia64__
338 static int
339 freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
340 		       int prot, int fd, off_t pos)
341 {
342 	vm_map_t map;
343 	vm_map_entry_t entry;
344 	int rv;
345 
346 	map = &td->td_proc->p_vmspace->vm_map;
347 	if (fd != -1)
348 		prot |= VM_PROT_WRITE;
349 
350 	if (vm_map_lookup_entry(map, start, &entry)) {
351 		if ((entry->protection & prot) != prot) {
352 			rv = vm_map_protect(map,
353 					    trunc_page(start),
354 					    round_page(end),
355 					    entry->protection | prot,
356 					    FALSE);
357 			if (rv != KERN_SUCCESS)
358 				return (EINVAL);
359 		}
360 	} else {
361 		vm_offset_t addr = trunc_page(start);
362 		rv = vm_map_find(map, 0, 0,
363 				 &addr, PAGE_SIZE, FALSE, prot,
364 				 VM_PROT_ALL, 0);
365 		if (rv != KERN_SUCCESS)
366 			return (EINVAL);
367 	}
368 
369 	if (fd != -1) {
370 		struct pread_args r;
371 		r.fd = fd;
372 		r.buf = (void *) start;
373 		r.nbyte = end - start;
374 		r.offset = pos;
375 		return (pread(td, &r));
376 	} else {
377 		while (start < end) {
378 			subyte((void *) start, 0);
379 			start++;
380 		}
381 		return (0);
382 	}
383 }
384 #endif
385 
386 int
387 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
388 {
389 	struct mmap_args ap;
390 	vm_offset_t addr = (vm_offset_t) uap->addr;
391 	vm_size_t len	 = uap->len;
392 	int prot	 = uap->prot;
393 	int flags	 = uap->flags;
394 	int fd		 = uap->fd;
395 	off_t pos	 = (uap->poslo
396 			    | ((off_t)uap->poshi << 32));
397 #ifdef __ia64__
398 	vm_size_t pageoff;
399 	int error;
400 
401 	/*
402 	 * Attempt to handle page size hassles.
403 	 */
404 	pageoff = (pos & PAGE_MASK);
405 	if (flags & MAP_FIXED) {
406 		vm_offset_t start, end;
407 		start = addr;
408 		end = addr + len;
409 
410 		if (start != trunc_page(start)) {
411 			error = freebsd32_mmap_partial(td, start,
412 						       round_page(start), prot,
413 						       fd, pos);
414 			if (fd != -1)
415 				pos += round_page(start) - start;
416 			start = round_page(start);
417 		}
418 		if (end != round_page(end)) {
419 			vm_offset_t t = trunc_page(end);
420 			error = freebsd32_mmap_partial(td, t, end,
421 						  prot, fd,
422 						  pos + t - start);
423 			end = trunc_page(end);
424 		}
425 		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
426 			/*
427 			 * We can't map this region at all. The specified
428 			 * address doesn't have the same alignment as the file
429 			 * position. Fake the mapping by simply reading the
430 			 * entire region into memory. First we need to make
431 			 * sure the region exists.
432 			 */
433 			vm_map_t map;
434 			struct pread_args r;
435 			int rv;
436 
437 			prot |= VM_PROT_WRITE;
438 			map = &td->td_proc->p_vmspace->vm_map;
439 			rv = vm_map_remove(map, start, end);
440 			if (rv != KERN_SUCCESS)
441 				return (EINVAL);
442 			rv = vm_map_find(map, 0, 0,
443 					 &start, end - start, FALSE,
444 					 prot, VM_PROT_ALL, 0);
445 			if (rv != KERN_SUCCESS)
446 				return (EINVAL);
447 			r.fd = fd;
448 			r.buf = (void *) start;
449 			r.nbyte = end - start;
450 			r.offset = pos;
451 			error = pread(td, &r);
452 			if (error)
453 				return (error);
454 
455 			td->td_retval[0] = addr;
456 			return (0);
457 		}
458 		if (end == start) {
459 			/*
460 			 * After dealing with the ragged ends, there
461 			 * might be none left.
462 			 */
463 			td->td_retval[0] = addr;
464 			return (0);
465 		}
466 		addr = start;
467 		len = end - start;
468 	}
469 #endif
470 
471 	ap.addr = (void *) addr;
472 	ap.len = len;
473 	ap.prot = prot;
474 	ap.flags = flags;
475 	ap.fd = fd;
476 	ap.pos = pos;
477 
478 	return (mmap(td, &ap));
479 }
480 
481 struct itimerval32 {
482 	struct timeval32 it_interval;
483 	struct timeval32 it_value;
484 };
485 
486 CTASSERT(sizeof(struct itimerval32) == 16);
487 
488 int
489 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
490 {
491 	struct itimerval itv, oitv, *itvp;
492 	struct itimerval32 i32;
493 	int error;
494 
495 	if (uap->itv != NULL) {
496 		error = copyin(uap->itv, &i32, sizeof(i32));
497 		if (error)
498 			return (error);
499 		TV_CP(i32, itv, it_interval);
500 		TV_CP(i32, itv, it_value);
501 		itvp = &itv;
502 	} else
503 		itvp = NULL;
504 	error = kern_setitimer(td, uap->which, itvp, &oitv);
505 	if (error || uap->oitv == NULL)
506 		return (error);
507 	TV_CP(oitv, i32, it_interval);
508 	TV_CP(oitv, i32, it_value);
509 	return (copyout(&i32, uap->oitv, sizeof(i32)));
510 }
511 
512 int
513 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
514 {
515 	struct itimerval itv;
516 	struct itimerval32 i32;
517 	int error;
518 
519 	error = kern_getitimer(td, uap->which, &itv);
520 	if (error || uap->itv == NULL)
521 		return (error);
522 	TV_CP(itv, i32, it_interval);
523 	TV_CP(itv, i32, it_value);
524 	return (copyout(&i32, uap->itv, sizeof(i32)));
525 }
526 
527 int
528 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
529 {
530 	struct timeval32 tv32;
531 	struct timeval tv, *tvp;
532 	int error;
533 
534 	if (uap->tv != NULL) {
535 		error = copyin(uap->tv, &tv32, sizeof(tv32));
536 		if (error)
537 			return (error);
538 		CP(tv32, tv, tv_sec);
539 		CP(tv32, tv, tv_usec);
540 		tvp = &tv;
541 	} else
542 		tvp = NULL;
543 	/*
544 	 * XXX big-endian needs to convert the fd_sets too.
545 	 * XXX Do pointers need PTRIN()?
546 	 */
547 	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
548 }
549 
550 struct kevent32 {
551 	u_int32_t	ident;		/* identifier for this event */
552 	short		filter;		/* filter for event */
553 	u_short		flags;
554 	u_int		fflags;
555 	int32_t		data;
556 	u_int32_t	udata;		/* opaque user data identifier */
557 };
558 
559 CTASSERT(sizeof(struct kevent32) == 20);
560 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
561 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
562 
563 /*
564  * Copy 'count' items into the destination list pointed to by uap->eventlist.
565  */
566 static int
567 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
568 {
569 	struct freebsd32_kevent_args *uap;
570 	struct kevent32	ks32[KQ_NEVENTS];
571 	int i, error = 0;
572 
573 	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
574 	uap = (struct freebsd32_kevent_args *)arg;
575 
576 	for (i = 0; i < count; i++) {
577 		CP(kevp[i], ks32[i], ident);
578 		CP(kevp[i], ks32[i], filter);
579 		CP(kevp[i], ks32[i], flags);
580 		CP(kevp[i], ks32[i], fflags);
581 		CP(kevp[i], ks32[i], data);
582 		PTROUT_CP(kevp[i], ks32[i], udata);
583 	}
584 	error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
585 	if (error == 0)
586 		uap->eventlist += count;
587 	return (error);
588 }
589 
590 /*
591  * Copy 'count' items from the list pointed to by uap->changelist.
592  */
593 static int
594 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
595 {
596 	struct freebsd32_kevent_args *uap;
597 	struct kevent32	ks32[KQ_NEVENTS];
598 	int i, error = 0;
599 
600 	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
601 	uap = (struct freebsd32_kevent_args *)arg;
602 
603 	error = copyin(uap->changelist, ks32, count * sizeof *ks32);
604 	if (error)
605 		goto done;
606 	uap->changelist += count;
607 
608 	for (i = 0; i < count; i++) {
609 		CP(ks32[i], kevp[i], ident);
610 		CP(ks32[i], kevp[i], filter);
611 		CP(ks32[i], kevp[i], flags);
612 		CP(ks32[i], kevp[i], fflags);
613 		CP(ks32[i], kevp[i], data);
614 		PTRIN_CP(ks32[i], kevp[i], udata);
615 	}
616 done:
617 	return (error);
618 }
619 
620 int
621 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
622 {
623 	struct timespec32 ts32;
624 	struct timespec ts, *tsp;
625 	struct kevent_copyops k_ops = { uap,
626 					freebsd32_kevent_copyout,
627 					freebsd32_kevent_copyin};
628 	int error;
629 
630 
631 	if (uap->timeout) {
632 		error = copyin(uap->timeout, &ts32, sizeof(ts32));
633 		if (error)
634 			return (error);
635 		CP(ts32, ts, tv_sec);
636 		CP(ts32, ts, tv_nsec);
637 		tsp = &ts;
638 	} else
639 		tsp = NULL;
640 	error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
641 	    &k_ops, tsp);
642 	return (error);
643 }
644 
645 int
646 freebsd32_gettimeofday(struct thread *td,
647 		       struct freebsd32_gettimeofday_args *uap)
648 {
649 	struct timeval atv;
650 	struct timeval32 atv32;
651 	struct timezone rtz;
652 	int error = 0;
653 
654 	if (uap->tp) {
655 		microtime(&atv);
656 		CP(atv, atv32, tv_sec);
657 		CP(atv, atv32, tv_usec);
658 		error = copyout(&atv32, uap->tp, sizeof (atv32));
659 	}
660 	if (error == 0 && uap->tzp != NULL) {
661 		rtz.tz_minuteswest = tz_minuteswest;
662 		rtz.tz_dsttime = tz_dsttime;
663 		error = copyout(&rtz, uap->tzp, sizeof (rtz));
664 	}
665 	return (error);
666 }
667 
668 int
669 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
670 {
671 	struct rusage32 s32;
672 	struct rusage s;
673 	int error;
674 
675 	error = kern_getrusage(td, uap->who, &s);
676 	if (error)
677 		return (error);
678 	if (uap->rusage != NULL) {
679 		TV_CP(s, s32, ru_utime);
680 		TV_CP(s, s32, ru_stime);
681 		CP(s, s32, ru_maxrss);
682 		CP(s, s32, ru_ixrss);
683 		CP(s, s32, ru_idrss);
684 		CP(s, s32, ru_isrss);
685 		CP(s, s32, ru_minflt);
686 		CP(s, s32, ru_majflt);
687 		CP(s, s32, ru_nswap);
688 		CP(s, s32, ru_inblock);
689 		CP(s, s32, ru_oublock);
690 		CP(s, s32, ru_msgsnd);
691 		CP(s, s32, ru_msgrcv);
692 		CP(s, s32, ru_nsignals);
693 		CP(s, s32, ru_nvcsw);
694 		CP(s, s32, ru_nivcsw);
695 		error = copyout(&s32, uap->rusage, sizeof(s32));
696 	}
697 	return (error);
698 }
699 
700 struct iovec32 {
701 	u_int32_t iov_base;
702 	int	iov_len;
703 };
704 
705 CTASSERT(sizeof(struct iovec32) == 8);
706 
707 static int
708 freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
709 {
710 	struct iovec32 iov32;
711 	struct iovec *iov;
712 	struct uio *uio;
713 	u_int iovlen;
714 	int error, i;
715 
716 	*uiop = NULL;
717 	if (iovcnt > UIO_MAXIOV)
718 		return (EINVAL);
719 	iovlen = iovcnt * sizeof(struct iovec);
720 	uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
721 	iov = (struct iovec *)(uio + 1);
722 	for (i = 0; i < iovcnt; i++) {
723 		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
724 		if (error) {
725 			free(uio, M_IOV);
726 			return (error);
727 		}
728 		iov[i].iov_base = PTRIN(iov32.iov_base);
729 		iov[i].iov_len = iov32.iov_len;
730 	}
731 	uio->uio_iov = iov;
732 	uio->uio_iovcnt = iovcnt;
733 	uio->uio_segflg = UIO_USERSPACE;
734 	uio->uio_offset = -1;
735 	uio->uio_resid = 0;
736 	for (i = 0; i < iovcnt; i++) {
737 		if (iov->iov_len > INT_MAX - uio->uio_resid) {
738 			free(uio, M_IOV);
739 			return (EINVAL);
740 		}
741 		uio->uio_resid += iov->iov_len;
742 		iov++;
743 	}
744 	*uiop = uio;
745 	return (0);
746 }
747 
748 int
749 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
750 {
751 	struct uio *auio;
752 	int error;
753 
754 	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
755 	if (error)
756 		return (error);
757 	error = kern_readv(td, uap->fd, auio);
758 	free(auio, M_IOV);
759 	return (error);
760 }
761 
762 int
763 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
764 {
765 	struct uio *auio;
766 	int error;
767 
768 	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
769 	if (error)
770 		return (error);
771 	error = kern_writev(td, uap->fd, auio);
772 	free(auio, M_IOV);
773 	return (error);
774 }
775 
776 int
777 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
778 {
779 	struct uio *auio;
780 	int error;
781 
782 	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
783 	if (error)
784 		return (error);
785 	error = kern_preadv(td, uap->fd, auio, uap->offset);
786 	free(auio, M_IOV);
787 	return (error);
788 }
789 
790 int
791 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
792 {
793 	struct uio *auio;
794 	int error;
795 
796 	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
797 	if (error)
798 		return (error);
799 	error = kern_pwritev(td, uap->fd, auio, uap->offset);
800 	free(auio, M_IOV);
801 	return (error);
802 }
803 
804 static int
805 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
806     int error)
807 {
808 	struct iovec32 iov32;
809 	struct iovec *iov;
810 	u_int iovlen;
811 	int i;
812 
813 	*iovp = NULL;
814 	if (iovcnt > UIO_MAXIOV)
815 		return (error);
816 	iovlen = iovcnt * sizeof(struct iovec);
817 	iov = malloc(iovlen, M_IOV, M_WAITOK);
818 	for (i = 0; i < iovcnt; i++) {
819 		error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
820 		if (error) {
821 			free(iov, M_IOV);
822 			return (error);
823 		}
824 		iov[i].iov_base = PTRIN(iov32.iov_base);
825 		iov[i].iov_len = iov32.iov_len;
826 	}
827 	*iovp = iov;
828 	return (0);
829 }
830 
831 struct msghdr32 {
832 	u_int32_t	 msg_name;
833 	socklen_t	 msg_namelen;
834 	u_int32_t	 msg_iov;
835 	int		 msg_iovlen;
836 	u_int32_t	 msg_control;
837 	socklen_t	 msg_controllen;
838 	int		 msg_flags;
839 };
840 CTASSERT(sizeof(struct msghdr32) == 28);
841 
842 static int
843 freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
844 {
845 	struct msghdr32 m32;
846 	int error;
847 
848 	error = copyin(msg32, &m32, sizeof(m32));
849 	if (error)
850 		return (error);
851 	msg->msg_name = PTRIN(m32.msg_name);
852 	msg->msg_namelen = m32.msg_namelen;
853 	msg->msg_iov = PTRIN(m32.msg_iov);
854 	msg->msg_iovlen = m32.msg_iovlen;
855 	msg->msg_control = PTRIN(m32.msg_control);
856 	msg->msg_controllen = m32.msg_controllen;
857 	msg->msg_flags = m32.msg_flags;
858 	return (0);
859 }
860 
861 static int
862 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
863 {
864 	struct msghdr32 m32;
865 	int error;
866 
867 	m32.msg_name = PTROUT(msg->msg_name);
868 	m32.msg_namelen = msg->msg_namelen;
869 	m32.msg_iov = PTROUT(msg->msg_iov);
870 	m32.msg_iovlen = msg->msg_iovlen;
871 	m32.msg_control = PTROUT(msg->msg_control);
872 	m32.msg_controllen = msg->msg_controllen;
873 	m32.msg_flags = msg->msg_flags;
874 	error = copyout(&m32, msg32, sizeof(m32));
875 	return (error);
876 }
877 
878 #define FREEBSD32_ALIGNBYTES	(sizeof(int) - 1)
879 #define FREEBSD32_ALIGN(p)	\
880 	(((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
881 #define	FREEBSD32_CMSG_SPACE(l)	\
882 	(FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
883 
884 #define	FREEBSD32_CMSG_DATA(cmsg)	((unsigned char *)(cmsg) + \
885 				 FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
886 static int
887 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
888 {
889 	struct cmsghdr *cm;
890 	void *data;
891 	socklen_t clen, datalen;
892 	int error;
893 	caddr_t ctlbuf;
894 	int len, maxlen, copylen;
895 	struct mbuf *m;
896 	error = 0;
897 
898 	len    = msg->msg_controllen;
899 	maxlen = msg->msg_controllen;
900 	msg->msg_controllen = 0;
901 
902 	m = control;
903 	ctlbuf = msg->msg_control;
904 
905 	while (m && len > 0) {
906 		cm = mtod(m, struct cmsghdr *);
907 		clen = m->m_len;
908 
909 		while (cm != NULL) {
910 
911 			if (sizeof(struct cmsghdr) > clen ||
912 			    cm->cmsg_len > clen) {
913 				error = EINVAL;
914 				break;
915 			}
916 
917 			data   = CMSG_DATA(cm);
918 			datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
919 
920 			/* Adjust message length */
921 			cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
922 			    datalen;
923 
924 
925 			/* Copy cmsghdr */
926 			copylen = sizeof(struct cmsghdr);
927 			if (len < copylen) {
928 				msg->msg_flags |= MSG_CTRUNC;
929 				copylen = len;
930 			}
931 
932 			error = copyout(cm,ctlbuf,copylen);
933 			if (error)
934 				goto exit;
935 
936 			ctlbuf += FREEBSD32_ALIGN(copylen);
937 			len    -= FREEBSD32_ALIGN(copylen);
938 
939 			if (len <= 0)
940 				break;
941 
942 			/* Copy data */
943 			copylen = datalen;
944 			if (len < copylen) {
945 				msg->msg_flags |= MSG_CTRUNC;
946 				copylen = len;
947 			}
948 
949 			error = copyout(data,ctlbuf,copylen);
950 			if (error)
951 				goto exit;
952 
953 			ctlbuf += FREEBSD32_ALIGN(copylen);
954 			len    -= FREEBSD32_ALIGN(copylen);
955 
956 			if (CMSG_SPACE(datalen) < clen) {
957 				clen -= CMSG_SPACE(datalen);
958 				cm = (struct cmsghdr *)
959 					((caddr_t)cm + CMSG_SPACE(datalen));
960 			} else {
961 				clen = 0;
962 				cm = NULL;
963 			}
964 		}
965 		m = m->m_next;
966 	}
967 
968 	msg->msg_controllen = (len <= 0) ? maxlen :  ctlbuf - (caddr_t)msg->msg_control;
969 
970 exit:
971 	return (error);
972 
973 }
974 
975 int
976 freebsd32_recvmsg(td, uap)
977 	struct thread *td;
978 	struct freebsd32_recvmsg_args /* {
979 		int	s;
980 		struct	msghdr32 *msg;
981 		int	flags;
982 	} */ *uap;
983 {
984 	struct msghdr msg;
985 	struct msghdr32 m32;
986 	struct iovec *uiov, *iov;
987 	struct mbuf *control = NULL;
988 	struct mbuf **controlp;
989 
990 	int error;
991 	error = copyin(uap->msg, &m32, sizeof(m32));
992 	if (error)
993 		return (error);
994 	error = freebsd32_copyinmsghdr(uap->msg, &msg);
995 	if (error)
996 		return (error);
997 	error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
998 	    EMSGSIZE);
999 	if (error)
1000 		return (error);
1001 	msg.msg_flags = uap->flags;
1002 	uiov = msg.msg_iov;
1003 	msg.msg_iov = iov;
1004 
1005 	controlp = (msg.msg_control != NULL) ?  &control : NULL;
1006 	error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1007 	if (error == 0) {
1008 		msg.msg_iov = uiov;
1009 
1010 		if (control != NULL)
1011 			error = freebsd32_copy_msg_out(&msg, control);
1012 
1013 		if (error == 0)
1014 			error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1015 	}
1016 	free(iov, M_IOV);
1017 
1018 	if (control != NULL)
1019 		m_freem(control);
1020 
1021 	return (error);
1022 }
1023 
1024 
1025 static int
1026 freebsd32_convert_msg_in(struct mbuf **controlp)
1027 {
1028 	struct mbuf *control = *controlp;
1029 	struct cmsghdr *cm = mtod(control, struct cmsghdr *);
1030 	void *data;
1031 	socklen_t clen = control->m_len, datalen;
1032 	int error;
1033 
1034 	error = 0;
1035 	*controlp = NULL;
1036 
1037 	while (cm != NULL) {
1038 		if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) {
1039 			error = EINVAL;
1040 			break;
1041 		}
1042 
1043 		data = FREEBSD32_CMSG_DATA(cm);
1044 		datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1045 
1046 		*controlp = sbcreatecontrol(data, datalen, cm->cmsg_type,
1047 		    cm->cmsg_level);
1048 		controlp = &(*controlp)->m_next;
1049 
1050 		if (FREEBSD32_CMSG_SPACE(datalen) < clen) {
1051 			clen -= FREEBSD32_CMSG_SPACE(datalen);
1052 			cm = (struct cmsghdr *)
1053 				((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen));
1054 		} else {
1055 			clen = 0;
1056 			cm = NULL;
1057 		}
1058 	}
1059 
1060 	m_freem(control);
1061 	return (error);
1062 }
1063 
1064 
1065 int
1066 freebsd32_sendmsg(struct thread *td,
1067 		  struct freebsd32_sendmsg_args *uap)
1068 {
1069 	struct msghdr msg;
1070 	struct msghdr32 m32;
1071 	struct iovec *iov;
1072 	struct mbuf *control = NULL;
1073 	struct sockaddr *to = NULL;
1074 	int error;
1075 
1076 	error = copyin(uap->msg, &m32, sizeof(m32));
1077 	if (error)
1078 		return (error);
1079 	error = freebsd32_copyinmsghdr(uap->msg, &msg);
1080 	if (error)
1081 		return (error);
1082 	error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
1083 	    EMSGSIZE);
1084 	if (error)
1085 		return (error);
1086 	msg.msg_iov = iov;
1087 	if (msg.msg_name != NULL) {
1088 		error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1089 		if (error) {
1090 			to = NULL;
1091 			goto out;
1092 		}
1093 		msg.msg_name = to;
1094 	}
1095 
1096 	if (msg.msg_control) {
1097 		if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1098 			error = EINVAL;
1099 			goto out;
1100 		}
1101 
1102 		error = sockargs(&control, msg.msg_control,
1103 		    msg.msg_controllen, MT_CONTROL);
1104 		if (error)
1105 			goto out;
1106 
1107 		error = freebsd32_convert_msg_in(&control);
1108 		if (error)
1109 			goto out;
1110 	}
1111 
1112 	error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1113 	    UIO_USERSPACE);
1114 
1115 out:
1116 	free(iov, M_IOV);
1117 	if (to)
1118 		free(to, M_SONAME);
1119 	return (error);
1120 }
1121 
1122 int
1123 freebsd32_recvfrom(struct thread *td,
1124 		   struct freebsd32_recvfrom_args *uap)
1125 {
1126 	struct msghdr msg;
1127 	struct iovec aiov;
1128 	int error;
1129 
1130 	if (uap->fromlenaddr) {
1131 		error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
1132 		    sizeof(msg.msg_namelen));
1133 		if (error)
1134 			return (error);
1135 	} else {
1136 		msg.msg_namelen = 0;
1137 	}
1138 
1139 	msg.msg_name = PTRIN(uap->from);
1140 	msg.msg_iov = &aiov;
1141 	msg.msg_iovlen = 1;
1142 	aiov.iov_base = PTRIN(uap->buf);
1143 	aiov.iov_len = uap->len;
1144 	msg.msg_control = NULL;
1145 	msg.msg_flags = uap->flags;
1146 	error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
1147 	if (error == 0 && uap->fromlenaddr)
1148 		error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
1149 		    sizeof (msg.msg_namelen));
1150 	return (error);
1151 }
1152 
1153 int
1154 freebsd32_settimeofday(struct thread *td,
1155 		       struct freebsd32_settimeofday_args *uap)
1156 {
1157 	struct timeval32 tv32;
1158 	struct timeval tv, *tvp;
1159 	struct timezone tz, *tzp;
1160 	int error;
1161 
1162 	if (uap->tv) {
1163 		error = copyin(uap->tv, &tv32, sizeof(tv32));
1164 		if (error)
1165 			return (error);
1166 		CP(tv32, tv, tv_sec);
1167 		CP(tv32, tv, tv_usec);
1168 		tvp = &tv;
1169 	} else
1170 		tvp = NULL;
1171 	if (uap->tzp) {
1172 		error = copyin(uap->tzp, &tz, sizeof(tz));
1173 		if (error)
1174 			return (error);
1175 		tzp = &tz;
1176 	} else
1177 		tzp = NULL;
1178 	return (kern_settimeofday(td, tvp, tzp));
1179 }
1180 
1181 int
1182 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1183 {
1184 	struct timeval32 s32[2];
1185 	struct timeval s[2], *sp;
1186 	int error;
1187 
1188 	if (uap->tptr != NULL) {
1189 		error = copyin(uap->tptr, s32, sizeof(s32));
1190 		if (error)
1191 			return (error);
1192 		CP(s32[0], s[0], tv_sec);
1193 		CP(s32[0], s[0], tv_usec);
1194 		CP(s32[1], s[1], tv_sec);
1195 		CP(s32[1], s[1], tv_usec);
1196 		sp = s;
1197 	} else
1198 		sp = NULL;
1199 	return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1200 }
1201 
1202 int
1203 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1204 {
1205 	struct timeval32 s32[2];
1206 	struct timeval s[2], *sp;
1207 	int error;
1208 
1209 	if (uap->tptr != NULL) {
1210 		error = copyin(uap->tptr, s32, sizeof(s32));
1211 		if (error)
1212 			return (error);
1213 		CP(s32[0], s[0], tv_sec);
1214 		CP(s32[0], s[0], tv_usec);
1215 		CP(s32[1], s[1], tv_sec);
1216 		CP(s32[1], s[1], tv_usec);
1217 		sp = s;
1218 	} else
1219 		sp = NULL;
1220 	return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1221 }
1222 
1223 int
1224 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1225 {
1226 	struct timeval32 s32[2];
1227 	struct timeval s[2], *sp;
1228 	int error;
1229 
1230 	if (uap->tptr != NULL) {
1231 		error = copyin(uap->tptr, s32, sizeof(s32));
1232 		if (error)
1233 			return (error);
1234 		CP(s32[0], s[0], tv_sec);
1235 		CP(s32[0], s[0], tv_usec);
1236 		CP(s32[1], s[1], tv_sec);
1237 		CP(s32[1], s[1], tv_usec);
1238 		sp = s;
1239 	} else
1240 		sp = NULL;
1241 	return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1242 }
1243 
1244 
1245 int
1246 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1247 {
1248 	struct timeval32 tv32;
1249 	struct timeval delta, olddelta, *deltap;
1250 	int error;
1251 
1252 	if (uap->delta) {
1253 		error = copyin(uap->delta, &tv32, sizeof(tv32));
1254 		if (error)
1255 			return (error);
1256 		CP(tv32, delta, tv_sec);
1257 		CP(tv32, delta, tv_usec);
1258 		deltap = &delta;
1259 	} else
1260 		deltap = NULL;
1261 	error = kern_adjtime(td, deltap, &olddelta);
1262 	if (uap->olddelta && error == 0) {
1263 		CP(olddelta, tv32, tv_sec);
1264 		CP(olddelta, tv32, tv_usec);
1265 		error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1266 	}
1267 	return (error);
1268 }
1269 
1270 #ifdef COMPAT_FREEBSD4
1271 int
1272 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1273 {
1274 	struct statfs32 s32;
1275 	struct statfs s;
1276 	int error;
1277 
1278 	error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
1279 	if (error)
1280 		return (error);
1281 	copy_statfs(&s, &s32);
1282 	return (copyout(&s32, uap->buf, sizeof(s32)));
1283 }
1284 #endif
1285 
1286 #ifdef COMPAT_FREEBSD4
1287 int
1288 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1289 {
1290 	struct statfs32 s32;
1291 	struct statfs s;
1292 	int error;
1293 
1294 	error = kern_fstatfs(td, uap->fd, &s);
1295 	if (error)
1296 		return (error);
1297 	copy_statfs(&s, &s32);
1298 	return (copyout(&s32, uap->buf, sizeof(s32)));
1299 }
1300 #endif
1301 
1302 #ifdef COMPAT_FREEBSD4
1303 int
1304 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1305 {
1306 	struct statfs32 s32;
1307 	struct statfs s;
1308 	fhandle_t fh;
1309 	int error;
1310 
1311 	if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
1312 		return (error);
1313 	error = kern_fhstatfs(td, fh, &s);
1314 	if (error)
1315 		return (error);
1316 	copy_statfs(&s, &s32);
1317 	return (copyout(&s32, uap->buf, sizeof(s32)));
1318 }
1319 #endif
1320 
1321 int
1322 freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1323 {
1324 	/*
1325 	 * Vector through to semsys if it is loaded.
1326 	 */
1327 	return sysent[SYS_semsys].sy_call(td, uap);
1328 }
1329 
1330 int
1331 freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1332 {
1333 	switch (uap->which) {
1334 	case 2:
1335 		return (freebsd32_msgsnd(td,
1336 		    (struct freebsd32_msgsnd_args *)&uap->a2));
1337 		break;
1338 	case 3:
1339 		return (freebsd32_msgrcv(td,
1340 		    (struct freebsd32_msgrcv_args *)&uap->a2));
1341 		break;
1342 	default:
1343 		/*
1344 		 * Vector through to msgsys if it is loaded.
1345 		 */
1346 		return (sysent[SYS_msgsys].sy_call(td, uap));
1347 		break;
1348 	}
1349 }
1350 
1351 int
1352 freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
1353 {
1354 	const void *msgp;
1355 	long mtype;
1356 	int32_t mtype32;
1357 	int error;
1358 
1359 	if (!SYSCALL_MODULE_PRESENT(msgsnd))
1360 		return (nosys(td, (struct nosys_args *)uap));
1361 
1362 	msgp = PTRIN(uap->msgp);
1363 	if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
1364 		return (error);
1365 	mtype = mtype32;
1366 	return (kern_msgsnd(td, uap->msqid,
1367 	    (const char *)msgp + sizeof(mtype32),
1368 	    uap->msgsz, uap->msgflg, mtype));
1369 }
1370 
1371 int
1372 freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
1373 {
1374 	void *msgp;
1375 	long mtype;
1376 	int32_t mtype32;
1377 	int error;
1378 
1379 	if (!SYSCALL_MODULE_PRESENT(msgrcv))
1380 		return (nosys(td, (struct nosys_args *)uap));
1381 
1382 	msgp = PTRIN(uap->msgp);
1383 	if ((error = kern_msgrcv(td, uap->msqid,
1384 	    (char *)msgp + sizeof(mtype32), uap->msgsz,
1385 	    uap->msgtyp, uap->msgflg, &mtype)) != 0)
1386 		return (error);
1387 	mtype32 = (int32_t)mtype;
1388 	return (copyout(&mtype32, msgp, sizeof(mtype32)));
1389 }
1390 
1391 int
1392 freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1393 {
1394 
1395 	switch (uap->which) {
1396 	case 0:	{	/* shmat */
1397 		struct shmat_args ap;
1398 
1399 		ap.shmid = uap->a2;
1400 		ap.shmaddr = PTRIN(uap->a3);
1401 		ap.shmflg = uap->a4;
1402 		return (sysent[SYS_shmat].sy_call(td, &ap));
1403 	}
1404 	case 2: {	/* shmdt */
1405 		struct shmdt_args ap;
1406 
1407 		ap.shmaddr = PTRIN(uap->a2);
1408 		return (sysent[SYS_shmdt].sy_call(td, &ap));
1409 	}
1410 	case 3: {	/* shmget */
1411 		struct shmget_args ap;
1412 
1413 		ap.key = uap->a2;
1414 		ap.size = uap->a3;
1415 		ap.shmflg = uap->a4;
1416 		return (sysent[SYS_shmget].sy_call(td, &ap));
1417 	}
1418 	case 4: {	/* shmctl */
1419 		struct freebsd32_shmctl_args ap;
1420 
1421 		ap.shmid = uap->a2;
1422 		ap.cmd = uap->a3;
1423 		ap.buf = PTRIN(uap->a4);
1424 		return (freebsd32_shmctl(td, &ap));
1425 	}
1426 	case 1:		/* oshmctl */
1427 	default:
1428 		return (EINVAL);
1429 	}
1430 }
1431 
1432 struct ipc_perm32 {
1433 	uint16_t	cuid;
1434 	uint16_t	cgid;
1435 	uint16_t	uid;
1436 	uint16_t	gid;
1437 	uint16_t	mode;
1438 	uint16_t	seq;
1439 	uint32_t	key;
1440 };
1441 struct shmid_ds32 {
1442 	struct ipc_perm32 shm_perm;
1443 	int32_t		shm_segsz;
1444 	int32_t		shm_lpid;
1445 	int32_t		shm_cpid;
1446 	int16_t		shm_nattch;
1447 	int32_t		shm_atime;
1448 	int32_t		shm_dtime;
1449 	int32_t		shm_ctime;
1450 	uint32_t	shm_internal;
1451 };
1452 struct shm_info32 {
1453 	int32_t		used_ids;
1454 	uint32_t	shm_tot;
1455 	uint32_t	shm_rss;
1456 	uint32_t	shm_swp;
1457 	uint32_t	swap_attempts;
1458 	uint32_t	swap_successes;
1459 };
1460 struct shminfo32 {
1461 	uint32_t	shmmax;
1462 	uint32_t	shmmin;
1463 	uint32_t	shmmni;
1464 	uint32_t	shmseg;
1465 	uint32_t	shmall;
1466 };
1467 
1468 int
1469 freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
1470 {
1471 	int error = 0;
1472 	union {
1473 		struct shmid_ds shmid_ds;
1474 		struct shm_info shm_info;
1475 		struct shminfo shminfo;
1476 	} u;
1477 	union {
1478 		struct shmid_ds32 shmid_ds32;
1479 		struct shm_info32 shm_info32;
1480 		struct shminfo32 shminfo32;
1481 	} u32;
1482 	size_t sz;
1483 
1484 	if (uap->cmd == IPC_SET) {
1485 		if ((error = copyin(uap->buf, &u32.shmid_ds32,
1486 		    sizeof(u32.shmid_ds32))))
1487 			goto done;
1488 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cuid);
1489 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cgid);
1490 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.uid);
1491 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.gid);
1492 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.mode);
1493 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.seq);
1494 		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.key);
1495 		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1496 		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1497 		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1498 		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1499 		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1500 		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1501 		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1502 		PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal);
1503 	}
1504 
1505 	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
1506 	if (error)
1507 		goto done;
1508 
1509 	/* Cases in which we need to copyout */
1510 	switch (uap->cmd) {
1511 	case IPC_INFO:
1512 		CP(u.shminfo, u32.shminfo32, shmmax);
1513 		CP(u.shminfo, u32.shminfo32, shmmin);
1514 		CP(u.shminfo, u32.shminfo32, shmmni);
1515 		CP(u.shminfo, u32.shminfo32, shmseg);
1516 		CP(u.shminfo, u32.shminfo32, shmall);
1517 		error = copyout(&u32.shminfo32, uap->buf,
1518 		    sizeof(u32.shminfo32));
1519 		break;
1520 	case SHM_INFO:
1521 		CP(u.shm_info, u32.shm_info32, used_ids);
1522 		CP(u.shm_info, u32.shm_info32, shm_rss);
1523 		CP(u.shm_info, u32.shm_info32, shm_tot);
1524 		CP(u.shm_info, u32.shm_info32, shm_swp);
1525 		CP(u.shm_info, u32.shm_info32, swap_attempts);
1526 		CP(u.shm_info, u32.shm_info32, swap_successes);
1527 		error = copyout(&u32.shm_info32, uap->buf,
1528 		    sizeof(u32.shm_info32));
1529 		break;
1530 	case SHM_STAT:
1531 	case IPC_STAT:
1532 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cuid);
1533 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cgid);
1534 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.uid);
1535 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.gid);
1536 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.mode);
1537 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.seq);
1538 		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.key);
1539 		CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1540 		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1541 		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1542 		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1543 		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1544 		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1545 		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1546 		PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal);
1547 		error = copyout(&u32.shmid_ds32, uap->buf,
1548 		    sizeof(u32.shmid_ds32));
1549 		break;
1550 	}
1551 
1552 done:
1553 	if (error) {
1554 		/* Invalidate the return value */
1555 		td->td_retval[0] = -1;
1556 	}
1557 	return (error);
1558 }
1559 
1560 int
1561 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1562 {
1563 	struct pread_args ap;
1564 
1565 	ap.fd = uap->fd;
1566 	ap.buf = uap->buf;
1567 	ap.nbyte = uap->nbyte;
1568 	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1569 	return (pread(td, &ap));
1570 }
1571 
1572 int
1573 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1574 {
1575 	struct pwrite_args ap;
1576 
1577 	ap.fd = uap->fd;
1578 	ap.buf = uap->buf;
1579 	ap.nbyte = uap->nbyte;
1580 	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1581 	return (pwrite(td, &ap));
1582 }
1583 
1584 int
1585 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1586 {
1587 	int error;
1588 	struct lseek_args ap;
1589 	off_t pos;
1590 
1591 	ap.fd = uap->fd;
1592 	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1593 	ap.whence = uap->whence;
1594 	error = lseek(td, &ap);
1595 	/* Expand the quad return into two parts for eax and edx */
1596 	pos = *(off_t *)(td->td_retval);
1597 	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1598 	td->td_retval[1] = pos >> 32;		/* %edx */
1599 	return error;
1600 }
1601 
1602 int
1603 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1604 {
1605 	struct truncate_args ap;
1606 
1607 	ap.path = uap->path;
1608 	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1609 	return (truncate(td, &ap));
1610 }
1611 
1612 int
1613 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1614 {
1615 	struct ftruncate_args ap;
1616 
1617 	ap.fd = uap->fd;
1618 	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1619 	return (ftruncate(td, &ap));
1620 }
1621 
1622 struct sf_hdtr32 {
1623 	uint32_t headers;
1624 	int hdr_cnt;
1625 	uint32_t trailers;
1626 	int trl_cnt;
1627 };
1628 
1629 static int
1630 freebsd32_do_sendfile(struct thread *td,
1631     struct freebsd32_sendfile_args *uap, int compat)
1632 {
1633 	struct sendfile_args ap;
1634 	struct sf_hdtr32 hdtr32;
1635 	struct sf_hdtr hdtr;
1636 	struct uio *hdr_uio, *trl_uio;
1637 	struct iovec32 *iov32;
1638 	int error;
1639 
1640 	hdr_uio = trl_uio = NULL;
1641 
1642 	ap.fd = uap->fd;
1643 	ap.s = uap->s;
1644 	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1645 	ap.nbytes = uap->nbytes;
1646 	ap.hdtr = (struct sf_hdtr *)uap->hdtr;		/* XXX not used */
1647 	ap.sbytes = uap->sbytes;
1648 	ap.flags = uap->flags;
1649 
1650 	if (uap->hdtr != NULL) {
1651 		error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
1652 		if (error)
1653 			goto out;
1654 		PTRIN_CP(hdtr32, hdtr, headers);
1655 		CP(hdtr32, hdtr, hdr_cnt);
1656 		PTRIN_CP(hdtr32, hdtr, trailers);
1657 		CP(hdtr32, hdtr, trl_cnt);
1658 
1659 		if (hdtr.headers != NULL) {
1660 			iov32 = PTRIN(hdtr32.headers);
1661 			error = freebsd32_copyinuio(iov32,
1662 			    hdtr32.hdr_cnt, &hdr_uio);
1663 			if (error)
1664 				goto out;
1665 		}
1666 		if (hdtr.trailers != NULL) {
1667 			iov32 = PTRIN(hdtr32.trailers);
1668 			error = freebsd32_copyinuio(iov32,
1669 			    hdtr32.trl_cnt, &trl_uio);
1670 			if (error)
1671 				goto out;
1672 		}
1673 	}
1674 
1675 	error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat);
1676 out:
1677 	if (hdr_uio)
1678 		free(hdr_uio, M_IOV);
1679 	if (trl_uio)
1680 		free(trl_uio, M_IOV);
1681 	return (error);
1682 }
1683 
1684 #ifdef COMPAT_FREEBSD4
1685 int
1686 freebsd4_freebsd32_sendfile(struct thread *td,
1687     struct freebsd4_freebsd32_sendfile_args *uap)
1688 {
1689 	return (freebsd32_do_sendfile(td,
1690 	    (struct freebsd32_sendfile_args *)uap, 1));
1691 }
1692 #endif
1693 
1694 int
1695 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1696 {
1697 
1698 	return (freebsd32_do_sendfile(td, uap, 0));
1699 }
1700 
1701 struct stat32 {
1702 	dev_t	st_dev;
1703 	ino_t	st_ino;
1704 	mode_t	st_mode;
1705 	nlink_t	st_nlink;
1706 	uid_t	st_uid;
1707 	gid_t	st_gid;
1708 	dev_t	st_rdev;
1709 	struct timespec32 st_atimespec;
1710 	struct timespec32 st_mtimespec;
1711 	struct timespec32 st_ctimespec;
1712 	off_t	st_size;
1713 	int64_t	st_blocks;
1714 	u_int32_t st_blksize;
1715 	u_int32_t st_flags;
1716 	u_int32_t st_gen;
1717 	struct timespec32 st_birthtimespec;
1718 	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1719 	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1720 };
1721 
1722 
1723 CTASSERT(sizeof(struct stat32) == 96);
1724 
1725 static void
1726 copy_stat( struct stat *in, struct stat32 *out)
1727 {
1728 	CP(*in, *out, st_dev);
1729 	CP(*in, *out, st_ino);
1730 	CP(*in, *out, st_mode);
1731 	CP(*in, *out, st_nlink);
1732 	CP(*in, *out, st_uid);
1733 	CP(*in, *out, st_gid);
1734 	CP(*in, *out, st_rdev);
1735 	TS_CP(*in, *out, st_atimespec);
1736 	TS_CP(*in, *out, st_mtimespec);
1737 	TS_CP(*in, *out, st_ctimespec);
1738 	CP(*in, *out, st_size);
1739 	CP(*in, *out, st_blocks);
1740 	CP(*in, *out, st_blksize);
1741 	CP(*in, *out, st_flags);
1742 	CP(*in, *out, st_gen);
1743 }
1744 
1745 int
1746 freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1747 {
1748 	struct stat sb;
1749 	struct stat32 sb32;
1750 	int error;
1751 
1752 	error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1753 	if (error)
1754 		return (error);
1755 	copy_stat(&sb, &sb32);
1756 	error = copyout(&sb32, uap->ub, sizeof (sb32));
1757 	return (error);
1758 }
1759 
1760 int
1761 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1762 {
1763 	struct stat ub;
1764 	struct stat32 ub32;
1765 	int error;
1766 
1767 	error = kern_fstat(td, uap->fd, &ub);
1768 	if (error)
1769 		return (error);
1770 	copy_stat(&ub, &ub32);
1771 	error = copyout(&ub32, uap->ub, sizeof(ub32));
1772 	return (error);
1773 }
1774 
1775 int
1776 freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1777 {
1778 	struct stat sb;
1779 	struct stat32 sb32;
1780 	int error;
1781 
1782 	error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1783 	if (error)
1784 		return (error);
1785 	copy_stat(&sb, &sb32);
1786 	error = copyout(&sb32, uap->ub, sizeof (sb32));
1787 	return (error);
1788 }
1789 
1790 /*
1791  * MPSAFE
1792  */
1793 int
1794 freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1795 {
1796 	int error, name[CTL_MAXNAME];
1797 	size_t j, oldlen;
1798 
1799 	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1800 		return (EINVAL);
1801  	error = copyin(uap->name, name, uap->namelen * sizeof(int));
1802  	if (error)
1803 		return (error);
1804 	mtx_lock(&Giant);
1805 	if (uap->oldlenp)
1806 		oldlen = fuword32(uap->oldlenp);
1807 	else
1808 		oldlen = 0;
1809 	error = userland_sysctl(td, name, uap->namelen,
1810 		uap->old, &oldlen, 1,
1811 		uap->new, uap->newlen, &j, SCTL_MASK32);
1812 	if (error && error != ENOMEM)
1813 		goto done2;
1814 	if (uap->oldlenp)
1815 		suword32(uap->oldlenp, j);
1816 done2:
1817 	mtx_unlock(&Giant);
1818 	return (error);
1819 }
1820 
1821 struct sigaction32 {
1822 	u_int32_t	sa_u;
1823 	int		sa_flags;
1824 	sigset_t	sa_mask;
1825 };
1826 
1827 CTASSERT(sizeof(struct sigaction32) == 24);
1828 
1829 int
1830 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1831 {
1832 	struct sigaction32 s32;
1833 	struct sigaction sa, osa, *sap;
1834 	int error;
1835 
1836 	if (uap->act) {
1837 		error = copyin(uap->act, &s32, sizeof(s32));
1838 		if (error)
1839 			return (error);
1840 		sa.sa_handler = PTRIN(s32.sa_u);
1841 		CP(s32, sa, sa_flags);
1842 		CP(s32, sa, sa_mask);
1843 		sap = &sa;
1844 	} else
1845 		sap = NULL;
1846 	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1847 	if (error == 0 && uap->oact != NULL) {
1848 		s32.sa_u = PTROUT(osa.sa_handler);
1849 		CP(osa, s32, sa_flags);
1850 		CP(osa, s32, sa_mask);
1851 		error = copyout(&s32, uap->oact, sizeof(s32));
1852 	}
1853 	return (error);
1854 }
1855 
1856 #ifdef COMPAT_FREEBSD4
1857 int
1858 freebsd4_freebsd32_sigaction(struct thread *td,
1859 			     struct freebsd4_freebsd32_sigaction_args *uap)
1860 {
1861 	struct sigaction32 s32;
1862 	struct sigaction sa, osa, *sap;
1863 	int error;
1864 
1865 	if (uap->act) {
1866 		error = copyin(uap->act, &s32, sizeof(s32));
1867 		if (error)
1868 			return (error);
1869 		sa.sa_handler = PTRIN(s32.sa_u);
1870 		CP(s32, sa, sa_flags);
1871 		CP(s32, sa, sa_mask);
1872 		sap = &sa;
1873 	} else
1874 		sap = NULL;
1875 	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1876 	if (error == 0 && uap->oact != NULL) {
1877 		s32.sa_u = PTROUT(osa.sa_handler);
1878 		CP(osa, s32, sa_flags);
1879 		CP(osa, s32, sa_mask);
1880 		error = copyout(&s32, uap->oact, sizeof(s32));
1881 	}
1882 	return (error);
1883 }
1884 #endif
1885 
1886 #ifdef COMPAT_43
1887 struct osigaction32 {
1888 	u_int32_t	sa_u;
1889 	osigset_t	sa_mask;
1890 	int		sa_flags;
1891 };
1892 
1893 #define	ONSIG	32
1894 
1895 int
1896 ofreebsd32_sigaction(struct thread *td,
1897 			     struct ofreebsd32_sigaction_args *uap)
1898 {
1899 	struct osigaction32 s32;
1900 	struct sigaction sa, osa, *sap;
1901 	int error;
1902 
1903 	if (uap->signum <= 0 || uap->signum >= ONSIG)
1904 		return (EINVAL);
1905 
1906 	if (uap->nsa) {
1907 		error = copyin(uap->nsa, &s32, sizeof(s32));
1908 		if (error)
1909 			return (error);
1910 		sa.sa_handler = PTRIN(s32.sa_u);
1911 		CP(s32, sa, sa_flags);
1912 		OSIG2SIG(s32.sa_mask, sa.sa_mask);
1913 		sap = &sa;
1914 	} else
1915 		sap = NULL;
1916 	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
1917 	if (error == 0 && uap->osa != NULL) {
1918 		s32.sa_u = PTROUT(osa.sa_handler);
1919 		CP(osa, s32, sa_flags);
1920 		SIG2OSIG(osa.sa_mask, s32.sa_mask);
1921 		error = copyout(&s32, uap->osa, sizeof(s32));
1922 	}
1923 	return (error);
1924 }
1925 
1926 int
1927 ofreebsd32_sigprocmask(struct thread *td,
1928 			       struct ofreebsd32_sigprocmask_args *uap)
1929 {
1930 	sigset_t set, oset;
1931 	int error;
1932 
1933 	OSIG2SIG(uap->mask, set);
1934 	error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
1935 	SIG2OSIG(oset, td->td_retval[0]);
1936 	return (error);
1937 }
1938 
1939 int
1940 ofreebsd32_sigpending(struct thread *td,
1941 			      struct ofreebsd32_sigpending_args *uap)
1942 {
1943 	struct proc *p = td->td_proc;
1944 	sigset_t siglist;
1945 
1946 	PROC_LOCK(p);
1947 	siglist = p->p_siglist;
1948 	SIGSETOR(siglist, td->td_siglist);
1949 	PROC_UNLOCK(p);
1950 	SIG2OSIG(siglist, td->td_retval[0]);
1951 	return (0);
1952 }
1953 
1954 struct sigvec32 {
1955 	u_int32_t	sv_handler;
1956 	int		sv_mask;
1957 	int		sv_flags;
1958 };
1959 
1960 int
1961 ofreebsd32_sigvec(struct thread *td,
1962 			  struct ofreebsd32_sigvec_args *uap)
1963 {
1964 	struct sigvec32 vec;
1965 	struct sigaction sa, osa, *sap;
1966 	int error;
1967 
1968 	if (uap->signum <= 0 || uap->signum >= ONSIG)
1969 		return (EINVAL);
1970 
1971 	if (uap->nsv) {
1972 		error = copyin(uap->nsv, &vec, sizeof(vec));
1973 		if (error)
1974 			return (error);
1975 		sa.sa_handler = PTRIN(vec.sv_handler);
1976 		OSIG2SIG(vec.sv_mask, sa.sa_mask);
1977 		sa.sa_flags = vec.sv_flags;
1978 		sa.sa_flags ^= SA_RESTART;
1979 		sap = &sa;
1980 	} else
1981 		sap = NULL;
1982 	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
1983 	if (error == 0 && uap->osv != NULL) {
1984 		vec.sv_handler = PTROUT(osa.sa_handler);
1985 		SIG2OSIG(osa.sa_mask, vec.sv_mask);
1986 		vec.sv_flags = osa.sa_flags;
1987 		vec.sv_flags &= ~SA_NOCLDWAIT;
1988 		vec.sv_flags ^= SA_RESTART;
1989 		error = copyout(&vec, uap->osv, sizeof(vec));
1990 	}
1991 	return (error);
1992 }
1993 
1994 int
1995 ofreebsd32_sigblock(struct thread *td,
1996 			    struct ofreebsd32_sigblock_args *uap)
1997 {
1998 	struct proc *p = td->td_proc;
1999 	sigset_t set;
2000 
2001 	OSIG2SIG(uap->mask, set);
2002 	SIG_CANTMASK(set);
2003 	PROC_LOCK(p);
2004 	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
2005 	SIGSETOR(td->td_sigmask, set);
2006 	PROC_UNLOCK(p);
2007 	return (0);
2008 }
2009 
2010 int
2011 ofreebsd32_sigsetmask(struct thread *td,
2012 			      struct ofreebsd32_sigsetmask_args *uap)
2013 {
2014 	struct proc *p = td->td_proc;
2015 	sigset_t set;
2016 
2017 	OSIG2SIG(uap->mask, set);
2018 	SIG_CANTMASK(set);
2019 	PROC_LOCK(p);
2020 	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
2021 	SIGSETLO(td->td_sigmask, set);
2022 	signotify(td);
2023 	PROC_UNLOCK(p);
2024 	return (0);
2025 }
2026 
2027 int
2028 ofreebsd32_sigsuspend(struct thread *td,
2029 			      struct ofreebsd32_sigsuspend_args *uap)
2030 {
2031 	struct proc *p = td->td_proc;
2032 	sigset_t mask;
2033 
2034 	PROC_LOCK(p);
2035 	td->td_oldsigmask = td->td_sigmask;
2036 	td->td_pflags |= TDP_OLDMASK;
2037 	OSIG2SIG(uap->mask, mask);
2038 	SIG_CANTMASK(mask);
2039 	SIGSETLO(td->td_sigmask, mask);
2040 	signotify(td);
2041 	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
2042 		/* void */;
2043 	PROC_UNLOCK(p);
2044 	/* always return EINTR rather than ERESTART... */
2045 	return (EINTR);
2046 }
2047 
2048 struct sigstack32 {
2049 	u_int32_t	ss_sp;
2050 	int		ss_onstack;
2051 };
2052 
2053 int
2054 ofreebsd32_sigstack(struct thread *td,
2055 			    struct ofreebsd32_sigstack_args *uap)
2056 {
2057 	struct sigstack32 s32;
2058 	struct sigstack nss, oss;
2059 	int error = 0;
2060 
2061 	if (uap->nss != NULL) {
2062 		error = copyin(uap->nss, &s32, sizeof(s32));
2063 		if (error)
2064 			return (error);
2065 		nss.ss_sp = PTRIN(s32.ss_sp);
2066 		CP(s32, nss, ss_onstack);
2067 	}
2068 	oss.ss_sp = td->td_sigstk.ss_sp;
2069 	oss.ss_onstack = sigonstack(cpu_getstack(td));
2070 	if (uap->nss != NULL) {
2071 		td->td_sigstk.ss_sp = nss.ss_sp;
2072 		td->td_sigstk.ss_size = 0;
2073 		td->td_sigstk.ss_flags |= nss.ss_onstack & SS_ONSTACK;
2074 		td->td_pflags |= TDP_ALTSTACK;
2075 	}
2076 	if (uap->oss != NULL) {
2077 		s32.ss_sp = PTROUT(oss.ss_sp);
2078 		CP(oss, s32, ss_onstack);
2079 		error = copyout(&s32, uap->oss, sizeof(s32));
2080 	}
2081 	return (error);
2082 }
2083 #endif
2084 
2085 int
2086 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
2087 {
2088 	struct timespec32 rmt32, rqt32;
2089 	struct timespec rmt, rqt;
2090 	int error;
2091 
2092 	error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
2093 	if (error)
2094 		return (error);
2095 
2096 	CP(rqt32, rqt, tv_sec);
2097 	CP(rqt32, rqt, tv_nsec);
2098 
2099 	if (uap->rmtp &&
2100 	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
2101 		return (EFAULT);
2102 	error = kern_nanosleep(td, &rqt, &rmt);
2103 	if (error && uap->rmtp) {
2104 		int error2;
2105 
2106 		CP(rmt, rmt32, tv_sec);
2107 		CP(rmt, rmt32, tv_nsec);
2108 
2109 		error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
2110 		if (error2)
2111 			error = error2;
2112 	}
2113 	return (error);
2114 }
2115 
2116 int
2117 freebsd32_clock_gettime(struct thread *td,
2118 			struct freebsd32_clock_gettime_args *uap)
2119 {
2120 	struct timespec	ats;
2121 	struct timespec32 ats32;
2122 	int error;
2123 
2124 	error = kern_clock_gettime(td, uap->clock_id, &ats);
2125 	if (error == 0) {
2126 		CP(ats, ats32, tv_sec);
2127 		CP(ats, ats32, tv_nsec);
2128 		error = copyout(&ats32, uap->tp, sizeof(ats32));
2129 	}
2130 	return (error);
2131 }
2132 
2133 int
2134 freebsd32_clock_settime(struct thread *td,
2135 			struct freebsd32_clock_settime_args *uap)
2136 {
2137 	struct timespec	ats;
2138 	struct timespec32 ats32;
2139 	int error;
2140 
2141 	error = copyin(uap->tp, &ats32, sizeof(ats32));
2142 	if (error)
2143 		return (error);
2144 	CP(ats32, ats, tv_sec);
2145 	CP(ats32, ats, tv_nsec);
2146 
2147 	return (kern_clock_settime(td, uap->clock_id, &ats));
2148 }
2149 
2150 int
2151 freebsd32_clock_getres(struct thread *td,
2152 		       struct freebsd32_clock_getres_args *uap)
2153 {
2154 	struct timespec	ts;
2155 	struct timespec32 ts32;
2156 	int error;
2157 
2158 	if (uap->tp == NULL)
2159 		return (0);
2160 	error = kern_clock_getres(td, uap->clock_id, &ts);
2161 	if (error == 0) {
2162 		CP(ts, ts32, tv_sec);
2163 		CP(ts, ts32, tv_nsec);
2164 		error = copyout(&ts32, uap->tp, sizeof(ts32));
2165 	}
2166 	return (error);
2167 }
2168 
2169 int
2170 freebsd32_thr_new(struct thread *td,
2171 		  struct freebsd32_thr_new_args *uap)
2172 {
2173 	struct thr_param32 param32;
2174 	struct thr_param param;
2175 	int error;
2176 
2177 	if (uap->param_size < 0 ||
2178 	    uap->param_size > sizeof(struct thr_param32))
2179 		return (EINVAL);
2180 	bzero(&param, sizeof(struct thr_param));
2181 	bzero(&param32, sizeof(struct thr_param32));
2182 	error = copyin(uap->param, &param32, uap->param_size);
2183 	if (error != 0)
2184 		return (error);
2185 	param.start_func = PTRIN(param32.start_func);
2186 	param.arg = PTRIN(param32.arg);
2187 	param.stack_base = PTRIN(param32.stack_base);
2188 	param.stack_size = param32.stack_size;
2189 	param.tls_base = PTRIN(param32.tls_base);
2190 	param.tls_size = param32.tls_size;
2191 	param.child_tid = PTRIN(param32.child_tid);
2192 	param.parent_tid = PTRIN(param32.parent_tid);
2193 	param.flags = param32.flags;
2194 	param.rtp = PTRIN(param32.rtp);
2195 	param.spare[0] = PTRIN(param32.spare[0]);
2196 	param.spare[1] = PTRIN(param32.spare[1]);
2197 	param.spare[2] = PTRIN(param32.spare[2]);
2198 
2199 	return (kern_thr_new(td, &param));
2200 }
2201 
2202 int
2203 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
2204 {
2205 	struct timespec32 ts32;
2206 	struct timespec ts, *tsp;
2207 	int error;
2208 
2209 	error = 0;
2210 	tsp = NULL;
2211 	if (uap->timeout != NULL) {
2212 		error = copyin((const void *)uap->timeout, (void *)&ts32,
2213 		    sizeof(struct timespec32));
2214 		if (error != 0)
2215 			return (error);
2216 		ts.tv_sec = ts32.tv_sec;
2217 		ts.tv_nsec = ts32.tv_nsec;
2218 		tsp = &ts;
2219 	}
2220 	return (kern_thr_suspend(td, tsp));
2221 }
2222 
2223 void
2224 siginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst)
2225 {
2226 	bzero(dst, sizeof(*dst));
2227 	dst->si_signo = src->si_signo;
2228 	dst->si_errno = src->si_errno;
2229 	dst->si_code = src->si_code;
2230 	dst->si_pid = src->si_pid;
2231 	dst->si_uid = src->si_uid;
2232 	dst->si_status = src->si_status;
2233 	dst->si_addr = dst->si_addr;
2234 	dst->si_value.sigval_int = src->si_value.sival_int;
2235 	dst->si_timerid = src->si_timerid;
2236 	dst->si_overrun = src->si_overrun;
2237 }
2238 
2239 int
2240 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
2241 {
2242 	struct timespec32 ts32;
2243 	struct timespec ts;
2244 	struct timespec *timeout;
2245 	sigset_t set;
2246 	ksiginfo_t ksi;
2247 	struct siginfo32 si32;
2248 	int error;
2249 
2250 	if (uap->timeout) {
2251 		error = copyin(uap->timeout, &ts32, sizeof(ts32));
2252 		if (error)
2253 			return (error);
2254 		ts.tv_sec = ts32.tv_sec;
2255 		ts.tv_nsec = ts32.tv_nsec;
2256 		timeout = &ts;
2257 	} else
2258 		timeout = NULL;
2259 
2260 	error = copyin(uap->set, &set, sizeof(set));
2261 	if (error)
2262 		return (error);
2263 
2264 	error = kern_sigtimedwait(td, set, &ksi, timeout);
2265 	if (error)
2266 		return (error);
2267 
2268 	if (uap->info) {
2269 		siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2270 		error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2271 	}
2272 
2273 	if (error == 0)
2274 		td->td_retval[0] = ksi.ksi_signo;
2275 	return (error);
2276 }
2277 
2278 /*
2279  * MPSAFE
2280  */
2281 int
2282 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
2283 {
2284 	ksiginfo_t ksi;
2285 	struct siginfo32 si32;
2286 	sigset_t set;
2287 	int error;
2288 
2289 	error = copyin(uap->set, &set, sizeof(set));
2290 	if (error)
2291 		return (error);
2292 
2293 	error = kern_sigtimedwait(td, set, &ksi, NULL);
2294 	if (error)
2295 		return (error);
2296 
2297 	if (uap->info) {
2298 		siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2299 		error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2300 	}
2301 	if (error == 0)
2302 		td->td_retval[0] = ksi.ksi_signo;
2303 	return (error);
2304 }
2305 
2306 #if 0
2307 
2308 int
2309 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
2310 {
2311 	int error;
2312 	struct yyy32 *p32, s32;
2313 	struct yyy *p = NULL, s;
2314 
2315 	if (uap->zzz) {
2316 		error = copyin(uap->zzz, &s32, sizeof(s32));
2317 		if (error)
2318 			return (error);
2319 		/* translate in */
2320 		p = &s;
2321 	}
2322 	error = kern_xxx(td, p);
2323 	if (error)
2324 		return (error);
2325 	if (uap->zzz) {
2326 		/* translate out */
2327 		error = copyout(&s32, p32, sizeof(s32));
2328 	}
2329 	return (error);
2330 }
2331 
2332 #endif
2333