freebsd32_misc.c revision 146583
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 146583 2005-05-24 17:52:14Z ps $");
29118031Sobrien
30104738Speter#include "opt_compat.h"
31104738Speter
32100384Speter#include <sys/param.h>
33100384Speter#include <sys/systm.h>
34100384Speter#include <sys/bus.h>
35100384Speter#include <sys/exec.h>
36100384Speter#include <sys/fcntl.h>
37100384Speter#include <sys/filedesc.h>
38123746Speter#include <sys/namei.h>
39100384Speter#include <sys/imgact.h>
40100384Speter#include <sys/kernel.h>
41100384Speter#include <sys/lock.h>
42100384Speter#include <sys/malloc.h>
43100384Speter#include <sys/file.h>		/* Must come after sys/malloc.h */
44100384Speter#include <sys/mman.h>
45100384Speter#include <sys/module.h>
46100384Speter#include <sys/mount.h>
47100384Speter#include <sys/mutex.h>
48100384Speter#include <sys/namei.h>
49100384Speter#include <sys/param.h>
50100384Speter#include <sys/proc.h>
51100384Speter#include <sys/reboot.h>
52100384Speter#include <sys/resource.h>
53100384Speter#include <sys/resourcevar.h>
54100384Speter#include <sys/selinfo.h>
55100384Speter#include <sys/pipe.h>		/* Must come after sys/selinfo.h */
56100384Speter#include <sys/signal.h>
57100384Speter#include <sys/signalvar.h>
58100384Speter#include <sys/socket.h>
59100384Speter#include <sys/socketvar.h>
60100384Speter#include <sys/stat.h>
61113859Sjhb#include <sys/syscallsubr.h>
62100384Speter#include <sys/sysctl.h>
63100384Speter#include <sys/sysent.h>
64100384Speter#include <sys/sysproto.h>
65100384Speter#include <sys/systm.h>
66100384Speter#include <sys/unistd.h>
67100384Speter#include <sys/vnode.h>
68127140Sjhb#include <sys/wait.h>
69100384Speter
70100384Speter#include <vm/vm.h>
71100384Speter#include <vm/vm_kern.h>
72100384Speter#include <vm/vm_param.h>
73100384Speter#include <vm/pmap.h>
74100384Speter#include <vm/vm_map.h>
75100384Speter#include <vm/vm_object.h>
76100384Speter#include <vm/vm_extern.h>
77100384Speter
78119333Speter#include <compat/freebsd32/freebsd32_util.h>
79119333Speter#include <compat/freebsd32/freebsd32.h>
80119333Speter#include <compat/freebsd32/freebsd32_proto.h>
81100384Speter
82121719SpeterCTASSERT(sizeof(struct timeval32) == 8);
83121719SpeterCTASSERT(sizeof(struct timespec32) == 8);
84121719SpeterCTASSERT(sizeof(struct statfs32) == 256);
85121719SpeterCTASSERT(sizeof(struct rusage32) == 72);
86121719Speter
87100384Speterint
88119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
89100384Speter{
90127140Sjhb	int error, status;
91127140Sjhb	struct rusage32 ru32;
92136152Sjhb	struct rusage ru, *rup;
93100384Speter
94136152Sjhb	if (uap->rusage != NULL)
95136152Sjhb		rup = &ru;
96136152Sjhb	else
97136152Sjhb		rup = NULL;
98136152Sjhb	error = kern_wait(td, uap->pid, &status, uap->options, rup);
99100384Speter	if (error)
100100384Speter		return (error);
101127140Sjhb	if (uap->status != NULL)
102127140Sjhb		error = copyout(&status, uap->status, sizeof(status));
103127140Sjhb	if (uap->rusage != NULL && error == 0) {
104100384Speter		TV_CP(ru, ru32, ru_utime);
105100384Speter		TV_CP(ru, ru32, ru_stime);
106100384Speter		CP(ru, ru32, ru_maxrss);
107100384Speter		CP(ru, ru32, ru_ixrss);
108100384Speter		CP(ru, ru32, ru_idrss);
109100384Speter		CP(ru, ru32, ru_isrss);
110100384Speter		CP(ru, ru32, ru_minflt);
111100384Speter		CP(ru, ru32, ru_majflt);
112100384Speter		CP(ru, ru32, ru_nswap);
113100384Speter		CP(ru, ru32, ru_inblock);
114100384Speter		CP(ru, ru32, ru_oublock);
115100384Speter		CP(ru, ru32, ru_msgsnd);
116100384Speter		CP(ru, ru32, ru_msgrcv);
117100384Speter		CP(ru, ru32, ru_nsignals);
118100384Speter		CP(ru, ru32, ru_nvcsw);
119100384Speter		CP(ru, ru32, ru_nivcsw);
120127140Sjhb		error = copyout(&ru32, uap->rusage, sizeof(ru32));
121100384Speter	}
122100384Speter	return (error);
123100384Speter}
124100384Speter
125128597Smarcel#ifdef COMPAT_FREEBSD4
126100384Speterstatic void
127100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
128100384Speter{
129100384Speter	CP(*in, *out, f_bsize);
130100384Speter	CP(*in, *out, f_iosize);
131100384Speter	CP(*in, *out, f_blocks);
132100384Speter	CP(*in, *out, f_bfree);
133100384Speter	CP(*in, *out, f_bavail);
134100384Speter	CP(*in, *out, f_files);
135100384Speter	CP(*in, *out, f_ffree);
136100384Speter	CP(*in, *out, f_fsid);
137100384Speter	CP(*in, *out, f_owner);
138100384Speter	CP(*in, *out, f_type);
139100384Speter	CP(*in, *out, f_flags);
140100384Speter	CP(*in, *out, f_flags);
141100384Speter	CP(*in, *out, f_syncwrites);
142100384Speter	CP(*in, *out, f_asyncwrites);
143100384Speter	bcopy(in->f_fstypename,
144100384Speter	      out->f_fstypename, MFSNAMELEN);
145100384Speter	bcopy(in->f_mntonname,
146128260Speter	      out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
147100384Speter	CP(*in, *out, f_syncreads);
148100384Speter	CP(*in, *out, f_asyncreads);
149100384Speter	bcopy(in->f_mntfromname,
150128260Speter	      out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
151100384Speter}
152128597Smarcel#endif
153100384Speter
154128597Smarcel#ifdef COMPAT_FREEBSD4
155100384Speterint
156128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
157100384Speter{
158100384Speter	int error;
159100384Speter	caddr_t sg;
160100384Speter	struct statfs32 *sp32, stat32;
161100384Speter	struct statfs *sp = NULL, stat;
162100384Speter	int maxcount, count, i;
163100384Speter
164107849Salfred	sp32 = uap->buf;
165107849Salfred	maxcount = uap->bufsize / sizeof(struct statfs32);
166100384Speter
167100384Speter	if (sp32) {
168100384Speter		sg = stackgap_init();
169100384Speter		sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
170107849Salfred		uap->buf = (struct statfs32 *)sp;
171100384Speter	}
172100384Speter	error = getfsstat(td, (struct getfsstat_args *) uap);
173100384Speter	if (sp32 && !error) {
174100384Speter		count = td->td_retval[0];
175100384Speter		for (i = 0; i < count; i++) {
176100384Speter			error = copyin(&sp[i], &stat, sizeof(stat));
177100384Speter			if (error)
178100384Speter				return (error);
179100384Speter			copy_statfs(&stat, &stat32);
180100384Speter			error = copyout(&stat32, &sp32[i], sizeof(stat32));
181100384Speter			if (error)
182100384Speter				return (error);
183100384Speter		}
184100384Speter	}
185100384Speter	return (error);
186100384Speter}
187128597Smarcel#endif
188100384Speter
189100384Speterstruct sigaltstack32 {
190100384Speter	u_int32_t	ss_sp;
191100384Speter	u_int32_t	ss_size;
192100384Speter	int		ss_flags;
193100384Speter};
194100384Speter
195121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12);
196121719Speter
197100384Speterint
198119333Speterfreebsd32_sigaltstack(struct thread *td,
199119333Speter		      struct freebsd32_sigaltstack_args *uap)
200100384Speter{
201113859Sjhb	struct sigaltstack32 s32;
202113859Sjhb	struct sigaltstack ss, oss, *ssp;
203100384Speter	int error;
204100384Speter
205113859Sjhb	if (uap->ss != NULL) {
206113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
207100384Speter		if (error)
208100384Speter			return (error);
209113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
210113859Sjhb		CP(s32, ss, ss_size);
211113859Sjhb		CP(s32, ss, ss_flags);
212113859Sjhb		ssp = &ss;
213113859Sjhb	} else
214113859Sjhb		ssp = NULL;
215113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
216113859Sjhb	if (error == 0 && uap->oss != NULL) {
217113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
218113859Sjhb		CP(oss, s32, ss_size);
219113859Sjhb		CP(oss, s32, ss_flags);
220113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
221100384Speter	}
222100384Speter	return (error);
223100384Speter}
224100384Speter
225142059Sjhb/*
226142059Sjhb * Custom version of exec_copyin_args() so that we can translate
227142059Sjhb * the pointers.
228142059Sjhb */
229142059Sjhbstatic int
230142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname,
231142059Sjhb    enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
232100384Speter{
233142059Sjhb	char *argp, *envp;
234142059Sjhb	u_int32_t *p32, arg;
235142059Sjhb	size_t length;
236100384Speter	int error;
237100384Speter
238142059Sjhb	bzero(args, sizeof(*args));
239142059Sjhb	if (argv == NULL)
240142059Sjhb		return (EFAULT);
241100384Speter
242142059Sjhb	/*
243142059Sjhb	 * Allocate temporary demand zeroed space for argument and
244142059Sjhb	 *	environment strings
245142059Sjhb	 */
246142059Sjhb	args->buf = (char *) kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX);
247142059Sjhb	if (args->buf == NULL)
248142059Sjhb		return (ENOMEM);
249142059Sjhb	args->begin_argv = args->buf;
250142059Sjhb	args->endp = args->begin_argv;
251142059Sjhb	args->stringspace = ARG_MAX;
252142059Sjhb
253142059Sjhb	args->fname = args->buf + ARG_MAX;
254142059Sjhb
255142059Sjhb	/*
256142059Sjhb	 * Copy the file name.
257142059Sjhb	 */
258142059Sjhb	error = (segflg == UIO_SYSSPACE) ?
259142059Sjhb	    copystr(fname, args->fname, PATH_MAX, &length) :
260142059Sjhb	    copyinstr(fname, args->fname, PATH_MAX, &length);
261142059Sjhb	if (error != 0)
262142059Sjhb		return (error);
263142059Sjhb
264142059Sjhb	/*
265142059Sjhb	 * extract arguments first
266142059Sjhb	 */
267142059Sjhb	p32 = argv;
268142059Sjhb	for (;;) {
269142059Sjhb		error = copyin(p32++, &arg, sizeof(arg));
270142059Sjhb		if (error)
271142059Sjhb			return (error);
272142059Sjhb		if (arg == 0)
273142059Sjhb			break;
274142059Sjhb		argp = PTRIN(arg);
275142059Sjhb		error = copyinstr(argp, args->endp, args->stringspace, &length);
276142059Sjhb		if (error) {
277142059Sjhb			if (error == ENAMETOOLONG)
278142059Sjhb				return (E2BIG);
279142059Sjhb			else
280142059Sjhb				return (error);
281142059Sjhb		}
282142059Sjhb		args->stringspace -= length;
283142059Sjhb		args->endp += length;
284142059Sjhb		args->argc++;
285100384Speter	}
286142059Sjhb
287142059Sjhb	args->begin_envv = args->endp;
288142059Sjhb
289142059Sjhb	/*
290142059Sjhb	 * extract environment strings
291142059Sjhb	 */
292142059Sjhb	if (envv) {
293142059Sjhb		p32 = envv;
294142059Sjhb		for (;;) {
295100384Speter			error = copyin(p32++, &arg, sizeof(arg));
296100384Speter			if (error)
297142059Sjhb				return (error);
298142059Sjhb			if (arg == 0)
299142059Sjhb				break;
300142059Sjhb			envp = PTRIN(arg);
301142059Sjhb			error = copyinstr(envp, args->endp, args->stringspace,
302142059Sjhb			    &length);
303142059Sjhb			if (error) {
304142059Sjhb				if (error == ENAMETOOLONG)
305142059Sjhb					return (E2BIG);
306142059Sjhb				else
307142059Sjhb					return (error);
308142059Sjhb			}
309142059Sjhb			args->stringspace -= length;
310142059Sjhb			args->endp += length;
311142059Sjhb			args->envc++;
312142059Sjhb		}
313100384Speter	}
314100384Speter
315142059Sjhb	return (0);
316100384Speter}
317100384Speter
318142059Sjhbint
319142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
320142059Sjhb{
321142059Sjhb	struct image_args eargs;
322142059Sjhb	int error;
323142059Sjhb
324142059Sjhb	error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
325142059Sjhb	    uap->argv, uap->envv);
326142059Sjhb	if (error == 0)
327142059Sjhb		error = kern_execve(td, &eargs, NULL);
328142059Sjhb	exec_free_args(&eargs);
329142059Sjhb	return (error);
330142059Sjhb}
331142059Sjhb
332114987Speter#ifdef __ia64__
333100384Speterstatic int
334119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
335119333Speter		       int prot, int fd, off_t pos)
336100384Speter{
337100384Speter	vm_map_t map;
338100384Speter	vm_map_entry_t entry;
339100384Speter	int rv;
340100384Speter
341100384Speter	map = &td->td_proc->p_vmspace->vm_map;
342100384Speter	if (fd != -1)
343100384Speter		prot |= VM_PROT_WRITE;
344100384Speter
345100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
346100384Speter		if ((entry->protection & prot) != prot) {
347100384Speter			rv = vm_map_protect(map,
348100384Speter					    trunc_page(start),
349100384Speter					    round_page(end),
350100384Speter					    entry->protection | prot,
351100384Speter					    FALSE);
352100384Speter			if (rv != KERN_SUCCESS)
353100384Speter				return (EINVAL);
354100384Speter		}
355100384Speter	} else {
356100384Speter		vm_offset_t addr = trunc_page(start);
357100384Speter		rv = vm_map_find(map, 0, 0,
358100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
359100384Speter				 VM_PROT_ALL, 0);
360100384Speter		if (rv != KERN_SUCCESS)
361100384Speter			return (EINVAL);
362100384Speter	}
363100384Speter
364100384Speter	if (fd != -1) {
365100384Speter		struct pread_args r;
366107849Salfred		r.fd = fd;
367107849Salfred		r.buf = (void *) start;
368107849Salfred		r.nbyte = end - start;
369107849Salfred		r.offset = pos;
370100384Speter		return (pread(td, &r));
371100384Speter	} else {
372100384Speter		while (start < end) {
373100384Speter			subyte((void *) start, 0);
374100384Speter			start++;
375100384Speter		}
376100384Speter		return (0);
377100384Speter	}
378100384Speter}
379114987Speter#endif
380100384Speter
381100384Speterint
382119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
383100384Speter{
384100384Speter	struct mmap_args ap;
385107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
386107849Salfred	vm_size_t len	 = uap->len;
387107849Salfred	int prot	 = uap->prot;
388107849Salfred	int flags	 = uap->flags;
389107849Salfred	int fd		 = uap->fd;
390107849Salfred	off_t pos	 = (uap->poslo
391107849Salfred			    | ((off_t)uap->poshi << 32));
392114987Speter#ifdef __ia64__
393100384Speter	vm_size_t pageoff;
394100384Speter	int error;
395100384Speter
396100384Speter	/*
397100384Speter	 * Attempt to handle page size hassles.
398100384Speter	 */
399100384Speter	pageoff = (pos & PAGE_MASK);
400100384Speter	if (flags & MAP_FIXED) {
401100384Speter		vm_offset_t start, end;
402100384Speter		start = addr;
403100384Speter		end = addr + len;
404100384Speter
405100384Speter		if (start != trunc_page(start)) {
406119333Speter			error = freebsd32_mmap_partial(td, start,
407119333Speter						       round_page(start), prot,
408119333Speter						       fd, pos);
409100384Speter			if (fd != -1)
410100384Speter				pos += round_page(start) - start;
411100384Speter			start = round_page(start);
412100384Speter		}
413100384Speter		if (end != round_page(end)) {
414100384Speter			vm_offset_t t = trunc_page(end);
415119333Speter			error = freebsd32_mmap_partial(td, t, end,
416100384Speter						  prot, fd,
417100384Speter						  pos + t - start);
418100384Speter			end = trunc_page(end);
419100384Speter		}
420100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
421100384Speter			/*
422100384Speter			 * We can't map this region at all. The specified
423100384Speter			 * address doesn't have the same alignment as the file
424100384Speter			 * position. Fake the mapping by simply reading the
425100384Speter			 * entire region into memory. First we need to make
426100384Speter			 * sure the region exists.
427100384Speter			 */
428100384Speter			vm_map_t map;
429100384Speter			struct pread_args r;
430100384Speter			int rv;
431100384Speter
432100384Speter			prot |= VM_PROT_WRITE;
433100384Speter			map = &td->td_proc->p_vmspace->vm_map;
434100384Speter			rv = vm_map_remove(map, start, end);
435100384Speter			if (rv != KERN_SUCCESS)
436100384Speter				return (EINVAL);
437100384Speter			rv = vm_map_find(map, 0, 0,
438100384Speter					 &start, end - start, FALSE,
439100384Speter					 prot, VM_PROT_ALL, 0);
440100384Speter			if (rv != KERN_SUCCESS)
441100384Speter				return (EINVAL);
442107849Salfred			r.fd = fd;
443107849Salfred			r.buf = (void *) start;
444107849Salfred			r.nbyte = end - start;
445107849Salfred			r.offset = pos;
446100384Speter			error = pread(td, &r);
447100384Speter			if (error)
448100384Speter				return (error);
449100384Speter
450100384Speter			td->td_retval[0] = addr;
451100384Speter			return (0);
452100384Speter		}
453100384Speter		if (end == start) {
454100384Speter			/*
455100384Speter			 * After dealing with the ragged ends, there
456100384Speter			 * might be none left.
457100384Speter			 */
458100384Speter			td->td_retval[0] = addr;
459100384Speter			return (0);
460100384Speter		}
461100384Speter		addr = start;
462100384Speter		len = end - start;
463100384Speter	}
464114987Speter#endif
465100384Speter
466107849Salfred	ap.addr = (void *) addr;
467107849Salfred	ap.len = len;
468107849Salfred	ap.prot = prot;
469107849Salfred	ap.flags = flags;
470107849Salfred	ap.fd = fd;
471107849Salfred	ap.pos = pos;
472100384Speter
473100384Speter	return (mmap(td, &ap));
474100384Speter}
475100384Speter
476100384Speterstruct itimerval32 {
477100384Speter	struct timeval32 it_interval;
478100384Speter	struct timeval32 it_value;
479100384Speter};
480100384Speter
481121719SpeterCTASSERT(sizeof(struct itimerval32) == 16);
482121719Speter
483100384Speterint
484119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
485100384Speter{
486142059Sjhb	struct itimerval itv, oitv, *itvp;
487142059Sjhb	struct itimerval32 i32;
488100384Speter	int error;
489100384Speter
490142059Sjhb	if (uap->itv != NULL) {
491142059Sjhb		error = copyin(uap->itv, &i32, sizeof(i32));
492100384Speter		if (error)
493100384Speter			return (error);
494142059Sjhb		TV_CP(i32, itv, it_interval);
495142059Sjhb		TV_CP(i32, itv, it_value);
496142059Sjhb		itvp = &itv;
497142059Sjhb	} else
498142059Sjhb		itvp = NULL;
499142059Sjhb	error = kern_setitimer(td, uap->which, itvp, &oitv);
500142059Sjhb	if (error || uap->oitv == NULL)
501100384Speter		return (error);
502142059Sjhb	TV_CP(oitv, i32, it_interval);
503142059Sjhb	TV_CP(oitv, i32, it_value);
504142059Sjhb	return (copyout(&i32, uap->oitv, sizeof(i32)));
505100384Speter}
506100384Speter
507100384Speterint
508125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
509125171Speter{
510142059Sjhb	struct itimerval itv;
511142059Sjhb	struct itimerval32 i32;
512125171Speter	int error;
513125171Speter
514142059Sjhb	error = kern_getitimer(td, uap->which, &itv);
515142059Sjhb	if (error || uap->itv == NULL)
516125171Speter		return (error);
517142059Sjhb	TV_CP(itv, i32, it_interval);
518142059Sjhb	TV_CP(itv, i32, it_value);
519142059Sjhb	return (copyout(&i32, uap->itv, sizeof(i32)));
520125171Speter}
521125171Speter
522125171Speterint
523119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
524100384Speter{
525142059Sjhb	struct timeval32 tv32;
526142059Sjhb	struct timeval tv, *tvp;
527100384Speter	int error;
528100384Speter
529142059Sjhb	if (uap->tv != NULL) {
530142059Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
531100384Speter		if (error)
532100384Speter			return (error);
533142059Sjhb		CP(tv32, tv, tv_sec);
534142059Sjhb		CP(tv32, tv, tv_usec);
535142059Sjhb		tvp = &tv;
536142059Sjhb	} else
537142059Sjhb		tvp = NULL;
538100384Speter	/*
539100384Speter	 * XXX big-endian needs to convert the fd_sets too.
540142059Sjhb	 * XXX Do pointers need PTRIN()?
541100384Speter	 */
542142059Sjhb	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
543100384Speter}
544100384Speter
545114987Speterstruct kevent32 {
546114987Speter	u_int32_t	ident;		/* identifier for this event */
547114987Speter	short		filter;		/* filter for event */
548114987Speter	u_short		flags;
549114987Speter	u_int		fflags;
550114987Speter	int32_t		data;
551114987Speter	u_int32_t	udata;		/* opaque user data identifier */
552114987Speter};
553114987Speter
554121719SpeterCTASSERT(sizeof(struct kevent32) == 20);
555121719Speter
556100384Speterint
557119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
558114987Speter{
559114987Speter	struct timespec32 ts32;
560142934Sps	struct timespec ts, *tsp;
561142934Sps	struct kevent *ks;
562114987Speter	struct kevent32 ks32;
563142934Sps	struct kevent *changes, *events;
564142934Sps	int error, i;
565114987Speter
566114987Speter
567114987Speter	if (uap->timeout) {
568114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
569114987Speter		if (error)
570114987Speter			return (error);
571114987Speter		CP(ts32, ts, tv_sec);
572114987Speter		CP(ts32, ts, tv_nsec);
573142934Sps		tsp = &ts;
574142934Sps	} else
575142934Sps		tsp = NULL;
576142934Sps	if (uap->changelist && uap->nchanges > 0) {
577142934Sps		changes = malloc(sizeof(struct kevent) * uap->nchanges, M_TEMP,
578142934Sps		    M_WAITOK);
579114987Speter		for (i = 0; i < uap->nchanges; i++) {
580119333Speter			error = copyin(&uap->changelist[i], &ks32,
581119333Speter			    sizeof(ks32));
582142934Sps			if (error) {
583142934Sps				free(changes, M_TEMP);
584114987Speter				return (error);
585142934Sps			}
586142934Sps			ks = &changes[i];
587114987Speter			CP(ks32, *ks, ident);
588114987Speter			CP(ks32, *ks, filter);
589114987Speter			CP(ks32, *ks, flags);
590114987Speter			CP(ks32, *ks, fflags);
591114987Speter			CP(ks32, *ks, data);
592114987Speter			PTRIN_CP(ks32, *ks, udata);
593114987Speter		}
594142934Sps	} else
595142934Sps		changes = NULL;
596142934Sps	if (uap->eventlist && uap->nevents > 0)
597142934Sps		events = malloc(sizeof(struct kevent) * uap->nevents, M_TEMP,
598142934Sps		    M_WAITOK);
599142934Sps	else
600142934Sps		events = NULL;
601142934Sps	error = kern_kevent(td, uap->fd, changes, uap->nchanges, UIO_SYSSPACE,
602142934Sps	    events, uap->nevents, UIO_SYSSPACE, tsp);
603142934Sps	free(changes, M_TEMP);
604142934Sps	if (uap->eventlist && events && td->td_retval[0] > 0) {
605142934Sps		for (i = 0; i < td->td_retval[0]; i++) {
606142934Sps			ks = &events[i];
607114987Speter			CP(*ks, ks32, ident);
608114987Speter			CP(*ks, ks32, filter);
609114987Speter			CP(*ks, ks32, flags);
610114987Speter			CP(*ks, ks32, fflags);
611114987Speter			CP(*ks, ks32, data);
612114987Speter			PTROUT_CP(*ks, ks32, udata);
613119333Speter			error = copyout(&ks32, &uap->eventlist[i],
614119333Speter			    sizeof(ks32));
615114987Speter			if (error)
616142934Sps				break;
617114987Speter		}
618114987Speter	}
619142934Sps	if (events)
620142934Sps		free(events, M_TEMP);
621142934Sps	return (error);
622114987Speter}
623114987Speter
624114987Speterint
625119333Speterfreebsd32_gettimeofday(struct thread *td,
626119333Speter		       struct freebsd32_gettimeofday_args *uap)
627100384Speter{
628123425Speter	struct timeval atv;
629123425Speter	struct timeval32 atv32;
630123425Speter	struct timezone rtz;
631123425Speter	int error = 0;
632100384Speter
633123425Speter	if (uap->tp) {
634123425Speter		microtime(&atv);
635123425Speter		CP(atv, atv32, tv_sec);
636123425Speter		CP(atv, atv32, tv_usec);
637123425Speter		error = copyout(&atv32, uap->tp, sizeof (atv32));
638100384Speter	}
639123425Speter	if (error == 0 && uap->tzp != NULL) {
640123425Speter		rtz.tz_minuteswest = tz_minuteswest;
641123425Speter		rtz.tz_dsttime = tz_dsttime;
642123425Speter		error = copyout(&rtz, uap->tzp, sizeof (rtz));
643100384Speter	}
644100384Speter	return (error);
645100384Speter}
646100384Speter
647100384Speterint
648119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
649100384Speter{
650136152Sjhb	struct rusage32 s32;
651136152Sjhb	struct rusage s;
652100384Speter	int error;
653100384Speter
654136152Sjhb	error = kern_getrusage(td, uap->who, &s);
655100384Speter	if (error)
656100384Speter		return (error);
657136152Sjhb	if (uap->rusage != NULL) {
658100384Speter		TV_CP(s, s32, ru_utime);
659100384Speter		TV_CP(s, s32, ru_stime);
660100384Speter		CP(s, s32, ru_maxrss);
661100384Speter		CP(s, s32, ru_ixrss);
662100384Speter		CP(s, s32, ru_idrss);
663100384Speter		CP(s, s32, ru_isrss);
664100384Speter		CP(s, s32, ru_minflt);
665100384Speter		CP(s, s32, ru_majflt);
666100384Speter		CP(s, s32, ru_nswap);
667100384Speter		CP(s, s32, ru_inblock);
668100384Speter		CP(s, s32, ru_oublock);
669100384Speter		CP(s, s32, ru_msgsnd);
670100384Speter		CP(s, s32, ru_msgrcv);
671100384Speter		CP(s, s32, ru_nsignals);
672100384Speter		CP(s, s32, ru_nvcsw);
673100384Speter		CP(s, s32, ru_nivcsw);
674136152Sjhb		error = copyout(&s32, uap->rusage, sizeof(s32));
675100384Speter	}
676100384Speter	return (error);
677100384Speter}
678100384Speter
679100384Speterstruct iovec32 {
680100384Speter	u_int32_t iov_base;
681100384Speter	int	iov_len;
682100384Speter};
683100384Speter
684121719SpeterCTASSERT(sizeof(struct iovec32) == 8);
685121719Speter
686144450Sjhbstatic int
687144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
688100384Speter{
689144450Sjhb	struct iovec32 iov32;
690144450Sjhb	struct iovec *iov;
691144450Sjhb	struct uio *uio;
692144450Sjhb	u_int iovlen;
693144450Sjhb	int error, i;
694100384Speter
695144450Sjhb	*uiop = NULL;
696144450Sjhb	if (iovcnt > UIO_MAXIOV)
697100384Speter		return (EINVAL);
698144450Sjhb	iovlen = iovcnt * sizeof(struct iovec);
699144450Sjhb	uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
700144450Sjhb	iov = (struct iovec *)(uio + 1);
701144450Sjhb	for (i = 0; i < iovcnt; i++) {
702144450Sjhb		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
703144450Sjhb		if (error) {
704144450Sjhb			free(uio, M_IOV);
705144450Sjhb			return (error);
706144450Sjhb		}
707144450Sjhb		iov[i].iov_base = PTRIN(iov32.iov_base);
708144450Sjhb		iov[i].iov_len = iov32.iov_len;
709100384Speter	}
710144450Sjhb	uio->uio_iov = iov;
711144450Sjhb	uio->uio_iovcnt = iovcnt;
712144450Sjhb	uio->uio_segflg = UIO_USERSPACE;
713144450Sjhb	uio->uio_offset = -1;
714144450Sjhb	uio->uio_resid = 0;
715144450Sjhb	for (i = 0; i < iovcnt; i++) {
716144450Sjhb		if (iov->iov_len > INT_MAX - uio->uio_resid) {
717144450Sjhb			free(uio, M_IOV);
718144450Sjhb			return (EINVAL);
719144450Sjhb		}
720144450Sjhb		uio->uio_resid += iov->iov_len;
721144450Sjhb		iov++;
722144450Sjhb	}
723144450Sjhb	*uiop = uio;
724144450Sjhb	return (0);
725144450Sjhb}
726100384Speter
727144450Sjhbint
728144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
729144450Sjhb{
730144450Sjhb	struct uio *auio;
731144450Sjhb	int error;
732100384Speter
733144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
734144450Sjhb	if (error)
735144450Sjhb		return (error);
736144450Sjhb	error = kern_readv(td, uap->fd, auio);
737144450Sjhb	free(auio, M_IOV);
738100384Speter	return (error);
739100384Speter}
740100384Speter
741100384Speterint
742119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
743100384Speter{
744144450Sjhb	struct uio *auio;
745144450Sjhb	int error;
746100384Speter
747144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
748144450Sjhb	if (error)
749144450Sjhb		return (error);
750144450Sjhb	error = kern_writev(td, uap->fd, auio);
751144450Sjhb	free(auio, M_IOV);
752100384Speter	return (error);
753100384Speter}
754100384Speter
755100384Speterint
756119333Speterfreebsd32_settimeofday(struct thread *td,
757119333Speter		       struct freebsd32_settimeofday_args *uap)
758100384Speter{
759144450Sjhb	struct timeval32 tv32;
760144450Sjhb	struct timeval tv, *tvp;
761144450Sjhb	struct timezone tz, *tzp;
762100384Speter	int error;
763100384Speter
764144450Sjhb	if (uap->tv) {
765144450Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
766100384Speter		if (error)
767100384Speter			return (error);
768144450Sjhb		CP(tv32, tv, tv_sec);
769144450Sjhb		CP(tv32, tv, tv_usec);
770144450Sjhb		tvp = &tv;
771144450Sjhb	} else
772144450Sjhb		tvp = NULL;
773144450Sjhb	if (uap->tzp) {
774144450Sjhb		error = copyin(uap->tzp, &tz, sizeof(tz));
775100384Speter		if (error)
776100384Speter			return (error);
777144450Sjhb		tzp = &tz;
778144450Sjhb	} else
779144450Sjhb		tzp = NULL;
780144450Sjhb	return (kern_settimeofday(td, tvp, tzp));
781100384Speter}
782100384Speter
783100384Speterint
784119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
785100384Speter{
786142059Sjhb	struct timeval32 s32[2];
787142059Sjhb	struct timeval s[2], *sp;
788100384Speter	int error;
789100384Speter
790142059Sjhb	if (uap->tptr != NULL) {
791142059Sjhb		error = copyin(uap->tptr, s32, sizeof(s32));
792100384Speter		if (error)
793100384Speter			return (error);
794100384Speter		CP(s32[0], s[0], tv_sec);
795100384Speter		CP(s32[0], s[0], tv_usec);
796100384Speter		CP(s32[1], s[1], tv_sec);
797100384Speter		CP(s32[1], s[1], tv_usec);
798142059Sjhb		sp = s;
799142059Sjhb	} else
800142059Sjhb		sp = NULL;
801142059Sjhb	return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
802100384Speter}
803100384Speter
804100384Speterint
805119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
806100384Speter{
807144450Sjhb	struct timeval32 tv32;
808144450Sjhb	struct timeval delta, olddelta, *deltap;
809100384Speter	int error;
810100384Speter
811144450Sjhb	if (uap->delta) {
812144450Sjhb		error = copyin(uap->delta, &tv32, sizeof(tv32));
813100384Speter		if (error)
814100384Speter			return (error);
815144450Sjhb		CP(tv32, delta, tv_sec);
816144450Sjhb		CP(tv32, delta, tv_usec);
817144450Sjhb		deltap = &delta;
818144450Sjhb	} else
819144450Sjhb		deltap = NULL;
820144450Sjhb	error = kern_adjtime(td, deltap, &olddelta);
821144450Sjhb	if (uap->olddelta && error == 0) {
822144450Sjhb		CP(olddelta, tv32, tv_sec);
823144450Sjhb		CP(olddelta, tv32, tv_usec);
824144450Sjhb		error = copyout(&tv32, uap->olddelta, sizeof(tv32));
825100384Speter	}
826100384Speter	return (error);
827100384Speter}
828100384Speter
829128597Smarcel#ifdef COMPAT_FREEBSD4
830100384Speterint
831128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
832100384Speter{
833142059Sjhb	struct statfs32 s32;
834142059Sjhb	struct statfs s;
835100384Speter	int error;
836100384Speter
837142059Sjhb	error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
838100384Speter	if (error)
839100384Speter		return (error);
840142059Sjhb	copy_statfs(&s, &s32);
841142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
842100384Speter}
843128597Smarcel#endif
844100384Speter
845128597Smarcel#ifdef COMPAT_FREEBSD4
846100384Speterint
847128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
848100384Speter{
849142059Sjhb	struct statfs32 s32;
850142059Sjhb	struct statfs s;
851100384Speter	int error;
852100384Speter
853142059Sjhb	error = kern_fstatfs(td, uap->fd, &s);
854100384Speter	if (error)
855100384Speter		return (error);
856142059Sjhb	copy_statfs(&s, &s32);
857142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
858100384Speter}
859128597Smarcel#endif
860100384Speter
861128597Smarcel#ifdef COMPAT_FREEBSD4
862100384Speterint
863128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
864128260Speter{
865142059Sjhb	struct statfs32 s32;
866142059Sjhb	struct statfs s;
867142059Sjhb	fhandle_t fh;
868128260Speter	int error;
869128260Speter
870142059Sjhb	if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
871142059Sjhb		return (error);
872142059Sjhb	error = kern_fhstatfs(td, fh, &s);
873128260Speter	if (error)
874128260Speter		return (error);
875142059Sjhb	copy_statfs(&s, &s32);
876142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
877128260Speter}
878128597Smarcel#endif
879128260Speter
880128260Speterint
881119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
882100384Speter{
883100384Speter	/*
884100384Speter	 * Vector through to semsys if it is loaded.
885100384Speter	 */
886100384Speter	return sysent[169].sy_call(td, uap);
887100384Speter}
888100384Speter
889100384Speterint
890119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
891100384Speter{
892100384Speter	/*
893100384Speter	 * Vector through to msgsys if it is loaded.
894100384Speter	 */
895100384Speter	return sysent[170].sy_call(td, uap);
896100384Speter}
897100384Speter
898100384Speterint
899119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
900100384Speter{
901100384Speter	/*
902100384Speter	 * Vector through to shmsys if it is loaded.
903100384Speter	 */
904100384Speter	return sysent[171].sy_call(td, uap);
905100384Speter}
906100384Speter
907100384Speterint
908119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
909100384Speter{
910100384Speter	struct pread_args ap;
911100384Speter
912107849Salfred	ap.fd = uap->fd;
913107849Salfred	ap.buf = uap->buf;
914107849Salfred	ap.nbyte = uap->nbyte;
915119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
916100384Speter	return (pread(td, &ap));
917100384Speter}
918100384Speter
919100384Speterint
920119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
921100384Speter{
922100384Speter	struct pwrite_args ap;
923100384Speter
924107849Salfred	ap.fd = uap->fd;
925107849Salfred	ap.buf = uap->buf;
926107849Salfred	ap.nbyte = uap->nbyte;
927119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
928100384Speter	return (pwrite(td, &ap));
929100384Speter}
930100384Speter
931100384Speterint
932119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
933100384Speter{
934100384Speter	int error;
935100384Speter	struct lseek_args ap;
936100384Speter	off_t pos;
937100384Speter
938107849Salfred	ap.fd = uap->fd;
939119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
940107849Salfred	ap.whence = uap->whence;
941100384Speter	error = lseek(td, &ap);
942100384Speter	/* Expand the quad return into two parts for eax and edx */
943100384Speter	pos = *(off_t *)(td->td_retval);
944100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
945100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
946100384Speter	return error;
947100384Speter}
948100384Speter
949100384Speterint
950119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
951100384Speter{
952100384Speter	struct truncate_args ap;
953100384Speter
954107849Salfred	ap.path = uap->path;
955119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
956100384Speter	return (truncate(td, &ap));
957100384Speter}
958100384Speter
959100384Speterint
960119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
961100384Speter{
962100384Speter	struct ftruncate_args ap;
963100384Speter
964107849Salfred	ap.fd = uap->fd;
965119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
966100384Speter	return (ftruncate(td, &ap));
967100384Speter}
968100384Speter
969104738Speter#ifdef COMPAT_FREEBSD4
970100384Speterint
971119333Speterfreebsd4_freebsd32_sendfile(struct thread *td,
972119333Speter    struct freebsd4_freebsd32_sendfile_args *uap)
973104738Speter{
974104738Speter	struct freebsd4_sendfile_args ap;
975104738Speter
976107849Salfred	ap.fd = uap->fd;
977107849Salfred	ap.s = uap->s;
978119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
979107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
980107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
981107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
982107849Salfred	ap.flags = uap->flags;
983104738Speter	return (freebsd4_sendfile(td, &ap));
984104738Speter}
985104738Speter#endif
986104738Speter
987104738Speterint
988119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
989100384Speter{
990100384Speter	struct sendfile_args ap;
991100384Speter
992107849Salfred	ap.fd = uap->fd;
993107849Salfred	ap.s = uap->s;
994119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
995107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
996107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
997107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
998107849Salfred	ap.flags = uap->flags;
999100384Speter	return (sendfile(td, &ap));
1000100384Speter}
1001100384Speter
1002100384Speterstruct stat32 {
1003130640Sphk	dev_t	st_dev;
1004100384Speter	ino_t	st_ino;
1005100384Speter	mode_t	st_mode;
1006100384Speter	nlink_t	st_nlink;
1007100384Speter	uid_t	st_uid;
1008100384Speter	gid_t	st_gid;
1009130640Sphk	dev_t	st_rdev;
1010100384Speter	struct timespec32 st_atimespec;
1011100384Speter	struct timespec32 st_mtimespec;
1012100384Speter	struct timespec32 st_ctimespec;
1013100384Speter	off_t	st_size;
1014100384Speter	int64_t	st_blocks;
1015100384Speter	u_int32_t st_blksize;
1016100384Speter	u_int32_t st_flags;
1017100384Speter	u_int32_t st_gen;
1018121719Speter	struct timespec32 st_birthtimespec;
1019121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1020121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1021100384Speter};
1022100384Speter
1023121719Speter
1024121719SpeterCTASSERT(sizeof(struct stat32) == 96);
1025121719Speter
1026100384Speterstatic void
1027100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1028100384Speter{
1029100384Speter	CP(*in, *out, st_dev);
1030100384Speter	CP(*in, *out, st_ino);
1031100384Speter	CP(*in, *out, st_mode);
1032100384Speter	CP(*in, *out, st_nlink);
1033100384Speter	CP(*in, *out, st_uid);
1034100384Speter	CP(*in, *out, st_gid);
1035100384Speter	CP(*in, *out, st_rdev);
1036100384Speter	TS_CP(*in, *out, st_atimespec);
1037100384Speter	TS_CP(*in, *out, st_mtimespec);
1038100384Speter	TS_CP(*in, *out, st_ctimespec);
1039100384Speter	CP(*in, *out, st_size);
1040100384Speter	CP(*in, *out, st_blocks);
1041100384Speter	CP(*in, *out, st_blksize);
1042100384Speter	CP(*in, *out, st_flags);
1043100384Speter	CP(*in, *out, st_gen);
1044100384Speter}
1045100384Speter
1046100384Speterint
1047119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1048100384Speter{
1049123746Speter	struct stat sb;
1050123746Speter	struct stat32 sb32;
1051100384Speter	int error;
1052100384Speter
1053142059Sjhb	error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1054100384Speter	if (error)
1055100384Speter		return (error);
1056123746Speter	copy_stat(&sb, &sb32);
1057123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1058100384Speter	return (error);
1059100384Speter}
1060100384Speter
1061100384Speterint
1062119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1063100384Speter{
1064123746Speter	struct stat ub;
1065123746Speter	struct stat32 ub32;
1066100384Speter	int error;
1067100384Speter
1068142059Sjhb	error = kern_fstat(td, uap->fd, &ub);
1069100384Speter	if (error)
1070100384Speter		return (error);
1071123746Speter	copy_stat(&ub, &ub32);
1072123746Speter	error = copyout(&ub32, uap->ub, sizeof(ub32));
1073100384Speter	return (error);
1074100384Speter}
1075100384Speter
1076100384Speterint
1077119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1078100384Speter{
1079123746Speter	struct stat sb;
1080123746Speter	struct stat32 sb32;
1081142059Sjhb	int error;
1082100384Speter
1083142059Sjhb	error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1084100384Speter	if (error)
1085100384Speter		return (error);
1086123746Speter	copy_stat(&sb, &sb32);
1087123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1088100384Speter	return (error);
1089100384Speter}
1090100384Speter
1091100384Speter/*
1092100384Speter * MPSAFE
1093100384Speter */
1094100384Speterint
1095119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1096100384Speter{
1097100384Speter	int error, name[CTL_MAXNAME];
1098100384Speter	size_t j, oldlen;
1099100384Speter
1100100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1101100384Speter		return (EINVAL);
1102136404Speter 	error = copyin(uap->name, name, uap->namelen * sizeof(int));
1103100384Speter 	if (error)
1104100384Speter		return (error);
1105100384Speter	mtx_lock(&Giant);
1106100384Speter	if (uap->oldlenp)
1107100384Speter		oldlen = fuword32(uap->oldlenp);
1108100384Speter	else
1109100384Speter		oldlen = 0;
1110100384Speter	error = userland_sysctl(td, name, uap->namelen,
1111100384Speter		uap->old, &oldlen, 1,
1112136404Speter		uap->new, uap->newlen, &j, SCTL_MASK32);
1113100384Speter	if (error && error != ENOMEM)
1114100384Speter		goto done2;
1115136404Speter	if (uap->oldlenp)
1116100384Speter		suword32(uap->oldlenp, j);
1117100384Speterdone2:
1118100384Speter	mtx_unlock(&Giant);
1119100384Speter	return (error);
1120100384Speter}
1121100384Speter
1122100384Speterstruct sigaction32 {
1123100384Speter	u_int32_t	sa_u;
1124100384Speter	int		sa_flags;
1125100384Speter	sigset_t	sa_mask;
1126100384Speter};
1127100384Speter
1128121719SpeterCTASSERT(sizeof(struct sigaction32) == 24);
1129121719Speter
1130100384Speterint
1131119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1132100384Speter{
1133113859Sjhb	struct sigaction32 s32;
1134113859Sjhb	struct sigaction sa, osa, *sap;
1135100384Speter	int error;
1136100384Speter
1137113859Sjhb	if (uap->act) {
1138113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1139100384Speter		if (error)
1140100384Speter			return (error);
1141113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1142113859Sjhb		CP(s32, sa, sa_flags);
1143113859Sjhb		CP(s32, sa, sa_mask);
1144113859Sjhb		sap = &sa;
1145113859Sjhb	} else
1146113859Sjhb		sap = NULL;
1147113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1148146583Sps	if (error == 0 && uap->oact != NULL) {
1149113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1150113859Sjhb		CP(osa, s32, sa_flags);
1151113859Sjhb		CP(osa, s32, sa_mask);
1152113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1153100384Speter	}
1154100384Speter	return (error);
1155100384Speter}
1156100384Speter
1157114987Speter#ifdef COMPAT_FREEBSD4
1158114987Speterint
1159119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1160119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1161114987Speter{
1162114987Speter	struct sigaction32 s32;
1163114987Speter	struct sigaction sa, osa, *sap;
1164114987Speter	int error;
1165114987Speter
1166114987Speter	if (uap->act) {
1167114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1168114987Speter		if (error)
1169114987Speter			return (error);
1170114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1171114987Speter		CP(s32, sa, sa_flags);
1172114987Speter		CP(s32, sa, sa_mask);
1173114987Speter		sap = &sa;
1174114987Speter	} else
1175114987Speter		sap = NULL;
1176114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1177146583Sps	if (error == 0 && uap->oact != NULL) {
1178114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1179114987Speter		CP(osa, s32, sa_flags);
1180114987Speter		CP(osa, s32, sa_mask);
1181114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1182114987Speter	}
1183114987Speter	return (error);
1184114987Speter}
1185114987Speter#endif
1186114987Speter
1187140481Spsint
1188140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
1189140481Sps{
1190140481Sps	struct timespec32 rmt32, rqt32;
1191140481Sps	struct timespec rmt, rqt;
1192140481Sps	int error;
1193140481Sps
1194140481Sps	error = copyin(uap->rqtp, &rqt32, sizeof(rqt));
1195140481Sps	if (error)
1196140481Sps		return (error);
1197140481Sps
1198140481Sps	CP(rqt32, rqt, tv_sec);
1199140481Sps	CP(rqt32, rqt, tv_nsec);
1200140481Sps
1201140481Sps	if (uap->rmtp &&
1202140481Sps	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
1203140481Sps		return (EFAULT);
1204140481Sps	error = kern_nanosleep(td, &rqt, &rmt);
1205140481Sps	if (error && uap->rmtp) {
1206140481Sps		int error2;
1207140481Sps
1208140481Sps		CP(rmt, rmt32, tv_sec);
1209140481Sps		CP(rmt, rmt32, tv_nsec);
1210140481Sps
1211140481Sps		error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt));
1212140481Sps		if (error2)
1213140481Sps			error = error2;
1214140481Sps	}
1215140481Sps	return (error);
1216140481Sps}
1217140481Sps
1218100384Speter#if 0
1219100384Speter
1220100384Speterint
1221119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
1222100384Speter{
1223100384Speter	int error;
1224100384Speter	caddr_t sg;
1225100384Speter	struct yyy32 *p32, s32;
1226100384Speter	struct yyy *p = NULL, s;
1227100384Speter
1228107849Salfred	p32 = uap->zzz;
1229100384Speter	if (p32) {
1230100384Speter		sg = stackgap_init();
1231100384Speter		p = stackgap_alloc(&sg, sizeof(struct yyy));
1232107849Salfred		uap->zzz = (struct yyy32 *)p;
1233100384Speter		error = copyin(p32, &s32, sizeof(s32));
1234100384Speter		if (error)
1235100384Speter			return (error);
1236100384Speter		/* translate in */
1237100384Speter		error = copyout(&s, p, sizeof(s));
1238100384Speter		if (error)
1239100384Speter			return (error);
1240100384Speter	}
1241100384Speter	error = xxx(td, (struct xxx_args *) uap);
1242100384Speter	if (error)
1243100384Speter		return (error);
1244100384Speter	if (p32) {
1245100384Speter		error = copyin(p, &s, sizeof(s));
1246100384Speter		if (error)
1247100384Speter			return (error);
1248100384Speter		/* translate out */
1249100384Speter		error = copyout(&s32, p32, sizeof(s32));
1250100384Speter	}
1251100384Speter	return (error);
1252100384Speter}
1253100384Speter
1254100384Speter#endif
1255