freebsd32_misc.c revision 127140
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 127140 2004-03-17 20:00:00Z 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;
94127140Sjhb	struct rusage ru;
95100384Speter
96127140Sjhb	error = kern_wait(td, uap->pid, &status, uap->options, &ru);
97100384Speter	if (error)
98100384Speter		return (error);
99127140Sjhb	if (uap->status != NULL)
100127140Sjhb		error = copyout(&status, uap->status, sizeof(status));
101127140Sjhb	if (uap->rusage != NULL && error == 0) {
102100384Speter		TV_CP(ru, ru32, ru_utime);
103100384Speter		TV_CP(ru, ru32, ru_stime);
104100384Speter		CP(ru, ru32, ru_maxrss);
105100384Speter		CP(ru, ru32, ru_ixrss);
106100384Speter		CP(ru, ru32, ru_idrss);
107100384Speter		CP(ru, ru32, ru_isrss);
108100384Speter		CP(ru, ru32, ru_minflt);
109100384Speter		CP(ru, ru32, ru_majflt);
110100384Speter		CP(ru, ru32, ru_nswap);
111100384Speter		CP(ru, ru32, ru_inblock);
112100384Speter		CP(ru, ru32, ru_oublock);
113100384Speter		CP(ru, ru32, ru_msgsnd);
114100384Speter		CP(ru, ru32, ru_msgrcv);
115100384Speter		CP(ru, ru32, ru_nsignals);
116100384Speter		CP(ru, ru32, ru_nvcsw);
117100384Speter		CP(ru, ru32, ru_nivcsw);
118127140Sjhb		error = copyout(&ru32, uap->rusage, sizeof(ru32));
119100384Speter	}
120100384Speter	return (error);
121100384Speter}
122100384Speter
123100384Speterstatic void
124100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
125100384Speter{
126100384Speter	CP(*in, *out, f_bsize);
127100384Speter	CP(*in, *out, f_iosize);
128100384Speter	CP(*in, *out, f_blocks);
129100384Speter	CP(*in, *out, f_bfree);
130100384Speter	CP(*in, *out, f_bavail);
131100384Speter	CP(*in, *out, f_files);
132100384Speter	CP(*in, *out, f_ffree);
133100384Speter	CP(*in, *out, f_fsid);
134100384Speter	CP(*in, *out, f_owner);
135100384Speter	CP(*in, *out, f_type);
136100384Speter	CP(*in, *out, f_flags);
137100384Speter	CP(*in, *out, f_flags);
138100384Speter	CP(*in, *out, f_syncwrites);
139100384Speter	CP(*in, *out, f_asyncwrites);
140100384Speter	bcopy(in->f_fstypename,
141100384Speter	      out->f_fstypename, MFSNAMELEN);
142100384Speter	bcopy(in->f_mntonname,
143100384Speter	      out->f_mntonname, MNAMELEN);
144100384Speter	CP(*in, *out, f_syncreads);
145100384Speter	CP(*in, *out, f_asyncreads);
146100384Speter	bcopy(in->f_mntfromname,
147100384Speter	      out->f_mntfromname, MNAMELEN);
148100384Speter}
149100384Speter
150100384Speterint
151119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap)
152100384Speter{
153100384Speter	int error;
154100384Speter	caddr_t sg;
155100384Speter	struct statfs32 *sp32, stat32;
156100384Speter	struct statfs *sp = NULL, stat;
157100384Speter	int maxcount, count, i;
158100384Speter
159107849Salfred	sp32 = uap->buf;
160107849Salfred	maxcount = uap->bufsize / sizeof(struct statfs32);
161100384Speter
162100384Speter	if (sp32) {
163100384Speter		sg = stackgap_init();
164100384Speter		sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
165107849Salfred		uap->buf = (struct statfs32 *)sp;
166100384Speter	}
167100384Speter	error = getfsstat(td, (struct getfsstat_args *) uap);
168100384Speter	if (sp32 && !error) {
169100384Speter		count = td->td_retval[0];
170100384Speter		for (i = 0; i < count; i++) {
171100384Speter			error = copyin(&sp[i], &stat, sizeof(stat));
172100384Speter			if (error)
173100384Speter				return (error);
174100384Speter			copy_statfs(&stat, &stat32);
175100384Speter			error = copyout(&stat32, &sp32[i], sizeof(stat32));
176100384Speter			if (error)
177100384Speter				return (error);
178100384Speter		}
179100384Speter	}
180100384Speter	return (error);
181100384Speter}
182100384Speter
183100384Speterstruct sigaltstack32 {
184100384Speter	u_int32_t	ss_sp;
185100384Speter	u_int32_t	ss_size;
186100384Speter	int		ss_flags;
187100384Speter};
188100384Speter
189121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12);
190121719Speter
191100384Speterint
192119333Speterfreebsd32_sigaltstack(struct thread *td,
193119333Speter		      struct freebsd32_sigaltstack_args *uap)
194100384Speter{
195113859Sjhb	struct sigaltstack32 s32;
196113859Sjhb	struct sigaltstack ss, oss, *ssp;
197100384Speter	int error;
198100384Speter
199113859Sjhb	if (uap->ss != NULL) {
200113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
201100384Speter		if (error)
202100384Speter			return (error);
203113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
204113859Sjhb		CP(s32, ss, ss_size);
205113859Sjhb		CP(s32, ss, ss_flags);
206113859Sjhb		ssp = &ss;
207113859Sjhb	} else
208113859Sjhb		ssp = NULL;
209113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
210113859Sjhb	if (error == 0 && uap->oss != NULL) {
211113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
212113859Sjhb		CP(oss, s32, ss_size);
213113859Sjhb		CP(oss, s32, ss_flags);
214113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
215100384Speter	}
216100384Speter	return (error);
217100384Speter}
218100384Speter
219100384Speterint
220119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
221100384Speter{
222100384Speter	int error;
223100384Speter	caddr_t sg;
224100384Speter	struct execve_args ap;
225100384Speter	u_int32_t *p32, arg;
226122253Speter	char **p, *p64;
227100384Speter	int count;
228100384Speter
229100384Speter	sg = stackgap_init();
230107849Salfred	ap.fname = uap->fname;
231100384Speter
232107849Salfred	if (uap->argv) {
233100384Speter		count = 0;
234107849Salfred		p32 = uap->argv;
235100384Speter		do {
236100384Speter			error = copyin(p32++, &arg, sizeof(arg));
237100384Speter			if (error)
238100384Speter				return error;
239100384Speter			count++;
240100384Speter		} while (arg != 0);
241100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
242107849Salfred		ap.argv = p;
243107849Salfred		p32 = uap->argv;
244100384Speter		do {
245100384Speter			error = copyin(p32++, &arg, sizeof(arg));
246100384Speter			if (error)
247100384Speter				return error;
248122253Speter			p64 = PTRIN(arg);
249122253Speter			error = copyout(&p64, p++, sizeof(p64));
250122253Speter			if (error)
251122253Speter				return error;
252100384Speter		} while (arg != 0);
253100384Speter	}
254107849Salfred	if (uap->envv) {
255100384Speter		count = 0;
256107849Salfred		p32 = uap->envv;
257100384Speter		do {
258100384Speter			error = copyin(p32++, &arg, sizeof(arg));
259100384Speter			if (error)
260100384Speter				return error;
261100384Speter			count++;
262100384Speter		} while (arg != 0);
263100384Speter		p = stackgap_alloc(&sg, count * sizeof(char *));
264107849Salfred		ap.envv = p;
265107849Salfred		p32 = uap->envv;
266100384Speter		do {
267100384Speter			error = copyin(p32++, &arg, sizeof(arg));
268100384Speter			if (error)
269100384Speter				return error;
270122253Speter			p64 = PTRIN(arg);
271122253Speter			error = copyout(&p64, p++, sizeof(p64));
272122253Speter			if (error)
273122253Speter				return error;
274100384Speter		} while (arg != 0);
275100384Speter	}
276100384Speter
277100384Speter	return execve(td, &ap);
278100384Speter}
279100384Speter
280114987Speter#ifdef __ia64__
281100384Speterstatic int
282119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
283119333Speter		       int prot, int fd, off_t pos)
284100384Speter{
285100384Speter	vm_map_t map;
286100384Speter	vm_map_entry_t entry;
287100384Speter	int rv;
288100384Speter
289100384Speter	map = &td->td_proc->p_vmspace->vm_map;
290100384Speter	if (fd != -1)
291100384Speter		prot |= VM_PROT_WRITE;
292100384Speter
293100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
294100384Speter		if ((entry->protection & prot) != prot) {
295100384Speter			rv = vm_map_protect(map,
296100384Speter					    trunc_page(start),
297100384Speter					    round_page(end),
298100384Speter					    entry->protection | prot,
299100384Speter					    FALSE);
300100384Speter			if (rv != KERN_SUCCESS)
301100384Speter				return (EINVAL);
302100384Speter		}
303100384Speter	} else {
304100384Speter		vm_offset_t addr = trunc_page(start);
305100384Speter		rv = vm_map_find(map, 0, 0,
306100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
307100384Speter				 VM_PROT_ALL, 0);
308100384Speter		if (rv != KERN_SUCCESS)
309100384Speter			return (EINVAL);
310100384Speter	}
311100384Speter
312100384Speter	if (fd != -1) {
313100384Speter		struct pread_args r;
314107849Salfred		r.fd = fd;
315107849Salfred		r.buf = (void *) start;
316107849Salfred		r.nbyte = end - start;
317107849Salfred		r.offset = pos;
318100384Speter		return (pread(td, &r));
319100384Speter	} else {
320100384Speter		while (start < end) {
321100384Speter			subyte((void *) start, 0);
322100384Speter			start++;
323100384Speter		}
324100384Speter		return (0);
325100384Speter	}
326100384Speter}
327114987Speter#endif
328100384Speter
329100384Speterint
330119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
331100384Speter{
332100384Speter	struct mmap_args ap;
333107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
334107849Salfred	vm_size_t len	 = uap->len;
335107849Salfred	int prot	 = uap->prot;
336107849Salfred	int flags	 = uap->flags;
337107849Salfred	int fd		 = uap->fd;
338107849Salfred	off_t pos	 = (uap->poslo
339107849Salfred			    | ((off_t)uap->poshi << 32));
340114987Speter#ifdef __ia64__
341100384Speter	vm_size_t pageoff;
342100384Speter	int error;
343100384Speter
344100384Speter	/*
345100384Speter	 * Attempt to handle page size hassles.
346100384Speter	 */
347100384Speter	pageoff = (pos & PAGE_MASK);
348100384Speter	if (flags & MAP_FIXED) {
349100384Speter		vm_offset_t start, end;
350100384Speter		start = addr;
351100384Speter		end = addr + len;
352100384Speter
353100384Speter		if (start != trunc_page(start)) {
354119333Speter			error = freebsd32_mmap_partial(td, start,
355119333Speter						       round_page(start), prot,
356119333Speter						       fd, pos);
357100384Speter			if (fd != -1)
358100384Speter				pos += round_page(start) - start;
359100384Speter			start = round_page(start);
360100384Speter		}
361100384Speter		if (end != round_page(end)) {
362100384Speter			vm_offset_t t = trunc_page(end);
363119333Speter			error = freebsd32_mmap_partial(td, t, end,
364100384Speter						  prot, fd,
365100384Speter						  pos + t - start);
366100384Speter			end = trunc_page(end);
367100384Speter		}
368100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
369100384Speter			/*
370100384Speter			 * We can't map this region at all. The specified
371100384Speter			 * address doesn't have the same alignment as the file
372100384Speter			 * position. Fake the mapping by simply reading the
373100384Speter			 * entire region into memory. First we need to make
374100384Speter			 * sure the region exists.
375100384Speter			 */
376100384Speter			vm_map_t map;
377100384Speter			struct pread_args r;
378100384Speter			int rv;
379100384Speter
380100384Speter			prot |= VM_PROT_WRITE;
381100384Speter			map = &td->td_proc->p_vmspace->vm_map;
382100384Speter			rv = vm_map_remove(map, start, end);
383100384Speter			if (rv != KERN_SUCCESS)
384100384Speter				return (EINVAL);
385100384Speter			rv = vm_map_find(map, 0, 0,
386100384Speter					 &start, end - start, FALSE,
387100384Speter					 prot, VM_PROT_ALL, 0);
388100384Speter			if (rv != KERN_SUCCESS)
389100384Speter				return (EINVAL);
390107849Salfred			r.fd = fd;
391107849Salfred			r.buf = (void *) start;
392107849Salfred			r.nbyte = end - start;
393107849Salfred			r.offset = pos;
394100384Speter			error = pread(td, &r);
395100384Speter			if (error)
396100384Speter				return (error);
397100384Speter
398100384Speter			td->td_retval[0] = addr;
399100384Speter			return (0);
400100384Speter		}
401100384Speter		if (end == start) {
402100384Speter			/*
403100384Speter			 * After dealing with the ragged ends, there
404100384Speter			 * might be none left.
405100384Speter			 */
406100384Speter			td->td_retval[0] = addr;
407100384Speter			return (0);
408100384Speter		}
409100384Speter		addr = start;
410100384Speter		len = end - start;
411100384Speter	}
412114987Speter#endif
413100384Speter
414107849Salfred	ap.addr = (void *) addr;
415107849Salfred	ap.len = len;
416107849Salfred	ap.prot = prot;
417107849Salfred	ap.flags = flags;
418107849Salfred	ap.fd = fd;
419107849Salfred	ap.pos = pos;
420100384Speter
421100384Speter	return (mmap(td, &ap));
422100384Speter}
423100384Speter
424100384Speterstruct itimerval32 {
425100384Speter	struct timeval32 it_interval;
426100384Speter	struct timeval32 it_value;
427100384Speter};
428100384Speter
429121719SpeterCTASSERT(sizeof(struct itimerval32) == 16);
430121719Speter
431100384Speterint
432119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
433100384Speter{
434100384Speter	int error;
435100384Speter	caddr_t sg;
436100384Speter	struct itimerval32 *p32, *op32, s32;
437100384Speter	struct itimerval *p = NULL, *op = NULL, s;
438100384Speter
439107849Salfred	p32 = uap->itv;
440100384Speter	if (p32) {
441100384Speter		sg = stackgap_init();
442100384Speter		p = stackgap_alloc(&sg, sizeof(struct itimerval));
443107849Salfred		uap->itv = (struct itimerval32 *)p;
444100384Speter		error = copyin(p32, &s32, sizeof(s32));
445100384Speter		if (error)
446100384Speter			return (error);
447100384Speter		TV_CP(s32, s, it_interval);
448100384Speter		TV_CP(s32, s, it_value);
449100384Speter		error = copyout(&s, p, sizeof(s));
450100384Speter		if (error)
451100384Speter			return (error);
452100384Speter	}
453107849Salfred	op32 = uap->oitv;
454100384Speter	if (op32) {
455100384Speter		sg = stackgap_init();
456100384Speter		op = stackgap_alloc(&sg, sizeof(struct itimerval));
457107849Salfred		uap->oitv = (struct itimerval32 *)op;
458100384Speter	}
459100384Speter	error = setitimer(td, (struct setitimer_args *) uap);
460100384Speter	if (error)
461100384Speter		return (error);
462100384Speter	if (op32) {
463100384Speter		error = copyin(op, &s, sizeof(s));
464100384Speter		if (error)
465100384Speter			return (error);
466100384Speter		TV_CP(s, s32, it_interval);
467100384Speter		TV_CP(s, s32, it_value);
468100384Speter		error = copyout(&s32, op32, sizeof(s32));
469100384Speter	}
470100384Speter	return (error);
471100384Speter}
472100384Speter
473100384Speterint
474125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
475125171Speter{
476125171Speter	int error;
477125171Speter	caddr_t sg;
478125171Speter	struct itimerval32 *p32, s32;
479125171Speter	struct itimerval *p = NULL, s;
480125171Speter
481125171Speter	p32 = uap->itv;
482125171Speter	if (p32) {
483125171Speter		sg = stackgap_init();
484125171Speter		p = stackgap_alloc(&sg, sizeof(struct itimerval));
485125171Speter		uap->itv = (struct itimerval32 *)p;
486125171Speter	}
487125171Speter	error = getitimer(td, (struct getitimer_args *) uap);
488125171Speter	if (error)
489125171Speter		return (error);
490125171Speter	if (p32) {
491125171Speter		error = copyin(p, &s, sizeof(s));
492125171Speter		if (error)
493125171Speter			return (error);
494125171Speter		TV_CP(s, s32, it_interval);
495125171Speter		TV_CP(s, s32, it_value);
496125171Speter		error = copyout(&s32, p32, sizeof(s32));
497125171Speter	}
498125171Speter	return (error);
499125171Speter}
500125171Speter
501125171Speterint
502119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
503100384Speter{
504100384Speter	int error;
505100384Speter	caddr_t sg;
506100384Speter	struct timeval32 *p32, s32;
507100384Speter	struct timeval *p = NULL, s;
508100384Speter
509107849Salfred	p32 = uap->tv;
510100384Speter	if (p32) {
511100384Speter		sg = stackgap_init();
512100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
513107849Salfred		uap->tv = (struct timeval32 *)p;
514100384Speter		error = copyin(p32, &s32, sizeof(s32));
515100384Speter		if (error)
516100384Speter			return (error);
517100384Speter		CP(s32, s, tv_sec);
518100384Speter		CP(s32, s, tv_usec);
519100384Speter		error = copyout(&s, p, sizeof(s));
520100384Speter		if (error)
521100384Speter			return (error);
522100384Speter	}
523100384Speter	/*
524100384Speter	 * XXX big-endian needs to convert the fd_sets too.
525100384Speter	 */
526100384Speter	return (select(td, (struct select_args *) uap));
527100384Speter}
528100384Speter
529114987Speterstruct kevent32 {
530114987Speter	u_int32_t	ident;		/* identifier for this event */
531114987Speter	short		filter;		/* filter for event */
532114987Speter	u_short		flags;
533114987Speter	u_int		fflags;
534114987Speter	int32_t		data;
535114987Speter	u_int32_t	udata;		/* opaque user data identifier */
536114987Speter};
537114987Speter
538121719SpeterCTASSERT(sizeof(struct kevent32) == 20);
539121719Speter
540100384Speterint
541119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
542114987Speter{
543114987Speter	int error;
544114987Speter	caddr_t sg;
545114987Speter	struct timespec32 ts32;
546114987Speter	struct timespec ts;
547114987Speter	struct kevent32 ks32;
548114987Speter	struct kevent *ks;
549114987Speter	struct kevent_args a;
550114987Speter	int i;
551114987Speter
552114987Speter	sg = stackgap_init();
553114987Speter
554114987Speter	a.fd = uap->fd;
555114987Speter	a.changelist = uap->changelist;
556114987Speter	a.nchanges = uap->nchanges;
557114987Speter	a.eventlist = uap->eventlist;
558114987Speter	a.nevents = uap->nevents;
559114987Speter	a.timeout = NULL;
560114987Speter
561114987Speter	if (uap->timeout) {
562114987Speter		a.timeout = stackgap_alloc(&sg, sizeof(struct timespec));
563114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
564114987Speter		if (error)
565114987Speter			return (error);
566114987Speter		CP(ts32, ts, tv_sec);
567114987Speter		CP(ts32, ts, tv_nsec);
568114987Speter		error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts));
569114987Speter		if (error)
570114987Speter			return (error);
571114987Speter	}
572114987Speter	if (uap->changelist) {
573119333Speter		a.changelist = (struct kevent *)stackgap_alloc(&sg,
574119333Speter		    uap->nchanges * sizeof(struct kevent));
575114987Speter		for (i = 0; i < uap->nchanges; i++) {
576119333Speter			error = copyin(&uap->changelist[i], &ks32,
577119333Speter			    sizeof(ks32));
578114987Speter			if (error)
579114987Speter				return (error);
580114987Speter			ks = (struct kevent *)(uintptr_t)&a.changelist[i];
581114987Speter			CP(ks32, *ks, ident);
582114987Speter			CP(ks32, *ks, filter);
583114987Speter			CP(ks32, *ks, flags);
584114987Speter			CP(ks32, *ks, fflags);
585114987Speter			CP(ks32, *ks, data);
586114987Speter			PTRIN_CP(ks32, *ks, udata);
587114987Speter		}
588114987Speter	}
589114987Speter	if (uap->eventlist) {
590119333Speter		a.eventlist = stackgap_alloc(&sg,
591119333Speter		    uap->nevents * sizeof(struct kevent));
592114987Speter	}
593114987Speter	error = kevent(td, &a);
594114987Speter	if (uap->eventlist && error > 0) {
595114987Speter		for (i = 0; i < error; i++) {
596114987Speter			ks = &a.eventlist[i];
597114987Speter			CP(*ks, ks32, ident);
598114987Speter			CP(*ks, ks32, filter);
599114987Speter			CP(*ks, ks32, flags);
600114987Speter			CP(*ks, ks32, fflags);
601114987Speter			CP(*ks, ks32, data);
602114987Speter			PTROUT_CP(*ks, ks32, udata);
603119333Speter			error = copyout(&ks32, &uap->eventlist[i],
604119333Speter			    sizeof(ks32));
605114987Speter			if (error)
606114987Speter				return (error);
607114987Speter		}
608114987Speter	}
609114987Speter	return error;
610114987Speter}
611114987Speter
612114987Speterint
613119333Speterfreebsd32_gettimeofday(struct thread *td,
614119333Speter		       struct freebsd32_gettimeofday_args *uap)
615100384Speter{
616123425Speter	struct timeval atv;
617123425Speter	struct timeval32 atv32;
618123425Speter	struct timezone rtz;
619123425Speter	int error = 0;
620100384Speter
621123425Speter	if (uap->tp) {
622123425Speter		microtime(&atv);
623123425Speter		CP(atv, atv32, tv_sec);
624123425Speter		CP(atv, atv32, tv_usec);
625123425Speter		error = copyout(&atv32, uap->tp, sizeof (atv32));
626100384Speter	}
627123425Speter	if (error == 0 && uap->tzp != NULL) {
628123425Speter		rtz.tz_minuteswest = tz_minuteswest;
629123425Speter		rtz.tz_dsttime = tz_dsttime;
630123425Speter		error = copyout(&rtz, uap->tzp, sizeof (rtz));
631100384Speter	}
632100384Speter	return (error);
633100384Speter}
634100384Speter
635100384Speterint
636119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
637100384Speter{
638100384Speter	int error;
639100384Speter	caddr_t sg;
640100384Speter	struct rusage32 *p32, s32;
641100384Speter	struct rusage *p = NULL, s;
642100384Speter
643107849Salfred	p32 = uap->rusage;
644100384Speter	if (p32) {
645100384Speter		sg = stackgap_init();
646100384Speter		p = stackgap_alloc(&sg, sizeof(struct rusage));
647107849Salfred		uap->rusage = (struct rusage32 *)p;
648100384Speter	}
649100384Speter	error = getrusage(td, (struct getrusage_args *) uap);
650100384Speter	if (error)
651100384Speter		return (error);
652100384Speter	if (p32) {
653100384Speter		error = copyin(p, &s, sizeof(s));
654100384Speter		if (error)
655100384Speter			return (error);
656100384Speter		TV_CP(s, s32, ru_utime);
657100384Speter		TV_CP(s, s32, ru_stime);
658100384Speter		CP(s, s32, ru_maxrss);
659100384Speter		CP(s, s32, ru_ixrss);
660100384Speter		CP(s, s32, ru_idrss);
661100384Speter		CP(s, s32, ru_isrss);
662100384Speter		CP(s, s32, ru_minflt);
663100384Speter		CP(s, s32, ru_majflt);
664100384Speter		CP(s, s32, ru_nswap);
665100384Speter		CP(s, s32, ru_inblock);
666100384Speter		CP(s, s32, ru_oublock);
667100384Speter		CP(s, s32, ru_msgsnd);
668100384Speter		CP(s, s32, ru_msgrcv);
669100384Speter		CP(s, s32, ru_nsignals);
670100384Speter		CP(s, s32, ru_nvcsw);
671100384Speter		CP(s, s32, ru_nivcsw);
672100384Speter		error = copyout(&s32, p32, sizeof(s32));
673100384Speter	}
674100384Speter	return (error);
675100384Speter}
676100384Speter
677100384Speterstruct iovec32 {
678100384Speter	u_int32_t iov_base;
679100384Speter	int	iov_len;
680100384Speter};
681100384Speter#define	STACKGAPLEN	400
682100384Speter
683121719SpeterCTASSERT(sizeof(struct iovec32) == 8);
684121719Speter
685100384Speterint
686119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
687100384Speter{
688100384Speter	int error, osize, nsize, i;
689100384Speter	caddr_t sg;
690100384Speter	struct readv_args /* {
691100384Speter		syscallarg(int) fd;
692100384Speter		syscallarg(struct iovec *) iovp;
693100384Speter		syscallarg(u_int) iovcnt;
694100384Speter	} */ a;
695100384Speter	struct iovec32 *oio;
696100384Speter	struct iovec *nio;
697100384Speter
698100384Speter	sg = stackgap_init();
699100384Speter
700107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
701100384Speter		return (EINVAL);
702100384Speter
703107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
704107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
705100384Speter
706111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
707111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
708100384Speter
709100384Speter	error = 0;
710107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
711100384Speter		goto punt;
712107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
713100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
714100384Speter		nio[i].iov_len = oio[i].iov_len;
715100384Speter	}
716100384Speter
717107849Salfred	a.fd = uap->fd;
718107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
719107849Salfred	a.iovcnt = uap->iovcnt;
720100384Speter
721107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
722100384Speter		goto punt;
723100384Speter	error = readv(td, &a);
724100384Speter
725100384Speterpunt:
726100384Speter	free(oio, M_TEMP);
727100384Speter	free(nio, M_TEMP);
728100384Speter	return (error);
729100384Speter}
730100384Speter
731100384Speterint
732119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
733100384Speter{
734100384Speter	int error, i, nsize, osize;
735100384Speter	caddr_t sg;
736100384Speter	struct writev_args /* {
737100384Speter		syscallarg(int) fd;
738100384Speter		syscallarg(struct iovec *) iovp;
739100384Speter		syscallarg(u_int) iovcnt;
740100384Speter	} */ a;
741100384Speter	struct iovec32 *oio;
742100384Speter	struct iovec *nio;
743100384Speter
744100384Speter	sg = stackgap_init();
745100384Speter
746107849Salfred	if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
747100384Speter		return (EINVAL);
748100384Speter
749107849Salfred	osize = uap->iovcnt * sizeof (struct iovec32);
750107849Salfred	nsize = uap->iovcnt * sizeof (struct iovec);
751100384Speter
752111119Simp	oio = malloc(osize, M_TEMP, M_WAITOK);
753111119Simp	nio = malloc(nsize, M_TEMP, M_WAITOK);
754100384Speter
755100384Speter	error = 0;
756107849Salfred	if ((error = copyin(uap->iovp, oio, osize)))
757100384Speter		goto punt;
758107849Salfred	for (i = 0; i < uap->iovcnt; i++) {
759100384Speter		nio[i].iov_base = PTRIN(oio[i].iov_base);
760100384Speter		nio[i].iov_len = oio[i].iov_len;
761100384Speter	}
762100384Speter
763107849Salfred	a.fd = uap->fd;
764107849Salfred	a.iovp = stackgap_alloc(&sg, nsize);
765107849Salfred	a.iovcnt = uap->iovcnt;
766100384Speter
767107849Salfred	if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
768100384Speter		goto punt;
769100384Speter	error = writev(td, &a);
770100384Speter
771100384Speterpunt:
772100384Speter	free(oio, M_TEMP);
773100384Speter	free(nio, M_TEMP);
774100384Speter	return (error);
775100384Speter}
776100384Speter
777100384Speterint
778119333Speterfreebsd32_settimeofday(struct thread *td,
779119333Speter		       struct freebsd32_settimeofday_args *uap)
780100384Speter{
781100384Speter	int error;
782100384Speter	caddr_t sg;
783100384Speter	struct timeval32 *p32, s32;
784100384Speter	struct timeval *p = NULL, s;
785100384Speter
786107849Salfred	p32 = uap->tv;
787100384Speter	if (p32) {
788100384Speter		sg = stackgap_init();
789100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
790107849Salfred		uap->tv = (struct timeval32 *)p;
791100384Speter		error = copyin(p32, &s32, sizeof(s32));
792100384Speter		if (error)
793100384Speter			return (error);
794100384Speter		CP(s32, s, tv_sec);
795100384Speter		CP(s32, s, tv_usec);
796100384Speter		error = copyout(&s, p, sizeof(s));
797100384Speter		if (error)
798100384Speter			return (error);
799100384Speter	}
800100384Speter	return (settimeofday(td, (struct settimeofday_args *) uap));
801100384Speter}
802100384Speter
803100384Speterint
804119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
805100384Speter{
806100384Speter	int error;
807100384Speter	caddr_t sg;
808100384Speter	struct timeval32 *p32, s32[2];
809100384Speter	struct timeval *p = NULL, s[2];
810100384Speter
811107849Salfred	p32 = uap->tptr;
812100384Speter	if (p32) {
813100384Speter		sg = stackgap_init();
814100384Speter		p = stackgap_alloc(&sg, 2*sizeof(struct timeval));
815107849Salfred		uap->tptr = (struct timeval32 *)p;
816100384Speter		error = copyin(p32, s32, sizeof(s32));
817100384Speter		if (error)
818100384Speter			return (error);
819100384Speter		CP(s32[0], s[0], tv_sec);
820100384Speter		CP(s32[0], s[0], tv_usec);
821100384Speter		CP(s32[1], s[1], tv_sec);
822100384Speter		CP(s32[1], s[1], tv_usec);
823100384Speter		error = copyout(s, p, sizeof(s));
824100384Speter		if (error)
825100384Speter			return (error);
826100384Speter	}
827100384Speter	return (utimes(td, (struct utimes_args *) uap));
828100384Speter}
829100384Speter
830100384Speterint
831119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
832100384Speter{
833100384Speter	int error;
834100384Speter	caddr_t sg;
835100384Speter	struct timeval32 *p32, *op32, s32;
836100384Speter	struct timeval *p = NULL, *op = NULL, s;
837100384Speter
838107849Salfred	p32 = uap->delta;
839100384Speter	if (p32) {
840100384Speter		sg = stackgap_init();
841100384Speter		p = stackgap_alloc(&sg, sizeof(struct timeval));
842107849Salfred		uap->delta = (struct timeval32 *)p;
843100384Speter		error = copyin(p32, &s32, sizeof(s32));
844100384Speter		if (error)
845100384Speter			return (error);
846100384Speter		CP(s32, s, tv_sec);
847100384Speter		CP(s32, s, tv_usec);
848100384Speter		error = copyout(&s, p, sizeof(s));
849100384Speter		if (error)
850100384Speter			return (error);
851100384Speter	}
852107849Salfred	op32 = uap->olddelta;
853100384Speter	if (op32) {
854100384Speter		sg = stackgap_init();
855100384Speter		op = stackgap_alloc(&sg, sizeof(struct timeval));
856107849Salfred		uap->olddelta = (struct timeval32 *)op;
857100384Speter	}
858100384Speter	error = utimes(td, (struct utimes_args *) uap);
859100384Speter	if (error)
860100384Speter		return error;
861100384Speter	if (op32) {
862100384Speter		error = copyin(op, &s, sizeof(s));
863100384Speter		if (error)
864100384Speter			return (error);
865100384Speter		CP(s, s32, tv_sec);
866100384Speter		CP(s, s32, tv_usec);
867100384Speter		error = copyout(&s32, op32, sizeof(s32));
868100384Speter	}
869100384Speter	return (error);
870100384Speter}
871100384Speter
872100384Speterint
873119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap)
874100384Speter{
875100384Speter	int error;
876100384Speter	caddr_t sg;
877100384Speter	struct statfs32 *p32, s32;
878100384Speter	struct statfs *p = NULL, s;
879100384Speter
880107849Salfred	p32 = uap->buf;
881100384Speter	if (p32) {
882100384Speter		sg = stackgap_init();
883100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
884107849Salfred		uap->buf = (struct statfs32 *)p;
885100384Speter	}
886100384Speter	error = statfs(td, (struct statfs_args *) uap);
887100384Speter	if (error)
888100384Speter		return (error);
889100384Speter	if (p32) {
890100384Speter		error = copyin(p, &s, sizeof(s));
891100384Speter		if (error)
892100384Speter			return (error);
893100384Speter		copy_statfs(&s, &s32);
894100384Speter		error = copyout(&s32, p32, sizeof(s32));
895100384Speter	}
896100384Speter	return (error);
897100384Speter}
898100384Speter
899100384Speterint
900119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap)
901100384Speter{
902100384Speter	int error;
903100384Speter	caddr_t sg;
904100384Speter	struct statfs32 *p32, s32;
905100384Speter	struct statfs *p = NULL, s;
906100384Speter
907107849Salfred	p32 = uap->buf;
908100384Speter	if (p32) {
909100384Speter		sg = stackgap_init();
910100384Speter		p = stackgap_alloc(&sg, sizeof(struct statfs));
911107849Salfred		uap->buf = (struct statfs32 *)p;
912100384Speter	}
913100384Speter	error = fstatfs(td, (struct fstatfs_args *) uap);
914100384Speter	if (error)
915100384Speter		return (error);
916100384Speter	if (p32) {
917100384Speter		error = copyin(p, &s, sizeof(s));
918100384Speter		if (error)
919100384Speter			return (error);
920100384Speter		copy_statfs(&s, &s32);
921100384Speter		error = copyout(&s32, p32, sizeof(s32));
922100384Speter	}
923100384Speter	return (error);
924100384Speter}
925100384Speter
926100384Speterint
927119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
928100384Speter{
929100384Speter	/*
930100384Speter	 * Vector through to semsys if it is loaded.
931100384Speter	 */
932100384Speter	return sysent[169].sy_call(td, uap);
933100384Speter}
934100384Speter
935100384Speterint
936119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
937100384Speter{
938100384Speter	/*
939100384Speter	 * Vector through to msgsys if it is loaded.
940100384Speter	 */
941100384Speter	return sysent[170].sy_call(td, uap);
942100384Speter}
943100384Speter
944100384Speterint
945119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
946100384Speter{
947100384Speter	/*
948100384Speter	 * Vector through to shmsys if it is loaded.
949100384Speter	 */
950100384Speter	return sysent[171].sy_call(td, uap);
951100384Speter}
952100384Speter
953100384Speterint
954119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
955100384Speter{
956100384Speter	struct pread_args ap;
957100384Speter
958107849Salfred	ap.fd = uap->fd;
959107849Salfred	ap.buf = uap->buf;
960107849Salfred	ap.nbyte = uap->nbyte;
961119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
962100384Speter	return (pread(td, &ap));
963100384Speter}
964100384Speter
965100384Speterint
966119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
967100384Speter{
968100384Speter	struct pwrite_args ap;
969100384Speter
970107849Salfred	ap.fd = uap->fd;
971107849Salfred	ap.buf = uap->buf;
972107849Salfred	ap.nbyte = uap->nbyte;
973119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
974100384Speter	return (pwrite(td, &ap));
975100384Speter}
976100384Speter
977100384Speterint
978119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
979100384Speter{
980100384Speter	int error;
981100384Speter	struct lseek_args ap;
982100384Speter	off_t pos;
983100384Speter
984107849Salfred	ap.fd = uap->fd;
985119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
986107849Salfred	ap.whence = uap->whence;
987100384Speter	error = lseek(td, &ap);
988100384Speter	/* Expand the quad return into two parts for eax and edx */
989100384Speter	pos = *(off_t *)(td->td_retval);
990100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
991100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
992100384Speter	return error;
993100384Speter}
994100384Speter
995100384Speterint
996119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
997100384Speter{
998100384Speter	struct truncate_args ap;
999100384Speter
1000107849Salfred	ap.path = uap->path;
1001119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1002100384Speter	return (truncate(td, &ap));
1003100384Speter}
1004100384Speter
1005100384Speterint
1006119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1007100384Speter{
1008100384Speter	struct ftruncate_args ap;
1009100384Speter
1010107849Salfred	ap.fd = uap->fd;
1011119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1012100384Speter	return (ftruncate(td, &ap));
1013100384Speter}
1014100384Speter
1015104738Speter#ifdef COMPAT_FREEBSD4
1016100384Speterint
1017119333Speterfreebsd4_freebsd32_sendfile(struct thread *td,
1018119333Speter    struct freebsd4_freebsd32_sendfile_args *uap)
1019104738Speter{
1020104738Speter	struct freebsd4_sendfile_args ap;
1021104738Speter
1022107849Salfred	ap.fd = uap->fd;
1023107849Salfred	ap.s = uap->s;
1024119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1025107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1026107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1027107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1028107849Salfred	ap.flags = uap->flags;
1029104738Speter	return (freebsd4_sendfile(td, &ap));
1030104738Speter}
1031104738Speter#endif
1032104738Speter
1033104738Speterint
1034119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1035100384Speter{
1036100384Speter	struct sendfile_args ap;
1037100384Speter
1038107849Salfred	ap.fd = uap->fd;
1039107849Salfred	ap.s = uap->s;
1040119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1041107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1042107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1043107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1044107849Salfred	ap.flags = uap->flags;
1045100384Speter	return (sendfile(td, &ap));
1046100384Speter}
1047100384Speter
1048100384Speterstruct stat32 {
1049100384Speter	udev_t	st_dev;
1050100384Speter	ino_t	st_ino;
1051100384Speter	mode_t	st_mode;
1052100384Speter	nlink_t	st_nlink;
1053100384Speter	uid_t	st_uid;
1054100384Speter	gid_t	st_gid;
1055100384Speter	udev_t	st_rdev;
1056100384Speter	struct timespec32 st_atimespec;
1057100384Speter	struct timespec32 st_mtimespec;
1058100384Speter	struct timespec32 st_ctimespec;
1059100384Speter	off_t	st_size;
1060100384Speter	int64_t	st_blocks;
1061100384Speter	u_int32_t st_blksize;
1062100384Speter	u_int32_t st_flags;
1063100384Speter	u_int32_t st_gen;
1064121719Speter	struct timespec32 st_birthtimespec;
1065121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1066121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1067100384Speter};
1068100384Speter
1069121719Speter
1070121719SpeterCTASSERT(sizeof(struct stat32) == 96);
1071121719Speter
1072100384Speterstatic void
1073100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1074100384Speter{
1075100384Speter	CP(*in, *out, st_dev);
1076100384Speter	CP(*in, *out, st_ino);
1077100384Speter	CP(*in, *out, st_mode);
1078100384Speter	CP(*in, *out, st_nlink);
1079100384Speter	CP(*in, *out, st_uid);
1080100384Speter	CP(*in, *out, st_gid);
1081100384Speter	CP(*in, *out, st_rdev);
1082100384Speter	TS_CP(*in, *out, st_atimespec);
1083100384Speter	TS_CP(*in, *out, st_mtimespec);
1084100384Speter	TS_CP(*in, *out, st_ctimespec);
1085100384Speter	CP(*in, *out, st_size);
1086100384Speter	CP(*in, *out, st_blocks);
1087100384Speter	CP(*in, *out, st_blksize);
1088100384Speter	CP(*in, *out, st_flags);
1089100384Speter	CP(*in, *out, st_gen);
1090100384Speter}
1091100384Speter
1092100384Speterint
1093119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1094100384Speter{
1095123746Speter	struct stat sb;
1096123746Speter	struct stat32 sb32;
1097100384Speter	int error;
1098123746Speter	struct nameidata nd;
1099100384Speter
1100123746Speter#ifdef LOOKUP_SHARED
1101123746Speter	NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ,
1102123746Speter	    UIO_USERSPACE, uap->path, td);
1103123746Speter#else
1104123746Speter	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1105123746Speter	    uap->path, td);
1106123746Speter#endif
1107123746Speter	if ((error = namei(&nd)) != 0)
1108123746Speter		return (error);
1109123746Speter	error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
1110123746Speter	NDFREE(&nd, NDF_ONLY_PNBUF);
1111123746Speter	vput(nd.ni_vp);
1112100384Speter	if (error)
1113100384Speter		return (error);
1114123746Speter	copy_stat(&sb, &sb32);
1115123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1116100384Speter	return (error);
1117100384Speter}
1118100384Speter
1119100384Speterint
1120119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1121100384Speter{
1122123746Speter	struct file *fp;
1123123746Speter	struct stat ub;
1124123746Speter	struct stat32 ub32;
1125100384Speter	int error;
1126100384Speter
1127123746Speter	if ((error = fget(td, uap->fd, &fp)) != 0)
1128123746Speter		return (error);
1129123746Speter	mtx_lock(&Giant);
1130123746Speter	error = fo_stat(fp, &ub, td->td_ucred, td);
1131123746Speter	mtx_unlock(&Giant);
1132123746Speter	fdrop(fp, td);
1133100384Speter	if (error)
1134100384Speter		return (error);
1135123746Speter	copy_stat(&ub, &ub32);
1136123746Speter	error = copyout(&ub32, uap->ub, sizeof(ub32));
1137100384Speter	return (error);
1138100384Speter}
1139100384Speter
1140100384Speterint
1141119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1142100384Speter{
1143100384Speter	int error;
1144123746Speter	struct vnode *vp;
1145123746Speter	struct stat sb;
1146123746Speter	struct stat32 sb32;
1147123746Speter	struct nameidata nd;
1148100384Speter
1149123746Speter	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1150123746Speter	    uap->path, td);
1151123746Speter	if ((error = namei(&nd)) != 0)
1152123746Speter		return (error);
1153123746Speter	vp = nd.ni_vp;
1154123746Speter	error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
1155123746Speter	NDFREE(&nd, NDF_ONLY_PNBUF);
1156123746Speter	vput(vp);
1157100384Speter	if (error)
1158100384Speter		return (error);
1159123746Speter	copy_stat(&sb, &sb32);
1160123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1161100384Speter	return (error);
1162100384Speter}
1163100384Speter
1164100384Speter/*
1165100384Speter * MPSAFE
1166100384Speter */
1167100384Speterint
1168119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1169100384Speter{
1170100384Speter	int error, name[CTL_MAXNAME];
1171100384Speter	size_t j, oldlen;
1172100384Speter
1173100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1174100384Speter		return (EINVAL);
1175100384Speter
1176100384Speter 	error = copyin(uap->name, &name, uap->namelen * sizeof(int));
1177100384Speter 	if (error)
1178100384Speter		return (error);
1179100384Speter
1180100384Speter	mtx_lock(&Giant);
1181100384Speter
1182100384Speter	if (uap->oldlenp)
1183100384Speter		oldlen = fuword32(uap->oldlenp);
1184100384Speter	else
1185100384Speter		oldlen = 0;
1186100384Speter	error = userland_sysctl(td, name, uap->namelen,
1187100384Speter		uap->old, &oldlen, 1,
1188100384Speter		uap->new, uap->newlen, &j);
1189100384Speter	if (error && error != ENOMEM)
1190100384Speter		goto done2;
1191100384Speter	if (uap->oldlenp) {
1192100384Speter		suword32(uap->oldlenp, j);
1193100384Speter	}
1194100384Speterdone2:
1195100384Speter	mtx_unlock(&Giant);
1196100384Speter	return (error);
1197100384Speter}
1198100384Speter
1199100384Speterstruct sigaction32 {
1200100384Speter	u_int32_t	sa_u;
1201100384Speter	int		sa_flags;
1202100384Speter	sigset_t	sa_mask;
1203100384Speter};
1204100384Speter
1205121719SpeterCTASSERT(sizeof(struct sigaction32) == 24);
1206121719Speter
1207100384Speterint
1208119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1209100384Speter{
1210113859Sjhb	struct sigaction32 s32;
1211113859Sjhb	struct sigaction sa, osa, *sap;
1212100384Speter	int error;
1213100384Speter
1214113859Sjhb	if (uap->act) {
1215113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1216100384Speter		if (error)
1217100384Speter			return (error);
1218113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1219113859Sjhb		CP(s32, sa, sa_flags);
1220113859Sjhb		CP(s32, sa, sa_mask);
1221113859Sjhb		sap = &sa;
1222113859Sjhb	} else
1223113859Sjhb		sap = NULL;
1224113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1225113859Sjhb	if (error != 0 && uap->oact != NULL) {
1226113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1227113859Sjhb		CP(osa, s32, sa_flags);
1228113859Sjhb		CP(osa, s32, sa_mask);
1229113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1230100384Speter	}
1231100384Speter	return (error);
1232100384Speter}
1233100384Speter
1234114987Speter#ifdef COMPAT_FREEBSD4
1235114987Speterint
1236119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1237119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1238114987Speter{
1239114987Speter	struct sigaction32 s32;
1240114987Speter	struct sigaction sa, osa, *sap;
1241114987Speter	int error;
1242114987Speter
1243114987Speter	if (uap->act) {
1244114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1245114987Speter		if (error)
1246114987Speter			return (error);
1247114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1248114987Speter		CP(s32, sa, sa_flags);
1249114987Speter		CP(s32, sa, sa_mask);
1250114987Speter		sap = &sa;
1251114987Speter	} else
1252114987Speter		sap = NULL;
1253114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1254114987Speter	if (error != 0 && uap->oact != NULL) {
1255114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1256114987Speter		CP(osa, s32, sa_flags);
1257114987Speter		CP(osa, s32, sa_mask);
1258114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1259114987Speter	}
1260114987Speter	return (error);
1261114987Speter}
1262114987Speter#endif
1263114987Speter
1264100384Speter#if 0
1265100384Speter
1266100384Speterint
1267119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
1268100384Speter{
1269100384Speter	int error;
1270100384Speter	caddr_t sg;
1271100384Speter	struct yyy32 *p32, s32;
1272100384Speter	struct yyy *p = NULL, s;
1273100384Speter
1274107849Salfred	p32 = uap->zzz;
1275100384Speter	if (p32) {
1276100384Speter		sg = stackgap_init();
1277100384Speter		p = stackgap_alloc(&sg, sizeof(struct yyy));
1278107849Salfred		uap->zzz = (struct yyy32 *)p;
1279100384Speter		error = copyin(p32, &s32, sizeof(s32));
1280100384Speter		if (error)
1281100384Speter			return (error);
1282100384Speter		/* translate in */
1283100384Speter		error = copyout(&s, p, sizeof(s));
1284100384Speter		if (error)
1285100384Speter			return (error);
1286100384Speter	}
1287100384Speter	error = xxx(td, (struct xxx_args *) uap);
1288100384Speter	if (error)
1289100384Speter		return (error);
1290100384Speter	if (p32) {
1291100384Speter		error = copyin(p, &s, sizeof(s));
1292100384Speter		if (error)
1293100384Speter			return (error);
1294100384Speter		/* translate out */
1295100384Speter		error = copyout(&s32, p32, sizeof(s32));
1296100384Speter	}
1297100384Speter	return (error);
1298100384Speter}
1299100384Speter
1300100384Speter#endif
1301