2 * Copyright (c) 2002 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include "opt_compat.h"
31 #include <sys/param.h>
32 #include <sys/systm.h>
34 #include <sys/dkstat.h>
36 #include <sys/fcntl.h>
37 #include <sys/filedesc.h>
38 #include <sys/imgact.h>
39 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/file.h> /* Must come after sys/malloc.h */
44 #include <sys/module.h>
45 #include <sys/mount.h>
46 #include <sys/mutex.h>
47 #include <sys/namei.h>
48 #include <sys/param.h>
50 #include <sys/reboot.h>
51 #include <sys/resource.h>
52 #include <sys/resourcevar.h>
53 #include <sys/selinfo.h>
54 #include <sys/pipe.h> /* Must come after sys/selinfo.h */
55 #include <sys/signal.h>
56 #include <sys/signalvar.h>
57 #include <sys/socket.h>
58 #include <sys/socketvar.h>
60 #include <sys/sysctl.h>
61 #include <sys/sysent.h>
62 #include <sys/sysproto.h>
63 #include <sys/systm.h>
64 #include <sys/unistd.h>
66 #include <sys/utsname.h>
67 #include <sys/vnode.h>
70 #include <vm/vm_kern.h>
71 #include <vm/vm_param.h>
73 #include <vm/vm_map.h>
74 #include <vm/vm_object.h>
75 #include <vm/vm_extern.h>
77 #include <ia64/ia32/ia32_util.h>
78 #include <ia64/ia32/ia32.h>
79 #include <ia64/ia32/ia32_proto.h>
81 static const char ia32_emul_path[] = "/compat/ia32";
83 * [ taken from the linux emulator ]
84 * Search an alternate path before passing pathname arguments on
85 * to system calls. Useful for keeping a separate 'emulation tree'.
87 * If cflag is set, we check if an attempt can be made to create
88 * the named file, i.e. we check if the directory it should
92 ia32_emul_find(td, sgp, prefix, path, pbuf, cflag)
94 caddr_t *sgp; /* Pointer to stackgap memory */
102 char *buf, *cp, *ptr;
105 struct nameidata ndroot;
107 struct vattr vatroot;
109 buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
112 for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
115 sz = MAXPATHLEN - (ptr - buf);
118 * If sgp is not given then the path is already in kernel space
121 error = copystr(path, ptr, sz, &len);
123 error = copyinstr(path, ptr, sz, &len);
136 * We know that there is a / somewhere in this pathname.
137 * Search backwards for it, to find the file's parent dir
138 * to see if it exists in the alternate tree. If it does,
139 * and we want to create a file (cflag is set). We don't
140 * need to worry about the root comparison in this case.
144 for (cp = &ptr[len] - 1; *cp != '/'; cp--)
148 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
150 if ((error = namei(&nd)) != 0) {
157 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
159 if ((error = namei(&nd)) != 0) {
165 * We now compare the vnode of the ia32_root to the one
166 * vnode asked. If they resolve to be the same, then we
167 * ignore the match so that the real root gets used.
168 * This avoids the problem of traversing "../.." to find the
169 * root directory and never finding it, because "/" resolves
170 * to the emulation root directory. This is expensive :-(
172 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, ia32_emul_path,
175 if ((error = namei(&ndroot)) != 0) {
182 ucred = td->td_ucred;
183 if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) {
187 if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred,
192 if (vat.va_fsid == vatroot.va_fsid &&
193 vat.va_fileid == vatroot.va_fileid) {
202 sz = &ptr[len] - buf;
203 *pbuf = stackgap_alloc(sgp, sz + 1);
204 error = copyout(buf, *pbuf, sz);
222 ia32_open(struct thread *td, struct ia32_open_args *uap)
226 sg = stackgap_init();
227 CHECKALTEXIST(td, &sg, uap->path);
229 return open(td, (struct open_args *) uap);
233 ia32_wait4(struct thread *td, struct ia32_wait4_args *uap)
237 struct rusage32 *rusage32, ru32;
238 struct rusage *rusage = NULL, ru;
240 rusage32 = SCARG(uap, rusage);
242 sg = stackgap_init();
243 rusage = stackgap_alloc(&sg, sizeof(struct rusage));
244 SCARG(uap, rusage) = (struct rusage32 *)rusage;
246 error = wait4(td, (struct wait_args *)uap);
249 if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) {
250 TV_CP(ru, ru32, ru_utime);
251 TV_CP(ru, ru32, ru_stime);
252 CP(ru, ru32, ru_maxrss);
253 CP(ru, ru32, ru_ixrss);
254 CP(ru, ru32, ru_idrss);
255 CP(ru, ru32, ru_isrss);
256 CP(ru, ru32, ru_minflt);
257 CP(ru, ru32, ru_majflt);
258 CP(ru, ru32, ru_nswap);
259 CP(ru, ru32, ru_inblock);
260 CP(ru, ru32, ru_oublock);
261 CP(ru, ru32, ru_msgsnd);
262 CP(ru, ru32, ru_msgrcv);
263 CP(ru, ru32, ru_nsignals);
264 CP(ru, ru32, ru_nvcsw);
265 CP(ru, ru32, ru_nivcsw);
266 error = copyout(&ru32, rusage32, sizeof(ru32));
272 copy_statfs(struct statfs *in, struct statfs32 *out)
274 CP(*in, *out, f_bsize);
275 CP(*in, *out, f_iosize);
276 CP(*in, *out, f_blocks);
277 CP(*in, *out, f_bfree);
278 CP(*in, *out, f_bavail);
279 CP(*in, *out, f_files);
280 CP(*in, *out, f_ffree);
281 CP(*in, *out, f_fsid);
282 CP(*in, *out, f_owner);
283 CP(*in, *out, f_type);
284 CP(*in, *out, f_flags);
285 CP(*in, *out, f_flags);
286 CP(*in, *out, f_syncwrites);
287 CP(*in, *out, f_asyncwrites);
288 bcopy(in->f_fstypename,
289 out->f_fstypename, MFSNAMELEN);
290 bcopy(in->f_mntonname,
291 out->f_mntonname, MNAMELEN);
292 CP(*in, *out, f_syncreads);
293 CP(*in, *out, f_asyncreads);
294 bcopy(in->f_mntfromname,
295 out->f_mntfromname, MNAMELEN);
299 ia32_getfsstat(struct thread *td, struct ia32_getfsstat_args *uap)
303 struct statfs32 *sp32, stat32;
304 struct statfs *sp = NULL, stat;
305 int maxcount, count, i;
307 sp32 = SCARG(uap, buf);
308 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs32);
311 sg = stackgap_init();
312 sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
313 SCARG(uap, buf) = (struct statfs32 *)sp;
315 error = getfsstat(td, (struct getfsstat_args *) uap);
316 if (sp32 && !error) {
317 count = td->td_retval[0];
318 for (i = 0; i < count; i++) {
319 error = copyin(&sp[i], &stat, sizeof(stat));
322 copy_statfs(&stat, &stat32);
323 error = copyout(&stat32, &sp32[i], sizeof(stat32));
332 ia32_access(struct thread *td, struct ia32_access_args *uap)
336 sg = stackgap_init();
337 CHECKALTEXIST(td, &sg, uap->path);
339 return access(td, (struct access_args *)uap);
343 ia32_chflags(struct thread *td, struct ia32_chflags_args *uap)
347 sg = stackgap_init();
348 CHECKALTEXIST(td, &sg, uap->path);
350 return chflags(td, (struct chflags_args *)uap);
353 struct sigaltstack32 {
360 ia32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap)
364 struct sigaltstack32 *p32, *op32, s32;
365 struct sigaltstack *p = NULL, *op = NULL, s;
367 p32 = SCARG(uap, ss);
369 sg = stackgap_init();
370 p = stackgap_alloc(&sg, sizeof(struct sigaltstack));
371 SCARG(uap, ss) = (struct sigaltstack32 *)p;
372 error = copyin(p32, &s32, sizeof(s32));
375 PTRIN_CP(s32, s, ss_sp);
377 CP(s32, s, ss_flags);
378 error = copyout(&s, p, sizeof(s));
382 op32 = SCARG(uap, oss);
384 sg = stackgap_init();
385 op = stackgap_alloc(&sg, sizeof(struct sigaltstack));
386 SCARG(uap, oss) = (struct sigaltstack32 *)op;
388 error = sigaltstack(td, (struct sigaltstack_args *) uap);
392 error = copyin(op, &s, sizeof(s));
395 PTROUT_CP(s, s32, ss_sp);
397 CP(s, s32, ss_flags);
398 error = copyout(&s32, op32, sizeof(s32));
404 ia32_execve(struct thread *td, struct ia32_execve_args *uap)
408 struct execve_args ap;
413 sg = stackgap_init();
414 CHECKALTEXIST(td, &sg, SCARG(uap, fname));
415 SCARG(&ap, fname) = SCARG(uap, fname);
417 if (SCARG(uap, argv)) {
419 p32 = SCARG(uap, argv);
421 error = copyin(p32++, &arg, sizeof(arg));
426 p = stackgap_alloc(&sg, count * sizeof(char *));
427 SCARG(&ap, argv) = p;
428 p32 = SCARG(uap, argv);
430 error = copyin(p32++, &arg, sizeof(arg));
436 if (SCARG(uap, envv)) {
438 p32 = SCARG(uap, envv);
440 error = copyin(p32++, &arg, sizeof(arg));
445 p = stackgap_alloc(&sg, count * sizeof(char *));
446 SCARG(&ap, envv) = p;
447 p32 = SCARG(uap, envv);
449 error = copyin(p32++, &arg, sizeof(arg));
456 return execve(td, &ap);
460 ia32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
461 int prot, int fd, off_t pos)
464 vm_map_entry_t entry;
467 map = &td->td_proc->p_vmspace->vm_map;
469 prot |= VM_PROT_WRITE;
471 if (vm_map_lookup_entry(map, start, &entry)) {
472 if ((entry->protection & prot) != prot) {
473 rv = vm_map_protect(map,
476 entry->protection | prot,
478 if (rv != KERN_SUCCESS)
482 vm_offset_t addr = trunc_page(start);
483 rv = vm_map_find(map, 0, 0,
484 &addr, PAGE_SIZE, FALSE, prot,
486 if (rv != KERN_SUCCESS)
493 SCARG(&r, buf) = (void *) start;
494 SCARG(&r, nbyte) = end - start;
495 SCARG(&r, offset) = pos;
496 return (pread(td, &r));
498 while (start < end) {
499 subyte((void *) start, 0);
507 ia32_mmap(struct thread *td, struct ia32_mmap_args *uap)
510 vm_offset_t addr = (vm_offset_t) SCARG(uap, addr);
511 vm_size_t len = SCARG(uap, len);
512 int prot = SCARG(uap, prot);
513 int flags = SCARG(uap, flags);
514 int fd = SCARG(uap, fd);
515 off_t pos = (SCARG(uap, poslo)
516 | ((off_t)SCARG(uap, poshi) << 32));
521 * Attempt to handle page size hassles.
523 pageoff = (pos & PAGE_MASK);
524 if (flags & MAP_FIXED) {
525 vm_offset_t start, end;
529 if (start != trunc_page(start)) {
530 error = ia32_mmap_partial(td, start, round_page(start),
533 pos += round_page(start) - start;
534 start = round_page(start);
536 if (end != round_page(end)) {
537 vm_offset_t t = trunc_page(end);
538 error = ia32_mmap_partial(td, t, end,
541 end = trunc_page(end);
543 if (end > start && fd != -1 && (pos & PAGE_MASK)) {
545 * We can't map this region at all. The specified
546 * address doesn't have the same alignment as the file
547 * position. Fake the mapping by simply reading the
548 * entire region into memory. First we need to make
549 * sure the region exists.
555 prot |= VM_PROT_WRITE;
556 map = &td->td_proc->p_vmspace->vm_map;
557 rv = vm_map_remove(map, start, end);
558 if (rv != KERN_SUCCESS)
560 rv = vm_map_find(map, 0, 0,
561 &start, end - start, FALSE,
562 prot, VM_PROT_ALL, 0);
563 if (rv != KERN_SUCCESS)
566 SCARG(&r, buf) = (void *) start;
567 SCARG(&r, nbyte) = end - start;
568 SCARG(&r, offset) = pos;
569 error = pread(td, &r);
573 td->td_retval[0] = addr;
578 * After dealing with the ragged ends, there
579 * might be none left.
581 td->td_retval[0] = addr;
588 SCARG(&ap, addr) = (void *) addr;
589 SCARG(&ap, len) = len;
590 SCARG(&ap, prot) = prot;
591 SCARG(&ap, flags) = flags;
593 SCARG(&ap, pos) = pos;
595 return (mmap(td, &ap));
599 struct timeval32 it_interval;
600 struct timeval32 it_value;
604 ia32_setitimer(struct thread *td, struct ia32_setitimer_args *uap)
608 struct itimerval32 *p32, *op32, s32;
609 struct itimerval *p = NULL, *op = NULL, s;
611 p32 = SCARG(uap, itv);
613 sg = stackgap_init();
614 p = stackgap_alloc(&sg, sizeof(struct itimerval));
615 SCARG(uap, itv) = (struct itimerval32 *)p;
616 error = copyin(p32, &s32, sizeof(s32));
619 TV_CP(s32, s, it_interval);
620 TV_CP(s32, s, it_value);
621 error = copyout(&s, p, sizeof(s));
625 op32 = SCARG(uap, oitv);
627 sg = stackgap_init();
628 op = stackgap_alloc(&sg, sizeof(struct itimerval));
629 SCARG(uap, oitv) = (struct itimerval32 *)op;
631 error = setitimer(td, (struct setitimer_args *) uap);
635 error = copyin(op, &s, sizeof(s));
638 TV_CP(s, s32, it_interval);
639 TV_CP(s, s32, it_value);
640 error = copyout(&s32, op32, sizeof(s32));
646 ia32_select(struct thread *td, struct ia32_select_args *uap)
650 struct timeval32 *p32, s32;
651 struct timeval *p = NULL, s;
653 p32 = SCARG(uap, tv);
655 sg = stackgap_init();
656 p = stackgap_alloc(&sg, sizeof(struct timeval));
657 SCARG(uap, tv) = (struct timeval32 *)p;
658 error = copyin(p32, &s32, sizeof(s32));
663 error = copyout(&s, p, sizeof(s));
668 * XXX big-endian needs to convert the fd_sets too.
670 return (select(td, (struct select_args *) uap));
674 ia32_gettimeofday(struct thread *td, struct ia32_gettimeofday_args *uap)
678 struct timeval32 *p32, s32;
679 struct timeval *p = NULL, s;
681 p32 = SCARG(uap, tp);
683 sg = stackgap_init();
684 p = stackgap_alloc(&sg, sizeof(struct timeval));
685 SCARG(uap, tp) = (struct timeval32 *)p;
687 error = gettimeofday(td, (struct gettimeofday_args *) uap);
691 error = copyin(p, &s, sizeof(s));
696 error = copyout(&s32, p32, sizeof(s32));
704 ia32_getrusage(struct thread *td, struct ia32_getrusage_args *uap)
708 struct rusage32 *p32, s32;
709 struct rusage *p = NULL, s;
711 p32 = SCARG(uap, rusage);
713 sg = stackgap_init();
714 p = stackgap_alloc(&sg, sizeof(struct rusage));
715 SCARG(uap, rusage) = (struct rusage32 *)p;
717 error = getrusage(td, (struct getrusage_args *) uap);
721 error = copyin(p, &s, sizeof(s));
724 TV_CP(s, s32, ru_utime);
725 TV_CP(s, s32, ru_stime);
726 CP(s, s32, ru_maxrss);
727 CP(s, s32, ru_ixrss);
728 CP(s, s32, ru_idrss);
729 CP(s, s32, ru_isrss);
730 CP(s, s32, ru_minflt);
731 CP(s, s32, ru_majflt);
732 CP(s, s32, ru_nswap);
733 CP(s, s32, ru_inblock);
734 CP(s, s32, ru_oublock);
735 CP(s, s32, ru_msgsnd);
736 CP(s, s32, ru_msgrcv);
737 CP(s, s32, ru_nsignals);
738 CP(s, s32, ru_nvcsw);
739 CP(s, s32, ru_nivcsw);
740 error = copyout(&s32, p32, sizeof(s32));
749 #define STACKGAPLEN 400
752 ia32_readv(struct thread *td, struct ia32_readv_args *uap)
754 int error, osize, nsize, i;
756 struct readv_args /* {
758 syscallarg(struct iovec *) iovp;
759 syscallarg(u_int) iovcnt;
764 sg = stackgap_init();
766 if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
769 osize = SCARG(uap, iovcnt) * sizeof (struct iovec32);
770 nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
772 oio = malloc(osize, M_TEMP, M_WAITOK);
773 nio = malloc(nsize, M_TEMP, M_WAITOK);
776 if ((error = copyin(SCARG(uap, iovp), oio, osize)))
778 for (i = 0; i < SCARG(uap, iovcnt); i++) {
779 nio[i].iov_base = PTRIN(oio[i].iov_base);
780 nio[i].iov_len = oio[i].iov_len;
783 SCARG(&a, fd) = SCARG(uap, fd);
784 SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
785 SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
787 if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
789 error = readv(td, &a);
798 ia32_writev(struct thread *td, struct ia32_writev_args *uap)
800 int error, i, nsize, osize;
802 struct writev_args /* {
804 syscallarg(struct iovec *) iovp;
805 syscallarg(u_int) iovcnt;
810 sg = stackgap_init();
812 if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
815 osize = SCARG(uap, iovcnt) * sizeof (struct iovec32);
816 nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
818 oio = malloc(osize, M_TEMP, M_WAITOK);
819 nio = malloc(nsize, M_TEMP, M_WAITOK);
822 if ((error = copyin(SCARG(uap, iovp), oio, osize)))
824 for (i = 0; i < SCARG(uap, iovcnt); i++) {
825 nio[i].iov_base = PTRIN(oio[i].iov_base);
826 nio[i].iov_len = oio[i].iov_len;
829 SCARG(&a, fd) = SCARG(uap, fd);
830 SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
831 SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
833 if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
835 error = writev(td, &a);
844 ia32_settimeofday(struct thread *td, struct ia32_settimeofday_args *uap)
848 struct timeval32 *p32, s32;
849 struct timeval *p = NULL, s;
851 p32 = SCARG(uap, tv);
853 sg = stackgap_init();
854 p = stackgap_alloc(&sg, sizeof(struct timeval));
855 SCARG(uap, tv) = (struct timeval32 *)p;
856 error = copyin(p32, &s32, sizeof(s32));
861 error = copyout(&s, p, sizeof(s));
865 return (settimeofday(td, (struct settimeofday_args *) uap));
869 ia32_utimes(struct thread *td, struct ia32_utimes_args *uap)
873 struct timeval32 *p32, s32[2];
874 struct timeval *p = NULL, s[2];
876 p32 = SCARG(uap, tptr);
878 sg = stackgap_init();
879 p = stackgap_alloc(&sg, 2*sizeof(struct timeval));
880 SCARG(uap, tptr) = (struct timeval32 *)p;
881 error = copyin(p32, s32, sizeof(s32));
884 CP(s32[0], s[0], tv_sec);
885 CP(s32[0], s[0], tv_usec);
886 CP(s32[1], s[1], tv_sec);
887 CP(s32[1], s[1], tv_usec);
888 error = copyout(s, p, sizeof(s));
892 return (utimes(td, (struct utimes_args *) uap));
896 ia32_adjtime(struct thread *td, struct ia32_adjtime_args *uap)
900 struct timeval32 *p32, *op32, s32;
901 struct timeval *p = NULL, *op = NULL, s;
903 p32 = SCARG(uap, delta);
905 sg = stackgap_init();
906 p = stackgap_alloc(&sg, sizeof(struct timeval));
907 SCARG(uap, delta) = (struct timeval32 *)p;
908 error = copyin(p32, &s32, sizeof(s32));
913 error = copyout(&s, p, sizeof(s));
917 op32 = SCARG(uap, olddelta);
919 sg = stackgap_init();
920 op = stackgap_alloc(&sg, sizeof(struct timeval));
921 SCARG(uap, olddelta) = (struct timeval32 *)op;
923 error = utimes(td, (struct utimes_args *) uap);
927 error = copyin(op, &s, sizeof(s));
932 error = copyout(&s32, op32, sizeof(s32));
938 ia32_statfs(struct thread *td, struct ia32_statfs_args *uap)
942 struct statfs32 *p32, s32;
943 struct statfs *p = NULL, s;
945 p32 = SCARG(uap, buf);
947 sg = stackgap_init();
948 p = stackgap_alloc(&sg, sizeof(struct statfs));
949 SCARG(uap, buf) = (struct statfs32 *)p;
951 error = statfs(td, (struct statfs_args *) uap);
955 error = copyin(p, &s, sizeof(s));
958 copy_statfs(&s, &s32);
959 error = copyout(&s32, p32, sizeof(s32));
965 ia32_fstatfs(struct thread *td, struct ia32_fstatfs_args *uap)
969 struct statfs32 *p32, s32;
970 struct statfs *p = NULL, s;
972 p32 = SCARG(uap, buf);
974 sg = stackgap_init();
975 p = stackgap_alloc(&sg, sizeof(struct statfs));
976 SCARG(uap, buf) = (struct statfs32 *)p;
978 error = fstatfs(td, (struct fstatfs_args *) uap);
982 error = copyin(p, &s, sizeof(s));
985 copy_statfs(&s, &s32);
986 error = copyout(&s32, p32, sizeof(s32));
992 ia32_semsys(struct thread *td, struct ia32_semsys_args *uap)
995 * Vector through to semsys if it is loaded.
997 return sysent[169].sy_call(td, uap);
1001 ia32_msgsys(struct thread *td, struct ia32_msgsys_args *uap)
1004 * Vector through to msgsys if it is loaded.
1006 return sysent[170].sy_call(td, uap);
1010 ia32_shmsys(struct thread *td, struct ia32_shmsys_args *uap)
1013 * Vector through to shmsys if it is loaded.
1015 return sysent[171].sy_call(td, uap);
1019 ia32_pread(struct thread *td, struct ia32_pread_args *uap)
1021 struct pread_args ap;
1023 SCARG(&ap, fd) = SCARG(uap, fd);
1024 SCARG(&ap, buf) = SCARG(uap, buf);
1025 SCARG(&ap, nbyte) = SCARG(uap, nbyte);
1026 SCARG(&ap, offset) = (SCARG(uap, offsetlo)
1027 | ((off_t)SCARG(uap, offsethi) << 32));
1028 return (pread(td, &ap));
1032 ia32_pwrite(struct thread *td, struct ia32_pwrite_args *uap)
1034 struct pwrite_args ap;
1036 SCARG(&ap, fd) = SCARG(uap, fd);
1037 SCARG(&ap, buf) = SCARG(uap, buf);
1038 SCARG(&ap, nbyte) = SCARG(uap, nbyte);
1039 SCARG(&ap, offset) = (SCARG(uap, offsetlo)
1040 | ((off_t)SCARG(uap, offsethi) << 32));
1041 return (pwrite(td, &ap));
1045 ia32_lseek(struct thread *td, struct ia32_lseek_args *uap)
1048 struct lseek_args ap;
1051 SCARG(&ap, fd) = SCARG(uap, fd);
1052 SCARG(&ap, offset) = (SCARG(uap, offsetlo)
1053 | ((off_t)SCARG(uap, offsethi) << 32));
1054 SCARG(&ap, whence) = SCARG(uap, whence);
1055 error = lseek(td, &ap);
1056 /* Expand the quad return into two parts for eax and edx */
1057 pos = *(off_t *)(td->td_retval);
1058 td->td_retval[0] = pos & 0xffffffff; /* %eax */
1059 td->td_retval[1] = pos >> 32; /* %edx */
1064 ia32_truncate(struct thread *td, struct ia32_truncate_args *uap)
1066 struct truncate_args ap;
1068 SCARG(&ap, path) = SCARG(uap, path);
1069 SCARG(&ap, length) = (SCARG(uap, lengthlo)
1070 | ((off_t)SCARG(uap, lengthhi) << 32));
1071 return (truncate(td, &ap));
1075 ia32_ftruncate(struct thread *td, struct ia32_ftruncate_args *uap)
1077 struct ftruncate_args ap;
1079 SCARG(&ap, fd) = SCARG(uap, fd);
1080 SCARG(&ap, length) = (SCARG(uap, lengthlo)
1081 | ((off_t)SCARG(uap, lengthhi) << 32));
1082 return (ftruncate(td, &ap));
1085 #ifdef COMPAT_FREEBSD4
1087 freebsd4_ia32_sendfile(struct thread *td,
1088 struct freebsd4_ia32_sendfile_args *uap)
1090 struct freebsd4_sendfile_args ap;
1092 SCARG(&ap, fd) = SCARG(uap, fd);
1093 SCARG(&ap, s) = SCARG(uap, s);
1094 SCARG(&ap, offset) = (SCARG(uap, offsetlo)
1095 | ((off_t)SCARG(uap, offsethi) << 32));
1096 SCARG(&ap, nbytes) = SCARG(uap, nbytes); /* XXX check */
1097 SCARG(&ap, hdtr) = SCARG(uap, hdtr); /* XXX check */
1098 SCARG(&ap, sbytes) = SCARG(uap, sbytes); /* XXX FIXME!! */
1099 SCARG(&ap, flags) = SCARG(uap, flags);
1100 return (freebsd4_sendfile(td, &ap));
1105 ia32_sendfile(struct thread *td, struct ia32_sendfile_args *uap)
1107 struct sendfile_args ap;
1109 SCARG(&ap, fd) = SCARG(uap, fd);
1110 SCARG(&ap, s) = SCARG(uap, s);
1111 SCARG(&ap, offset) = (SCARG(uap, offsetlo)
1112 | ((off_t)SCARG(uap, offsethi) << 32));
1113 SCARG(&ap, nbytes) = SCARG(uap, nbytes); /* XXX check */
1114 SCARG(&ap, hdtr) = SCARG(uap, hdtr); /* XXX check */
1115 SCARG(&ap, sbytes) = SCARG(uap, sbytes); /* XXX FIXME!! */
1116 SCARG(&ap, flags) = SCARG(uap, flags);
1117 return (sendfile(td, &ap));
1128 struct timespec32 st_atimespec;
1129 struct timespec32 st_mtimespec;
1130 struct timespec32 st_ctimespec;
1133 u_int32_t st_blksize;
1139 copy_stat( struct stat *in, struct stat32 *out)
1141 CP(*in, *out, st_dev);
1142 CP(*in, *out, st_ino);
1143 CP(*in, *out, st_mode);
1144 CP(*in, *out, st_nlink);
1145 CP(*in, *out, st_uid);
1146 CP(*in, *out, st_gid);
1147 CP(*in, *out, st_rdev);
1148 TS_CP(*in, *out, st_atimespec);
1149 TS_CP(*in, *out, st_mtimespec);
1150 TS_CP(*in, *out, st_ctimespec);
1151 CP(*in, *out, st_size);
1152 CP(*in, *out, st_blocks);
1153 CP(*in, *out, st_blksize);
1154 CP(*in, *out, st_flags);
1155 CP(*in, *out, st_gen);
1159 ia32_stat(struct thread *td, struct ia32_stat_args *uap)
1163 struct stat32 *p32, s32;
1164 struct stat *p = NULL, s;
1166 p32 = SCARG(uap, ub);
1168 sg = stackgap_init();
1169 p = stackgap_alloc(&sg, sizeof(struct stat));
1170 SCARG(uap, ub) = (struct stat32 *)p;
1172 error = stat(td, (struct stat_args *) uap);
1176 error = copyin(p, &s, sizeof(s));
1179 copy_stat(&s, &s32);
1180 error = copyout(&s32, p32, sizeof(s32));
1186 ia32_fstat(struct thread *td, struct ia32_fstat_args *uap)
1190 struct stat32 *p32, s32;
1191 struct stat *p = NULL, s;
1193 p32 = SCARG(uap, ub);
1195 sg = stackgap_init();
1196 p = stackgap_alloc(&sg, sizeof(struct stat));
1197 SCARG(uap, ub) = (struct stat32 *)p;
1199 error = fstat(td, (struct fstat_args *) uap);
1203 error = copyin(p, &s, sizeof(s));
1206 copy_stat(&s, &s32);
1207 error = copyout(&s32, p32, sizeof(s32));
1213 ia32_lstat(struct thread *td, struct ia32_lstat_args *uap)
1217 struct stat32 *p32, s32;
1218 struct stat *p = NULL, s;
1220 p32 = SCARG(uap, ub);
1222 sg = stackgap_init();
1223 p = stackgap_alloc(&sg, sizeof(struct stat));
1224 SCARG(uap, ub) = (struct stat32 *)p;
1226 error = lstat(td, (struct lstat_args *) uap);
1230 error = copyin(p, &s, sizeof(s));
1233 copy_stat(&s, &s32);
1234 error = copyout(&s32, p32, sizeof(s32));
1243 ia32_sysctl(struct thread *td, struct ia32_sysctl_args *uap)
1245 int error, name[CTL_MAXNAME];
1248 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1251 error = copyin(uap->name, &name, uap->namelen * sizeof(int));
1258 oldlen = fuword32(uap->oldlenp);
1261 error = userland_sysctl(td, name, uap->namelen,
1262 uap->old, &oldlen, 1,
1263 uap->new, uap->newlen, &j);
1264 if (error && error != ENOMEM)
1267 suword32(uap->oldlenp, j);
1274 struct sigaction32 {
1281 ia32_sigaction(struct thread *td, struct ia32_sigaction_args *uap)
1285 struct sigaction32 *p32, *op32, s32;
1286 struct sigaction *p = NULL, *op = NULL, s;
1288 p32 = SCARG(uap, act);
1290 sg = stackgap_init();
1291 p = stackgap_alloc(&sg, sizeof(struct sigaction));
1292 SCARG(uap, act) = (struct sigaction32 *)p;
1293 error = copyin(p32, &s32, sizeof(s32));
1296 s.sa_handler = PTRIN(s32.sa_u);
1297 CP(s32, s, sa_flags);
1298 CP(s32, s, sa_mask);
1299 error = copyout(&s, p, sizeof(s));
1303 op32 = SCARG(uap, oact);
1305 sg = stackgap_init();
1306 op = stackgap_alloc(&sg, sizeof(struct sigaction));
1307 SCARG(uap, oact) = (struct sigaction32 *)op;
1309 error = sigaction(td, (struct sigaction_args *) uap);
1313 error = copyin(op, &s, sizeof(s));
1316 s32.sa_u = PTROUT(s.sa_handler);
1317 CP(s, s32, sa_flags);
1318 CP(s, s32, sa_mask);
1319 error = copyout(&s32, op32, sizeof(s32));
1327 ia32_xxx(struct thread *td, struct ia32_xxx_args *uap)
1331 struct yyy32 *p32, s32;
1332 struct yyy *p = NULL, s;
1334 p32 = SCARG(uap, zzz);
1336 sg = stackgap_init();
1337 p = stackgap_alloc(&sg, sizeof(struct yyy));
1338 SCARG(uap, zzz) = (struct yyy32 *)p;
1339 error = copyin(p32, &s32, sizeof(s32));
1343 error = copyout(&s, p, sizeof(s));
1347 error = xxx(td, (struct xxx_args *) uap);
1351 error = copyin(p, &s, sizeof(s));
1355 error = copyout(&s32, p32, sizeof(s32));