freebsd32_misc.c revision 174377
1100384Speter/*-
2100384Speter * Copyright (c) 2002 Doug Rabson
3100384Speter * All rights reserved.
4100384Speter *
5100384Speter * Redistribution and use in source and binary forms, with or without
6100384Speter * modification, are permitted provided that the following conditions
7100384Speter * are met:
8100384Speter * 1. Redistributions of source code must retain the above copyright
9100384Speter *    notice, this list of conditions and the following disclaimer.
10100384Speter * 2. Redistributions in binary form must reproduce the above copyright
11100384Speter *    notice, this list of conditions and the following disclaimer in the
12100384Speter *    documentation and/or other materials provided with the distribution.
13100384Speter *
14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17100384Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24100384Speter * SUCH DAMAGE.
25100384Speter */
26100384Speter
27118031Sobrien#include <sys/cdefs.h>
28118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 174377 2007-12-06 23:11:27Z jhb $");
29118031Sobrien
30104738Speter#include "opt_compat.h"
31104738Speter
32100384Speter#include <sys/param.h>
33100384Speter#include <sys/systm.h>
34100384Speter#include <sys/bus.h>
35162954Sphk#include <sys/clock.h>
36100384Speter#include <sys/exec.h>
37100384Speter#include <sys/fcntl.h>
38100384Speter#include <sys/filedesc.h>
39123746Speter#include <sys/namei.h>
40100384Speter#include <sys/imgact.h>
41100384Speter#include <sys/kernel.h>
42161343Sjkim#include <sys/limits.h>
43100384Speter#include <sys/lock.h>
44100384Speter#include <sys/malloc.h>
45100384Speter#include <sys/file.h>		/* Must come after sys/malloc.h */
46151909Sps#include <sys/mbuf.h>
47100384Speter#include <sys/mman.h>
48100384Speter#include <sys/module.h>
49100384Speter#include <sys/mount.h>
50100384Speter#include <sys/mutex.h>
51100384Speter#include <sys/proc.h>
52100384Speter#include <sys/reboot.h>
53100384Speter#include <sys/resource.h>
54100384Speter#include <sys/resourcevar.h>
55100384Speter#include <sys/selinfo.h>
56146950Sps#include <sys/eventvar.h>	/* Must come after sys/selinfo.h */
57100384Speter#include <sys/pipe.h>		/* Must come after sys/selinfo.h */
58100384Speter#include <sys/signal.h>
59100384Speter#include <sys/signalvar.h>
60100384Speter#include <sys/socket.h>
61100384Speter#include <sys/socketvar.h>
62100384Speter#include <sys/stat.h>
63150883Sjhb#include <sys/syscall.h>
64113859Sjhb#include <sys/syscallsubr.h>
65100384Speter#include <sys/sysctl.h>
66100384Speter#include <sys/sysent.h>
67100384Speter#include <sys/sysproto.h>
68162551Sdavidxu#include <sys/thr.h>
69100384Speter#include <sys/unistd.h>
70162551Sdavidxu#include <sys/ucontext.h>
71100384Speter#include <sys/vnode.h>
72127140Sjhb#include <sys/wait.h>
73157285Sps#include <sys/ipc.h>
74157285Sps#include <sys/shm.h>
75100384Speter
76100384Speter#include <vm/vm.h>
77100384Speter#include <vm/vm_kern.h>
78100384Speter#include <vm/vm_param.h>
79100384Speter#include <vm/pmap.h>
80100384Speter#include <vm/vm_map.h>
81100384Speter#include <vm/vm_object.h>
82100384Speter#include <vm/vm_extern.h>
83100384Speter
84151582Sps#include <machine/cpu.h>
85151582Sps
86119333Speter#include <compat/freebsd32/freebsd32_util.h>
87119333Speter#include <compat/freebsd32/freebsd32.h>
88163018Sdavidxu#include <compat/freebsd32/freebsd32_signal.h>
89119333Speter#include <compat/freebsd32/freebsd32_proto.h>
90100384Speter
91121719SpeterCTASSERT(sizeof(struct timeval32) == 8);
92121719SpeterCTASSERT(sizeof(struct timespec32) == 8);
93174377SjhbCTASSERT(sizeof(struct itimerval32) == 16);
94121719SpeterCTASSERT(sizeof(struct statfs32) == 256);
95121719SpeterCTASSERT(sizeof(struct rusage32) == 72);
96174377SjhbCTASSERT(sizeof(struct sigaltstack32) == 12);
97174377SjhbCTASSERT(sizeof(struct kevent32) == 20);
98174377SjhbCTASSERT(sizeof(struct iovec32) == 8);
99174377SjhbCTASSERT(sizeof(struct msghdr32) == 28);
100174377SjhbCTASSERT(sizeof(struct stat32) == 96);
101174377SjhbCTASSERT(sizeof(struct sigaction32) == 24);
102121719Speter
103174377Sjhbstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
104174377Sjhbstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
105174377Sjhb
106100384Speterint
107119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
108100384Speter{
109127140Sjhb	int error, status;
110127140Sjhb	struct rusage32 ru32;
111136152Sjhb	struct rusage ru, *rup;
112100384Speter
113136152Sjhb	if (uap->rusage != NULL)
114136152Sjhb		rup = &ru;
115136152Sjhb	else
116136152Sjhb		rup = NULL;
117136152Sjhb	error = kern_wait(td, uap->pid, &status, uap->options, rup);
118100384Speter	if (error)
119100384Speter		return (error);
120127140Sjhb	if (uap->status != NULL)
121127140Sjhb		error = copyout(&status, uap->status, sizeof(status));
122127140Sjhb	if (uap->rusage != NULL && error == 0) {
123100384Speter		TV_CP(ru, ru32, ru_utime);
124100384Speter		TV_CP(ru, ru32, ru_stime);
125100384Speter		CP(ru, ru32, ru_maxrss);
126100384Speter		CP(ru, ru32, ru_ixrss);
127100384Speter		CP(ru, ru32, ru_idrss);
128100384Speter		CP(ru, ru32, ru_isrss);
129100384Speter		CP(ru, ru32, ru_minflt);
130100384Speter		CP(ru, ru32, ru_majflt);
131100384Speter		CP(ru, ru32, ru_nswap);
132100384Speter		CP(ru, ru32, ru_inblock);
133100384Speter		CP(ru, ru32, ru_oublock);
134100384Speter		CP(ru, ru32, ru_msgsnd);
135100384Speter		CP(ru, ru32, ru_msgrcv);
136100384Speter		CP(ru, ru32, ru_nsignals);
137100384Speter		CP(ru, ru32, ru_nvcsw);
138100384Speter		CP(ru, ru32, ru_nivcsw);
139127140Sjhb		error = copyout(&ru32, uap->rusage, sizeof(ru32));
140100384Speter	}
141100384Speter	return (error);
142100384Speter}
143100384Speter
144128597Smarcel#ifdef COMPAT_FREEBSD4
145174377Sjhbstatic int
146100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
147100384Speter{
148174377Sjhb	int error;
149172003Sjhb
150174377Sjhb	error = statfs_scale_blocks(in, INT32_MAX);
151174377Sjhb	if (error)
152174377Sjhb		return (error);
153156266Sps	bzero(out, sizeof(*out));
154100384Speter	CP(*in, *out, f_bsize);
155172003Sjhb	out->f_iosize = MIN(in->f_iosize, INT32_MAX);
156100384Speter	CP(*in, *out, f_blocks);
157100384Speter	CP(*in, *out, f_bfree);
158100384Speter	CP(*in, *out, f_bavail);
159172003Sjhb	out->f_files = MIN(in->f_files, INT32_MAX);
160174377Sjhb	if (in->f_ffree < 0)
161174377Sjhb		out->f_ffree = MAX(in->f_ffree, INT32_MIN);
162174377Sjhb	else
163174377Sjhb		out->f_ffree = MIN(in->f_ffree, INT32_MAX);
164100384Speter	CP(*in, *out, f_fsid);
165100384Speter	CP(*in, *out, f_owner);
166100384Speter	CP(*in, *out, f_type);
167100384Speter	CP(*in, *out, f_flags);
168174377Sjhb	CP(*in, *out, f_syncwrites);
169174377Sjhb	CP(*in, *out, f_asyncwrites);
170156266Sps	strlcpy(out->f_fstypename,
171156266Sps	      in->f_fstypename, MFSNAMELEN);
172156266Sps	strlcpy(out->f_mntonname,
173156266Sps	      in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
174174377Sjhb	CP(*in, *out, f_syncreads);
175174377Sjhb	CP(*in, *out, f_asyncreads);
176156266Sps	strlcpy(out->f_mntfromname,
177156266Sps	      in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
178174377Sjhb	return (0);
179100384Speter}
180128597Smarcel#endif
181100384Speter
182128597Smarcel#ifdef COMPAT_FREEBSD4
183100384Speterint
184128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
185100384Speter{
186147178Spjd	struct statfs *buf, *sp;
187147178Spjd	struct statfs32 stat32;
188147178Spjd	size_t count, size;
189100384Speter	int error;
190100384Speter
191147178Spjd	count = uap->bufsize / sizeof(struct statfs32);
192147178Spjd	size = count * sizeof(struct statfs);
193147302Spjd	error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
194147302Spjd	if (size > 0) {
195100384Speter		count = td->td_retval[0];
196147178Spjd		sp = buf;
197147178Spjd		while (count > 0 && error == 0) {
198174377Sjhb			error = copy_statfs(sp, &stat32);
199174377Sjhb			if (error)
200174377Sjhb				break;
201147178Spjd			error = copyout(&stat32, uap->buf, sizeof(stat32));
202147178Spjd			sp++;
203147178Spjd			uap->buf++;
204147178Spjd			count--;
205100384Speter		}
206147178Spjd		free(buf, M_TEMP);
207100384Speter	}
208100384Speter	return (error);
209100384Speter}
210128597Smarcel#endif
211100384Speter
212100384Speterint
213119333Speterfreebsd32_sigaltstack(struct thread *td,
214119333Speter		      struct freebsd32_sigaltstack_args *uap)
215100384Speter{
216113859Sjhb	struct sigaltstack32 s32;
217113859Sjhb	struct sigaltstack ss, oss, *ssp;
218100384Speter	int error;
219100384Speter
220113859Sjhb	if (uap->ss != NULL) {
221113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
222100384Speter		if (error)
223100384Speter			return (error);
224113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
225113859Sjhb		CP(s32, ss, ss_size);
226113859Sjhb		CP(s32, ss, ss_flags);
227113859Sjhb		ssp = &ss;
228113859Sjhb	} else
229113859Sjhb		ssp = NULL;
230113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
231113859Sjhb	if (error == 0 && uap->oss != NULL) {
232113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
233113859Sjhb		CP(oss, s32, ss_size);
234113859Sjhb		CP(oss, s32, ss_flags);
235113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
236100384Speter	}
237100384Speter	return (error);
238100384Speter}
239100384Speter
240142059Sjhb/*
241142059Sjhb * Custom version of exec_copyin_args() so that we can translate
242142059Sjhb * the pointers.
243142059Sjhb */
244142059Sjhbstatic int
245142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname,
246142059Sjhb    enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
247100384Speter{
248142059Sjhb	char *argp, *envp;
249142059Sjhb	u_int32_t *p32, arg;
250142059Sjhb	size_t length;
251100384Speter	int error;
252100384Speter
253142059Sjhb	bzero(args, sizeof(*args));
254142059Sjhb	if (argv == NULL)
255142059Sjhb		return (EFAULT);
256100384Speter
257142059Sjhb	/*
258142059Sjhb	 * Allocate temporary demand zeroed space for argument and
259142059Sjhb	 *	environment strings
260142059Sjhb	 */
261147588Sjhb	args->buf = (char *) kmem_alloc_wait(exec_map,
262147588Sjhb	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
263142059Sjhb	if (args->buf == NULL)
264142059Sjhb		return (ENOMEM);
265142059Sjhb	args->begin_argv = args->buf;
266142059Sjhb	args->endp = args->begin_argv;
267142059Sjhb	args->stringspace = ARG_MAX;
268142059Sjhb
269142059Sjhb	args->fname = args->buf + ARG_MAX;
270142059Sjhb
271142059Sjhb	/*
272142059Sjhb	 * Copy the file name.
273142059Sjhb	 */
274142059Sjhb	error = (segflg == UIO_SYSSPACE) ?
275142059Sjhb	    copystr(fname, args->fname, PATH_MAX, &length) :
276142059Sjhb	    copyinstr(fname, args->fname, PATH_MAX, &length);
277142059Sjhb	if (error != 0)
278156440Sups		goto err_exit;
279142059Sjhb
280142059Sjhb	/*
281142059Sjhb	 * extract arguments first
282142059Sjhb	 */
283142059Sjhb	p32 = argv;
284142059Sjhb	for (;;) {
285142059Sjhb		error = copyin(p32++, &arg, sizeof(arg));
286142059Sjhb		if (error)
287156440Sups			goto err_exit;
288142059Sjhb		if (arg == 0)
289142059Sjhb			break;
290142059Sjhb		argp = PTRIN(arg);
291142059Sjhb		error = copyinstr(argp, args->endp, args->stringspace, &length);
292142059Sjhb		if (error) {
293142059Sjhb			if (error == ENAMETOOLONG)
294156440Sups				error = E2BIG;
295156440Sups			goto err_exit;
296142059Sjhb		}
297142059Sjhb		args->stringspace -= length;
298142059Sjhb		args->endp += length;
299142059Sjhb		args->argc++;
300100384Speter	}
301142059Sjhb
302142059Sjhb	args->begin_envv = args->endp;
303142059Sjhb
304142059Sjhb	/*
305142059Sjhb	 * extract environment strings
306142059Sjhb	 */
307142059Sjhb	if (envv) {
308142059Sjhb		p32 = envv;
309142059Sjhb		for (;;) {
310100384Speter			error = copyin(p32++, &arg, sizeof(arg));
311100384Speter			if (error)
312156440Sups				goto err_exit;
313142059Sjhb			if (arg == 0)
314142059Sjhb				break;
315142059Sjhb			envp = PTRIN(arg);
316142059Sjhb			error = copyinstr(envp, args->endp, args->stringspace,
317142059Sjhb			    &length);
318142059Sjhb			if (error) {
319142059Sjhb				if (error == ENAMETOOLONG)
320156440Sups					error = E2BIG;
321156440Sups				goto err_exit;
322142059Sjhb			}
323142059Sjhb			args->stringspace -= length;
324142059Sjhb			args->endp += length;
325142059Sjhb			args->envc++;
326142059Sjhb		}
327100384Speter	}
328100384Speter
329142059Sjhb	return (0);
330156440Sups
331156440Supserr_exit:
332156440Sups	kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
333156440Sups	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
334156440Sups	args->buf = NULL;
335156440Sups	return (error);
336100384Speter}
337100384Speter
338142059Sjhbint
339142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
340142059Sjhb{
341142059Sjhb	struct image_args eargs;
342142059Sjhb	int error;
343142059Sjhb
344142059Sjhb	error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
345142059Sjhb	    uap->argv, uap->envv);
346142059Sjhb	if (error == 0)
347142059Sjhb		error = kern_execve(td, &eargs, NULL);
348142059Sjhb	return (error);
349142059Sjhb}
350142059Sjhb
351114987Speter#ifdef __ia64__
352100384Speterstatic int
353119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
354119333Speter		       int prot, int fd, off_t pos)
355100384Speter{
356100384Speter	vm_map_t map;
357100384Speter	vm_map_entry_t entry;
358100384Speter	int rv;
359100384Speter
360100384Speter	map = &td->td_proc->p_vmspace->vm_map;
361100384Speter	if (fd != -1)
362100384Speter		prot |= VM_PROT_WRITE;
363100384Speter
364100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
365100384Speter		if ((entry->protection & prot) != prot) {
366100384Speter			rv = vm_map_protect(map,
367100384Speter					    trunc_page(start),
368100384Speter					    round_page(end),
369100384Speter					    entry->protection | prot,
370100384Speter					    FALSE);
371100384Speter			if (rv != KERN_SUCCESS)
372100384Speter				return (EINVAL);
373100384Speter		}
374100384Speter	} else {
375100384Speter		vm_offset_t addr = trunc_page(start);
376100384Speter		rv = vm_map_find(map, 0, 0,
377100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
378100384Speter				 VM_PROT_ALL, 0);
379100384Speter		if (rv != KERN_SUCCESS)
380100384Speter			return (EINVAL);
381100384Speter	}
382100384Speter
383100384Speter	if (fd != -1) {
384100384Speter		struct pread_args r;
385107849Salfred		r.fd = fd;
386107849Salfred		r.buf = (void *) start;
387107849Salfred		r.nbyte = end - start;
388107849Salfred		r.offset = pos;
389100384Speter		return (pread(td, &r));
390100384Speter	} else {
391100384Speter		while (start < end) {
392100384Speter			subyte((void *) start, 0);
393100384Speter			start++;
394100384Speter		}
395100384Speter		return (0);
396100384Speter	}
397100384Speter}
398114987Speter#endif
399100384Speter
400100384Speterint
401119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
402100384Speter{
403100384Speter	struct mmap_args ap;
404107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
405107849Salfred	vm_size_t len	 = uap->len;
406107849Salfred	int prot	 = uap->prot;
407107849Salfred	int flags	 = uap->flags;
408107849Salfred	int fd		 = uap->fd;
409107849Salfred	off_t pos	 = (uap->poslo
410107849Salfred			    | ((off_t)uap->poshi << 32));
411114987Speter#ifdef __ia64__
412100384Speter	vm_size_t pageoff;
413100384Speter	int error;
414100384Speter
415100384Speter	/*
416100384Speter	 * Attempt to handle page size hassles.
417100384Speter	 */
418100384Speter	pageoff = (pos & PAGE_MASK);
419100384Speter	if (flags & MAP_FIXED) {
420100384Speter		vm_offset_t start, end;
421100384Speter		start = addr;
422100384Speter		end = addr + len;
423100384Speter
424100384Speter		if (start != trunc_page(start)) {
425119333Speter			error = freebsd32_mmap_partial(td, start,
426119333Speter						       round_page(start), prot,
427119333Speter						       fd, pos);
428100384Speter			if (fd != -1)
429100384Speter				pos += round_page(start) - start;
430100384Speter			start = round_page(start);
431100384Speter		}
432100384Speter		if (end != round_page(end)) {
433100384Speter			vm_offset_t t = trunc_page(end);
434119333Speter			error = freebsd32_mmap_partial(td, t, end,
435100384Speter						  prot, fd,
436100384Speter						  pos + t - start);
437100384Speter			end = trunc_page(end);
438100384Speter		}
439100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
440100384Speter			/*
441100384Speter			 * We can't map this region at all. The specified
442100384Speter			 * address doesn't have the same alignment as the file
443100384Speter			 * position. Fake the mapping by simply reading the
444100384Speter			 * entire region into memory. First we need to make
445100384Speter			 * sure the region exists.
446100384Speter			 */
447100384Speter			vm_map_t map;
448100384Speter			struct pread_args r;
449100384Speter			int rv;
450100384Speter
451100384Speter			prot |= VM_PROT_WRITE;
452100384Speter			map = &td->td_proc->p_vmspace->vm_map;
453100384Speter			rv = vm_map_remove(map, start, end);
454169181Salc			if (rv != KERN_SUCCESS)
455100384Speter				return (EINVAL);
456100384Speter			rv = vm_map_find(map, 0, 0,
457100384Speter					 &start, end - start, FALSE,
458100384Speter					 prot, VM_PROT_ALL, 0);
459100384Speter			if (rv != KERN_SUCCESS)
460100384Speter				return (EINVAL);
461107849Salfred			r.fd = fd;
462107849Salfred			r.buf = (void *) start;
463107849Salfred			r.nbyte = end - start;
464107849Salfred			r.offset = pos;
465100384Speter			error = pread(td, &r);
466100384Speter			if (error)
467100384Speter				return (error);
468100384Speter
469100384Speter			td->td_retval[0] = addr;
470100384Speter			return (0);
471100384Speter		}
472100384Speter		if (end == start) {
473100384Speter			/*
474100384Speter			 * After dealing with the ragged ends, there
475100384Speter			 * might be none left.
476100384Speter			 */
477100384Speter			td->td_retval[0] = addr;
478100384Speter			return (0);
479100384Speter		}
480100384Speter		addr = start;
481100384Speter		len = end - start;
482100384Speter	}
483114987Speter#endif
484100384Speter
485107849Salfred	ap.addr = (void *) addr;
486107849Salfred	ap.len = len;
487107849Salfred	ap.prot = prot;
488107849Salfred	ap.flags = flags;
489107849Salfred	ap.fd = fd;
490107849Salfred	ap.pos = pos;
491100384Speter
492100384Speter	return (mmap(td, &ap));
493100384Speter}
494100384Speter
495171215Speter#ifdef COMPAT_FREEBSD6
496171215Speterint
497171215Speterfreebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap)
498171215Speter{
499171215Speter	struct freebsd32_mmap_args ap;
500171215Speter
501171215Speter	ap.addr = uap->addr;
502171215Speter	ap.len = uap->len;
503171215Speter	ap.prot = uap->prot;
504171215Speter	ap.flags = uap->flags;
505171215Speter	ap.fd = uap->fd;
506171215Speter	ap.poslo = uap->poslo;
507171215Speter	ap.poshi = uap->poshi;
508171215Speter
509171215Speter	return (freebsd32_mmap(td, &ap));
510171215Speter}
511171215Speter#endif
512171215Speter
513100384Speterint
514119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
515100384Speter{
516142059Sjhb	struct itimerval itv, oitv, *itvp;
517142059Sjhb	struct itimerval32 i32;
518100384Speter	int error;
519100384Speter
520142059Sjhb	if (uap->itv != NULL) {
521142059Sjhb		error = copyin(uap->itv, &i32, sizeof(i32));
522100384Speter		if (error)
523100384Speter			return (error);
524142059Sjhb		TV_CP(i32, itv, it_interval);
525142059Sjhb		TV_CP(i32, itv, it_value);
526142059Sjhb		itvp = &itv;
527142059Sjhb	} else
528142059Sjhb		itvp = NULL;
529142059Sjhb	error = kern_setitimer(td, uap->which, itvp, &oitv);
530142059Sjhb	if (error || uap->oitv == NULL)
531100384Speter		return (error);
532142059Sjhb	TV_CP(oitv, i32, it_interval);
533142059Sjhb	TV_CP(oitv, i32, it_value);
534142059Sjhb	return (copyout(&i32, uap->oitv, sizeof(i32)));
535100384Speter}
536100384Speter
537100384Speterint
538125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
539125171Speter{
540142059Sjhb	struct itimerval itv;
541142059Sjhb	struct itimerval32 i32;
542125171Speter	int error;
543125171Speter
544142059Sjhb	error = kern_getitimer(td, uap->which, &itv);
545142059Sjhb	if (error || uap->itv == NULL)
546125171Speter		return (error);
547142059Sjhb	TV_CP(itv, i32, it_interval);
548142059Sjhb	TV_CP(itv, i32, it_value);
549142059Sjhb	return (copyout(&i32, uap->itv, sizeof(i32)));
550125171Speter}
551125171Speter
552125171Speterint
553119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
554100384Speter{
555142059Sjhb	struct timeval32 tv32;
556142059Sjhb	struct timeval tv, *tvp;
557100384Speter	int error;
558100384Speter
559142059Sjhb	if (uap->tv != NULL) {
560142059Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
561100384Speter		if (error)
562100384Speter			return (error);
563142059Sjhb		CP(tv32, tv, tv_sec);
564142059Sjhb		CP(tv32, tv, tv_usec);
565142059Sjhb		tvp = &tv;
566142059Sjhb	} else
567142059Sjhb		tvp = NULL;
568100384Speter	/*
569100384Speter	 * XXX big-endian needs to convert the fd_sets too.
570142059Sjhb	 * XXX Do pointers need PTRIN()?
571100384Speter	 */
572142059Sjhb	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
573100384Speter}
574100384Speter
575146950Sps/*
576146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist.
577146950Sps */
578146950Spsstatic int
579146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
580146950Sps{
581146950Sps	struct freebsd32_kevent_args *uap;
582146950Sps	struct kevent32	ks32[KQ_NEVENTS];
583146950Sps	int i, error = 0;
584146950Sps
585146950Sps	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
586146950Sps	uap = (struct freebsd32_kevent_args *)arg;
587146950Sps
588146950Sps	for (i = 0; i < count; i++) {
589146950Sps		CP(kevp[i], ks32[i], ident);
590146950Sps		CP(kevp[i], ks32[i], filter);
591146950Sps		CP(kevp[i], ks32[i], flags);
592146950Sps		CP(kevp[i], ks32[i], fflags);
593146950Sps		CP(kevp[i], ks32[i], data);
594146950Sps		PTROUT_CP(kevp[i], ks32[i], udata);
595146950Sps	}
596146950Sps	error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
597146950Sps	if (error == 0)
598146950Sps		uap->eventlist += count;
599146950Sps	return (error);
600146950Sps}
601146950Sps
602146950Sps/*
603146950Sps * Copy 'count' items from the list pointed to by uap->changelist.
604146950Sps */
605146950Spsstatic int
606146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
607146950Sps{
608146950Sps	struct freebsd32_kevent_args *uap;
609146950Sps	struct kevent32	ks32[KQ_NEVENTS];
610146950Sps	int i, error = 0;
611146950Sps
612146950Sps	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
613146950Sps	uap = (struct freebsd32_kevent_args *)arg;
614146950Sps
615146950Sps	error = copyin(uap->changelist, ks32, count * sizeof *ks32);
616146950Sps	if (error)
617146950Sps		goto done;
618146950Sps	uap->changelist += count;
619146950Sps
620146950Sps	for (i = 0; i < count; i++) {
621146950Sps		CP(ks32[i], kevp[i], ident);
622146950Sps		CP(ks32[i], kevp[i], filter);
623146950Sps		CP(ks32[i], kevp[i], flags);
624146950Sps		CP(ks32[i], kevp[i], fflags);
625146950Sps		CP(ks32[i], kevp[i], data);
626146950Sps		PTRIN_CP(ks32[i], kevp[i], udata);
627146950Sps	}
628146950Spsdone:
629146950Sps	return (error);
630146950Sps}
631146950Sps
632100384Speterint
633119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
634114987Speter{
635114987Speter	struct timespec32 ts32;
636142934Sps	struct timespec ts, *tsp;
637146950Sps	struct kevent_copyops k_ops = { uap,
638146950Sps					freebsd32_kevent_copyout,
639146950Sps					freebsd32_kevent_copyin};
640146950Sps	int error;
641114987Speter
642114987Speter
643114987Speter	if (uap->timeout) {
644114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
645114987Speter		if (error)
646114987Speter			return (error);
647114987Speter		CP(ts32, ts, tv_sec);
648114987Speter		CP(ts32, ts, tv_nsec);
649142934Sps		tsp = &ts;
650142934Sps	} else
651142934Sps		tsp = NULL;
652146950Sps	error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
653146950Sps	    &k_ops, tsp);
654142934Sps	return (error);
655114987Speter}
656114987Speter
657114987Speterint
658119333Speterfreebsd32_gettimeofday(struct thread *td,
659119333Speter		       struct freebsd32_gettimeofday_args *uap)
660100384Speter{
661123425Speter	struct timeval atv;
662123425Speter	struct timeval32 atv32;
663123425Speter	struct timezone rtz;
664123425Speter	int error = 0;
665100384Speter
666123425Speter	if (uap->tp) {
667123425Speter		microtime(&atv);
668123425Speter		CP(atv, atv32, tv_sec);
669123425Speter		CP(atv, atv32, tv_usec);
670123425Speter		error = copyout(&atv32, uap->tp, sizeof (atv32));
671100384Speter	}
672123425Speter	if (error == 0 && uap->tzp != NULL) {
673123425Speter		rtz.tz_minuteswest = tz_minuteswest;
674123425Speter		rtz.tz_dsttime = tz_dsttime;
675123425Speter		error = copyout(&rtz, uap->tzp, sizeof (rtz));
676100384Speter	}
677100384Speter	return (error);
678100384Speter}
679100384Speter
680100384Speterint
681119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
682100384Speter{
683136152Sjhb	struct rusage32 s32;
684136152Sjhb	struct rusage s;
685100384Speter	int error;
686100384Speter
687136152Sjhb	error = kern_getrusage(td, uap->who, &s);
688100384Speter	if (error)
689100384Speter		return (error);
690136152Sjhb	if (uap->rusage != NULL) {
691100384Speter		TV_CP(s, s32, ru_utime);
692100384Speter		TV_CP(s, s32, ru_stime);
693100384Speter		CP(s, s32, ru_maxrss);
694100384Speter		CP(s, s32, ru_ixrss);
695100384Speter		CP(s, s32, ru_idrss);
696100384Speter		CP(s, s32, ru_isrss);
697100384Speter		CP(s, s32, ru_minflt);
698100384Speter		CP(s, s32, ru_majflt);
699100384Speter		CP(s, s32, ru_nswap);
700100384Speter		CP(s, s32, ru_inblock);
701100384Speter		CP(s, s32, ru_oublock);
702100384Speter		CP(s, s32, ru_msgsnd);
703100384Speter		CP(s, s32, ru_msgrcv);
704100384Speter		CP(s, s32, ru_nsignals);
705100384Speter		CP(s, s32, ru_nvcsw);
706100384Speter		CP(s, s32, ru_nivcsw);
707136152Sjhb		error = copyout(&s32, uap->rusage, sizeof(s32));
708100384Speter	}
709100384Speter	return (error);
710100384Speter}
711100384Speter
712144450Sjhbstatic int
713144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
714100384Speter{
715144450Sjhb	struct iovec32 iov32;
716144450Sjhb	struct iovec *iov;
717144450Sjhb	struct uio *uio;
718144450Sjhb	u_int iovlen;
719144450Sjhb	int error, i;
720100384Speter
721144450Sjhb	*uiop = NULL;
722144450Sjhb	if (iovcnt > UIO_MAXIOV)
723100384Speter		return (EINVAL);
724144450Sjhb	iovlen = iovcnt * sizeof(struct iovec);
725144450Sjhb	uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
726144450Sjhb	iov = (struct iovec *)(uio + 1);
727144450Sjhb	for (i = 0; i < iovcnt; i++) {
728144450Sjhb		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
729144450Sjhb		if (error) {
730144450Sjhb			free(uio, M_IOV);
731144450Sjhb			return (error);
732144450Sjhb		}
733144450Sjhb		iov[i].iov_base = PTRIN(iov32.iov_base);
734144450Sjhb		iov[i].iov_len = iov32.iov_len;
735100384Speter	}
736144450Sjhb	uio->uio_iov = iov;
737144450Sjhb	uio->uio_iovcnt = iovcnt;
738144450Sjhb	uio->uio_segflg = UIO_USERSPACE;
739144450Sjhb	uio->uio_offset = -1;
740144450Sjhb	uio->uio_resid = 0;
741144450Sjhb	for (i = 0; i < iovcnt; i++) {
742144450Sjhb		if (iov->iov_len > INT_MAX - uio->uio_resid) {
743144450Sjhb			free(uio, M_IOV);
744144450Sjhb			return (EINVAL);
745144450Sjhb		}
746144450Sjhb		uio->uio_resid += iov->iov_len;
747144450Sjhb		iov++;
748144450Sjhb	}
749144450Sjhb	*uiop = uio;
750144450Sjhb	return (0);
751144450Sjhb}
752100384Speter
753144450Sjhbint
754144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
755144450Sjhb{
756144450Sjhb	struct uio *auio;
757144450Sjhb	int error;
758100384Speter
759144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
760144450Sjhb	if (error)
761144450Sjhb		return (error);
762144450Sjhb	error = kern_readv(td, uap->fd, auio);
763144450Sjhb	free(auio, M_IOV);
764100384Speter	return (error);
765100384Speter}
766100384Speter
767100384Speterint
768119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
769100384Speter{
770144450Sjhb	struct uio *auio;
771144450Sjhb	int error;
772100384Speter
773144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
774144450Sjhb	if (error)
775144450Sjhb		return (error);
776144450Sjhb	error = kern_writev(td, uap->fd, auio);
777144450Sjhb	free(auio, M_IOV);
778100384Speter	return (error);
779100384Speter}
780100384Speter
781100384Speterint
782147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
783147813Sjhb{
784147813Sjhb	struct uio *auio;
785147813Sjhb	int error;
786147813Sjhb
787147813Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
788147813Sjhb	if (error)
789147813Sjhb		return (error);
790147813Sjhb	error = kern_preadv(td, uap->fd, auio, uap->offset);
791147813Sjhb	free(auio, M_IOV);
792147813Sjhb	return (error);
793147813Sjhb}
794147813Sjhb
795147813Sjhbint
796147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
797147813Sjhb{
798147813Sjhb	struct uio *auio;
799147813Sjhb	int error;
800147813Sjhb
801147813Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
802147813Sjhb	if (error)
803147813Sjhb		return (error);
804147813Sjhb	error = kern_pwritev(td, uap->fd, auio, uap->offset);
805147813Sjhb	free(auio, M_IOV);
806147813Sjhb	return (error);
807147813Sjhb}
808147813Sjhb
809151359Spsstatic int
810151909Spsfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
811151359Sps    int error)
812151359Sps{
813151359Sps	struct iovec32 iov32;
814151909Sps	struct iovec *iov;
815151909Sps	u_int iovlen;
816151359Sps	int i;
817151359Sps
818151909Sps	*iovp = NULL;
819151359Sps	if (iovcnt > UIO_MAXIOV)
820151359Sps		return (error);
821151359Sps	iovlen = iovcnt * sizeof(struct iovec);
822151909Sps	iov = malloc(iovlen, M_IOV, M_WAITOK);
823151359Sps	for (i = 0; i < iovcnt; i++) {
824151909Sps		error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
825151359Sps		if (error) {
826151909Sps			free(iov, M_IOV);
827151359Sps			return (error);
828151359Sps		}
829151909Sps		iov[i].iov_base = PTRIN(iov32.iov_base);
830151909Sps		iov[i].iov_len = iov32.iov_len;
831151359Sps	}
832151909Sps	*iovp = iov;
833151359Sps	return (0);
834151359Sps}
835151359Sps
836151359Spsstatic int
837151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
838151359Sps{
839151359Sps	struct msghdr32 m32;
840151359Sps	int error;
841151359Sps
842151359Sps	error = copyin(msg32, &m32, sizeof(m32));
843151359Sps	if (error)
844151359Sps		return (error);
845151359Sps	msg->msg_name = PTRIN(m32.msg_name);
846151359Sps	msg->msg_namelen = m32.msg_namelen;
847151359Sps	msg->msg_iov = PTRIN(m32.msg_iov);
848151359Sps	msg->msg_iovlen = m32.msg_iovlen;
849151359Sps	msg->msg_control = PTRIN(m32.msg_control);
850151359Sps	msg->msg_controllen = m32.msg_controllen;
851151359Sps	msg->msg_flags = m32.msg_flags;
852151909Sps	return (0);
853151359Sps}
854151359Sps
855151359Spsstatic int
856151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
857151359Sps{
858151359Sps	struct msghdr32 m32;
859151359Sps	int error;
860151359Sps
861151359Sps	m32.msg_name = PTROUT(msg->msg_name);
862151359Sps	m32.msg_namelen = msg->msg_namelen;
863151359Sps	m32.msg_iov = PTROUT(msg->msg_iov);
864151359Sps	m32.msg_iovlen = msg->msg_iovlen;
865151359Sps	m32.msg_control = PTROUT(msg->msg_control);
866151359Sps	m32.msg_controllen = msg->msg_controllen;
867151359Sps	m32.msg_flags = msg->msg_flags;
868151359Sps	error = copyout(&m32, msg32, sizeof(m32));
869151359Sps	return (error);
870151359Sps}
871151359Sps
872151909Sps#define FREEBSD32_ALIGNBYTES	(sizeof(int) - 1)
873151909Sps#define FREEBSD32_ALIGN(p)	\
874151909Sps	(((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
875151909Sps#define	FREEBSD32_CMSG_SPACE(l)	\
876151909Sps	(FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
877151909Sps
878151909Sps#define	FREEBSD32_CMSG_DATA(cmsg)	((unsigned char *)(cmsg) + \
879151909Sps				 FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
880151909Spsstatic int
881151909Spsfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
882151909Sps{
883151909Sps	struct cmsghdr *cm;
884151909Sps	void *data;
885151909Sps	socklen_t clen, datalen;
886151909Sps	int error;
887151909Sps	caddr_t ctlbuf;
888151909Sps	int len, maxlen, copylen;
889151909Sps	struct mbuf *m;
890151909Sps	error = 0;
891151909Sps
892151909Sps	len    = msg->msg_controllen;
893151909Sps	maxlen = msg->msg_controllen;
894151909Sps	msg->msg_controllen = 0;
895151909Sps
896151909Sps	m = control;
897151909Sps	ctlbuf = msg->msg_control;
898151909Sps
899151909Sps	while (m && len > 0) {
900151909Sps		cm = mtod(m, struct cmsghdr *);
901151909Sps		clen = m->m_len;
902151909Sps
903151909Sps		while (cm != NULL) {
904151909Sps
905151909Sps			if (sizeof(struct cmsghdr) > clen ||
906151909Sps			    cm->cmsg_len > clen) {
907151909Sps				error = EINVAL;
908151909Sps				break;
909151909Sps			}
910151909Sps
911151909Sps			data   = CMSG_DATA(cm);
912151909Sps			datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
913151909Sps
914151909Sps			/* Adjust message length */
915151909Sps			cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
916151909Sps			    datalen;
917151909Sps
918151909Sps
919151909Sps			/* Copy cmsghdr */
920151909Sps			copylen = sizeof(struct cmsghdr);
921151909Sps			if (len < copylen) {
922151909Sps				msg->msg_flags |= MSG_CTRUNC;
923151909Sps				copylen = len;
924151909Sps			}
925151909Sps
926151909Sps			error = copyout(cm,ctlbuf,copylen);
927151909Sps			if (error)
928151909Sps				goto exit;
929151909Sps
930151909Sps			ctlbuf += FREEBSD32_ALIGN(copylen);
931151909Sps			len    -= FREEBSD32_ALIGN(copylen);
932151909Sps
933151909Sps			if (len <= 0)
934151909Sps				break;
935151909Sps
936151909Sps			/* Copy data */
937151909Sps			copylen = datalen;
938151909Sps			if (len < copylen) {
939151909Sps				msg->msg_flags |= MSG_CTRUNC;
940151909Sps				copylen = len;
941151909Sps			}
942151909Sps
943151909Sps			error = copyout(data,ctlbuf,copylen);
944151909Sps			if (error)
945151909Sps				goto exit;
946151909Sps
947151909Sps			ctlbuf += FREEBSD32_ALIGN(copylen);
948151909Sps			len    -= FREEBSD32_ALIGN(copylen);
949151909Sps
950151909Sps			if (CMSG_SPACE(datalen) < clen) {
951151909Sps				clen -= CMSG_SPACE(datalen);
952151909Sps				cm = (struct cmsghdr *)
953151909Sps					((caddr_t)cm + CMSG_SPACE(datalen));
954151909Sps			} else {
955151909Sps				clen = 0;
956151909Sps				cm = NULL;
957151909Sps			}
958151909Sps		}
959151909Sps		m = m->m_next;
960151909Sps	}
961151909Sps
962151909Sps	msg->msg_controllen = (len <= 0) ? maxlen :  ctlbuf - (caddr_t)msg->msg_control;
963151909Sps
964151909Spsexit:
965151909Sps	return (error);
966151909Sps
967151909Sps}
968151909Sps
969147813Sjhbint
970151359Spsfreebsd32_recvmsg(td, uap)
971151359Sps	struct thread *td;
972151359Sps	struct freebsd32_recvmsg_args /* {
973151359Sps		int	s;
974151359Sps		struct	msghdr32 *msg;
975151359Sps		int	flags;
976151359Sps	} */ *uap;
977151359Sps{
978151359Sps	struct msghdr msg;
979151359Sps	struct msghdr32 m32;
980151359Sps	struct iovec *uiov, *iov;
981151909Sps	struct mbuf *control = NULL;
982151909Sps	struct mbuf **controlp;
983151909Sps
984151359Sps	int error;
985151359Sps	error = copyin(uap->msg, &m32, sizeof(m32));
986151359Sps	if (error)
987151359Sps		return (error);
988151359Sps	error = freebsd32_copyinmsghdr(uap->msg, &msg);
989151359Sps	if (error)
990151359Sps		return (error);
991160246Sjhb	error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
992160246Sjhb	    EMSGSIZE);
993151359Sps	if (error)
994151359Sps		return (error);
995151359Sps	msg.msg_flags = uap->flags;
996151359Sps	uiov = msg.msg_iov;
997151359Sps	msg.msg_iov = iov;
998151909Sps
999151909Sps	controlp = (msg.msg_control != NULL) ?  &control : NULL;
1000160249Sjhb	error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1001151359Sps	if (error == 0) {
1002151359Sps		msg.msg_iov = uiov;
1003151909Sps
1004151909Sps		if (control != NULL)
1005151909Sps			error = freebsd32_copy_msg_out(&msg, control);
1006151909Sps
1007151909Sps		if (error == 0)
1008151909Sps			error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1009151359Sps	}
1010151359Sps	free(iov, M_IOV);
1011151909Sps
1012151909Sps	if (control != NULL)
1013151909Sps		m_freem(control);
1014151909Sps
1015151359Sps	return (error);
1016151359Sps}
1017151359Sps
1018151909Sps
1019151909Spsstatic int
1020151909Spsfreebsd32_convert_msg_in(struct mbuf **controlp)
1021151909Sps{
1022151909Sps	struct mbuf *control = *controlp;
1023151909Sps	struct cmsghdr *cm = mtod(control, struct cmsghdr *);
1024151909Sps	void *data;
1025151909Sps	socklen_t clen = control->m_len, datalen;
1026151909Sps	int error;
1027151909Sps
1028151909Sps	error = 0;
1029151909Sps	*controlp = NULL;
1030151909Sps
1031151909Sps	while (cm != NULL) {
1032151909Sps		if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) {
1033151909Sps			error = EINVAL;
1034151909Sps			break;
1035151909Sps		}
1036151909Sps
1037151909Sps		data = FREEBSD32_CMSG_DATA(cm);
1038151909Sps		datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1039151909Sps
1040151909Sps		*controlp = sbcreatecontrol(data, datalen, cm->cmsg_type,
1041151909Sps		    cm->cmsg_level);
1042151909Sps		controlp = &(*controlp)->m_next;
1043151909Sps
1044151909Sps		if (FREEBSD32_CMSG_SPACE(datalen) < clen) {
1045151909Sps			clen -= FREEBSD32_CMSG_SPACE(datalen);
1046151909Sps			cm = (struct cmsghdr *)
1047151909Sps				((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen));
1048151909Sps		} else {
1049151909Sps			clen = 0;
1050151909Sps			cm = NULL;
1051151909Sps		}
1052151909Sps	}
1053151909Sps
1054151909Sps	m_freem(control);
1055151909Sps	return (error);
1056151909Sps}
1057151909Sps
1058151909Sps
1059151359Spsint
1060151359Spsfreebsd32_sendmsg(struct thread *td,
1061151359Sps		  struct freebsd32_sendmsg_args *uap)
1062151359Sps{
1063151359Sps	struct msghdr msg;
1064151359Sps	struct msghdr32 m32;
1065151359Sps	struct iovec *iov;
1066151909Sps	struct mbuf *control = NULL;
1067151909Sps	struct sockaddr *to = NULL;
1068151359Sps	int error;
1069151359Sps
1070151359Sps	error = copyin(uap->msg, &m32, sizeof(m32));
1071151359Sps	if (error)
1072151359Sps		return (error);
1073151359Sps	error = freebsd32_copyinmsghdr(uap->msg, &msg);
1074151359Sps	if (error)
1075151359Sps		return (error);
1076160246Sjhb	error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
1077160246Sjhb	    EMSGSIZE);
1078151359Sps	if (error)
1079151359Sps		return (error);
1080151359Sps	msg.msg_iov = iov;
1081151909Sps	if (msg.msg_name != NULL) {
1082151909Sps		error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1083151909Sps		if (error) {
1084151909Sps			to = NULL;
1085151909Sps			goto out;
1086151909Sps		}
1087151909Sps		msg.msg_name = to;
1088151909Sps	}
1089151909Sps
1090151909Sps	if (msg.msg_control) {
1091151909Sps		if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1092151909Sps			error = EINVAL;
1093151909Sps			goto out;
1094151909Sps		}
1095151909Sps
1096151909Sps		error = sockargs(&control, msg.msg_control,
1097151909Sps		    msg.msg_controllen, MT_CONTROL);
1098151909Sps		if (error)
1099151909Sps			goto out;
1100151909Sps
1101151909Sps		error = freebsd32_convert_msg_in(&control);
1102151909Sps		if (error)
1103151909Sps			goto out;
1104151909Sps	}
1105151909Sps
1106151909Sps	error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1107151909Sps	    UIO_USERSPACE);
1108151909Sps
1109151909Spsout:
1110151359Sps	free(iov, M_IOV);
1111151909Sps	if (to)
1112151909Sps		free(to, M_SONAME);
1113151359Sps	return (error);
1114151359Sps}
1115151359Sps
1116151359Spsint
1117151359Spsfreebsd32_recvfrom(struct thread *td,
1118151359Sps		   struct freebsd32_recvfrom_args *uap)
1119151359Sps{
1120151359Sps	struct msghdr msg;
1121151359Sps	struct iovec aiov;
1122151359Sps	int error;
1123151359Sps
1124151359Sps	if (uap->fromlenaddr) {
1125160246Sjhb		error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
1126160246Sjhb		    sizeof(msg.msg_namelen));
1127151359Sps		if (error)
1128151359Sps			return (error);
1129151359Sps	} else {
1130151359Sps		msg.msg_namelen = 0;
1131151359Sps	}
1132151359Sps
1133160246Sjhb	msg.msg_name = PTRIN(uap->from);
1134151359Sps	msg.msg_iov = &aiov;
1135151359Sps	msg.msg_iovlen = 1;
1136160246Sjhb	aiov.iov_base = PTRIN(uap->buf);
1137151359Sps	aiov.iov_len = uap->len;
1138160246Sjhb	msg.msg_control = NULL;
1139151359Sps	msg.msg_flags = uap->flags;
1140160249Sjhb	error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
1141160249Sjhb	if (error == 0 && uap->fromlenaddr)
1142160249Sjhb		error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
1143160249Sjhb		    sizeof (msg.msg_namelen));
1144151359Sps	return (error);
1145151359Sps}
1146151359Sps
1147151359Spsint
1148119333Speterfreebsd32_settimeofday(struct thread *td,
1149119333Speter		       struct freebsd32_settimeofday_args *uap)
1150100384Speter{
1151144450Sjhb	struct timeval32 tv32;
1152144450Sjhb	struct timeval tv, *tvp;
1153144450Sjhb	struct timezone tz, *tzp;
1154100384Speter	int error;
1155100384Speter
1156144450Sjhb	if (uap->tv) {
1157144450Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
1158100384Speter		if (error)
1159100384Speter			return (error);
1160144450Sjhb		CP(tv32, tv, tv_sec);
1161144450Sjhb		CP(tv32, tv, tv_usec);
1162144450Sjhb		tvp = &tv;
1163144450Sjhb	} else
1164144450Sjhb		tvp = NULL;
1165144450Sjhb	if (uap->tzp) {
1166144450Sjhb		error = copyin(uap->tzp, &tz, sizeof(tz));
1167100384Speter		if (error)
1168100384Speter			return (error);
1169144450Sjhb		tzp = &tz;
1170144450Sjhb	} else
1171144450Sjhb		tzp = NULL;
1172144450Sjhb	return (kern_settimeofday(td, tvp, tzp));
1173100384Speter}
1174100384Speter
1175100384Speterint
1176119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1177100384Speter{
1178142059Sjhb	struct timeval32 s32[2];
1179142059Sjhb	struct timeval s[2], *sp;
1180100384Speter	int error;
1181100384Speter
1182142059Sjhb	if (uap->tptr != NULL) {
1183142059Sjhb		error = copyin(uap->tptr, s32, sizeof(s32));
1184100384Speter		if (error)
1185100384Speter			return (error);
1186100384Speter		CP(s32[0], s[0], tv_sec);
1187100384Speter		CP(s32[0], s[0], tv_usec);
1188100384Speter		CP(s32[1], s[1], tv_sec);
1189100384Speter		CP(s32[1], s[1], tv_usec);
1190142059Sjhb		sp = s;
1191142059Sjhb	} else
1192142059Sjhb		sp = NULL;
1193142059Sjhb	return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1194100384Speter}
1195100384Speter
1196100384Speterint
1197154586Sambriskofreebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1198154586Sambrisko{
1199154586Sambrisko	struct timeval32 s32[2];
1200154586Sambrisko	struct timeval s[2], *sp;
1201154586Sambrisko	int error;
1202154586Sambrisko
1203154586Sambrisko	if (uap->tptr != NULL) {
1204154586Sambrisko		error = copyin(uap->tptr, s32, sizeof(s32));
1205154586Sambrisko		if (error)
1206154586Sambrisko			return (error);
1207154586Sambrisko		CP(s32[0], s[0], tv_sec);
1208154586Sambrisko		CP(s32[0], s[0], tv_usec);
1209154586Sambrisko		CP(s32[1], s[1], tv_sec);
1210154586Sambrisko		CP(s32[1], s[1], tv_usec);
1211154586Sambrisko		sp = s;
1212154586Sambrisko	} else
1213154586Sambrisko		sp = NULL;
1214154586Sambrisko	return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1215154586Sambrisko}
1216154586Sambrisko
1217154586Sambriskoint
1218153247Sambriskofreebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1219153247Sambrisko{
1220153247Sambrisko	struct timeval32 s32[2];
1221153247Sambrisko	struct timeval s[2], *sp;
1222153247Sambrisko	int error;
1223153247Sambrisko
1224153247Sambrisko	if (uap->tptr != NULL) {
1225153247Sambrisko		error = copyin(uap->tptr, s32, sizeof(s32));
1226153247Sambrisko		if (error)
1227153247Sambrisko			return (error);
1228153247Sambrisko		CP(s32[0], s[0], tv_sec);
1229153247Sambrisko		CP(s32[0], s[0], tv_usec);
1230153247Sambrisko		CP(s32[1], s[1], tv_sec);
1231153247Sambrisko		CP(s32[1], s[1], tv_usec);
1232153247Sambrisko		sp = s;
1233153247Sambrisko	} else
1234153247Sambrisko		sp = NULL;
1235153247Sambrisko	return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1236153247Sambrisko}
1237153247Sambrisko
1238153247Sambrisko
1239153247Sambriskoint
1240119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1241100384Speter{
1242144450Sjhb	struct timeval32 tv32;
1243144450Sjhb	struct timeval delta, olddelta, *deltap;
1244100384Speter	int error;
1245100384Speter
1246144450Sjhb	if (uap->delta) {
1247144450Sjhb		error = copyin(uap->delta, &tv32, sizeof(tv32));
1248100384Speter		if (error)
1249100384Speter			return (error);
1250144450Sjhb		CP(tv32, delta, tv_sec);
1251144450Sjhb		CP(tv32, delta, tv_usec);
1252144450Sjhb		deltap = &delta;
1253144450Sjhb	} else
1254144450Sjhb		deltap = NULL;
1255144450Sjhb	error = kern_adjtime(td, deltap, &olddelta);
1256144450Sjhb	if (uap->olddelta && error == 0) {
1257144450Sjhb		CP(olddelta, tv32, tv_sec);
1258144450Sjhb		CP(olddelta, tv32, tv_usec);
1259144450Sjhb		error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1260100384Speter	}
1261100384Speter	return (error);
1262100384Speter}
1263100384Speter
1264128597Smarcel#ifdef COMPAT_FREEBSD4
1265100384Speterint
1266128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1267100384Speter{
1268142059Sjhb	struct statfs32 s32;
1269142059Sjhb	struct statfs s;
1270100384Speter	int error;
1271100384Speter
1272142059Sjhb	error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
1273100384Speter	if (error)
1274100384Speter		return (error);
1275174377Sjhb	error = copy_statfs(&s, &s32);
1276174377Sjhb	if (error)
1277174377Sjhb		return (error);
1278142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1279100384Speter}
1280128597Smarcel#endif
1281100384Speter
1282128597Smarcel#ifdef COMPAT_FREEBSD4
1283100384Speterint
1284128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1285100384Speter{
1286142059Sjhb	struct statfs32 s32;
1287142059Sjhb	struct statfs s;
1288100384Speter	int error;
1289100384Speter
1290142059Sjhb	error = kern_fstatfs(td, uap->fd, &s);
1291100384Speter	if (error)
1292100384Speter		return (error);
1293174377Sjhb	error = copy_statfs(&s, &s32);
1294174377Sjhb	if (error)
1295174377Sjhb		return (error);
1296142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1297100384Speter}
1298128597Smarcel#endif
1299100384Speter
1300128597Smarcel#ifdef COMPAT_FREEBSD4
1301100384Speterint
1302128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1303128260Speter{
1304142059Sjhb	struct statfs32 s32;
1305142059Sjhb	struct statfs s;
1306142059Sjhb	fhandle_t fh;
1307128260Speter	int error;
1308128260Speter
1309142059Sjhb	if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
1310142059Sjhb		return (error);
1311142059Sjhb	error = kern_fhstatfs(td, fh, &s);
1312128260Speter	if (error)
1313128260Speter		return (error);
1314174377Sjhb	error = copy_statfs(&s, &s32);
1315174377Sjhb	if (error)
1316174377Sjhb		return (error);
1317142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1318128260Speter}
1319128597Smarcel#endif
1320128260Speter
1321128260Speterint
1322119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1323100384Speter{
1324100384Speter	/*
1325100384Speter	 * Vector through to semsys if it is loaded.
1326100384Speter	 */
1327150883Sjhb	return sysent[SYS_semsys].sy_call(td, uap);
1328100384Speter}
1329100384Speter
1330100384Speterint
1331119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1332100384Speter{
1333165405Sjkim	switch (uap->which) {
1334165405Sjkim	case 2:
1335165405Sjkim		return (freebsd32_msgsnd(td,
1336165405Sjkim		    (struct freebsd32_msgsnd_args *)&uap->a2));
1337165405Sjkim		break;
1338165405Sjkim	case 3:
1339165405Sjkim		return (freebsd32_msgrcv(td,
1340165405Sjkim		    (struct freebsd32_msgrcv_args *)&uap->a2));
1341165405Sjkim		break;
1342165405Sjkim	default:
1343165405Sjkim		/*
1344165405Sjkim		 * Vector through to msgsys if it is loaded.
1345165405Sjkim		 */
1346165405Sjkim		return (sysent[SYS_msgsys].sy_call(td, uap));
1347165405Sjkim		break;
1348165405Sjkim	}
1349100384Speter}
1350100384Speter
1351100384Speterint
1352165405Sjkimfreebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
1353165405Sjkim{
1354165405Sjkim	const void *msgp;
1355165405Sjkim	long mtype;
1356165405Sjkim	int32_t mtype32;
1357165405Sjkim	int error;
1358165405Sjkim
1359165405Sjkim	msgp = PTRIN(uap->msgp);
1360165405Sjkim	if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
1361165405Sjkim		return (error);
1362165405Sjkim	mtype = mtype32;
1363165405Sjkim	return (kern_msgsnd(td, uap->msqid,
1364165405Sjkim	    (const char *)msgp + sizeof(mtype32),
1365165405Sjkim	    uap->msgsz, uap->msgflg, mtype));
1366165405Sjkim}
1367165405Sjkim
1368165405Sjkimint
1369165405Sjkimfreebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
1370165405Sjkim{
1371165405Sjkim	void *msgp;
1372165405Sjkim	long mtype;
1373165405Sjkim	int32_t mtype32;
1374165405Sjkim	int error;
1375165405Sjkim
1376165405Sjkim	msgp = PTRIN(uap->msgp);
1377165405Sjkim	if ((error = kern_msgrcv(td, uap->msqid,
1378165405Sjkim	    (char *)msgp + sizeof(mtype32), uap->msgsz,
1379165405Sjkim	    uap->msgtyp, uap->msgflg, &mtype)) != 0)
1380165405Sjkim		return (error);
1381165405Sjkim	mtype32 = (int32_t)mtype;
1382165405Sjkim	return (copyout(&mtype32, msgp, sizeof(mtype32)));
1383165405Sjkim}
1384165405Sjkim
1385165405Sjkimint
1386119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1387100384Speter{
1388157285Sps
1389157285Sps	switch (uap->which) {
1390157285Sps	case 0:	{	/* shmat */
1391157285Sps		struct shmat_args ap;
1392157285Sps
1393157285Sps		ap.shmid = uap->a2;
1394157285Sps		ap.shmaddr = PTRIN(uap->a3);
1395157285Sps		ap.shmflg = uap->a4;
1396157285Sps		return (sysent[SYS_shmat].sy_call(td, &ap));
1397157285Sps	}
1398157285Sps	case 2: {	/* shmdt */
1399157285Sps		struct shmdt_args ap;
1400157285Sps
1401157285Sps		ap.shmaddr = PTRIN(uap->a2);
1402157285Sps		return (sysent[SYS_shmdt].sy_call(td, &ap));
1403157285Sps	}
1404157285Sps	case 3: {	/* shmget */
1405157285Sps		struct shmget_args ap;
1406157285Sps
1407157285Sps		ap.key = uap->a2;
1408157285Sps		ap.size = uap->a3;
1409157285Sps		ap.shmflg = uap->a4;
1410157285Sps		return (sysent[SYS_shmget].sy_call(td, &ap));
1411157285Sps	}
1412157285Sps	case 4: {	/* shmctl */
1413157285Sps		struct freebsd32_shmctl_args ap;
1414157285Sps
1415157285Sps		ap.shmid = uap->a2;
1416157285Sps		ap.cmd = uap->a3;
1417157285Sps		ap.buf = PTRIN(uap->a4);
1418157285Sps		return (freebsd32_shmctl(td, &ap));
1419157285Sps	}
1420157285Sps	case 1:		/* oshmctl */
1421157285Sps	default:
1422157285Sps		return (EINVAL);
1423157285Sps	}
1424100384Speter}
1425100384Speter
1426157285Spsstruct ipc_perm32 {
1427157285Sps	uint16_t	cuid;
1428157285Sps	uint16_t	cgid;
1429157285Sps	uint16_t	uid;
1430157285Sps	uint16_t	gid;
1431157285Sps	uint16_t	mode;
1432157285Sps	uint16_t	seq;
1433157285Sps	uint32_t	key;
1434157285Sps};
1435157285Spsstruct shmid_ds32 {
1436157285Sps	struct ipc_perm32 shm_perm;
1437157285Sps	int32_t		shm_segsz;
1438157285Sps	int32_t		shm_lpid;
1439157285Sps	int32_t		shm_cpid;
1440157285Sps	int16_t		shm_nattch;
1441157285Sps	int32_t		shm_atime;
1442157285Sps	int32_t		shm_dtime;
1443157285Sps	int32_t		shm_ctime;
1444157285Sps	uint32_t	shm_internal;
1445157285Sps};
1446157285Spsstruct shm_info32 {
1447157285Sps	int32_t		used_ids;
1448157285Sps	uint32_t	shm_tot;
1449157285Sps	uint32_t	shm_rss;
1450157285Sps	uint32_t	shm_swp;
1451157285Sps	uint32_t	swap_attempts;
1452157285Sps	uint32_t	swap_successes;
1453157285Sps};
1454157285Spsstruct shminfo32 {
1455157285Sps	uint32_t	shmmax;
1456157285Sps	uint32_t	shmmin;
1457157285Sps	uint32_t	shmmni;
1458157285Sps	uint32_t	shmseg;
1459157285Sps	uint32_t	shmall;
1460157285Sps};
1461157285Sps
1462100384Speterint
1463157285Spsfreebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
1464157285Sps{
1465157285Sps	int error = 0;
1466157285Sps	union {
1467157285Sps		struct shmid_ds shmid_ds;
1468157285Sps		struct shm_info shm_info;
1469157285Sps		struct shminfo shminfo;
1470157285Sps	} u;
1471157285Sps	union {
1472157285Sps		struct shmid_ds32 shmid_ds32;
1473157285Sps		struct shm_info32 shm_info32;
1474157285Sps		struct shminfo32 shminfo32;
1475157285Sps	} u32;
1476157285Sps	size_t sz;
1477157285Sps
1478157285Sps	if (uap->cmd == IPC_SET) {
1479157285Sps		if ((error = copyin(uap->buf, &u32.shmid_ds32,
1480157285Sps		    sizeof(u32.shmid_ds32))))
1481157285Sps			goto done;
1482157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cuid);
1483157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cgid);
1484157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.uid);
1485157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.gid);
1486157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.mode);
1487157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.seq);
1488157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_perm.key);
1489157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1490157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1491157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1492157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1493157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1494157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1495157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1496157285Sps		PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal);
1497157285Sps	}
1498157285Sps
1499157285Sps	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
1500157285Sps	if (error)
1501157285Sps		goto done;
1502157285Sps
1503157285Sps	/* Cases in which we need to copyout */
1504157285Sps	switch (uap->cmd) {
1505157285Sps	case IPC_INFO:
1506157285Sps		CP(u.shminfo, u32.shminfo32, shmmax);
1507157285Sps		CP(u.shminfo, u32.shminfo32, shmmin);
1508157285Sps		CP(u.shminfo, u32.shminfo32, shmmni);
1509157285Sps		CP(u.shminfo, u32.shminfo32, shmseg);
1510157285Sps		CP(u.shminfo, u32.shminfo32, shmall);
1511157285Sps		error = copyout(&u32.shminfo32, uap->buf,
1512157285Sps		    sizeof(u32.shminfo32));
1513157285Sps		break;
1514157285Sps	case SHM_INFO:
1515157285Sps		CP(u.shm_info, u32.shm_info32, used_ids);
1516157285Sps		CP(u.shm_info, u32.shm_info32, shm_rss);
1517157285Sps		CP(u.shm_info, u32.shm_info32, shm_tot);
1518157285Sps		CP(u.shm_info, u32.shm_info32, shm_swp);
1519157285Sps		CP(u.shm_info, u32.shm_info32, swap_attempts);
1520157285Sps		CP(u.shm_info, u32.shm_info32, swap_successes);
1521157285Sps		error = copyout(&u32.shm_info32, uap->buf,
1522157285Sps		    sizeof(u32.shm_info32));
1523157285Sps		break;
1524157285Sps	case SHM_STAT:
1525157285Sps	case IPC_STAT:
1526157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cuid);
1527157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cgid);
1528157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.uid);
1529157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.gid);
1530157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.mode);
1531157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.seq);
1532157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_perm.key);
1533157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1534157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1535157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1536157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1537157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1538157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1539157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1540157285Sps		PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal);
1541157285Sps		error = copyout(&u32.shmid_ds32, uap->buf,
1542157285Sps		    sizeof(u32.shmid_ds32));
1543157285Sps		break;
1544157285Sps	}
1545157285Sps
1546157285Spsdone:
1547157285Sps	if (error) {
1548157285Sps		/* Invalidate the return value */
1549157285Sps		td->td_retval[0] = -1;
1550157285Sps	}
1551157285Sps	return (error);
1552157285Sps}
1553157285Sps
1554157285Spsint
1555119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1556100384Speter{
1557100384Speter	struct pread_args ap;
1558100384Speter
1559107849Salfred	ap.fd = uap->fd;
1560107849Salfred	ap.buf = uap->buf;
1561107849Salfred	ap.nbyte = uap->nbyte;
1562119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1563100384Speter	return (pread(td, &ap));
1564100384Speter}
1565100384Speter
1566100384Speterint
1567119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1568100384Speter{
1569100384Speter	struct pwrite_args ap;
1570100384Speter
1571107849Salfred	ap.fd = uap->fd;
1572107849Salfred	ap.buf = uap->buf;
1573107849Salfred	ap.nbyte = uap->nbyte;
1574119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1575100384Speter	return (pwrite(td, &ap));
1576100384Speter}
1577100384Speter
1578100384Speterint
1579119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1580100384Speter{
1581100384Speter	int error;
1582100384Speter	struct lseek_args ap;
1583100384Speter	off_t pos;
1584100384Speter
1585107849Salfred	ap.fd = uap->fd;
1586119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1587107849Salfred	ap.whence = uap->whence;
1588100384Speter	error = lseek(td, &ap);
1589100384Speter	/* Expand the quad return into two parts for eax and edx */
1590100384Speter	pos = *(off_t *)(td->td_retval);
1591100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1592100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1593100384Speter	return error;
1594100384Speter}
1595100384Speter
1596100384Speterint
1597119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1598100384Speter{
1599100384Speter	struct truncate_args ap;
1600100384Speter
1601107849Salfred	ap.path = uap->path;
1602119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1603100384Speter	return (truncate(td, &ap));
1604100384Speter}
1605100384Speter
1606100384Speterint
1607119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1608100384Speter{
1609100384Speter	struct ftruncate_args ap;
1610100384Speter
1611107849Salfred	ap.fd = uap->fd;
1612119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1613100384Speter	return (ftruncate(td, &ap));
1614100384Speter}
1615100384Speter
1616171215Speter#ifdef COMPAT_FREEBSD6
1617171215Speter/* versions with the 'int pad' argument */
1618171215Speterint
1619171215Speterfreebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
1620171215Speter{
1621171215Speter	struct pread_args ap;
1622171215Speter
1623171215Speter	ap.fd = uap->fd;
1624171215Speter	ap.buf = uap->buf;
1625171215Speter	ap.nbyte = uap->nbyte;
1626171215Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1627171215Speter	return (pread(td, &ap));
1628171215Speter}
1629171215Speter
1630171215Speterint
1631171215Speterfreebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
1632171215Speter{
1633171215Speter	struct pwrite_args ap;
1634171215Speter
1635171215Speter	ap.fd = uap->fd;
1636171215Speter	ap.buf = uap->buf;
1637171215Speter	ap.nbyte = uap->nbyte;
1638171215Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1639171215Speter	return (pwrite(td, &ap));
1640171215Speter}
1641171215Speter
1642171215Speterint
1643171215Speterfreebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
1644171215Speter{
1645171215Speter	int error;
1646171215Speter	struct lseek_args ap;
1647171215Speter	off_t pos;
1648171215Speter
1649171215Speter	ap.fd = uap->fd;
1650171215Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1651171215Speter	ap.whence = uap->whence;
1652171215Speter	error = lseek(td, &ap);
1653171215Speter	/* Expand the quad return into two parts for eax and edx */
1654171215Speter	pos = *(off_t *)(td->td_retval);
1655171215Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1656171215Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1657171215Speter	return error;
1658171215Speter}
1659171215Speter
1660171215Speterint
1661171215Speterfreebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
1662171215Speter{
1663171215Speter	struct truncate_args ap;
1664171215Speter
1665171215Speter	ap.path = uap->path;
1666171215Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1667171215Speter	return (truncate(td, &ap));
1668171215Speter}
1669171215Speter
1670171215Speterint
1671171215Speterfreebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
1672171215Speter{
1673171215Speter	struct ftruncate_args ap;
1674171215Speter
1675171215Speter	ap.fd = uap->fd;
1676171215Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1677171215Speter	return (ftruncate(td, &ap));
1678171215Speter}
1679171215Speter#endif /* COMPAT_FREEBSD6 */
1680171215Speter
1681156114Spsstruct sf_hdtr32 {
1682156114Sps	uint32_t headers;
1683156114Sps	int hdr_cnt;
1684156114Sps	uint32_t trailers;
1685156114Sps	int trl_cnt;
1686156114Sps};
1687156114Sps
1688156114Spsstatic int
1689156114Spsfreebsd32_do_sendfile(struct thread *td,
1690156114Sps    struct freebsd32_sendfile_args *uap, int compat)
1691104738Speter{
1692156114Sps	struct sendfile_args ap;
1693156114Sps	struct sf_hdtr32 hdtr32;
1694156114Sps	struct sf_hdtr hdtr;
1695156114Sps	struct uio *hdr_uio, *trl_uio;
1696156114Sps	struct iovec32 *iov32;
1697156114Sps	int error;
1698104738Speter
1699156114Sps	hdr_uio = trl_uio = NULL;
1700156114Sps
1701107849Salfred	ap.fd = uap->fd;
1702107849Salfred	ap.s = uap->s;
1703119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1704156114Sps	ap.nbytes = uap->nbytes;
1705156114Sps	ap.hdtr = (struct sf_hdtr *)uap->hdtr;		/* XXX not used */
1706156114Sps	ap.sbytes = uap->sbytes;
1707107849Salfred	ap.flags = uap->flags;
1708156114Sps
1709156114Sps	if (uap->hdtr != NULL) {
1710156114Sps		error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
1711156114Sps		if (error)
1712156114Sps			goto out;
1713156114Sps		PTRIN_CP(hdtr32, hdtr, headers);
1714156114Sps		CP(hdtr32, hdtr, hdr_cnt);
1715156114Sps		PTRIN_CP(hdtr32, hdtr, trailers);
1716156114Sps		CP(hdtr32, hdtr, trl_cnt);
1717156114Sps
1718156114Sps		if (hdtr.headers != NULL) {
1719160246Sjhb			iov32 = PTRIN(hdtr32.headers);
1720156114Sps			error = freebsd32_copyinuio(iov32,
1721156114Sps			    hdtr32.hdr_cnt, &hdr_uio);
1722156114Sps			if (error)
1723156114Sps				goto out;
1724156114Sps		}
1725156114Sps		if (hdtr.trailers != NULL) {
1726160246Sjhb			iov32 = PTRIN(hdtr32.trailers);
1727156114Sps			error = freebsd32_copyinuio(iov32,
1728156114Sps			    hdtr32.trl_cnt, &trl_uio);
1729156114Sps			if (error)
1730156114Sps				goto out;
1731156114Sps		}
1732156114Sps	}
1733156114Sps
1734156114Sps	error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat);
1735156114Spsout:
1736156114Sps	if (hdr_uio)
1737156114Sps		free(hdr_uio, M_IOV);
1738156114Sps	if (trl_uio)
1739156114Sps		free(trl_uio, M_IOV);
1740156114Sps	return (error);
1741104738Speter}
1742156114Sps
1743156114Sps#ifdef COMPAT_FREEBSD4
1744156114Spsint
1745156114Spsfreebsd4_freebsd32_sendfile(struct thread *td,
1746156114Sps    struct freebsd4_freebsd32_sendfile_args *uap)
1747156114Sps{
1748156114Sps	return (freebsd32_do_sendfile(td,
1749156114Sps	    (struct freebsd32_sendfile_args *)uap, 1));
1750156114Sps}
1751104738Speter#endif
1752104738Speter
1753104738Speterint
1754119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1755100384Speter{
1756100384Speter
1757156114Sps	return (freebsd32_do_sendfile(td, uap, 0));
1758100384Speter}
1759100384Speter
1760100384Speterstatic void
1761100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1762100384Speter{
1763100384Speter	CP(*in, *out, st_dev);
1764100384Speter	CP(*in, *out, st_ino);
1765100384Speter	CP(*in, *out, st_mode);
1766100384Speter	CP(*in, *out, st_nlink);
1767100384Speter	CP(*in, *out, st_uid);
1768100384Speter	CP(*in, *out, st_gid);
1769100384Speter	CP(*in, *out, st_rdev);
1770100384Speter	TS_CP(*in, *out, st_atimespec);
1771100384Speter	TS_CP(*in, *out, st_mtimespec);
1772100384Speter	TS_CP(*in, *out, st_ctimespec);
1773100384Speter	CP(*in, *out, st_size);
1774100384Speter	CP(*in, *out, st_blocks);
1775100384Speter	CP(*in, *out, st_blksize);
1776100384Speter	CP(*in, *out, st_flags);
1777100384Speter	CP(*in, *out, st_gen);
1778100384Speter}
1779100384Speter
1780100384Speterint
1781119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1782100384Speter{
1783123746Speter	struct stat sb;
1784123746Speter	struct stat32 sb32;
1785100384Speter	int error;
1786100384Speter
1787142059Sjhb	error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1788100384Speter	if (error)
1789100384Speter		return (error);
1790123746Speter	copy_stat(&sb, &sb32);
1791123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1792100384Speter	return (error);
1793100384Speter}
1794100384Speter
1795100384Speterint
1796119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1797100384Speter{
1798123746Speter	struct stat ub;
1799123746Speter	struct stat32 ub32;
1800100384Speter	int error;
1801100384Speter
1802142059Sjhb	error = kern_fstat(td, uap->fd, &ub);
1803100384Speter	if (error)
1804100384Speter		return (error);
1805123746Speter	copy_stat(&ub, &ub32);
1806123746Speter	error = copyout(&ub32, uap->ub, sizeof(ub32));
1807100384Speter	return (error);
1808100384Speter}
1809100384Speter
1810100384Speterint
1811119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1812100384Speter{
1813123746Speter	struct stat sb;
1814123746Speter	struct stat32 sb32;
1815142059Sjhb	int error;
1816100384Speter
1817142059Sjhb	error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1818100384Speter	if (error)
1819100384Speter		return (error);
1820123746Speter	copy_stat(&sb, &sb32);
1821123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1822100384Speter	return (error);
1823100384Speter}
1824100384Speter
1825100384Speter/*
1826100384Speter * MPSAFE
1827100384Speter */
1828100384Speterint
1829119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1830100384Speter{
1831100384Speter	int error, name[CTL_MAXNAME];
1832100384Speter	size_t j, oldlen;
1833100384Speter
1834100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1835100384Speter		return (EINVAL);
1836136404Speter 	error = copyin(uap->name, name, uap->namelen * sizeof(int));
1837100384Speter 	if (error)
1838100384Speter		return (error);
1839100384Speter	mtx_lock(&Giant);
1840100384Speter	if (uap->oldlenp)
1841100384Speter		oldlen = fuword32(uap->oldlenp);
1842100384Speter	else
1843100384Speter		oldlen = 0;
1844100384Speter	error = userland_sysctl(td, name, uap->namelen,
1845100384Speter		uap->old, &oldlen, 1,
1846136404Speter		uap->new, uap->newlen, &j, SCTL_MASK32);
1847100384Speter	if (error && error != ENOMEM)
1848100384Speter		goto done2;
1849136404Speter	if (uap->oldlenp)
1850100384Speter		suword32(uap->oldlenp, j);
1851100384Speterdone2:
1852100384Speter	mtx_unlock(&Giant);
1853100384Speter	return (error);
1854100384Speter}
1855100384Speter
1856100384Speterint
1857119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1858100384Speter{
1859113859Sjhb	struct sigaction32 s32;
1860113859Sjhb	struct sigaction sa, osa, *sap;
1861100384Speter	int error;
1862100384Speter
1863113859Sjhb	if (uap->act) {
1864113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1865100384Speter		if (error)
1866100384Speter			return (error);
1867113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1868113859Sjhb		CP(s32, sa, sa_flags);
1869113859Sjhb		CP(s32, sa, sa_mask);
1870113859Sjhb		sap = &sa;
1871113859Sjhb	} else
1872113859Sjhb		sap = NULL;
1873113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1874146583Sps	if (error == 0 && uap->oact != NULL) {
1875113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1876113859Sjhb		CP(osa, s32, sa_flags);
1877113859Sjhb		CP(osa, s32, sa_mask);
1878113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1879100384Speter	}
1880100384Speter	return (error);
1881100384Speter}
1882100384Speter
1883114987Speter#ifdef COMPAT_FREEBSD4
1884114987Speterint
1885119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1886119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1887114987Speter{
1888114987Speter	struct sigaction32 s32;
1889114987Speter	struct sigaction sa, osa, *sap;
1890114987Speter	int error;
1891114987Speter
1892114987Speter	if (uap->act) {
1893114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1894114987Speter		if (error)
1895114987Speter			return (error);
1896114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1897114987Speter		CP(s32, sa, sa_flags);
1898114987Speter		CP(s32, sa, sa_mask);
1899114987Speter		sap = &sa;
1900114987Speter	} else
1901114987Speter		sap = NULL;
1902114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1903146583Sps	if (error == 0 && uap->oact != NULL) {
1904114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1905114987Speter		CP(osa, s32, sa_flags);
1906114987Speter		CP(osa, s32, sa_mask);
1907114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1908114987Speter	}
1909114987Speter	return (error);
1910114987Speter}
1911114987Speter#endif
1912114987Speter
1913151582Sps#ifdef COMPAT_43
1914151720Speterstruct osigaction32 {
1915151582Sps	u_int32_t	sa_u;
1916151582Sps	osigset_t	sa_mask;
1917151582Sps	int		sa_flags;
1918151582Sps};
1919151582Sps
1920151582Sps#define	ONSIG	32
1921151582Sps
1922140481Spsint
1923151720Speterofreebsd32_sigaction(struct thread *td,
1924151720Speter			     struct ofreebsd32_sigaction_args *uap)
1925151582Sps{
1926151720Speter	struct osigaction32 s32;
1927151582Sps	struct sigaction sa, osa, *sap;
1928151582Sps	int error;
1929151582Sps
1930151582Sps	if (uap->signum <= 0 || uap->signum >= ONSIG)
1931151582Sps		return (EINVAL);
1932151582Sps
1933151582Sps	if (uap->nsa) {
1934151582Sps		error = copyin(uap->nsa, &s32, sizeof(s32));
1935151582Sps		if (error)
1936151582Sps			return (error);
1937151582Sps		sa.sa_handler = PTRIN(s32.sa_u);
1938151582Sps		CP(s32, sa, sa_flags);
1939151582Sps		OSIG2SIG(s32.sa_mask, sa.sa_mask);
1940151582Sps		sap = &sa;
1941151582Sps	} else
1942151582Sps		sap = NULL;
1943151582Sps	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
1944151582Sps	if (error == 0 && uap->osa != NULL) {
1945151582Sps		s32.sa_u = PTROUT(osa.sa_handler);
1946151582Sps		CP(osa, s32, sa_flags);
1947151582Sps		SIG2OSIG(osa.sa_mask, s32.sa_mask);
1948151582Sps		error = copyout(&s32, uap->osa, sizeof(s32));
1949151582Sps	}
1950151582Sps	return (error);
1951151582Sps}
1952151582Sps
1953151582Spsint
1954151720Speterofreebsd32_sigprocmask(struct thread *td,
1955151720Speter			       struct ofreebsd32_sigprocmask_args *uap)
1956151582Sps{
1957151582Sps	sigset_t set, oset;
1958151582Sps	int error;
1959151582Sps
1960151582Sps	OSIG2SIG(uap->mask, set);
1961151582Sps	error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
1962151582Sps	SIG2OSIG(oset, td->td_retval[0]);
1963151582Sps	return (error);
1964151582Sps}
1965151582Sps
1966151582Spsint
1967151720Speterofreebsd32_sigpending(struct thread *td,
1968151720Speter			      struct ofreebsd32_sigpending_args *uap)
1969151582Sps{
1970151582Sps	struct proc *p = td->td_proc;
1971151582Sps	sigset_t siglist;
1972151582Sps
1973151582Sps	PROC_LOCK(p);
1974151582Sps	siglist = p->p_siglist;
1975151582Sps	SIGSETOR(siglist, td->td_siglist);
1976151582Sps	PROC_UNLOCK(p);
1977151582Sps	SIG2OSIG(siglist, td->td_retval[0]);
1978151582Sps	return (0);
1979151582Sps}
1980151582Sps
1981151582Spsstruct sigvec32 {
1982151582Sps	u_int32_t	sv_handler;
1983151582Sps	int		sv_mask;
1984151582Sps	int		sv_flags;
1985151582Sps};
1986151582Sps
1987151582Spsint
1988151720Speterofreebsd32_sigvec(struct thread *td,
1989151720Speter			  struct ofreebsd32_sigvec_args *uap)
1990151582Sps{
1991151582Sps	struct sigvec32 vec;
1992151582Sps	struct sigaction sa, osa, *sap;
1993151582Sps	int error;
1994151582Sps
1995151582Sps	if (uap->signum <= 0 || uap->signum >= ONSIG)
1996151582Sps		return (EINVAL);
1997151582Sps
1998151582Sps	if (uap->nsv) {
1999151582Sps		error = copyin(uap->nsv, &vec, sizeof(vec));
2000151582Sps		if (error)
2001151582Sps			return (error);
2002151582Sps		sa.sa_handler = PTRIN(vec.sv_handler);
2003151582Sps		OSIG2SIG(vec.sv_mask, sa.sa_mask);
2004151582Sps		sa.sa_flags = vec.sv_flags;
2005151582Sps		sa.sa_flags ^= SA_RESTART;
2006151582Sps		sap = &sa;
2007151582Sps	} else
2008151582Sps		sap = NULL;
2009151582Sps	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2010151582Sps	if (error == 0 && uap->osv != NULL) {
2011151582Sps		vec.sv_handler = PTROUT(osa.sa_handler);
2012151582Sps		SIG2OSIG(osa.sa_mask, vec.sv_mask);
2013151582Sps		vec.sv_flags = osa.sa_flags;
2014151582Sps		vec.sv_flags &= ~SA_NOCLDWAIT;
2015151582Sps		vec.sv_flags ^= SA_RESTART;
2016151582Sps		error = copyout(&vec, uap->osv, sizeof(vec));
2017151582Sps	}
2018151582Sps	return (error);
2019151582Sps}
2020151582Sps
2021151582Spsint
2022151720Speterofreebsd32_sigblock(struct thread *td,
2023151720Speter			    struct ofreebsd32_sigblock_args *uap)
2024151582Sps{
2025151582Sps	struct proc *p = td->td_proc;
2026151582Sps	sigset_t set;
2027151582Sps
2028151582Sps	OSIG2SIG(uap->mask, set);
2029151582Sps	SIG_CANTMASK(set);
2030151582Sps	PROC_LOCK(p);
2031151582Sps	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
2032151582Sps	SIGSETOR(td->td_sigmask, set);
2033151582Sps	PROC_UNLOCK(p);
2034151582Sps	return (0);
2035151582Sps}
2036151582Sps
2037151582Spsint
2038151720Speterofreebsd32_sigsetmask(struct thread *td,
2039151720Speter			      struct ofreebsd32_sigsetmask_args *uap)
2040151582Sps{
2041151582Sps	struct proc *p = td->td_proc;
2042151582Sps	sigset_t set;
2043151582Sps
2044151582Sps	OSIG2SIG(uap->mask, set);
2045151582Sps	SIG_CANTMASK(set);
2046151582Sps	PROC_LOCK(p);
2047151582Sps	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
2048151582Sps	SIGSETLO(td->td_sigmask, set);
2049151582Sps	signotify(td);
2050151582Sps	PROC_UNLOCK(p);
2051151582Sps	return (0);
2052151582Sps}
2053151582Sps
2054151582Spsint
2055151720Speterofreebsd32_sigsuspend(struct thread *td,
2056151720Speter			      struct ofreebsd32_sigsuspend_args *uap)
2057151582Sps{
2058151582Sps	struct proc *p = td->td_proc;
2059151582Sps	sigset_t mask;
2060151582Sps
2061151582Sps	PROC_LOCK(p);
2062151582Sps	td->td_oldsigmask = td->td_sigmask;
2063151582Sps	td->td_pflags |= TDP_OLDMASK;
2064151582Sps	OSIG2SIG(uap->mask, mask);
2065151582Sps	SIG_CANTMASK(mask);
2066151582Sps	SIGSETLO(td->td_sigmask, mask);
2067151582Sps	signotify(td);
2068151582Sps	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
2069151582Sps		/* void */;
2070151582Sps	PROC_UNLOCK(p);
2071151582Sps	/* always return EINTR rather than ERESTART... */
2072151582Sps	return (EINTR);
2073151582Sps}
2074151582Sps
2075151582Spsstruct sigstack32 {
2076151582Sps	u_int32_t	ss_sp;
2077151582Sps	int		ss_onstack;
2078151582Sps};
2079151582Sps
2080151582Spsint
2081151720Speterofreebsd32_sigstack(struct thread *td,
2082151720Speter			    struct ofreebsd32_sigstack_args *uap)
2083151582Sps{
2084151582Sps	struct sigstack32 s32;
2085151582Sps	struct sigstack nss, oss;
2086170870Smjacob	int error = 0, unss;
2087151582Sps
2088151582Sps	if (uap->nss != NULL) {
2089151582Sps		error = copyin(uap->nss, &s32, sizeof(s32));
2090151582Sps		if (error)
2091151582Sps			return (error);
2092151582Sps		nss.ss_sp = PTRIN(s32.ss_sp);
2093151582Sps		CP(s32, nss, ss_onstack);
2094170870Smjacob		unss = 1;
2095170870Smjacob	} else {
2096170870Smjacob		unss = 0;
2097151582Sps	}
2098151582Sps	oss.ss_sp = td->td_sigstk.ss_sp;
2099151582Sps	oss.ss_onstack = sigonstack(cpu_getstack(td));
2100170870Smjacob	if (unss) {
2101151582Sps		td->td_sigstk.ss_sp = nss.ss_sp;
2102151582Sps		td->td_sigstk.ss_size = 0;
2103170870Smjacob		td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
2104151582Sps		td->td_pflags |= TDP_ALTSTACK;
2105151582Sps	}
2106151582Sps	if (uap->oss != NULL) {
2107151582Sps		s32.ss_sp = PTROUT(oss.ss_sp);
2108151582Sps		CP(oss, s32, ss_onstack);
2109151582Sps		error = copyout(&s32, uap->oss, sizeof(s32));
2110151582Sps	}
2111151582Sps	return (error);
2112151582Sps}
2113151582Sps#endif
2114151582Sps
2115151582Spsint
2116140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
2117140481Sps{
2118140481Sps	struct timespec32 rmt32, rqt32;
2119140481Sps	struct timespec rmt, rqt;
2120140481Sps	int error;
2121140481Sps
2122151355Sps	error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
2123140481Sps	if (error)
2124140481Sps		return (error);
2125140481Sps
2126140481Sps	CP(rqt32, rqt, tv_sec);
2127140481Sps	CP(rqt32, rqt, tv_nsec);
2128140481Sps
2129140481Sps	if (uap->rmtp &&
2130140481Sps	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
2131140481Sps		return (EFAULT);
2132140481Sps	error = kern_nanosleep(td, &rqt, &rmt);
2133140481Sps	if (error && uap->rmtp) {
2134140481Sps		int error2;
2135140481Sps
2136140481Sps		CP(rmt, rmt32, tv_sec);
2137140481Sps		CP(rmt, rmt32, tv_nsec);
2138140481Sps
2139151355Sps		error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
2140140481Sps		if (error2)
2141140481Sps			error = error2;
2142140481Sps	}
2143140481Sps	return (error);
2144140481Sps}
2145140481Sps
2146151357Spsint
2147151357Spsfreebsd32_clock_gettime(struct thread *td,
2148151357Sps			struct freebsd32_clock_gettime_args *uap)
2149151357Sps{
2150151357Sps	struct timespec	ats;
2151151357Sps	struct timespec32 ats32;
2152151357Sps	int error;
2153151357Sps
2154151357Sps	error = kern_clock_gettime(td, uap->clock_id, &ats);
2155151357Sps	if (error == 0) {
2156151357Sps		CP(ats, ats32, tv_sec);
2157151357Sps		CP(ats, ats32, tv_nsec);
2158151357Sps		error = copyout(&ats32, uap->tp, sizeof(ats32));
2159151357Sps	}
2160151357Sps	return (error);
2161151357Sps}
2162151357Sps
2163151357Spsint
2164151357Spsfreebsd32_clock_settime(struct thread *td,
2165151357Sps			struct freebsd32_clock_settime_args *uap)
2166151357Sps{
2167151357Sps	struct timespec	ats;
2168151357Sps	struct timespec32 ats32;
2169151357Sps	int error;
2170151357Sps
2171151357Sps	error = copyin(uap->tp, &ats32, sizeof(ats32));
2172151357Sps	if (error)
2173151357Sps		return (error);
2174151357Sps	CP(ats32, ats, tv_sec);
2175151357Sps	CP(ats32, ats, tv_nsec);
2176151357Sps
2177151357Sps	return (kern_clock_settime(td, uap->clock_id, &ats));
2178151357Sps}
2179151357Sps
2180151357Spsint
2181151357Spsfreebsd32_clock_getres(struct thread *td,
2182151357Sps		       struct freebsd32_clock_getres_args *uap)
2183151357Sps{
2184151357Sps	struct timespec	ts;
2185151357Sps	struct timespec32 ts32;
2186151357Sps	int error;
2187151357Sps
2188151357Sps	if (uap->tp == NULL)
2189151357Sps		return (0);
2190151357Sps	error = kern_clock_getres(td, uap->clock_id, &ts);
2191151357Sps	if (error == 0) {
2192151357Sps		CP(ts, ts32, tv_sec);
2193151357Sps		CP(ts, ts32, tv_nsec);
2194151357Sps		error = copyout(&ts32, uap->tp, sizeof(ts32));
2195151357Sps	}
2196151357Sps	return (error);
2197151357Sps}
2198151357Sps
2199162551Sdavidxuint
2200162551Sdavidxufreebsd32_thr_new(struct thread *td,
2201162551Sdavidxu		  struct freebsd32_thr_new_args *uap)
2202162551Sdavidxu{
2203162551Sdavidxu	struct thr_param32 param32;
2204162551Sdavidxu	struct thr_param param;
2205162551Sdavidxu	int error;
2206162551Sdavidxu
2207162551Sdavidxu	if (uap->param_size < 0 ||
2208162551Sdavidxu	    uap->param_size > sizeof(struct thr_param32))
2209162551Sdavidxu		return (EINVAL);
2210162551Sdavidxu	bzero(&param, sizeof(struct thr_param));
2211162551Sdavidxu	bzero(&param32, sizeof(struct thr_param32));
2212162551Sdavidxu	error = copyin(uap->param, &param32, uap->param_size);
2213162551Sdavidxu	if (error != 0)
2214162551Sdavidxu		return (error);
2215162551Sdavidxu	param.start_func = PTRIN(param32.start_func);
2216162551Sdavidxu	param.arg = PTRIN(param32.arg);
2217162551Sdavidxu	param.stack_base = PTRIN(param32.stack_base);
2218162551Sdavidxu	param.stack_size = param32.stack_size;
2219162551Sdavidxu	param.tls_base = PTRIN(param32.tls_base);
2220162551Sdavidxu	param.tls_size = param32.tls_size;
2221162551Sdavidxu	param.child_tid = PTRIN(param32.child_tid);
2222162551Sdavidxu	param.parent_tid = PTRIN(param32.parent_tid);
2223162551Sdavidxu	param.flags = param32.flags;
2224162551Sdavidxu	param.rtp = PTRIN(param32.rtp);
2225162551Sdavidxu	param.spare[0] = PTRIN(param32.spare[0]);
2226162551Sdavidxu	param.spare[1] = PTRIN(param32.spare[1]);
2227162551Sdavidxu	param.spare[2] = PTRIN(param32.spare[2]);
2228162551Sdavidxu
2229162551Sdavidxu	return (kern_thr_new(td, &param));
2230162551Sdavidxu}
2231162551Sdavidxu
2232162551Sdavidxuint
2233162551Sdavidxufreebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
2234162551Sdavidxu{
2235162551Sdavidxu	struct timespec32 ts32;
2236162551Sdavidxu	struct timespec ts, *tsp;
2237162551Sdavidxu	int error;
2238162551Sdavidxu
2239162551Sdavidxu	error = 0;
2240162551Sdavidxu	tsp = NULL;
2241162551Sdavidxu	if (uap->timeout != NULL) {
2242162551Sdavidxu		error = copyin((const void *)uap->timeout, (void *)&ts32,
2243162551Sdavidxu		    sizeof(struct timespec32));
2244162551Sdavidxu		if (error != 0)
2245162551Sdavidxu			return (error);
2246162551Sdavidxu		ts.tv_sec = ts32.tv_sec;
2247162551Sdavidxu		ts.tv_nsec = ts32.tv_nsec;
2248162551Sdavidxu		tsp = &ts;
2249162551Sdavidxu	}
2250162551Sdavidxu	return (kern_thr_suspend(td, tsp));
2251162551Sdavidxu}
2252162551Sdavidxu
2253163018Sdavidxuvoid
2254163018Sdavidxusiginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst)
2255163018Sdavidxu{
2256163018Sdavidxu	bzero(dst, sizeof(*dst));
2257163018Sdavidxu	dst->si_signo = src->si_signo;
2258163018Sdavidxu	dst->si_errno = src->si_errno;
2259163018Sdavidxu	dst->si_code = src->si_code;
2260163018Sdavidxu	dst->si_pid = src->si_pid;
2261163018Sdavidxu	dst->si_uid = src->si_uid;
2262163018Sdavidxu	dst->si_status = src->si_status;
2263163018Sdavidxu	dst->si_addr = dst->si_addr;
2264163018Sdavidxu	dst->si_value.sigval_int = src->si_value.sival_int;
2265163018Sdavidxu	dst->si_timerid = src->si_timerid;
2266163018Sdavidxu	dst->si_overrun = src->si_overrun;
2267163018Sdavidxu}
2268163018Sdavidxu
2269163018Sdavidxuint
2270163018Sdavidxufreebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
2271163018Sdavidxu{
2272163018Sdavidxu	struct timespec32 ts32;
2273163018Sdavidxu	struct timespec ts;
2274163018Sdavidxu	struct timespec *timeout;
2275163018Sdavidxu	sigset_t set;
2276163018Sdavidxu	ksiginfo_t ksi;
2277163018Sdavidxu	struct siginfo32 si32;
2278163018Sdavidxu	int error;
2279163018Sdavidxu
2280163018Sdavidxu	if (uap->timeout) {
2281163018Sdavidxu		error = copyin(uap->timeout, &ts32, sizeof(ts32));
2282163018Sdavidxu		if (error)
2283163018Sdavidxu			return (error);
2284163018Sdavidxu		ts.tv_sec = ts32.tv_sec;
2285163018Sdavidxu		ts.tv_nsec = ts32.tv_nsec;
2286163018Sdavidxu		timeout = &ts;
2287163018Sdavidxu	} else
2288163018Sdavidxu		timeout = NULL;
2289163018Sdavidxu
2290163018Sdavidxu	error = copyin(uap->set, &set, sizeof(set));
2291163018Sdavidxu	if (error)
2292163018Sdavidxu		return (error);
2293163018Sdavidxu
2294163018Sdavidxu	error = kern_sigtimedwait(td, set, &ksi, timeout);
2295163018Sdavidxu	if (error)
2296163018Sdavidxu		return (error);
2297163018Sdavidxu
2298163018Sdavidxu	if (uap->info) {
2299163018Sdavidxu		siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2300163018Sdavidxu		error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2301163018Sdavidxu	}
2302163018Sdavidxu
2303163018Sdavidxu	if (error == 0)
2304163018Sdavidxu		td->td_retval[0] = ksi.ksi_signo;
2305163018Sdavidxu	return (error);
2306163018Sdavidxu}
2307163018Sdavidxu
2308163018Sdavidxu/*
2309163018Sdavidxu * MPSAFE
2310163018Sdavidxu */
2311163018Sdavidxuint
2312163018Sdavidxufreebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
2313163018Sdavidxu{
2314163018Sdavidxu	ksiginfo_t ksi;
2315163018Sdavidxu	struct siginfo32 si32;
2316163018Sdavidxu	sigset_t set;
2317163018Sdavidxu	int error;
2318163018Sdavidxu
2319163018Sdavidxu	error = copyin(uap->set, &set, sizeof(set));
2320163018Sdavidxu	if (error)
2321163018Sdavidxu		return (error);
2322163018Sdavidxu
2323163018Sdavidxu	error = kern_sigtimedwait(td, set, &ksi, NULL);
2324163018Sdavidxu	if (error)
2325163018Sdavidxu		return (error);
2326163018Sdavidxu
2327163018Sdavidxu	if (uap->info) {
2328163018Sdavidxu		siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2329163018Sdavidxu		error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2330163018Sdavidxu	}
2331163018Sdavidxu	if (error == 0)
2332163018Sdavidxu		td->td_retval[0] = ksi.ksi_signo;
2333163018Sdavidxu	return (error);
2334163018Sdavidxu}
2335163018Sdavidxu
2336100384Speter#if 0
2337100384Speter
2338100384Speterint
2339119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
2340100384Speter{
2341100384Speter	int error;
2342100384Speter	struct yyy32 *p32, s32;
2343100384Speter	struct yyy *p = NULL, s;
2344100384Speter
2345147654Sjhb	if (uap->zzz) {
2346147654Sjhb		error = copyin(uap->zzz, &s32, sizeof(s32));
2347100384Speter		if (error)
2348100384Speter			return (error);
2349100384Speter		/* translate in */
2350147654Sjhb		p = &s;
2351100384Speter	}
2352147654Sjhb	error = kern_xxx(td, p);
2353100384Speter	if (error)
2354100384Speter		return (error);
2355147654Sjhb	if (uap->zzz) {
2356100384Speter		/* translate out */
2357100384Speter		error = copyout(&s32, p32, sizeof(s32));
2358100384Speter	}
2359100384Speter	return (error);
2360100384Speter}
2361100384Speter
2362100384Speter#endif
2363