freebsd32_misc.c revision 119333
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 119333 2003-08-22 23:07:28Z peter $");
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>
38100384Speter#include <sys/imgact.h>
39100384Speter#include <sys/kernel.h>
40100384Speter#include <sys/lock.h>
41100384Speter#include <sys/malloc.h>
42100384Speter#include <sys/file.h>		/* Must come after sys/malloc.h */
43100384Speter#include <sys/mman.h>
44100384Speter#include <sys/module.h>
45100384Speter#include <sys/mount.h>
46100384Speter#include <sys/mutex.h>
47100384Speter#include <sys/namei.h>
48100384Speter#include <sys/param.h>
49100384Speter#include <sys/proc.h>
50100384Speter#include <sys/reboot.h>
51100384Speter#include <sys/resource.h>
52100384Speter#include <sys/resourcevar.h>
53100384Speter#include <sys/selinfo.h>
54100384Speter#include <sys/pipe.h>		/* Must come after sys/selinfo.h */
55100384Speter#include <sys/signal.h>
56100384Speter#include <sys/signalvar.h>
57100384Speter#include <sys/socket.h>
58100384Speter#include <sys/socketvar.h>
59100384Speter#include <sys/stat.h>
60113859Sjhb#include <sys/syscallsubr.h>
61100384Speter#include <sys/sysctl.h>
62100384Speter#include <sys/sysent.h>
63100384Speter#include <sys/sysproto.h>
64100384Speter#include <sys/systm.h>
65100384Speter#include <sys/unistd.h>
66100384Speter#include <sys/user.h>
67100384Speter#include <sys/utsname.h>
68100384Speter#include <sys/vnode.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
82119333Speterextern const char freebsd32_emul_path[];
83119333Speter
84100384Speter/*
85100384Speter * [ taken from the linux emulator ]
86100384Speter * Search an alternate path before passing pathname arguments on
87100384Speter * to system calls. Useful for keeping a separate 'emulation tree'.
88100384Speter *
89100384Speter * If cflag is set, we check if an attempt can be made to create
90100384Speter * the named file, i.e. we check if the directory it should
91100384Speter * be in exists.
92100384Speter */
93100384Speterint
94119333Speterfreebsd32_emul_find(td, sgp, prefix, path, pbuf, cflag)
95100384Speter	struct thread	*td;
96100384Speter	caddr_t		*sgp;		/* Pointer to stackgap memory */
97100384Speter	const char	*prefix;
98100384Speter	char		*path;
99100384Speter	char		**pbuf;
100100384Speter	int		cflag;
101100384Speter{
102100384Speter	int			error;
103100384Speter	size_t			len, sz;
104100384Speter	char			*buf, *cp, *ptr;
105100384Speter	struct ucred		*ucred;
106100384Speter	struct nameidata	nd;
107100384Speter	struct nameidata	ndroot;
108100384Speter	struct vattr		vat;
109100384Speter	struct vattr		vatroot;
110100384Speter
111111119Simp	buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
112100384Speter	*pbuf = path;
113100384Speter
114100384Speter	for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
115100384Speter		continue;
116100384Speter
117100384Speter	sz = MAXPATHLEN - (ptr - buf);
118100384Speter
119100384Speter	/*
120100384Speter	 * If sgp is not given then the path is already in kernel space
121100384Speter	 */
122100384Speter	if (sgp == NULL)
123100384Speter		error = copystr(path, ptr, sz, &len);
124100384Speter	else
125100384Speter		error = copyinstr(path, ptr, sz, &len);
126100384Speter
127100384Speter	if (error) {
128100384Speter		free(buf, M_TEMP);
129100384Speter		return error;
130100384Speter	}
131100384Speter
132100384Speter	if (*ptr != '/') {
133100384Speter		free(buf, M_TEMP);
134100384Speter		return EINVAL;
135100384Speter	}
136100384Speter
137100384Speter	/*
138100384Speter	 *  We know that there is a / somewhere in this pathname.
139100384Speter	 *  Search backwards for it, to find the file's parent dir
140100384Speter	 *  to see if it exists in the alternate tree. If it does,
141100384Speter	 *  and we want to create a file (cflag is set). We don't
142100384Speter	 *  need to worry about the root comparison in this case.
143100384Speter	 */
144100384Speter
145100384Speter	if (cflag) {
146100384Speter		for (cp = &ptr[len] - 1; *cp != '/'; cp--)
147100384Speter			;
148100384Speter		*cp = '\0';
149100384Speter
150100384Speter		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
151100384Speter
152100384Speter		if ((error = namei(&nd)) != 0) {
153100384Speter			free(buf, M_TEMP);
154100384Speter			return error;
155100384Speter		}
156100384Speter
157100384Speter		*cp = '/';
158100384Speter	} else {
159100384Speter		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
160100384Speter
161100384Speter		if ((error = namei(&nd)) != 0) {
162100384Speter			free(buf, M_TEMP);
163100384Speter			return error;
164100384Speter		}
165100384Speter
166100384Speter		/*
167119333Speter		 * We now compare the vnode of the freebsd32_root to the one
168100384Speter		 * vnode asked. If they resolve to be the same, then we
169100384Speter		 * ignore the match so that the real root gets used.
170100384Speter		 * This avoids the problem of traversing "../.." to find the
171100384Speter		 * root directory and never finding it, because "/" resolves
172100384Speter		 * to the emulation root directory. This is expensive :-(
173100384Speter		 */
174119333Speter		NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE,
175119333Speter		    freebsd32_emul_path, td);
176100384Speter
177100384Speter		if ((error = namei(&ndroot)) != 0) {
178100384Speter			/* Cannot happen! */
179100384Speter			free(buf, M_TEMP);
180100384Speter			vrele(nd.ni_vp);
181100384Speter			return error;
182100384Speter		}
183100384Speter
184100384Speter		ucred = td->td_ucred;
185100384Speter		if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) {
186100384Speter			goto bad;
187100384Speter		}
188100384Speter
189100384Speter		if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred,
190100384Speter		    td)) != 0) {
191100384Speter			goto bad;
192100384Speter		}
193100384Speter
194100384Speter		if (vat.va_fsid == vatroot.va_fsid &&
195100384Speter		    vat.va_fileid == vatroot.va_fileid) {
196100384Speter			error = ENOENT;
197100384Speter			goto bad;
198100384Speter		}
199100384Speter
200100384Speter	}
201100384Speter	if (sgp == NULL)
202100384Speter		*pbuf = buf;
203100384Speter	else {
204100384Speter		sz = &ptr[len] - buf;
205100384Speter		*pbuf = stackgap_alloc(sgp, sz + 1);
206100384Speter		error = copyout(buf, *pbuf, sz);
207100384Speter		free(buf, M_TEMP);
208100384Speter	}
209100384Speter
210100384Speter	vrele(nd.ni_vp);
211100384Speter	if (!cflag)
212100384Speter		vrele(ndroot.ni_vp);
213100384Speter
214100384Speter	return error;
215100384Speter
216100384Speterbad:
217100384Speter	vrele(ndroot.ni_vp);
218100384Speter	vrele(nd.ni_vp);
219100384Speter	free(buf, M_TEMP);
220100384Speter	return error;
221100384Speter}
222100384Speter
223100384Speterint
224119333Speterfreebsd32_open(struct thread *td, struct freebsd32_open_args *uap)
225100384Speter{
226100384Speter	caddr_t sg;
227100384Speter
228100384Speter	sg = stackgap_init();
229100384Speter	CHECKALTEXIST(td, &sg, uap->path);
230100384Speter
231100384Speter	return open(td, (struct open_args *) uap);
232100384Speter}
233100384Speter
234100384Speterint
235119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
236100384Speter{
237100384Speter	int error;
238100384Speter	caddr_t sg;
239100384Speter	struct rusage32 *rusage32, ru32;
240100384Speter	struct rusage *rusage = NULL, ru;
241100384Speter
242107849Salfred	rusage32 = uap->rusage;
243100384Speter	if (rusage32) {
244100384Speter		sg = stackgap_init();
245100384Speter		rusage = stackgap_alloc(&sg, sizeof(struct rusage));
246107849Salfred		uap->rusage = (struct rusage32 *)rusage;
247100384Speter	}
248100384Speter	error = wait4(td, (struct wait_args *)uap);
249100384Speter	if (error)
250100384Speter		return (error);
251100384Speter	if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) {
252100384Speter		TV_CP(ru, ru32, ru_utime);
253100384Speter		TV_CP(ru, ru32, ru_stime);
254100384Speter		CP(ru, ru32, ru_maxrss);
255100384Speter		CP(ru, ru32, ru_ixrss);
256100384Speter		CP(ru, ru32, ru_idrss);
257100384Speter		CP(ru, ru32, ru_isrss);
258100384Speter		CP(ru, ru32, ru_minflt);
259100384Speter		CP(ru, ru32, ru_majflt);
260100384Speter		CP(ru, ru32, ru_nswap);
261100384Speter		CP(ru, ru32, ru_inblock);
262100384Speter		CP(ru, ru32, ru_oublock);
263100384Speter		CP(ru, ru32, ru_msgsnd);
264100384Speter		CP(ru, ru32, ru_msgrcv);
265100384Speter		CP(ru, ru32, ru_nsignals);
266100384Speter		CP(ru, ru32, ru_nvcsw);
267100384Speter		CP(ru, ru32, ru_nivcsw);
268100384Speter		error = copyout(&ru32, rusage32, sizeof(ru32));
269100384Speter	}
270100384Speter	return (error);
271100384Speter}
272100384Speter
273100384Speterstatic void
274100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
275100384Speter{
276100384Speter	CP(*in, *out, f_bsize);
277100384Speter	CP(*in, *out, f_iosize);
278100384Speter	CP(*in, *out, f_blocks);
279100384Speter	CP(*in, *out, f_bfree);
280100384Speter	CP(*in, *out, f_bavail);
281100384Speter	CP(*in, *out, f_files);
282100384Speter	CP(*in, *out, f_ffree);
283100384Speter	CP(*in, *out, f_fsid);
284100384Speter	CP(*in, *out, f_owner);
285100384Speter	CP(*in, *out, f_type);
286100384Speter	CP(*in, *out, f_flags);
287100384Speter	CP(*in, *out, f_flags);
288100384Speter	CP(*in, *out, f_syncwrites);
289100384Speter	CP(*in, *out, f_asyncwrites);
290100384Speter	bcopy(in->f_fstypename,
291100384Speter	      out->f_fstypename, MFSNAMELEN);
292100384Speter	bcopy(in->f_mntonname,
293100384Speter	      out->f_mntonname, MNAMELEN);
294100384Speter	CP(*in, *out, f_syncreads);
295100384Speter	CP(*in, *out, f_asyncreads);
296100384Speter	bcopy(in->f_mntfromname,
297100384Speter	      out->f_mntfromname, MNAMELEN);
298100384Speter}
299100384Speter
300100384Speterint
301119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap)
302100384Speter{
303100384Speter	int error;
304100384Speter	caddr_t sg;
305100384Speter	struct statfs32 *sp32, stat32;
306100384Speter	struct statfs *sp = NULL, stat;
307100384Speter	int maxcount, count, i;
308100384Speter
309107849Salfred	sp32 = uap->buf;
310107849Salfred	maxcount = uap->bufsize / sizeof(struct statfs32);
311100384Speter
312100384Speter	if (sp32) {
313100384Speter		sg = stackgap_init();
314100384Speter		sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
315107849Salfred		uap->buf = (struct statfs32 *)sp;
316100384Speter	}
317100384Speter	error = getfsstat(td, (struct getfsstat_args *) uap);
318100384Speter	if (sp32 && !error) {
319100384Speter		count = td->td_retval[0];
320100384Speter		for (i = 0; i < count; i++) {
321100384Speter			error = copyin(&sp[i], &stat, sizeof(stat));
322100384Speter			if (error)
323100384Speter				return (error);
324100384Speter			copy_statfs(&stat, &stat32);
325100384Speter			error = copyout(&stat32, &sp32[i], sizeof(stat32));
326100384Speter			if (error)
327100384Speter				return (error);
328100384Speter		}
329100384Speter	}
330100384Speter	return (error);
331100384Speter}
332100384Speter
333100384Speterint
334119333Speterfreebsd32_access(struct thread *td, struct freebsd32_access_args *uap)
335100384Speter{
336100384Speter	caddr_t sg;
337100384Speter
338100384Speter	sg = stackgap_init();
339100384Speter	CHECKALTEXIST(td, &sg, uap->path);
340100384Speter
341100384Speter	return access(td, (struct access_args *)uap);
342100384Speter}
343100384Speter
344100384Speterint
345119333Speterfreebsd32_chflags(struct thread *td, struct freebsd32_chflags_args *uap)
346100384Speter{
347100384Speter	caddr_t sg;
348100384Speter
349100384Speter	sg = stackgap_init();
350100384Speter	CHECKALTEXIST(td, &sg, uap->path);
351100384Speter
352100384Speter	return chflags(td, (struct chflags_args *)uap);
353100384Speter}
354100384Speter
355100384Speterstruct sigaltstack32 {
356100384Speter	u_int32_t	ss_sp;
357100384Speter	u_int32_t	ss_size;
358100384Speter	int		ss_flags;
359100384Speter};
360100384Speter
361100384Speterint
362119333Speterfreebsd32_sigaltstack(struct thread *td,
363119333Speter		      struct freebsd32_sigaltstack_args *uap)
364100384Speter{
365113859Sjhb	struct sigaltstack32 s32;
366113859Sjhb	struct sigaltstack ss, oss, *ssp;
367100384Speter	int error;
368100384Speter
369113859Sjhb	if (uap->ss != NULL) {
370113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
371100384Speter		if (error)
372100384Speter			return (error);
373113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
374113859Sjhb		CP(s32, ss, ss_size);
375113859Sjhb		CP(s32, ss, ss_flags);
376113859Sjhb		ssp = &ss;
377113859Sjhb	} else
378113859Sjhb		ssp = NULL;
379113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
380113859Sjhb	if (error == 0 && uap->oss != NULL) {
381113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
382113859Sjhb		CP(oss, s32, ss_size);
383113859Sjhb		CP(oss, s32, ss_flags);
384113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
385100384Speter	}
386100384Speter	return (error);
387100384Speter}
388100384Speter
389100384Speterint
390119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
391100384Speter{
392100384Speter	int error;
393100384Speter	caddr_t sg;
394100384Speter	struct execve_args ap;
395100384Speter	u_int32_t *p32, arg;
396100384Speter	char **p;
397100384Speter	int count;
398100384Speter
399100384Speter	sg = stackgap_init();
400107849Salfred	CHECKALTEXIST(td, &sg, uap->fname);
401107849Salfred	ap.fname = uap->fname;
402100384Speter
403107849Salfred	if (uap->argv) {
404100384Speter		count = 0;
405107849Salfred		p32 = uap->argv;
406100384Speter		do {
407100384Speter			error = copyin(p32++, &arg, sizeof(arg));
408100384Speter			if (error)
409100384Speter				return error;
410100384Speter			count++;
411100384Speter		} while (arg != 0);
412100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
413107849Salfred		ap.argv = p;
414107849Salfred		p32 = uap->argv;
415100384Speter		do {
416100384Speter			error = copyin(p32++, &arg, sizeof(arg));
417100384Speter			if (error)
418100384Speter				return error;
419100384Speter			*p++ = PTRIN(arg);
420100384Speter		} while (arg != 0);
421100384Speter	}
422107849Salfred	if (uap->envv) {
423100384Speter		count = 0;
424107849Salfred		p32 = uap->envv;
425100384Speter		do {
426100384Speter			error = copyin(p32++, &arg, sizeof(arg));
427100384Speter			if (error)
428100384Speter				return error;
429100384Speter			count++;
430100384Speter		} while (arg != 0);
431100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
432107849Salfred		ap.envv = p;
433107849Salfred		p32 = uap->envv;
434100384Speter		do {
435100384Speter			error = copyin(p32++, &arg, sizeof(arg));
436100384Speter			if (error)
437100384Speter				return error;
438100384Speter			*p++ = PTRIN(arg);
439100384Speter		} while (arg != 0);
440100384Speter	}
441100384Speter
442100384Speter	return execve(td, &ap);
443100384Speter}
444100384Speter
445114987Speter#ifdef __ia64__
446100384Speterstatic int
447119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
448119333Speter		       int prot, int fd, off_t pos)
449100384Speter{
450100384Speter	vm_map_t map;
451100384Speter	vm_map_entry_t entry;
452100384Speter	int rv;
453100384Speter
454100384Speter	map = &td->td_proc->p_vmspace->vm_map;
455100384Speter	if (fd != -1)
456100384Speter		prot |= VM_PROT_WRITE;
457100384Speter
458100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
459100384Speter		if ((entry->protection & prot) != prot) {
460100384Speter			rv = vm_map_protect(map,
461100384Speter					    trunc_page(start),
462100384Speter					    round_page(end),
463100384Speter					    entry->protection | prot,
464100384Speter					    FALSE);
465100384Speter			if (rv != KERN_SUCCESS)
466100384Speter				return (EINVAL);
467100384Speter		}
468100384Speter	} else {
469100384Speter		vm_offset_t addr = trunc_page(start);
470100384Speter		rv = vm_map_find(map, 0, 0,
471100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
472100384Speter				 VM_PROT_ALL, 0);
473100384Speter		if (rv != KERN_SUCCESS)
474100384Speter			return (EINVAL);
475100384Speter	}
476100384Speter
477100384Speter	if (fd != -1) {
478100384Speter		struct pread_args r;
479107849Salfred		r.fd = fd;
480107849Salfred		r.buf = (void *) start;
481107849Salfred		r.nbyte = end - start;
482107849Salfred		r.offset = pos;
483100384Speter		return (pread(td, &r));
484100384Speter	} else {
485100384Speter		while (start < end) {
486100384Speter			subyte((void *) start, 0);
487100384Speter			start++;
488100384Speter		}
489100384Speter		return (0);
490100384Speter	}
491100384Speter}
492114987Speter#endif
493100384Speter
494100384Speterint
495119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
496100384Speter{
497100384Speter	struct mmap_args ap;
498107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
499107849Salfred	vm_size_t len	 = uap->len;
500107849Salfred	int prot	 = uap->prot;
501107849Salfred	int flags	 = uap->flags;
502107849Salfred	int fd		 = uap->fd;
503107849Salfred	off_t pos	 = (uap->poslo
504107849Salfred			    | ((off_t)uap->poshi << 32));
505114987Speter#ifdef __ia64__
506100384Speter	vm_size_t pageoff;
507100384Speter	int error;
508100384Speter
509100384Speter	/*
510100384Speter	 * Attempt to handle page size hassles.
511100384Speter	 */
512100384Speter	pageoff = (pos & PAGE_MASK);
513100384Speter	if (flags & MAP_FIXED) {
514100384Speter		vm_offset_t start, end;
515100384Speter		start = addr;
516100384Speter		end = addr + len;
517100384Speter
518100384Speter		if (start != trunc_page(start)) {
519119333Speter			error = freebsd32_mmap_partial(td, start,
520119333Speter						       round_page(start), prot,
521119333Speter						       fd, pos);
522100384Speter			if (fd != -1)
523100384Speter				pos += round_page(start) - start;
524100384Speter			start = round_page(start);
525100384Speter		}
526100384Speter		if (end != round_page(end)) {
527100384Speter			vm_offset_t t = trunc_page(end);
528119333Speter			error = freebsd32_mmap_partial(td, t, end,
529100384Speter						  prot, fd,
530100384Speter						  pos + t - start);
531100384Speter			end = trunc_page(end);
532100384Speter		}
533100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
534100384Speter			/*
535100384Speter			 * We can't map this region at all. The specified
536100384Speter			 * address doesn't have the same alignment as the file
537100384Speter			 * position. Fake the mapping by simply reading the
538100384Speter			 * entire region into memory. First we need to make
539100384Speter			 * sure the region exists.
540100384Speter			 */
541100384Speter			vm_map_t map;
542100384Speter			struct pread_args r;
543100384Speter			int rv;
544100384Speter
545100384Speter			prot |= VM_PROT_WRITE;
546100384Speter			map = &td->td_proc->p_vmspace->vm_map;
547100384Speter			rv = vm_map_remove(map, start, end);
548100384Speter			if (rv != KERN_SUCCESS)
549100384Speter				return (EINVAL);
550100384Speter			rv = vm_map_find(map, 0, 0,
551100384Speter					 &start, end - start, FALSE,
552100384Speter					 prot, VM_PROT_ALL, 0);
553100384Speter			if (rv != KERN_SUCCESS)
554100384Speter				return (EINVAL);
555107849Salfred			r.fd = fd;
556107849Salfred			r.buf = (void *) start;
557107849Salfred			r.nbyte = end - start;
558107849Salfred			r.offset = pos;
559100384Speter			error = pread(td, &r);
560100384Speter			if (error)
561100384Speter				return (error);
562100384Speter
563100384Speter			td->td_retval[0] = addr;
564100384Speter			return (0);
565100384Speter		}
566100384Speter		if (end == start) {
567100384Speter			/*
568100384Speter			 * After dealing with the ragged ends, there
569100384Speter			 * might be none left.
570100384Speter			 */
571100384Speter			td->td_retval[0] = addr;
572100384Speter			return (0);
573100384Speter		}
574100384Speter		addr = start;
575100384Speter		len = end - start;
576100384Speter	}
577114987Speter#endif
578100384Speter
579107849Salfred	ap.addr = (void *) addr;
580107849Salfred	ap.len = len;
581107849Salfred	ap.prot = prot;
582107849Salfred	ap.flags = flags;
583107849Salfred	ap.fd = fd;
584107849Salfred	ap.pos = pos;
585100384Speter
586100384Speter	return (mmap(td, &ap));
587100384Speter}
588100384Speter
589100384Speterstruct itimerval32 {
590100384Speter	struct timeval32 it_interval;
591100384Speter	struct timeval32 it_value;
592100384Speter};
593100384Speter
594100384Speterint
595119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
596100384Speter{
597100384Speter	int error;
598100384Speter	caddr_t sg;
599100384Speter	struct itimerval32 *p32, *op32, s32;
600100384Speter	struct itimerval *p = NULL, *op = NULL, s;
601100384Speter
602107849Salfred	p32 = uap->itv;
603100384Speter	if (p32) {
604100384Speter		sg = stackgap_init();
605100384Speter		p = stackgap_alloc(&sg, sizeof(struct itimerval));
606107849Salfred		uap->itv = (struct itimerval32 *)p;
607100384Speter		error = copyin(p32, &s32, sizeof(s32));
608100384Speter		if (error)
609100384Speter			return (error);
610100384Speter		TV_CP(s32, s, it_interval);
611100384Speter		TV_CP(s32, s, it_value);
612100384Speter		error = copyout(&s, p, sizeof(s));
613100384Speter		if (error)
614100384Speter			return (error);
615100384Speter	}
616107849Salfred	op32 = uap->oitv;
617100384Speter	if (op32) {
618100384Speter		sg = stackgap_init();
619100384Speter		op = stackgap_alloc(&sg, sizeof(struct itimerval));
620107849Salfred		uap->oitv = (struct itimerval32 *)op;
621100384Speter	}
622100384Speter	error = setitimer(td, (struct setitimer_args *) uap);
623100384Speter	if (error)
624100384Speter		return (error);
625100384Speter	if (op32) {
626100384Speter		error = copyin(op, &s, sizeof(s));
627100384Speter		if (error)
628100384Speter			return (error);
629100384Speter		TV_CP(s, s32, it_interval);
630100384Speter		TV_CP(s, s32, it_value);
631100384Speter		error = copyout(&s32, op32, sizeof(s32));
632100384Speter	}
633100384Speter	return (error);
634100384Speter}
635100384Speter
636100384Speterint
637119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
638100384Speter{
639100384Speter	int error;
640100384Speter	caddr_t sg;
641100384Speter	struct timeval32 *p32, s32;
642100384Speter	struct timeval *p = NULL, s;
643100384Speter
644107849Salfred	p32 = uap->tv;
645100384Speter	if (p32) {
646100384Speter		sg = stackgap_init();
647100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
648107849Salfred		uap->tv = (struct timeval32 *)p;
649100384Speter		error = copyin(p32, &s32, sizeof(s32));
650100384Speter		if (error)
651100384Speter			return (error);
652100384Speter		CP(s32, s, tv_sec);
653100384Speter		CP(s32, s, tv_usec);
654100384Speter		error = copyout(&s, p, sizeof(s));
655100384Speter		if (error)
656100384Speter			return (error);
657100384Speter	}
658100384Speter	/*
659100384Speter	 * XXX big-endian needs to convert the fd_sets too.
660100384Speter	 */
661100384Speter	return (select(td, (struct select_args *) uap));
662100384Speter}
663100384Speter
664114987Speterstruct kevent32 {
665114987Speter	u_int32_t	ident;		/* identifier for this event */
666114987Speter	short		filter;		/* filter for event */
667114987Speter	u_short		flags;
668114987Speter	u_int		fflags;
669114987Speter	int32_t		data;
670114987Speter	u_int32_t	udata;		/* opaque user data identifier */
671114987Speter};
672114987Speter
673100384Speterint
674119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
675114987Speter{
676114987Speter	int error;
677114987Speter	caddr_t sg;
678114987Speter	struct timespec32 ts32;
679114987Speter	struct timespec ts;
680114987Speter	struct kevent32 ks32;
681114987Speter	struct kevent *ks;
682114987Speter	struct kevent_args a;
683114987Speter	int i;
684114987Speter
685114987Speter	sg = stackgap_init();
686114987Speter
687114987Speter	a.fd = uap->fd;
688114987Speter	a.changelist = uap->changelist;
689114987Speter	a.nchanges = uap->nchanges;
690114987Speter	a.eventlist = uap->eventlist;
691114987Speter	a.nevents = uap->nevents;
692114987Speter	a.timeout = NULL;
693114987Speter
694114987Speter	if (uap->timeout) {
695114987Speter		a.timeout = stackgap_alloc(&sg, sizeof(struct timespec));
696114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
697114987Speter		if (error)
698114987Speter			return (error);
699114987Speter		CP(ts32, ts, tv_sec);
700114987Speter		CP(ts32, ts, tv_nsec);
701114987Speter		error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts));
702114987Speter		if (error)
703114987Speter			return (error);
704114987Speter	}
705114987Speter	if (uap->changelist) {
706119333Speter		a.changelist = (struct kevent *)stackgap_alloc(&sg,
707119333Speter		    uap->nchanges * sizeof(struct kevent));
708114987Speter		for (i = 0; i < uap->nchanges; i++) {
709119333Speter			error = copyin(&uap->changelist[i], &ks32,
710119333Speter			    sizeof(ks32));
711114987Speter			if (error)
712114987Speter				return (error);
713114987Speter			ks = (struct kevent *)(uintptr_t)&a.changelist[i];
714114987Speter			CP(ks32, *ks, ident);
715114987Speter			CP(ks32, *ks, filter);
716114987Speter			CP(ks32, *ks, flags);
717114987Speter			CP(ks32, *ks, fflags);
718114987Speter			CP(ks32, *ks, data);
719114987Speter			PTRIN_CP(ks32, *ks, udata);
720114987Speter		}
721114987Speter	}
722114987Speter	if (uap->eventlist) {
723119333Speter		a.eventlist = stackgap_alloc(&sg,
724119333Speter		    uap->nevents * sizeof(struct kevent));
725114987Speter	}
726114987Speter	error = kevent(td, &a);
727114987Speter	if (uap->eventlist && error > 0) {
728114987Speter		for (i = 0; i < error; i++) {
729114987Speter			ks = &a.eventlist[i];
730114987Speter			CP(*ks, ks32, ident);
731114987Speter			CP(*ks, ks32, filter);
732114987Speter			CP(*ks, ks32, flags);
733114987Speter			CP(*ks, ks32, fflags);
734114987Speter			CP(*ks, ks32, data);
735114987Speter			PTROUT_CP(*ks, ks32, udata);
736119333Speter			error = copyout(&ks32, &uap->eventlist[i],
737119333Speter			    sizeof(ks32));
738114987Speter			if (error)
739114987Speter				return (error);
740114987Speter		}
741114987Speter	}
742114987Speter	return error;
743114987Speter}
744114987Speter
745114987Speterint
746119333Speterfreebsd32_gettimeofday(struct thread *td,
747119333Speter		       struct freebsd32_gettimeofday_args *uap)
748100384Speter{
749100384Speter	int error;
750100384Speter	caddr_t sg;
751100384Speter	struct timeval32 *p32, s32;
752100384Speter	struct timeval *p = NULL, s;
753100384Speter
754107849Salfred	p32 = uap->tp;
755100384Speter	if (p32) {
756100384Speter		sg = stackgap_init();
757100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
758107849Salfred		uap->tp = (struct timeval32 *)p;
759100384Speter	}
760100384Speter	error = gettimeofday(td, (struct gettimeofday_args *) uap);
761100384Speter	if (error)
762100384Speter		return (error);
763100384Speter	if (p32) {
764100384Speter		error = copyin(p, &s, sizeof(s));
765100384Speter		if (error)
766100384Speter			return (error);
767100384Speter		CP(s, s32, tv_sec);
768100384Speter		CP(s, s32, tv_usec);
769100384Speter		error = copyout(&s32, p32, sizeof(s32));
770100384Speter		if (error)
771100384Speter			return (error);
772100384Speter	}
773100384Speter	return (error);
774100384Speter}
775100384Speter
776100384Speterint
777119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
778100384Speter{
779100384Speter	int error;
780100384Speter	caddr_t sg;
781100384Speter	struct rusage32 *p32, s32;
782100384Speter	struct rusage *p = NULL, s;
783100384Speter
784107849Salfred	p32 = uap->rusage;
785100384Speter	if (p32) {
786100384Speter		sg = stackgap_init();
787100384Speter		p = stackgap_alloc(&sg, sizeof(struct rusage));
788107849Salfred		uap->rusage = (struct rusage32 *)p;
789100384Speter	}
790100384Speter	error = getrusage(td, (struct getrusage_args *) uap);
791100384Speter	if (error)
792100384Speter		return (error);
793100384Speter	if (p32) {
794100384Speter		error = copyin(p, &s, sizeof(s));
795100384Speter		if (error)
796100384Speter			return (error);
797100384Speter		TV_CP(s, s32, ru_utime);
798100384Speter		TV_CP(s, s32, ru_stime);
799100384Speter		CP(s, s32, ru_maxrss);
800100384Speter		CP(s, s32, ru_ixrss);
801100384Speter		CP(s, s32, ru_idrss);
802100384Speter		CP(s, s32, ru_isrss);
803100384Speter		CP(s, s32, ru_minflt);
804100384Speter		CP(s, s32, ru_majflt);
805100384Speter		CP(s, s32, ru_nswap);
806100384Speter		CP(s, s32, ru_inblock);
807100384Speter		CP(s, s32, ru_oublock);
808100384Speter		CP(s, s32, ru_msgsnd);
809100384Speter		CP(s, s32, ru_msgrcv);
810100384Speter		CP(s, s32, ru_nsignals);
811100384Speter		CP(s, s32, ru_nvcsw);
812100384Speter		CP(s, s32, ru_nivcsw);
813100384Speter		error = copyout(&s32, p32, sizeof(s32));
814100384Speter	}
815100384Speter	return (error);
816100384Speter}
817100384Speter
818100384Speterstruct iovec32 {
819100384Speter	u_int32_t iov_base;
820100384Speter	int	iov_len;
821100384Speter};
822100384Speter#define	STACKGAPLEN	400
823100384Speter
824100384Speterint
825119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
826100384Speter{
827100384Speter	int error, osize, nsize, i;
828100384Speter	caddr_t sg;
829100384Speter	struct readv_args /* {
830100384Speter		syscallarg(int) fd;
831100384Speter		syscallarg(struct iovec *) iovp;
832100384Speter		syscallarg(u_int) iovcnt;
833100384Speter	} */ a;
834100384Speter	struct iovec32 *oio;
835100384Speter	struct iovec *nio;
836100384Speter
837100384Speter	sg = stackgap_init();
838100384Speter
839107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
840100384Speter		return (EINVAL);
841100384Speter
842107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
843107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
844100384Speter
845111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
846111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
847100384Speter
848100384Speter	error = 0;
849107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
850100384Speter		goto punt;
851107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
852100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
853100384Speter		nio[i].iov_len = oio[i].iov_len;
854100384Speter	}
855100384Speter
856107849Salfred	a.fd = uap->fd;
857107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
858107849Salfred	a.iovcnt = uap->iovcnt;
859100384Speter
860107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
861100384Speter		goto punt;
862100384Speter	error = readv(td, &a);
863100384Speter
864100384Speterpunt:
865100384Speter	free(oio, M_TEMP);
866100384Speter	free(nio, M_TEMP);
867100384Speter	return (error);
868100384Speter}
869100384Speter
870100384Speterint
871119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
872100384Speter{
873100384Speter	int error, i, nsize, osize;
874100384Speter	caddr_t sg;
875100384Speter	struct writev_args /* {
876100384Speter		syscallarg(int) fd;
877100384Speter		syscallarg(struct iovec *) iovp;
878100384Speter		syscallarg(u_int) iovcnt;
879100384Speter	} */ a;
880100384Speter	struct iovec32 *oio;
881100384Speter	struct iovec *nio;
882100384Speter
883100384Speter	sg = stackgap_init();
884100384Speter
885107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
886100384Speter		return (EINVAL);
887100384Speter
888107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
889107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
890100384Speter
891111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
892111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
893100384Speter
894100384Speter	error = 0;
895107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
896100384Speter		goto punt;
897107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
898100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
899100384Speter		nio[i].iov_len = oio[i].iov_len;
900100384Speter	}
901100384Speter
902107849Salfred	a.fd = uap->fd;
903107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
904107849Salfred	a.iovcnt = uap->iovcnt;
905100384Speter
906107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
907100384Speter		goto punt;
908100384Speter	error = writev(td, &a);
909100384Speter
910100384Speterpunt:
911100384Speter	free(oio, M_TEMP);
912100384Speter	free(nio, M_TEMP);
913100384Speter	return (error);
914100384Speter}
915100384Speter
916100384Speterint
917119333Speterfreebsd32_settimeofday(struct thread *td,
918119333Speter		       struct freebsd32_settimeofday_args *uap)
919100384Speter{
920100384Speter	int error;
921100384Speter	caddr_t sg;
922100384Speter	struct timeval32 *p32, s32;
923100384Speter	struct timeval *p = NULL, s;
924100384Speter
925107849Salfred	p32 = uap->tv;
926100384Speter	if (p32) {
927100384Speter		sg = stackgap_init();
928100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
929107849Salfred		uap->tv = (struct timeval32 *)p;
930100384Speter		error = copyin(p32, &s32, sizeof(s32));
931100384Speter		if (error)
932100384Speter			return (error);
933100384Speter		CP(s32, s, tv_sec);
934100384Speter		CP(s32, s, tv_usec);
935100384Speter		error = copyout(&s, p, sizeof(s));
936100384Speter		if (error)
937100384Speter			return (error);
938100384Speter	}
939100384Speter	return (settimeofday(td, (struct settimeofday_args *) uap));
940100384Speter}
941100384Speter
942100384Speterint
943119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
944100384Speter{
945100384Speter	int error;
946100384Speter	caddr_t sg;
947100384Speter	struct timeval32 *p32, s32[2];
948100384Speter	struct timeval *p = NULL, s[2];
949100384Speter
950107849Salfred	p32 = uap->tptr;
951100384Speter	if (p32) {
952100384Speter		sg = stackgap_init();
953100384Speter		p = stackgap_alloc(&sg, 2*sizeof(struct timeval));
954107849Salfred		uap->tptr = (struct timeval32 *)p;
955100384Speter		error = copyin(p32, s32, sizeof(s32));
956100384Speter		if (error)
957100384Speter			return (error);
958100384Speter		CP(s32[0], s[0], tv_sec);
959100384Speter		CP(s32[0], s[0], tv_usec);
960100384Speter		CP(s32[1], s[1], tv_sec);
961100384Speter		CP(s32[1], s[1], tv_usec);
962100384Speter		error = copyout(s, p, sizeof(s));
963100384Speter		if (error)
964100384Speter			return (error);
965100384Speter	}
966100384Speter	return (utimes(td, (struct utimes_args *) uap));
967100384Speter}
968100384Speter
969100384Speterint
970119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
971100384Speter{
972100384Speter	int error;
973100384Speter	caddr_t sg;
974100384Speter	struct timeval32 *p32, *op32, s32;
975100384Speter	struct timeval *p = NULL, *op = NULL, s;
976100384Speter
977107849Salfred	p32 = uap->delta;
978100384Speter	if (p32) {
979100384Speter		sg = stackgap_init();
980100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
981107849Salfred		uap->delta = (struct timeval32 *)p;
982100384Speter		error = copyin(p32, &s32, sizeof(s32));
983100384Speter		if (error)
984100384Speter			return (error);
985100384Speter		CP(s32, s, tv_sec);
986100384Speter		CP(s32, s, tv_usec);
987100384Speter		error = copyout(&s, p, sizeof(s));
988100384Speter		if (error)
989100384Speter			return (error);
990100384Speter	}
991107849Salfred	op32 = uap->olddelta;
992100384Speter	if (op32) {
993100384Speter		sg = stackgap_init();
994100384Speter		op = stackgap_alloc(&sg, sizeof(struct timeval));
995107849Salfred		uap->olddelta = (struct timeval32 *)op;
996100384Speter	}
997100384Speter	error = utimes(td, (struct utimes_args *) uap);
998100384Speter	if (error)
999100384Speter		return error;
1000100384Speter	if (op32) {
1001100384Speter		error = copyin(op, &s, sizeof(s));
1002100384Speter		if (error)
1003100384Speter			return (error);
1004100384Speter		CP(s, s32, tv_sec);
1005100384Speter		CP(s, s32, tv_usec);
1006100384Speter		error = copyout(&s32, op32, sizeof(s32));
1007100384Speter	}
1008100384Speter	return (error);
1009100384Speter}
1010100384Speter
1011100384Speterint
1012119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap)
1013100384Speter{
1014100384Speter	int error;
1015100384Speter	caddr_t sg;
1016100384Speter	struct statfs32 *p32, s32;
1017100384Speter	struct statfs *p = NULL, s;
1018100384Speter
1019107849Salfred	p32 = uap->buf;
1020100384Speter	if (p32) {
1021100384Speter		sg = stackgap_init();
1022100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
1023107849Salfred		uap->buf = (struct statfs32 *)p;
1024100384Speter	}
1025100384Speter	error = statfs(td, (struct statfs_args *) uap);
1026100384Speter	if (error)
1027100384Speter		return (error);
1028100384Speter	if (p32) {
1029100384Speter		error = copyin(p, &s, sizeof(s));
1030100384Speter		if (error)
1031100384Speter			return (error);
1032100384Speter		copy_statfs(&s, &s32);
1033100384Speter		error = copyout(&s32, p32, sizeof(s32));
1034100384Speter	}
1035100384Speter	return (error);
1036100384Speter}
1037100384Speter
1038100384Speterint
1039119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap)
1040100384Speter{
1041100384Speter	int error;
1042100384Speter	caddr_t sg;
1043100384Speter	struct statfs32 *p32, s32;
1044100384Speter	struct statfs *p = NULL, s;
1045100384Speter
1046107849Salfred	p32 = uap->buf;
1047100384Speter	if (p32) {
1048100384Speter		sg = stackgap_init();
1049100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
1050107849Salfred		uap->buf = (struct statfs32 *)p;
1051100384Speter	}
1052100384Speter	error = fstatfs(td, (struct fstatfs_args *) uap);
1053100384Speter	if (error)
1054100384Speter		return (error);
1055100384Speter	if (p32) {
1056100384Speter		error = copyin(p, &s, sizeof(s));
1057100384Speter		if (error)
1058100384Speter			return (error);
1059100384Speter		copy_statfs(&s, &s32);
1060100384Speter		error = copyout(&s32, p32, sizeof(s32));
1061100384Speter	}
1062100384Speter	return (error);
1063100384Speter}
1064100384Speter
1065100384Speterint
1066119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1067100384Speter{
1068100384Speter	/*
1069100384Speter	 * Vector through to semsys if it is loaded.
1070100384Speter	 */
1071100384Speter	return sysent[169].sy_call(td, uap);
1072100384Speter}
1073100384Speter
1074100384Speterint
1075119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1076100384Speter{
1077100384Speter	/*
1078100384Speter	 * Vector through to msgsys if it is loaded.
1079100384Speter	 */
1080100384Speter	return sysent[170].sy_call(td, uap);
1081100384Speter}
1082100384Speter
1083100384Speterint
1084119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1085100384Speter{
1086100384Speter	/*
1087100384Speter	 * Vector through to shmsys if it is loaded.
1088100384Speter	 */
1089100384Speter	return sysent[171].sy_call(td, uap);
1090100384Speter}
1091100384Speter
1092100384Speterint
1093119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1094100384Speter{
1095100384Speter	struct pread_args ap;
1096100384Speter
1097107849Salfred	ap.fd = uap->fd;
1098107849Salfred	ap.buf = uap->buf;
1099107849Salfred	ap.nbyte = uap->nbyte;
1100119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1101100384Speter	return (pread(td, &ap));
1102100384Speter}
1103100384Speter
1104100384Speterint
1105119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1106100384Speter{
1107100384Speter	struct pwrite_args ap;
1108100384Speter
1109107849Salfred	ap.fd = uap->fd;
1110107849Salfred	ap.buf = uap->buf;
1111107849Salfred	ap.nbyte = uap->nbyte;
1112119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1113100384Speter	return (pwrite(td, &ap));
1114100384Speter}
1115100384Speter
1116100384Speterint
1117119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1118100384Speter{
1119100384Speter	int error;
1120100384Speter	struct lseek_args ap;
1121100384Speter	off_t pos;
1122100384Speter
1123107849Salfred	ap.fd = uap->fd;
1124119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1125107849Salfred	ap.whence = uap->whence;
1126100384Speter	error = lseek(td, &ap);
1127100384Speter	/* Expand the quad return into two parts for eax and edx */
1128100384Speter	pos = *(off_t *)(td->td_retval);
1129100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1130100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1131100384Speter	return error;
1132100384Speter}
1133100384Speter
1134100384Speterint
1135119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1136100384Speter{
1137100384Speter	struct truncate_args ap;
1138100384Speter
1139107849Salfred	ap.path = uap->path;
1140119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1141100384Speter	return (truncate(td, &ap));
1142100384Speter}
1143100384Speter
1144100384Speterint
1145119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1146100384Speter{
1147100384Speter	struct ftruncate_args ap;
1148100384Speter
1149107849Salfred	ap.fd = uap->fd;
1150119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1151100384Speter	return (ftruncate(td, &ap));
1152100384Speter}
1153100384Speter
1154104738Speter#ifdef COMPAT_FREEBSD4
1155100384Speterint
1156119333Speterfreebsd4_freebsd32_sendfile(struct thread *td,
1157119333Speter    struct freebsd4_freebsd32_sendfile_args *uap)
1158104738Speter{
1159104738Speter	struct freebsd4_sendfile_args ap;
1160104738Speter
1161107849Salfred	ap.fd = uap->fd;
1162107849Salfred	ap.s = uap->s;
1163119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1164107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1165107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1166107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1167107849Salfred	ap.flags = uap->flags;
1168104738Speter	return (freebsd4_sendfile(td, &ap));
1169104738Speter}
1170104738Speter#endif
1171104738Speter
1172104738Speterint
1173119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1174100384Speter{
1175100384Speter	struct sendfile_args ap;
1176100384Speter
1177107849Salfred	ap.fd = uap->fd;
1178107849Salfred	ap.s = uap->s;
1179119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1180107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1181107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1182107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1183107849Salfred	ap.flags = uap->flags;
1184100384Speter	return (sendfile(td, &ap));
1185100384Speter}
1186100384Speter
1187100384Speterstruct stat32 {
1188100384Speter	udev_t	st_dev;
1189100384Speter	ino_t	st_ino;
1190100384Speter	mode_t	st_mode;
1191100384Speter	nlink_t	st_nlink;
1192100384Speter	uid_t	st_uid;
1193100384Speter	gid_t	st_gid;
1194100384Speter	udev_t	st_rdev;
1195100384Speter	struct timespec32 st_atimespec;
1196100384Speter	struct timespec32 st_mtimespec;
1197100384Speter	struct timespec32 st_ctimespec;
1198100384Speter	off_t	st_size;
1199100384Speter	int64_t	st_blocks;
1200100384Speter	u_int32_t st_blksize;
1201100384Speter	u_int32_t st_flags;
1202100384Speter	u_int32_t st_gen;
1203100384Speter};
1204100384Speter
1205100384Speterstatic void
1206100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1207100384Speter{
1208100384Speter	CP(*in, *out, st_dev);
1209100384Speter	CP(*in, *out, st_ino);
1210100384Speter	CP(*in, *out, st_mode);
1211100384Speter	CP(*in, *out, st_nlink);
1212100384Speter	CP(*in, *out, st_uid);
1213100384Speter	CP(*in, *out, st_gid);
1214100384Speter	CP(*in, *out, st_rdev);
1215100384Speter	TS_CP(*in, *out, st_atimespec);
1216100384Speter	TS_CP(*in, *out, st_mtimespec);
1217100384Speter	TS_CP(*in, *out, st_ctimespec);
1218100384Speter	CP(*in, *out, st_size);
1219100384Speter	CP(*in, *out, st_blocks);
1220100384Speter	CP(*in, *out, st_blksize);
1221100384Speter	CP(*in, *out, st_flags);
1222100384Speter	CP(*in, *out, st_gen);
1223100384Speter}
1224100384Speter
1225100384Speterint
1226119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1227100384Speter{
1228100384Speter	int error;
1229100384Speter	caddr_t sg;
1230100384Speter	struct stat32 *p32, s32;
1231100384Speter	struct stat *p = NULL, s;
1232100384Speter
1233107849Salfred	p32 = uap->ub;
1234100384Speter	if (p32) {
1235100384Speter		sg = stackgap_init();
1236100384Speter		p = stackgap_alloc(&sg, sizeof(struct stat));
1237107849Salfred		uap->ub = (struct stat32 *)p;
1238100384Speter	}
1239100384Speter	error = stat(td, (struct stat_args *) uap);
1240100384Speter	if (error)
1241100384Speter		return (error);
1242100384Speter	if (p32) {
1243100384Speter		error = copyin(p, &s, sizeof(s));
1244100384Speter		if (error)
1245100384Speter			return (error);
1246100384Speter		copy_stat(&s, &s32);
1247100384Speter		error = copyout(&s32, p32, sizeof(s32));
1248100384Speter	}
1249100384Speter	return (error);
1250100384Speter}
1251100384Speter
1252100384Speterint
1253119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1254100384Speter{
1255100384Speter	int error;
1256100384Speter	caddr_t sg;
1257100384Speter	struct stat32 *p32, s32;
1258100384Speter	struct stat *p = NULL, s;
1259100384Speter
1260107849Salfred	p32 = uap->ub;
1261100384Speter	if (p32) {
1262100384Speter		sg = stackgap_init();
1263100384Speter		p = stackgap_alloc(&sg, sizeof(struct stat));
1264107849Salfred		uap->ub = (struct stat32 *)p;
1265100384Speter	}
1266100384Speter	error = fstat(td, (struct fstat_args *) uap);
1267100384Speter	if (error)
1268100384Speter		return (error);
1269100384Speter	if (p32) {
1270100384Speter		error = copyin(p, &s, sizeof(s));
1271100384Speter		if (error)
1272100384Speter			return (error);
1273100384Speter		copy_stat(&s, &s32);
1274100384Speter		error = copyout(&s32, p32, sizeof(s32));
1275100384Speter	}
1276100384Speter	return (error);
1277100384Speter}
1278100384Speter
1279100384Speterint
1280119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1281100384Speter{
1282100384Speter	int error;
1283100384Speter	caddr_t sg;
1284100384Speter	struct stat32 *p32, s32;
1285100384Speter	struct stat *p = NULL, s;
1286100384Speter
1287107849Salfred	p32 = uap->ub;
1288100384Speter	if (p32) {
1289100384Speter		sg = stackgap_init();
1290100384Speter		p = stackgap_alloc(&sg, sizeof(struct stat));
1291107849Salfred		uap->ub = (struct stat32 *)p;
1292100384Speter	}
1293100384Speter	error = lstat(td, (struct lstat_args *) uap);
1294100384Speter	if (error)
1295100384Speter		return (error);
1296100384Speter	if (p32) {
1297100384Speter		error = copyin(p, &s, sizeof(s));
1298100384Speter		if (error)
1299100384Speter			return (error);
1300100384Speter		copy_stat(&s, &s32);
1301100384Speter		error = copyout(&s32, p32, sizeof(s32));
1302100384Speter	}
1303100384Speter	return (error);
1304100384Speter}
1305100384Speter
1306100384Speter/*
1307100384Speter * MPSAFE
1308100384Speter */
1309100384Speterint
1310119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1311100384Speter{
1312100384Speter	int error, name[CTL_MAXNAME];
1313100384Speter	size_t j, oldlen;
1314100384Speter
1315100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1316100384Speter		return (EINVAL);
1317100384Speter
1318100384Speter 	error = copyin(uap->name, &name, uap->namelen * sizeof(int));
1319100384Speter 	if (error)
1320100384Speter		return (error);
1321100384Speter
1322100384Speter	mtx_lock(&Giant);
1323100384Speter
1324100384Speter	if (uap->oldlenp)
1325100384Speter		oldlen = fuword32(uap->oldlenp);
1326100384Speter	else
1327100384Speter		oldlen = 0;
1328100384Speter	error = userland_sysctl(td, name, uap->namelen,
1329100384Speter		uap->old, &oldlen, 1,
1330100384Speter		uap->new, uap->newlen, &j);
1331100384Speter	if (error && error != ENOMEM)
1332100384Speter		goto done2;
1333100384Speter	if (uap->oldlenp) {
1334100384Speter		suword32(uap->oldlenp, j);
1335100384Speter	}
1336100384Speterdone2:
1337100384Speter	mtx_unlock(&Giant);
1338100384Speter	return (error);
1339100384Speter}
1340100384Speter
1341100384Speterstruct sigaction32 {
1342100384Speter	u_int32_t	sa_u;
1343100384Speter	int		sa_flags;
1344100384Speter	sigset_t	sa_mask;
1345100384Speter};
1346100384Speter
1347100384Speterint
1348119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1349100384Speter{
1350113859Sjhb	struct sigaction32 s32;
1351113859Sjhb	struct sigaction sa, osa, *sap;
1352100384Speter	int error;
1353100384Speter
1354113859Sjhb	if (uap->act) {
1355113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1356100384Speter		if (error)
1357100384Speter			return (error);
1358113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1359113859Sjhb		CP(s32, sa, sa_flags);
1360113859Sjhb		CP(s32, sa, sa_mask);
1361113859Sjhb		sap = &sa;
1362113859Sjhb	} else
1363113859Sjhb		sap = NULL;
1364113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1365113859Sjhb	if (error != 0 && uap->oact != NULL) {
1366113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1367113859Sjhb		CP(osa, s32, sa_flags);
1368113859Sjhb		CP(osa, s32, sa_mask);
1369113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1370100384Speter	}
1371100384Speter	return (error);
1372100384Speter}
1373100384Speter
1374114987Speter#ifdef COMPAT_FREEBSD4
1375114987Speterint
1376119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1377119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1378114987Speter{
1379114987Speter	struct sigaction32 s32;
1380114987Speter	struct sigaction sa, osa, *sap;
1381114987Speter	int error;
1382114987Speter
1383114987Speter	if (uap->act) {
1384114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1385114987Speter		if (error)
1386114987Speter			return (error);
1387114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1388114987Speter		CP(s32, sa, sa_flags);
1389114987Speter		CP(s32, sa, sa_mask);
1390114987Speter		sap = &sa;
1391114987Speter	} else
1392114987Speter		sap = NULL;
1393114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1394114987Speter	if (error != 0 && uap->oact != NULL) {
1395114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1396114987Speter		CP(osa, s32, sa_flags);
1397114987Speter		CP(osa, s32, sa_mask);
1398114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1399114987Speter	}
1400114987Speter	return (error);
1401114987Speter}
1402114987Speter#endif
1403114987Speter
1404100384Speter#if 0
1405100384Speter
1406100384Speterint
1407119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
1408100384Speter{
1409100384Speter	int error;
1410100384Speter	caddr_t sg;
1411100384Speter	struct yyy32 *p32, s32;
1412100384Speter	struct yyy *p = NULL, s;
1413100384Speter
1414107849Salfred	p32 = uap->zzz;
1415100384Speter	if (p32) {
1416100384Speter		sg = stackgap_init();
1417100384Speter		p = stackgap_alloc(&sg, sizeof(struct yyy));
1418107849Salfred		uap->zzz = (struct yyy32 *)p;
1419100384Speter		error = copyin(p32, &s32, sizeof(s32));
1420100384Speter		if (error)
1421100384Speter			return (error);
1422100384Speter		/* translate in */
1423100384Speter		error = copyout(&s, p, sizeof(s));
1424100384Speter		if (error)
1425100384Speter			return (error);
1426100384Speter	}
1427100384Speter	error = xxx(td, (struct xxx_args *) uap);
1428100384Speter	if (error)
1429100384Speter		return (error);
1430100384Speter	if (p32) {
1431100384Speter		error = copyin(p, &s, sizeof(s));
1432100384Speter		if (error)
1433100384Speter			return (error);
1434100384Speter		/* translate out */
1435100384Speter		error = copyout(&s32, p32, sizeof(s32));
1436100384Speter	}
1437100384Speter	return (error);
1438100384Speter}
1439100384Speter
1440100384Speter#endif
1441