freebsd32_misc.c revision 136152
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 136152 2004-10-05 18:51:11Z jhb $");
29118031Sobrien
30104738Speter#include "opt_compat.h"
31104738Speter
32100384Speter#include <sys/param.h>
33100384Speter#include <sys/systm.h>
34100384Speter#include <sys/bus.h>
35100384Speter#include <sys/exec.h>
36100384Speter#include <sys/fcntl.h>
37100384Speter#include <sys/filedesc.h>
38123746Speter#include <sys/namei.h>
39100384Speter#include <sys/imgact.h>
40100384Speter#include <sys/kernel.h>
41100384Speter#include <sys/lock.h>
42100384Speter#include <sys/malloc.h>
43100384Speter#include <sys/file.h>		/* Must come after sys/malloc.h */
44100384Speter#include <sys/mman.h>
45100384Speter#include <sys/module.h>
46100384Speter#include <sys/mount.h>
47100384Speter#include <sys/mutex.h>
48100384Speter#include <sys/namei.h>
49100384Speter#include <sys/param.h>
50100384Speter#include <sys/proc.h>
51100384Speter#include <sys/reboot.h>
52100384Speter#include <sys/resource.h>
53100384Speter#include <sys/resourcevar.h>
54100384Speter#include <sys/selinfo.h>
55100384Speter#include <sys/pipe.h>		/* Must come after sys/selinfo.h */
56100384Speter#include <sys/signal.h>
57100384Speter#include <sys/signalvar.h>
58100384Speter#include <sys/socket.h>
59100384Speter#include <sys/socketvar.h>
60100384Speter#include <sys/stat.h>
61113859Sjhb#include <sys/syscallsubr.h>
62100384Speter#include <sys/sysctl.h>
63100384Speter#include <sys/sysent.h>
64100384Speter#include <sys/sysproto.h>
65100384Speter#include <sys/systm.h>
66100384Speter#include <sys/unistd.h>
67100384Speter#include <sys/user.h>
68100384Speter#include <sys/utsname.h>
69100384Speter#include <sys/vnode.h>
70127140Sjhb#include <sys/wait.h>
71100384Speter
72100384Speter#include <vm/vm.h>
73100384Speter#include <vm/vm_kern.h>
74100384Speter#include <vm/vm_param.h>
75100384Speter#include <vm/pmap.h>
76100384Speter#include <vm/vm_map.h>
77100384Speter#include <vm/vm_object.h>
78100384Speter#include <vm/vm_extern.h>
79100384Speter
80119333Speter#include <compat/freebsd32/freebsd32_util.h>
81119333Speter#include <compat/freebsd32/freebsd32.h>
82119333Speter#include <compat/freebsd32/freebsd32_proto.h>
83100384Speter
84121719SpeterCTASSERT(sizeof(struct timeval32) == 8);
85121719SpeterCTASSERT(sizeof(struct timespec32) == 8);
86121719SpeterCTASSERT(sizeof(struct statfs32) == 256);
87121719SpeterCTASSERT(sizeof(struct rusage32) == 72);
88121719Speter
89100384Speterint
90119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
91100384Speter{
92127140Sjhb	int error, status;
93127140Sjhb	struct rusage32 ru32;
94136152Sjhb	struct rusage ru, *rup;
95100384Speter
96136152Sjhb	if (uap->rusage != NULL)
97136152Sjhb		rup = &ru;
98136152Sjhb	else
99136152Sjhb		rup = NULL;
100136152Sjhb	error = kern_wait(td, uap->pid, &status, uap->options, rup);
101100384Speter	if (error)
102100384Speter		return (error);
103127140Sjhb	if (uap->status != NULL)
104127140Sjhb		error = copyout(&status, uap->status, sizeof(status));
105127140Sjhb	if (uap->rusage != NULL && error == 0) {
106100384Speter		TV_CP(ru, ru32, ru_utime);
107100384Speter		TV_CP(ru, ru32, ru_stime);
108100384Speter		CP(ru, ru32, ru_maxrss);
109100384Speter		CP(ru, ru32, ru_ixrss);
110100384Speter		CP(ru, ru32, ru_idrss);
111100384Speter		CP(ru, ru32, ru_isrss);
112100384Speter		CP(ru, ru32, ru_minflt);
113100384Speter		CP(ru, ru32, ru_majflt);
114100384Speter		CP(ru, ru32, ru_nswap);
115100384Speter		CP(ru, ru32, ru_inblock);
116100384Speter		CP(ru, ru32, ru_oublock);
117100384Speter		CP(ru, ru32, ru_msgsnd);
118100384Speter		CP(ru, ru32, ru_msgrcv);
119100384Speter		CP(ru, ru32, ru_nsignals);
120100384Speter		CP(ru, ru32, ru_nvcsw);
121100384Speter		CP(ru, ru32, ru_nivcsw);
122127140Sjhb		error = copyout(&ru32, uap->rusage, sizeof(ru32));
123100384Speter	}
124100384Speter	return (error);
125100384Speter}
126100384Speter
127128597Smarcel#ifdef COMPAT_FREEBSD4
128100384Speterstatic void
129100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
130100384Speter{
131100384Speter	CP(*in, *out, f_bsize);
132100384Speter	CP(*in, *out, f_iosize);
133100384Speter	CP(*in, *out, f_blocks);
134100384Speter	CP(*in, *out, f_bfree);
135100384Speter	CP(*in, *out, f_bavail);
136100384Speter	CP(*in, *out, f_files);
137100384Speter	CP(*in, *out, f_ffree);
138100384Speter	CP(*in, *out, f_fsid);
139100384Speter	CP(*in, *out, f_owner);
140100384Speter	CP(*in, *out, f_type);
141100384Speter	CP(*in, *out, f_flags);
142100384Speter	CP(*in, *out, f_flags);
143100384Speter	CP(*in, *out, f_syncwrites);
144100384Speter	CP(*in, *out, f_asyncwrites);
145100384Speter	bcopy(in->f_fstypename,
146100384Speter	      out->f_fstypename, MFSNAMELEN);
147100384Speter	bcopy(in->f_mntonname,
148128260Speter	      out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
149100384Speter	CP(*in, *out, f_syncreads);
150100384Speter	CP(*in, *out, f_asyncreads);
151100384Speter	bcopy(in->f_mntfromname,
152128260Speter	      out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
153100384Speter}
154128597Smarcel#endif
155100384Speter
156128597Smarcel#ifdef COMPAT_FREEBSD4
157100384Speterint
158128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
159100384Speter{
160100384Speter	int error;
161100384Speter	caddr_t sg;
162100384Speter	struct statfs32 *sp32, stat32;
163100384Speter	struct statfs *sp = NULL, stat;
164100384Speter	int maxcount, count, i;
165100384Speter
166107849Salfred	sp32 = uap->buf;
167107849Salfred	maxcount = uap->bufsize / sizeof(struct statfs32);
168100384Speter
169100384Speter	if (sp32) {
170100384Speter		sg = stackgap_init();
171100384Speter		sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
172107849Salfred		uap->buf = (struct statfs32 *)sp;
173100384Speter	}
174100384Speter	error = getfsstat(td, (struct getfsstat_args *) uap);
175100384Speter	if (sp32 && !error) {
176100384Speter		count = td->td_retval[0];
177100384Speter		for (i = 0; i < count; i++) {
178100384Speter			error = copyin(&sp[i], &stat, sizeof(stat));
179100384Speter			if (error)
180100384Speter				return (error);
181100384Speter			copy_statfs(&stat, &stat32);
182100384Speter			error = copyout(&stat32, &sp32[i], sizeof(stat32));
183100384Speter			if (error)
184100384Speter				return (error);
185100384Speter		}
186100384Speter	}
187100384Speter	return (error);
188100384Speter}
189128597Smarcel#endif
190100384Speter
191100384Speterstruct sigaltstack32 {
192100384Speter	u_int32_t	ss_sp;
193100384Speter	u_int32_t	ss_size;
194100384Speter	int		ss_flags;
195100384Speter};
196100384Speter
197121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12);
198121719Speter
199100384Speterint
200119333Speterfreebsd32_sigaltstack(struct thread *td,
201119333Speter		      struct freebsd32_sigaltstack_args *uap)
202100384Speter{
203113859Sjhb	struct sigaltstack32 s32;
204113859Sjhb	struct sigaltstack ss, oss, *ssp;
205100384Speter	int error;
206100384Speter
207113859Sjhb	if (uap->ss != NULL) {
208113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
209100384Speter		if (error)
210100384Speter			return (error);
211113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
212113859Sjhb		CP(s32, ss, ss_size);
213113859Sjhb		CP(s32, ss, ss_flags);
214113859Sjhb		ssp = &ss;
215113859Sjhb	} else
216113859Sjhb		ssp = NULL;
217113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
218113859Sjhb	if (error == 0 && uap->oss != NULL) {
219113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
220113859Sjhb		CP(oss, s32, ss_size);
221113859Sjhb		CP(oss, s32, ss_flags);
222113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
223100384Speter	}
224100384Speter	return (error);
225100384Speter}
226100384Speter
227100384Speterint
228119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
229100384Speter{
230100384Speter	int error;
231100384Speter	caddr_t sg;
232100384Speter	struct execve_args ap;
233100384Speter	u_int32_t *p32, arg;
234122253Speter	char **p, *p64;
235100384Speter	int count;
236100384Speter
237100384Speter	sg = stackgap_init();
238107849Salfred	ap.fname = uap->fname;
239100384Speter
240107849Salfred	if (uap->argv) {
241100384Speter		count = 0;
242107849Salfred		p32 = uap->argv;
243100384Speter		do {
244100384Speter			error = copyin(p32++, &arg, sizeof(arg));
245100384Speter			if (error)
246100384Speter				return error;
247100384Speter			count++;
248100384Speter		} while (arg != 0);
249100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
250107849Salfred		ap.argv = p;
251107849Salfred		p32 = uap->argv;
252100384Speter		do {
253100384Speter			error = copyin(p32++, &arg, sizeof(arg));
254100384Speter			if (error)
255100384Speter				return error;
256122253Speter			p64 = PTRIN(arg);
257122253Speter			error = copyout(&p64, p++, sizeof(p64));
258122253Speter			if (error)
259122253Speter				return error;
260100384Speter		} while (arg != 0);
261100384Speter	}
262107849Salfred	if (uap->envv) {
263100384Speter		count = 0;
264107849Salfred		p32 = uap->envv;
265100384Speter		do {
266100384Speter			error = copyin(p32++, &arg, sizeof(arg));
267100384Speter			if (error)
268100384Speter				return error;
269100384Speter			count++;
270100384Speter		} while (arg != 0);
271100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
272107849Salfred		ap.envv = p;
273107849Salfred		p32 = uap->envv;
274100384Speter		do {
275100384Speter			error = copyin(p32++, &arg, sizeof(arg));
276100384Speter			if (error)
277100384Speter				return error;
278122253Speter			p64 = PTRIN(arg);
279122253Speter			error = copyout(&p64, p++, sizeof(p64));
280122253Speter			if (error)
281122253Speter				return error;
282100384Speter		} while (arg != 0);
283100384Speter	}
284100384Speter
285100384Speter	return execve(td, &ap);
286100384Speter}
287100384Speter
288114987Speter#ifdef __ia64__
289100384Speterstatic int
290119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
291119333Speter		       int prot, int fd, off_t pos)
292100384Speter{
293100384Speter	vm_map_t map;
294100384Speter	vm_map_entry_t entry;
295100384Speter	int rv;
296100384Speter
297100384Speter	map = &td->td_proc->p_vmspace->vm_map;
298100384Speter	if (fd != -1)
299100384Speter		prot |= VM_PROT_WRITE;
300100384Speter
301100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
302100384Speter		if ((entry->protection & prot) != prot) {
303100384Speter			rv = vm_map_protect(map,
304100384Speter					    trunc_page(start),
305100384Speter					    round_page(end),
306100384Speter					    entry->protection | prot,
307100384Speter					    FALSE);
308100384Speter			if (rv != KERN_SUCCESS)
309100384Speter				return (EINVAL);
310100384Speter		}
311100384Speter	} else {
312100384Speter		vm_offset_t addr = trunc_page(start);
313100384Speter		rv = vm_map_find(map, 0, 0,
314100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
315100384Speter				 VM_PROT_ALL, 0);
316100384Speter		if (rv != KERN_SUCCESS)
317100384Speter			return (EINVAL);
318100384Speter	}
319100384Speter
320100384Speter	if (fd != -1) {
321100384Speter		struct pread_args r;
322107849Salfred		r.fd = fd;
323107849Salfred		r.buf = (void *) start;
324107849Salfred		r.nbyte = end - start;
325107849Salfred		r.offset = pos;
326100384Speter		return (pread(td, &r));
327100384Speter	} else {
328100384Speter		while (start < end) {
329100384Speter			subyte((void *) start, 0);
330100384Speter			start++;
331100384Speter		}
332100384Speter		return (0);
333100384Speter	}
334100384Speter}
335114987Speter#endif
336100384Speter
337100384Speterint
338119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
339100384Speter{
340100384Speter	struct mmap_args ap;
341107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
342107849Salfred	vm_size_t len	 = uap->len;
343107849Salfred	int prot	 = uap->prot;
344107849Salfred	int flags	 = uap->flags;
345107849Salfred	int fd		 = uap->fd;
346107849Salfred	off_t pos	 = (uap->poslo
347107849Salfred			    | ((off_t)uap->poshi << 32));
348114987Speter#ifdef __ia64__
349100384Speter	vm_size_t pageoff;
350100384Speter	int error;
351100384Speter
352100384Speter	/*
353100384Speter	 * Attempt to handle page size hassles.
354100384Speter	 */
355100384Speter	pageoff = (pos & PAGE_MASK);
356100384Speter	if (flags & MAP_FIXED) {
357100384Speter		vm_offset_t start, end;
358100384Speter		start = addr;
359100384Speter		end = addr + len;
360100384Speter
361100384Speter		if (start != trunc_page(start)) {
362119333Speter			error = freebsd32_mmap_partial(td, start,
363119333Speter						       round_page(start), prot,
364119333Speter						       fd, pos);
365100384Speter			if (fd != -1)
366100384Speter				pos += round_page(start) - start;
367100384Speter			start = round_page(start);
368100384Speter		}
369100384Speter		if (end != round_page(end)) {
370100384Speter			vm_offset_t t = trunc_page(end);
371119333Speter			error = freebsd32_mmap_partial(td, t, end,
372100384Speter						  prot, fd,
373100384Speter						  pos + t - start);
374100384Speter			end = trunc_page(end);
375100384Speter		}
376100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
377100384Speter			/*
378100384Speter			 * We can't map this region at all. The specified
379100384Speter			 * address doesn't have the same alignment as the file
380100384Speter			 * position. Fake the mapping by simply reading the
381100384Speter			 * entire region into memory. First we need to make
382100384Speter			 * sure the region exists.
383100384Speter			 */
384100384Speter			vm_map_t map;
385100384Speter			struct pread_args r;
386100384Speter			int rv;
387100384Speter
388100384Speter			prot |= VM_PROT_WRITE;
389100384Speter			map = &td->td_proc->p_vmspace->vm_map;
390100384Speter			rv = vm_map_remove(map, start, end);
391100384Speter			if (rv != KERN_SUCCESS)
392100384Speter				return (EINVAL);
393100384Speter			rv = vm_map_find(map, 0, 0,
394100384Speter					 &start, end - start, FALSE,
395100384Speter					 prot, VM_PROT_ALL, 0);
396100384Speter			if (rv != KERN_SUCCESS)
397100384Speter				return (EINVAL);
398107849Salfred			r.fd = fd;
399107849Salfred			r.buf = (void *) start;
400107849Salfred			r.nbyte = end - start;
401107849Salfred			r.offset = pos;
402100384Speter			error = pread(td, &r);
403100384Speter			if (error)
404100384Speter				return (error);
405100384Speter
406100384Speter			td->td_retval[0] = addr;
407100384Speter			return (0);
408100384Speter		}
409100384Speter		if (end == start) {
410100384Speter			/*
411100384Speter			 * After dealing with the ragged ends, there
412100384Speter			 * might be none left.
413100384Speter			 */
414100384Speter			td->td_retval[0] = addr;
415100384Speter			return (0);
416100384Speter		}
417100384Speter		addr = start;
418100384Speter		len = end - start;
419100384Speter	}
420114987Speter#endif
421100384Speter
422107849Salfred	ap.addr = (void *) addr;
423107849Salfred	ap.len = len;
424107849Salfred	ap.prot = prot;
425107849Salfred	ap.flags = flags;
426107849Salfred	ap.fd = fd;
427107849Salfred	ap.pos = pos;
428100384Speter
429100384Speter	return (mmap(td, &ap));
430100384Speter}
431100384Speter
432100384Speterstruct itimerval32 {
433100384Speter	struct timeval32 it_interval;
434100384Speter	struct timeval32 it_value;
435100384Speter};
436100384Speter
437121719SpeterCTASSERT(sizeof(struct itimerval32) == 16);
438121719Speter
439100384Speterint
440119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
441100384Speter{
442100384Speter	int error;
443100384Speter	caddr_t sg;
444100384Speter	struct itimerval32 *p32, *op32, s32;
445100384Speter	struct itimerval *p = NULL, *op = NULL, s;
446100384Speter
447107849Salfred	p32 = uap->itv;
448100384Speter	if (p32) {
449100384Speter		sg = stackgap_init();
450100384Speter		p = stackgap_alloc(&sg, sizeof(struct itimerval));
451107849Salfred		uap->itv = (struct itimerval32 *)p;
452100384Speter		error = copyin(p32, &s32, sizeof(s32));
453100384Speter		if (error)
454100384Speter			return (error);
455100384Speter		TV_CP(s32, s, it_interval);
456100384Speter		TV_CP(s32, s, it_value);
457100384Speter		error = copyout(&s, p, sizeof(s));
458100384Speter		if (error)
459100384Speter			return (error);
460100384Speter	}
461107849Salfred	op32 = uap->oitv;
462100384Speter	if (op32) {
463100384Speter		sg = stackgap_init();
464100384Speter		op = stackgap_alloc(&sg, sizeof(struct itimerval));
465107849Salfred		uap->oitv = (struct itimerval32 *)op;
466100384Speter	}
467100384Speter	error = setitimer(td, (struct setitimer_args *) uap);
468100384Speter	if (error)
469100384Speter		return (error);
470100384Speter	if (op32) {
471100384Speter		error = copyin(op, &s, sizeof(s));
472100384Speter		if (error)
473100384Speter			return (error);
474100384Speter		TV_CP(s, s32, it_interval);
475100384Speter		TV_CP(s, s32, it_value);
476100384Speter		error = copyout(&s32, op32, sizeof(s32));
477100384Speter	}
478100384Speter	return (error);
479100384Speter}
480100384Speter
481100384Speterint
482125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
483125171Speter{
484125171Speter	int error;
485125171Speter	caddr_t sg;
486125171Speter	struct itimerval32 *p32, s32;
487125171Speter	struct itimerval *p = NULL, s;
488125171Speter
489125171Speter	p32 = uap->itv;
490125171Speter	if (p32) {
491125171Speter		sg = stackgap_init();
492125171Speter		p = stackgap_alloc(&sg, sizeof(struct itimerval));
493125171Speter		uap->itv = (struct itimerval32 *)p;
494125171Speter	}
495125171Speter	error = getitimer(td, (struct getitimer_args *) uap);
496125171Speter	if (error)
497125171Speter		return (error);
498125171Speter	if (p32) {
499125171Speter		error = copyin(p, &s, sizeof(s));
500125171Speter		if (error)
501125171Speter			return (error);
502125171Speter		TV_CP(s, s32, it_interval);
503125171Speter		TV_CP(s, s32, it_value);
504125171Speter		error = copyout(&s32, p32, sizeof(s32));
505125171Speter	}
506125171Speter	return (error);
507125171Speter}
508125171Speter
509125171Speterint
510119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
511100384Speter{
512100384Speter	int error;
513100384Speter	caddr_t sg;
514100384Speter	struct timeval32 *p32, s32;
515100384Speter	struct timeval *p = NULL, s;
516100384Speter
517107849Salfred	p32 = uap->tv;
518100384Speter	if (p32) {
519100384Speter		sg = stackgap_init();
520100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
521107849Salfred		uap->tv = (struct timeval32 *)p;
522100384Speter		error = copyin(p32, &s32, sizeof(s32));
523100384Speter		if (error)
524100384Speter			return (error);
525100384Speter		CP(s32, s, tv_sec);
526100384Speter		CP(s32, s, tv_usec);
527100384Speter		error = copyout(&s, p, sizeof(s));
528100384Speter		if (error)
529100384Speter			return (error);
530100384Speter	}
531100384Speter	/*
532100384Speter	 * XXX big-endian needs to convert the fd_sets too.
533100384Speter	 */
534100384Speter	return (select(td, (struct select_args *) uap));
535100384Speter}
536100384Speter
537114987Speterstruct kevent32 {
538114987Speter	u_int32_t	ident;		/* identifier for this event */
539114987Speter	short		filter;		/* filter for event */
540114987Speter	u_short		flags;
541114987Speter	u_int		fflags;
542114987Speter	int32_t		data;
543114987Speter	u_int32_t	udata;		/* opaque user data identifier */
544114987Speter};
545114987Speter
546121719SpeterCTASSERT(sizeof(struct kevent32) == 20);
547121719Speter
548100384Speterint
549119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
550114987Speter{
551114987Speter	int error;
552114987Speter	caddr_t sg;
553114987Speter	struct timespec32 ts32;
554114987Speter	struct timespec ts;
555114987Speter	struct kevent32 ks32;
556114987Speter	struct kevent *ks;
557114987Speter	struct kevent_args a;
558114987Speter	int i;
559114987Speter
560114987Speter	sg = stackgap_init();
561114987Speter
562114987Speter	a.fd = uap->fd;
563114987Speter	a.changelist = uap->changelist;
564114987Speter	a.nchanges = uap->nchanges;
565114987Speter	a.eventlist = uap->eventlist;
566114987Speter	a.nevents = uap->nevents;
567114987Speter	a.timeout = NULL;
568114987Speter
569114987Speter	if (uap->timeout) {
570114987Speter		a.timeout = stackgap_alloc(&sg, sizeof(struct timespec));
571114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
572114987Speter		if (error)
573114987Speter			return (error);
574114987Speter		CP(ts32, ts, tv_sec);
575114987Speter		CP(ts32, ts, tv_nsec);
576114987Speter		error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts));
577114987Speter		if (error)
578114987Speter			return (error);
579114987Speter	}
580114987Speter	if (uap->changelist) {
581119333Speter		a.changelist = (struct kevent *)stackgap_alloc(&sg,
582119333Speter		    uap->nchanges * sizeof(struct kevent));
583114987Speter		for (i = 0; i < uap->nchanges; i++) {
584119333Speter			error = copyin(&uap->changelist[i], &ks32,
585119333Speter			    sizeof(ks32));
586114987Speter			if (error)
587114987Speter				return (error);
588114987Speter			ks = (struct kevent *)(uintptr_t)&a.changelist[i];
589114987Speter			CP(ks32, *ks, ident);
590114987Speter			CP(ks32, *ks, filter);
591114987Speter			CP(ks32, *ks, flags);
592114987Speter			CP(ks32, *ks, fflags);
593114987Speter			CP(ks32, *ks, data);
594114987Speter			PTRIN_CP(ks32, *ks, udata);
595114987Speter		}
596114987Speter	}
597114987Speter	if (uap->eventlist) {
598119333Speter		a.eventlist = stackgap_alloc(&sg,
599119333Speter		    uap->nevents * sizeof(struct kevent));
600114987Speter	}
601114987Speter	error = kevent(td, &a);
602114987Speter	if (uap->eventlist && error > 0) {
603114987Speter		for (i = 0; i < error; i++) {
604114987Speter			ks = &a.eventlist[i];
605114987Speter			CP(*ks, ks32, ident);
606114987Speter			CP(*ks, ks32, filter);
607114987Speter			CP(*ks, ks32, flags);
608114987Speter			CP(*ks, ks32, fflags);
609114987Speter			CP(*ks, ks32, data);
610114987Speter			PTROUT_CP(*ks, ks32, udata);
611119333Speter			error = copyout(&ks32, &uap->eventlist[i],
612119333Speter			    sizeof(ks32));
613114987Speter			if (error)
614114987Speter				return (error);
615114987Speter		}
616114987Speter	}
617114987Speter	return error;
618114987Speter}
619114987Speter
620114987Speterint
621119333Speterfreebsd32_gettimeofday(struct thread *td,
622119333Speter		       struct freebsd32_gettimeofday_args *uap)
623100384Speter{
624123425Speter	struct timeval atv;
625123425Speter	struct timeval32 atv32;
626123425Speter	struct timezone rtz;
627123425Speter	int error = 0;
628100384Speter
629123425Speter	if (uap->tp) {
630123425Speter		microtime(&atv);
631123425Speter		CP(atv, atv32, tv_sec);
632123425Speter		CP(atv, atv32, tv_usec);
633123425Speter		error = copyout(&atv32, uap->tp, sizeof (atv32));
634100384Speter	}
635123425Speter	if (error == 0 && uap->tzp != NULL) {
636123425Speter		rtz.tz_minuteswest = tz_minuteswest;
637123425Speter		rtz.tz_dsttime = tz_dsttime;
638123425Speter		error = copyout(&rtz, uap->tzp, sizeof (rtz));
639100384Speter	}
640100384Speter	return (error);
641100384Speter}
642100384Speter
643100384Speterint
644119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
645100384Speter{
646136152Sjhb	struct rusage32 s32;
647136152Sjhb	struct rusage s;
648100384Speter	int error;
649100384Speter
650136152Sjhb	error = kern_getrusage(td, uap->who, &s);
651100384Speter	if (error)
652100384Speter		return (error);
653136152Sjhb	if (uap->rusage != NULL) {
654100384Speter		TV_CP(s, s32, ru_utime);
655100384Speter		TV_CP(s, s32, ru_stime);
656100384Speter		CP(s, s32, ru_maxrss);
657100384Speter		CP(s, s32, ru_ixrss);
658100384Speter		CP(s, s32, ru_idrss);
659100384Speter		CP(s, s32, ru_isrss);
660100384Speter		CP(s, s32, ru_minflt);
661100384Speter		CP(s, s32, ru_majflt);
662100384Speter		CP(s, s32, ru_nswap);
663100384Speter		CP(s, s32, ru_inblock);
664100384Speter		CP(s, s32, ru_oublock);
665100384Speter		CP(s, s32, ru_msgsnd);
666100384Speter		CP(s, s32, ru_msgrcv);
667100384Speter		CP(s, s32, ru_nsignals);
668100384Speter		CP(s, s32, ru_nvcsw);
669100384Speter		CP(s, s32, ru_nivcsw);
670136152Sjhb		error = copyout(&s32, uap->rusage, sizeof(s32));
671100384Speter	}
672100384Speter	return (error);
673100384Speter}
674100384Speter
675100384Speterstruct iovec32 {
676100384Speter	u_int32_t iov_base;
677100384Speter	int	iov_len;
678100384Speter};
679100384Speter#define	STACKGAPLEN	400
680100384Speter
681121719SpeterCTASSERT(sizeof(struct iovec32) == 8);
682121719Speter
683100384Speterint
684119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
685100384Speter{
686100384Speter	int error, osize, nsize, i;
687100384Speter	caddr_t sg;
688100384Speter	struct readv_args /* {
689100384Speter		syscallarg(int) fd;
690100384Speter		syscallarg(struct iovec *) iovp;
691100384Speter		syscallarg(u_int) iovcnt;
692100384Speter	} */ a;
693100384Speter	struct iovec32 *oio;
694100384Speter	struct iovec *nio;
695100384Speter
696100384Speter	sg = stackgap_init();
697100384Speter
698107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
699100384Speter		return (EINVAL);
700100384Speter
701107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
702107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
703100384Speter
704111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
705111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
706100384Speter
707100384Speter	error = 0;
708107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
709100384Speter		goto punt;
710107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
711100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
712100384Speter		nio[i].iov_len = oio[i].iov_len;
713100384Speter	}
714100384Speter
715107849Salfred	a.fd = uap->fd;
716107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
717107849Salfred	a.iovcnt = uap->iovcnt;
718100384Speter
719107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
720100384Speter		goto punt;
721100384Speter	error = readv(td, &a);
722100384Speter
723100384Speterpunt:
724100384Speter	free(oio, M_TEMP);
725100384Speter	free(nio, M_TEMP);
726100384Speter	return (error);
727100384Speter}
728100384Speter
729100384Speterint
730119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
731100384Speter{
732100384Speter	int error, i, nsize, osize;
733100384Speter	caddr_t sg;
734100384Speter	struct writev_args /* {
735100384Speter		syscallarg(int) fd;
736100384Speter		syscallarg(struct iovec *) iovp;
737100384Speter		syscallarg(u_int) iovcnt;
738100384Speter	} */ a;
739100384Speter	struct iovec32 *oio;
740100384Speter	struct iovec *nio;
741100384Speter
742100384Speter	sg = stackgap_init();
743100384Speter
744107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
745100384Speter		return (EINVAL);
746100384Speter
747107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
748107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
749100384Speter
750111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
751111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
752100384Speter
753100384Speter	error = 0;
754107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
755100384Speter		goto punt;
756107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
757100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
758100384Speter		nio[i].iov_len = oio[i].iov_len;
759100384Speter	}
760100384Speter
761107849Salfred	a.fd = uap->fd;
762107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
763107849Salfred	a.iovcnt = uap->iovcnt;
764100384Speter
765107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
766100384Speter		goto punt;
767100384Speter	error = writev(td, &a);
768100384Speter
769100384Speterpunt:
770100384Speter	free(oio, M_TEMP);
771100384Speter	free(nio, M_TEMP);
772100384Speter	return (error);
773100384Speter}
774100384Speter
775100384Speterint
776119333Speterfreebsd32_settimeofday(struct thread *td,
777119333Speter		       struct freebsd32_settimeofday_args *uap)
778100384Speter{
779100384Speter	int error;
780100384Speter	caddr_t sg;
781100384Speter	struct timeval32 *p32, s32;
782100384Speter	struct timeval *p = NULL, s;
783100384Speter
784107849Salfred	p32 = uap->tv;
785100384Speter	if (p32) {
786100384Speter		sg = stackgap_init();
787100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
788107849Salfred		uap->tv = (struct timeval32 *)p;
789100384Speter		error = copyin(p32, &s32, sizeof(s32));
790100384Speter		if (error)
791100384Speter			return (error);
792100384Speter		CP(s32, s, tv_sec);
793100384Speter		CP(s32, s, tv_usec);
794100384Speter		error = copyout(&s, p, sizeof(s));
795100384Speter		if (error)
796100384Speter			return (error);
797100384Speter	}
798100384Speter	return (settimeofday(td, (struct settimeofday_args *) uap));
799100384Speter}
800100384Speter
801100384Speterint
802119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
803100384Speter{
804100384Speter	int error;
805100384Speter	caddr_t sg;
806100384Speter	struct timeval32 *p32, s32[2];
807100384Speter	struct timeval *p = NULL, s[2];
808100384Speter
809107849Salfred	p32 = uap->tptr;
810100384Speter	if (p32) {
811100384Speter		sg = stackgap_init();
812100384Speter		p = stackgap_alloc(&sg, 2*sizeof(struct timeval));
813107849Salfred		uap->tptr = (struct timeval32 *)p;
814100384Speter		error = copyin(p32, s32, sizeof(s32));
815100384Speter		if (error)
816100384Speter			return (error);
817100384Speter		CP(s32[0], s[0], tv_sec);
818100384Speter		CP(s32[0], s[0], tv_usec);
819100384Speter		CP(s32[1], s[1], tv_sec);
820100384Speter		CP(s32[1], s[1], tv_usec);
821100384Speter		error = copyout(s, p, sizeof(s));
822100384Speter		if (error)
823100384Speter			return (error);
824100384Speter	}
825100384Speter	return (utimes(td, (struct utimes_args *) uap));
826100384Speter}
827100384Speter
828100384Speterint
829119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
830100384Speter{
831100384Speter	int error;
832100384Speter	caddr_t sg;
833100384Speter	struct timeval32 *p32, *op32, s32;
834100384Speter	struct timeval *p = NULL, *op = NULL, s;
835100384Speter
836107849Salfred	p32 = uap->delta;
837100384Speter	if (p32) {
838100384Speter		sg = stackgap_init();
839100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
840107849Salfred		uap->delta = (struct timeval32 *)p;
841100384Speter		error = copyin(p32, &s32, sizeof(s32));
842100384Speter		if (error)
843100384Speter			return (error);
844100384Speter		CP(s32, s, tv_sec);
845100384Speter		CP(s32, s, tv_usec);
846100384Speter		error = copyout(&s, p, sizeof(s));
847100384Speter		if (error)
848100384Speter			return (error);
849100384Speter	}
850107849Salfred	op32 = uap->olddelta;
851100384Speter	if (op32) {
852100384Speter		sg = stackgap_init();
853100384Speter		op = stackgap_alloc(&sg, sizeof(struct timeval));
854107849Salfred		uap->olddelta = (struct timeval32 *)op;
855100384Speter	}
856100384Speter	error = utimes(td, (struct utimes_args *) uap);
857100384Speter	if (error)
858100384Speter		return error;
859100384Speter	if (op32) {
860100384Speter		error = copyin(op, &s, sizeof(s));
861100384Speter		if (error)
862100384Speter			return (error);
863100384Speter		CP(s, s32, tv_sec);
864100384Speter		CP(s, s32, tv_usec);
865100384Speter		error = copyout(&s32, op32, sizeof(s32));
866100384Speter	}
867100384Speter	return (error);
868100384Speter}
869100384Speter
870128597Smarcel#ifdef COMPAT_FREEBSD4
871100384Speterint
872128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
873100384Speter{
874100384Speter	int error;
875100384Speter	caddr_t sg;
876100384Speter	struct statfs32 *p32, s32;
877100384Speter	struct statfs *p = NULL, s;
878100384Speter
879107849Salfred	p32 = uap->buf;
880100384Speter	if (p32) {
881100384Speter		sg = stackgap_init();
882100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
883107849Salfred		uap->buf = (struct statfs32 *)p;
884100384Speter	}
885100384Speter	error = statfs(td, (struct statfs_args *) uap);
886100384Speter	if (error)
887100384Speter		return (error);
888100384Speter	if (p32) {
889100384Speter		error = copyin(p, &s, sizeof(s));
890100384Speter		if (error)
891100384Speter			return (error);
892100384Speter		copy_statfs(&s, &s32);
893100384Speter		error = copyout(&s32, p32, sizeof(s32));
894100384Speter	}
895100384Speter	return (error);
896100384Speter}
897128597Smarcel#endif
898100384Speter
899128597Smarcel#ifdef COMPAT_FREEBSD4
900100384Speterint
901128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
902100384Speter{
903100384Speter	int error;
904100384Speter	caddr_t sg;
905100384Speter	struct statfs32 *p32, s32;
906100384Speter	struct statfs *p = NULL, s;
907100384Speter
908107849Salfred	p32 = uap->buf;
909100384Speter	if (p32) {
910100384Speter		sg = stackgap_init();
911100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
912107849Salfred		uap->buf = (struct statfs32 *)p;
913100384Speter	}
914100384Speter	error = fstatfs(td, (struct fstatfs_args *) uap);
915100384Speter	if (error)
916100384Speter		return (error);
917100384Speter	if (p32) {
918100384Speter		error = copyin(p, &s, sizeof(s));
919100384Speter		if (error)
920100384Speter			return (error);
921100384Speter		copy_statfs(&s, &s32);
922100384Speter		error = copyout(&s32, p32, sizeof(s32));
923100384Speter	}
924100384Speter	return (error);
925100384Speter}
926128597Smarcel#endif
927100384Speter
928128597Smarcel#ifdef COMPAT_FREEBSD4
929100384Speterint
930128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
931128260Speter{
932128260Speter	int error;
933128260Speter	caddr_t sg;
934128260Speter	struct statfs32 *p32, s32;
935128260Speter	struct statfs *p = NULL, s;
936128260Speter
937128260Speter	p32 = uap->buf;
938128260Speter	if (p32) {
939128260Speter		sg = stackgap_init();
940128260Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
941128260Speter		uap->buf = (struct statfs32 *)p;
942128260Speter	}
943128260Speter	error = fhstatfs(td, (struct fhstatfs_args *) uap);
944128260Speter	if (error)
945128260Speter		return (error);
946128260Speter	if (p32) {
947128260Speter		error = copyin(p, &s, sizeof(s));
948128260Speter		if (error)
949128260Speter			return (error);
950128260Speter		copy_statfs(&s, &s32);
951128260Speter		error = copyout(&s32, p32, sizeof(s32));
952128260Speter	}
953128260Speter	return (error);
954128260Speter}
955128597Smarcel#endif
956128260Speter
957128260Speterint
958119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
959100384Speter{
960100384Speter	/*
961100384Speter	 * Vector through to semsys if it is loaded.
962100384Speter	 */
963100384Speter	return sysent[169].sy_call(td, uap);
964100384Speter}
965100384Speter
966100384Speterint
967119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
968100384Speter{
969100384Speter	/*
970100384Speter	 * Vector through to msgsys if it is loaded.
971100384Speter	 */
972100384Speter	return sysent[170].sy_call(td, uap);
973100384Speter}
974100384Speter
975100384Speterint
976119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
977100384Speter{
978100384Speter	/*
979100384Speter	 * Vector through to shmsys if it is loaded.
980100384Speter	 */
981100384Speter	return sysent[171].sy_call(td, uap);
982100384Speter}
983100384Speter
984100384Speterint
985119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
986100384Speter{
987100384Speter	struct pread_args ap;
988100384Speter
989107849Salfred	ap.fd = uap->fd;
990107849Salfred	ap.buf = uap->buf;
991107849Salfred	ap.nbyte = uap->nbyte;
992119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
993100384Speter	return (pread(td, &ap));
994100384Speter}
995100384Speter
996100384Speterint
997119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
998100384Speter{
999100384Speter	struct pwrite_args ap;
1000100384Speter
1001107849Salfred	ap.fd = uap->fd;
1002107849Salfred	ap.buf = uap->buf;
1003107849Salfred	ap.nbyte = uap->nbyte;
1004119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1005100384Speter	return (pwrite(td, &ap));
1006100384Speter}
1007100384Speter
1008100384Speterint
1009119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1010100384Speter{
1011100384Speter	int error;
1012100384Speter	struct lseek_args ap;
1013100384Speter	off_t pos;
1014100384Speter
1015107849Salfred	ap.fd = uap->fd;
1016119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1017107849Salfred	ap.whence = uap->whence;
1018100384Speter	error = lseek(td, &ap);
1019100384Speter	/* Expand the quad return into two parts for eax and edx */
1020100384Speter	pos = *(off_t *)(td->td_retval);
1021100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1022100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1023100384Speter	return error;
1024100384Speter}
1025100384Speter
1026100384Speterint
1027119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1028100384Speter{
1029100384Speter	struct truncate_args ap;
1030100384Speter
1031107849Salfred	ap.path = uap->path;
1032119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1033100384Speter	return (truncate(td, &ap));
1034100384Speter}
1035100384Speter
1036100384Speterint
1037119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1038100384Speter{
1039100384Speter	struct ftruncate_args ap;
1040100384Speter
1041107849Salfred	ap.fd = uap->fd;
1042119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1043100384Speter	return (ftruncate(td, &ap));
1044100384Speter}
1045100384Speter
1046104738Speter#ifdef COMPAT_FREEBSD4
1047100384Speterint
1048119333Speterfreebsd4_freebsd32_sendfile(struct thread *td,
1049119333Speter    struct freebsd4_freebsd32_sendfile_args *uap)
1050104738Speter{
1051104738Speter	struct freebsd4_sendfile_args ap;
1052104738Speter
1053107849Salfred	ap.fd = uap->fd;
1054107849Salfred	ap.s = uap->s;
1055119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1056107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1057107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1058107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1059107849Salfred	ap.flags = uap->flags;
1060104738Speter	return (freebsd4_sendfile(td, &ap));
1061104738Speter}
1062104738Speter#endif
1063104738Speter
1064104738Speterint
1065119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1066100384Speter{
1067100384Speter	struct sendfile_args ap;
1068100384Speter
1069107849Salfred	ap.fd = uap->fd;
1070107849Salfred	ap.s = uap->s;
1071119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1072107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1073107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1074107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1075107849Salfred	ap.flags = uap->flags;
1076100384Speter	return (sendfile(td, &ap));
1077100384Speter}
1078100384Speter
1079100384Speterstruct stat32 {
1080130640Sphk	dev_t	st_dev;
1081100384Speter	ino_t	st_ino;
1082100384Speter	mode_t	st_mode;
1083100384Speter	nlink_t	st_nlink;
1084100384Speter	uid_t	st_uid;
1085100384Speter	gid_t	st_gid;
1086130640Sphk	dev_t	st_rdev;
1087100384Speter	struct timespec32 st_atimespec;
1088100384Speter	struct timespec32 st_mtimespec;
1089100384Speter	struct timespec32 st_ctimespec;
1090100384Speter	off_t	st_size;
1091100384Speter	int64_t	st_blocks;
1092100384Speter	u_int32_t st_blksize;
1093100384Speter	u_int32_t st_flags;
1094100384Speter	u_int32_t st_gen;
1095121719Speter	struct timespec32 st_birthtimespec;
1096121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1097121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1098100384Speter};
1099100384Speter
1100121719Speter
1101121719SpeterCTASSERT(sizeof(struct stat32) == 96);
1102121719Speter
1103100384Speterstatic void
1104100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1105100384Speter{
1106100384Speter	CP(*in, *out, st_dev);
1107100384Speter	CP(*in, *out, st_ino);
1108100384Speter	CP(*in, *out, st_mode);
1109100384Speter	CP(*in, *out, st_nlink);
1110100384Speter	CP(*in, *out, st_uid);
1111100384Speter	CP(*in, *out, st_gid);
1112100384Speter	CP(*in, *out, st_rdev);
1113100384Speter	TS_CP(*in, *out, st_atimespec);
1114100384Speter	TS_CP(*in, *out, st_mtimespec);
1115100384Speter	TS_CP(*in, *out, st_ctimespec);
1116100384Speter	CP(*in, *out, st_size);
1117100384Speter	CP(*in, *out, st_blocks);
1118100384Speter	CP(*in, *out, st_blksize);
1119100384Speter	CP(*in, *out, st_flags);
1120100384Speter	CP(*in, *out, st_gen);
1121100384Speter}
1122100384Speter
1123100384Speterint
1124119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1125100384Speter{
1126123746Speter	struct stat sb;
1127123746Speter	struct stat32 sb32;
1128100384Speter	int error;
1129123746Speter	struct nameidata nd;
1130100384Speter
1131123746Speter#ifdef LOOKUP_SHARED
1132123746Speter	NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ,
1133123746Speter	    UIO_USERSPACE, uap->path, td);
1134123746Speter#else
1135123746Speter	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1136123746Speter	    uap->path, td);
1137123746Speter#endif
1138123746Speter	if ((error = namei(&nd)) != 0)
1139123746Speter		return (error);
1140123746Speter	error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
1141123746Speter	NDFREE(&nd, NDF_ONLY_PNBUF);
1142123746Speter	vput(nd.ni_vp);
1143100384Speter	if (error)
1144100384Speter		return (error);
1145123746Speter	copy_stat(&sb, &sb32);
1146123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1147100384Speter	return (error);
1148100384Speter}
1149100384Speter
1150100384Speterint
1151119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1152100384Speter{
1153123746Speter	struct file *fp;
1154123746Speter	struct stat ub;
1155123746Speter	struct stat32 ub32;
1156100384Speter	int error;
1157100384Speter
1158123746Speter	if ((error = fget(td, uap->fd, &fp)) != 0)
1159123746Speter		return (error);
1160123746Speter	mtx_lock(&Giant);
1161123746Speter	error = fo_stat(fp, &ub, td->td_ucred, td);
1162123746Speter	mtx_unlock(&Giant);
1163123746Speter	fdrop(fp, td);
1164100384Speter	if (error)
1165100384Speter		return (error);
1166123746Speter	copy_stat(&ub, &ub32);
1167123746Speter	error = copyout(&ub32, uap->ub, sizeof(ub32));
1168100384Speter	return (error);
1169100384Speter}
1170100384Speter
1171100384Speterint
1172119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1173100384Speter{
1174100384Speter	int error;
1175123746Speter	struct vnode *vp;
1176123746Speter	struct stat sb;
1177123746Speter	struct stat32 sb32;
1178123746Speter	struct nameidata nd;
1179100384Speter
1180123746Speter	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1181123746Speter	    uap->path, td);
1182123746Speter	if ((error = namei(&nd)) != 0)
1183123746Speter		return (error);
1184123746Speter	vp = nd.ni_vp;
1185123746Speter	error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
1186123746Speter	NDFREE(&nd, NDF_ONLY_PNBUF);
1187123746Speter	vput(vp);
1188100384Speter	if (error)
1189100384Speter		return (error);
1190123746Speter	copy_stat(&sb, &sb32);
1191123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1192100384Speter	return (error);
1193100384Speter}
1194100384Speter
1195100384Speter/*
1196100384Speter * MPSAFE
1197100384Speter */
1198100384Speterint
1199119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1200100384Speter{
1201100384Speter	int error, name[CTL_MAXNAME];
1202100384Speter	size_t j, oldlen;
1203100384Speter
1204100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1205100384Speter		return (EINVAL);
1206100384Speter
1207100384Speter 	error = copyin(uap->name, &name, uap->namelen * sizeof(int));
1208100384Speter 	if (error)
1209100384Speter		return (error);
1210100384Speter
1211100384Speter	mtx_lock(&Giant);
1212100384Speter
1213100384Speter	if (uap->oldlenp)
1214100384Speter		oldlen = fuword32(uap->oldlenp);
1215100384Speter	else
1216100384Speter		oldlen = 0;
1217100384Speter	error = userland_sysctl(td, name, uap->namelen,
1218100384Speter		uap->old, &oldlen, 1,
1219100384Speter		uap->new, uap->newlen, &j);
1220100384Speter	if (error && error != ENOMEM)
1221100384Speter		goto done2;
1222100384Speter	if (uap->oldlenp) {
1223100384Speter		suword32(uap->oldlenp, j);
1224100384Speter	}
1225100384Speterdone2:
1226100384Speter	mtx_unlock(&Giant);
1227100384Speter	return (error);
1228100384Speter}
1229100384Speter
1230100384Speterstruct sigaction32 {
1231100384Speter	u_int32_t	sa_u;
1232100384Speter	int		sa_flags;
1233100384Speter	sigset_t	sa_mask;
1234100384Speter};
1235100384Speter
1236121719SpeterCTASSERT(sizeof(struct sigaction32) == 24);
1237121719Speter
1238100384Speterint
1239119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1240100384Speter{
1241113859Sjhb	struct sigaction32 s32;
1242113859Sjhb	struct sigaction sa, osa, *sap;
1243100384Speter	int error;
1244100384Speter
1245113859Sjhb	if (uap->act) {
1246113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1247100384Speter		if (error)
1248100384Speter			return (error);
1249113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1250113859Sjhb		CP(s32, sa, sa_flags);
1251113859Sjhb		CP(s32, sa, sa_mask);
1252113859Sjhb		sap = &sa;
1253113859Sjhb	} else
1254113859Sjhb		sap = NULL;
1255113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1256113859Sjhb	if (error != 0 && uap->oact != NULL) {
1257113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1258113859Sjhb		CP(osa, s32, sa_flags);
1259113859Sjhb		CP(osa, s32, sa_mask);
1260113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1261100384Speter	}
1262100384Speter	return (error);
1263100384Speter}
1264100384Speter
1265114987Speter#ifdef COMPAT_FREEBSD4
1266114987Speterint
1267119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1268119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1269114987Speter{
1270114987Speter	struct sigaction32 s32;
1271114987Speter	struct sigaction sa, osa, *sap;
1272114987Speter	int error;
1273114987Speter
1274114987Speter	if (uap->act) {
1275114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1276114987Speter		if (error)
1277114987Speter			return (error);
1278114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1279114987Speter		CP(s32, sa, sa_flags);
1280114987Speter		CP(s32, sa, sa_mask);
1281114987Speter		sap = &sa;
1282114987Speter	} else
1283114987Speter		sap = NULL;
1284114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1285114987Speter	if (error != 0 && uap->oact != NULL) {
1286114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1287114987Speter		CP(osa, s32, sa_flags);
1288114987Speter		CP(osa, s32, sa_mask);
1289114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1290114987Speter	}
1291114987Speter	return (error);
1292114987Speter}
1293114987Speter#endif
1294114987Speter
1295100384Speter#if 0
1296100384Speter
1297100384Speterint
1298119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
1299100384Speter{
1300100384Speter	int error;
1301100384Speter	caddr_t sg;
1302100384Speter	struct yyy32 *p32, s32;
1303100384Speter	struct yyy *p = NULL, s;
1304100384Speter
1305107849Salfred	p32 = uap->zzz;
1306100384Speter	if (p32) {
1307100384Speter		sg = stackgap_init();
1308100384Speter		p = stackgap_alloc(&sg, sizeof(struct yyy));
1309107849Salfred		uap->zzz = (struct yyy32 *)p;
1310100384Speter		error = copyin(p32, &s32, sizeof(s32));
1311100384Speter		if (error)
1312100384Speter			return (error);
1313100384Speter		/* translate in */
1314100384Speter		error = copyout(&s, p, sizeof(s));
1315100384Speter		if (error)
1316100384Speter			return (error);
1317100384Speter	}
1318100384Speter	error = xxx(td, (struct xxx_args *) uap);
1319100384Speter	if (error)
1320100384Speter		return (error);
1321100384Speter	if (p32) {
1322100384Speter		error = copyin(p, &s, sizeof(s));
1323100384Speter		if (error)
1324100384Speter			return (error);
1325100384Speter		/* translate out */
1326100384Speter		error = copyout(&s32, p32, sizeof(s32));
1327100384Speter	}
1328100384Speter	return (error);
1329100384Speter}
1330100384Speter
1331100384Speter#endif
1332