13ebc1248SPeter Wemm /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
37f2d13d6SPedro F. Giffuni *
43ebc1248SPeter Wemm * Copyright (c) 2002 Doug Rabson
53ebc1248SPeter Wemm * All rights reserved.
63ebc1248SPeter Wemm *
73ebc1248SPeter Wemm * Redistribution and use in source and binary forms, with or without
83ebc1248SPeter Wemm * modification, are permitted provided that the following conditions
93ebc1248SPeter Wemm * are met:
103ebc1248SPeter Wemm * 1. Redistributions of source code must retain the above copyright
113ebc1248SPeter Wemm * notice, this list of conditions and the following disclaimer.
123ebc1248SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright
133ebc1248SPeter Wemm * notice, this list of conditions and the following disclaimer in the
143ebc1248SPeter Wemm * documentation and/or other materials provided with the distribution.
153ebc1248SPeter Wemm *
163ebc1248SPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
173ebc1248SPeter Wemm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
183ebc1248SPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
193ebc1248SPeter Wemm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
203ebc1248SPeter Wemm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
213ebc1248SPeter Wemm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
223ebc1248SPeter Wemm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
233ebc1248SPeter Wemm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
243ebc1248SPeter Wemm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
253ebc1248SPeter Wemm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
263ebc1248SPeter Wemm * SUCH DAMAGE.
273ebc1248SPeter Wemm */
283ebc1248SPeter Wemm
2956ae44c5SDavid E. O'Brien #include <sys/cdefs.h>
30e3e811a3SBrooks Davis #include "opt_ffclock.h"
31b38ff370SJamie Gritton #include "opt_inet.h"
32b38ff370SJamie Gritton #include "opt_inet6.h"
33ffb66079SJohn Baldwin #include "opt_ktrace.h"
34459e3a7aSPeter Wemm
35841c0c7eSNathan Whitehorn #define __ELF_WORD_SIZE 32
36841c0c7eSNathan Whitehorn
37ffb66079SJohn Baldwin #ifdef COMPAT_FREEBSD11
38ffb66079SJohn Baldwin #define _WANT_FREEBSD11_KEVENT
39ffb66079SJohn Baldwin #endif
40ffb66079SJohn Baldwin
413ebc1248SPeter Wemm #include <sys/param.h>
423ebc1248SPeter Wemm #include <sys/bus.h>
434a144410SRobert Watson #include <sys/capsicum.h>
44f645b0b5SPoul-Henning Kamp #include <sys/clock.h>
453ebc1248SPeter Wemm #include <sys/exec.h>
463ebc1248SPeter Wemm #include <sys/fcntl.h>
473ebc1248SPeter Wemm #include <sys/filedesc.h>
483ebc1248SPeter Wemm #include <sys/imgact.h>
49413628a7SBjoern A. Zeeb #include <sys/jail.h>
503ebc1248SPeter Wemm #include <sys/kernel.h>
51a88d050dSJung-uk Kim #include <sys/limits.h>
5286665509SKonstantin Belousov #include <sys/linker.h>
533ebc1248SPeter Wemm #include <sys/lock.h>
543ebc1248SPeter Wemm #include <sys/malloc.h>
553ebc1248SPeter Wemm #include <sys/file.h> /* Must come after sys/malloc.h */
56841c0c7eSNathan Whitehorn #include <sys/imgact.h>
57ecc44de7SPaul Saab #include <sys/mbuf.h>
583ebc1248SPeter Wemm #include <sys/mman.h>
593ebc1248SPeter Wemm #include <sys/module.h>
603ebc1248SPeter Wemm #include <sys/mount.h>
613ebc1248SPeter Wemm #include <sys/mutex.h>
62109ea24cSDavid E. O'Brien #include <sys/namei.h>
63e3e811a3SBrooks Davis #include <sys/priv.h>
643ebc1248SPeter Wemm #include <sys/proc.h>
6555648840SJohn Baldwin #include <sys/procctl.h>
6658b552dcSJohn Baldwin #include <sys/ptrace.h>
673ebc1248SPeter Wemm #include <sys/reboot.h>
683ebc1248SPeter Wemm #include <sys/resource.h>
693ebc1248SPeter Wemm #include <sys/resourcevar.h>
703ebc1248SPeter Wemm #include <sys/selinfo.h>
71efe5becaSPaul Saab #include <sys/eventvar.h> /* Must come after sys/selinfo.h */
723ebc1248SPeter Wemm #include <sys/pipe.h> /* Must come after sys/selinfo.h */
733ebc1248SPeter Wemm #include <sys/signal.h>
743ebc1248SPeter Wemm #include <sys/signalvar.h>
753ebc1248SPeter Wemm #include <sys/socket.h>
763ebc1248SPeter Wemm #include <sys/socketvar.h>
773ebc1248SPeter Wemm #include <sys/stat.h>
78f2107e8dSJohn Baldwin #include <sys/syscall.h>
79fe8cdcaeSJohn Baldwin #include <sys/syscallsubr.h>
803ebc1248SPeter Wemm #include <sys/sysctl.h>
813ebc1248SPeter Wemm #include <sys/sysent.h>
823ebc1248SPeter Wemm #include <sys/sysproto.h>
83109ea24cSDavid E. O'Brien #include <sys/systm.h>
84cda9a0d1SDavid Xu #include <sys/thr.h>
85918966a2SJake Freeland #include <sys/timerfd.h>
8631df9c26SKonstantin Belousov #include <sys/timex.h>
873ebc1248SPeter Wemm #include <sys/unistd.h>
88cda9a0d1SDavid Xu #include <sys/ucontext.h>
89ddb3eb4eSOlivier Certner #include <sys/ucred.h>
903ebc1248SPeter Wemm #include <sys/vnode.h>
91b7e23e82SJohn Baldwin #include <sys/wait.h>
92fbb273bcSPaul Saab #include <sys/ipc.h>
933c39e0d8SJohn Baldwin #include <sys/msg.h>
943c39e0d8SJohn Baldwin #include <sys/sem.h>
95fbb273bcSPaul Saab #include <sys/shm.h>
96e3e811a3SBrooks Davis #include <sys/timeffc.h>
97ffb66079SJohn Baldwin #ifdef KTRACE
98ffb66079SJohn Baldwin #include <sys/ktrace.h>
99ffb66079SJohn Baldwin #endif
1003ebc1248SPeter Wemm
101b38ff370SJamie Gritton #ifdef INET
102b38ff370SJamie Gritton #include <netinet/in.h>
103b38ff370SJamie Gritton #endif
104b38ff370SJamie Gritton
1053ebc1248SPeter Wemm #include <vm/vm.h>
1063ebc1248SPeter Wemm #include <vm/vm_param.h>
1073ebc1248SPeter Wemm #include <vm/pmap.h>
1083ebc1248SPeter Wemm #include <vm/vm_map.h>
1093ebc1248SPeter Wemm #include <vm/vm_object.h>
1103ebc1248SPeter Wemm #include <vm/vm_extern.h>
1113ebc1248SPeter Wemm
112e7abd4a0SPaul Saab #include <machine/cpu.h>
113841c0c7eSNathan Whitehorn #include <machine/elf.h>
114a7f67facSKonstantin Belousov #ifdef __amd64__
115a7f67facSKonstantin Belousov #include <machine/md_var.h>
116a7f67facSKonstantin Belousov #endif
117e7abd4a0SPaul Saab
1186e6049e9SDavid E. O'Brien #include <security/audit/audit.h>
119ddb3eb4eSOlivier Certner #include <security/mac/mac_syscalls.h>
1206e6049e9SDavid E. O'Brien
1211c7abef7SPeter Wemm #include <compat/freebsd32/freebsd32_util.h>
1221c7abef7SPeter Wemm #include <compat/freebsd32/freebsd32.h>
123d43c6fa4SJohn Baldwin #include <compat/freebsd32/freebsd32_ipc.h>
124d6f6b876SPawel Jakub Dawidek #include <compat/freebsd32/freebsd32_misc.h>
125c6511aeaSDavid Xu #include <compat/freebsd32/freebsd32_signal.h>
1261c7abef7SPeter Wemm #include <compat/freebsd32/freebsd32_proto.h>
1273ebc1248SPeter Wemm
1285a2bbaceSKonstantin Belousov int compat_freebsd_32bit = 1;
1295a2bbaceSKonstantin Belousov
1305a2bbaceSKonstantin Belousov static void
register_compat32_feature(void * arg)1315a2bbaceSKonstantin Belousov register_compat32_feature(void *arg)
1325a2bbaceSKonstantin Belousov {
1335a2bbaceSKonstantin Belousov if (!compat_freebsd_32bit)
1345a2bbaceSKonstantin Belousov return;
1355a2bbaceSKonstantin Belousov
136bddc7a8aSKonstantin Belousov FEATURE_ADD("compat_freebsd32", "Compatible with 32-bit FreeBSD");
137bddc7a8aSKonstantin Belousov FEATURE_ADD("compat_freebsd_32bit",
138bddc7a8aSKonstantin Belousov "Compatible with 32-bit FreeBSD (legacy feature name)");
1395a2bbaceSKonstantin Belousov }
1405a2bbaceSKonstantin Belousov SYSINIT(freebsd32, SI_SUB_EXEC, SI_ORDER_ANY, register_compat32_feature,
1415a2bbaceSKonstantin Belousov NULL);
1421f4e9654SDavid E. O'Brien
14358b552dcSJohn Baldwin struct ptrace_io_desc32 {
14458b552dcSJohn Baldwin int piod_op;
14558b552dcSJohn Baldwin uint32_t piod_offs;
14658b552dcSJohn Baldwin uint32_t piod_addr;
14758b552dcSJohn Baldwin uint32_t piod_len;
14858b552dcSJohn Baldwin };
14958b552dcSJohn Baldwin
15058b552dcSJohn Baldwin struct ptrace_vm_entry32 {
15158b552dcSJohn Baldwin int pve_entry;
15258b552dcSJohn Baldwin int pve_timestamp;
15358b552dcSJohn Baldwin uint32_t pve_start;
15458b552dcSJohn Baldwin uint32_t pve_end;
15558b552dcSJohn Baldwin uint32_t pve_offset;
15658b552dcSJohn Baldwin u_int pve_prot;
15758b552dcSJohn Baldwin u_int pve_pathlen;
15858b552dcSJohn Baldwin int32_t pve_fileid;
15958b552dcSJohn Baldwin u_int pve_fsid;
16058b552dcSJohn Baldwin uint32_t pve_path;
16158b552dcSJohn Baldwin };
16258b552dcSJohn Baldwin
163b4366092SJustin Hibbits #ifdef __amd64__
16460a8c422SPeter Wemm CTASSERT(sizeof(struct timeval32) == 8);
16560a8c422SPeter Wemm CTASSERT(sizeof(struct timespec32) == 8);
16674427aa4SJohn Baldwin CTASSERT(sizeof(struct itimerval32) == 16);
167afbd12c1SMaxim Sobolev CTASSERT(sizeof(struct bintime32) == 12);
1688299f9a5SEd Maste #else
1698299f9a5SEd Maste CTASSERT(sizeof(struct timeval32) == 16);
1708299f9a5SEd Maste CTASSERT(sizeof(struct timespec32) == 16);
1718299f9a5SEd Maste CTASSERT(sizeof(struct itimerval32) == 32);
1728299f9a5SEd Maste CTASSERT(sizeof(struct bintime32) == 16);
1739624d947SJuli Mallett #endif
1742e89f95dSBrooks Davis CTASSERT(sizeof(struct ostatfs32) == 256);
175b4366092SJustin Hibbits #ifdef __amd64__
17660a8c422SPeter Wemm CTASSERT(sizeof(struct rusage32) == 72);
1778299f9a5SEd Maste #else
1788299f9a5SEd Maste CTASSERT(sizeof(struct rusage32) == 88);
1799624d947SJuli Mallett #endif
18074427aa4SJohn Baldwin CTASSERT(sizeof(struct sigaltstack32) == 12);
181aef2a6a7SKonstantin Belousov #ifdef __amd64__
1822b34e843SKonstantin Belousov CTASSERT(sizeof(struct kevent32) == 56);
183aef2a6a7SKonstantin Belousov #else
184aef2a6a7SKonstantin Belousov CTASSERT(sizeof(struct kevent32) == 64);
185cfb2d93bSKonstantin Belousov #endif
18674427aa4SJohn Baldwin CTASSERT(sizeof(struct iovec32) == 8);
18774427aa4SJohn Baldwin CTASSERT(sizeof(struct msghdr32) == 28);
18869921123SKonstantin Belousov #ifdef __amd64__
18969921123SKonstantin Belousov CTASSERT(sizeof(struct stat32) == 208);
19069921123SKonstantin Belousov CTASSERT(sizeof(struct freebsd11_stat32) == 96);
1918299f9a5SEd Maste #else
1928299f9a5SEd Maste CTASSERT(sizeof(struct stat32) == 224);
1938299f9a5SEd Maste CTASSERT(sizeof(struct freebsd11_stat32) == 120);
1949624d947SJuli Mallett #endif
19574427aa4SJohn Baldwin CTASSERT(sizeof(struct sigaction32) == 24);
19674427aa4SJohn Baldwin
19774427aa4SJohn Baldwin static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
19874427aa4SJohn Baldwin static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
1993f8455b0SEric van Gyzen static int freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
2003f8455b0SEric van Gyzen int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp);
20160a8c422SPeter Wemm
2029847e91bSKonstantin Belousov void
freebsd32_rusage_out(const struct rusage * s,struct rusage32 * s32)2039847e91bSKonstantin Belousov freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
2049847e91bSKonstantin Belousov {
2059847e91bSKonstantin Belousov
2069847e91bSKonstantin Belousov TV_CP(*s, *s32, ru_utime);
2079847e91bSKonstantin Belousov TV_CP(*s, *s32, ru_stime);
2089847e91bSKonstantin Belousov CP(*s, *s32, ru_maxrss);
2099847e91bSKonstantin Belousov CP(*s, *s32, ru_ixrss);
2109847e91bSKonstantin Belousov CP(*s, *s32, ru_idrss);
2119847e91bSKonstantin Belousov CP(*s, *s32, ru_isrss);
2129847e91bSKonstantin Belousov CP(*s, *s32, ru_minflt);
2139847e91bSKonstantin Belousov CP(*s, *s32, ru_majflt);
2149847e91bSKonstantin Belousov CP(*s, *s32, ru_nswap);
2159847e91bSKonstantin Belousov CP(*s, *s32, ru_inblock);
2169847e91bSKonstantin Belousov CP(*s, *s32, ru_oublock);
2179847e91bSKonstantin Belousov CP(*s, *s32, ru_msgsnd);
2189847e91bSKonstantin Belousov CP(*s, *s32, ru_msgrcv);
2199847e91bSKonstantin Belousov CP(*s, *s32, ru_nsignals);
2209847e91bSKonstantin Belousov CP(*s, *s32, ru_nvcsw);
2219847e91bSKonstantin Belousov CP(*s, *s32, ru_nivcsw);
2229847e91bSKonstantin Belousov }
2239847e91bSKonstantin Belousov
2243ebc1248SPeter Wemm int
freebsd32_wait4(struct thread * td,struct freebsd32_wait4_args * uap)2251c7abef7SPeter Wemm freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
2263ebc1248SPeter Wemm {
227b7e23e82SJohn Baldwin int error, status;
228b7e23e82SJohn Baldwin struct rusage32 ru32;
22978c85e8dSJohn Baldwin struct rusage ru, *rup;
2303ebc1248SPeter Wemm
23178c85e8dSJohn Baldwin if (uap->rusage != NULL)
23278c85e8dSJohn Baldwin rup = &ru;
23378c85e8dSJohn Baldwin else
23478c85e8dSJohn Baldwin rup = NULL;
23578c85e8dSJohn Baldwin error = kern_wait(td, uap->pid, &status, uap->options, rup);
2363ebc1248SPeter Wemm if (error)
2373ebc1248SPeter Wemm return (error);
238b7e23e82SJohn Baldwin if (uap->status != NULL)
239b7e23e82SJohn Baldwin error = copyout(&status, uap->status, sizeof(status));
240b7e23e82SJohn Baldwin if (uap->rusage != NULL && error == 0) {
2419847e91bSKonstantin Belousov freebsd32_rusage_out(&ru, &ru32);
242b7e23e82SJohn Baldwin error = copyout(&ru32, uap->rusage, sizeof(ru32));
2433ebc1248SPeter Wemm }
2443ebc1248SPeter Wemm return (error);
2453ebc1248SPeter Wemm }
2463ebc1248SPeter Wemm
247f13b5a0fSKonstantin Belousov int
freebsd32_wait6(struct thread * td,struct freebsd32_wait6_args * uap)248f13b5a0fSKonstantin Belousov freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
249f13b5a0fSKonstantin Belousov {
250b35c2bcaSBrooks Davis struct __wrusage32 wru32;
251f13b5a0fSKonstantin Belousov struct __wrusage wru, *wrup;
252d060b420SBrooks Davis struct __siginfo32 si32;
253f13b5a0fSKonstantin Belousov struct __siginfo si, *sip;
254f13b5a0fSKonstantin Belousov int error, status;
255f13b5a0fSKonstantin Belousov
256f13b5a0fSKonstantin Belousov if (uap->wrusage != NULL)
257f13b5a0fSKonstantin Belousov wrup = &wru;
258f13b5a0fSKonstantin Belousov else
259f13b5a0fSKonstantin Belousov wrup = NULL;
260f13b5a0fSKonstantin Belousov if (uap->info != NULL) {
261f13b5a0fSKonstantin Belousov sip = &si;
262f13b5a0fSKonstantin Belousov bzero(sip, sizeof(*sip));
263f13b5a0fSKonstantin Belousov } else
264f13b5a0fSKonstantin Belousov sip = NULL;
26548947eccSKonstantin Belousov error = kern_wait6(td, uap->idtype, PAIR32TO64(id_t, uap->id),
26648947eccSKonstantin Belousov &status, uap->options, wrup, sip);
267f13b5a0fSKonstantin Belousov if (error != 0)
268f13b5a0fSKonstantin Belousov return (error);
269f13b5a0fSKonstantin Belousov if (uap->status != NULL)
270f13b5a0fSKonstantin Belousov error = copyout(&status, uap->status, sizeof(status));
271f13b5a0fSKonstantin Belousov if (uap->wrusage != NULL && error == 0) {
272f13b5a0fSKonstantin Belousov freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
273f13b5a0fSKonstantin Belousov freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
274f13b5a0fSKonstantin Belousov error = copyout(&wru32, uap->wrusage, sizeof(wru32));
275f13b5a0fSKonstantin Belousov }
276f13b5a0fSKonstantin Belousov if (uap->info != NULL && error == 0) {
277f13b5a0fSKonstantin Belousov siginfo_to_siginfo32 (&si, &si32);
278f13b5a0fSKonstantin Belousov error = copyout(&si32, uap->info, sizeof(si32));
279f13b5a0fSKonstantin Belousov }
280f13b5a0fSKonstantin Belousov return (error);
281f13b5a0fSKonstantin Belousov }
282f13b5a0fSKonstantin Belousov
283c050455eSMarcel Moolenaar #ifdef COMPAT_FREEBSD4
2840a635741SJohn Baldwin static void
copy_statfs(struct statfs * in,struct ostatfs32 * out)2852e89f95dSBrooks Davis copy_statfs(struct statfs *in, struct ostatfs32 *out)
2863ebc1248SPeter Wemm {
2876308f39dSPaul Saab
2887815c9e2SScott Long statfs_scale_blocks(in, INT32_MAX);
2896308f39dSPaul Saab bzero(out, sizeof(*out));
2903ebc1248SPeter Wemm CP(*in, *out, f_bsize);
291cc479ddaSJohn Baldwin out->f_iosize = MIN(in->f_iosize, INT32_MAX);
2923ebc1248SPeter Wemm CP(*in, *out, f_blocks);
2933ebc1248SPeter Wemm CP(*in, *out, f_bfree);
2943ebc1248SPeter Wemm CP(*in, *out, f_bavail);
295cc479ddaSJohn Baldwin out->f_files = MIN(in->f_files, INT32_MAX);
296cc479ddaSJohn Baldwin out->f_ffree = MIN(in->f_ffree, INT32_MAX);
2973ebc1248SPeter Wemm CP(*in, *out, f_fsid);
2983ebc1248SPeter Wemm CP(*in, *out, f_owner);
2993ebc1248SPeter Wemm CP(*in, *out, f_type);
3003ebc1248SPeter Wemm CP(*in, *out, f_flags);
3010a635741SJohn Baldwin out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX);
3020a635741SJohn Baldwin out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX);
3036308f39dSPaul Saab strlcpy(out->f_fstypename,
3046308f39dSPaul Saab in->f_fstypename, MFSNAMELEN);
3056308f39dSPaul Saab strlcpy(out->f_mntonname,
3062e89f95dSBrooks Davis in->f_mntonname, min(MNAMELEN, FREEBSD4_OMNAMELEN));
3070a635741SJohn Baldwin out->f_syncreads = MIN(in->f_syncreads, INT32_MAX);
3080a635741SJohn Baldwin out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX);
3096308f39dSPaul Saab strlcpy(out->f_mntfromname,
3102e89f95dSBrooks Davis in->f_mntfromname, min(MNAMELEN, FREEBSD4_OMNAMELEN));
3113ebc1248SPeter Wemm }
312c050455eSMarcel Moolenaar #endif
3133ebc1248SPeter Wemm
3142b9d052dSBrooks Davis int
freebsd32_getfsstat(struct thread * td,struct freebsd32_getfsstat_args * uap)3152b9d052dSBrooks Davis freebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap)
3162b9d052dSBrooks Davis {
3172b9d052dSBrooks Davis size_t count;
3182b9d052dSBrooks Davis int error;
3192b9d052dSBrooks Davis
3202b9d052dSBrooks Davis if (uap->bufsize < 0 || uap->bufsize > SIZE_MAX)
3212b9d052dSBrooks Davis return (EINVAL);
3222b9d052dSBrooks Davis error = kern_getfsstat(td, &uap->buf, uap->bufsize, &count,
3232b9d052dSBrooks Davis UIO_USERSPACE, uap->mode);
3242b9d052dSBrooks Davis if (error == 0)
3252b9d052dSBrooks Davis td->td_retval[0] = count;
3262b9d052dSBrooks Davis return (error);
3272b9d052dSBrooks Davis }
3282b9d052dSBrooks Davis
329c050455eSMarcel Moolenaar #ifdef COMPAT_FREEBSD4
3303ebc1248SPeter Wemm int
freebsd4_freebsd32_getfsstat(struct thread * td,struct freebsd4_freebsd32_getfsstat_args * uap)331607fa849SKonstantin Belousov freebsd4_freebsd32_getfsstat(struct thread *td,
332607fa849SKonstantin Belousov struct freebsd4_freebsd32_getfsstat_args *uap)
3333ebc1248SPeter Wemm {
33413a82b96SPawel Jakub Dawidek struct statfs *buf, *sp;
3352e89f95dSBrooks Davis struct ostatfs32 stat32;
33676cd2549SPeter Wemm size_t count, size, copycount;
3373ebc1248SPeter Wemm int error;
3383ebc1248SPeter Wemm
3392e89f95dSBrooks Davis count = uap->bufsize / sizeof(struct ostatfs32);
34013a82b96SPawel Jakub Dawidek size = count * sizeof(struct statfs);
34134ed0c63SJohn Baldwin error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode);
3423a996d6eSPawel Jakub Dawidek if (size > 0) {
34313a82b96SPawel Jakub Dawidek sp = buf;
34476cd2549SPeter Wemm copycount = count;
34576cd2549SPeter Wemm while (copycount > 0 && error == 0) {
3460a635741SJohn Baldwin copy_statfs(sp, &stat32);
34713a82b96SPawel Jakub Dawidek error = copyout(&stat32, uap->buf, sizeof(stat32));
34813a82b96SPawel Jakub Dawidek sp++;
34913a82b96SPawel Jakub Dawidek uap->buf++;
35076cd2549SPeter Wemm copycount--;
3513ebc1248SPeter Wemm }
3522f304845SKonstantin Belousov free(buf, M_STATFS);
3533ebc1248SPeter Wemm }
3541c73bcabSEdward Tomasz Napierala if (error == 0)
3551c73bcabSEdward Tomasz Napierala td->td_retval[0] = count;
3563ebc1248SPeter Wemm return (error);
3573ebc1248SPeter Wemm }
358c050455eSMarcel Moolenaar #endif
3593ebc1248SPeter Wemm
3602b9d052dSBrooks Davis #ifdef COMPAT_FREEBSD11
3612b9d052dSBrooks Davis int
freebsd11_freebsd32_getfsstat(struct thread * td,struct freebsd11_freebsd32_getfsstat_args * uap)3622b9d052dSBrooks Davis freebsd11_freebsd32_getfsstat(struct thread *td,
3632b9d052dSBrooks Davis struct freebsd11_freebsd32_getfsstat_args *uap)
3642b9d052dSBrooks Davis {
3652b9d052dSBrooks Davis return(kern_freebsd11_getfsstat(td, uap->buf, uap->bufsize,
3662b9d052dSBrooks Davis uap->mode));
3672b9d052dSBrooks Davis }
3682b9d052dSBrooks Davis #endif
3692b9d052dSBrooks Davis
3703ebc1248SPeter Wemm int
freebsd32_sigaltstack(struct thread * td,struct freebsd32_sigaltstack_args * uap)3711c7abef7SPeter Wemm freebsd32_sigaltstack(struct thread *td,
3721c7abef7SPeter Wemm struct freebsd32_sigaltstack_args *uap)
3733ebc1248SPeter Wemm {
374fe8cdcaeSJohn Baldwin struct sigaltstack32 s32;
375fe8cdcaeSJohn Baldwin struct sigaltstack ss, oss, *ssp;
3763ebc1248SPeter Wemm int error;
3773ebc1248SPeter Wemm
378fe8cdcaeSJohn Baldwin if (uap->ss != NULL) {
379fe8cdcaeSJohn Baldwin error = copyin(uap->ss, &s32, sizeof(s32));
3803ebc1248SPeter Wemm if (error)
3813ebc1248SPeter Wemm return (error);
382fe8cdcaeSJohn Baldwin PTRIN_CP(s32, ss, ss_sp);
383fe8cdcaeSJohn Baldwin CP(s32, ss, ss_size);
384fe8cdcaeSJohn Baldwin CP(s32, ss, ss_flags);
385fe8cdcaeSJohn Baldwin ssp = &ss;
386fe8cdcaeSJohn Baldwin } else
387fe8cdcaeSJohn Baldwin ssp = NULL;
388fe8cdcaeSJohn Baldwin error = kern_sigaltstack(td, ssp, &oss);
389fe8cdcaeSJohn Baldwin if (error == 0 && uap->oss != NULL) {
390fe8cdcaeSJohn Baldwin PTROUT_CP(oss, s32, ss_sp);
391fe8cdcaeSJohn Baldwin CP(oss, s32, ss_size);
392fe8cdcaeSJohn Baldwin CP(oss, s32, ss_flags);
393fe8cdcaeSJohn Baldwin error = copyout(&s32, uap->oss, sizeof(s32));
3943ebc1248SPeter Wemm }
3953ebc1248SPeter Wemm return (error);
3963ebc1248SPeter Wemm }
3973ebc1248SPeter Wemm
39838765a31SJohn Baldwin /*
39938765a31SJohn Baldwin * Custom version of exec_copyin_args() so that we can translate
40038765a31SJohn Baldwin * the pointers.
40138765a31SJohn Baldwin */
4020b53d156SKonstantin Belousov int
freebsd32_exec_copyin_args(struct image_args * args,const char * fname,uint32_t * argv,uint32_t * envv)40312e69f96SBrooks Davis freebsd32_exec_copyin_args(struct image_args *args, const char *fname,
40415581af7SWuyang Chung uint32_t *argv, uint32_t *envv)
40538765a31SJohn Baldwin {
40638765a31SJohn Baldwin char *argp, *envp;
407cc5aa0a4SJohn Baldwin uint32_t *p32, arg;
40838765a31SJohn Baldwin int error;
40938765a31SJohn Baldwin
41038765a31SJohn Baldwin bzero(args, sizeof(*args));
41138765a31SJohn Baldwin if (argv == NULL)
41238765a31SJohn Baldwin return (EFAULT);
41338765a31SJohn Baldwin
41438765a31SJohn Baldwin /*
4152af6e14dSAlan Cox * Allocate demand-paged memory for the file name, argument, and
4162af6e14dSAlan Cox * environment strings.
41738765a31SJohn Baldwin */
4182af6e14dSAlan Cox error = exec_alloc_args(args);
4192af6e14dSAlan Cox if (error != 0)
4202af6e14dSAlan Cox return (error);
42138765a31SJohn Baldwin
42238765a31SJohn Baldwin /*
42338765a31SJohn Baldwin * Copy the file name.
42438765a31SJohn Baldwin */
42515581af7SWuyang Chung error = exec_args_add_fname(args, fname, UIO_USERSPACE);
42638765a31SJohn Baldwin if (error != 0)
42768ff3c24SStephan Uphoff goto err_exit;
42838765a31SJohn Baldwin
42938765a31SJohn Baldwin /*
43038765a31SJohn Baldwin * extract arguments first
43138765a31SJohn Baldwin */
43238765a31SJohn Baldwin p32 = argv;
43338765a31SJohn Baldwin for (;;) {
43438765a31SJohn Baldwin error = copyin(p32++, &arg, sizeof(arg));
43538765a31SJohn Baldwin if (error)
43668ff3c24SStephan Uphoff goto err_exit;
43738765a31SJohn Baldwin if (arg == 0)
43838765a31SJohn Baldwin break;
43938765a31SJohn Baldwin argp = PTRIN(arg);
440f373437aSBrooks Davis error = exec_args_add_arg(args, argp, UIO_USERSPACE);
441f373437aSBrooks Davis if (error != 0)
44268ff3c24SStephan Uphoff goto err_exit;
44338765a31SJohn Baldwin }
44438765a31SJohn Baldwin
44538765a31SJohn Baldwin /*
44638765a31SJohn Baldwin * extract environment strings
44738765a31SJohn Baldwin */
44838765a31SJohn Baldwin if (envv) {
44938765a31SJohn Baldwin p32 = envv;
45038765a31SJohn Baldwin for (;;) {
45138765a31SJohn Baldwin error = copyin(p32++, &arg, sizeof(arg));
45238765a31SJohn Baldwin if (error)
45368ff3c24SStephan Uphoff goto err_exit;
45438765a31SJohn Baldwin if (arg == 0)
45538765a31SJohn Baldwin break;
45638765a31SJohn Baldwin envp = PTRIN(arg);
457f373437aSBrooks Davis error = exec_args_add_env(args, envp, UIO_USERSPACE);
458f373437aSBrooks Davis if (error != 0)
45968ff3c24SStephan Uphoff goto err_exit;
46038765a31SJohn Baldwin }
46138765a31SJohn Baldwin }
46238765a31SJohn Baldwin
46338765a31SJohn Baldwin return (0);
46468ff3c24SStephan Uphoff
46568ff3c24SStephan Uphoff err_exit:
46669a8f9e3SAlan Cox exec_free_args(args);
46768ff3c24SStephan Uphoff return (error);
46838765a31SJohn Baldwin }
46938765a31SJohn Baldwin
4703ebc1248SPeter Wemm int
freebsd32_execve(struct thread * td,struct freebsd32_execve_args * uap)4711c7abef7SPeter Wemm freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
4723ebc1248SPeter Wemm {
47338765a31SJohn Baldwin struct image_args eargs;
4747b445033SKonstantin Belousov struct vmspace *oldvmspace;
4753ebc1248SPeter Wemm int error;
4763ebc1248SPeter Wemm
4777b445033SKonstantin Belousov error = pre_execve(td, &oldvmspace);
4787b445033SKonstantin Belousov if (error != 0)
4797b445033SKonstantin Belousov return (error);
48015581af7SWuyang Chung error = freebsd32_exec_copyin_args(&eargs, uap->fname, uap->argv,
48115581af7SWuyang Chung uap->envv);
48238765a31SJohn Baldwin if (error == 0)
483aaf78c16SKonstantin Belousov error = kern_execve(td, &eargs, NULL, oldvmspace);
4847b445033SKonstantin Belousov post_execve(td, error, oldvmspace);
485275c821dSKyle Evans AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
48638765a31SJohn Baldwin return (error);
4873ebc1248SPeter Wemm }
4883ebc1248SPeter Wemm
4894f1e7213SKonstantin Belousov int
freebsd32_fexecve(struct thread * td,struct freebsd32_fexecve_args * uap)4904f1e7213SKonstantin Belousov freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
4914f1e7213SKonstantin Belousov {
4924f1e7213SKonstantin Belousov struct image_args eargs;
4937b445033SKonstantin Belousov struct vmspace *oldvmspace;
4944f1e7213SKonstantin Belousov int error;
4954f1e7213SKonstantin Belousov
4967b445033SKonstantin Belousov error = pre_execve(td, &oldvmspace);
4977b445033SKonstantin Belousov if (error != 0)
4987b445033SKonstantin Belousov return (error);
49915581af7SWuyang Chung error = freebsd32_exec_copyin_args(&eargs, NULL, uap->argv, uap->envv);
5004f1e7213SKonstantin Belousov if (error == 0) {
5014f1e7213SKonstantin Belousov eargs.fd = uap->fd;
502aaf78c16SKonstantin Belousov error = kern_execve(td, &eargs, NULL, oldvmspace);
5034f1e7213SKonstantin Belousov }
5047b445033SKonstantin Belousov post_execve(td, error, oldvmspace);
505275c821dSKyle Evans AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
5064f1e7213SKonstantin Belousov return (error);
5074f1e7213SKonstantin Belousov }
5084f1e7213SKonstantin Belousov
50969921123SKonstantin Belousov int
freebsd32_mknodat(struct thread * td,struct freebsd32_mknodat_args * uap)5109a38df59SBrooks Davis freebsd32_mknodat(struct thread *td, struct freebsd32_mknodat_args *uap)
51169921123SKonstantin Belousov {
51269921123SKonstantin Belousov
5139a38df59SBrooks Davis return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE,
5149a38df59SBrooks Davis uap->mode, PAIR32TO64(dev_t, uap->dev)));
51569921123SKonstantin Belousov }
51669921123SKonstantin Belousov
5173ebc1248SPeter Wemm int
freebsd32_mprotect(struct thread * td,struct freebsd32_mprotect_args * uap)518f8244106SMarcel Moolenaar freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
519f8244106SMarcel Moolenaar {
52069cdfcefSEdward Tomasz Napierala int prot;
521f8244106SMarcel Moolenaar
52269cdfcefSEdward Tomasz Napierala prot = uap->prot;
523e7d939bdSMarcel Moolenaar #if defined(__amd64__)
52469cdfcefSEdward Tomasz Napierala if (i386_read_exec && (prot & PROT_READ) != 0)
52569cdfcefSEdward Tomasz Napierala prot |= PROT_EXEC;
526f8244106SMarcel Moolenaar #endif
527496ab053SKonstantin Belousov return (kern_mprotect(td, (uintptr_t)PTRIN(uap->addr), uap->len,
5289b65fa69SKonstantin Belousov prot, 0));
529f8244106SMarcel Moolenaar }
530f8244106SMarcel Moolenaar
531f8244106SMarcel Moolenaar int
freebsd32_mmap(struct thread * td,struct freebsd32_mmap_args * uap)5321c7abef7SPeter Wemm freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
5333ebc1248SPeter Wemm {
53469cdfcefSEdward Tomasz Napierala int prot;
5353ebc1248SPeter Wemm
53669cdfcefSEdward Tomasz Napierala prot = uap->prot;
537e7d939bdSMarcel Moolenaar #if defined(__amd64__)
538126b36a2SKonstantin Belousov if (i386_read_exec && (prot & PROT_READ))
539488a1605SMarcel Moolenaar prot |= PROT_EXEC;
540488a1605SMarcel Moolenaar #endif
541488a1605SMarcel Moolenaar
5427a1591c1SBrooks Davis return (kern_mmap(td, &(struct mmap_req){
5437a1591c1SBrooks Davis .mr_hint = (uintptr_t)uap->addr,
5447a1591c1SBrooks Davis .mr_len = uap->len,
5457a1591c1SBrooks Davis .mr_prot = prot,
5467a1591c1SBrooks Davis .mr_flags = uap->flags,
5477a1591c1SBrooks Davis .mr_fd = uap->fd,
5487a1591c1SBrooks Davis .mr_pos = PAIR32TO64(off_t, uap->pos),
5497a1591c1SBrooks Davis }));
5503ebc1248SPeter Wemm }
5513ebc1248SPeter Wemm
5525aa69f9cSPeter Wemm #ifdef COMPAT_FREEBSD6
5535aa69f9cSPeter Wemm int
freebsd6_freebsd32_mmap(struct thread * td,struct freebsd6_freebsd32_mmap_args * uap)554995b8f4fSKonstantin Belousov freebsd6_freebsd32_mmap(struct thread *td,
555995b8f4fSKonstantin Belousov struct freebsd6_freebsd32_mmap_args *uap)
5565aa69f9cSPeter Wemm {
557496ab053SKonstantin Belousov int prot;
5585aa69f9cSPeter Wemm
559496ab053SKonstantin Belousov prot = uap->prot;
560496ab053SKonstantin Belousov #if defined(__amd64__)
561496ab053SKonstantin Belousov if (i386_read_exec && (prot & PROT_READ))
562496ab053SKonstantin Belousov prot |= PROT_EXEC;
563496ab053SKonstantin Belousov #endif
5645aa69f9cSPeter Wemm
5657a1591c1SBrooks Davis return (kern_mmap(td, &(struct mmap_req){
5667a1591c1SBrooks Davis .mr_hint = (uintptr_t)uap->addr,
5677a1591c1SBrooks Davis .mr_len = uap->len,
5687a1591c1SBrooks Davis .mr_prot = prot,
5697a1591c1SBrooks Davis .mr_flags = uap->flags,
5707a1591c1SBrooks Davis .mr_fd = uap->fd,
5717a1591c1SBrooks Davis .mr_pos = PAIR32TO64(off_t, uap->pos),
5727a1591c1SBrooks Davis }));
5735aa69f9cSPeter Wemm }
5745aa69f9cSPeter Wemm #endif
5755aa69f9cSPeter Wemm
57601ce7fcaSBrooks Davis #ifdef COMPAT_43
57701ce7fcaSBrooks Davis int
ofreebsd32_mmap(struct thread * td,struct ofreebsd32_mmap_args * uap)57801ce7fcaSBrooks Davis ofreebsd32_mmap(struct thread *td, struct ofreebsd32_mmap_args *uap)
57901ce7fcaSBrooks Davis {
58001ce7fcaSBrooks Davis return (kern_ommap(td, (uintptr_t)uap->addr, uap->len, uap->prot,
58101ce7fcaSBrooks Davis uap->flags, uap->fd, uap->pos));
58201ce7fcaSBrooks Davis }
58301ce7fcaSBrooks Davis #endif
58401ce7fcaSBrooks Davis
5853ebc1248SPeter Wemm int
freebsd32_setitimer(struct thread * td,struct freebsd32_setitimer_args * uap)5861c7abef7SPeter Wemm freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
5873ebc1248SPeter Wemm {
58838765a31SJohn Baldwin struct itimerval itv, oitv, *itvp;
58938765a31SJohn Baldwin struct itimerval32 i32;
5903ebc1248SPeter Wemm int error;
5913ebc1248SPeter Wemm
59238765a31SJohn Baldwin if (uap->itv != NULL) {
59338765a31SJohn Baldwin error = copyin(uap->itv, &i32, sizeof(i32));
5943ebc1248SPeter Wemm if (error)
5953ebc1248SPeter Wemm return (error);
59638765a31SJohn Baldwin TV_CP(i32, itv, it_interval);
59738765a31SJohn Baldwin TV_CP(i32, itv, it_value);
59838765a31SJohn Baldwin itvp = &itv;
59938765a31SJohn Baldwin } else
60038765a31SJohn Baldwin itvp = NULL;
60138765a31SJohn Baldwin error = kern_setitimer(td, uap->which, itvp, &oitv);
60238765a31SJohn Baldwin if (error || uap->oitv == NULL)
6033ebc1248SPeter Wemm return (error);
60438765a31SJohn Baldwin TV_CP(oitv, i32, it_interval);
60538765a31SJohn Baldwin TV_CP(oitv, i32, it_value);
60638765a31SJohn Baldwin return (copyout(&i32, uap->oitv, sizeof(i32)));
6073ebc1248SPeter Wemm }
6083ebc1248SPeter Wemm
6093ebc1248SPeter Wemm int
freebsd32_getitimer(struct thread * td,struct freebsd32_getitimer_args * uap)610996a568eSPeter Wemm freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
611996a568eSPeter Wemm {
61238765a31SJohn Baldwin struct itimerval itv;
61338765a31SJohn Baldwin struct itimerval32 i32;
614996a568eSPeter Wemm int error;
615996a568eSPeter Wemm
61638765a31SJohn Baldwin error = kern_getitimer(td, uap->which, &itv);
61738765a31SJohn Baldwin if (error || uap->itv == NULL)
618996a568eSPeter Wemm return (error);
61938765a31SJohn Baldwin TV_CP(itv, i32, it_interval);
62038765a31SJohn Baldwin TV_CP(itv, i32, it_value);
62138765a31SJohn Baldwin return (copyout(&i32, uap->itv, sizeof(i32)));
622996a568eSPeter Wemm }
623996a568eSPeter Wemm
624996a568eSPeter Wemm int
freebsd32_select(struct thread * td,struct freebsd32_select_args * uap)6251c7abef7SPeter Wemm freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
6263ebc1248SPeter Wemm {
62738765a31SJohn Baldwin struct timeval32 tv32;
62838765a31SJohn Baldwin struct timeval tv, *tvp;
6293ebc1248SPeter Wemm int error;
6303ebc1248SPeter Wemm
63138765a31SJohn Baldwin if (uap->tv != NULL) {
63238765a31SJohn Baldwin error = copyin(uap->tv, &tv32, sizeof(tv32));
6333ebc1248SPeter Wemm if (error)
6343ebc1248SPeter Wemm return (error);
63538765a31SJohn Baldwin CP(tv32, tv, tv_sec);
63638765a31SJohn Baldwin CP(tv32, tv, tv_usec);
63738765a31SJohn Baldwin tvp = &tv;
63838765a31SJohn Baldwin } else
63938765a31SJohn Baldwin tvp = NULL;
6403ebc1248SPeter Wemm /*
64138765a31SJohn Baldwin * XXX Do pointers need PTRIN()?
6423ebc1248SPeter Wemm */
643b55ef216SKonstantin Belousov return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
644b55ef216SKonstantin Belousov sizeof(int32_t) * 8));
6453ebc1248SPeter Wemm }
6463ebc1248SPeter Wemm
647066d836bSKonstantin Belousov int
freebsd32_pselect(struct thread * td,struct freebsd32_pselect_args * uap)648066d836bSKonstantin Belousov freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
649066d836bSKonstantin Belousov {
650066d836bSKonstantin Belousov struct timespec32 ts32;
651066d836bSKonstantin Belousov struct timespec ts;
652066d836bSKonstantin Belousov struct timeval tv, *tvp;
653066d836bSKonstantin Belousov sigset_t set, *uset;
654066d836bSKonstantin Belousov int error;
655066d836bSKonstantin Belousov
656066d836bSKonstantin Belousov if (uap->ts != NULL) {
657066d836bSKonstantin Belousov error = copyin(uap->ts, &ts32, sizeof(ts32));
658066d836bSKonstantin Belousov if (error != 0)
659066d836bSKonstantin Belousov return (error);
660066d836bSKonstantin Belousov CP(ts32, ts, tv_sec);
661066d836bSKonstantin Belousov CP(ts32, ts, tv_nsec);
662066d836bSKonstantin Belousov TIMESPEC_TO_TIMEVAL(&tv, &ts);
663066d836bSKonstantin Belousov tvp = &tv;
664066d836bSKonstantin Belousov } else
665066d836bSKonstantin Belousov tvp = NULL;
666066d836bSKonstantin Belousov if (uap->sm != NULL) {
667066d836bSKonstantin Belousov error = copyin(uap->sm, &set, sizeof(set));
668066d836bSKonstantin Belousov if (error != 0)
669066d836bSKonstantin Belousov return (error);
670066d836bSKonstantin Belousov uset = &set;
671066d836bSKonstantin Belousov } else
672066d836bSKonstantin Belousov uset = NULL;
673066d836bSKonstantin Belousov /*
674066d836bSKonstantin Belousov * XXX Do pointers need PTRIN()?
675066d836bSKonstantin Belousov */
676066d836bSKonstantin Belousov error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
677066d836bSKonstantin Belousov uset, sizeof(int32_t) * 8);
678066d836bSKonstantin Belousov return (error);
679066d836bSKonstantin Belousov }
680066d836bSKonstantin Belousov
6816534c173SKonstantin Belousov static void
freebsd32_kevent_to_kevent32(const struct kevent * kevp,struct kevent32 * ks32)6826534c173SKonstantin Belousov freebsd32_kevent_to_kevent32(const struct kevent *kevp, struct kevent32 *ks32)
6836534c173SKonstantin Belousov {
6846534c173SKonstantin Belousov uint64_t e;
6856534c173SKonstantin Belousov int j;
6866534c173SKonstantin Belousov
6876534c173SKonstantin Belousov CP(*kevp, *ks32, ident);
6886534c173SKonstantin Belousov CP(*kevp, *ks32, filter);
6896534c173SKonstantin Belousov CP(*kevp, *ks32, flags);
6906534c173SKonstantin Belousov CP(*kevp, *ks32, fflags);
6916534c173SKonstantin Belousov #if BYTE_ORDER == LITTLE_ENDIAN
6926534c173SKonstantin Belousov ks32->data1 = kevp->data;
6936534c173SKonstantin Belousov ks32->data2 = kevp->data >> 32;
6946534c173SKonstantin Belousov #else
6956534c173SKonstantin Belousov ks32->data1 = kevp->data >> 32;
6966534c173SKonstantin Belousov ks32->data2 = kevp->data;
6976534c173SKonstantin Belousov #endif
6986534c173SKonstantin Belousov PTROUT_CP(*kevp, *ks32, udata);
6996534c173SKonstantin Belousov for (j = 0; j < nitems(kevp->ext); j++) {
7006534c173SKonstantin Belousov e = kevp->ext[j];
7016534c173SKonstantin Belousov #if BYTE_ORDER == LITTLE_ENDIAN
7026534c173SKonstantin Belousov ks32->ext64[2 * j] = e;
7036534c173SKonstantin Belousov ks32->ext64[2 * j + 1] = e >> 32;
7046534c173SKonstantin Belousov #else
7056534c173SKonstantin Belousov ks32->ext64[2 * j] = e >> 32;
7066534c173SKonstantin Belousov ks32->ext64[2 * j + 1] = e;
7076534c173SKonstantin Belousov #endif
7086534c173SKonstantin Belousov }
7096534c173SKonstantin Belousov }
7106534c173SKonstantin Belousov
711fa8fdd80SKonstantin Belousov void
freebsd32_kinfo_knote_to_32(const struct kinfo_knote * kin,struct kinfo_knote32 * kin32)712fa8fdd80SKonstantin Belousov freebsd32_kinfo_knote_to_32(const struct kinfo_knote *kin,
713fa8fdd80SKonstantin Belousov struct kinfo_knote32 *kin32)
714fa8fdd80SKonstantin Belousov {
715fa8fdd80SKonstantin Belousov memset(kin32, 0, sizeof(*kin32));
716fa8fdd80SKonstantin Belousov CP(*kin, *kin32, knt_kq_fd);
717fa8fdd80SKonstantin Belousov freebsd32_kevent_to_kevent32(&kin->knt_event, &kin32->knt_event);
718fa8fdd80SKonstantin Belousov CP(*kin, *kin32, knt_status);
719fa8fdd80SKonstantin Belousov CP(*kin, *kin32, knt_extdata);
720fa8fdd80SKonstantin Belousov switch (kin->knt_extdata) {
721fa8fdd80SKonstantin Belousov case KNOTE_EXTDATA_NONE:
722fa8fdd80SKonstantin Belousov break;
723fa8fdd80SKonstantin Belousov case KNOTE_EXTDATA_VNODE:
724fa8fdd80SKonstantin Belousov CP(*kin, *kin32, knt_vnode.knt_vnode_type);
725fa8fdd80SKonstantin Belousov #if BYTE_ORDER == LITTLE_ENDIAN
726fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
727fa8fdd80SKonstantin Belousov knt_vnode_fsid;
728fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
729fa8fdd80SKonstantin Belousov knt_vnode_fsid >> 32;
730fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
731fa8fdd80SKonstantin Belousov knt_vnode_fileid;
732fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
733fa8fdd80SKonstantin Belousov knt_vnode_fileid >> 32;
734fa8fdd80SKonstantin Belousov #else
735fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
736fa8fdd80SKonstantin Belousov knt_vnode_fsid;
737fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
738fa8fdd80SKonstantin Belousov knt_vnode_fsid >> 32;
739fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
740fa8fdd80SKonstantin Belousov knt_vnode_fileid;
741fa8fdd80SKonstantin Belousov kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
742fa8fdd80SKonstantin Belousov knt_vnode_fileid >> 32;
743fa8fdd80SKonstantin Belousov #endif
744fa8fdd80SKonstantin Belousov memcpy(kin32->knt_vnode.knt_vnode_fullpath,
745fa8fdd80SKonstantin Belousov kin->knt_vnode.knt_vnode_fullpath, PATH_MAX);
746fa8fdd80SKonstantin Belousov break;
747fa8fdd80SKonstantin Belousov case KNOTE_EXTDATA_PIPE:
748fa8fdd80SKonstantin Belousov #if BYTE_ORDER == LITTLE_ENDIAN
749fa8fdd80SKonstantin Belousov kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.knt_pipe_ino;
750fa8fdd80SKonstantin Belousov kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.
751fa8fdd80SKonstantin Belousov knt_pipe_ino >> 32;
752fa8fdd80SKonstantin Belousov #else
753fa8fdd80SKonstantin Belousov kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.knt_pipe_ino;
754fa8fdd80SKonstantin Belousov kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.
755fa8fdd80SKonstantin Belousov knt_pipe_ino >> 32;
756fa8fdd80SKonstantin Belousov #endif
757fa8fdd80SKonstantin Belousov break;
758fa8fdd80SKonstantin Belousov }
759fa8fdd80SKonstantin Belousov }
760fa8fdd80SKonstantin Belousov
761efe5becaSPaul Saab /*
762efe5becaSPaul Saab * Copy 'count' items into the destination list pointed to by uap->eventlist.
763efe5becaSPaul Saab */
764efe5becaSPaul Saab static int
freebsd32_kevent_copyout(void * arg,struct kevent * kevp,int count)765efe5becaSPaul Saab freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
766efe5becaSPaul Saab {
767efe5becaSPaul Saab struct freebsd32_kevent_args *uap;
768efe5becaSPaul Saab struct kevent32 ks32[KQ_NEVENTS];
7696534c173SKonstantin Belousov int i, error;
770efe5becaSPaul Saab
771efe5becaSPaul Saab KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
772efe5becaSPaul Saab uap = (struct freebsd32_kevent_args *)arg;
773efe5becaSPaul Saab
7746534c173SKonstantin Belousov for (i = 0; i < count; i++)
7756534c173SKonstantin Belousov freebsd32_kevent_to_kevent32(&kevp[i], &ks32[i]);
7762b34e843SKonstantin Belousov error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
7772b34e843SKonstantin Belousov if (error == 0)
7782b34e843SKonstantin Belousov uap->eventlist += count;
7792b34e843SKonstantin Belousov return (error);
7802b34e843SKonstantin Belousov }
7812b34e843SKonstantin Belousov
7822b34e843SKonstantin Belousov /*
7832b34e843SKonstantin Belousov * Copy 'count' items from the list pointed to by uap->changelist.
7842b34e843SKonstantin Belousov */
7852b34e843SKonstantin Belousov static int
freebsd32_kevent_copyin(void * arg,struct kevent * kevp,int count)7862b34e843SKonstantin Belousov freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
7872b34e843SKonstantin Belousov {
7882b34e843SKonstantin Belousov struct freebsd32_kevent_args *uap;
7892b34e843SKonstantin Belousov struct kevent32 ks32[KQ_NEVENTS];
7902b34e843SKonstantin Belousov uint64_t e;
7912b34e843SKonstantin Belousov int i, j, error;
7922b34e843SKonstantin Belousov
7932b34e843SKonstantin Belousov KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
7942b34e843SKonstantin Belousov uap = (struct freebsd32_kevent_args *)arg;
7952b34e843SKonstantin Belousov
7962b34e843SKonstantin Belousov error = copyin(uap->changelist, ks32, count * sizeof *ks32);
7972b34e843SKonstantin Belousov if (error)
7982b34e843SKonstantin Belousov goto done;
7992b34e843SKonstantin Belousov uap->changelist += count;
8002b34e843SKonstantin Belousov
8012b34e843SKonstantin Belousov for (i = 0; i < count; i++) {
8022b34e843SKonstantin Belousov CP(ks32[i], kevp[i], ident);
8032b34e843SKonstantin Belousov CP(ks32[i], kevp[i], filter);
8042b34e843SKonstantin Belousov CP(ks32[i], kevp[i], flags);
8052b34e843SKonstantin Belousov CP(ks32[i], kevp[i], fflags);
8062b34e843SKonstantin Belousov kevp[i].data = PAIR32TO64(uint64_t, ks32[i].data);
8072b34e843SKonstantin Belousov PTRIN_CP(ks32[i], kevp[i], udata);
8082b34e843SKonstantin Belousov for (j = 0; j < nitems(kevp->ext); j++) {
8092b34e843SKonstantin Belousov #if BYTE_ORDER == LITTLE_ENDIAN
8102b34e843SKonstantin Belousov e = ks32[i].ext64[2 * j + 1];
8112b34e843SKonstantin Belousov e <<= 32;
8122b34e843SKonstantin Belousov e += ks32[i].ext64[2 * j];
8132b34e843SKonstantin Belousov #else
8142b34e843SKonstantin Belousov e = ks32[i].ext64[2 * j];
8152b34e843SKonstantin Belousov e <<= 32;
8162b34e843SKonstantin Belousov e += ks32[i].ext64[2 * j + 1];
8172b34e843SKonstantin Belousov #endif
8182b34e843SKonstantin Belousov kevp[i].ext[j] = e;
8192b34e843SKonstantin Belousov }
8202b34e843SKonstantin Belousov }
8212b34e843SKonstantin Belousov done:
8222b34e843SKonstantin Belousov return (error);
8232b34e843SKonstantin Belousov }
8242b34e843SKonstantin Belousov
8252b34e843SKonstantin Belousov int
freebsd32_kevent(struct thread * td,struct freebsd32_kevent_args * uap)8262b34e843SKonstantin Belousov freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
8272b34e843SKonstantin Belousov {
8282b34e843SKonstantin Belousov struct timespec32 ts32;
8292b34e843SKonstantin Belousov struct timespec ts, *tsp;
8302b34e843SKonstantin Belousov struct kevent_copyops k_ops = {
8312b34e843SKonstantin Belousov .arg = uap,
8322b34e843SKonstantin Belousov .k_copyout = freebsd32_kevent_copyout,
8332b34e843SKonstantin Belousov .k_copyin = freebsd32_kevent_copyin,
8342b34e843SKonstantin Belousov };
835ffb66079SJohn Baldwin #ifdef KTRACE
836ffb66079SJohn Baldwin struct kevent32 *eventlist = uap->eventlist;
837ffb66079SJohn Baldwin #endif
8382b34e843SKonstantin Belousov int error;
8392b34e843SKonstantin Belousov
8402b34e843SKonstantin Belousov if (uap->timeout) {
8412b34e843SKonstantin Belousov error = copyin(uap->timeout, &ts32, sizeof(ts32));
8422b34e843SKonstantin Belousov if (error)
8432b34e843SKonstantin Belousov return (error);
8442b34e843SKonstantin Belousov CP(ts32, ts, tv_sec);
8452b34e843SKonstantin Belousov CP(ts32, ts, tv_nsec);
8462b34e843SKonstantin Belousov tsp = &ts;
8472b34e843SKonstantin Belousov } else
8482b34e843SKonstantin Belousov tsp = NULL;
849ffb66079SJohn Baldwin #ifdef KTRACE
850ffb66079SJohn Baldwin if (KTRPOINT(td, KTR_STRUCT_ARRAY))
851ffb66079SJohn Baldwin ktrstructarray("kevent32", UIO_USERSPACE, uap->changelist,
852ffb66079SJohn Baldwin uap->nchanges, sizeof(struct kevent32));
853ffb66079SJohn Baldwin #endif
8542b34e843SKonstantin Belousov error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
8552b34e843SKonstantin Belousov &k_ops, tsp);
856ffb66079SJohn Baldwin #ifdef KTRACE
857ffb66079SJohn Baldwin if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY))
858ffb66079SJohn Baldwin ktrstructarray("kevent32", UIO_USERSPACE, eventlist,
859ffb66079SJohn Baldwin td->td_retval[0], sizeof(struct kevent32));
860ffb66079SJohn Baldwin #endif
8612b34e843SKonstantin Belousov return (error);
8622b34e843SKonstantin Belousov }
8632b34e843SKonstantin Belousov
8642b34e843SKonstantin Belousov #ifdef COMPAT_FREEBSD11
8652b34e843SKonstantin Belousov static int
freebsd32_kevent11_copyout(void * arg,struct kevent * kevp,int count)8662b34e843SKonstantin Belousov freebsd32_kevent11_copyout(void *arg, struct kevent *kevp, int count)
8672b34e843SKonstantin Belousov {
8682b34e843SKonstantin Belousov struct freebsd11_freebsd32_kevent_args *uap;
8698e4a3addSBrooks Davis struct freebsd11_kevent32 ks32[KQ_NEVENTS];
8702b34e843SKonstantin Belousov int i, error;
8712b34e843SKonstantin Belousov
8722b34e843SKonstantin Belousov KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
8732b34e843SKonstantin Belousov uap = (struct freebsd11_freebsd32_kevent_args *)arg;
8742b34e843SKonstantin Belousov
8752b34e843SKonstantin Belousov for (i = 0; i < count; i++) {
8762b34e843SKonstantin Belousov CP(kevp[i], ks32[i], ident);
8772b34e843SKonstantin Belousov CP(kevp[i], ks32[i], filter);
8782b34e843SKonstantin Belousov CP(kevp[i], ks32[i], flags);
8792b34e843SKonstantin Belousov CP(kevp[i], ks32[i], fflags);
880efe5becaSPaul Saab CP(kevp[i], ks32[i], data);
881efe5becaSPaul Saab PTROUT_CP(kevp[i], ks32[i], udata);
882efe5becaSPaul Saab }
883efe5becaSPaul Saab error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
884efe5becaSPaul Saab if (error == 0)
885efe5becaSPaul Saab uap->eventlist += count;
886efe5becaSPaul Saab return (error);
887efe5becaSPaul Saab }
888efe5becaSPaul Saab
889efe5becaSPaul Saab /*
890efe5becaSPaul Saab * Copy 'count' items from the list pointed to by uap->changelist.
891efe5becaSPaul Saab */
892efe5becaSPaul Saab static int
freebsd32_kevent11_copyin(void * arg,struct kevent * kevp,int count)8932b34e843SKonstantin Belousov freebsd32_kevent11_copyin(void *arg, struct kevent *kevp, int count)
894efe5becaSPaul Saab {
8952b34e843SKonstantin Belousov struct freebsd11_freebsd32_kevent_args *uap;
8968e4a3addSBrooks Davis struct freebsd11_kevent32 ks32[KQ_NEVENTS];
8972b34e843SKonstantin Belousov int i, j, error;
898efe5becaSPaul Saab
899efe5becaSPaul Saab KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
9002b34e843SKonstantin Belousov uap = (struct freebsd11_freebsd32_kevent_args *)arg;
901efe5becaSPaul Saab
902efe5becaSPaul Saab error = copyin(uap->changelist, ks32, count * sizeof *ks32);
903efe5becaSPaul Saab if (error)
904efe5becaSPaul Saab goto done;
905efe5becaSPaul Saab uap->changelist += count;
906efe5becaSPaul Saab
907efe5becaSPaul Saab for (i = 0; i < count; i++) {
908efe5becaSPaul Saab CP(ks32[i], kevp[i], ident);
909efe5becaSPaul Saab CP(ks32[i], kevp[i], filter);
910efe5becaSPaul Saab CP(ks32[i], kevp[i], flags);
911efe5becaSPaul Saab CP(ks32[i], kevp[i], fflags);
912efe5becaSPaul Saab CP(ks32[i], kevp[i], data);
913efe5becaSPaul Saab PTRIN_CP(ks32[i], kevp[i], udata);
9142b34e843SKonstantin Belousov for (j = 0; j < nitems(kevp->ext); j++)
9152b34e843SKonstantin Belousov kevp[i].ext[j] = 0;
916efe5becaSPaul Saab }
917efe5becaSPaul Saab done:
918efe5becaSPaul Saab return (error);
919efe5becaSPaul Saab }
92060a8c422SPeter Wemm
921d85631c4SPeter Wemm int
freebsd11_freebsd32_kevent(struct thread * td,struct freebsd11_freebsd32_kevent_args * uap)9222b34e843SKonstantin Belousov freebsd11_freebsd32_kevent(struct thread *td,
9232b34e843SKonstantin Belousov struct freebsd11_freebsd32_kevent_args *uap)
924d85631c4SPeter Wemm {
925d85631c4SPeter Wemm struct timespec32 ts32;
926b8a4edc1SPaul Saab struct timespec ts, *tsp;
92701feb4c3SKonstantin Belousov struct kevent_copyops k_ops = {
92801feb4c3SKonstantin Belousov .arg = uap,
9292b34e843SKonstantin Belousov .k_copyout = freebsd32_kevent11_copyout,
9302b34e843SKonstantin Belousov .k_copyin = freebsd32_kevent11_copyin,
93101feb4c3SKonstantin Belousov };
932ffb66079SJohn Baldwin #ifdef KTRACE
9338e4a3addSBrooks Davis struct freebsd11_kevent32 *eventlist = uap->eventlist;
934ffb66079SJohn Baldwin #endif
935efe5becaSPaul Saab int error;
936d85631c4SPeter Wemm
937d85631c4SPeter Wemm if (uap->timeout) {
938d85631c4SPeter Wemm error = copyin(uap->timeout, &ts32, sizeof(ts32));
939d85631c4SPeter Wemm if (error)
940d85631c4SPeter Wemm return (error);
941d85631c4SPeter Wemm CP(ts32, ts, tv_sec);
942d85631c4SPeter Wemm CP(ts32, ts, tv_nsec);
943b8a4edc1SPaul Saab tsp = &ts;
944b8a4edc1SPaul Saab } else
945b8a4edc1SPaul Saab tsp = NULL;
946ffb66079SJohn Baldwin #ifdef KTRACE
947ffb66079SJohn Baldwin if (KTRPOINT(td, KTR_STRUCT_ARRAY))
9488e4a3addSBrooks Davis ktrstructarray("freebsd11_kevent32", UIO_USERSPACE,
949ffb66079SJohn Baldwin uap->changelist, uap->nchanges,
9508e4a3addSBrooks Davis sizeof(struct freebsd11_kevent32));
951ffb66079SJohn Baldwin #endif
952efe5becaSPaul Saab error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
953efe5becaSPaul Saab &k_ops, tsp);
954ffb66079SJohn Baldwin #ifdef KTRACE
955ffb66079SJohn Baldwin if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY))
9568e4a3addSBrooks Davis ktrstructarray("freebsd11_kevent32", UIO_USERSPACE,
957ffb66079SJohn Baldwin eventlist, td->td_retval[0],
9588e4a3addSBrooks Davis sizeof(struct freebsd11_kevent32));
959ffb66079SJohn Baldwin #endif
960d85631c4SPeter Wemm return (error);
961d85631c4SPeter Wemm }
9622b34e843SKonstantin Belousov #endif
963d85631c4SPeter Wemm
9643ebc1248SPeter Wemm int
freebsd32_gettimeofday(struct thread * td,struct freebsd32_gettimeofday_args * uap)9651c7abef7SPeter Wemm freebsd32_gettimeofday(struct thread *td,
9661c7abef7SPeter Wemm struct freebsd32_gettimeofday_args *uap)
9673ebc1248SPeter Wemm {
9684eeb271aSPeter Wemm struct timeval atv;
9694eeb271aSPeter Wemm struct timeval32 atv32;
9704eeb271aSPeter Wemm struct timezone rtz;
9714eeb271aSPeter Wemm int error = 0;
9723ebc1248SPeter Wemm
9734eeb271aSPeter Wemm if (uap->tp) {
9744eeb271aSPeter Wemm microtime(&atv);
9754eeb271aSPeter Wemm CP(atv, atv32, tv_sec);
9764eeb271aSPeter Wemm CP(atv, atv32, tv_usec);
9774eeb271aSPeter Wemm error = copyout(&atv32, uap->tp, sizeof (atv32));
9783ebc1248SPeter Wemm }
9794eeb271aSPeter Wemm if (error == 0 && uap->tzp != NULL) {
980329f0aa9SWarner Losh rtz.tz_minuteswest = 0;
981329f0aa9SWarner Losh rtz.tz_dsttime = 0;
9824eeb271aSPeter Wemm error = copyout(&rtz, uap->tzp, sizeof (rtz));
9833ebc1248SPeter Wemm }
9843ebc1248SPeter Wemm return (error);
9853ebc1248SPeter Wemm }
9863ebc1248SPeter Wemm
9873ebc1248SPeter Wemm int
freebsd32_getrusage(struct thread * td,struct freebsd32_getrusage_args * uap)9881c7abef7SPeter Wemm freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
9893ebc1248SPeter Wemm {
99078c85e8dSJohn Baldwin struct rusage32 s32;
99178c85e8dSJohn Baldwin struct rusage s;
9923ebc1248SPeter Wemm int error;
9933ebc1248SPeter Wemm
99478c85e8dSJohn Baldwin error = kern_getrusage(td, uap->who, &s);
9959dea3ac8SAlan Somers if (error == 0) {
9969847e91bSKonstantin Belousov freebsd32_rusage_out(&s, &s32);
99778c85e8dSJohn Baldwin error = copyout(&s32, uap->rusage, sizeof(s32));
9989dea3ac8SAlan Somers }
9993ebc1248SPeter Wemm return (error);
10003ebc1248SPeter Wemm }
10013ebc1248SPeter Wemm
100258b552dcSJohn Baldwin static void
ptrace_lwpinfo_to32(const struct ptrace_lwpinfo * pl,struct ptrace_lwpinfo32 * pl32)100358b552dcSJohn Baldwin ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
100458b552dcSJohn Baldwin struct ptrace_lwpinfo32 *pl32)
100558b552dcSJohn Baldwin {
100658b552dcSJohn Baldwin
100758b552dcSJohn Baldwin bzero(pl32, sizeof(*pl32));
100858b552dcSJohn Baldwin pl32->pl_lwpid = pl->pl_lwpid;
100958b552dcSJohn Baldwin pl32->pl_event = pl->pl_event;
101058b552dcSJohn Baldwin pl32->pl_flags = pl->pl_flags;
101158b552dcSJohn Baldwin pl32->pl_sigmask = pl->pl_sigmask;
101258b552dcSJohn Baldwin pl32->pl_siglist = pl->pl_siglist;
101358b552dcSJohn Baldwin siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
101458b552dcSJohn Baldwin strcpy(pl32->pl_tdname, pl->pl_tdname);
101558b552dcSJohn Baldwin pl32->pl_child_pid = pl->pl_child_pid;
101658b552dcSJohn Baldwin pl32->pl_syscall_code = pl->pl_syscall_code;
101758b552dcSJohn Baldwin pl32->pl_syscall_narg = pl->pl_syscall_narg;
101858b552dcSJohn Baldwin }
101958b552dcSJohn Baldwin
102058b552dcSJohn Baldwin static void
ptrace_sc_ret_to32(const struct ptrace_sc_ret * psr,struct ptrace_sc_ret32 * psr32)102158b552dcSJohn Baldwin ptrace_sc_ret_to32(const struct ptrace_sc_ret *psr,
102258b552dcSJohn Baldwin struct ptrace_sc_ret32 *psr32)
102358b552dcSJohn Baldwin {
102458b552dcSJohn Baldwin
102558b552dcSJohn Baldwin bzero(psr32, sizeof(*psr32));
102658b552dcSJohn Baldwin psr32->sr_retval[0] = psr->sr_retval[0];
102758b552dcSJohn Baldwin psr32->sr_retval[1] = psr->sr_retval[1];
102858b552dcSJohn Baldwin psr32->sr_error = psr->sr_error;
102958b552dcSJohn Baldwin }
103058b552dcSJohn Baldwin
103158b552dcSJohn Baldwin int
freebsd32_ptrace(struct thread * td,struct freebsd32_ptrace_args * uap)103258b552dcSJohn Baldwin freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
103358b552dcSJohn Baldwin {
103458b552dcSJohn Baldwin union {
103558b552dcSJohn Baldwin struct ptrace_io_desc piod;
103658b552dcSJohn Baldwin struct ptrace_lwpinfo pl;
103758b552dcSJohn Baldwin struct ptrace_vm_entry pve;
103887a64872SKonstantin Belousov struct ptrace_coredump pc;
1039140ceb5dSKonstantin Belousov struct ptrace_sc_remote sr;
104058b552dcSJohn Baldwin struct dbreg32 dbreg;
104158b552dcSJohn Baldwin struct fpreg32 fpreg;
104258b552dcSJohn Baldwin struct reg32 reg;
1043548a2ec4SAndrew Turner struct iovec vec;
104458b552dcSJohn Baldwin register_t args[nitems(td->td_sa.args)];
104558b552dcSJohn Baldwin struct ptrace_sc_ret psr;
104658b552dcSJohn Baldwin int ptevents;
104758b552dcSJohn Baldwin } r;
104858b552dcSJohn Baldwin union {
104958b552dcSJohn Baldwin struct ptrace_io_desc32 piod;
105058b552dcSJohn Baldwin struct ptrace_lwpinfo32 pl;
105158b552dcSJohn Baldwin struct ptrace_vm_entry32 pve;
105287a64872SKonstantin Belousov struct ptrace_coredump32 pc;
1053140ceb5dSKonstantin Belousov struct ptrace_sc_remote32 sr;
105458b552dcSJohn Baldwin uint32_t args[nitems(td->td_sa.args)];
105558b552dcSJohn Baldwin struct ptrace_sc_ret32 psr;
1056548a2ec4SAndrew Turner struct iovec32 vec;
105758b552dcSJohn Baldwin } r32;
1058140ceb5dSKonstantin Belousov syscallarg_t pscr_args[nitems(td->td_sa.args)];
1059140ceb5dSKonstantin Belousov u_int pscr_args32[nitems(td->td_sa.args)];
106058b552dcSJohn Baldwin void *addr;
1061fe6db727SKonstantin Belousov int data, error, i;
1062fe6db727SKonstantin Belousov
1063fe6db727SKonstantin Belousov if (!allow_ptrace)
1064fe6db727SKonstantin Belousov return (ENOSYS);
1065fe6db727SKonstantin Belousov error = 0;
106658b552dcSJohn Baldwin
106758b552dcSJohn Baldwin AUDIT_ARG_PID(uap->pid);
106858b552dcSJohn Baldwin AUDIT_ARG_CMD(uap->req);
106958b552dcSJohn Baldwin AUDIT_ARG_VALUE(uap->data);
107058b552dcSJohn Baldwin addr = &r;
107158b552dcSJohn Baldwin data = uap->data;
107258b552dcSJohn Baldwin switch (uap->req) {
107358b552dcSJohn Baldwin case PT_GET_EVENT_MASK:
107458b552dcSJohn Baldwin case PT_GET_SC_ARGS:
107558b552dcSJohn Baldwin case PT_GET_SC_RET:
107658b552dcSJohn Baldwin break;
107758b552dcSJohn Baldwin case PT_LWPINFO:
107858b552dcSJohn Baldwin if (uap->data > sizeof(r32.pl))
107958b552dcSJohn Baldwin return (EINVAL);
108058b552dcSJohn Baldwin
108158b552dcSJohn Baldwin /*
108258b552dcSJohn Baldwin * Pass size of native structure in 'data'. Truncate
108358b552dcSJohn Baldwin * if necessary to avoid siginfo.
108458b552dcSJohn Baldwin */
108558b552dcSJohn Baldwin data = sizeof(r.pl);
108658b552dcSJohn Baldwin if (uap->data < offsetof(struct ptrace_lwpinfo32, pl_siginfo) +
1087d060b420SBrooks Davis sizeof(struct __siginfo32))
108858b552dcSJohn Baldwin data = offsetof(struct ptrace_lwpinfo, pl_siginfo);
108958b552dcSJohn Baldwin break;
109058b552dcSJohn Baldwin case PT_GETREGS:
109158b552dcSJohn Baldwin bzero(&r.reg, sizeof(r.reg));
109258b552dcSJohn Baldwin break;
109358b552dcSJohn Baldwin case PT_GETFPREGS:
109458b552dcSJohn Baldwin bzero(&r.fpreg, sizeof(r.fpreg));
109558b552dcSJohn Baldwin break;
109658b552dcSJohn Baldwin case PT_GETDBREGS:
109758b552dcSJohn Baldwin bzero(&r.dbreg, sizeof(r.dbreg));
109858b552dcSJohn Baldwin break;
109958b552dcSJohn Baldwin case PT_SETREGS:
110058b552dcSJohn Baldwin error = copyin(uap->addr, &r.reg, sizeof(r.reg));
110158b552dcSJohn Baldwin break;
110258b552dcSJohn Baldwin case PT_SETFPREGS:
110358b552dcSJohn Baldwin error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg));
110458b552dcSJohn Baldwin break;
110558b552dcSJohn Baldwin case PT_SETDBREGS:
110658b552dcSJohn Baldwin error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg));
110758b552dcSJohn Baldwin break;
1108548a2ec4SAndrew Turner case PT_GETREGSET:
1109949e3959SJohn Baldwin case PT_SETREGSET:
1110548a2ec4SAndrew Turner error = copyin(uap->addr, &r32.vec, sizeof(r32.vec));
1111548a2ec4SAndrew Turner if (error != 0)
1112548a2ec4SAndrew Turner break;
1113548a2ec4SAndrew Turner
1114548a2ec4SAndrew Turner r.vec.iov_len = r32.vec.iov_len;
1115548a2ec4SAndrew Turner r.vec.iov_base = PTRIN(r32.vec.iov_base);
1116548a2ec4SAndrew Turner break;
111758b552dcSJohn Baldwin case PT_SET_EVENT_MASK:
111858b552dcSJohn Baldwin if (uap->data != sizeof(r.ptevents))
111958b552dcSJohn Baldwin error = EINVAL;
112058b552dcSJohn Baldwin else
112158b552dcSJohn Baldwin error = copyin(uap->addr, &r.ptevents, uap->data);
112258b552dcSJohn Baldwin break;
112358b552dcSJohn Baldwin case PT_IO:
112458b552dcSJohn Baldwin error = copyin(uap->addr, &r32.piod, sizeof(r32.piod));
112558b552dcSJohn Baldwin if (error)
112658b552dcSJohn Baldwin break;
112758b552dcSJohn Baldwin CP(r32.piod, r.piod, piod_op);
112858b552dcSJohn Baldwin PTRIN_CP(r32.piod, r.piod, piod_offs);
112958b552dcSJohn Baldwin PTRIN_CP(r32.piod, r.piod, piod_addr);
113058b552dcSJohn Baldwin CP(r32.piod, r.piod, piod_len);
113158b552dcSJohn Baldwin break;
113258b552dcSJohn Baldwin case PT_VM_ENTRY:
113358b552dcSJohn Baldwin error = copyin(uap->addr, &r32.pve, sizeof(r32.pve));
113458b552dcSJohn Baldwin if (error)
113558b552dcSJohn Baldwin break;
113658b552dcSJohn Baldwin
113758b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_entry);
113858b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_timestamp);
113958b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_start);
114058b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_end);
114158b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_offset);
114258b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_prot);
114358b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_pathlen);
114458b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_fileid);
114558b552dcSJohn Baldwin CP(r32.pve, r.pve, pve_fsid);
114658b552dcSJohn Baldwin PTRIN_CP(r32.pve, r.pve, pve_path);
114758b552dcSJohn Baldwin break;
114887a64872SKonstantin Belousov case PT_COREDUMP:
114987a64872SKonstantin Belousov if (uap->data != sizeof(r32.pc))
115087a64872SKonstantin Belousov error = EINVAL;
115187a64872SKonstantin Belousov else
115287a64872SKonstantin Belousov error = copyin(uap->addr, &r32.pc, uap->data);
115387a64872SKonstantin Belousov CP(r32.pc, r.pc, pc_fd);
115487a64872SKonstantin Belousov CP(r32.pc, r.pc, pc_flags);
115587a64872SKonstantin Belousov r.pc.pc_limit = PAIR32TO64(off_t, r32.pc.pc_limit);
115687a64872SKonstantin Belousov data = sizeof(r.pc);
115787a64872SKonstantin Belousov break;
1158140ceb5dSKonstantin Belousov case PT_SC_REMOTE:
1159140ceb5dSKonstantin Belousov if (uap->data != sizeof(r32.sr)) {
1160140ceb5dSKonstantin Belousov error = EINVAL;
1161140ceb5dSKonstantin Belousov break;
1162140ceb5dSKonstantin Belousov }
1163140ceb5dSKonstantin Belousov error = copyin(uap->addr, &r32.sr, uap->data);
1164140ceb5dSKonstantin Belousov if (error != 0)
1165140ceb5dSKonstantin Belousov break;
1166140ceb5dSKonstantin Belousov CP(r32.sr, r.sr, pscr_syscall);
1167140ceb5dSKonstantin Belousov CP(r32.sr, r.sr, pscr_nargs);
1168140ceb5dSKonstantin Belousov if (r.sr.pscr_nargs > nitems(td->td_sa.args)) {
1169140ceb5dSKonstantin Belousov error = EINVAL;
1170140ceb5dSKonstantin Belousov break;
1171140ceb5dSKonstantin Belousov }
1172140ceb5dSKonstantin Belousov error = copyin(PTRIN(r32.sr.pscr_args), pscr_args32,
1173140ceb5dSKonstantin Belousov sizeof(u_int) * r32.sr.pscr_nargs);
1174140ceb5dSKonstantin Belousov if (error != 0)
1175140ceb5dSKonstantin Belousov break;
1176140ceb5dSKonstantin Belousov for (i = 0; i < r32.sr.pscr_nargs; i++)
1177140ceb5dSKonstantin Belousov pscr_args[i] = pscr_args32[i];
1178140ceb5dSKonstantin Belousov r.sr.pscr_args = pscr_args;
1179140ceb5dSKonstantin Belousov break;
1180*ee609560SMark Johnston case PTINTERNAL_FIRST ... PTINTERNAL_LAST:
118148a656c5SMark Johnston error = EINVAL;
118248a656c5SMark Johnston break;
118358b552dcSJohn Baldwin default:
118458b552dcSJohn Baldwin addr = uap->addr;
118558b552dcSJohn Baldwin break;
118658b552dcSJohn Baldwin }
118758b552dcSJohn Baldwin if (error)
118858b552dcSJohn Baldwin return (error);
118958b552dcSJohn Baldwin
119058b552dcSJohn Baldwin error = kern_ptrace(td, uap->req, uap->pid, addr, data);
119158b552dcSJohn Baldwin if (error)
119258b552dcSJohn Baldwin return (error);
119358b552dcSJohn Baldwin
119458b552dcSJohn Baldwin switch (uap->req) {
119558b552dcSJohn Baldwin case PT_VM_ENTRY:
119658b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_entry);
119758b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_timestamp);
119858b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_start);
119958b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_end);
120058b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_offset);
120158b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_prot);
120258b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_pathlen);
120358b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_fileid);
120458b552dcSJohn Baldwin CP(r.pve, r32.pve, pve_fsid);
120558b552dcSJohn Baldwin error = copyout(&r32.pve, uap->addr, sizeof(r32.pve));
120658b552dcSJohn Baldwin break;
120758b552dcSJohn Baldwin case PT_IO:
120858b552dcSJohn Baldwin CP(r.piod, r32.piod, piod_len);
120958b552dcSJohn Baldwin error = copyout(&r32.piod, uap->addr, sizeof(r32.piod));
121058b552dcSJohn Baldwin break;
121158b552dcSJohn Baldwin case PT_GETREGS:
121258b552dcSJohn Baldwin error = copyout(&r.reg, uap->addr, sizeof(r.reg));
121358b552dcSJohn Baldwin break;
121458b552dcSJohn Baldwin case PT_GETFPREGS:
121558b552dcSJohn Baldwin error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg));
121658b552dcSJohn Baldwin break;
121758b552dcSJohn Baldwin case PT_GETDBREGS:
121858b552dcSJohn Baldwin error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg));
121958b552dcSJohn Baldwin break;
1220548a2ec4SAndrew Turner case PT_GETREGSET:
1221548a2ec4SAndrew Turner r32.vec.iov_len = r.vec.iov_len;
1222548a2ec4SAndrew Turner error = copyout(&r32.vec, uap->addr, sizeof(r32.vec));
1223548a2ec4SAndrew Turner break;
122458b552dcSJohn Baldwin case PT_GET_EVENT_MASK:
122558b552dcSJohn Baldwin /* NB: The size in uap->data is validated in kern_ptrace(). */
122658b552dcSJohn Baldwin error = copyout(&r.ptevents, uap->addr, uap->data);
122758b552dcSJohn Baldwin break;
122858b552dcSJohn Baldwin case PT_LWPINFO:
122958b552dcSJohn Baldwin ptrace_lwpinfo_to32(&r.pl, &r32.pl);
123058b552dcSJohn Baldwin error = copyout(&r32.pl, uap->addr, uap->data);
123158b552dcSJohn Baldwin break;
123258b552dcSJohn Baldwin case PT_GET_SC_ARGS:
123358b552dcSJohn Baldwin for (i = 0; i < nitems(r.args); i++)
123458b552dcSJohn Baldwin r32.args[i] = (uint32_t)r.args[i];
123558b552dcSJohn Baldwin error = copyout(r32.args, uap->addr, MIN(uap->data,
123658b552dcSJohn Baldwin sizeof(r32.args)));
123758b552dcSJohn Baldwin break;
123858b552dcSJohn Baldwin case PT_GET_SC_RET:
123958b552dcSJohn Baldwin ptrace_sc_ret_to32(&r.psr, &r32.psr);
124058b552dcSJohn Baldwin error = copyout(&r32.psr, uap->addr, MIN(uap->data,
124158b552dcSJohn Baldwin sizeof(r32.psr)));
124258b552dcSJohn Baldwin break;
1243140ceb5dSKonstantin Belousov case PT_SC_REMOTE:
1244140ceb5dSKonstantin Belousov ptrace_sc_ret_to32(&r.sr.pscr_ret, &r32.sr.pscr_ret);
1245140ceb5dSKonstantin Belousov error = copyout(&r32.sr.pscr_ret, uap->addr +
1246140ceb5dSKonstantin Belousov offsetof(struct ptrace_sc_remote32, pscr_ret),
1247140ceb5dSKonstantin Belousov sizeof(r32.psr));
1248140ceb5dSKonstantin Belousov break;
124958b552dcSJohn Baldwin }
125058b552dcSJohn Baldwin
125158b552dcSJohn Baldwin return (error);
125258b552dcSJohn Baldwin }
125358b552dcSJohn Baldwin
1254022ca2fcSAlan Somers int
freebsd32_copyinuio(const struct iovec32 * iovp,u_int iovcnt,struct uio ** uiop)1255694ef157SBrooks Davis freebsd32_copyinuio(const struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
125648052f99SJohn Baldwin {
125748052f99SJohn Baldwin struct iovec32 iov32;
125848052f99SJohn Baldwin struct iovec *iov;
125948052f99SJohn Baldwin struct uio *uio;
126048052f99SJohn Baldwin int error, i;
126148052f99SJohn Baldwin
126248052f99SJohn Baldwin *uiop = NULL;
126348052f99SJohn Baldwin if (iovcnt > UIO_MAXIOV)
126448052f99SJohn Baldwin return (EINVAL);
126561cc4830SAlfredo Mazzinghi uio = allocuio(iovcnt);
126661cc4830SAlfredo Mazzinghi iov = uio->uio_iov;
126748052f99SJohn Baldwin for (i = 0; i < iovcnt; i++) {
126848052f99SJohn Baldwin error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
126948052f99SJohn Baldwin if (error) {
127061cc4830SAlfredo Mazzinghi freeuio(uio);
127148052f99SJohn Baldwin return (error);
127248052f99SJohn Baldwin }
127348052f99SJohn Baldwin iov[i].iov_base = PTRIN(iov32.iov_base);
127448052f99SJohn Baldwin iov[i].iov_len = iov32.iov_len;
127548052f99SJohn Baldwin }
127648052f99SJohn Baldwin uio->uio_iovcnt = iovcnt;
127748052f99SJohn Baldwin uio->uio_segflg = UIO_USERSPACE;
127848052f99SJohn Baldwin uio->uio_offset = -1;
127948052f99SJohn Baldwin uio->uio_resid = 0;
128048052f99SJohn Baldwin for (i = 0; i < iovcnt; i++) {
128148052f99SJohn Baldwin if (iov->iov_len > INT_MAX - uio->uio_resid) {
128261cc4830SAlfredo Mazzinghi freeuio(uio);
128348052f99SJohn Baldwin return (EINVAL);
128448052f99SJohn Baldwin }
128548052f99SJohn Baldwin uio->uio_resid += iov->iov_len;
128648052f99SJohn Baldwin iov++;
128748052f99SJohn Baldwin }
128848052f99SJohn Baldwin *uiop = uio;
128948052f99SJohn Baldwin return (0);
129048052f99SJohn Baldwin }
129148052f99SJohn Baldwin
12923ebc1248SPeter Wemm int
freebsd32_readv(struct thread * td,struct freebsd32_readv_args * uap)12931c7abef7SPeter Wemm freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
12943ebc1248SPeter Wemm {
129548052f99SJohn Baldwin struct uio *auio;
129648052f99SJohn Baldwin int error;
12973ebc1248SPeter Wemm
129848052f99SJohn Baldwin error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
129948052f99SJohn Baldwin if (error)
130048052f99SJohn Baldwin return (error);
130148052f99SJohn Baldwin error = kern_readv(td, uap->fd, auio);
130261cc4830SAlfredo Mazzinghi freeuio(auio);
13033ebc1248SPeter Wemm return (error);
13043ebc1248SPeter Wemm }
13053ebc1248SPeter Wemm
13063ebc1248SPeter Wemm int
freebsd32_writev(struct thread * td,struct freebsd32_writev_args * uap)13071c7abef7SPeter Wemm freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
13083ebc1248SPeter Wemm {
130948052f99SJohn Baldwin struct uio *auio;
131048052f99SJohn Baldwin int error;
13113ebc1248SPeter Wemm
131248052f99SJohn Baldwin error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
131348052f99SJohn Baldwin if (error)
131448052f99SJohn Baldwin return (error);
131548052f99SJohn Baldwin error = kern_writev(td, uap->fd, auio);
131661cc4830SAlfredo Mazzinghi freeuio(auio);
13173ebc1248SPeter Wemm return (error);
13183ebc1248SPeter Wemm }
13193ebc1248SPeter Wemm
13203ebc1248SPeter Wemm int
freebsd32_preadv(struct thread * td,struct freebsd32_preadv_args * uap)1321bcd9e0ddSJohn Baldwin freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
1322bcd9e0ddSJohn Baldwin {
1323bcd9e0ddSJohn Baldwin struct uio *auio;
1324bcd9e0ddSJohn Baldwin int error;
1325bcd9e0ddSJohn Baldwin
1326bcd9e0ddSJohn Baldwin error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1327bcd9e0ddSJohn Baldwin if (error)
1328bcd9e0ddSJohn Baldwin return (error);
1329841c0c7eSNathan Whitehorn error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
133061cc4830SAlfredo Mazzinghi freeuio(auio);
1331bcd9e0ddSJohn Baldwin return (error);
1332bcd9e0ddSJohn Baldwin }
1333bcd9e0ddSJohn Baldwin
1334bcd9e0ddSJohn Baldwin int
freebsd32_pwritev(struct thread * td,struct freebsd32_pwritev_args * uap)1335bcd9e0ddSJohn Baldwin freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
1336bcd9e0ddSJohn Baldwin {
1337bcd9e0ddSJohn Baldwin struct uio *auio;
1338bcd9e0ddSJohn Baldwin int error;
1339bcd9e0ddSJohn Baldwin
1340bcd9e0ddSJohn Baldwin error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1341bcd9e0ddSJohn Baldwin if (error)
1342bcd9e0ddSJohn Baldwin return (error);
1343841c0c7eSNathan Whitehorn error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
134461cc4830SAlfredo Mazzinghi freeuio(auio);
1345bcd9e0ddSJohn Baldwin return (error);
1346bcd9e0ddSJohn Baldwin }
1347bcd9e0ddSJohn Baldwin
1348c5e4763dSKonstantin Belousov int
freebsd32_copyiniov(struct iovec32 * iovp32,u_int iovcnt,struct iovec ** iovp,int error)1349ecc44de7SPaul Saab freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
1350ecc44de7SPaul Saab int error)
1351ecc44de7SPaul Saab {
1352ecc44de7SPaul Saab struct iovec32 iov32;
1353ecc44de7SPaul Saab struct iovec *iov;
1354ecc44de7SPaul Saab u_int iovlen;
1355ecc44de7SPaul Saab int i;
1356ecc44de7SPaul Saab
1357ecc44de7SPaul Saab *iovp = NULL;
1358ecc44de7SPaul Saab if (iovcnt > UIO_MAXIOV)
1359ecc44de7SPaul Saab return (error);
1360ecc44de7SPaul Saab iovlen = iovcnt * sizeof(struct iovec);
1361ecc44de7SPaul Saab iov = malloc(iovlen, M_IOV, M_WAITOK);
1362ecc44de7SPaul Saab for (i = 0; i < iovcnt; i++) {
1363ecc44de7SPaul Saab error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
1364ecc44de7SPaul Saab if (error) {
1365ecc44de7SPaul Saab free(iov, M_IOV);
1366ecc44de7SPaul Saab return (error);
1367ecc44de7SPaul Saab }
1368ecc44de7SPaul Saab iov[i].iov_base = PTRIN(iov32.iov_base);
1369ecc44de7SPaul Saab iov[i].iov_len = iov32.iov_len;
1370ecc44de7SPaul Saab }
1371ecc44de7SPaul Saab *iovp = iov;
1372ecc44de7SPaul Saab return (0);
1373ecc44de7SPaul Saab }
1374ecc44de7SPaul Saab
1375a372f822SPaul Saab static int
freebsd32_copyinmsghdr(const struct msghdr32 * msg32,struct msghdr * msg)1376a944d28dSBrooks Davis freebsd32_copyinmsghdr(const struct msghdr32 *msg32, struct msghdr *msg)
1377a372f822SPaul Saab {
1378a372f822SPaul Saab struct msghdr32 m32;
1379a372f822SPaul Saab int error;
1380a372f822SPaul Saab
1381a372f822SPaul Saab error = copyin(msg32, &m32, sizeof(m32));
1382a372f822SPaul Saab if (error)
1383a372f822SPaul Saab return (error);
1384a372f822SPaul Saab msg->msg_name = PTRIN(m32.msg_name);
1385a372f822SPaul Saab msg->msg_namelen = m32.msg_namelen;
1386a372f822SPaul Saab msg->msg_iov = PTRIN(m32.msg_iov);
1387a372f822SPaul Saab msg->msg_iovlen = m32.msg_iovlen;
1388a372f822SPaul Saab msg->msg_control = PTRIN(m32.msg_control);
1389a372f822SPaul Saab msg->msg_controllen = m32.msg_controllen;
1390a372f822SPaul Saab msg->msg_flags = m32.msg_flags;
1391ecc44de7SPaul Saab return (0);
1392a372f822SPaul Saab }
1393a372f822SPaul Saab
1394a372f822SPaul Saab static int
freebsd32_copyoutmsghdr(struct msghdr * msg,struct msghdr32 * msg32)1395a372f822SPaul Saab freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
1396a372f822SPaul Saab {
1397a372f822SPaul Saab struct msghdr32 m32;
1398a372f822SPaul Saab int error;
1399a372f822SPaul Saab
1400a372f822SPaul Saab m32.msg_name = PTROUT(msg->msg_name);
1401a372f822SPaul Saab m32.msg_namelen = msg->msg_namelen;
1402a372f822SPaul Saab m32.msg_iov = PTROUT(msg->msg_iov);
1403a372f822SPaul Saab m32.msg_iovlen = msg->msg_iovlen;
1404a372f822SPaul Saab m32.msg_control = PTROUT(msg->msg_control);
1405a372f822SPaul Saab m32.msg_controllen = msg->msg_controllen;
1406a372f822SPaul Saab m32.msg_flags = msg->msg_flags;
1407a372f822SPaul Saab error = copyout(&m32, msg32, sizeof(m32));
1408a372f822SPaul Saab return (error);
1409a372f822SPaul Saab }
1410a372f822SPaul Saab
1411ecc44de7SPaul Saab #define FREEBSD32_ALIGNBYTES (sizeof(int) - 1)
1412ecc44de7SPaul Saab #define FREEBSD32_ALIGN(p) \
1413ecc44de7SPaul Saab (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
1414ecc44de7SPaul Saab #define FREEBSD32_CMSG_SPACE(l) \
1415ecc44de7SPaul Saab (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
1416ecc44de7SPaul Saab
1417ecc44de7SPaul Saab #define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \
1418ecc44de7SPaul Saab FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
1419afbd12c1SMaxim Sobolev
1420afbd12c1SMaxim Sobolev static size_t
freebsd32_cmsg_convert(const struct cmsghdr * cm,void * data,socklen_t datalen)1421c7902fbeSMark Johnston freebsd32_cmsg_convert(const struct cmsghdr *cm, void *data, socklen_t datalen)
1422afbd12c1SMaxim Sobolev {
1423afbd12c1SMaxim Sobolev size_t copylen;
1424afbd12c1SMaxim Sobolev union {
1425afbd12c1SMaxim Sobolev struct timespec32 ts;
1426afbd12c1SMaxim Sobolev struct timeval32 tv;
1427afbd12c1SMaxim Sobolev struct bintime32 bt;
1428afbd12c1SMaxim Sobolev } tmp32;
1429afbd12c1SMaxim Sobolev
1430afbd12c1SMaxim Sobolev union {
1431afbd12c1SMaxim Sobolev struct timespec ts;
1432afbd12c1SMaxim Sobolev struct timeval tv;
1433afbd12c1SMaxim Sobolev struct bintime bt;
1434afbd12c1SMaxim Sobolev } *in;
1435afbd12c1SMaxim Sobolev
1436afbd12c1SMaxim Sobolev in = data;
1437afbd12c1SMaxim Sobolev copylen = 0;
1438afbd12c1SMaxim Sobolev switch (cm->cmsg_level) {
1439afbd12c1SMaxim Sobolev case SOL_SOCKET:
1440afbd12c1SMaxim Sobolev switch (cm->cmsg_type) {
1441afbd12c1SMaxim Sobolev case SCM_TIMESTAMP:
1442afbd12c1SMaxim Sobolev TV_CP(*in, tmp32, tv);
1443afbd12c1SMaxim Sobolev copylen = sizeof(tmp32.tv);
1444afbd12c1SMaxim Sobolev break;
1445afbd12c1SMaxim Sobolev
1446afbd12c1SMaxim Sobolev case SCM_BINTIME:
1447afbd12c1SMaxim Sobolev BT_CP(*in, tmp32, bt);
1448afbd12c1SMaxim Sobolev copylen = sizeof(tmp32.bt);
1449afbd12c1SMaxim Sobolev break;
1450afbd12c1SMaxim Sobolev
1451afbd12c1SMaxim Sobolev case SCM_REALTIME:
1452afbd12c1SMaxim Sobolev case SCM_MONOTONIC:
1453afbd12c1SMaxim Sobolev TS_CP(*in, tmp32, ts);
1454afbd12c1SMaxim Sobolev copylen = sizeof(tmp32.ts);
1455afbd12c1SMaxim Sobolev break;
1456afbd12c1SMaxim Sobolev
1457afbd12c1SMaxim Sobolev default:
1458afbd12c1SMaxim Sobolev break;
1459afbd12c1SMaxim Sobolev }
1460afbd12c1SMaxim Sobolev
1461afbd12c1SMaxim Sobolev default:
1462afbd12c1SMaxim Sobolev break;
1463afbd12c1SMaxim Sobolev }
1464afbd12c1SMaxim Sobolev
1465afbd12c1SMaxim Sobolev if (copylen == 0)
1466afbd12c1SMaxim Sobolev return (datalen);
1467afbd12c1SMaxim Sobolev
1468afbd12c1SMaxim Sobolev KASSERT((datalen >= copylen), ("corrupted cmsghdr"));
1469afbd12c1SMaxim Sobolev
1470afbd12c1SMaxim Sobolev bcopy(&tmp32, data, copylen);
1471afbd12c1SMaxim Sobolev return (copylen);
1472afbd12c1SMaxim Sobolev }
1473afbd12c1SMaxim Sobolev
1474ecc44de7SPaul Saab static int
freebsd32_copy_msg_out(struct msghdr * msg,struct mbuf * control)1475ecc44de7SPaul Saab freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
1476ecc44de7SPaul Saab {
1477ecc44de7SPaul Saab struct cmsghdr *cm;
1478ecc44de7SPaul Saab void *data;
1479c7902fbeSMark Johnston socklen_t clen, datalen, datalen_out, oldclen;
1480ecc44de7SPaul Saab int error;
1481ecc44de7SPaul Saab caddr_t ctlbuf;
14821caaf555SMateusz Guzik int len, copylen;
1483ecc44de7SPaul Saab struct mbuf *m;
1484ecc44de7SPaul Saab error = 0;
1485ecc44de7SPaul Saab
1486ecc44de7SPaul Saab len = msg->msg_controllen;
1487ecc44de7SPaul Saab msg->msg_controllen = 0;
1488ecc44de7SPaul Saab
1489ecc44de7SPaul Saab ctlbuf = msg->msg_control;
1490c7902fbeSMark Johnston for (m = control; m != NULL && len > 0; m = m->m_next) {
1491ecc44de7SPaul Saab cm = mtod(m, struct cmsghdr *);
1492ecc44de7SPaul Saab clen = m->m_len;
1493ecc44de7SPaul Saab while (cm != NULL) {
1494ecc44de7SPaul Saab if (sizeof(struct cmsghdr) > clen ||
1495ecc44de7SPaul Saab cm->cmsg_len > clen) {
1496ecc44de7SPaul Saab error = EINVAL;
1497ecc44de7SPaul Saab break;
1498ecc44de7SPaul Saab }
1499ecc44de7SPaul Saab
1500ecc44de7SPaul Saab data = CMSG_DATA(cm);
1501ecc44de7SPaul Saab datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1502afbd12c1SMaxim Sobolev datalen_out = freebsd32_cmsg_convert(cm, data, datalen);
1503ecc44de7SPaul Saab
1504c7902fbeSMark Johnston /*
1505c7902fbeSMark Johnston * Copy out the message header. Preserve the native
1506c7902fbeSMark Johnston * message size in case we need to inspect the message
1507c7902fbeSMark Johnston * contents later.
1508c7902fbeSMark Johnston */
1509ecc44de7SPaul Saab copylen = sizeof(struct cmsghdr);
1510ecc44de7SPaul Saab if (len < copylen) {
1511ecc44de7SPaul Saab msg->msg_flags |= MSG_CTRUNC;
1512c7902fbeSMark Johnston m_dispose_extcontrolm(m);
1513c7902fbeSMark Johnston goto exit;
1514ecc44de7SPaul Saab }
1515c7902fbeSMark Johnston oldclen = cm->cmsg_len;
1516c7902fbeSMark Johnston cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
1517c7902fbeSMark Johnston datalen_out;
1518ecc44de7SPaul Saab error = copyout(cm, ctlbuf, copylen);
1519c7902fbeSMark Johnston cm->cmsg_len = oldclen;
1520c7902fbeSMark Johnston if (error != 0)
1521ecc44de7SPaul Saab goto exit;
1522ecc44de7SPaul Saab
1523ecc44de7SPaul Saab ctlbuf += FREEBSD32_ALIGN(copylen);
1524ecc44de7SPaul Saab len -= FREEBSD32_ALIGN(copylen);
1525ecc44de7SPaul Saab
1526afbd12c1SMaxim Sobolev copylen = datalen_out;
1527ecc44de7SPaul Saab if (len < copylen) {
1528ecc44de7SPaul Saab msg->msg_flags |= MSG_CTRUNC;
1529c7902fbeSMark Johnston m_dispose_extcontrolm(m);
1530c7902fbeSMark Johnston break;
1531ecc44de7SPaul Saab }
1532ecc44de7SPaul Saab
1533c7902fbeSMark Johnston /* Copy out the message data. */
1534ecc44de7SPaul Saab error = copyout(data, ctlbuf, copylen);
1535ecc44de7SPaul Saab if (error)
1536ecc44de7SPaul Saab goto exit;
1537ecc44de7SPaul Saab
1538ecc44de7SPaul Saab ctlbuf += FREEBSD32_ALIGN(copylen);
1539ecc44de7SPaul Saab len -= FREEBSD32_ALIGN(copylen);
1540ecc44de7SPaul Saab
1541ecc44de7SPaul Saab if (CMSG_SPACE(datalen) < clen) {
1542ecc44de7SPaul Saab clen -= CMSG_SPACE(datalen);
1543ecc44de7SPaul Saab cm = (struct cmsghdr *)
1544ecc44de7SPaul Saab ((caddr_t)cm + CMSG_SPACE(datalen));
1545ecc44de7SPaul Saab } else {
1546ecc44de7SPaul Saab clen = 0;
1547ecc44de7SPaul Saab cm = NULL;
1548ecc44de7SPaul Saab }
1549ecc44de7SPaul Saab
1550f0645b3aSJason A. Harmening msg->msg_controllen +=
1551f0645b3aSJason A. Harmening FREEBSD32_CMSG_SPACE(datalen_out);
1552c7902fbeSMark Johnston }
1553c7902fbeSMark Johnston }
1554c7902fbeSMark Johnston if (len == 0 && m != NULL) {
1555c7902fbeSMark Johnston msg->msg_flags |= MSG_CTRUNC;
1556c7902fbeSMark Johnston m_dispose_extcontrolm(m);
1557c7902fbeSMark Johnston }
1558ecc44de7SPaul Saab
1559ecc44de7SPaul Saab exit:
1560ecc44de7SPaul Saab return (error);
1561ecc44de7SPaul Saab }
1562ecc44de7SPaul Saab
1563a372f822SPaul Saab int
freebsd32_recvmsg(struct thread * td,struct freebsd32_recvmsg_args * uap)15644bda16ffSMark Johnston freebsd32_recvmsg(struct thread *td, struct freebsd32_recvmsg_args *uap)
1565a372f822SPaul Saab {
1566a372f822SPaul Saab struct msghdr msg;
1567a372f822SPaul Saab struct iovec *uiov, *iov;
1568ecc44de7SPaul Saab struct mbuf *control = NULL;
1569ecc44de7SPaul Saab struct mbuf **controlp;
1570ecc44de7SPaul Saab int error;
1571fea1a98eSMark Johnston
1572a372f822SPaul Saab error = freebsd32_copyinmsghdr(uap->msg, &msg);
1573a372f822SPaul Saab if (error)
1574a372f822SPaul Saab return (error);
1575fea1a98eSMark Johnston error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov,
1576acdd09f9SJohn Baldwin EMSGSIZE);
1577a372f822SPaul Saab if (error)
1578a372f822SPaul Saab return (error);
1579a372f822SPaul Saab msg.msg_flags = uap->flags;
1580a372f822SPaul Saab uiov = msg.msg_iov;
1581a372f822SPaul Saab msg.msg_iov = iov;
1582ecc44de7SPaul Saab
1583ecc44de7SPaul Saab controlp = (msg.msg_control != NULL) ? &control : NULL;
1584c870740eSJohn Baldwin error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1585a372f822SPaul Saab if (error == 0) {
1586a372f822SPaul Saab msg.msg_iov = uiov;
1587ecc44de7SPaul Saab
1588ecc44de7SPaul Saab if (control != NULL)
1589ecc44de7SPaul Saab error = freebsd32_copy_msg_out(&msg, control);
159034ab36a3SKonstantin Belousov else
159134ab36a3SKonstantin Belousov msg.msg_controllen = 0;
1592ecc44de7SPaul Saab
1593ecc44de7SPaul Saab if (error == 0)
1594a372f822SPaul Saab error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1595a372f822SPaul Saab }
1596a372f822SPaul Saab free(iov, M_IOV);
1597ecc44de7SPaul Saab
1598c7902fbeSMark Johnston if (control != NULL) {
1599c7902fbeSMark Johnston if (error != 0)
1600c7902fbeSMark Johnston m_dispose_extcontrolm(control);
1601ecc44de7SPaul Saab m_freem(control);
1602c7902fbeSMark Johnston }
1603ecc44de7SPaul Saab
1604a372f822SPaul Saab return (error);
1605a372f822SPaul Saab }
1606a372f822SPaul Saab
1607f089a2f3SBrooks Davis #ifdef COMPAT_43
1608f089a2f3SBrooks Davis int
ofreebsd32_recvmsg(struct thread * td,struct ofreebsd32_recvmsg_args * uap)1609f089a2f3SBrooks Davis ofreebsd32_recvmsg(struct thread *td, struct ofreebsd32_recvmsg_args *uap)
1610f089a2f3SBrooks Davis {
1611f089a2f3SBrooks Davis return (ENOSYS);
1612f089a2f3SBrooks Davis }
1613f089a2f3SBrooks Davis #endif
1614f089a2f3SBrooks Davis
16150fa211beSMarcel Moolenaar /*
16160fa211beSMarcel Moolenaar * Copy-in the array of control messages constructed using alignment
16170fa211beSMarcel Moolenaar * and padding suitable for a 32-bit environment and construct an
16180fa211beSMarcel Moolenaar * mbuf using alignment and padding suitable for a 64-bit kernel.
16190fa211beSMarcel Moolenaar * The alignment and padding are defined indirectly by CMSG_DATA(),
16200fa211beSMarcel Moolenaar * CMSG_SPACE() and CMSG_LEN().
16210fa211beSMarcel Moolenaar */
1622ecc44de7SPaul Saab static int
freebsd32_copyin_control(struct mbuf ** mp,caddr_t buf,u_int buflen)16230fa211beSMarcel Moolenaar freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
1624ecc44de7SPaul Saab {
16251b1428dcSMark Johnston struct cmsghdr *cm;
16260fa211beSMarcel Moolenaar struct mbuf *m;
16271b1428dcSMark Johnston void *in, *in1, *md;
16281b1428dcSMark Johnston u_int msglen, outlen;
1629ecc44de7SPaul Saab int error;
1630ecc44de7SPaul Saab
1631c46697b9SBrooks Davis /* Enforce the size limit of the native implementation. */
16320fa211beSMarcel Moolenaar if (buflen > MCLBYTES)
16330fa211beSMarcel Moolenaar return (EINVAL);
16340fa211beSMarcel Moolenaar
16351b1428dcSMark Johnston in = malloc(buflen, M_TEMP, M_WAITOK);
16361b1428dcSMark Johnston error = copyin(buf, in, buflen);
16371b1428dcSMark Johnston if (error != 0)
16381b1428dcSMark Johnston goto out;
16391b1428dcSMark Johnston
16400fa211beSMarcel Moolenaar /*
16411b1428dcSMark Johnston * Make a pass over the input buffer to determine the amount of space
16421b1428dcSMark Johnston * required for 64 bit-aligned copies of the control messages.
16430fa211beSMarcel Moolenaar */
16441b1428dcSMark Johnston in1 = in;
16451b1428dcSMark Johnston outlen = 0;
16460fa211beSMarcel Moolenaar while (buflen > 0) {
16471b1428dcSMark Johnston if (buflen < sizeof(*cm)) {
16481b1428dcSMark Johnston error = EINVAL;
1649ecc44de7SPaul Saab break;
16501b1428dcSMark Johnston }
16511b1428dcSMark Johnston cm = (struct cmsghdr *)in1;
16527b673a2cSJessica Clarke if (cm->cmsg_len < FREEBSD32_ALIGN(sizeof(*cm)) ||
16537b673a2cSJessica Clarke cm->cmsg_len > buflen) {
16541b1428dcSMark Johnston error = EINVAL;
16550fa211beSMarcel Moolenaar break;
16561b1428dcSMark Johnston }
16571b1428dcSMark Johnston msglen = FREEBSD32_ALIGN(cm->cmsg_len);
16587b673a2cSJessica Clarke if (msglen < cm->cmsg_len) {
16591b1428dcSMark Johnston error = EINVAL;
16601b1428dcSMark Johnston break;
16611b1428dcSMark Johnston }
16627b673a2cSJessica Clarke /* The native ABI permits the final padding to be omitted. */
16637b673a2cSJessica Clarke if (msglen > buflen)
16647b673a2cSJessica Clarke msglen = buflen;
16650fa211beSMarcel Moolenaar buflen -= msglen;
16661b1428dcSMark Johnston
16671b1428dcSMark Johnston in1 = (char *)in1 + msglen;
16681b1428dcSMark Johnston outlen += CMSG_ALIGN(sizeof(*cm)) +
16691b1428dcSMark Johnston CMSG_ALIGN(msglen - FREEBSD32_ALIGN(sizeof(*cm)));
1670ecc44de7SPaul Saab }
16711b1428dcSMark Johnston if (error != 0)
16721b1428dcSMark Johnston goto out;
16731b1428dcSMark Johnston
1674c46697b9SBrooks Davis /*
1675c46697b9SBrooks Davis * Allocate up to MJUMPAGESIZE space for the re-aligned and
1676c46697b9SBrooks Davis * re-padded control messages. This allows a full MCLBYTES of
1677c46697b9SBrooks Davis * 32-bit sized and aligned messages to fit and avoids an ABI
1678c46697b9SBrooks Davis * mismatch with the native implementation.
1679c46697b9SBrooks Davis */
16801b1428dcSMark Johnston m = m_get2(outlen, M_WAITOK, MT_CONTROL, 0);
1681c46697b9SBrooks Davis if (m == NULL) {
1682c46697b9SBrooks Davis error = EINVAL;
1683c46697b9SBrooks Davis goto out;
1684c46697b9SBrooks Davis }
16851b1428dcSMark Johnston m->m_len = outlen;
16861b1428dcSMark Johnston md = mtod(m, void *);
16871b1428dcSMark Johnston
16881b1428dcSMark Johnston /*
16891b1428dcSMark Johnston * Make a second pass over input messages, copying them into the output
16901b1428dcSMark Johnston * buffer.
16911b1428dcSMark Johnston */
16921b1428dcSMark Johnston in1 = in;
16931b1428dcSMark Johnston while (outlen > 0) {
16941b1428dcSMark Johnston /* Copy the message header and align the length field. */
16951b1428dcSMark Johnston cm = md;
16961b1428dcSMark Johnston memcpy(cm, in1, sizeof(*cm));
16971b1428dcSMark Johnston msglen = cm->cmsg_len - FREEBSD32_ALIGN(sizeof(*cm));
16981b1428dcSMark Johnston cm->cmsg_len = CMSG_ALIGN(sizeof(*cm)) + msglen;
16991b1428dcSMark Johnston
17001b1428dcSMark Johnston /* Copy the message body. */
17011b1428dcSMark Johnston in1 = (char *)in1 + FREEBSD32_ALIGN(sizeof(*cm));
17021b1428dcSMark Johnston md = (char *)md + CMSG_ALIGN(sizeof(*cm));
17031b1428dcSMark Johnston memcpy(md, in1, msglen);
17041b1428dcSMark Johnston in1 = (char *)in1 + FREEBSD32_ALIGN(msglen);
17051b1428dcSMark Johnston md = (char *)md + CMSG_ALIGN(msglen);
17061b1428dcSMark Johnston KASSERT(outlen >= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen),
17071b1428dcSMark Johnston ("outlen %u underflow, msglen %u", outlen, msglen));
17081b1428dcSMark Johnston outlen -= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen);
1709ecc44de7SPaul Saab }
1710ecc44de7SPaul Saab
17110fa211beSMarcel Moolenaar *mp = m;
17121b1428dcSMark Johnston out:
17131b1428dcSMark Johnston free(in, M_TEMP);
1714ecc44de7SPaul Saab return (error);
1715ecc44de7SPaul Saab }
1716ecc44de7SPaul Saab
1717a372f822SPaul Saab int
freebsd32_sendmsg(struct thread * td,struct freebsd32_sendmsg_args * uap)17184bda16ffSMark Johnston freebsd32_sendmsg(struct thread *td, struct freebsd32_sendmsg_args *uap)
1719a372f822SPaul Saab {
1720a372f822SPaul Saab struct msghdr msg;
1721a372f822SPaul Saab struct iovec *iov;
1722ecc44de7SPaul Saab struct mbuf *control = NULL;
1723ecc44de7SPaul Saab struct sockaddr *to = NULL;
1724a372f822SPaul Saab int error;
1725a372f822SPaul Saab
1726a372f822SPaul Saab error = freebsd32_copyinmsghdr(uap->msg, &msg);
1727a372f822SPaul Saab if (error)
1728a372f822SPaul Saab return (error);
1729fea1a98eSMark Johnston error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov,
1730acdd09f9SJohn Baldwin EMSGSIZE);
1731a372f822SPaul Saab if (error)
1732a372f822SPaul Saab return (error);
1733a372f822SPaul Saab msg.msg_iov = iov;
1734ecc44de7SPaul Saab if (msg.msg_name != NULL) {
1735ecc44de7SPaul Saab error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1736ecc44de7SPaul Saab if (error) {
1737ecc44de7SPaul Saab to = NULL;
1738ecc44de7SPaul Saab goto out;
1739ecc44de7SPaul Saab }
1740ecc44de7SPaul Saab msg.msg_name = to;
1741ecc44de7SPaul Saab }
1742ecc44de7SPaul Saab
1743ecc44de7SPaul Saab if (msg.msg_control) {
1744ecc44de7SPaul Saab if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1745ecc44de7SPaul Saab error = EINVAL;
1746ecc44de7SPaul Saab goto out;
1747ecc44de7SPaul Saab }
1748ecc44de7SPaul Saab
17490fa211beSMarcel Moolenaar error = freebsd32_copyin_control(&control, msg.msg_control,
17500fa211beSMarcel Moolenaar msg.msg_controllen);
1751ecc44de7SPaul Saab if (error)
1752ecc44de7SPaul Saab goto out;
1753ecc44de7SPaul Saab
17540fa211beSMarcel Moolenaar msg.msg_control = NULL;
17550fa211beSMarcel Moolenaar msg.msg_controllen = 0;
1756ecc44de7SPaul Saab }
1757ecc44de7SPaul Saab
1758ecc44de7SPaul Saab error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1759ecc44de7SPaul Saab UIO_USERSPACE);
1760ecc44de7SPaul Saab
1761ecc44de7SPaul Saab out:
1762a372f822SPaul Saab free(iov, M_IOV);
1763ecc44de7SPaul Saab if (to)
1764ecc44de7SPaul Saab free(to, M_SONAME);
1765a372f822SPaul Saab return (error);
1766a372f822SPaul Saab }
1767a372f822SPaul Saab
1768f089a2f3SBrooks Davis #ifdef COMPAT_43
1769f089a2f3SBrooks Davis int
ofreebsd32_sendmsg(struct thread * td,struct ofreebsd32_sendmsg_args * uap)1770f089a2f3SBrooks Davis ofreebsd32_sendmsg(struct thread *td, struct ofreebsd32_sendmsg_args *uap)
1771f089a2f3SBrooks Davis {
1772f089a2f3SBrooks Davis return (ENOSYS);
1773f089a2f3SBrooks Davis }
1774f089a2f3SBrooks Davis #endif
1775f089a2f3SBrooks Davis
1776f089a2f3SBrooks Davis
1777a372f822SPaul Saab int
freebsd32_settimeofday(struct thread * td,struct freebsd32_settimeofday_args * uap)17781c7abef7SPeter Wemm freebsd32_settimeofday(struct thread *td,
17791c7abef7SPeter Wemm struct freebsd32_settimeofday_args *uap)
17803ebc1248SPeter Wemm {
178148052f99SJohn Baldwin struct timeval32 tv32;
178248052f99SJohn Baldwin struct timeval tv, *tvp;
178348052f99SJohn Baldwin struct timezone tz, *tzp;
17843ebc1248SPeter Wemm int error;
17853ebc1248SPeter Wemm
178648052f99SJohn Baldwin if (uap->tv) {
178748052f99SJohn Baldwin error = copyin(uap->tv, &tv32, sizeof(tv32));
17883ebc1248SPeter Wemm if (error)
17893ebc1248SPeter Wemm return (error);
179048052f99SJohn Baldwin CP(tv32, tv, tv_sec);
179148052f99SJohn Baldwin CP(tv32, tv, tv_usec);
179248052f99SJohn Baldwin tvp = &tv;
179348052f99SJohn Baldwin } else
179448052f99SJohn Baldwin tvp = NULL;
179548052f99SJohn Baldwin if (uap->tzp) {
179648052f99SJohn Baldwin error = copyin(uap->tzp, &tz, sizeof(tz));
17973ebc1248SPeter Wemm if (error)
17983ebc1248SPeter Wemm return (error);
179948052f99SJohn Baldwin tzp = &tz;
180048052f99SJohn Baldwin } else
180148052f99SJohn Baldwin tzp = NULL;
180248052f99SJohn Baldwin return (kern_settimeofday(td, tvp, tzp));
18033ebc1248SPeter Wemm }
18043ebc1248SPeter Wemm
18053ebc1248SPeter Wemm int
freebsd32_utimes(struct thread * td,struct freebsd32_utimes_args * uap)18061c7abef7SPeter Wemm freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
18073ebc1248SPeter Wemm {
180838765a31SJohn Baldwin struct timeval32 s32[2];
180938765a31SJohn Baldwin struct timeval s[2], *sp;
18103ebc1248SPeter Wemm int error;
18113ebc1248SPeter Wemm
181238765a31SJohn Baldwin if (uap->tptr != NULL) {
181338765a31SJohn Baldwin error = copyin(uap->tptr, s32, sizeof(s32));
18143ebc1248SPeter Wemm if (error)
18153ebc1248SPeter Wemm return (error);
18163ebc1248SPeter Wemm CP(s32[0], s[0], tv_sec);
18173ebc1248SPeter Wemm CP(s32[0], s[0], tv_usec);
18183ebc1248SPeter Wemm CP(s32[1], s[1], tv_sec);
18193ebc1248SPeter Wemm CP(s32[1], s[1], tv_usec);
182038765a31SJohn Baldwin sp = s;
182138765a31SJohn Baldwin } else
182238765a31SJohn Baldwin sp = NULL;
18236e646651SKonstantin Belousov return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
18246e646651SKonstantin Belousov sp, UIO_SYSSPACE));
18253ebc1248SPeter Wemm }
18263ebc1248SPeter Wemm
18273ebc1248SPeter Wemm int
freebsd32_lutimes(struct thread * td,struct freebsd32_lutimes_args * uap)182808a3081dSDoug Ambrisko freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
182908a3081dSDoug Ambrisko {
183008a3081dSDoug Ambrisko struct timeval32 s32[2];
183108a3081dSDoug Ambrisko struct timeval s[2], *sp;
183208a3081dSDoug Ambrisko int error;
183308a3081dSDoug Ambrisko
183408a3081dSDoug Ambrisko if (uap->tptr != NULL) {
183508a3081dSDoug Ambrisko error = copyin(uap->tptr, s32, sizeof(s32));
183608a3081dSDoug Ambrisko if (error)
183708a3081dSDoug Ambrisko return (error);
183808a3081dSDoug Ambrisko CP(s32[0], s[0], tv_sec);
183908a3081dSDoug Ambrisko CP(s32[0], s[0], tv_usec);
184008a3081dSDoug Ambrisko CP(s32[1], s[1], tv_sec);
184108a3081dSDoug Ambrisko CP(s32[1], s[1], tv_usec);
184208a3081dSDoug Ambrisko sp = s;
184308a3081dSDoug Ambrisko } else
184408a3081dSDoug Ambrisko sp = NULL;
184508a3081dSDoug Ambrisko return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
184608a3081dSDoug Ambrisko }
184708a3081dSDoug Ambrisko
184808a3081dSDoug Ambrisko int
freebsd32_futimes(struct thread * td,struct freebsd32_futimes_args * uap)18498e7604dbSDoug Ambrisko freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
18508e7604dbSDoug Ambrisko {
18518e7604dbSDoug Ambrisko struct timeval32 s32[2];
18528e7604dbSDoug Ambrisko struct timeval s[2], *sp;
18538e7604dbSDoug Ambrisko int error;
18548e7604dbSDoug Ambrisko
18558e7604dbSDoug Ambrisko if (uap->tptr != NULL) {
18568e7604dbSDoug Ambrisko error = copyin(uap->tptr, s32, sizeof(s32));
18578e7604dbSDoug Ambrisko if (error)
18588e7604dbSDoug Ambrisko return (error);
18598e7604dbSDoug Ambrisko CP(s32[0], s[0], tv_sec);
18608e7604dbSDoug Ambrisko CP(s32[0], s[0], tv_usec);
18618e7604dbSDoug Ambrisko CP(s32[1], s[1], tv_sec);
18628e7604dbSDoug Ambrisko CP(s32[1], s[1], tv_usec);
18638e7604dbSDoug Ambrisko sp = s;
18648e7604dbSDoug Ambrisko } else
18658e7604dbSDoug Ambrisko sp = NULL;
18668e7604dbSDoug Ambrisko return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
18678e7604dbSDoug Ambrisko }
18688e7604dbSDoug Ambrisko
18694f1e7213SKonstantin Belousov int
freebsd32_futimesat(struct thread * td,struct freebsd32_futimesat_args * uap)18704f1e7213SKonstantin Belousov freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
18714f1e7213SKonstantin Belousov {
18724f1e7213SKonstantin Belousov struct timeval32 s32[2];
18734f1e7213SKonstantin Belousov struct timeval s[2], *sp;
18744f1e7213SKonstantin Belousov int error;
18754f1e7213SKonstantin Belousov
18764f1e7213SKonstantin Belousov if (uap->times != NULL) {
18774f1e7213SKonstantin Belousov error = copyin(uap->times, s32, sizeof(s32));
18784f1e7213SKonstantin Belousov if (error)
18794f1e7213SKonstantin Belousov return (error);
18804f1e7213SKonstantin Belousov CP(s32[0], s[0], tv_sec);
18814f1e7213SKonstantin Belousov CP(s32[0], s[0], tv_usec);
18824f1e7213SKonstantin Belousov CP(s32[1], s[1], tv_sec);
18834f1e7213SKonstantin Belousov CP(s32[1], s[1], tv_usec);
18844f1e7213SKonstantin Belousov sp = s;
18854f1e7213SKonstantin Belousov } else
18864f1e7213SKonstantin Belousov sp = NULL;
18874f1e7213SKonstantin Belousov return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
18884f1e7213SKonstantin Belousov sp, UIO_SYSSPACE));
18894f1e7213SKonstantin Belousov }
18908e7604dbSDoug Ambrisko
18918e7604dbSDoug Ambrisko int
freebsd32_futimens(struct thread * td,struct freebsd32_futimens_args * uap)18922205e0d1SJilles Tjoelker freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap)
18932205e0d1SJilles Tjoelker {
18942205e0d1SJilles Tjoelker struct timespec32 ts32[2];
18952205e0d1SJilles Tjoelker struct timespec ts[2], *tsp;
18962205e0d1SJilles Tjoelker int error;
18972205e0d1SJilles Tjoelker
18982205e0d1SJilles Tjoelker if (uap->times != NULL) {
18992205e0d1SJilles Tjoelker error = copyin(uap->times, ts32, sizeof(ts32));
19002205e0d1SJilles Tjoelker if (error)
19012205e0d1SJilles Tjoelker return (error);
19022205e0d1SJilles Tjoelker CP(ts32[0], ts[0], tv_sec);
19032205e0d1SJilles Tjoelker CP(ts32[0], ts[0], tv_nsec);
19042205e0d1SJilles Tjoelker CP(ts32[1], ts[1], tv_sec);
19052205e0d1SJilles Tjoelker CP(ts32[1], ts[1], tv_nsec);
19062205e0d1SJilles Tjoelker tsp = ts;
19072205e0d1SJilles Tjoelker } else
19082205e0d1SJilles Tjoelker tsp = NULL;
19092205e0d1SJilles Tjoelker return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE));
19102205e0d1SJilles Tjoelker }
19112205e0d1SJilles Tjoelker
19122205e0d1SJilles Tjoelker int
freebsd32_utimensat(struct thread * td,struct freebsd32_utimensat_args * uap)19132205e0d1SJilles Tjoelker freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap)
19142205e0d1SJilles Tjoelker {
19152205e0d1SJilles Tjoelker struct timespec32 ts32[2];
19162205e0d1SJilles Tjoelker struct timespec ts[2], *tsp;
19172205e0d1SJilles Tjoelker int error;
19182205e0d1SJilles Tjoelker
19192205e0d1SJilles Tjoelker if (uap->times != NULL) {
19202205e0d1SJilles Tjoelker error = copyin(uap->times, ts32, sizeof(ts32));
19212205e0d1SJilles Tjoelker if (error)
19222205e0d1SJilles Tjoelker return (error);
19232205e0d1SJilles Tjoelker CP(ts32[0], ts[0], tv_sec);
19242205e0d1SJilles Tjoelker CP(ts32[0], ts[0], tv_nsec);
19252205e0d1SJilles Tjoelker CP(ts32[1], ts[1], tv_sec);
19262205e0d1SJilles Tjoelker CP(ts32[1], ts[1], tv_nsec);
19272205e0d1SJilles Tjoelker tsp = ts;
19282205e0d1SJilles Tjoelker } else
19292205e0d1SJilles Tjoelker tsp = NULL;
19302205e0d1SJilles Tjoelker return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE,
19312205e0d1SJilles Tjoelker tsp, UIO_SYSSPACE, uap->flag));
19322205e0d1SJilles Tjoelker }
19332205e0d1SJilles Tjoelker
19342205e0d1SJilles Tjoelker int
freebsd32_adjtime(struct thread * td,struct freebsd32_adjtime_args * uap)19351c7abef7SPeter Wemm freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
19363ebc1248SPeter Wemm {
193748052f99SJohn Baldwin struct timeval32 tv32;
193848052f99SJohn Baldwin struct timeval delta, olddelta, *deltap;
19393ebc1248SPeter Wemm int error;
19403ebc1248SPeter Wemm
194148052f99SJohn Baldwin if (uap->delta) {
194248052f99SJohn Baldwin error = copyin(uap->delta, &tv32, sizeof(tv32));
19433ebc1248SPeter Wemm if (error)
19443ebc1248SPeter Wemm return (error);
194548052f99SJohn Baldwin CP(tv32, delta, tv_sec);
194648052f99SJohn Baldwin CP(tv32, delta, tv_usec);
194748052f99SJohn Baldwin deltap = δ
194848052f99SJohn Baldwin } else
194948052f99SJohn Baldwin deltap = NULL;
195048052f99SJohn Baldwin error = kern_adjtime(td, deltap, &olddelta);
195148052f99SJohn Baldwin if (uap->olddelta && error == 0) {
195248052f99SJohn Baldwin CP(olddelta, tv32, tv_sec);
195348052f99SJohn Baldwin CP(olddelta, tv32, tv_usec);
195448052f99SJohn Baldwin error = copyout(&tv32, uap->olddelta, sizeof(tv32));
19553ebc1248SPeter Wemm }
19563ebc1248SPeter Wemm return (error);
19573ebc1248SPeter Wemm }
19583ebc1248SPeter Wemm
1959c050455eSMarcel Moolenaar #ifdef COMPAT_FREEBSD4
19603ebc1248SPeter Wemm int
freebsd4_freebsd32_statfs(struct thread * td,struct freebsd4_freebsd32_statfs_args * uap)19610c70bcedSPeter Wemm freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
19623ebc1248SPeter Wemm {
19632e89f95dSBrooks Davis struct ostatfs32 s32;
19642f304845SKonstantin Belousov struct statfs *sp;
19653ebc1248SPeter Wemm int error;
19663ebc1248SPeter Wemm
19672f304845SKonstantin Belousov sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
19682f304845SKonstantin Belousov error = kern_statfs(td, uap->path, UIO_USERSPACE, sp);
19692f304845SKonstantin Belousov if (error == 0) {
19702f304845SKonstantin Belousov copy_statfs(sp, &s32);
19712f304845SKonstantin Belousov error = copyout(&s32, uap->buf, sizeof(s32));
19722f304845SKonstantin Belousov }
19732f304845SKonstantin Belousov free(sp, M_STATFS);
19743ebc1248SPeter Wemm return (error);
19753ebc1248SPeter Wemm }
1976c050455eSMarcel Moolenaar #endif
19773ebc1248SPeter Wemm
1978c050455eSMarcel Moolenaar #ifdef COMPAT_FREEBSD4
19793ebc1248SPeter Wemm int
freebsd4_freebsd32_fstatfs(struct thread * td,struct freebsd4_freebsd32_fstatfs_args * uap)19800c70bcedSPeter Wemm freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
19813ebc1248SPeter Wemm {
19822e89f95dSBrooks Davis struct ostatfs32 s32;
19832f304845SKonstantin Belousov struct statfs *sp;
19843ebc1248SPeter Wemm int error;
19853ebc1248SPeter Wemm
19862f304845SKonstantin Belousov sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
19872f304845SKonstantin Belousov error = kern_fstatfs(td, uap->fd, sp);
19882f304845SKonstantin Belousov if (error == 0) {
19892f304845SKonstantin Belousov copy_statfs(sp, &s32);
19902f304845SKonstantin Belousov error = copyout(&s32, uap->buf, sizeof(s32));
19912f304845SKonstantin Belousov }
19922f304845SKonstantin Belousov free(sp, M_STATFS);
19933ebc1248SPeter Wemm return (error);
19943ebc1248SPeter Wemm }
1995c050455eSMarcel Moolenaar #endif
19963ebc1248SPeter Wemm
1997c050455eSMarcel Moolenaar #ifdef COMPAT_FREEBSD4
19983ebc1248SPeter Wemm int
freebsd4_freebsd32_fhstatfs(struct thread * td,struct freebsd4_freebsd32_fhstatfs_args * uap)19990c70bcedSPeter Wemm freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
20000c70bcedSPeter Wemm {
20012e89f95dSBrooks Davis struct ostatfs32 s32;
20022f304845SKonstantin Belousov struct statfs *sp;
200338765a31SJohn Baldwin fhandle_t fh;
20040c70bcedSPeter Wemm int error;
20050c70bcedSPeter Wemm
200638765a31SJohn Baldwin if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
20070c70bcedSPeter Wemm return (error);
20082f304845SKonstantin Belousov sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
20092f304845SKonstantin Belousov error = kern_fhstatfs(td, fh, sp);
20102f304845SKonstantin Belousov if (error == 0) {
20112f304845SKonstantin Belousov copy_statfs(sp, &s32);
20122f304845SKonstantin Belousov error = copyout(&s32, uap->buf, sizeof(s32));
20132f304845SKonstantin Belousov }
20142f304845SKonstantin Belousov free(sp, M_STATFS);
20150c70bcedSPeter Wemm return (error);
20160c70bcedSPeter Wemm }
2017c050455eSMarcel Moolenaar #endif
20180c70bcedSPeter Wemm
20190c70bcedSPeter Wemm int
freebsd32_pread(struct thread * td,struct freebsd32_pread_args * uap)20201c7abef7SPeter Wemm freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
20213ebc1248SPeter Wemm {
20223ebc1248SPeter Wemm
2023b38b22b0SEdward Tomasz Napierala return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
2024b38b22b0SEdward Tomasz Napierala PAIR32TO64(off_t, uap->offset)));
20253ebc1248SPeter Wemm }
20263ebc1248SPeter Wemm
20273ebc1248SPeter Wemm int
freebsd32_pwrite(struct thread * td,struct freebsd32_pwrite_args * uap)20281c7abef7SPeter Wemm freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
20293ebc1248SPeter Wemm {
20303ebc1248SPeter Wemm
2031b38b22b0SEdward Tomasz Napierala return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
2032b38b22b0SEdward Tomasz Napierala PAIR32TO64(off_t, uap->offset)));
20333ebc1248SPeter Wemm }
20343ebc1248SPeter Wemm
203571812178SKonstantin Belousov #ifdef COMPAT_43
203671812178SKonstantin Belousov int
ofreebsd32_lseek(struct thread * td,struct ofreebsd32_lseek_args * uap)203771812178SKonstantin Belousov ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
203871812178SKonstantin Belousov {
203971812178SKonstantin Belousov
2040f67d6b5fSEdward Tomasz Napierala return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
204171812178SKonstantin Belousov }
204271812178SKonstantin Belousov #endif
204371812178SKonstantin Belousov
20443ebc1248SPeter Wemm int
freebsd32_lseek(struct thread * td,struct freebsd32_lseek_args * uap)20451c7abef7SPeter Wemm freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
20463ebc1248SPeter Wemm {
20473ebc1248SPeter Wemm int error;
20483ebc1248SPeter Wemm off_t pos;
20493ebc1248SPeter Wemm
2050f67d6b5fSEdward Tomasz Napierala error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2051f67d6b5fSEdward Tomasz Napierala uap->whence);
20523ebc1248SPeter Wemm /* Expand the quad return into two parts for eax and edx */
20536f2b769cSJohn-Mark Gurney pos = td->td_uretoff.tdu_off;
2054841c0c7eSNathan Whitehorn td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
2055841c0c7eSNathan Whitehorn td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
20563ebc1248SPeter Wemm return error;
20573ebc1248SPeter Wemm }
20583ebc1248SPeter Wemm
20593ebc1248SPeter Wemm int
freebsd32_truncate(struct thread * td,struct freebsd32_truncate_args * uap)20601c7abef7SPeter Wemm freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
20613ebc1248SPeter Wemm {
20623ebc1248SPeter Wemm
2063fc8bde8fSEdward Tomasz Napierala return (kern_truncate(td, uap->path, UIO_USERSPACE,
2064fc8bde8fSEdward Tomasz Napierala PAIR32TO64(off_t, uap->length)));
20653ebc1248SPeter Wemm }
20663ebc1248SPeter Wemm
2067f19e3fd2SBrooks Davis #ifdef COMPAT_43
2068f19e3fd2SBrooks Davis int
ofreebsd32_truncate(struct thread * td,struct ofreebsd32_truncate_args * uap)2069f19e3fd2SBrooks Davis ofreebsd32_truncate(struct thread *td, struct ofreebsd32_truncate_args *uap)
2070f19e3fd2SBrooks Davis {
2071f19e3fd2SBrooks Davis return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
2072f19e3fd2SBrooks Davis }
2073f19e3fd2SBrooks Davis #endif
2074f19e3fd2SBrooks Davis
20753ebc1248SPeter Wemm int
freebsd32_ftruncate(struct thread * td,struct freebsd32_ftruncate_args * uap)20761c7abef7SPeter Wemm freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
20773ebc1248SPeter Wemm {
20783ebc1248SPeter Wemm
2079ae6b6ef6SEdward Tomasz Napierala return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
20803ebc1248SPeter Wemm }
20813ebc1248SPeter Wemm
20827332c129SKonstantin Belousov #ifdef COMPAT_43
20837332c129SKonstantin Belousov int
ofreebsd32_ftruncate(struct thread * td,struct ofreebsd32_ftruncate_args * uap)2084f19e3fd2SBrooks Davis ofreebsd32_ftruncate(struct thread *td, struct ofreebsd32_ftruncate_args *uap)
2085f19e3fd2SBrooks Davis {
2086f19e3fd2SBrooks Davis return (kern_ftruncate(td, uap->fd, uap->length));
2087f19e3fd2SBrooks Davis }
2088f19e3fd2SBrooks Davis
2089f19e3fd2SBrooks Davis int
ofreebsd32_getdirentries(struct thread * td,struct ofreebsd32_getdirentries_args * uap)20907332c129SKonstantin Belousov ofreebsd32_getdirentries(struct thread *td,
20917332c129SKonstantin Belousov struct ofreebsd32_getdirentries_args *uap)
20927332c129SKonstantin Belousov {
20937332c129SKonstantin Belousov struct ogetdirentries_args ap;
20947332c129SKonstantin Belousov int error;
20957332c129SKonstantin Belousov long loff;
20967332c129SKonstantin Belousov int32_t loff_cut;
20977332c129SKonstantin Belousov
20987332c129SKonstantin Belousov ap.fd = uap->fd;
20997332c129SKonstantin Belousov ap.buf = uap->buf;
21007332c129SKonstantin Belousov ap.count = uap->count;
21017332c129SKonstantin Belousov ap.basep = NULL;
21027332c129SKonstantin Belousov error = kern_ogetdirentries(td, &ap, &loff);
21037332c129SKonstantin Belousov if (error == 0) {
21047332c129SKonstantin Belousov loff_cut = loff;
21057332c129SKonstantin Belousov error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
21067332c129SKonstantin Belousov }
21077332c129SKonstantin Belousov return (error);
21087332c129SKonstantin Belousov }
21097332c129SKonstantin Belousov #endif
21107332c129SKonstantin Belousov
211169921123SKonstantin Belousov #if defined(COMPAT_FREEBSD11)
211269921123SKonstantin Belousov int
freebsd11_freebsd32_getdirentries(struct thread * td,struct freebsd11_freebsd32_getdirentries_args * uap)211369921123SKonstantin Belousov freebsd11_freebsd32_getdirentries(struct thread *td,
211469921123SKonstantin Belousov struct freebsd11_freebsd32_getdirentries_args *uap)
211569921123SKonstantin Belousov {
211669921123SKonstantin Belousov long base;
211769921123SKonstantin Belousov int32_t base32;
211869921123SKonstantin Belousov int error;
211969921123SKonstantin Belousov
212069921123SKonstantin Belousov error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
212169921123SKonstantin Belousov &base, NULL);
212269921123SKonstantin Belousov if (error)
212369921123SKonstantin Belousov return (error);
212469921123SKonstantin Belousov if (uap->basep != NULL) {
212569921123SKonstantin Belousov base32 = base;
212669921123SKonstantin Belousov error = copyout(&base32, uap->basep, sizeof(int32_t));
212769921123SKonstantin Belousov }
212869921123SKonstantin Belousov return (error);
212969921123SKonstantin Belousov }
213069921123SKonstantin Belousov #endif /* COMPAT_FREEBSD11 */
213169921123SKonstantin Belousov
21325aa69f9cSPeter Wemm #ifdef COMPAT_FREEBSD6
21335aa69f9cSPeter Wemm /* versions with the 'int pad' argument */
21345aa69f9cSPeter Wemm int
freebsd6_freebsd32_pread(struct thread * td,struct freebsd6_freebsd32_pread_args * uap)21355aa69f9cSPeter Wemm freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
21365aa69f9cSPeter Wemm {
21375aa69f9cSPeter Wemm
2138b38b22b0SEdward Tomasz Napierala return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
2139b38b22b0SEdward Tomasz Napierala PAIR32TO64(off_t, uap->offset)));
21405aa69f9cSPeter Wemm }
21415aa69f9cSPeter Wemm
21425aa69f9cSPeter Wemm int
freebsd6_freebsd32_pwrite(struct thread * td,struct freebsd6_freebsd32_pwrite_args * uap)21435aa69f9cSPeter Wemm freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
21445aa69f9cSPeter Wemm {
21455aa69f9cSPeter Wemm
2146b38b22b0SEdward Tomasz Napierala return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
2147b38b22b0SEdward Tomasz Napierala PAIR32TO64(off_t, uap->offset)));
21485aa69f9cSPeter Wemm }
21495aa69f9cSPeter Wemm
21505aa69f9cSPeter Wemm int
freebsd6_freebsd32_lseek(struct thread * td,struct freebsd6_freebsd32_lseek_args * uap)21515aa69f9cSPeter Wemm freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
21525aa69f9cSPeter Wemm {
21535aa69f9cSPeter Wemm int error;
21545aa69f9cSPeter Wemm off_t pos;
21555aa69f9cSPeter Wemm
2156f67d6b5fSEdward Tomasz Napierala error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2157f67d6b5fSEdward Tomasz Napierala uap->whence);
21585aa69f9cSPeter Wemm /* Expand the quad return into two parts for eax and edx */
21595aa69f9cSPeter Wemm pos = *(off_t *)(td->td_retval);
2160841c0c7eSNathan Whitehorn td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
2161841c0c7eSNathan Whitehorn td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
21625aa69f9cSPeter Wemm return error;
21635aa69f9cSPeter Wemm }
21645aa69f9cSPeter Wemm
21655aa69f9cSPeter Wemm int
freebsd6_freebsd32_truncate(struct thread * td,struct freebsd6_freebsd32_truncate_args * uap)21665aa69f9cSPeter Wemm freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
21675aa69f9cSPeter Wemm {
21685aa69f9cSPeter Wemm
2169fc8bde8fSEdward Tomasz Napierala return (kern_truncate(td, uap->path, UIO_USERSPACE,
2170fc8bde8fSEdward Tomasz Napierala PAIR32TO64(off_t, uap->length)));
21715aa69f9cSPeter Wemm }
21725aa69f9cSPeter Wemm
21735aa69f9cSPeter Wemm int
freebsd6_freebsd32_ftruncate(struct thread * td,struct freebsd6_freebsd32_ftruncate_args * uap)21745aa69f9cSPeter Wemm freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
21755aa69f9cSPeter Wemm {
21765aa69f9cSPeter Wemm
2177ae6b6ef6SEdward Tomasz Napierala return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
21785aa69f9cSPeter Wemm }
21795aa69f9cSPeter Wemm #endif /* COMPAT_FREEBSD6 */
21805aa69f9cSPeter Wemm
2181fa545f43SPaul Saab struct sf_hdtr32 {
2182fa545f43SPaul Saab uint32_t headers;
2183fa545f43SPaul Saab int hdr_cnt;
2184fa545f43SPaul Saab uint32_t trailers;
2185fa545f43SPaul Saab int trl_cnt;
2186fa545f43SPaul Saab };
2187fa545f43SPaul Saab
2188fa545f43SPaul Saab static int
freebsd32_do_sendfile(struct thread * td,struct freebsd32_sendfile_args * uap,int compat)2189fa545f43SPaul Saab freebsd32_do_sendfile(struct thread *td,
2190fa545f43SPaul Saab struct freebsd32_sendfile_args *uap, int compat)
2191fa545f43SPaul Saab {
2192fa545f43SPaul Saab struct sf_hdtr32 hdtr32;
2193fa545f43SPaul Saab struct sf_hdtr hdtr;
2194fa545f43SPaul Saab struct uio *hdr_uio, *trl_uio;
2195efe28398SGleb Smirnoff struct file *fp;
2196efe28398SGleb Smirnoff cap_rights_t rights;
2197fa545f43SPaul Saab struct iovec32 *iov32;
21980e87b36eSGleb Smirnoff off_t offset, sbytes;
2199fa545f43SPaul Saab int error;
2200fa545f43SPaul Saab
2201ca04d21dSGleb Smirnoff offset = PAIR32TO64(off_t, uap->offset);
2202ca04d21dSGleb Smirnoff if (offset < 0)
2203ca04d21dSGleb Smirnoff return (EINVAL);
2204fa545f43SPaul Saab
2205ca04d21dSGleb Smirnoff hdr_uio = trl_uio = NULL;
2206fa545f43SPaul Saab
2207fa545f43SPaul Saab if (uap->hdtr != NULL) {
2208fa545f43SPaul Saab error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
2209fa545f43SPaul Saab if (error)
2210fa545f43SPaul Saab goto out;
2211fa545f43SPaul Saab PTRIN_CP(hdtr32, hdtr, headers);
2212fa545f43SPaul Saab CP(hdtr32, hdtr, hdr_cnt);
2213fa545f43SPaul Saab PTRIN_CP(hdtr32, hdtr, trailers);
2214fa545f43SPaul Saab CP(hdtr32, hdtr, trl_cnt);
2215fa545f43SPaul Saab
2216fa545f43SPaul Saab if (hdtr.headers != NULL) {
2217acdd09f9SJohn Baldwin iov32 = PTRIN(hdtr32.headers);
2218fa545f43SPaul Saab error = freebsd32_copyinuio(iov32,
2219fa545f43SPaul Saab hdtr32.hdr_cnt, &hdr_uio);
2220fa545f43SPaul Saab if (error)
2221fa545f43SPaul Saab goto out;
22229c64cfe5SGleb Smirnoff #ifdef COMPAT_FREEBSD4
22239c64cfe5SGleb Smirnoff /*
22249c64cfe5SGleb Smirnoff * In FreeBSD < 5.0 the nbytes to send also included
22259c64cfe5SGleb Smirnoff * the header. If compat is specified subtract the
22269c64cfe5SGleb Smirnoff * header size from nbytes.
22279c64cfe5SGleb Smirnoff */
22289c64cfe5SGleb Smirnoff if (compat) {
22299c64cfe5SGleb Smirnoff if (uap->nbytes > hdr_uio->uio_resid)
22309c64cfe5SGleb Smirnoff uap->nbytes -= hdr_uio->uio_resid;
22319c64cfe5SGleb Smirnoff else
22329c64cfe5SGleb Smirnoff uap->nbytes = 0;
22339c64cfe5SGleb Smirnoff }
22349c64cfe5SGleb Smirnoff #endif
2235fa545f43SPaul Saab }
2236fa545f43SPaul Saab if (hdtr.trailers != NULL) {
2237acdd09f9SJohn Baldwin iov32 = PTRIN(hdtr32.trailers);
2238fa545f43SPaul Saab error = freebsd32_copyinuio(iov32,
2239fa545f43SPaul Saab hdtr32.trl_cnt, &trl_uio);
2240fa545f43SPaul Saab if (error)
2241fa545f43SPaul Saab goto out;
2242fa545f43SPaul Saab }
22430e87b36eSGleb Smirnoff }
22440cfea1c8SAdrian Chadd
22450e87b36eSGleb Smirnoff AUDIT_ARG_FD(uap->fd);
22460e87b36eSGleb Smirnoff
22470e87b36eSGleb Smirnoff if ((error = fget_read(td, uap->fd,
22486b3a9a0fSMateusz Guzik cap_rights_init_one(&rights, CAP_PREAD), &fp)) != 0)
22490cfea1c8SAdrian Chadd goto out;
22500cfea1c8SAdrian Chadd
22510e87b36eSGleb Smirnoff error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset,
22529c64cfe5SGleb Smirnoff uap->nbytes, &sbytes, uap->flags, td);
22530e87b36eSGleb Smirnoff fdrop(fp, td);
2254ca04d21dSGleb Smirnoff
22557689abaeSAdrian Chadd if (uap->sbytes != NULL)
2256d0adc2f2SMark Johnston (void)copyout(&sbytes, uap->sbytes, sizeof(off_t));
2257ca04d21dSGleb Smirnoff
2258fa545f43SPaul Saab out:
2259fa545f43SPaul Saab if (hdr_uio)
226061cc4830SAlfredo Mazzinghi freeuio(hdr_uio);
2261fa545f43SPaul Saab if (trl_uio)
226261cc4830SAlfredo Mazzinghi freeuio(trl_uio);
2263fa545f43SPaul Saab return (error);
2264fa545f43SPaul Saab }
2265fa545f43SPaul Saab
2266459e3a7aSPeter Wemm #ifdef COMPAT_FREEBSD4
2267459e3a7aSPeter Wemm int
freebsd4_freebsd32_sendfile(struct thread * td,struct freebsd4_freebsd32_sendfile_args * uap)22681c7abef7SPeter Wemm freebsd4_freebsd32_sendfile(struct thread *td,
22691c7abef7SPeter Wemm struct freebsd4_freebsd32_sendfile_args *uap)
2270459e3a7aSPeter Wemm {
2271fa545f43SPaul Saab return (freebsd32_do_sendfile(td,
2272fa545f43SPaul Saab (struct freebsd32_sendfile_args *)uap, 1));
2273459e3a7aSPeter Wemm }
2274459e3a7aSPeter Wemm #endif
2275459e3a7aSPeter Wemm
22763ebc1248SPeter Wemm int
freebsd32_sendfile(struct thread * td,struct freebsd32_sendfile_args * uap)22771c7abef7SPeter Wemm freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
22783ebc1248SPeter Wemm {
22793ebc1248SPeter Wemm
2280fa545f43SPaul Saab return (freebsd32_do_sendfile(td, uap, 0));
22813ebc1248SPeter Wemm }
22823ebc1248SPeter Wemm
22833ebc1248SPeter Wemm static void
copy_stat(struct stat * in,struct stat32 * out)22843ebc1248SPeter Wemm copy_stat(struct stat *in, struct stat32 *out)
22853ebc1248SPeter Wemm {
228645b6fa3bSKonstantin Belousov
2287f90cd1aeSEd Maste #ifndef __amd64__
2288f90cd1aeSEd Maste /*
2289f90cd1aeSEd Maste * 32-bit architectures other than i386 have 64-bit time_t. This
2290f90cd1aeSEd Maste * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
2291f90cd1aeSEd Maste * and 4 bytes of padding. Zero the padding holes in struct stat32.
2292f90cd1aeSEd Maste */
2293f90cd1aeSEd Maste bzero(&out->st_atim, sizeof(out->st_atim));
2294f90cd1aeSEd Maste bzero(&out->st_mtim, sizeof(out->st_mtim));
2295f90cd1aeSEd Maste bzero(&out->st_ctim, sizeof(out->st_ctim));
2296f90cd1aeSEd Maste bzero(&out->st_birthtim, sizeof(out->st_birthtim));
2297f90cd1aeSEd Maste #endif
22983ebc1248SPeter Wemm CP(*in, *out, st_dev);
22993ebc1248SPeter Wemm CP(*in, *out, st_ino);
23003ebc1248SPeter Wemm CP(*in, *out, st_mode);
23013ebc1248SPeter Wemm CP(*in, *out, st_nlink);
23023ebc1248SPeter Wemm CP(*in, *out, st_uid);
23033ebc1248SPeter Wemm CP(*in, *out, st_gid);
23043ebc1248SPeter Wemm CP(*in, *out, st_rdev);
2305510ea843SEd Schouten TS_CP(*in, *out, st_atim);
2306510ea843SEd Schouten TS_CP(*in, *out, st_mtim);
2307510ea843SEd Schouten TS_CP(*in, *out, st_ctim);
23083ebc1248SPeter Wemm CP(*in, *out, st_size);
23093ebc1248SPeter Wemm CP(*in, *out, st_blocks);
23103ebc1248SPeter Wemm CP(*in, *out, st_blksize);
23113ebc1248SPeter Wemm CP(*in, *out, st_flags);
23123ebc1248SPeter Wemm CP(*in, *out, st_gen);
2313b4663a8dSKonstantin Belousov CP(*in, *out, st_filerev);
231486db734aSKonstantin Belousov CP(*in, *out, st_bsdflags);
231564dc04deSKonstantin Belousov TS_CP(*in, *out, st_birthtim);
231669921123SKonstantin Belousov out->st_padding1 = 0;
231769921123SKonstantin Belousov #ifdef __STAT32_TIME_T_EXT
231869921123SKonstantin Belousov out->st_atim_ext = 0;
231969921123SKonstantin Belousov out->st_mtim_ext = 0;
232069921123SKonstantin Belousov out->st_ctim_ext = 0;
232169921123SKonstantin Belousov out->st_btim_ext = 0;
232269921123SKonstantin Belousov #endif
232369921123SKonstantin Belousov bzero(out->st_spare, sizeof(out->st_spare));
23243ebc1248SPeter Wemm }
23253ebc1248SPeter Wemm
23267332c129SKonstantin Belousov #ifdef COMPAT_43
23277332c129SKonstantin Belousov static void
copy_ostat(struct stat * in,struct ostat32 * out)23287332c129SKonstantin Belousov copy_ostat(struct stat *in, struct ostat32 *out)
23297332c129SKonstantin Belousov {
23307332c129SKonstantin Belousov
2331372639f9SBruce Evans bzero(out, sizeof(*out));
23327332c129SKonstantin Belousov CP(*in, *out, st_dev);
23337332c129SKonstantin Belousov CP(*in, *out, st_ino);
23347332c129SKonstantin Belousov CP(*in, *out, st_mode);
23357332c129SKonstantin Belousov CP(*in, *out, st_nlink);
23367332c129SKonstantin Belousov CP(*in, *out, st_uid);
23377332c129SKonstantin Belousov CP(*in, *out, st_gid);
23387332c129SKonstantin Belousov CP(*in, *out, st_rdev);
2339372639f9SBruce Evans out->st_size = MIN(in->st_size, INT32_MAX);
23407332c129SKonstantin Belousov TS_CP(*in, *out, st_atim);
23417332c129SKonstantin Belousov TS_CP(*in, *out, st_mtim);
23427332c129SKonstantin Belousov TS_CP(*in, *out, st_ctim);
23437332c129SKonstantin Belousov CP(*in, *out, st_blksize);
23447332c129SKonstantin Belousov CP(*in, *out, st_blocks);
23457332c129SKonstantin Belousov CP(*in, *out, st_flags);
23467332c129SKonstantin Belousov CP(*in, *out, st_gen);
23477332c129SKonstantin Belousov }
23487332c129SKonstantin Belousov #endif
23497332c129SKonstantin Belousov
23507332c129SKonstantin Belousov #ifdef COMPAT_43
23517332c129SKonstantin Belousov int
ofreebsd32_stat(struct thread * td,struct ofreebsd32_stat_args * uap)23527332c129SKonstantin Belousov ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
23537332c129SKonstantin Belousov {
23547332c129SKonstantin Belousov struct stat sb;
23557332c129SKonstantin Belousov struct ostat32 sb32;
23567332c129SKonstantin Belousov int error;
23577332c129SKonstantin Belousov
2358cb858340SDmitry Chagin error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
23597332c129SKonstantin Belousov if (error)
23607332c129SKonstantin Belousov return (error);
23617332c129SKonstantin Belousov copy_ostat(&sb, &sb32);
23627332c129SKonstantin Belousov error = copyout(&sb32, uap->ub, sizeof (sb32));
23637332c129SKonstantin Belousov return (error);
23647332c129SKonstantin Belousov }
23657332c129SKonstantin Belousov #endif
23667332c129SKonstantin Belousov
23673ebc1248SPeter Wemm int
freebsd32_fstat(struct thread * td,struct freebsd32_fstat_args * uap)23681c7abef7SPeter Wemm freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
23693ebc1248SPeter Wemm {
237034eda634SPeter Wemm struct stat ub;
237134eda634SPeter Wemm struct stat32 ub32;
23723ebc1248SPeter Wemm int error;
23733ebc1248SPeter Wemm
237438765a31SJohn Baldwin error = kern_fstat(td, uap->fd, &ub);
23753ebc1248SPeter Wemm if (error)
23763ebc1248SPeter Wemm return (error);
237734eda634SPeter Wemm copy_stat(&ub, &ub32);
2378f1a14110SBrooks Davis error = copyout(&ub32, uap->sb, sizeof(ub32));
23793ebc1248SPeter Wemm return (error);
23803ebc1248SPeter Wemm }
23813ebc1248SPeter Wemm
23827332c129SKonstantin Belousov #ifdef COMPAT_43
23837332c129SKonstantin Belousov int
ofreebsd32_fstat(struct thread * td,struct ofreebsd32_fstat_args * uap)23847332c129SKonstantin Belousov ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
23857332c129SKonstantin Belousov {
23867332c129SKonstantin Belousov struct stat ub;
23877332c129SKonstantin Belousov struct ostat32 ub32;
23887332c129SKonstantin Belousov int error;
23897332c129SKonstantin Belousov
23907332c129SKonstantin Belousov error = kern_fstat(td, uap->fd, &ub);
23917332c129SKonstantin Belousov if (error)
23927332c129SKonstantin Belousov return (error);
23937332c129SKonstantin Belousov copy_ostat(&ub, &ub32);
2394ab3ccb75SBrooks Davis error = copyout(&ub32, uap->sb, sizeof(ub32));
23957332c129SKonstantin Belousov return (error);
23967332c129SKonstantin Belousov }
23977332c129SKonstantin Belousov #endif
23987332c129SKonstantin Belousov
23993ebc1248SPeter Wemm int
freebsd32_fstatat(struct thread * td,struct freebsd32_fstatat_args * uap)24004f1e7213SKonstantin Belousov freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
24014f1e7213SKonstantin Belousov {
24024f1e7213SKonstantin Belousov struct stat ub;
24034f1e7213SKonstantin Belousov struct stat32 ub32;
24044f1e7213SKonstantin Belousov int error;
24054f1e7213SKonstantin Belousov
24066e646651SKonstantin Belousov error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2407cb858340SDmitry Chagin &ub);
24084f1e7213SKonstantin Belousov if (error)
24094f1e7213SKonstantin Belousov return (error);
24104f1e7213SKonstantin Belousov copy_stat(&ub, &ub32);
24114f1e7213SKonstantin Belousov error = copyout(&ub32, uap->buf, sizeof(ub32));
24124f1e7213SKonstantin Belousov return (error);
24134f1e7213SKonstantin Belousov }
24144f1e7213SKonstantin Belousov
24157332c129SKonstantin Belousov #ifdef COMPAT_43
24167332c129SKonstantin Belousov int
ofreebsd32_lstat(struct thread * td,struct ofreebsd32_lstat_args * uap)24177332c129SKonstantin Belousov ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
24187332c129SKonstantin Belousov {
24197332c129SKonstantin Belousov struct stat sb;
24207332c129SKonstantin Belousov struct ostat32 sb32;
24217332c129SKonstantin Belousov int error;
24227332c129SKonstantin Belousov
24236e646651SKonstantin Belousov error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2424cb858340SDmitry Chagin UIO_USERSPACE, &sb);
24257332c129SKonstantin Belousov if (error)
24267332c129SKonstantin Belousov return (error);
24277332c129SKonstantin Belousov copy_ostat(&sb, &sb32);
24287332c129SKonstantin Belousov error = copyout(&sb32, uap->ub, sizeof (sb32));
24297332c129SKonstantin Belousov return (error);
24307332c129SKonstantin Belousov }
24317332c129SKonstantin Belousov #endif
24327332c129SKonstantin Belousov
24333ebc1248SPeter Wemm int
freebsd32_fhstat(struct thread * td,struct freebsd32_fhstat_args * uap)243469921123SKonstantin Belousov freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap)
243569921123SKonstantin Belousov {
243669921123SKonstantin Belousov struct stat sb;
243769921123SKonstantin Belousov struct stat32 sb32;
243869921123SKonstantin Belousov struct fhandle fh;
243969921123SKonstantin Belousov int error;
244069921123SKonstantin Belousov
244169921123SKonstantin Belousov error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
244269921123SKonstantin Belousov if (error != 0)
244369921123SKonstantin Belousov return (error);
244469921123SKonstantin Belousov error = kern_fhstat(td, fh, &sb);
244569921123SKonstantin Belousov if (error != 0)
244669921123SKonstantin Belousov return (error);
244769921123SKonstantin Belousov copy_stat(&sb, &sb32);
244869921123SKonstantin Belousov error = copyout(&sb32, uap->sb, sizeof (sb32));
244969921123SKonstantin Belousov return (error);
245069921123SKonstantin Belousov }
245169921123SKonstantin Belousov
245269921123SKonstantin Belousov #if defined(COMPAT_FREEBSD11)
24533df7ebc4SKonstantin Belousov extern int ino64_trunc_error;
24543df7ebc4SKonstantin Belousov
24553df7ebc4SKonstantin Belousov static int
freebsd11_cvtstat32(struct stat * in,struct freebsd11_stat32 * out)245669921123SKonstantin Belousov freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
245769921123SKonstantin Belousov {
245869921123SKonstantin Belousov
2459f90cd1aeSEd Maste #ifndef __amd64__
2460f90cd1aeSEd Maste /*
2461f90cd1aeSEd Maste * 32-bit architectures other than i386 have 64-bit time_t. This
2462f90cd1aeSEd Maste * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
2463f90cd1aeSEd Maste * and 4 bytes of padding. Zero the padding holes in freebsd11_stat32.
2464f90cd1aeSEd Maste */
2465f90cd1aeSEd Maste bzero(&out->st_atim, sizeof(out->st_atim));
2466f90cd1aeSEd Maste bzero(&out->st_mtim, sizeof(out->st_mtim));
2467f90cd1aeSEd Maste bzero(&out->st_ctim, sizeof(out->st_ctim));
2468f90cd1aeSEd Maste bzero(&out->st_birthtim, sizeof(out->st_birthtim));
2469f90cd1aeSEd Maste #endif
2470f90cd1aeSEd Maste
247169921123SKonstantin Belousov CP(*in, *out, st_ino);
24727abe0df2SKonstantin Belousov if (in->st_ino != out->st_ino) {
24737abe0df2SKonstantin Belousov switch (ino64_trunc_error) {
24747abe0df2SKonstantin Belousov default:
24757abe0df2SKonstantin Belousov case 0:
24767abe0df2SKonstantin Belousov break;
24777abe0df2SKonstantin Belousov case 1:
24783df7ebc4SKonstantin Belousov return (EOVERFLOW);
24797abe0df2SKonstantin Belousov case 2:
24807abe0df2SKonstantin Belousov out->st_ino = UINT32_MAX;
24817abe0df2SKonstantin Belousov break;
24827abe0df2SKonstantin Belousov }
24837abe0df2SKonstantin Belousov }
248469921123SKonstantin Belousov CP(*in, *out, st_nlink);
24857abe0df2SKonstantin Belousov if (in->st_nlink != out->st_nlink) {
24867abe0df2SKonstantin Belousov switch (ino64_trunc_error) {
24877abe0df2SKonstantin Belousov default:
24887abe0df2SKonstantin Belousov case 0:
24897abe0df2SKonstantin Belousov break;
24907abe0df2SKonstantin Belousov case 1:
24913df7ebc4SKonstantin Belousov return (EOVERFLOW);
24927abe0df2SKonstantin Belousov case 2:
24937abe0df2SKonstantin Belousov out->st_nlink = UINT16_MAX;
24947abe0df2SKonstantin Belousov break;
24957abe0df2SKonstantin Belousov }
24967abe0df2SKonstantin Belousov }
2497ab35e1c7SBruce Evans out->st_dev = in->st_dev;
2498ab35e1c7SBruce Evans if (out->st_dev != in->st_dev) {
2499ab35e1c7SBruce Evans switch (ino64_trunc_error) {
2500ab35e1c7SBruce Evans default:
2501ab35e1c7SBruce Evans break;
2502ab35e1c7SBruce Evans case 1:
2503ab35e1c7SBruce Evans return (EOVERFLOW);
2504ab35e1c7SBruce Evans }
2505ab35e1c7SBruce Evans }
250669921123SKonstantin Belousov CP(*in, *out, st_mode);
250769921123SKonstantin Belousov CP(*in, *out, st_uid);
250869921123SKonstantin Belousov CP(*in, *out, st_gid);
2509ab35e1c7SBruce Evans out->st_rdev = in->st_rdev;
2510ab35e1c7SBruce Evans if (out->st_rdev != in->st_rdev) {
2511ab35e1c7SBruce Evans switch (ino64_trunc_error) {
2512ab35e1c7SBruce Evans default:
2513ab35e1c7SBruce Evans break;
2514ab35e1c7SBruce Evans case 1:
2515ab35e1c7SBruce Evans return (EOVERFLOW);
2516ab35e1c7SBruce Evans }
2517ab35e1c7SBruce Evans }
251869921123SKonstantin Belousov TS_CP(*in, *out, st_atim);
251969921123SKonstantin Belousov TS_CP(*in, *out, st_mtim);
252069921123SKonstantin Belousov TS_CP(*in, *out, st_ctim);
252169921123SKonstantin Belousov CP(*in, *out, st_size);
252269921123SKonstantin Belousov CP(*in, *out, st_blocks);
252369921123SKonstantin Belousov CP(*in, *out, st_blksize);
252469921123SKonstantin Belousov CP(*in, *out, st_flags);
252569921123SKonstantin Belousov CP(*in, *out, st_gen);
252669921123SKonstantin Belousov TS_CP(*in, *out, st_birthtim);
252769921123SKonstantin Belousov out->st_lspare = 0;
252869921123SKonstantin Belousov bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),
252969921123SKonstantin Belousov sizeof(*out) - offsetof(struct freebsd11_stat32,
253069921123SKonstantin Belousov st_birthtim) - sizeof(out->st_birthtim));
25313df7ebc4SKonstantin Belousov return (0);
253269921123SKonstantin Belousov }
253369921123SKonstantin Belousov
253469921123SKonstantin Belousov int
freebsd11_freebsd32_stat(struct thread * td,struct freebsd11_freebsd32_stat_args * uap)253569921123SKonstantin Belousov freebsd11_freebsd32_stat(struct thread *td,
253669921123SKonstantin Belousov struct freebsd11_freebsd32_stat_args *uap)
253769921123SKonstantin Belousov {
253869921123SKonstantin Belousov struct stat sb;
253969921123SKonstantin Belousov struct freebsd11_stat32 sb32;
254069921123SKonstantin Belousov int error;
254169921123SKonstantin Belousov
2542cb858340SDmitry Chagin error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
254369921123SKonstantin Belousov if (error != 0)
254469921123SKonstantin Belousov return (error);
25453df7ebc4SKonstantin Belousov error = freebsd11_cvtstat32(&sb, &sb32);
25463df7ebc4SKonstantin Belousov if (error == 0)
254769921123SKonstantin Belousov error = copyout(&sb32, uap->ub, sizeof (sb32));
254869921123SKonstantin Belousov return (error);
254969921123SKonstantin Belousov }
255069921123SKonstantin Belousov
255169921123SKonstantin Belousov int
freebsd11_freebsd32_fstat(struct thread * td,struct freebsd11_freebsd32_fstat_args * uap)255269921123SKonstantin Belousov freebsd11_freebsd32_fstat(struct thread *td,
255369921123SKonstantin Belousov struct freebsd11_freebsd32_fstat_args *uap)
255469921123SKonstantin Belousov {
255569921123SKonstantin Belousov struct stat sb;
255669921123SKonstantin Belousov struct freebsd11_stat32 sb32;
255769921123SKonstantin Belousov int error;
255869921123SKonstantin Belousov
255969921123SKonstantin Belousov error = kern_fstat(td, uap->fd, &sb);
256069921123SKonstantin Belousov if (error != 0)
256169921123SKonstantin Belousov return (error);
25623df7ebc4SKonstantin Belousov error = freebsd11_cvtstat32(&sb, &sb32);
25633df7ebc4SKonstantin Belousov if (error == 0)
2564ab3ccb75SBrooks Davis error = copyout(&sb32, uap->sb, sizeof (sb32));
256569921123SKonstantin Belousov return (error);
256669921123SKonstantin Belousov }
256769921123SKonstantin Belousov
256869921123SKonstantin Belousov int
freebsd11_freebsd32_fstatat(struct thread * td,struct freebsd11_freebsd32_fstatat_args * uap)256969921123SKonstantin Belousov freebsd11_freebsd32_fstatat(struct thread *td,
257069921123SKonstantin Belousov struct freebsd11_freebsd32_fstatat_args *uap)
257169921123SKonstantin Belousov {
257269921123SKonstantin Belousov struct stat sb;
257369921123SKonstantin Belousov struct freebsd11_stat32 sb32;
257469921123SKonstantin Belousov int error;
257569921123SKonstantin Belousov
257669921123SKonstantin Belousov error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2577cb858340SDmitry Chagin &sb);
257869921123SKonstantin Belousov if (error != 0)
257969921123SKonstantin Belousov return (error);
25803df7ebc4SKonstantin Belousov error = freebsd11_cvtstat32(&sb, &sb32);
25813df7ebc4SKonstantin Belousov if (error == 0)
258269921123SKonstantin Belousov error = copyout(&sb32, uap->buf, sizeof (sb32));
258369921123SKonstantin Belousov return (error);
258469921123SKonstantin Belousov }
258569921123SKonstantin Belousov
258669921123SKonstantin Belousov int
freebsd11_freebsd32_lstat(struct thread * td,struct freebsd11_freebsd32_lstat_args * uap)258769921123SKonstantin Belousov freebsd11_freebsd32_lstat(struct thread *td,
258869921123SKonstantin Belousov struct freebsd11_freebsd32_lstat_args *uap)
258969921123SKonstantin Belousov {
259069921123SKonstantin Belousov struct stat sb;
259169921123SKonstantin Belousov struct freebsd11_stat32 sb32;
259269921123SKonstantin Belousov int error;
259369921123SKonstantin Belousov
259469921123SKonstantin Belousov error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2595cb858340SDmitry Chagin UIO_USERSPACE, &sb);
25963df7ebc4SKonstantin Belousov if (error != 0)
259769921123SKonstantin Belousov return (error);
25983df7ebc4SKonstantin Belousov error = freebsd11_cvtstat32(&sb, &sb32);
25993df7ebc4SKonstantin Belousov if (error == 0)
260069921123SKonstantin Belousov error = copyout(&sb32, uap->ub, sizeof (sb32));
260169921123SKonstantin Belousov return (error);
260269921123SKonstantin Belousov }
260369921123SKonstantin Belousov
260469921123SKonstantin Belousov int
freebsd11_freebsd32_fhstat(struct thread * td,struct freebsd11_freebsd32_fhstat_args * uap)260569921123SKonstantin Belousov freebsd11_freebsd32_fhstat(struct thread *td,
260669921123SKonstantin Belousov struct freebsd11_freebsd32_fhstat_args *uap)
260769921123SKonstantin Belousov {
260869921123SKonstantin Belousov struct stat sb;
260969921123SKonstantin Belousov struct freebsd11_stat32 sb32;
261069921123SKonstantin Belousov struct fhandle fh;
261169921123SKonstantin Belousov int error;
261269921123SKonstantin Belousov
261369921123SKonstantin Belousov error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
261469921123SKonstantin Belousov if (error != 0)
261569921123SKonstantin Belousov return (error);
261669921123SKonstantin Belousov error = kern_fhstat(td, fh, &sb);
261769921123SKonstantin Belousov if (error != 0)
261869921123SKonstantin Belousov return (error);
26193df7ebc4SKonstantin Belousov error = freebsd11_cvtstat32(&sb, &sb32);
26203df7ebc4SKonstantin Belousov if (error == 0)
262169921123SKonstantin Belousov error = copyout(&sb32, uap->sb, sizeof (sb32));
262269921123SKonstantin Belousov return (error);
262369921123SKonstantin Belousov }
26246eefabd4SBrooks Davis
26256eefabd4SBrooks Davis static int
freebsd11_cvtnstat32(struct stat * sb,struct nstat32 * nsb32)26266eefabd4SBrooks Davis freebsd11_cvtnstat32(struct stat *sb, struct nstat32 *nsb32)
26276eefabd4SBrooks Davis {
26286eefabd4SBrooks Davis struct nstat nsb;
26296eefabd4SBrooks Davis int error;
26306eefabd4SBrooks Davis
26316eefabd4SBrooks Davis error = freebsd11_cvtnstat(sb, &nsb);
26326eefabd4SBrooks Davis if (error != 0)
26336eefabd4SBrooks Davis return (error);
26346eefabd4SBrooks Davis
26356eefabd4SBrooks Davis bzero(nsb32, sizeof(*nsb32));
26366eefabd4SBrooks Davis CP(nsb, *nsb32, st_dev);
26376eefabd4SBrooks Davis CP(nsb, *nsb32, st_ino);
26386eefabd4SBrooks Davis CP(nsb, *nsb32, st_mode);
26396eefabd4SBrooks Davis CP(nsb, *nsb32, st_nlink);
26406eefabd4SBrooks Davis CP(nsb, *nsb32, st_uid);
26416eefabd4SBrooks Davis CP(nsb, *nsb32, st_gid);
26426eefabd4SBrooks Davis CP(nsb, *nsb32, st_rdev);
26436eefabd4SBrooks Davis CP(nsb, *nsb32, st_atim.tv_sec);
26446eefabd4SBrooks Davis CP(nsb, *nsb32, st_atim.tv_nsec);
26456eefabd4SBrooks Davis CP(nsb, *nsb32, st_mtim.tv_sec);
26466eefabd4SBrooks Davis CP(nsb, *nsb32, st_mtim.tv_nsec);
26476eefabd4SBrooks Davis CP(nsb, *nsb32, st_ctim.tv_sec);
26486eefabd4SBrooks Davis CP(nsb, *nsb32, st_ctim.tv_nsec);
26496eefabd4SBrooks Davis CP(nsb, *nsb32, st_size);
26506eefabd4SBrooks Davis CP(nsb, *nsb32, st_blocks);
26516eefabd4SBrooks Davis CP(nsb, *nsb32, st_blksize);
26526eefabd4SBrooks Davis CP(nsb, *nsb32, st_flags);
26536eefabd4SBrooks Davis CP(nsb, *nsb32, st_gen);
26546eefabd4SBrooks Davis CP(nsb, *nsb32, st_birthtim.tv_sec);
26556eefabd4SBrooks Davis CP(nsb, *nsb32, st_birthtim.tv_nsec);
26566eefabd4SBrooks Davis return (0);
26576eefabd4SBrooks Davis }
26586eefabd4SBrooks Davis
26596eefabd4SBrooks Davis int
freebsd11_freebsd32_nstat(struct thread * td,struct freebsd11_freebsd32_nstat_args * uap)26606eefabd4SBrooks Davis freebsd11_freebsd32_nstat(struct thread *td,
26616eefabd4SBrooks Davis struct freebsd11_freebsd32_nstat_args *uap)
26626eefabd4SBrooks Davis {
26636eefabd4SBrooks Davis struct stat sb;
26646eefabd4SBrooks Davis struct nstat32 nsb;
26656eefabd4SBrooks Davis int error;
26666eefabd4SBrooks Davis
2667cb858340SDmitry Chagin error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
26686eefabd4SBrooks Davis if (error != 0)
26696eefabd4SBrooks Davis return (error);
26706eefabd4SBrooks Davis error = freebsd11_cvtnstat32(&sb, &nsb);
26716eefabd4SBrooks Davis if (error != 0)
26726eefabd4SBrooks Davis error = copyout(&nsb, uap->ub, sizeof (nsb));
26736eefabd4SBrooks Davis return (error);
26746eefabd4SBrooks Davis }
26756eefabd4SBrooks Davis
26766eefabd4SBrooks Davis int
freebsd11_freebsd32_nlstat(struct thread * td,struct freebsd11_freebsd32_nlstat_args * uap)26776eefabd4SBrooks Davis freebsd11_freebsd32_nlstat(struct thread *td,
26786eefabd4SBrooks Davis struct freebsd11_freebsd32_nlstat_args *uap)
26796eefabd4SBrooks Davis {
26806eefabd4SBrooks Davis struct stat sb;
26816eefabd4SBrooks Davis struct nstat32 nsb;
26826eefabd4SBrooks Davis int error;
26836eefabd4SBrooks Davis
26846eefabd4SBrooks Davis error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2685cb858340SDmitry Chagin UIO_USERSPACE, &sb);
26866eefabd4SBrooks Davis if (error != 0)
26876eefabd4SBrooks Davis return (error);
26886eefabd4SBrooks Davis error = freebsd11_cvtnstat32(&sb, &nsb);
26896eefabd4SBrooks Davis if (error == 0)
26906eefabd4SBrooks Davis error = copyout(&nsb, uap->ub, sizeof (nsb));
26916eefabd4SBrooks Davis return (error);
26926eefabd4SBrooks Davis }
26936eefabd4SBrooks Davis
26946eefabd4SBrooks Davis int
freebsd11_freebsd32_nfstat(struct thread * td,struct freebsd11_freebsd32_nfstat_args * uap)26956eefabd4SBrooks Davis freebsd11_freebsd32_nfstat(struct thread *td,
26966eefabd4SBrooks Davis struct freebsd11_freebsd32_nfstat_args *uap)
26976eefabd4SBrooks Davis {
26986eefabd4SBrooks Davis struct nstat32 nub;
26996eefabd4SBrooks Davis struct stat ub;
27006eefabd4SBrooks Davis int error;
27016eefabd4SBrooks Davis
27026eefabd4SBrooks Davis error = kern_fstat(td, uap->fd, &ub);
27036eefabd4SBrooks Davis if (error != 0)
27046eefabd4SBrooks Davis return (error);
27056eefabd4SBrooks Davis error = freebsd11_cvtnstat32(&ub, &nub);
27066eefabd4SBrooks Davis if (error == 0)
27076eefabd4SBrooks Davis error = copyout(&nub, uap->sb, sizeof(nub));
27086eefabd4SBrooks Davis return (error);
27096eefabd4SBrooks Davis }
271069921123SKonstantin Belousov #endif
271169921123SKonstantin Belousov
271269921123SKonstantin Belousov int
freebsd32___sysctl(struct thread * td,struct freebsd32___sysctl_args * uap)271340747517SBrooks Davis freebsd32___sysctl(struct thread *td, struct freebsd32___sysctl_args *uap)
27143ebc1248SPeter Wemm {
27153ebc1248SPeter Wemm int error, name[CTL_MAXNAME];
27163ebc1248SPeter Wemm size_t j, oldlen;
27170a2c94b8SKonstantin Belousov uint32_t tmp;
27183ebc1248SPeter Wemm
27193ebc1248SPeter Wemm if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
27203ebc1248SPeter Wemm return (EINVAL);
2721a7bc3102SPeter Wemm error = copyin(uap->name, name, uap->namelen * sizeof(int));
27223ebc1248SPeter Wemm if (error)
27233ebc1248SPeter Wemm return (error);
27240a2c94b8SKonstantin Belousov if (uap->oldlenp) {
27250a2c94b8SKonstantin Belousov error = fueword32(uap->oldlenp, &tmp);
27260a2c94b8SKonstantin Belousov oldlen = tmp;
27270a2c94b8SKonstantin Belousov } else {
27283ebc1248SPeter Wemm oldlen = 0;
27290a2c94b8SKonstantin Belousov }
27300a2c94b8SKonstantin Belousov if (error != 0)
27310a2c94b8SKonstantin Belousov return (EFAULT);
27323ebc1248SPeter Wemm error = userland_sysctl(td, name, uap->namelen,
27333ebc1248SPeter Wemm uap->old, &oldlen, 1,
2734a7bc3102SPeter Wemm uap->new, uap->newlen, &j, SCTL_MASK32);
2735e15f0023SBrooks Davis if (error)
2736ddf9d243SEd Schouten return (error);
273781eb7baaSMark Johnston if (uap->oldlenp != NULL && suword32(uap->oldlenp, j) != 0)
273881eb7baaSMark Johnston error = EFAULT;
273981eb7baaSMark Johnston return (error);
27403ebc1248SPeter Wemm }
27413ebc1248SPeter Wemm
27423ebc1248SPeter Wemm int
freebsd32___sysctlbyname(struct thread * td,struct freebsd32___sysctlbyname_args * uap)2743d05b53e0SMateusz Guzik freebsd32___sysctlbyname(struct thread *td,
2744d05b53e0SMateusz Guzik struct freebsd32___sysctlbyname_args *uap)
2745d05b53e0SMateusz Guzik {
2746d05b53e0SMateusz Guzik size_t oldlen, rv;
2747d05b53e0SMateusz Guzik int error;
2748d05b53e0SMateusz Guzik uint32_t tmp;
2749d05b53e0SMateusz Guzik
2750d05b53e0SMateusz Guzik if (uap->oldlenp != NULL) {
2751d05b53e0SMateusz Guzik error = fueword32(uap->oldlenp, &tmp);
2752d05b53e0SMateusz Guzik oldlen = tmp;
2753d05b53e0SMateusz Guzik } else {
2754d05b53e0SMateusz Guzik error = oldlen = 0;
2755d05b53e0SMateusz Guzik }
2756d05b53e0SMateusz Guzik if (error != 0)
2757d05b53e0SMateusz Guzik return (EFAULT);
2758d05b53e0SMateusz Guzik error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
2759d05b53e0SMateusz Guzik &oldlen, uap->new, uap->newlen, &rv, SCTL_MASK32, 1);
2760d05b53e0SMateusz Guzik if (error != 0)
2761d05b53e0SMateusz Guzik return (error);
2762bd1654ceSMark Johnston if (uap->oldlenp != NULL && suword32(uap->oldlenp, rv) != 0)
2763bd1654ceSMark Johnston error = EFAULT;
2764d05b53e0SMateusz Guzik return (error);
2765d05b53e0SMateusz Guzik }
2766d05b53e0SMateusz Guzik
2767d05b53e0SMateusz Guzik int
freebsd32_jail(struct thread * td,struct freebsd32_jail_args * uap)2768c542c43eSJamie Gritton freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
2769413628a7SBjoern A. Zeeb {
2770413628a7SBjoern A. Zeeb uint32_t version;
2771413628a7SBjoern A. Zeeb int error;
27720304c731SJamie Gritton struct jail j;
2773413628a7SBjoern A. Zeeb
2774413628a7SBjoern A. Zeeb error = copyin(uap->jail, &version, sizeof(uint32_t));
2775413628a7SBjoern A. Zeeb if (error)
2776413628a7SBjoern A. Zeeb return (error);
27778571af59SJamie Gritton
2778413628a7SBjoern A. Zeeb switch (version) {
2779413628a7SBjoern A. Zeeb case 0:
2780413628a7SBjoern A. Zeeb {
2781413628a7SBjoern A. Zeeb /* FreeBSD single IPv4 jails. */
2782413628a7SBjoern A. Zeeb struct jail32_v0 j32_v0;
2783413628a7SBjoern A. Zeeb
27840304c731SJamie Gritton bzero(&j, sizeof(struct jail));
2785413628a7SBjoern A. Zeeb error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
2786413628a7SBjoern A. Zeeb if (error)
2787413628a7SBjoern A. Zeeb return (error);
27880304c731SJamie Gritton CP(j32_v0, j, version);
27890304c731SJamie Gritton PTRIN_CP(j32_v0, j, path);
27900304c731SJamie Gritton PTRIN_CP(j32_v0, j, hostname);
2791b5019bc4SPeter Wemm j.ip4s = htonl(j32_v0.ip_number); /* jail_v0 is host order */
2792413628a7SBjoern A. Zeeb break;
2793413628a7SBjoern A. Zeeb }
2794413628a7SBjoern A. Zeeb
2795413628a7SBjoern A. Zeeb case 1:
2796413628a7SBjoern A. Zeeb /*
2797413628a7SBjoern A. Zeeb * Version 1 was used by multi-IPv4 jail implementations
2798413628a7SBjoern A. Zeeb * that never made it into the official kernel.
2799413628a7SBjoern A. Zeeb */
2800413628a7SBjoern A. Zeeb return (EINVAL);
2801413628a7SBjoern A. Zeeb
2802413628a7SBjoern A. Zeeb case 2: /* JAIL_API_VERSION */
2803413628a7SBjoern A. Zeeb {
2804413628a7SBjoern A. Zeeb /* FreeBSD multi-IPv4/IPv6,noIP jails. */
2805413628a7SBjoern A. Zeeb struct jail32 j32;
2806413628a7SBjoern A. Zeeb
2807413628a7SBjoern A. Zeeb error = copyin(uap->jail, &j32, sizeof(struct jail32));
2808413628a7SBjoern A. Zeeb if (error)
2809413628a7SBjoern A. Zeeb return (error);
28100304c731SJamie Gritton CP(j32, j, version);
28110304c731SJamie Gritton PTRIN_CP(j32, j, path);
28120304c731SJamie Gritton PTRIN_CP(j32, j, hostname);
28130304c731SJamie Gritton PTRIN_CP(j32, j, jailname);
28140304c731SJamie Gritton CP(j32, j, ip4s);
28150304c731SJamie Gritton CP(j32, j, ip6s);
28160304c731SJamie Gritton PTRIN_CP(j32, j, ip4);
28170304c731SJamie Gritton PTRIN_CP(j32, j, ip6);
2818413628a7SBjoern A. Zeeb break;
2819413628a7SBjoern A. Zeeb }
2820413628a7SBjoern A. Zeeb
2821413628a7SBjoern A. Zeeb default:
2822413628a7SBjoern A. Zeeb /* Sci-Fi jails are not supported, sorry. */
2823413628a7SBjoern A. Zeeb return (EINVAL);
2824413628a7SBjoern A. Zeeb }
2825c542c43eSJamie Gritton return (kern_jail(td, &j));
2826b38ff370SJamie Gritton }
2827b38ff370SJamie Gritton
2828b38ff370SJamie Gritton int
freebsd32_jail_set(struct thread * td,struct freebsd32_jail_set_args * uap)2829b38ff370SJamie Gritton freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
2830b38ff370SJamie Gritton {
2831b38ff370SJamie Gritton struct uio *auio;
2832b38ff370SJamie Gritton int error;
2833b38ff370SJamie Gritton
2834b38ff370SJamie Gritton /* Check that we have an even number of iovecs. */
2835b38ff370SJamie Gritton if (uap->iovcnt & 1)
2836b38ff370SJamie Gritton return (EINVAL);
2837b38ff370SJamie Gritton
2838b38ff370SJamie Gritton error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2839b38ff370SJamie Gritton if (error)
2840b38ff370SJamie Gritton return (error);
2841b38ff370SJamie Gritton error = kern_jail_set(td, auio, uap->flags);
284261cc4830SAlfredo Mazzinghi freeuio(auio);
2843b38ff370SJamie Gritton return (error);
2844b38ff370SJamie Gritton }
2845b38ff370SJamie Gritton
2846b38ff370SJamie Gritton int
freebsd32_jail_get(struct thread * td,struct freebsd32_jail_get_args * uap)2847b38ff370SJamie Gritton freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
2848b38ff370SJamie Gritton {
2849b38ff370SJamie Gritton struct iovec32 iov32;
2850b38ff370SJamie Gritton struct uio *auio;
2851b38ff370SJamie Gritton int error, i;
2852b38ff370SJamie Gritton
2853b38ff370SJamie Gritton /* Check that we have an even number of iovecs. */
2854b38ff370SJamie Gritton if (uap->iovcnt & 1)
2855b38ff370SJamie Gritton return (EINVAL);
2856b38ff370SJamie Gritton
2857b38ff370SJamie Gritton error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2858b38ff370SJamie Gritton if (error)
2859b38ff370SJamie Gritton return (error);
2860b38ff370SJamie Gritton error = kern_jail_get(td, auio, uap->flags);
2861b38ff370SJamie Gritton if (error == 0)
2862b38ff370SJamie Gritton for (i = 0; i < uap->iovcnt; i++) {
2863b38ff370SJamie Gritton PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
2864b38ff370SJamie Gritton CP(auio->uio_iov[i], iov32, iov_len);
2865b38ff370SJamie Gritton error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
2866b38ff370SJamie Gritton if (error != 0)
2867b38ff370SJamie Gritton break;
2868b38ff370SJamie Gritton }
286961cc4830SAlfredo Mazzinghi freeuio(auio);
2870b38ff370SJamie Gritton return (error);
2871413628a7SBjoern A. Zeeb }
2872413628a7SBjoern A. Zeeb
2873413628a7SBjoern A. Zeeb int
freebsd32_sigaction(struct thread * td,struct freebsd32_sigaction_args * uap)28741c7abef7SPeter Wemm freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
28753ebc1248SPeter Wemm {
2876fe8cdcaeSJohn Baldwin struct sigaction32 s32;
2877fe8cdcaeSJohn Baldwin struct sigaction sa, osa, *sap;
28783ebc1248SPeter Wemm int error;
28793ebc1248SPeter Wemm
2880fe8cdcaeSJohn Baldwin if (uap->act) {
2881fe8cdcaeSJohn Baldwin error = copyin(uap->act, &s32, sizeof(s32));
28823ebc1248SPeter Wemm if (error)
28833ebc1248SPeter Wemm return (error);
2884fe8cdcaeSJohn Baldwin sa.sa_handler = PTRIN(s32.sa_u);
2885fe8cdcaeSJohn Baldwin CP(s32, sa, sa_flags);
2886fe8cdcaeSJohn Baldwin CP(s32, sa, sa_mask);
2887fe8cdcaeSJohn Baldwin sap = &sa;
2888fe8cdcaeSJohn Baldwin } else
2889fe8cdcaeSJohn Baldwin sap = NULL;
2890fe8cdcaeSJohn Baldwin error = kern_sigaction(td, uap->sig, sap, &osa, 0);
2891473dd55fSPaul Saab if (error == 0 && uap->oact != NULL) {
2892fe8cdcaeSJohn Baldwin s32.sa_u = PTROUT(osa.sa_handler);
2893fe8cdcaeSJohn Baldwin CP(osa, s32, sa_flags);
2894fe8cdcaeSJohn Baldwin CP(osa, s32, sa_mask);
2895fe8cdcaeSJohn Baldwin error = copyout(&s32, uap->oact, sizeof(s32));
28963ebc1248SPeter Wemm }
28973ebc1248SPeter Wemm return (error);
28983ebc1248SPeter Wemm }
28993ebc1248SPeter Wemm
2900d85631c4SPeter Wemm #ifdef COMPAT_FREEBSD4
2901d85631c4SPeter Wemm int
freebsd4_freebsd32_sigaction(struct thread * td,struct freebsd4_freebsd32_sigaction_args * uap)29021c7abef7SPeter Wemm freebsd4_freebsd32_sigaction(struct thread *td,
29031c7abef7SPeter Wemm struct freebsd4_freebsd32_sigaction_args *uap)
2904d85631c4SPeter Wemm {
2905d85631c4SPeter Wemm struct sigaction32 s32;
2906d85631c4SPeter Wemm struct sigaction sa, osa, *sap;
2907d85631c4SPeter Wemm int error;
2908d85631c4SPeter Wemm
2909d85631c4SPeter Wemm if (uap->act) {
2910d85631c4SPeter Wemm error = copyin(uap->act, &s32, sizeof(s32));
2911d85631c4SPeter Wemm if (error)
2912d85631c4SPeter Wemm return (error);
2913d85631c4SPeter Wemm sa.sa_handler = PTRIN(s32.sa_u);
2914d85631c4SPeter Wemm CP(s32, sa, sa_flags);
2915d85631c4SPeter Wemm CP(s32, sa, sa_mask);
2916d85631c4SPeter Wemm sap = &sa;
2917d85631c4SPeter Wemm } else
2918d85631c4SPeter Wemm sap = NULL;
2919d85631c4SPeter Wemm error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
2920473dd55fSPaul Saab if (error == 0 && uap->oact != NULL) {
2921d85631c4SPeter Wemm s32.sa_u = PTROUT(osa.sa_handler);
2922d85631c4SPeter Wemm CP(osa, s32, sa_flags);
2923d85631c4SPeter Wemm CP(osa, s32, sa_mask);
2924d85631c4SPeter Wemm error = copyout(&s32, uap->oact, sizeof(s32));
2925d85631c4SPeter Wemm }
2926d85631c4SPeter Wemm return (error);
2927d85631c4SPeter Wemm }
2928d85631c4SPeter Wemm #endif
2929d85631c4SPeter Wemm
2930e7abd4a0SPaul Saab #ifdef COMPAT_43
2931767dfc44SPeter Wemm struct osigaction32 {
2932cc5aa0a4SJohn Baldwin uint32_t sa_u;
2933e7abd4a0SPaul Saab osigset_t sa_mask;
2934e7abd4a0SPaul Saab int sa_flags;
2935e7abd4a0SPaul Saab };
2936e7abd4a0SPaul Saab
2937e7abd4a0SPaul Saab #define ONSIG 32
2938e7abd4a0SPaul Saab
2939e7abd4a0SPaul Saab int
ofreebsd32_sigaction(struct thread * td,struct ofreebsd32_sigaction_args * uap)2940767dfc44SPeter Wemm ofreebsd32_sigaction(struct thread *td,
2941767dfc44SPeter Wemm struct ofreebsd32_sigaction_args *uap)
2942e7abd4a0SPaul Saab {
2943767dfc44SPeter Wemm struct osigaction32 s32;
2944e7abd4a0SPaul Saab struct sigaction sa, osa, *sap;
2945e7abd4a0SPaul Saab int error;
2946e7abd4a0SPaul Saab
2947e7abd4a0SPaul Saab if (uap->signum <= 0 || uap->signum >= ONSIG)
2948e7abd4a0SPaul Saab return (EINVAL);
2949e7abd4a0SPaul Saab
2950e7abd4a0SPaul Saab if (uap->nsa) {
2951e7abd4a0SPaul Saab error = copyin(uap->nsa, &s32, sizeof(s32));
2952e7abd4a0SPaul Saab if (error)
2953e7abd4a0SPaul Saab return (error);
2954e7abd4a0SPaul Saab sa.sa_handler = PTRIN(s32.sa_u);
2955e7abd4a0SPaul Saab CP(s32, sa, sa_flags);
2956e7abd4a0SPaul Saab OSIG2SIG(s32.sa_mask, sa.sa_mask);
2957e7abd4a0SPaul Saab sap = &sa;
2958e7abd4a0SPaul Saab } else
2959e7abd4a0SPaul Saab sap = NULL;
2960e7abd4a0SPaul Saab error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2961e7abd4a0SPaul Saab if (error == 0 && uap->osa != NULL) {
2962e7abd4a0SPaul Saab s32.sa_u = PTROUT(osa.sa_handler);
2963e7abd4a0SPaul Saab CP(osa, s32, sa_flags);
2964e7abd4a0SPaul Saab SIG2OSIG(osa.sa_mask, s32.sa_mask);
2965e7abd4a0SPaul Saab error = copyout(&s32, uap->osa, sizeof(s32));
2966e7abd4a0SPaul Saab }
2967e7abd4a0SPaul Saab return (error);
2968e7abd4a0SPaul Saab }
2969e7abd4a0SPaul Saab
2970e7abd4a0SPaul Saab struct sigvec32 {
2971cc5aa0a4SJohn Baldwin uint32_t sv_handler;
2972e7abd4a0SPaul Saab int sv_mask;
2973e7abd4a0SPaul Saab int sv_flags;
2974e7abd4a0SPaul Saab };
2975e7abd4a0SPaul Saab
2976e7abd4a0SPaul Saab int
ofreebsd32_sigvec(struct thread * td,struct ofreebsd32_sigvec_args * uap)2977767dfc44SPeter Wemm ofreebsd32_sigvec(struct thread *td,
2978767dfc44SPeter Wemm struct ofreebsd32_sigvec_args *uap)
2979e7abd4a0SPaul Saab {
2980e7abd4a0SPaul Saab struct sigvec32 vec;
2981e7abd4a0SPaul Saab struct sigaction sa, osa, *sap;
2982e7abd4a0SPaul Saab int error;
2983e7abd4a0SPaul Saab
2984e7abd4a0SPaul Saab if (uap->signum <= 0 || uap->signum >= ONSIG)
2985e7abd4a0SPaul Saab return (EINVAL);
2986e7abd4a0SPaul Saab
2987e7abd4a0SPaul Saab if (uap->nsv) {
2988e7abd4a0SPaul Saab error = copyin(uap->nsv, &vec, sizeof(vec));
2989e7abd4a0SPaul Saab if (error)
2990e7abd4a0SPaul Saab return (error);
2991e7abd4a0SPaul Saab sa.sa_handler = PTRIN(vec.sv_handler);
2992e7abd4a0SPaul Saab OSIG2SIG(vec.sv_mask, sa.sa_mask);
2993e7abd4a0SPaul Saab sa.sa_flags = vec.sv_flags;
2994e7abd4a0SPaul Saab sa.sa_flags ^= SA_RESTART;
2995e7abd4a0SPaul Saab sap = &sa;
2996e7abd4a0SPaul Saab } else
2997e7abd4a0SPaul Saab sap = NULL;
2998e7abd4a0SPaul Saab error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2999e7abd4a0SPaul Saab if (error == 0 && uap->osv != NULL) {
3000e7abd4a0SPaul Saab vec.sv_handler = PTROUT(osa.sa_handler);
3001e7abd4a0SPaul Saab SIG2OSIG(osa.sa_mask, vec.sv_mask);
3002e7abd4a0SPaul Saab vec.sv_flags = osa.sa_flags;
3003e7abd4a0SPaul Saab vec.sv_flags &= ~SA_NOCLDWAIT;
3004e7abd4a0SPaul Saab vec.sv_flags ^= SA_RESTART;
3005e7abd4a0SPaul Saab error = copyout(&vec, uap->osv, sizeof(vec));
3006e7abd4a0SPaul Saab }
3007e7abd4a0SPaul Saab return (error);
3008e7abd4a0SPaul Saab }
3009e7abd4a0SPaul Saab
3010e7abd4a0SPaul Saab struct sigstack32 {
3011cc5aa0a4SJohn Baldwin uint32_t ss_sp;
3012e7abd4a0SPaul Saab int ss_onstack;
3013e7abd4a0SPaul Saab };
3014e7abd4a0SPaul Saab
3015e7abd4a0SPaul Saab int
ofreebsd32_sigstack(struct thread * td,struct ofreebsd32_sigstack_args * uap)3016767dfc44SPeter Wemm ofreebsd32_sigstack(struct thread *td,
3017767dfc44SPeter Wemm struct ofreebsd32_sigstack_args *uap)
3018e7abd4a0SPaul Saab {
3019e7abd4a0SPaul Saab struct sigstack32 s32;
3020e7abd4a0SPaul Saab struct sigstack nss, oss;
3021739c673cSMatt Jacob int error = 0, unss;
3022e7abd4a0SPaul Saab
3023e7abd4a0SPaul Saab if (uap->nss != NULL) {
3024e7abd4a0SPaul Saab error = copyin(uap->nss, &s32, sizeof(s32));
3025e7abd4a0SPaul Saab if (error)
3026e7abd4a0SPaul Saab return (error);
3027e7abd4a0SPaul Saab nss.ss_sp = PTRIN(s32.ss_sp);
3028e7abd4a0SPaul Saab CP(s32, nss, ss_onstack);
3029739c673cSMatt Jacob unss = 1;
3030739c673cSMatt Jacob } else {
3031739c673cSMatt Jacob unss = 0;
3032e7abd4a0SPaul Saab }
3033e7abd4a0SPaul Saab oss.ss_sp = td->td_sigstk.ss_sp;
3034e7abd4a0SPaul Saab oss.ss_onstack = sigonstack(cpu_getstack(td));
3035739c673cSMatt Jacob if (unss) {
3036e7abd4a0SPaul Saab td->td_sigstk.ss_sp = nss.ss_sp;
3037e7abd4a0SPaul Saab td->td_sigstk.ss_size = 0;
3038739c673cSMatt Jacob td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
3039e7abd4a0SPaul Saab td->td_pflags |= TDP_ALTSTACK;
3040e7abd4a0SPaul Saab }
3041e7abd4a0SPaul Saab if (uap->oss != NULL) {
3042e7abd4a0SPaul Saab s32.ss_sp = PTROUT(oss.ss_sp);
3043e7abd4a0SPaul Saab CP(oss, s32, ss_onstack);
3044e7abd4a0SPaul Saab error = copyout(&s32, uap->oss, sizeof(s32));
3045e7abd4a0SPaul Saab }
3046e7abd4a0SPaul Saab return (error);
3047e7abd4a0SPaul Saab }
3048e7abd4a0SPaul Saab #endif
3049e7abd4a0SPaul Saab
30507fdf2c85SPaul Saab int
freebsd32_nanosleep(struct thread * td,struct freebsd32_nanosleep_args * uap)30517fdf2c85SPaul Saab freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
30527fdf2c85SPaul Saab {
30533f8455b0SEric van Gyzen
30543f8455b0SEric van Gyzen return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME,
30553f8455b0SEric van Gyzen TIMER_RELTIME, uap->rqtp, uap->rmtp));
30563f8455b0SEric van Gyzen }
30573f8455b0SEric van Gyzen
30583f8455b0SEric van Gyzen int
freebsd32_clock_nanosleep(struct thread * td,struct freebsd32_clock_nanosleep_args * uap)30593f8455b0SEric van Gyzen freebsd32_clock_nanosleep(struct thread *td,
30603f8455b0SEric van Gyzen struct freebsd32_clock_nanosleep_args *uap)
30613f8455b0SEric van Gyzen {
30623f8455b0SEric van Gyzen int error;
30633f8455b0SEric van Gyzen
30643f8455b0SEric van Gyzen error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags,
30653f8455b0SEric van Gyzen uap->rqtp, uap->rmtp);
30663f8455b0SEric van Gyzen return (kern_posix_error(td, error));
30673f8455b0SEric van Gyzen }
30683f8455b0SEric van Gyzen
30693f8455b0SEric van Gyzen static int
freebsd32_user_clock_nanosleep(struct thread * td,clockid_t clock_id,int flags,const struct timespec32 * ua_rqtp,struct timespec32 * ua_rmtp)30703f8455b0SEric van Gyzen freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
30713f8455b0SEric van Gyzen int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp)
30723f8455b0SEric van Gyzen {
30737fdf2c85SPaul Saab struct timespec32 rmt32, rqt32;
30747fdf2c85SPaul Saab struct timespec rmt, rqt;
3075618a20d4SBrooks Davis int error, error2;
30767fdf2c85SPaul Saab
30773f8455b0SEric van Gyzen error = copyin(ua_rqtp, &rqt32, sizeof(rqt32));
30787fdf2c85SPaul Saab if (error)
30797fdf2c85SPaul Saab return (error);
30807fdf2c85SPaul Saab
30817fdf2c85SPaul Saab CP(rqt32, rqt, tv_sec);
30827fdf2c85SPaul Saab CP(rqt32, rqt, tv_nsec);
30837fdf2c85SPaul Saab
30843f8455b0SEric van Gyzen error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt);
30853f8455b0SEric van Gyzen if (error == EINTR && ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0) {
30867fdf2c85SPaul Saab CP(rmt, rmt32, tv_sec);
30877fdf2c85SPaul Saab CP(rmt, rmt32, tv_nsec);
30887fdf2c85SPaul Saab
30893f8455b0SEric van Gyzen error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32));
3090618a20d4SBrooks Davis if (error2 != 0)
30917fdf2c85SPaul Saab error = error2;
30927fdf2c85SPaul Saab }
30937fdf2c85SPaul Saab return (error);
30947fdf2c85SPaul Saab }
30957fdf2c85SPaul Saab
3096f0b479cdSPaul Saab int
freebsd32_clock_gettime(struct thread * td,struct freebsd32_clock_gettime_args * uap)3097f0b479cdSPaul Saab freebsd32_clock_gettime(struct thread *td,
3098f0b479cdSPaul Saab struct freebsd32_clock_gettime_args *uap)
3099f0b479cdSPaul Saab {
3100f0b479cdSPaul Saab struct timespec ats;
3101f0b479cdSPaul Saab struct timespec32 ats32;
3102f0b479cdSPaul Saab int error;
3103f0b479cdSPaul Saab
3104f0b479cdSPaul Saab error = kern_clock_gettime(td, uap->clock_id, &ats);
3105f0b479cdSPaul Saab if (error == 0) {
3106f0b479cdSPaul Saab CP(ats, ats32, tv_sec);
3107f0b479cdSPaul Saab CP(ats, ats32, tv_nsec);
3108f0b479cdSPaul Saab error = copyout(&ats32, uap->tp, sizeof(ats32));
3109f0b479cdSPaul Saab }
3110f0b479cdSPaul Saab return (error);
3111f0b479cdSPaul Saab }
3112f0b479cdSPaul Saab
3113f0b479cdSPaul Saab int
freebsd32_clock_settime(struct thread * td,struct freebsd32_clock_settime_args * uap)3114f0b479cdSPaul Saab freebsd32_clock_settime(struct thread *td,
3115f0b479cdSPaul Saab struct freebsd32_clock_settime_args *uap)
3116f0b479cdSPaul Saab {
3117f0b479cdSPaul Saab struct timespec ats;
3118f0b479cdSPaul Saab struct timespec32 ats32;
3119f0b479cdSPaul Saab int error;
3120f0b479cdSPaul Saab
3121f0b479cdSPaul Saab error = copyin(uap->tp, &ats32, sizeof(ats32));
3122f0b479cdSPaul Saab if (error)
3123f0b479cdSPaul Saab return (error);
3124f0b479cdSPaul Saab CP(ats32, ats, tv_sec);
3125f0b479cdSPaul Saab CP(ats32, ats, tv_nsec);
3126f0b479cdSPaul Saab
3127f0b479cdSPaul Saab return (kern_clock_settime(td, uap->clock_id, &ats));
3128f0b479cdSPaul Saab }
3129f0b479cdSPaul Saab
3130f0b479cdSPaul Saab int
freebsd32_clock_getres(struct thread * td,struct freebsd32_clock_getres_args * uap)3131f0b479cdSPaul Saab freebsd32_clock_getres(struct thread *td,
3132f0b479cdSPaul Saab struct freebsd32_clock_getres_args *uap)
3133f0b479cdSPaul Saab {
3134f0b479cdSPaul Saab struct timespec ts;
3135f0b479cdSPaul Saab struct timespec32 ts32;
3136f0b479cdSPaul Saab int error;
3137f0b479cdSPaul Saab
3138f0b479cdSPaul Saab if (uap->tp == NULL)
3139f0b479cdSPaul Saab return (0);
3140f0b479cdSPaul Saab error = kern_clock_getres(td, uap->clock_id, &ts);
3141f0b479cdSPaul Saab if (error == 0) {
3142f0b479cdSPaul Saab CP(ts, ts32, tv_sec);
3143f0b479cdSPaul Saab CP(ts, ts32, tv_nsec);
3144f0b479cdSPaul Saab error = copyout(&ts32, uap->tp, sizeof(ts32));
3145f0b479cdSPaul Saab }
3146f0b479cdSPaul Saab return (error);
3147f0b479cdSPaul Saab }
3148f0b479cdSPaul Saab
freebsd32_ktimer_create(struct thread * td,struct freebsd32_ktimer_create_args * uap)3149643ee871SKonstantin Belousov int freebsd32_ktimer_create(struct thread *td,
3150643ee871SKonstantin Belousov struct freebsd32_ktimer_create_args *uap)
3151643ee871SKonstantin Belousov {
3152643ee871SKonstantin Belousov struct sigevent32 ev32;
3153643ee871SKonstantin Belousov struct sigevent ev, *evp;
3154643ee871SKonstantin Belousov int error, id;
3155643ee871SKonstantin Belousov
3156643ee871SKonstantin Belousov if (uap->evp == NULL) {
3157643ee871SKonstantin Belousov evp = NULL;
3158643ee871SKonstantin Belousov } else {
3159643ee871SKonstantin Belousov evp = &ev;
3160643ee871SKonstantin Belousov error = copyin(uap->evp, &ev32, sizeof(ev32));
3161643ee871SKonstantin Belousov if (error != 0)
3162643ee871SKonstantin Belousov return (error);
3163643ee871SKonstantin Belousov error = convert_sigevent32(&ev32, &ev);
3164643ee871SKonstantin Belousov if (error != 0)
3165643ee871SKonstantin Belousov return (error);
3166643ee871SKonstantin Belousov }
3167643ee871SKonstantin Belousov error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
3168643ee871SKonstantin Belousov if (error == 0) {
3169643ee871SKonstantin Belousov error = copyout(&id, uap->timerid, sizeof(int));
3170643ee871SKonstantin Belousov if (error != 0)
3171643ee871SKonstantin Belousov kern_ktimer_delete(td, id);
3172643ee871SKonstantin Belousov }
3173643ee871SKonstantin Belousov return (error);
3174643ee871SKonstantin Belousov }
3175643ee871SKonstantin Belousov
3176643ee871SKonstantin Belousov int
freebsd32_ktimer_settime(struct thread * td,struct freebsd32_ktimer_settime_args * uap)3177643ee871SKonstantin Belousov freebsd32_ktimer_settime(struct thread *td,
3178643ee871SKonstantin Belousov struct freebsd32_ktimer_settime_args *uap)
3179643ee871SKonstantin Belousov {
3180643ee871SKonstantin Belousov struct itimerspec32 val32, oval32;
3181643ee871SKonstantin Belousov struct itimerspec val, oval, *ovalp;
3182643ee871SKonstantin Belousov int error;
3183643ee871SKonstantin Belousov
3184643ee871SKonstantin Belousov error = copyin(uap->value, &val32, sizeof(val32));
3185643ee871SKonstantin Belousov if (error != 0)
3186643ee871SKonstantin Belousov return (error);
3187643ee871SKonstantin Belousov ITS_CP(val32, val);
3188643ee871SKonstantin Belousov ovalp = uap->ovalue != NULL ? &oval : NULL;
3189643ee871SKonstantin Belousov error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
3190643ee871SKonstantin Belousov if (error == 0 && uap->ovalue != NULL) {
3191643ee871SKonstantin Belousov ITS_CP(oval, oval32);
3192643ee871SKonstantin Belousov error = copyout(&oval32, uap->ovalue, sizeof(oval32));
3193643ee871SKonstantin Belousov }
3194643ee871SKonstantin Belousov return (error);
3195643ee871SKonstantin Belousov }
3196643ee871SKonstantin Belousov
3197643ee871SKonstantin Belousov int
freebsd32_ktimer_gettime(struct thread * td,struct freebsd32_ktimer_gettime_args * uap)3198643ee871SKonstantin Belousov freebsd32_ktimer_gettime(struct thread *td,
3199643ee871SKonstantin Belousov struct freebsd32_ktimer_gettime_args *uap)
3200643ee871SKonstantin Belousov {
3201643ee871SKonstantin Belousov struct itimerspec32 val32;
3202643ee871SKonstantin Belousov struct itimerspec val;
3203643ee871SKonstantin Belousov int error;
3204643ee871SKonstantin Belousov
3205643ee871SKonstantin Belousov error = kern_ktimer_gettime(td, uap->timerid, &val);
3206643ee871SKonstantin Belousov if (error == 0) {
3207643ee871SKonstantin Belousov ITS_CP(val, val32);
3208643ee871SKonstantin Belousov error = copyout(&val32, uap->value, sizeof(val32));
3209643ee871SKonstantin Belousov }
3210643ee871SKonstantin Belousov return (error);
3211643ee871SKonstantin Belousov }
3212643ee871SKonstantin Belousov
3213cda9a0d1SDavid Xu int
freebsd32_timerfd_gettime(struct thread * td,struct freebsd32_timerfd_gettime_args * uap)3214918966a2SJake Freeland freebsd32_timerfd_gettime(struct thread *td,
3215918966a2SJake Freeland struct freebsd32_timerfd_gettime_args *uap)
3216918966a2SJake Freeland {
3217918966a2SJake Freeland struct itimerspec curr_value;
3218918966a2SJake Freeland struct itimerspec32 curr_value32;
3219918966a2SJake Freeland int error;
3220918966a2SJake Freeland
3221918966a2SJake Freeland error = kern_timerfd_gettime(td, uap->fd, &curr_value);
3222918966a2SJake Freeland if (error == 0) {
3223918966a2SJake Freeland CP(curr_value, curr_value32, it_value.tv_sec);
3224918966a2SJake Freeland CP(curr_value, curr_value32, it_value.tv_nsec);
3225918966a2SJake Freeland CP(curr_value, curr_value32, it_interval.tv_sec);
3226918966a2SJake Freeland CP(curr_value, curr_value32, it_interval.tv_nsec);
3227918966a2SJake Freeland error = copyout(&curr_value32, uap->curr_value,
3228918966a2SJake Freeland sizeof(curr_value32));
3229918966a2SJake Freeland }
3230918966a2SJake Freeland
3231918966a2SJake Freeland return (error);
3232918966a2SJake Freeland }
3233918966a2SJake Freeland
3234918966a2SJake Freeland int
freebsd32_timerfd_settime(struct thread * td,struct freebsd32_timerfd_settime_args * uap)3235918966a2SJake Freeland freebsd32_timerfd_settime(struct thread *td,
3236918966a2SJake Freeland struct freebsd32_timerfd_settime_args *uap)
3237918966a2SJake Freeland {
3238918966a2SJake Freeland struct itimerspec new_value, old_value;
3239918966a2SJake Freeland struct itimerspec32 new_value32, old_value32;
3240918966a2SJake Freeland int error;
3241918966a2SJake Freeland
3242918966a2SJake Freeland error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
3243918966a2SJake Freeland if (error != 0)
3244918966a2SJake Freeland return (error);
3245918966a2SJake Freeland CP(new_value32, new_value, it_value.tv_sec);
3246918966a2SJake Freeland CP(new_value32, new_value, it_value.tv_nsec);
3247918966a2SJake Freeland CP(new_value32, new_value, it_interval.tv_sec);
3248918966a2SJake Freeland CP(new_value32, new_value, it_interval.tv_nsec);
3249918966a2SJake Freeland if (uap->old_value == NULL) {
3250918966a2SJake Freeland error = kern_timerfd_settime(td, uap->fd, uap->flags,
3251918966a2SJake Freeland &new_value, NULL);
3252918966a2SJake Freeland } else {
3253918966a2SJake Freeland error = kern_timerfd_settime(td, uap->fd, uap->flags,
3254918966a2SJake Freeland &new_value, &old_value);
3255918966a2SJake Freeland if (error == 0) {
3256918966a2SJake Freeland CP(old_value, old_value32, it_value.tv_sec);
3257918966a2SJake Freeland CP(old_value, old_value32, it_value.tv_nsec);
3258918966a2SJake Freeland CP(old_value, old_value32, it_interval.tv_sec);
3259918966a2SJake Freeland CP(old_value, old_value32, it_interval.tv_nsec);
3260918966a2SJake Freeland error = copyout(&old_value32, uap->old_value,
3261918966a2SJake Freeland sizeof(old_value32));
3262918966a2SJake Freeland }
3263918966a2SJake Freeland }
3264918966a2SJake Freeland return (error);
3265918966a2SJake Freeland }
3266918966a2SJake Freeland
3267918966a2SJake Freeland int
freebsd32_clock_getcpuclockid2(struct thread * td,struct freebsd32_clock_getcpuclockid2_args * uap)3268d31e4b3aSKonstantin Belousov freebsd32_clock_getcpuclockid2(struct thread *td,
3269d31e4b3aSKonstantin Belousov struct freebsd32_clock_getcpuclockid2_args *uap)
3270d31e4b3aSKonstantin Belousov {
3271d31e4b3aSKonstantin Belousov clockid_t clk_id;
3272d31e4b3aSKonstantin Belousov int error;
3273d31e4b3aSKonstantin Belousov
3274d31e4b3aSKonstantin Belousov error = kern_clock_getcpuclockid2(td, PAIR32TO64(id_t, uap->id),
3275d31e4b3aSKonstantin Belousov uap->which, &clk_id);
3276d31e4b3aSKonstantin Belousov if (error == 0)
3277d31e4b3aSKonstantin Belousov error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
3278d31e4b3aSKonstantin Belousov return (error);
3279d31e4b3aSKonstantin Belousov }
3280d31e4b3aSKonstantin Belousov
3281d31e4b3aSKonstantin Belousov int
freebsd32_thr_new(struct thread * td,struct freebsd32_thr_new_args * uap)3282cda9a0d1SDavid Xu freebsd32_thr_new(struct thread *td,
3283cda9a0d1SDavid Xu struct freebsd32_thr_new_args *uap)
3284cda9a0d1SDavid Xu {
3285cda9a0d1SDavid Xu struct thr_param32 param32;
3286cda9a0d1SDavid Xu struct thr_param param;
3287cda9a0d1SDavid Xu int error;
3288cda9a0d1SDavid Xu
3289cda9a0d1SDavid Xu if (uap->param_size < 0 ||
3290cda9a0d1SDavid Xu uap->param_size > sizeof(struct thr_param32))
3291cda9a0d1SDavid Xu return (EINVAL);
3292cda9a0d1SDavid Xu bzero(¶m, sizeof(struct thr_param));
3293cda9a0d1SDavid Xu bzero(¶m32, sizeof(struct thr_param32));
3294cda9a0d1SDavid Xu error = copyin(uap->param, ¶m32, uap->param_size);
3295cda9a0d1SDavid Xu if (error != 0)
3296cda9a0d1SDavid Xu return (error);
3297cda9a0d1SDavid Xu param.start_func = PTRIN(param32.start_func);
3298cda9a0d1SDavid Xu param.arg = PTRIN(param32.arg);
3299cda9a0d1SDavid Xu param.stack_base = PTRIN(param32.stack_base);
3300cda9a0d1SDavid Xu param.stack_size = param32.stack_size;
3301cda9a0d1SDavid Xu param.tls_base = PTRIN(param32.tls_base);
3302cda9a0d1SDavid Xu param.tls_size = param32.tls_size;
3303cda9a0d1SDavid Xu param.child_tid = PTRIN(param32.child_tid);
3304cda9a0d1SDavid Xu param.parent_tid = PTRIN(param32.parent_tid);
3305cda9a0d1SDavid Xu param.flags = param32.flags;
3306cda9a0d1SDavid Xu param.rtp = PTRIN(param32.rtp);
3307cda9a0d1SDavid Xu param.spare[0] = PTRIN(param32.spare[0]);
3308cda9a0d1SDavid Xu param.spare[1] = PTRIN(param32.spare[1]);
3309cda9a0d1SDavid Xu param.spare[2] = PTRIN(param32.spare[2]);
3310cda9a0d1SDavid Xu
3311cda9a0d1SDavid Xu return (kern_thr_new(td, ¶m));
3312cda9a0d1SDavid Xu }
3313cda9a0d1SDavid Xu
3314cda9a0d1SDavid Xu int
freebsd32_thr_suspend(struct thread * td,struct freebsd32_thr_suspend_args * uap)3315cda9a0d1SDavid Xu freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
3316cda9a0d1SDavid Xu {
3317cda9a0d1SDavid Xu struct timespec32 ts32;
3318cda9a0d1SDavid Xu struct timespec ts, *tsp;
3319cda9a0d1SDavid Xu int error;
3320cda9a0d1SDavid Xu
3321cda9a0d1SDavid Xu error = 0;
3322cda9a0d1SDavid Xu tsp = NULL;
3323cda9a0d1SDavid Xu if (uap->timeout != NULL) {
3324cda9a0d1SDavid Xu error = copyin((const void *)uap->timeout, (void *)&ts32,
3325cda9a0d1SDavid Xu sizeof(struct timespec32));
3326cda9a0d1SDavid Xu if (error != 0)
3327cda9a0d1SDavid Xu return (error);
3328cda9a0d1SDavid Xu ts.tv_sec = ts32.tv_sec;
3329cda9a0d1SDavid Xu ts.tv_nsec = ts32.tv_nsec;
3330cda9a0d1SDavid Xu tsp = &ts;
3331cda9a0d1SDavid Xu }
3332cda9a0d1SDavid Xu return (kern_thr_suspend(td, tsp));
3333cda9a0d1SDavid Xu }
3334cda9a0d1SDavid Xu
3335c6511aeaSDavid Xu void
siginfo_to_siginfo32(const siginfo_t * src,struct __siginfo32 * dst)3336d060b420SBrooks Davis siginfo_to_siginfo32(const siginfo_t *src, struct __siginfo32 *dst)
3337c6511aeaSDavid Xu {
3338c6511aeaSDavid Xu bzero(dst, sizeof(*dst));
3339c6511aeaSDavid Xu dst->si_signo = src->si_signo;
3340c6511aeaSDavid Xu dst->si_errno = src->si_errno;
3341c6511aeaSDavid Xu dst->si_code = src->si_code;
3342c6511aeaSDavid Xu dst->si_pid = src->si_pid;
3343c6511aeaSDavid Xu dst->si_uid = src->si_uid;
3344c6511aeaSDavid Xu dst->si_status = src->si_status;
3345dc5aaa84SPeter Wemm dst->si_addr = (uintptr_t)src->si_addr;
3346df4d0ed1SKonstantin Belousov dst->si_value.sival_int = src->si_value.sival_int;
3347c6511aeaSDavid Xu dst->si_timerid = src->si_timerid;
3348c6511aeaSDavid Xu dst->si_overrun = src->si_overrun;
3349c6511aeaSDavid Xu }
3350c6511aeaSDavid Xu
3351f19351aaSBrooks Davis #ifndef _FREEBSD32_SYSPROTO_H_
3352f19351aaSBrooks Davis struct freebsd32_sigqueue_args {
3353f19351aaSBrooks Davis pid_t pid;
3354f19351aaSBrooks Davis int signum;
3355f19351aaSBrooks Davis /* union sigval32 */ int value;
3356f19351aaSBrooks Davis };
3357f19351aaSBrooks Davis #endif
3358f19351aaSBrooks Davis int
freebsd32_sigqueue(struct thread * td,struct freebsd32_sigqueue_args * uap)3359f19351aaSBrooks Davis freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap)
3360f19351aaSBrooks Davis {
3361f19351aaSBrooks Davis union sigval sv;
3362f19351aaSBrooks Davis
3363f19351aaSBrooks Davis /*
3364f19351aaSBrooks Davis * On 32-bit ABIs, sival_int and sival_ptr are the same.
3365f19351aaSBrooks Davis * On 64-bit little-endian ABIs, the low bits are the same.
3366f19351aaSBrooks Davis * In 64-bit big-endian ABIs, sival_int overlaps with
3367f19351aaSBrooks Davis * sival_ptr's HIGH bits. We choose to support sival_int
3368f19351aaSBrooks Davis * rather than sival_ptr in this case as it seems to be
3369f19351aaSBrooks Davis * more common.
3370f19351aaSBrooks Davis */
3371f19351aaSBrooks Davis bzero(&sv, sizeof(sv));
3372158dcd73SBrooks Davis sv.sival_int = (uint32_t)(uint64_t)uap->value;
3373f19351aaSBrooks Davis
3374f19351aaSBrooks Davis return (kern_sigqueue(td, uap->pid, uap->signum, &sv));
3375f19351aaSBrooks Davis }
3376f19351aaSBrooks Davis
3377c6511aeaSDavid Xu int
freebsd32_sigtimedwait(struct thread * td,struct freebsd32_sigtimedwait_args * uap)3378c6511aeaSDavid Xu freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
3379c6511aeaSDavid Xu {
3380c6511aeaSDavid Xu struct timespec32 ts32;
3381c6511aeaSDavid Xu struct timespec ts;
3382c6511aeaSDavid Xu struct timespec *timeout;
3383c6511aeaSDavid Xu sigset_t set;
3384c6511aeaSDavid Xu ksiginfo_t ksi;
3385d060b420SBrooks Davis struct __siginfo32 si32;
3386c6511aeaSDavid Xu int error;
3387c6511aeaSDavid Xu
3388c6511aeaSDavid Xu if (uap->timeout) {
3389c6511aeaSDavid Xu error = copyin(uap->timeout, &ts32, sizeof(ts32));
3390c6511aeaSDavid Xu if (error)
3391c6511aeaSDavid Xu return (error);
3392c6511aeaSDavid Xu ts.tv_sec = ts32.tv_sec;
3393c6511aeaSDavid Xu ts.tv_nsec = ts32.tv_nsec;
3394c6511aeaSDavid Xu timeout = &ts;
3395c6511aeaSDavid Xu } else
3396c6511aeaSDavid Xu timeout = NULL;
3397c6511aeaSDavid Xu
3398c6511aeaSDavid Xu error = copyin(uap->set, &set, sizeof(set));
3399c6511aeaSDavid Xu if (error)
3400c6511aeaSDavid Xu return (error);
3401c6511aeaSDavid Xu
3402c6511aeaSDavid Xu error = kern_sigtimedwait(td, set, &ksi, timeout);
3403c6511aeaSDavid Xu if (error)
3404c6511aeaSDavid Xu return (error);
3405c6511aeaSDavid Xu
3406c6511aeaSDavid Xu if (uap->info) {
3407c6511aeaSDavid Xu siginfo_to_siginfo32(&ksi.ksi_info, &si32);
3408d060b420SBrooks Davis error = copyout(&si32, uap->info, sizeof(struct __siginfo32));
3409c6511aeaSDavid Xu }
3410c6511aeaSDavid Xu
3411c6511aeaSDavid Xu if (error == 0)
3412c6511aeaSDavid Xu td->td_retval[0] = ksi.ksi_signo;
3413c6511aeaSDavid Xu return (error);
3414c6511aeaSDavid Xu }
3415c6511aeaSDavid Xu
3416c6511aeaSDavid Xu /*
3417c6511aeaSDavid Xu * MPSAFE
3418c6511aeaSDavid Xu */
3419c6511aeaSDavid Xu int
freebsd32_sigwaitinfo(struct thread * td,struct freebsd32_sigwaitinfo_args * uap)3420c6511aeaSDavid Xu freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
3421c6511aeaSDavid Xu {
3422c6511aeaSDavid Xu ksiginfo_t ksi;
3423d060b420SBrooks Davis struct __siginfo32 si32;
3424c6511aeaSDavid Xu sigset_t set;
3425c6511aeaSDavid Xu int error;
3426c6511aeaSDavid Xu
3427c6511aeaSDavid Xu error = copyin(uap->set, &set, sizeof(set));
3428c6511aeaSDavid Xu if (error)
3429c6511aeaSDavid Xu return (error);
3430c6511aeaSDavid Xu
3431c6511aeaSDavid Xu error = kern_sigtimedwait(td, set, &ksi, NULL);
3432c6511aeaSDavid Xu if (error)
3433c6511aeaSDavid Xu return (error);
3434c6511aeaSDavid Xu
3435c6511aeaSDavid Xu if (uap->info) {
3436c6511aeaSDavid Xu siginfo_to_siginfo32(&ksi.ksi_info, &si32);
3437d060b420SBrooks Davis error = copyout(&si32, uap->info, sizeof(struct __siginfo32));
3438c6511aeaSDavid Xu }
3439c6511aeaSDavid Xu if (error == 0)
3440c6511aeaSDavid Xu td->td_retval[0] = ksi.ksi_signo;
3441c6511aeaSDavid Xu return (error);
3442c6511aeaSDavid Xu }
3443c6511aeaSDavid Xu
3444a8c6d6d0SBrooks Davis int
freebsd32_cpuset_setid(struct thread * td,struct freebsd32_cpuset_setid_args * uap)3445a8c6d6d0SBrooks Davis freebsd32_cpuset_setid(struct thread *td,
3446a8c6d6d0SBrooks Davis struct freebsd32_cpuset_setid_args *uap)
3447a8c6d6d0SBrooks Davis {
3448a8c6d6d0SBrooks Davis
3449ea2ebdc1SEdward Tomasz Napierala return (kern_cpuset_setid(td, uap->which,
3450ea2ebdc1SEdward Tomasz Napierala PAIR32TO64(id_t, uap->id), uap->setid));
3451a8c6d6d0SBrooks Davis }
3452a8c6d6d0SBrooks Davis
3453a8c6d6d0SBrooks Davis int
freebsd32_cpuset_getid(struct thread * td,struct freebsd32_cpuset_getid_args * uap)3454a8c6d6d0SBrooks Davis freebsd32_cpuset_getid(struct thread *td,
3455a8c6d6d0SBrooks Davis struct freebsd32_cpuset_getid_args *uap)
3456a8c6d6d0SBrooks Davis {
3457a8c6d6d0SBrooks Davis
3458ea2ebdc1SEdward Tomasz Napierala return (kern_cpuset_getid(td, uap->level, uap->which,
3459ea2ebdc1SEdward Tomasz Napierala PAIR32TO64(id_t, uap->id), uap->setid));
3460a8c6d6d0SBrooks Davis }
3461a8c6d6d0SBrooks Davis
346247a57144SJustin Hibbits static int
copyin32_set(const void * u,void * k,size_t size)346347a57144SJustin Hibbits copyin32_set(const void *u, void *k, size_t size)
346447a57144SJustin Hibbits {
346547a57144SJustin Hibbits #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
346647a57144SJustin Hibbits int rv;
346747a57144SJustin Hibbits struct bitset *kb = k;
346847a57144SJustin Hibbits int *p;
346947a57144SJustin Hibbits
347047a57144SJustin Hibbits rv = copyin(u, k, size);
347147a57144SJustin Hibbits if (rv != 0)
347247a57144SJustin Hibbits return (rv);
347347a57144SJustin Hibbits
347447a57144SJustin Hibbits p = (int *)kb->__bits;
347547a57144SJustin Hibbits /* Loop through swapping words.
347647a57144SJustin Hibbits * `size' is in bytes, we need bits. */
347747a57144SJustin Hibbits for (int i = 0; i < __bitset_words(size * 8); i++) {
347847a57144SJustin Hibbits int tmp = p[0];
347947a57144SJustin Hibbits p[0] = p[1];
348047a57144SJustin Hibbits p[1] = tmp;
348147a57144SJustin Hibbits p += 2;
348247a57144SJustin Hibbits }
348347a57144SJustin Hibbits return (0);
348447a57144SJustin Hibbits #else
348547a57144SJustin Hibbits return (copyin(u, k, size));
348647a57144SJustin Hibbits #endif
348747a57144SJustin Hibbits }
348847a57144SJustin Hibbits
348947a57144SJustin Hibbits static int
copyout32_set(const void * k,void * u,size_t size)349047a57144SJustin Hibbits copyout32_set(const void *k, void *u, size_t size)
349147a57144SJustin Hibbits {
349247a57144SJustin Hibbits #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
349347a57144SJustin Hibbits const struct bitset *kb = k;
349447a57144SJustin Hibbits struct bitset *ub = u;
349547a57144SJustin Hibbits const int *kp = (const int *)kb->__bits;
349647a57144SJustin Hibbits int *up = (int *)ub->__bits;
349747a57144SJustin Hibbits int rv;
349847a57144SJustin Hibbits
349947a57144SJustin Hibbits for (int i = 0; i < __bitset_words(CPU_SETSIZE); i++) {
350047a57144SJustin Hibbits /* `size' is in bytes, we need bits. */
350147a57144SJustin Hibbits for (int i = 0; i < __bitset_words(size * 8); i++) {
350247a57144SJustin Hibbits rv = suword32(up, kp[1]);
350347a57144SJustin Hibbits if (rv == 0)
350447a57144SJustin Hibbits rv = suword32(up + 1, kp[0]);
350547a57144SJustin Hibbits if (rv != 0)
350647a57144SJustin Hibbits return (EFAULT);
350747a57144SJustin Hibbits }
350847a57144SJustin Hibbits }
350947a57144SJustin Hibbits return (0);
351047a57144SJustin Hibbits #else
351147a57144SJustin Hibbits return (copyout(k, u, size));
351247a57144SJustin Hibbits #endif
351347a57144SJustin Hibbits }
351447a57144SJustin Hibbits
351547a57144SJustin Hibbits static const struct cpuset_copy_cb cpuset_copy32_cb = {
35164a3e5133SMark Johnston .cpuset_copyin = copyin32_set,
35174a3e5133SMark Johnston .cpuset_copyout = copyout32_set
351847a57144SJustin Hibbits };
351947a57144SJustin Hibbits
3520a8c6d6d0SBrooks Davis int
freebsd32_cpuset_getaffinity(struct thread * td,struct freebsd32_cpuset_getaffinity_args * uap)3521a8c6d6d0SBrooks Davis freebsd32_cpuset_getaffinity(struct thread *td,
3522a8c6d6d0SBrooks Davis struct freebsd32_cpuset_getaffinity_args *uap)
3523a8c6d6d0SBrooks Davis {
3524a8c6d6d0SBrooks Davis
3525d46174cdSDmitry Chagin return (user_cpuset_getaffinity(td, uap->level, uap->which,
352647a57144SJustin Hibbits PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask,
352747a57144SJustin Hibbits &cpuset_copy32_cb));
3528a8c6d6d0SBrooks Davis }
3529a8c6d6d0SBrooks Davis
3530a8c6d6d0SBrooks Davis int
freebsd32_cpuset_setaffinity(struct thread * td,struct freebsd32_cpuset_setaffinity_args * uap)3531a8c6d6d0SBrooks Davis freebsd32_cpuset_setaffinity(struct thread *td,
3532a8c6d6d0SBrooks Davis struct freebsd32_cpuset_setaffinity_args *uap)
3533a8c6d6d0SBrooks Davis {
3534a8c6d6d0SBrooks Davis
3535f35093f8SDmitry Chagin return (user_cpuset_setaffinity(td, uap->level, uap->which,
353647a57144SJustin Hibbits PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask,
353747a57144SJustin Hibbits &cpuset_copy32_cb));
3538a8c6d6d0SBrooks Davis }
3539a8c6d6d0SBrooks Davis
35406e6049e9SDavid E. O'Brien int
freebsd32_cpuset_getdomain(struct thread * td,struct freebsd32_cpuset_getdomain_args * uap)35413f289c3fSJeff Roberson freebsd32_cpuset_getdomain(struct thread *td,
35423f289c3fSJeff Roberson struct freebsd32_cpuset_getdomain_args *uap)
35433f289c3fSJeff Roberson {
35443f289c3fSJeff Roberson
35453f289c3fSJeff Roberson return (kern_cpuset_getdomain(td, uap->level, uap->which,
354647a57144SJustin Hibbits PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy,
354747a57144SJustin Hibbits &cpuset_copy32_cb));
35483f289c3fSJeff Roberson }
35493f289c3fSJeff Roberson
35503f289c3fSJeff Roberson int
freebsd32_cpuset_setdomain(struct thread * td,struct freebsd32_cpuset_setdomain_args * uap)35513f289c3fSJeff Roberson freebsd32_cpuset_setdomain(struct thread *td,
35523f289c3fSJeff Roberson struct freebsd32_cpuset_setdomain_args *uap)
35533f289c3fSJeff Roberson {
35543f289c3fSJeff Roberson
35553f289c3fSJeff Roberson return (kern_cpuset_setdomain(td, uap->level, uap->which,
355647a57144SJustin Hibbits PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy,
355747a57144SJustin Hibbits &cpuset_copy32_cb));
35583f289c3fSJeff Roberson }
35593f289c3fSJeff Roberson
35603f289c3fSJeff Roberson int
freebsd32_nmount(struct thread * td,struct freebsd32_nmount_args * uap)35616e6049e9SDavid E. O'Brien freebsd32_nmount(struct thread *td,
35626e6049e9SDavid E. O'Brien struct freebsd32_nmount_args /* {
35636e6049e9SDavid E. O'Brien struct iovec *iovp;
35646e6049e9SDavid E. O'Brien unsigned int iovcnt;
35656e6049e9SDavid E. O'Brien int flags;
35666e6049e9SDavid E. O'Brien } */ *uap)
35676e6049e9SDavid E. O'Brien {
35686e6049e9SDavid E. O'Brien struct uio *auio;
3569cc672d35SKirk McKusick uint64_t flags;
3570f86bce5eSJamie Gritton int error;
35713ebc1248SPeter Wemm
3572cc672d35SKirk McKusick /*
3573cc672d35SKirk McKusick * Mount flags are now 64-bits. On 32-bit archtectures only
3574cc672d35SKirk McKusick * 32-bits are passed in, but from here on everything handles
3575cc672d35SKirk McKusick * 64-bit flags correctly.
3576cc672d35SKirk McKusick */
3577cc672d35SKirk McKusick flags = uap->flags;
3578cc672d35SKirk McKusick
3579cc672d35SKirk McKusick AUDIT_ARG_FFLAGS(flags);
35806e6049e9SDavid E. O'Brien
35816e6049e9SDavid E. O'Brien /*
35826e6049e9SDavid E. O'Brien * Filter out MNT_ROOTFS. We do not want clients of nmount() in
35836e6049e9SDavid E. O'Brien * userspace to set this flag, but we must filter it out if we want
35846e6049e9SDavid E. O'Brien * MNT_UPDATE on the root file system to work.
3585f03749caSSergey Kandaurov * MNT_ROOTFS should only be set by the kernel when mounting its
3586f03749caSSergey Kandaurov * root file system.
35876e6049e9SDavid E. O'Brien */
3588cc672d35SKirk McKusick flags &= ~MNT_ROOTFS;
35896e6049e9SDavid E. O'Brien
35906e6049e9SDavid E. O'Brien /*
35916e6049e9SDavid E. O'Brien * check that we have an even number of iovec's
35926e6049e9SDavid E. O'Brien * and that we have at least two options.
35936e6049e9SDavid E. O'Brien */
35946e6049e9SDavid E. O'Brien if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
35956e6049e9SDavid E. O'Brien return (EINVAL);
35966e6049e9SDavid E. O'Brien
35976e6049e9SDavid E. O'Brien error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
35986e6049e9SDavid E. O'Brien if (error)
35996e6049e9SDavid E. O'Brien return (error);
3600cc672d35SKirk McKusick error = vfs_donmount(td, flags, auio);
3601f86bce5eSJamie Gritton
360261cc4830SAlfredo Mazzinghi freeuio(auio);
36036e6049e9SDavid E. O'Brien return error;
36046e6049e9SDavid E. O'Brien }
36056e6049e9SDavid E. O'Brien
36066e6049e9SDavid E. O'Brien #if 0
36073ebc1248SPeter Wemm int
36081c7abef7SPeter Wemm freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
36093ebc1248SPeter Wemm {
36103ebc1248SPeter Wemm struct yyy32 *p32, s32;
36113ebc1248SPeter Wemm struct yyy *p = NULL, s;
3612109ea24cSDavid E. O'Brien struct xxx_arg ap;
3613109ea24cSDavid E. O'Brien int error;
36143ebc1248SPeter Wemm
361519042f9cSJohn Baldwin if (uap->zzz) {
361619042f9cSJohn Baldwin error = copyin(uap->zzz, &s32, sizeof(s32));
36173ebc1248SPeter Wemm if (error)
36183ebc1248SPeter Wemm return (error);
36193ebc1248SPeter Wemm /* translate in */
362019042f9cSJohn Baldwin p = &s;
36213ebc1248SPeter Wemm }
362219042f9cSJohn Baldwin error = kern_xxx(td, p);
36233ebc1248SPeter Wemm if (error)
36243ebc1248SPeter Wemm return (error);
362519042f9cSJohn Baldwin if (uap->zzz) {
36263ebc1248SPeter Wemm /* translate out */
36273ebc1248SPeter Wemm error = copyout(&s32, p32, sizeof(s32));
36283ebc1248SPeter Wemm }
36293ebc1248SPeter Wemm return (error);
36303ebc1248SPeter Wemm }
36313ebc1248SPeter Wemm #endif
363288ac915aSJohn Baldwin
363388ac915aSJohn Baldwin int
syscall32_module_handler(struct module * mod,int what,void * arg)363488ac915aSJohn Baldwin syscall32_module_handler(struct module *mod, int what, void *arg)
363588ac915aSJohn Baldwin {
363688ac915aSJohn Baldwin
3637b81e88d2SBrooks Davis return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg));
363888ac915aSJohn Baldwin }
3639841c0c7eSNathan Whitehorn
36400687ba3eSKonstantin Belousov int
syscall32_helper_register(struct syscall_helper_data * sd,int flags)3641e015b1abSMateusz Guzik syscall32_helper_register(struct syscall_helper_data *sd, int flags)
36420687ba3eSKonstantin Belousov {
36430687ba3eSKonstantin Belousov
3644b81e88d2SBrooks Davis return (kern_syscall_helper_register(freebsd32_sysent, sd, flags));
36450687ba3eSKonstantin Belousov }
36460687ba3eSKonstantin Belousov
36470687ba3eSKonstantin Belousov int
syscall32_helper_unregister(struct syscall_helper_data * sd)36480687ba3eSKonstantin Belousov syscall32_helper_unregister(struct syscall_helper_data *sd)
36490687ba3eSKonstantin Belousov {
36500687ba3eSKonstantin Belousov
3651b81e88d2SBrooks Davis return (kern_syscall_helper_unregister(freebsd32_sysent, sd));
36520687ba3eSKonstantin Belousov }
36530687ba3eSKonstantin Belousov
365403b0d68cSJohn Baldwin int
freebsd32_copyout_strings(struct image_params * imgp,uintptr_t * stack_base)365531174518SJohn Baldwin freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
3656841c0c7eSNathan Whitehorn {
3657f04a0960SMark Johnston struct sysentvec *sysent;
3658ee235befSKonstantin Belousov int argc, envc, i;
3659cc5aa0a4SJohn Baldwin uint32_t *vectp;
366088b124ceSKonstantin Belousov char *stringp;
366131174518SJohn Baldwin uintptr_t destp, ustringp;
3662841c0c7eSNathan Whitehorn struct freebsd32_ps_strings *arginfo;
3663ee235befSKonstantin Belousov char canary[sizeof(long) * 8];
3664ee235befSKonstantin Belousov int32_t pagesizes32[MAXPAGESIZES];
3665841c0c7eSNathan Whitehorn size_t execpath_len;
366603b0d68cSJohn Baldwin int error, szsigcode;
3667841c0c7eSNathan Whitehorn
3668f04a0960SMark Johnston sysent = imgp->sysent;
3669f04a0960SMark Johnston
3670706f4a81SMark Johnston arginfo = (struct freebsd32_ps_strings *)PROC_PS_STRINGS(imgp->proc);
3671397df744SBrooks Davis imgp->ps_strings = arginfo;
367288b124ceSKonstantin Belousov destp = (uintptr_t)arginfo;
3673841c0c7eSNathan Whitehorn
3674841c0c7eSNathan Whitehorn /*
3675f04a0960SMark Johnston * Install sigcode.
3676841c0c7eSNathan Whitehorn */
3677361971fbSKornel Dulęba if (!PROC_HAS_SHP(imgp->proc)) {
3678f04a0960SMark Johnston szsigcode = *sysent->sv_szsigcode;
367988b124ceSKonstantin Belousov destp -= szsigcode;
368088b124ceSKonstantin Belousov destp = rounddown2(destp, sizeof(uint32_t));
3681f04a0960SMark Johnston error = copyout(sysent->sv_sigcode, (void *)destp,
368288b124ceSKonstantin Belousov szsigcode);
368303b0d68cSJohn Baldwin if (error != 0)
368403b0d68cSJohn Baldwin return (error);
368588b124ceSKonstantin Belousov }
3686841c0c7eSNathan Whitehorn
3687841c0c7eSNathan Whitehorn /*
3688841c0c7eSNathan Whitehorn * Copy the image path for the rtld.
3689841c0c7eSNathan Whitehorn */
3690f04a0960SMark Johnston if (imgp->execpath != NULL && imgp->auxargs != NULL) {
3691f04a0960SMark Johnston execpath_len = strlen(imgp->execpath) + 1;
369288b124ceSKonstantin Belousov destp -= execpath_len;
3693b24e6ac8SBrooks Davis imgp->execpathp = (void *)destp;
3694b24e6ac8SBrooks Davis error = copyout(imgp->execpath, imgp->execpathp, execpath_len);
369503b0d68cSJohn Baldwin if (error != 0)
369603b0d68cSJohn Baldwin return (error);
3697841c0c7eSNathan Whitehorn }
3698841c0c7eSNathan Whitehorn
3699841c0c7eSNathan Whitehorn /*
3700ee235befSKonstantin Belousov * Prepare the canary for SSP.
3701ee235befSKonstantin Belousov */
3702ee235befSKonstantin Belousov arc4rand(canary, sizeof(canary), 0);
370388b124ceSKonstantin Belousov destp -= sizeof(canary);
3704b24e6ac8SBrooks Davis imgp->canary = (void *)destp;
3705b24e6ac8SBrooks Davis error = copyout(canary, imgp->canary, sizeof(canary));
370603b0d68cSJohn Baldwin if (error != 0)
370703b0d68cSJohn Baldwin return (error);
3708ee235befSKonstantin Belousov imgp->canarylen = sizeof(canary);
3709ee235befSKonstantin Belousov
3710ee235befSKonstantin Belousov /*
3711ee235befSKonstantin Belousov * Prepare the pagesizes array.
3712ee235befSKonstantin Belousov */
3713ee235befSKonstantin Belousov for (i = 0; i < MAXPAGESIZES; i++)
3714ee235befSKonstantin Belousov pagesizes32[i] = (uint32_t)pagesizes[i];
371588b124ceSKonstantin Belousov destp -= sizeof(pagesizes32);
371688b124ceSKonstantin Belousov destp = rounddown2(destp, sizeof(uint32_t));
3717b24e6ac8SBrooks Davis imgp->pagesizes = (void *)destp;
3718b24e6ac8SBrooks Davis error = copyout(pagesizes32, imgp->pagesizes, sizeof(pagesizes32));
371903b0d68cSJohn Baldwin if (error != 0)
372003b0d68cSJohn Baldwin return (error);
3721ee235befSKonstantin Belousov imgp->pagesizeslen = sizeof(pagesizes32);
3722ee235befSKonstantin Belousov
372331174518SJohn Baldwin /*
372431174518SJohn Baldwin * Allocate room for the argument and environment strings.
372531174518SJohn Baldwin */
372688b124ceSKonstantin Belousov destp -= ARG_MAX - imgp->args->stringspace;
372788b124ceSKonstantin Belousov destp = rounddown2(destp, sizeof(uint32_t));
372831174518SJohn Baldwin ustringp = destp;
372988b124ceSKonstantin Belousov
373003b0d68cSJohn Baldwin if (imgp->auxargs) {
3731d8010b11SJohn Baldwin /*
3732d8010b11SJohn Baldwin * Allocate room on the stack for the ELF auxargs
3733d8010b11SJohn Baldwin * array. It has up to AT_COUNT entries.
3734d8010b11SJohn Baldwin */
3735d8010b11SJohn Baldwin destp -= AT_COUNT * sizeof(Elf32_Auxinfo);
3736d8010b11SJohn Baldwin destp = rounddown2(destp, sizeof(uint32_t));
373703b0d68cSJohn Baldwin }
3738841c0c7eSNathan Whitehorn
373931174518SJohn Baldwin vectp = (uint32_t *)destp;
374031174518SJohn Baldwin
3741841c0c7eSNathan Whitehorn /*
374273c8686eSJohn Baldwin * Allocate room for the argv[] and env vectors including the
374373c8686eSJohn Baldwin * terminating NULL pointers.
374473c8686eSJohn Baldwin */
374573c8686eSJohn Baldwin vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
374673c8686eSJohn Baldwin
374773c8686eSJohn Baldwin /*
3748841c0c7eSNathan Whitehorn * vectp also becomes our initial stack base
3749841c0c7eSNathan Whitehorn */
375031174518SJohn Baldwin *stack_base = (uintptr_t)vectp;
3751841c0c7eSNathan Whitehorn
3752841c0c7eSNathan Whitehorn stringp = imgp->args->begin_argv;
3753841c0c7eSNathan Whitehorn argc = imgp->args->argc;
3754841c0c7eSNathan Whitehorn envc = imgp->args->envc;
3755841c0c7eSNathan Whitehorn /*
3756841c0c7eSNathan Whitehorn * Copy out strings - arguments and environment.
3757841c0c7eSNathan Whitehorn */
375831174518SJohn Baldwin error = copyout(stringp, (void *)ustringp,
375903b0d68cSJohn Baldwin ARG_MAX - imgp->args->stringspace);
376003b0d68cSJohn Baldwin if (error != 0)
376103b0d68cSJohn Baldwin return (error);
3762841c0c7eSNathan Whitehorn
3763841c0c7eSNathan Whitehorn /*
3764841c0c7eSNathan Whitehorn * Fill in "ps_strings" struct for ps, w, etc.
3765841c0c7eSNathan Whitehorn */
37669df1c38bSBrooks Davis imgp->argv = vectp;
3767cc5aa0a4SJohn Baldwin if (suword32(&arginfo->ps_argvstr, (uint32_t)(intptr_t)vectp) != 0 ||
376803b0d68cSJohn Baldwin suword32(&arginfo->ps_nargvstr, argc) != 0)
376903b0d68cSJohn Baldwin return (EFAULT);
3770841c0c7eSNathan Whitehorn
3771841c0c7eSNathan Whitehorn /*
3772841c0c7eSNathan Whitehorn * Fill in argument portion of vector table.
3773841c0c7eSNathan Whitehorn */
3774841c0c7eSNathan Whitehorn for (; argc > 0; --argc) {
377531174518SJohn Baldwin if (suword32(vectp++, ustringp) != 0)
377603b0d68cSJohn Baldwin return (EFAULT);
3777841c0c7eSNathan Whitehorn while (*stringp++ != 0)
377831174518SJohn Baldwin ustringp++;
377931174518SJohn Baldwin ustringp++;
3780841c0c7eSNathan Whitehorn }
3781841c0c7eSNathan Whitehorn
3782841c0c7eSNathan Whitehorn /* a null vector table pointer separates the argp's from the envp's */
378303b0d68cSJohn Baldwin if (suword32(vectp++, 0) != 0)
378403b0d68cSJohn Baldwin return (EFAULT);
3785841c0c7eSNathan Whitehorn
37869df1c38bSBrooks Davis imgp->envv = vectp;
3787cc5aa0a4SJohn Baldwin if (suword32(&arginfo->ps_envstr, (uint32_t)(intptr_t)vectp) != 0 ||
378803b0d68cSJohn Baldwin suword32(&arginfo->ps_nenvstr, envc) != 0)
378903b0d68cSJohn Baldwin return (EFAULT);
3790841c0c7eSNathan Whitehorn
3791841c0c7eSNathan Whitehorn /*
3792841c0c7eSNathan Whitehorn * Fill in environment portion of vector table.
3793841c0c7eSNathan Whitehorn */
3794841c0c7eSNathan Whitehorn for (; envc > 0; --envc) {
379531174518SJohn Baldwin if (suword32(vectp++, ustringp) != 0)
379603b0d68cSJohn Baldwin return (EFAULT);
3797841c0c7eSNathan Whitehorn while (*stringp++ != 0)
379831174518SJohn Baldwin ustringp++;
379931174518SJohn Baldwin ustringp++;
3800841c0c7eSNathan Whitehorn }
3801841c0c7eSNathan Whitehorn
3802841c0c7eSNathan Whitehorn /* end of vector table is a null pointer */
380303b0d68cSJohn Baldwin if (suword32(vectp, 0) != 0)
380403b0d68cSJohn Baldwin return (EFAULT);
3805841c0c7eSNathan Whitehorn
3806d8010b11SJohn Baldwin if (imgp->auxargs) {
3807d8010b11SJohn Baldwin vectp++;
3808d8010b11SJohn Baldwin error = imgp->sysent->sv_copyout_auxargs(imgp,
3809d8010b11SJohn Baldwin (uintptr_t)vectp);
3810d8010b11SJohn Baldwin if (error != 0)
3811d8010b11SJohn Baldwin return (error);
3812d8010b11SJohn Baldwin }
3813d8010b11SJohn Baldwin
381403b0d68cSJohn Baldwin return (0);
3815841c0c7eSNathan Whitehorn }
3816841c0c7eSNathan Whitehorn
381786665509SKonstantin Belousov int
freebsd32_kldstat(struct thread * td,struct freebsd32_kldstat_args * uap)381886665509SKonstantin Belousov freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
381986665509SKonstantin Belousov {
3820edb01d11SGordon Tetlow struct kld_file_stat *stat;
38215d0d6869SBrooks Davis struct kld_file_stat32 *stat32;
382286665509SKonstantin Belousov int error, version;
382386665509SKonstantin Belousov
382486665509SKonstantin Belousov if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
382586665509SKonstantin Belousov != 0)
382686665509SKonstantin Belousov return (error);
38275d0d6869SBrooks Davis if (version != sizeof(struct kld_file_stat_1_32) &&
38285d0d6869SBrooks Davis version != sizeof(struct kld_file_stat32))
382986665509SKonstantin Belousov return (EINVAL);
383086665509SKonstantin Belousov
3831edb01d11SGordon Tetlow stat = malloc(sizeof(*stat), M_TEMP, M_WAITOK | M_ZERO);
3832edb01d11SGordon Tetlow stat32 = malloc(sizeof(*stat32), M_TEMP, M_WAITOK | M_ZERO);
3833edb01d11SGordon Tetlow error = kern_kldstat(td, uap->fileid, stat);
3834edb01d11SGordon Tetlow if (error == 0) {
3835edb01d11SGordon Tetlow bcopy(&stat->name[0], &stat32->name[0], sizeof(stat->name));
3836edb01d11SGordon Tetlow CP(*stat, *stat32, refs);
3837edb01d11SGordon Tetlow CP(*stat, *stat32, id);
3838edb01d11SGordon Tetlow PTROUT_CP(*stat, *stat32, address);
3839edb01d11SGordon Tetlow CP(*stat, *stat32, size);
3840edb01d11SGordon Tetlow bcopy(&stat->pathname[0], &stat32->pathname[0],
3841edb01d11SGordon Tetlow sizeof(stat->pathname));
3842fb441a88SKonstantin Belousov stat32->version = version;
3843edb01d11SGordon Tetlow error = copyout(stat32, uap->stat, version);
3844edb01d11SGordon Tetlow }
3845edb01d11SGordon Tetlow free(stat, M_TEMP);
3846edb01d11SGordon Tetlow free(stat32, M_TEMP);
384786665509SKonstantin Belousov return (error);
384886665509SKonstantin Belousov }
3849d91f88f7SMatthew D Fleming
3850d91f88f7SMatthew D Fleming int
freebsd32_posix_fallocate(struct thread * td,struct freebsd32_posix_fallocate_args * uap)3851d91f88f7SMatthew D Fleming freebsd32_posix_fallocate(struct thread *td,
3852d91f88f7SMatthew D Fleming struct freebsd32_posix_fallocate_args *uap)
3853d91f88f7SMatthew D Fleming {
38540acf5d0bSMark Johnston int error;
3855d91f88f7SMatthew D Fleming
38560acf5d0bSMark Johnston error = kern_posix_fallocate(td, uap->fd,
38572852de04SKonstantin Belousov PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len));
38580acf5d0bSMark Johnston return (kern_posix_error(td, error));
3859d91f88f7SMatthew D Fleming }
3860936c09acSJohn Baldwin
3861936c09acSJohn Baldwin int
freebsd32_posix_fadvise(struct thread * td,struct freebsd32_posix_fadvise_args * uap)3862936c09acSJohn Baldwin freebsd32_posix_fadvise(struct thread *td,
3863936c09acSJohn Baldwin struct freebsd32_posix_fadvise_args *uap)
3864936c09acSJohn Baldwin {
38650acf5d0bSMark Johnston int error;
3866936c09acSJohn Baldwin
38670acf5d0bSMark Johnston error = kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
38680acf5d0bSMark Johnston PAIR32TO64(off_t, uap->len), uap->advice);
38690acf5d0bSMark Johnston return (kern_posix_error(td, error));
3870936c09acSJohn Baldwin }
387197319989SKonstantin Belousov
387297319989SKonstantin Belousov int
convert_sigevent32(struct sigevent32 * sig32,struct sigevent * sig)387397319989SKonstantin Belousov convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
387497319989SKonstantin Belousov {
387597319989SKonstantin Belousov
387697319989SKonstantin Belousov CP(*sig32, *sig, sigev_notify);
387797319989SKonstantin Belousov switch (sig->sigev_notify) {
387897319989SKonstantin Belousov case SIGEV_NONE:
387997319989SKonstantin Belousov break;
388097319989SKonstantin Belousov case SIGEV_THREAD_ID:
388197319989SKonstantin Belousov CP(*sig32, *sig, sigev_notify_thread_id);
388297319989SKonstantin Belousov /* FALLTHROUGH */
388397319989SKonstantin Belousov case SIGEV_SIGNAL:
388497319989SKonstantin Belousov CP(*sig32, *sig, sigev_signo);
388597319989SKonstantin Belousov PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
388697319989SKonstantin Belousov break;
388797319989SKonstantin Belousov case SIGEV_KEVENT:
388897319989SKonstantin Belousov CP(*sig32, *sig, sigev_notify_kqueue);
388997319989SKonstantin Belousov CP(*sig32, *sig, sigev_notify_kevent_flags);
389097319989SKonstantin Belousov PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
389197319989SKonstantin Belousov break;
389297319989SKonstantin Belousov default:
389397319989SKonstantin Belousov return (EINVAL);
389497319989SKonstantin Belousov }
389597319989SKonstantin Belousov return (0);
389697319989SKonstantin Belousov }
389755648840SJohn Baldwin
389855648840SJohn Baldwin int
freebsd32_procctl(struct thread * td,struct freebsd32_procctl_args * uap)389955648840SJohn Baldwin freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap)
390055648840SJohn Baldwin {
390155648840SJohn Baldwin void *data;
3902237623b0SKonstantin Belousov union {
3903237623b0SKonstantin Belousov struct procctl_reaper_status rs;
3904237623b0SKonstantin Belousov struct procctl_reaper_pids rp;
3905237623b0SKonstantin Belousov struct procctl_reaper_kill rk;
3906237623b0SKonstantin Belousov } x;
3907237623b0SKonstantin Belousov union {
3908237623b0SKonstantin Belousov struct procctl_reaper_pids32 rp;
3909237623b0SKonstantin Belousov } x32;
3910b9408863SKonstantin Belousov int error, error1, flags, signum;
391155648840SJohn Baldwin
3912fd8d844fSKonstantin Belousov if (uap->com >= PROC_PROCCTL_MD_MIN)
3913fd8d844fSKonstantin Belousov return (cpu_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
3914fd8d844fSKonstantin Belousov uap->com, PTRIN(uap->data)));
3915fd8d844fSKonstantin Belousov
391655648840SJohn Baldwin switch (uap->com) {
3917fa50a355SKonstantin Belousov case PROC_ASLR_CTL:
39185dc7e31aSKonstantin Belousov case PROC_PROTMAX_CTL:
391955648840SJohn Baldwin case PROC_SPROTECT:
3920fe69291fSKonstantin Belousov case PROC_STACKGAP_CTL:
3921677258f7SKonstantin Belousov case PROC_TRACE_CTL:
3922643f6f47SKonstantin Belousov case PROC_TRAPCAP_CTL:
3923db8d680eSEdward Tomasz Napierala case PROC_NO_NEW_PRIVS_CTL:
3924796a8e1aSKonstantin Belousov case PROC_WXMAP_CTL:
3925dabf006aSKyle Evans case PROC_LOGSIGEXIT_CTL:
392655648840SJohn Baldwin error = copyin(PTRIN(uap->data), &flags, sizeof(flags));
3927237623b0SKonstantin Belousov if (error != 0)
392855648840SJohn Baldwin return (error);
392955648840SJohn Baldwin data = &flags;
393055648840SJohn Baldwin break;
3931237623b0SKonstantin Belousov case PROC_REAP_ACQUIRE:
3932237623b0SKonstantin Belousov case PROC_REAP_RELEASE:
3933237623b0SKonstantin Belousov if (uap->data != NULL)
3934237623b0SKonstantin Belousov return (EINVAL);
3935237623b0SKonstantin Belousov data = NULL;
3936237623b0SKonstantin Belousov break;
3937237623b0SKonstantin Belousov case PROC_REAP_STATUS:
3938237623b0SKonstantin Belousov data = &x.rs;
3939237623b0SKonstantin Belousov break;
3940237623b0SKonstantin Belousov case PROC_REAP_GETPIDS:
3941237623b0SKonstantin Belousov error = copyin(uap->data, &x32.rp, sizeof(x32.rp));
3942237623b0SKonstantin Belousov if (error != 0)
3943237623b0SKonstantin Belousov return (error);
3944237623b0SKonstantin Belousov CP(x32.rp, x.rp, rp_count);
3945237623b0SKonstantin Belousov PTRIN_CP(x32.rp, x.rp, rp_pids);
3946237623b0SKonstantin Belousov data = &x.rp;
3947237623b0SKonstantin Belousov break;
3948237623b0SKonstantin Belousov case PROC_REAP_KILL:
3949237623b0SKonstantin Belousov error = copyin(uap->data, &x.rk, sizeof(x.rk));
3950237623b0SKonstantin Belousov if (error != 0)
3951237623b0SKonstantin Belousov return (error);
3952237623b0SKonstantin Belousov data = &x.rk;
3953237623b0SKonstantin Belousov break;
3954fa50a355SKonstantin Belousov case PROC_ASLR_STATUS:
39555dc7e31aSKonstantin Belousov case PROC_PROTMAX_STATUS:
3956fe69291fSKonstantin Belousov case PROC_STACKGAP_STATUS:
3957677258f7SKonstantin Belousov case PROC_TRACE_STATUS:
3958643f6f47SKonstantin Belousov case PROC_TRAPCAP_STATUS:
3959db8d680eSEdward Tomasz Napierala case PROC_NO_NEW_PRIVS_STATUS:
3960796a8e1aSKonstantin Belousov case PROC_WXMAP_STATUS:
3961dabf006aSKyle Evans case PROC_LOGSIGEXIT_STATUS:
3962677258f7SKonstantin Belousov data = &flags;
3963677258f7SKonstantin Belousov break;
39641302eea7SKonstantin Belousov case PROC_PDEATHSIG_CTL:
3965b9408863SKonstantin Belousov error = copyin(uap->data, &signum, sizeof(signum));
3966b9408863SKonstantin Belousov if (error != 0)
3967b9408863SKonstantin Belousov return (error);
3968b9408863SKonstantin Belousov data = &signum;
3969b9408863SKonstantin Belousov break;
39701302eea7SKonstantin Belousov case PROC_PDEATHSIG_STATUS:
3971b9408863SKonstantin Belousov data = &signum;
3972b9408863SKonstantin Belousov break;
397355648840SJohn Baldwin default:
397455648840SJohn Baldwin return (EINVAL);
397555648840SJohn Baldwin }
3976237623b0SKonstantin Belousov error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
3977237623b0SKonstantin Belousov uap->com, data);
3978237623b0SKonstantin Belousov switch (uap->com) {
3979237623b0SKonstantin Belousov case PROC_REAP_STATUS:
3980237623b0SKonstantin Belousov if (error == 0)
3981237623b0SKonstantin Belousov error = copyout(&x.rs, uap->data, sizeof(x.rs));
3982237623b0SKonstantin Belousov break;
3983237623b0SKonstantin Belousov case PROC_REAP_KILL:
3984237623b0SKonstantin Belousov error1 = copyout(&x.rk, uap->data, sizeof(x.rk));
3985237623b0SKonstantin Belousov if (error == 0)
3986237623b0SKonstantin Belousov error = error1;
3987237623b0SKonstantin Belousov break;
3988fa50a355SKonstantin Belousov case PROC_ASLR_STATUS:
39895dc7e31aSKonstantin Belousov case PROC_PROTMAX_STATUS:
3990fe69291fSKonstantin Belousov case PROC_STACKGAP_STATUS:
3991677258f7SKonstantin Belousov case PROC_TRACE_STATUS:
3992643f6f47SKonstantin Belousov case PROC_TRAPCAP_STATUS:
3993db8d680eSEdward Tomasz Napierala case PROC_NO_NEW_PRIVS_STATUS:
3994796a8e1aSKonstantin Belousov case PROC_WXMAP_STATUS:
3995dabf006aSKyle Evans case PROC_LOGSIGEXIT_STATUS:
3996677258f7SKonstantin Belousov if (error == 0)
3997677258f7SKonstantin Belousov error = copyout(&flags, uap->data, sizeof(flags));
3998677258f7SKonstantin Belousov break;
39991302eea7SKonstantin Belousov case PROC_PDEATHSIG_STATUS:
4000b9408863SKonstantin Belousov if (error == 0)
4001b9408863SKonstantin Belousov error = copyout(&signum, uap->data, sizeof(signum));
4002b9408863SKonstantin Belousov break;
4003237623b0SKonstantin Belousov }
4004237623b0SKonstantin Belousov return (error);
400555648840SJohn Baldwin }
40068fbeebf5SKonstantin Belousov
40078fbeebf5SKonstantin Belousov int
freebsd32_fcntl(struct thread * td,struct freebsd32_fcntl_args * uap)40088fbeebf5SKonstantin Belousov freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap)
40098fbeebf5SKonstantin Belousov {
4010d0efabdfSBrooks Davis intptr_t tmp;
40118fbeebf5SKonstantin Belousov
40128fbeebf5SKonstantin Belousov switch (uap->cmd) {
40138fbeebf5SKonstantin Belousov /*
40148fbeebf5SKonstantin Belousov * Do unsigned conversion for arg when operation
40158fbeebf5SKonstantin Belousov * interprets it as flags or pointer.
40168fbeebf5SKonstantin Belousov */
40178fbeebf5SKonstantin Belousov case F_SETLK_REMOTE:
40188fbeebf5SKonstantin Belousov case F_SETLKW:
40198fbeebf5SKonstantin Belousov case F_SETLK:
40208fbeebf5SKonstantin Belousov case F_GETLK:
40218fbeebf5SKonstantin Belousov case F_SETFD:
40228fbeebf5SKonstantin Belousov case F_SETFL:
4023b53fc49cSKonstantin Belousov case F_OGETLK:
4024b53fc49cSKonstantin Belousov case F_OSETLK:
4025b53fc49cSKonstantin Belousov case F_OSETLKW:
4026794d3e8eSKonstantin Belousov case F_KINFO:
40278fbeebf5SKonstantin Belousov tmp = (unsigned int)(uap->arg);
40288fbeebf5SKonstantin Belousov break;
40298fbeebf5SKonstantin Belousov default:
40308fbeebf5SKonstantin Belousov tmp = uap->arg;
40318fbeebf5SKonstantin Belousov break;
40328fbeebf5SKonstantin Belousov }
4033f69261f2SKonstantin Belousov return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
40348fbeebf5SKonstantin Belousov }
4035186d9c34SDmitry Chagin
4036186d9c34SDmitry Chagin int
freebsd32_ppoll(struct thread * td,struct freebsd32_ppoll_args * uap)4037186d9c34SDmitry Chagin freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap)
4038186d9c34SDmitry Chagin {
4039186d9c34SDmitry Chagin struct timespec32 ts32;
4040186d9c34SDmitry Chagin struct timespec ts, *tsp;
4041186d9c34SDmitry Chagin sigset_t set, *ssp;
4042186d9c34SDmitry Chagin int error;
4043186d9c34SDmitry Chagin
4044186d9c34SDmitry Chagin if (uap->ts != NULL) {
4045186d9c34SDmitry Chagin error = copyin(uap->ts, &ts32, sizeof(ts32));
4046186d9c34SDmitry Chagin if (error != 0)
4047186d9c34SDmitry Chagin return (error);
4048186d9c34SDmitry Chagin CP(ts32, ts, tv_sec);
4049186d9c34SDmitry Chagin CP(ts32, ts, tv_nsec);
4050186d9c34SDmitry Chagin tsp = &ts;
4051186d9c34SDmitry Chagin } else
4052186d9c34SDmitry Chagin tsp = NULL;
4053186d9c34SDmitry Chagin if (uap->set != NULL) {
4054186d9c34SDmitry Chagin error = copyin(uap->set, &set, sizeof(set));
4055186d9c34SDmitry Chagin if (error != 0)
4056186d9c34SDmitry Chagin return (error);
4057186d9c34SDmitry Chagin ssp = &set;
4058186d9c34SDmitry Chagin } else
4059186d9c34SDmitry Chagin ssp = NULL;
4060186d9c34SDmitry Chagin
4061186d9c34SDmitry Chagin return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
4062186d9c34SDmitry Chagin }
40633de1e9aaSKonstantin Belousov
40643de1e9aaSKonstantin Belousov int
freebsd32_sched_rr_get_interval(struct thread * td,struct freebsd32_sched_rr_get_interval_args * uap)40653de1e9aaSKonstantin Belousov freebsd32_sched_rr_get_interval(struct thread *td,
40663de1e9aaSKonstantin Belousov struct freebsd32_sched_rr_get_interval_args *uap)
40673de1e9aaSKonstantin Belousov {
40683de1e9aaSKonstantin Belousov struct timespec ts;
40693de1e9aaSKonstantin Belousov struct timespec32 ts32;
40703de1e9aaSKonstantin Belousov int error;
40713de1e9aaSKonstantin Belousov
40723de1e9aaSKonstantin Belousov error = kern_sched_rr_get_interval(td, uap->pid, &ts);
40733de1e9aaSKonstantin Belousov if (error == 0) {
40743de1e9aaSKonstantin Belousov CP(ts, ts32, tv_sec);
40753de1e9aaSKonstantin Belousov CP(ts, ts32, tv_nsec);
40763de1e9aaSKonstantin Belousov error = copyout(&ts32, uap->interval, sizeof(ts32));
40773de1e9aaSKonstantin Belousov }
40783de1e9aaSKonstantin Belousov return (error);
40793de1e9aaSKonstantin Belousov }
408031df9c26SKonstantin Belousov
408131df9c26SKonstantin Belousov static void
timex_to_32(struct timex32 * dst,struct timex * src)408231df9c26SKonstantin Belousov timex_to_32(struct timex32 *dst, struct timex *src)
408331df9c26SKonstantin Belousov {
408431df9c26SKonstantin Belousov CP(*src, *dst, modes);
408531df9c26SKonstantin Belousov CP(*src, *dst, offset);
408631df9c26SKonstantin Belousov CP(*src, *dst, freq);
408731df9c26SKonstantin Belousov CP(*src, *dst, maxerror);
408831df9c26SKonstantin Belousov CP(*src, *dst, esterror);
408931df9c26SKonstantin Belousov CP(*src, *dst, status);
409031df9c26SKonstantin Belousov CP(*src, *dst, constant);
409131df9c26SKonstantin Belousov CP(*src, *dst, precision);
409231df9c26SKonstantin Belousov CP(*src, *dst, tolerance);
409331df9c26SKonstantin Belousov CP(*src, *dst, ppsfreq);
409431df9c26SKonstantin Belousov CP(*src, *dst, jitter);
409531df9c26SKonstantin Belousov CP(*src, *dst, shift);
409631df9c26SKonstantin Belousov CP(*src, *dst, stabil);
409731df9c26SKonstantin Belousov CP(*src, *dst, jitcnt);
409831df9c26SKonstantin Belousov CP(*src, *dst, calcnt);
409931df9c26SKonstantin Belousov CP(*src, *dst, errcnt);
410031df9c26SKonstantin Belousov CP(*src, *dst, stbcnt);
410131df9c26SKonstantin Belousov }
410231df9c26SKonstantin Belousov
410331df9c26SKonstantin Belousov static void
timex_from_32(struct timex * dst,struct timex32 * src)410431df9c26SKonstantin Belousov timex_from_32(struct timex *dst, struct timex32 *src)
410531df9c26SKonstantin Belousov {
410631df9c26SKonstantin Belousov CP(*src, *dst, modes);
410731df9c26SKonstantin Belousov CP(*src, *dst, offset);
410831df9c26SKonstantin Belousov CP(*src, *dst, freq);
410931df9c26SKonstantin Belousov CP(*src, *dst, maxerror);
411031df9c26SKonstantin Belousov CP(*src, *dst, esterror);
411131df9c26SKonstantin Belousov CP(*src, *dst, status);
411231df9c26SKonstantin Belousov CP(*src, *dst, constant);
411331df9c26SKonstantin Belousov CP(*src, *dst, precision);
411431df9c26SKonstantin Belousov CP(*src, *dst, tolerance);
411531df9c26SKonstantin Belousov CP(*src, *dst, ppsfreq);
411631df9c26SKonstantin Belousov CP(*src, *dst, jitter);
411731df9c26SKonstantin Belousov CP(*src, *dst, shift);
411831df9c26SKonstantin Belousov CP(*src, *dst, stabil);
411931df9c26SKonstantin Belousov CP(*src, *dst, jitcnt);
412031df9c26SKonstantin Belousov CP(*src, *dst, calcnt);
412131df9c26SKonstantin Belousov CP(*src, *dst, errcnt);
412231df9c26SKonstantin Belousov CP(*src, *dst, stbcnt);
412331df9c26SKonstantin Belousov }
412431df9c26SKonstantin Belousov
412531df9c26SKonstantin Belousov int
freebsd32_ntp_adjtime(struct thread * td,struct freebsd32_ntp_adjtime_args * uap)412631df9c26SKonstantin Belousov freebsd32_ntp_adjtime(struct thread *td, struct freebsd32_ntp_adjtime_args *uap)
412731df9c26SKonstantin Belousov {
412831df9c26SKonstantin Belousov struct timex tx;
412931df9c26SKonstantin Belousov struct timex32 tx32;
413031df9c26SKonstantin Belousov int error, retval;
413131df9c26SKonstantin Belousov
413231df9c26SKonstantin Belousov error = copyin(uap->tp, &tx32, sizeof(tx32));
413331df9c26SKonstantin Belousov if (error == 0) {
413431df9c26SKonstantin Belousov timex_from_32(&tx, &tx32);
413531df9c26SKonstantin Belousov error = kern_ntp_adjtime(td, &tx, &retval);
413631df9c26SKonstantin Belousov if (error == 0) {
413731df9c26SKonstantin Belousov timex_to_32(&tx32, &tx);
413831df9c26SKonstantin Belousov error = copyout(&tx32, uap->tp, sizeof(tx32));
413931df9c26SKonstantin Belousov if (error == 0)
414031df9c26SKonstantin Belousov td->td_retval[0] = retval;
414131df9c26SKonstantin Belousov }
414231df9c26SKonstantin Belousov }
414331df9c26SKonstantin Belousov return (error);
414431df9c26SKonstantin Belousov }
41450dc332bfSKa Ho Ng
4146e3e811a3SBrooks Davis #ifdef FFCLOCK
4147e3e811a3SBrooks Davis extern struct mtx ffclock_mtx;
4148e3e811a3SBrooks Davis extern struct ffclock_estimate ffclock_estimate;
4149e3e811a3SBrooks Davis extern int8_t ffclock_updated;
4150e3e811a3SBrooks Davis
4151e3e811a3SBrooks Davis int
freebsd32_ffclock_setestimate(struct thread * td,struct freebsd32_ffclock_setestimate_args * uap)4152e3e811a3SBrooks Davis freebsd32_ffclock_setestimate(struct thread *td,
4153e3e811a3SBrooks Davis struct freebsd32_ffclock_setestimate_args *uap)
4154e3e811a3SBrooks Davis {
4155e3e811a3SBrooks Davis struct ffclock_estimate cest;
4156e3e811a3SBrooks Davis struct ffclock_estimate32 cest32;
4157e3e811a3SBrooks Davis int error;
4158e3e811a3SBrooks Davis
4159e3e811a3SBrooks Davis /* Reuse of PRIV_CLOCK_SETTIME. */
4160e3e811a3SBrooks Davis if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0)
4161e3e811a3SBrooks Davis return (error);
4162e3e811a3SBrooks Davis
4163e3e811a3SBrooks Davis if ((error = copyin(uap->cest, &cest32,
4164e3e811a3SBrooks Davis sizeof(struct ffclock_estimate32))) != 0)
4165e3e811a3SBrooks Davis return (error);
4166e3e811a3SBrooks Davis
4167e3e811a3SBrooks Davis CP(cest.update_time, cest32.update_time, sec);
4168e3e811a3SBrooks Davis memcpy(&cest.update_time.frac, &cest32.update_time.frac, sizeof(uint64_t));
4169e3e811a3SBrooks Davis CP(cest, cest32, update_ffcount);
4170e3e811a3SBrooks Davis CP(cest, cest32, leapsec_next);
4171e3e811a3SBrooks Davis CP(cest, cest32, period);
4172e3e811a3SBrooks Davis CP(cest, cest32, errb_abs);
4173e3e811a3SBrooks Davis CP(cest, cest32, errb_rate);
4174e3e811a3SBrooks Davis CP(cest, cest32, status);
4175e3e811a3SBrooks Davis CP(cest, cest32, leapsec_total);
4176e3e811a3SBrooks Davis CP(cest, cest32, leapsec);
4177e3e811a3SBrooks Davis
4178e3e811a3SBrooks Davis mtx_lock(&ffclock_mtx);
4179e3e811a3SBrooks Davis memcpy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate));
4180e3e811a3SBrooks Davis ffclock_updated++;
4181e3e811a3SBrooks Davis mtx_unlock(&ffclock_mtx);
4182e3e811a3SBrooks Davis return (error);
4183e3e811a3SBrooks Davis }
4184e3e811a3SBrooks Davis
4185e3e811a3SBrooks Davis int
freebsd32_ffclock_getestimate(struct thread * td,struct freebsd32_ffclock_getestimate_args * uap)4186e3e811a3SBrooks Davis freebsd32_ffclock_getestimate(struct thread *td,
4187e3e811a3SBrooks Davis struct freebsd32_ffclock_getestimate_args *uap)
4188e3e811a3SBrooks Davis {
4189e3e811a3SBrooks Davis struct ffclock_estimate cest;
4190e3e811a3SBrooks Davis struct ffclock_estimate32 cest32;
4191e3e811a3SBrooks Davis int error;
4192e3e811a3SBrooks Davis
4193e3e811a3SBrooks Davis mtx_lock(&ffclock_mtx);
4194e3e811a3SBrooks Davis memcpy(&cest, &ffclock_estimate, sizeof(struct ffclock_estimate));
4195e3e811a3SBrooks Davis mtx_unlock(&ffclock_mtx);
4196e3e811a3SBrooks Davis
4197e3e811a3SBrooks Davis CP(cest32.update_time, cest.update_time, sec);
4198e3e811a3SBrooks Davis memcpy(&cest32.update_time.frac, &cest.update_time.frac, sizeof(uint64_t));
4199e3e811a3SBrooks Davis CP(cest32, cest, update_ffcount);
4200e3e811a3SBrooks Davis CP(cest32, cest, leapsec_next);
4201e3e811a3SBrooks Davis CP(cest32, cest, period);
4202e3e811a3SBrooks Davis CP(cest32, cest, errb_abs);
4203e3e811a3SBrooks Davis CP(cest32, cest, errb_rate);
4204e3e811a3SBrooks Davis CP(cest32, cest, status);
4205e3e811a3SBrooks Davis CP(cest32, cest, leapsec_total);
4206e3e811a3SBrooks Davis CP(cest32, cest, leapsec);
4207e3e811a3SBrooks Davis
4208e3e811a3SBrooks Davis error = copyout(&cest32, uap->cest, sizeof(struct ffclock_estimate32));
4209e3e811a3SBrooks Davis return (error);
4210e3e811a3SBrooks Davis }
4211e3e811a3SBrooks Davis #else /* !FFCLOCK */
4212e3e811a3SBrooks Davis int
freebsd32_ffclock_setestimate(struct thread * td,struct freebsd32_ffclock_setestimate_args * uap)4213e3e811a3SBrooks Davis freebsd32_ffclock_setestimate(struct thread *td,
4214e3e811a3SBrooks Davis struct freebsd32_ffclock_setestimate_args *uap)
4215e3e811a3SBrooks Davis {
4216e3e811a3SBrooks Davis return (ENOSYS);
4217e3e811a3SBrooks Davis }
4218e3e811a3SBrooks Davis
4219e3e811a3SBrooks Davis int
freebsd32_ffclock_getestimate(struct thread * td,struct freebsd32_ffclock_getestimate_args * uap)4220e3e811a3SBrooks Davis freebsd32_ffclock_getestimate(struct thread *td,
4221e3e811a3SBrooks Davis struct freebsd32_ffclock_getestimate_args *uap)
4222e3e811a3SBrooks Davis {
4223e3e811a3SBrooks Davis return (ENOSYS);
4224e3e811a3SBrooks Davis }
4225e3e811a3SBrooks Davis #endif /* FFCLOCK */
4226e3e811a3SBrooks Davis
4227f19e3fd2SBrooks Davis #ifdef COMPAT_43
4228f19e3fd2SBrooks Davis int
ofreebsd32_sethostid(struct thread * td,struct ofreebsd32_sethostid_args * uap)4229f19e3fd2SBrooks Davis ofreebsd32_sethostid(struct thread *td, struct ofreebsd32_sethostid_args *uap)
4230f19e3fd2SBrooks Davis {
4231f19e3fd2SBrooks Davis int name[] = { CTL_KERN, KERN_HOSTID };
4232f19e3fd2SBrooks Davis long hostid;
4233f19e3fd2SBrooks Davis
4234f19e3fd2SBrooks Davis hostid = uap->hostid;
4235f19e3fd2SBrooks Davis return (kernel_sysctl(td, name, nitems(name), NULL, NULL, &hostid,
4236f19e3fd2SBrooks Davis sizeof(hostid), NULL, 0));
4237f19e3fd2SBrooks Davis }
4238f19e3fd2SBrooks Davis #endif
4239ddb3eb4eSOlivier Certner
4240ddb3eb4eSOlivier Certner int
freebsd32_setcred(struct thread * td,struct freebsd32_setcred_args * uap)4241ddb3eb4eSOlivier Certner freebsd32_setcred(struct thread *td, struct freebsd32_setcred_args *uap)
4242ddb3eb4eSOlivier Certner {
4243ddb3eb4eSOlivier Certner /* Last argument is 'is_32bit'. */
4244ddb3eb4eSOlivier Certner return (user_setcred(td, uap->flags, uap->wcred, uap->size, true));
4245ddb3eb4eSOlivier Certner }
4246