freebsd32_misc.c revision 121719
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 121719 2003-10-30 02:40:30Z 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
82121719SpeterCTASSERT(sizeof(struct timeval32) == 8);
83121719SpeterCTASSERT(sizeof(struct timespec32) == 8);
84121719SpeterCTASSERT(sizeof(struct statfs32) == 256);
85121719SpeterCTASSERT(sizeof(struct rusage32) == 72);
86121719Speter
87100384Speter/*
88100384Speter * [ taken from the linux emulator ]
89100384Speter * Search an alternate path before passing pathname arguments on
90100384Speter * to system calls. Useful for keeping a separate 'emulation tree'.
91100384Speter *
92100384Speter * If cflag is set, we check if an attempt can be made to create
93100384Speter * the named file, i.e. we check if the directory it should
94100384Speter * be in exists.
95100384Speter */
96100384Speterint
97119333Speterfreebsd32_emul_find(td, sgp, prefix, path, pbuf, cflag)
98100384Speter	struct thread	*td;
99100384Speter	caddr_t		*sgp;		/* Pointer to stackgap memory */
100100384Speter	const char	*prefix;
101100384Speter	char		*path;
102100384Speter	char		**pbuf;
103100384Speter	int		cflag;
104100384Speter{
105100384Speter	int			error;
106100384Speter	size_t			len, sz;
107100384Speter	char			*buf, *cp, *ptr;
108100384Speter	struct ucred		*ucred;
109100384Speter	struct nameidata	nd;
110100384Speter	struct nameidata	ndroot;
111100384Speter	struct vattr		vat;
112100384Speter	struct vattr		vatroot;
113100384Speter
114111119Simp	buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
115100384Speter	*pbuf = path;
116100384Speter
117100384Speter	for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
118100384Speter		continue;
119100384Speter
120100384Speter	sz = MAXPATHLEN - (ptr - buf);
121100384Speter
122100384Speter	/*
123100384Speter	 * If sgp is not given then the path is already in kernel space
124100384Speter	 */
125100384Speter	if (sgp == NULL)
126100384Speter		error = copystr(path, ptr, sz, &len);
127100384Speter	else
128100384Speter		error = copyinstr(path, ptr, sz, &len);
129100384Speter
130100384Speter	if (error) {
131100384Speter		free(buf, M_TEMP);
132100384Speter		return error;
133100384Speter	}
134100384Speter
135100384Speter	if (*ptr != '/') {
136100384Speter		free(buf, M_TEMP);
137100384Speter		return EINVAL;
138100384Speter	}
139100384Speter
140100384Speter	/*
141100384Speter	 *  We know that there is a / somewhere in this pathname.
142100384Speter	 *  Search backwards for it, to find the file's parent dir
143100384Speter	 *  to see if it exists in the alternate tree. If it does,
144100384Speter	 *  and we want to create a file (cflag is set). We don't
145100384Speter	 *  need to worry about the root comparison in this case.
146100384Speter	 */
147100384Speter
148100384Speter	if (cflag) {
149100384Speter		for (cp = &ptr[len] - 1; *cp != '/'; cp--)
150100384Speter			;
151100384Speter		*cp = '\0';
152100384Speter
153100384Speter		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
154100384Speter
155100384Speter		if ((error = namei(&nd)) != 0) {
156100384Speter			free(buf, M_TEMP);
157100384Speter			return error;
158100384Speter		}
159100384Speter
160100384Speter		*cp = '/';
161100384Speter	} else {
162100384Speter		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
163100384Speter
164100384Speter		if ((error = namei(&nd)) != 0) {
165100384Speter			free(buf, M_TEMP);
166100384Speter			return error;
167100384Speter		}
168100384Speter
169100384Speter		/*
170119333Speter		 * We now compare the vnode of the freebsd32_root to the one
171100384Speter		 * vnode asked. If they resolve to be the same, then we
172100384Speter		 * ignore the match so that the real root gets used.
173100384Speter		 * This avoids the problem of traversing "../.." to find the
174100384Speter		 * root directory and never finding it, because "/" resolves
175100384Speter		 * to the emulation root directory. This is expensive :-(
176100384Speter		 */
177119333Speter		NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE,
178119333Speter		    freebsd32_emul_path, td);
179100384Speter
180100384Speter		if ((error = namei(&ndroot)) != 0) {
181100384Speter			/* Cannot happen! */
182100384Speter			free(buf, M_TEMP);
183100384Speter			vrele(nd.ni_vp);
184100384Speter			return error;
185100384Speter		}
186100384Speter
187100384Speter		ucred = td->td_ucred;
188100384Speter		if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) {
189100384Speter			goto bad;
190100384Speter		}
191100384Speter
192100384Speter		if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred,
193100384Speter		    td)) != 0) {
194100384Speter			goto bad;
195100384Speter		}
196100384Speter
197100384Speter		if (vat.va_fsid == vatroot.va_fsid &&
198100384Speter		    vat.va_fileid == vatroot.va_fileid) {
199100384Speter			error = ENOENT;
200100384Speter			goto bad;
201100384Speter		}
202100384Speter
203100384Speter	}
204100384Speter	if (sgp == NULL)
205100384Speter		*pbuf = buf;
206100384Speter	else {
207100384Speter		sz = &ptr[len] - buf;
208100384Speter		*pbuf = stackgap_alloc(sgp, sz + 1);
209100384Speter		error = copyout(buf, *pbuf, sz);
210100384Speter		free(buf, M_TEMP);
211100384Speter	}
212100384Speter
213100384Speter	vrele(nd.ni_vp);
214100384Speter	if (!cflag)
215100384Speter		vrele(ndroot.ni_vp);
216100384Speter
217100384Speter	return error;
218100384Speter
219100384Speterbad:
220100384Speter	vrele(ndroot.ni_vp);
221100384Speter	vrele(nd.ni_vp);
222100384Speter	free(buf, M_TEMP);
223100384Speter	return error;
224100384Speter}
225100384Speter
226100384Speterint
227119333Speterfreebsd32_open(struct thread *td, struct freebsd32_open_args *uap)
228100384Speter{
229100384Speter	caddr_t sg;
230100384Speter
231100384Speter	sg = stackgap_init();
232100384Speter	CHECKALTEXIST(td, &sg, uap->path);
233100384Speter
234100384Speter	return open(td, (struct open_args *) uap);
235100384Speter}
236100384Speter
237100384Speterint
238119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
239100384Speter{
240100384Speter	int error;
241100384Speter	caddr_t sg;
242100384Speter	struct rusage32 *rusage32, ru32;
243100384Speter	struct rusage *rusage = NULL, ru;
244100384Speter
245107849Salfred	rusage32 = uap->rusage;
246100384Speter	if (rusage32) {
247100384Speter		sg = stackgap_init();
248100384Speter		rusage = stackgap_alloc(&sg, sizeof(struct rusage));
249107849Salfred		uap->rusage = (struct rusage32 *)rusage;
250100384Speter	}
251100384Speter	error = wait4(td, (struct wait_args *)uap);
252100384Speter	if (error)
253100384Speter		return (error);
254100384Speter	if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) {
255100384Speter		TV_CP(ru, ru32, ru_utime);
256100384Speter		TV_CP(ru, ru32, ru_stime);
257100384Speter		CP(ru, ru32, ru_maxrss);
258100384Speter		CP(ru, ru32, ru_ixrss);
259100384Speter		CP(ru, ru32, ru_idrss);
260100384Speter		CP(ru, ru32, ru_isrss);
261100384Speter		CP(ru, ru32, ru_minflt);
262100384Speter		CP(ru, ru32, ru_majflt);
263100384Speter		CP(ru, ru32, ru_nswap);
264100384Speter		CP(ru, ru32, ru_inblock);
265100384Speter		CP(ru, ru32, ru_oublock);
266100384Speter		CP(ru, ru32, ru_msgsnd);
267100384Speter		CP(ru, ru32, ru_msgrcv);
268100384Speter		CP(ru, ru32, ru_nsignals);
269100384Speter		CP(ru, ru32, ru_nvcsw);
270100384Speter		CP(ru, ru32, ru_nivcsw);
271100384Speter		error = copyout(&ru32, rusage32, sizeof(ru32));
272100384Speter	}
273100384Speter	return (error);
274100384Speter}
275100384Speter
276100384Speterstatic void
277100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
278100384Speter{
279100384Speter	CP(*in, *out, f_bsize);
280100384Speter	CP(*in, *out, f_iosize);
281100384Speter	CP(*in, *out, f_blocks);
282100384Speter	CP(*in, *out, f_bfree);
283100384Speter	CP(*in, *out, f_bavail);
284100384Speter	CP(*in, *out, f_files);
285100384Speter	CP(*in, *out, f_ffree);
286100384Speter	CP(*in, *out, f_fsid);
287100384Speter	CP(*in, *out, f_owner);
288100384Speter	CP(*in, *out, f_type);
289100384Speter	CP(*in, *out, f_flags);
290100384Speter	CP(*in, *out, f_flags);
291100384Speter	CP(*in, *out, f_syncwrites);
292100384Speter	CP(*in, *out, f_asyncwrites);
293100384Speter	bcopy(in->f_fstypename,
294100384Speter	      out->f_fstypename, MFSNAMELEN);
295100384Speter	bcopy(in->f_mntonname,
296100384Speter	      out->f_mntonname, MNAMELEN);
297100384Speter	CP(*in, *out, f_syncreads);
298100384Speter	CP(*in, *out, f_asyncreads);
299100384Speter	bcopy(in->f_mntfromname,
300100384Speter	      out->f_mntfromname, MNAMELEN);
301100384Speter}
302100384Speter
303100384Speterint
304119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap)
305100384Speter{
306100384Speter	int error;
307100384Speter	caddr_t sg;
308100384Speter	struct statfs32 *sp32, stat32;
309100384Speter	struct statfs *sp = NULL, stat;
310100384Speter	int maxcount, count, i;
311100384Speter
312107849Salfred	sp32 = uap->buf;
313107849Salfred	maxcount = uap->bufsize / sizeof(struct statfs32);
314100384Speter
315100384Speter	if (sp32) {
316100384Speter		sg = stackgap_init();
317100384Speter		sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
318107849Salfred		uap->buf = (struct statfs32 *)sp;
319100384Speter	}
320100384Speter	error = getfsstat(td, (struct getfsstat_args *) uap);
321100384Speter	if (sp32 && !error) {
322100384Speter		count = td->td_retval[0];
323100384Speter		for (i = 0; i < count; i++) {
324100384Speter			error = copyin(&sp[i], &stat, sizeof(stat));
325100384Speter			if (error)
326100384Speter				return (error);
327100384Speter			copy_statfs(&stat, &stat32);
328100384Speter			error = copyout(&stat32, &sp32[i], sizeof(stat32));
329100384Speter			if (error)
330100384Speter				return (error);
331100384Speter		}
332100384Speter	}
333100384Speter	return (error);
334100384Speter}
335100384Speter
336100384Speterint
337119333Speterfreebsd32_access(struct thread *td, struct freebsd32_access_args *uap)
338100384Speter{
339100384Speter	caddr_t sg;
340100384Speter
341100384Speter	sg = stackgap_init();
342100384Speter	CHECKALTEXIST(td, &sg, uap->path);
343100384Speter
344100384Speter	return access(td, (struct access_args *)uap);
345100384Speter}
346100384Speter
347100384Speterint
348119333Speterfreebsd32_chflags(struct thread *td, struct freebsd32_chflags_args *uap)
349100384Speter{
350100384Speter	caddr_t sg;
351100384Speter
352100384Speter	sg = stackgap_init();
353100384Speter	CHECKALTEXIST(td, &sg, uap->path);
354100384Speter
355100384Speter	return chflags(td, (struct chflags_args *)uap);
356100384Speter}
357100384Speter
358100384Speterstruct sigaltstack32 {
359100384Speter	u_int32_t	ss_sp;
360100384Speter	u_int32_t	ss_size;
361100384Speter	int		ss_flags;
362100384Speter};
363100384Speter
364121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12);
365121719Speter
366100384Speterint
367119333Speterfreebsd32_sigaltstack(struct thread *td,
368119333Speter		      struct freebsd32_sigaltstack_args *uap)
369100384Speter{
370113859Sjhb	struct sigaltstack32 s32;
371113859Sjhb	struct sigaltstack ss, oss, *ssp;
372100384Speter	int error;
373100384Speter
374113859Sjhb	if (uap->ss != NULL) {
375113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
376100384Speter		if (error)
377100384Speter			return (error);
378113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
379113859Sjhb		CP(s32, ss, ss_size);
380113859Sjhb		CP(s32, ss, ss_flags);
381113859Sjhb		ssp = &ss;
382113859Sjhb	} else
383113859Sjhb		ssp = NULL;
384113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
385113859Sjhb	if (error == 0 && uap->oss != NULL) {
386113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
387113859Sjhb		CP(oss, s32, ss_size);
388113859Sjhb		CP(oss, s32, ss_flags);
389113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
390100384Speter	}
391100384Speter	return (error);
392100384Speter}
393100384Speter
394100384Speterint
395119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
396100384Speter{
397100384Speter	int error;
398100384Speter	caddr_t sg;
399100384Speter	struct execve_args ap;
400100384Speter	u_int32_t *p32, arg;
401100384Speter	char **p;
402100384Speter	int count;
403100384Speter
404100384Speter	sg = stackgap_init();
405107849Salfred	CHECKALTEXIST(td, &sg, uap->fname);
406107849Salfred	ap.fname = uap->fname;
407100384Speter
408107849Salfred	if (uap->argv) {
409100384Speter		count = 0;
410107849Salfred		p32 = uap->argv;
411100384Speter		do {
412100384Speter			error = copyin(p32++, &arg, sizeof(arg));
413100384Speter			if (error)
414100384Speter				return error;
415100384Speter			count++;
416100384Speter		} while (arg != 0);
417100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
418107849Salfred		ap.argv = p;
419107849Salfred		p32 = uap->argv;
420100384Speter		do {
421100384Speter			error = copyin(p32++, &arg, sizeof(arg));
422100384Speter			if (error)
423100384Speter				return error;
424100384Speter			*p++ = PTRIN(arg);
425100384Speter		} while (arg != 0);
426100384Speter	}
427107849Salfred	if (uap->envv) {
428100384Speter		count = 0;
429107849Salfred		p32 = uap->envv;
430100384Speter		do {
431100384Speter			error = copyin(p32++, &arg, sizeof(arg));
432100384Speter			if (error)
433100384Speter				return error;
434100384Speter			count++;
435100384Speter		} while (arg != 0);
436100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
437107849Salfred		ap.envv = p;
438107849Salfred		p32 = uap->envv;
439100384Speter		do {
440100384Speter			error = copyin(p32++, &arg, sizeof(arg));
441100384Speter			if (error)
442100384Speter				return error;
443100384Speter			*p++ = PTRIN(arg);
444100384Speter		} while (arg != 0);
445100384Speter	}
446100384Speter
447100384Speter	return execve(td, &ap);
448100384Speter}
449100384Speter
450114987Speter#ifdef __ia64__
451100384Speterstatic int
452119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
453119333Speter		       int prot, int fd, off_t pos)
454100384Speter{
455100384Speter	vm_map_t map;
456100384Speter	vm_map_entry_t entry;
457100384Speter	int rv;
458100384Speter
459100384Speter	map = &td->td_proc->p_vmspace->vm_map;
460100384Speter	if (fd != -1)
461100384Speter		prot |= VM_PROT_WRITE;
462100384Speter
463100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
464100384Speter		if ((entry->protection & prot) != prot) {
465100384Speter			rv = vm_map_protect(map,
466100384Speter					    trunc_page(start),
467100384Speter					    round_page(end),
468100384Speter					    entry->protection | prot,
469100384Speter					    FALSE);
470100384Speter			if (rv != KERN_SUCCESS)
471100384Speter				return (EINVAL);
472100384Speter		}
473100384Speter	} else {
474100384Speter		vm_offset_t addr = trunc_page(start);
475100384Speter		rv = vm_map_find(map, 0, 0,
476100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
477100384Speter				 VM_PROT_ALL, 0);
478100384Speter		if (rv != KERN_SUCCESS)
479100384Speter			return (EINVAL);
480100384Speter	}
481100384Speter
482100384Speter	if (fd != -1) {
483100384Speter		struct pread_args r;
484107849Salfred		r.fd = fd;
485107849Salfred		r.buf = (void *) start;
486107849Salfred		r.nbyte = end - start;
487107849Salfred		r.offset = pos;
488100384Speter		return (pread(td, &r));
489100384Speter	} else {
490100384Speter		while (start < end) {
491100384Speter			subyte((void *) start, 0);
492100384Speter			start++;
493100384Speter		}
494100384Speter		return (0);
495100384Speter	}
496100384Speter}
497114987Speter#endif
498100384Speter
499100384Speterint
500119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
501100384Speter{
502100384Speter	struct mmap_args ap;
503107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
504107849Salfred	vm_size_t len	 = uap->len;
505107849Salfred	int prot	 = uap->prot;
506107849Salfred	int flags	 = uap->flags;
507107849Salfred	int fd		 = uap->fd;
508107849Salfred	off_t pos	 = (uap->poslo
509107849Salfred			    | ((off_t)uap->poshi << 32));
510114987Speter#ifdef __ia64__
511100384Speter	vm_size_t pageoff;
512100384Speter	int error;
513100384Speter
514100384Speter	/*
515100384Speter	 * Attempt to handle page size hassles.
516100384Speter	 */
517100384Speter	pageoff = (pos & PAGE_MASK);
518100384Speter	if (flags & MAP_FIXED) {
519100384Speter		vm_offset_t start, end;
520100384Speter		start = addr;
521100384Speter		end = addr + len;
522100384Speter
523100384Speter		if (start != trunc_page(start)) {
524119333Speter			error = freebsd32_mmap_partial(td, start,
525119333Speter						       round_page(start), prot,
526119333Speter						       fd, pos);
527100384Speter			if (fd != -1)
528100384Speter				pos += round_page(start) - start;
529100384Speter			start = round_page(start);
530100384Speter		}
531100384Speter		if (end != round_page(end)) {
532100384Speter			vm_offset_t t = trunc_page(end);
533119333Speter			error = freebsd32_mmap_partial(td, t, end,
534100384Speter						  prot, fd,
535100384Speter						  pos + t - start);
536100384Speter			end = trunc_page(end);
537100384Speter		}
538100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
539100384Speter			/*
540100384Speter			 * We can't map this region at all. The specified
541100384Speter			 * address doesn't have the same alignment as the file
542100384Speter			 * position. Fake the mapping by simply reading the
543100384Speter			 * entire region into memory. First we need to make
544100384Speter			 * sure the region exists.
545100384Speter			 */
546100384Speter			vm_map_t map;
547100384Speter			struct pread_args r;
548100384Speter			int rv;
549100384Speter
550100384Speter			prot |= VM_PROT_WRITE;
551100384Speter			map = &td->td_proc->p_vmspace->vm_map;
552100384Speter			rv = vm_map_remove(map, start, end);
553100384Speter			if (rv != KERN_SUCCESS)
554100384Speter				return (EINVAL);
555100384Speter			rv = vm_map_find(map, 0, 0,
556100384Speter					 &start, end - start, FALSE,
557100384Speter					 prot, VM_PROT_ALL, 0);
558100384Speter			if (rv != KERN_SUCCESS)
559100384Speter				return (EINVAL);
560107849Salfred			r.fd = fd;
561107849Salfred			r.buf = (void *) start;
562107849Salfred			r.nbyte = end - start;
563107849Salfred			r.offset = pos;
564100384Speter			error = pread(td, &r);
565100384Speter			if (error)
566100384Speter				return (error);
567100384Speter
568100384Speter			td->td_retval[0] = addr;
569100384Speter			return (0);
570100384Speter		}
571100384Speter		if (end == start) {
572100384Speter			/*
573100384Speter			 * After dealing with the ragged ends, there
574100384Speter			 * might be none left.
575100384Speter			 */
576100384Speter			td->td_retval[0] = addr;
577100384Speter			return (0);
578100384Speter		}
579100384Speter		addr = start;
580100384Speter		len = end - start;
581100384Speter	}
582114987Speter#endif
583100384Speter
584107849Salfred	ap.addr = (void *) addr;
585107849Salfred	ap.len = len;
586107849Salfred	ap.prot = prot;
587107849Salfred	ap.flags = flags;
588107849Salfred	ap.fd = fd;
589107849Salfred	ap.pos = pos;
590100384Speter
591100384Speter	return (mmap(td, &ap));
592100384Speter}
593100384Speter
594100384Speterstruct itimerval32 {
595100384Speter	struct timeval32 it_interval;
596100384Speter	struct timeval32 it_value;
597100384Speter};
598100384Speter
599121719SpeterCTASSERT(sizeof(struct itimerval32) == 16);
600121719Speter
601100384Speterint
602119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
603100384Speter{
604100384Speter	int error;
605100384Speter	caddr_t sg;
606100384Speter	struct itimerval32 *p32, *op32, s32;
607100384Speter	struct itimerval *p = NULL, *op = NULL, s;
608100384Speter
609107849Salfred	p32 = uap->itv;
610100384Speter	if (p32) {
611100384Speter		sg = stackgap_init();
612100384Speter		p = stackgap_alloc(&sg, sizeof(struct itimerval));
613107849Salfred		uap->itv = (struct itimerval32 *)p;
614100384Speter		error = copyin(p32, &s32, sizeof(s32));
615100384Speter		if (error)
616100384Speter			return (error);
617100384Speter		TV_CP(s32, s, it_interval);
618100384Speter		TV_CP(s32, s, it_value);
619100384Speter		error = copyout(&s, p, sizeof(s));
620100384Speter		if (error)
621100384Speter			return (error);
622100384Speter	}
623107849Salfred	op32 = uap->oitv;
624100384Speter	if (op32) {
625100384Speter		sg = stackgap_init();
626100384Speter		op = stackgap_alloc(&sg, sizeof(struct itimerval));
627107849Salfred		uap->oitv = (struct itimerval32 *)op;
628100384Speter	}
629100384Speter	error = setitimer(td, (struct setitimer_args *) uap);
630100384Speter	if (error)
631100384Speter		return (error);
632100384Speter	if (op32) {
633100384Speter		error = copyin(op, &s, sizeof(s));
634100384Speter		if (error)
635100384Speter			return (error);
636100384Speter		TV_CP(s, s32, it_interval);
637100384Speter		TV_CP(s, s32, it_value);
638100384Speter		error = copyout(&s32, op32, sizeof(s32));
639100384Speter	}
640100384Speter	return (error);
641100384Speter}
642100384Speter
643100384Speterint
644119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
645100384Speter{
646100384Speter	int error;
647100384Speter	caddr_t sg;
648100384Speter	struct timeval32 *p32, s32;
649100384Speter	struct timeval *p = NULL, s;
650100384Speter
651107849Salfred	p32 = uap->tv;
652100384Speter	if (p32) {
653100384Speter		sg = stackgap_init();
654100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
655107849Salfred		uap->tv = (struct timeval32 *)p;
656100384Speter		error = copyin(p32, &s32, sizeof(s32));
657100384Speter		if (error)
658100384Speter			return (error);
659100384Speter		CP(s32, s, tv_sec);
660100384Speter		CP(s32, s, tv_usec);
661100384Speter		error = copyout(&s, p, sizeof(s));
662100384Speter		if (error)
663100384Speter			return (error);
664100384Speter	}
665100384Speter	/*
666100384Speter	 * XXX big-endian needs to convert the fd_sets too.
667100384Speter	 */
668100384Speter	return (select(td, (struct select_args *) uap));
669100384Speter}
670100384Speter
671114987Speterstruct kevent32 {
672114987Speter	u_int32_t	ident;		/* identifier for this event */
673114987Speter	short		filter;		/* filter for event */
674114987Speter	u_short		flags;
675114987Speter	u_int		fflags;
676114987Speter	int32_t		data;
677114987Speter	u_int32_t	udata;		/* opaque user data identifier */
678114987Speter};
679114987Speter
680121719SpeterCTASSERT(sizeof(struct kevent32) == 20);
681121719Speter
682100384Speterint
683119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
684114987Speter{
685114987Speter	int error;
686114987Speter	caddr_t sg;
687114987Speter	struct timespec32 ts32;
688114987Speter	struct timespec ts;
689114987Speter	struct kevent32 ks32;
690114987Speter	struct kevent *ks;
691114987Speter	struct kevent_args a;
692114987Speter	int i;
693114987Speter
694114987Speter	sg = stackgap_init();
695114987Speter
696114987Speter	a.fd = uap->fd;
697114987Speter	a.changelist = uap->changelist;
698114987Speter	a.nchanges = uap->nchanges;
699114987Speter	a.eventlist = uap->eventlist;
700114987Speter	a.nevents = uap->nevents;
701114987Speter	a.timeout = NULL;
702114987Speter
703114987Speter	if (uap->timeout) {
704114987Speter		a.timeout = stackgap_alloc(&sg, sizeof(struct timespec));
705114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
706114987Speter		if (error)
707114987Speter			return (error);
708114987Speter		CP(ts32, ts, tv_sec);
709114987Speter		CP(ts32, ts, tv_nsec);
710114987Speter		error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts));
711114987Speter		if (error)
712114987Speter			return (error);
713114987Speter	}
714114987Speter	if (uap->changelist) {
715119333Speter		a.changelist = (struct kevent *)stackgap_alloc(&sg,
716119333Speter		    uap->nchanges * sizeof(struct kevent));
717114987Speter		for (i = 0; i < uap->nchanges; i++) {
718119333Speter			error = copyin(&uap->changelist[i], &ks32,
719119333Speter			    sizeof(ks32));
720114987Speter			if (error)
721114987Speter				return (error);
722114987Speter			ks = (struct kevent *)(uintptr_t)&a.changelist[i];
723114987Speter			CP(ks32, *ks, ident);
724114987Speter			CP(ks32, *ks, filter);
725114987Speter			CP(ks32, *ks, flags);
726114987Speter			CP(ks32, *ks, fflags);
727114987Speter			CP(ks32, *ks, data);
728114987Speter			PTRIN_CP(ks32, *ks, udata);
729114987Speter		}
730114987Speter	}
731114987Speter	if (uap->eventlist) {
732119333Speter		a.eventlist = stackgap_alloc(&sg,
733119333Speter		    uap->nevents * sizeof(struct kevent));
734114987Speter	}
735114987Speter	error = kevent(td, &a);
736114987Speter	if (uap->eventlist && error > 0) {
737114987Speter		for (i = 0; i < error; i++) {
738114987Speter			ks = &a.eventlist[i];
739114987Speter			CP(*ks, ks32, ident);
740114987Speter			CP(*ks, ks32, filter);
741114987Speter			CP(*ks, ks32, flags);
742114987Speter			CP(*ks, ks32, fflags);
743114987Speter			CP(*ks, ks32, data);
744114987Speter			PTROUT_CP(*ks, ks32, udata);
745119333Speter			error = copyout(&ks32, &uap->eventlist[i],
746119333Speter			    sizeof(ks32));
747114987Speter			if (error)
748114987Speter				return (error);
749114987Speter		}
750114987Speter	}
751114987Speter	return error;
752114987Speter}
753114987Speter
754114987Speterint
755119333Speterfreebsd32_gettimeofday(struct thread *td,
756119333Speter		       struct freebsd32_gettimeofday_args *uap)
757100384Speter{
758100384Speter	int error;
759100384Speter	caddr_t sg;
760100384Speter	struct timeval32 *p32, s32;
761100384Speter	struct timeval *p = NULL, s;
762100384Speter
763107849Salfred	p32 = uap->tp;
764100384Speter	if (p32) {
765100384Speter		sg = stackgap_init();
766100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
767107849Salfred		uap->tp = (struct timeval32 *)p;
768100384Speter	}
769100384Speter	error = gettimeofday(td, (struct gettimeofday_args *) uap);
770100384Speter	if (error)
771100384Speter		return (error);
772100384Speter	if (p32) {
773100384Speter		error = copyin(p, &s, sizeof(s));
774100384Speter		if (error)
775100384Speter			return (error);
776100384Speter		CP(s, s32, tv_sec);
777100384Speter		CP(s, s32, tv_usec);
778100384Speter		error = copyout(&s32, p32, sizeof(s32));
779100384Speter		if (error)
780100384Speter			return (error);
781100384Speter	}
782100384Speter	return (error);
783100384Speter}
784100384Speter
785100384Speterint
786119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
787100384Speter{
788100384Speter	int error;
789100384Speter	caddr_t sg;
790100384Speter	struct rusage32 *p32, s32;
791100384Speter	struct rusage *p = NULL, s;
792100384Speter
793107849Salfred	p32 = uap->rusage;
794100384Speter	if (p32) {
795100384Speter		sg = stackgap_init();
796100384Speter		p = stackgap_alloc(&sg, sizeof(struct rusage));
797107849Salfred		uap->rusage = (struct rusage32 *)p;
798100384Speter	}
799100384Speter	error = getrusage(td, (struct getrusage_args *) uap);
800100384Speter	if (error)
801100384Speter		return (error);
802100384Speter	if (p32) {
803100384Speter		error = copyin(p, &s, sizeof(s));
804100384Speter		if (error)
805100384Speter			return (error);
806100384Speter		TV_CP(s, s32, ru_utime);
807100384Speter		TV_CP(s, s32, ru_stime);
808100384Speter		CP(s, s32, ru_maxrss);
809100384Speter		CP(s, s32, ru_ixrss);
810100384Speter		CP(s, s32, ru_idrss);
811100384Speter		CP(s, s32, ru_isrss);
812100384Speter		CP(s, s32, ru_minflt);
813100384Speter		CP(s, s32, ru_majflt);
814100384Speter		CP(s, s32, ru_nswap);
815100384Speter		CP(s, s32, ru_inblock);
816100384Speter		CP(s, s32, ru_oublock);
817100384Speter		CP(s, s32, ru_msgsnd);
818100384Speter		CP(s, s32, ru_msgrcv);
819100384Speter		CP(s, s32, ru_nsignals);
820100384Speter		CP(s, s32, ru_nvcsw);
821100384Speter		CP(s, s32, ru_nivcsw);
822100384Speter		error = copyout(&s32, p32, sizeof(s32));
823100384Speter	}
824100384Speter	return (error);
825100384Speter}
826100384Speter
827100384Speterstruct iovec32 {
828100384Speter	u_int32_t iov_base;
829100384Speter	int	iov_len;
830100384Speter};
831100384Speter#define	STACKGAPLEN	400
832100384Speter
833121719SpeterCTASSERT(sizeof(struct iovec32) == 8);
834121719Speter
835100384Speterint
836119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
837100384Speter{
838100384Speter	int error, osize, nsize, i;
839100384Speter	caddr_t sg;
840100384Speter	struct readv_args /* {
841100384Speter		syscallarg(int) fd;
842100384Speter		syscallarg(struct iovec *) iovp;
843100384Speter		syscallarg(u_int) iovcnt;
844100384Speter	} */ a;
845100384Speter	struct iovec32 *oio;
846100384Speter	struct iovec *nio;
847100384Speter
848100384Speter	sg = stackgap_init();
849100384Speter
850107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
851100384Speter		return (EINVAL);
852100384Speter
853107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
854107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
855100384Speter
856111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
857111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
858100384Speter
859100384Speter	error = 0;
860107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
861100384Speter		goto punt;
862107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
863100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
864100384Speter		nio[i].iov_len = oio[i].iov_len;
865100384Speter	}
866100384Speter
867107849Salfred	a.fd = uap->fd;
868107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
869107849Salfred	a.iovcnt = uap->iovcnt;
870100384Speter
871107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
872100384Speter		goto punt;
873100384Speter	error = readv(td, &a);
874100384Speter
875100384Speterpunt:
876100384Speter	free(oio, M_TEMP);
877100384Speter	free(nio, M_TEMP);
878100384Speter	return (error);
879100384Speter}
880100384Speter
881100384Speterint
882119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
883100384Speter{
884100384Speter	int error, i, nsize, osize;
885100384Speter	caddr_t sg;
886100384Speter	struct writev_args /* {
887100384Speter		syscallarg(int) fd;
888100384Speter		syscallarg(struct iovec *) iovp;
889100384Speter		syscallarg(u_int) iovcnt;
890100384Speter	} */ a;
891100384Speter	struct iovec32 *oio;
892100384Speter	struct iovec *nio;
893100384Speter
894100384Speter	sg = stackgap_init();
895100384Speter
896107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
897100384Speter		return (EINVAL);
898100384Speter
899107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
900107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
901100384Speter
902111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
903111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
904100384Speter
905100384Speter	error = 0;
906107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
907100384Speter		goto punt;
908107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
909100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
910100384Speter		nio[i].iov_len = oio[i].iov_len;
911100384Speter	}
912100384Speter
913107849Salfred	a.fd = uap->fd;
914107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
915107849Salfred	a.iovcnt = uap->iovcnt;
916100384Speter
917107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
918100384Speter		goto punt;
919100384Speter	error = writev(td, &a);
920100384Speter
921100384Speterpunt:
922100384Speter	free(oio, M_TEMP);
923100384Speter	free(nio, M_TEMP);
924100384Speter	return (error);
925100384Speter}
926100384Speter
927100384Speterint
928119333Speterfreebsd32_settimeofday(struct thread *td,
929119333Speter		       struct freebsd32_settimeofday_args *uap)
930100384Speter{
931100384Speter	int error;
932100384Speter	caddr_t sg;
933100384Speter	struct timeval32 *p32, s32;
934100384Speter	struct timeval *p = NULL, s;
935100384Speter
936107849Salfred	p32 = uap->tv;
937100384Speter	if (p32) {
938100384Speter		sg = stackgap_init();
939100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
940107849Salfred		uap->tv = (struct timeval32 *)p;
941100384Speter		error = copyin(p32, &s32, sizeof(s32));
942100384Speter		if (error)
943100384Speter			return (error);
944100384Speter		CP(s32, s, tv_sec);
945100384Speter		CP(s32, s, tv_usec);
946100384Speter		error = copyout(&s, p, sizeof(s));
947100384Speter		if (error)
948100384Speter			return (error);
949100384Speter	}
950100384Speter	return (settimeofday(td, (struct settimeofday_args *) uap));
951100384Speter}
952100384Speter
953100384Speterint
954119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
955100384Speter{
956100384Speter	int error;
957100384Speter	caddr_t sg;
958100384Speter	struct timeval32 *p32, s32[2];
959100384Speter	struct timeval *p = NULL, s[2];
960100384Speter
961107849Salfred	p32 = uap->tptr;
962100384Speter	if (p32) {
963100384Speter		sg = stackgap_init();
964100384Speter		p = stackgap_alloc(&sg, 2*sizeof(struct timeval));
965107849Salfred		uap->tptr = (struct timeval32 *)p;
966100384Speter		error = copyin(p32, s32, sizeof(s32));
967100384Speter		if (error)
968100384Speter			return (error);
969100384Speter		CP(s32[0], s[0], tv_sec);
970100384Speter		CP(s32[0], s[0], tv_usec);
971100384Speter		CP(s32[1], s[1], tv_sec);
972100384Speter		CP(s32[1], s[1], tv_usec);
973100384Speter		error = copyout(s, p, sizeof(s));
974100384Speter		if (error)
975100384Speter			return (error);
976100384Speter	}
977100384Speter	return (utimes(td, (struct utimes_args *) uap));
978100384Speter}
979100384Speter
980100384Speterint
981119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
982100384Speter{
983100384Speter	int error;
984100384Speter	caddr_t sg;
985100384Speter	struct timeval32 *p32, *op32, s32;
986100384Speter	struct timeval *p = NULL, *op = NULL, s;
987100384Speter
988107849Salfred	p32 = uap->delta;
989100384Speter	if (p32) {
990100384Speter		sg = stackgap_init();
991100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
992107849Salfred		uap->delta = (struct timeval32 *)p;
993100384Speter		error = copyin(p32, &s32, sizeof(s32));
994100384Speter		if (error)
995100384Speter			return (error);
996100384Speter		CP(s32, s, tv_sec);
997100384Speter		CP(s32, s, tv_usec);
998100384Speter		error = copyout(&s, p, sizeof(s));
999100384Speter		if (error)
1000100384Speter			return (error);
1001100384Speter	}
1002107849Salfred	op32 = uap->olddelta;
1003100384Speter	if (op32) {
1004100384Speter		sg = stackgap_init();
1005100384Speter		op = stackgap_alloc(&sg, sizeof(struct timeval));
1006107849Salfred		uap->olddelta = (struct timeval32 *)op;
1007100384Speter	}
1008100384Speter	error = utimes(td, (struct utimes_args *) uap);
1009100384Speter	if (error)
1010100384Speter		return error;
1011100384Speter	if (op32) {
1012100384Speter		error = copyin(op, &s, sizeof(s));
1013100384Speter		if (error)
1014100384Speter			return (error);
1015100384Speter		CP(s, s32, tv_sec);
1016100384Speter		CP(s, s32, tv_usec);
1017100384Speter		error = copyout(&s32, op32, sizeof(s32));
1018100384Speter	}
1019100384Speter	return (error);
1020100384Speter}
1021100384Speter
1022100384Speterint
1023119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap)
1024100384Speter{
1025100384Speter	int error;
1026100384Speter	caddr_t sg;
1027100384Speter	struct statfs32 *p32, s32;
1028100384Speter	struct statfs *p = NULL, s;
1029100384Speter
1030107849Salfred	p32 = uap->buf;
1031100384Speter	if (p32) {
1032100384Speter		sg = stackgap_init();
1033100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
1034107849Salfred		uap->buf = (struct statfs32 *)p;
1035100384Speter	}
1036100384Speter	error = statfs(td, (struct statfs_args *) uap);
1037100384Speter	if (error)
1038100384Speter		return (error);
1039100384Speter	if (p32) {
1040100384Speter		error = copyin(p, &s, sizeof(s));
1041100384Speter		if (error)
1042100384Speter			return (error);
1043100384Speter		copy_statfs(&s, &s32);
1044100384Speter		error = copyout(&s32, p32, sizeof(s32));
1045100384Speter	}
1046100384Speter	return (error);
1047100384Speter}
1048100384Speter
1049100384Speterint
1050119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap)
1051100384Speter{
1052100384Speter	int error;
1053100384Speter	caddr_t sg;
1054100384Speter	struct statfs32 *p32, s32;
1055100384Speter	struct statfs *p = NULL, s;
1056100384Speter
1057107849Salfred	p32 = uap->buf;
1058100384Speter	if (p32) {
1059100384Speter		sg = stackgap_init();
1060100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
1061107849Salfred		uap->buf = (struct statfs32 *)p;
1062100384Speter	}
1063100384Speter	error = fstatfs(td, (struct fstatfs_args *) uap);
1064100384Speter	if (error)
1065100384Speter		return (error);
1066100384Speter	if (p32) {
1067100384Speter		error = copyin(p, &s, sizeof(s));
1068100384Speter		if (error)
1069100384Speter			return (error);
1070100384Speter		copy_statfs(&s, &s32);
1071100384Speter		error = copyout(&s32, p32, sizeof(s32));
1072100384Speter	}
1073100384Speter	return (error);
1074100384Speter}
1075100384Speter
1076100384Speterint
1077119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1078100384Speter{
1079100384Speter	/*
1080100384Speter	 * Vector through to semsys if it is loaded.
1081100384Speter	 */
1082100384Speter	return sysent[169].sy_call(td, uap);
1083100384Speter}
1084100384Speter
1085100384Speterint
1086119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1087100384Speter{
1088100384Speter	/*
1089100384Speter	 * Vector through to msgsys if it is loaded.
1090100384Speter	 */
1091100384Speter	return sysent[170].sy_call(td, uap);
1092100384Speter}
1093100384Speter
1094100384Speterint
1095119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1096100384Speter{
1097100384Speter	/*
1098100384Speter	 * Vector through to shmsys if it is loaded.
1099100384Speter	 */
1100100384Speter	return sysent[171].sy_call(td, uap);
1101100384Speter}
1102100384Speter
1103100384Speterint
1104119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1105100384Speter{
1106100384Speter	struct pread_args ap;
1107100384Speter
1108107849Salfred	ap.fd = uap->fd;
1109107849Salfred	ap.buf = uap->buf;
1110107849Salfred	ap.nbyte = uap->nbyte;
1111119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1112100384Speter	return (pread(td, &ap));
1113100384Speter}
1114100384Speter
1115100384Speterint
1116119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1117100384Speter{
1118100384Speter	struct pwrite_args ap;
1119100384Speter
1120107849Salfred	ap.fd = uap->fd;
1121107849Salfred	ap.buf = uap->buf;
1122107849Salfred	ap.nbyte = uap->nbyte;
1123119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1124100384Speter	return (pwrite(td, &ap));
1125100384Speter}
1126100384Speter
1127100384Speterint
1128119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1129100384Speter{
1130100384Speter	int error;
1131100384Speter	struct lseek_args ap;
1132100384Speter	off_t pos;
1133100384Speter
1134107849Salfred	ap.fd = uap->fd;
1135119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1136107849Salfred	ap.whence = uap->whence;
1137100384Speter	error = lseek(td, &ap);
1138100384Speter	/* Expand the quad return into two parts for eax and edx */
1139100384Speter	pos = *(off_t *)(td->td_retval);
1140100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1141100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1142100384Speter	return error;
1143100384Speter}
1144100384Speter
1145100384Speterint
1146119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1147100384Speter{
1148100384Speter	struct truncate_args ap;
1149100384Speter
1150107849Salfred	ap.path = uap->path;
1151119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1152100384Speter	return (truncate(td, &ap));
1153100384Speter}
1154100384Speter
1155100384Speterint
1156119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1157100384Speter{
1158100384Speter	struct ftruncate_args ap;
1159100384Speter
1160107849Salfred	ap.fd = uap->fd;
1161119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1162100384Speter	return (ftruncate(td, &ap));
1163100384Speter}
1164100384Speter
1165104738Speter#ifdef COMPAT_FREEBSD4
1166100384Speterint
1167119333Speterfreebsd4_freebsd32_sendfile(struct thread *td,
1168119333Speter    struct freebsd4_freebsd32_sendfile_args *uap)
1169104738Speter{
1170104738Speter	struct freebsd4_sendfile_args ap;
1171104738Speter
1172107849Salfred	ap.fd = uap->fd;
1173107849Salfred	ap.s = uap->s;
1174119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1175107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1176107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1177107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1178107849Salfred	ap.flags = uap->flags;
1179104738Speter	return (freebsd4_sendfile(td, &ap));
1180104738Speter}
1181104738Speter#endif
1182104738Speter
1183104738Speterint
1184119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1185100384Speter{
1186100384Speter	struct sendfile_args ap;
1187100384Speter
1188107849Salfred	ap.fd = uap->fd;
1189107849Salfred	ap.s = uap->s;
1190119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1191107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1192107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1193107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1194107849Salfred	ap.flags = uap->flags;
1195100384Speter	return (sendfile(td, &ap));
1196100384Speter}
1197100384Speter
1198100384Speterstruct stat32 {
1199100384Speter	udev_t	st_dev;
1200100384Speter	ino_t	st_ino;
1201100384Speter	mode_t	st_mode;
1202100384Speter	nlink_t	st_nlink;
1203100384Speter	uid_t	st_uid;
1204100384Speter	gid_t	st_gid;
1205100384Speter	udev_t	st_rdev;
1206100384Speter	struct timespec32 st_atimespec;
1207100384Speter	struct timespec32 st_mtimespec;
1208100384Speter	struct timespec32 st_ctimespec;
1209100384Speter	off_t	st_size;
1210100384Speter	int64_t	st_blocks;
1211100384Speter	u_int32_t st_blksize;
1212100384Speter	u_int32_t st_flags;
1213100384Speter	u_int32_t st_gen;
1214121719Speter	struct timespec32 st_birthtimespec;
1215121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1216121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1217100384Speter};
1218100384Speter
1219121719Speter
1220121719SpeterCTASSERT(sizeof(struct stat32) == 96);
1221121719Speter
1222100384Speterstatic void
1223100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1224100384Speter{
1225100384Speter	CP(*in, *out, st_dev);
1226100384Speter	CP(*in, *out, st_ino);
1227100384Speter	CP(*in, *out, st_mode);
1228100384Speter	CP(*in, *out, st_nlink);
1229100384Speter	CP(*in, *out, st_uid);
1230100384Speter	CP(*in, *out, st_gid);
1231100384Speter	CP(*in, *out, st_rdev);
1232100384Speter	TS_CP(*in, *out, st_atimespec);
1233100384Speter	TS_CP(*in, *out, st_mtimespec);
1234100384Speter	TS_CP(*in, *out, st_ctimespec);
1235100384Speter	CP(*in, *out, st_size);
1236100384Speter	CP(*in, *out, st_blocks);
1237100384Speter	CP(*in, *out, st_blksize);
1238100384Speter	CP(*in, *out, st_flags);
1239100384Speter	CP(*in, *out, st_gen);
1240100384Speter}
1241100384Speter
1242100384Speterint
1243119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1244100384Speter{
1245100384Speter	int error;
1246100384Speter	caddr_t sg;
1247100384Speter	struct stat32 *p32, s32;
1248100384Speter	struct stat *p = NULL, s;
1249100384Speter
1250107849Salfred	p32 = uap->ub;
1251100384Speter	if (p32) {
1252100384Speter		sg = stackgap_init();
1253100384Speter		p = stackgap_alloc(&sg, sizeof(struct stat));
1254107849Salfred		uap->ub = (struct stat32 *)p;
1255100384Speter	}
1256100384Speter	error = stat(td, (struct stat_args *) uap);
1257100384Speter	if (error)
1258100384Speter		return (error);
1259100384Speter	if (p32) {
1260100384Speter		error = copyin(p, &s, sizeof(s));
1261100384Speter		if (error)
1262100384Speter			return (error);
1263100384Speter		copy_stat(&s, &s32);
1264100384Speter		error = copyout(&s32, p32, sizeof(s32));
1265100384Speter	}
1266100384Speter	return (error);
1267100384Speter}
1268100384Speter
1269100384Speterint
1270119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1271100384Speter{
1272100384Speter	int error;
1273100384Speter	caddr_t sg;
1274100384Speter	struct stat32 *p32, s32;
1275100384Speter	struct stat *p = NULL, s;
1276100384Speter
1277107849Salfred	p32 = uap->ub;
1278100384Speter	if (p32) {
1279100384Speter		sg = stackgap_init();
1280100384Speter		p = stackgap_alloc(&sg, sizeof(struct stat));
1281107849Salfred		uap->ub = (struct stat32 *)p;
1282100384Speter	}
1283100384Speter	error = fstat(td, (struct fstat_args *) uap);
1284100384Speter	if (error)
1285100384Speter		return (error);
1286100384Speter	if (p32) {
1287100384Speter		error = copyin(p, &s, sizeof(s));
1288100384Speter		if (error)
1289100384Speter			return (error);
1290100384Speter		copy_stat(&s, &s32);
1291100384Speter		error = copyout(&s32, p32, sizeof(s32));
1292100384Speter	}
1293100384Speter	return (error);
1294100384Speter}
1295100384Speter
1296100384Speterint
1297119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1298100384Speter{
1299100384Speter	int error;
1300100384Speter	caddr_t sg;
1301100384Speter	struct stat32 *p32, s32;
1302100384Speter	struct stat *p = NULL, s;
1303100384Speter
1304107849Salfred	p32 = uap->ub;
1305100384Speter	if (p32) {
1306100384Speter		sg = stackgap_init();
1307100384Speter		p = stackgap_alloc(&sg, sizeof(struct stat));
1308107849Salfred		uap->ub = (struct stat32 *)p;
1309100384Speter	}
1310100384Speter	error = lstat(td, (struct lstat_args *) uap);
1311100384Speter	if (error)
1312100384Speter		return (error);
1313100384Speter	if (p32) {
1314100384Speter		error = copyin(p, &s, sizeof(s));
1315100384Speter		if (error)
1316100384Speter			return (error);
1317100384Speter		copy_stat(&s, &s32);
1318100384Speter		error = copyout(&s32, p32, sizeof(s32));
1319100384Speter	}
1320100384Speter	return (error);
1321100384Speter}
1322100384Speter
1323100384Speter/*
1324100384Speter * MPSAFE
1325100384Speter */
1326100384Speterint
1327119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1328100384Speter{
1329100384Speter	int error, name[CTL_MAXNAME];
1330100384Speter	size_t j, oldlen;
1331100384Speter
1332100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1333100384Speter		return (EINVAL);
1334100384Speter
1335100384Speter 	error = copyin(uap->name, &name, uap->namelen * sizeof(int));
1336100384Speter 	if (error)
1337100384Speter		return (error);
1338100384Speter
1339100384Speter	mtx_lock(&Giant);
1340100384Speter
1341100384Speter	if (uap->oldlenp)
1342100384Speter		oldlen = fuword32(uap->oldlenp);
1343100384Speter	else
1344100384Speter		oldlen = 0;
1345100384Speter	error = userland_sysctl(td, name, uap->namelen,
1346100384Speter		uap->old, &oldlen, 1,
1347100384Speter		uap->new, uap->newlen, &j);
1348100384Speter	if (error && error != ENOMEM)
1349100384Speter		goto done2;
1350100384Speter	if (uap->oldlenp) {
1351100384Speter		suword32(uap->oldlenp, j);
1352100384Speter	}
1353100384Speterdone2:
1354100384Speter	mtx_unlock(&Giant);
1355100384Speter	return (error);
1356100384Speter}
1357100384Speter
1358100384Speterstruct sigaction32 {
1359100384Speter	u_int32_t	sa_u;
1360100384Speter	int		sa_flags;
1361100384Speter	sigset_t	sa_mask;
1362100384Speter};
1363100384Speter
1364121719SpeterCTASSERT(sizeof(struct sigaction32) == 24);
1365121719Speter
1366100384Speterint
1367119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1368100384Speter{
1369113859Sjhb	struct sigaction32 s32;
1370113859Sjhb	struct sigaction sa, osa, *sap;
1371100384Speter	int error;
1372100384Speter
1373113859Sjhb	if (uap->act) {
1374113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1375100384Speter		if (error)
1376100384Speter			return (error);
1377113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1378113859Sjhb		CP(s32, sa, sa_flags);
1379113859Sjhb		CP(s32, sa, sa_mask);
1380113859Sjhb		sap = &sa;
1381113859Sjhb	} else
1382113859Sjhb		sap = NULL;
1383113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1384113859Sjhb	if (error != 0 && uap->oact != NULL) {
1385113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1386113859Sjhb		CP(osa, s32, sa_flags);
1387113859Sjhb		CP(osa, s32, sa_mask);
1388113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1389100384Speter	}
1390100384Speter	return (error);
1391100384Speter}
1392100384Speter
1393114987Speter#ifdef COMPAT_FREEBSD4
1394114987Speterint
1395119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1396119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1397114987Speter{
1398114987Speter	struct sigaction32 s32;
1399114987Speter	struct sigaction sa, osa, *sap;
1400114987Speter	int error;
1401114987Speter
1402114987Speter	if (uap->act) {
1403114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1404114987Speter		if (error)
1405114987Speter			return (error);
1406114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1407114987Speter		CP(s32, sa, sa_flags);
1408114987Speter		CP(s32, sa, sa_mask);
1409114987Speter		sap = &sa;
1410114987Speter	} else
1411114987Speter		sap = NULL;
1412114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1413114987Speter	if (error != 0 && uap->oact != NULL) {
1414114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1415114987Speter		CP(osa, s32, sa_flags);
1416114987Speter		CP(osa, s32, sa_mask);
1417114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1418114987Speter	}
1419114987Speter	return (error);
1420114987Speter}
1421114987Speter#endif
1422114987Speter
1423100384Speter#if 0
1424100384Speter
1425100384Speterint
1426119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
1427100384Speter{
1428100384Speter	int error;
1429100384Speter	caddr_t sg;
1430100384Speter	struct yyy32 *p32, s32;
1431100384Speter	struct yyy *p = NULL, s;
1432100384Speter
1433107849Salfred	p32 = uap->zzz;
1434100384Speter	if (p32) {
1435100384Speter		sg = stackgap_init();
1436100384Speter		p = stackgap_alloc(&sg, sizeof(struct yyy));
1437107849Salfred		uap->zzz = (struct yyy32 *)p;
1438100384Speter		error = copyin(p32, &s32, sizeof(s32));
1439100384Speter		if (error)
1440100384Speter			return (error);
1441100384Speter		/* translate in */
1442100384Speter		error = copyout(&s, p, sizeof(s));
1443100384Speter		if (error)
1444100384Speter			return (error);
1445100384Speter	}
1446100384Speter	error = xxx(td, (struct xxx_args *) uap);
1447100384Speter	if (error)
1448100384Speter		return (error);
1449100384Speter	if (p32) {
1450100384Speter		error = copyin(p, &s, sizeof(s));
1451100384Speter		if (error)
1452100384Speter			return (error);
1453100384Speter		/* translate out */
1454100384Speter		error = copyout(&s32, p32, sizeof(s32));
1455100384Speter	}
1456100384Speter	return (error);
1457100384Speter}
1458100384Speter
1459100384Speter#endif
1460