File: | compat/freebsd32/freebsd32_misc.c |
Warning: | line 2199, column 11 Copies out a struct with untouched element(s): , |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /*- | |||
2 | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||
3 | * | |||
4 | * Copyright (c) 2002 Doug Rabson | |||
5 | * All rights reserved. | |||
6 | * | |||
7 | * Redistribution and use in source and binary forms, with or without | |||
8 | * modification, are permitted provided that the following conditions | |||
9 | * are met: | |||
10 | * 1. Redistributions of source code must retain the above copyright | |||
11 | * notice, this list of conditions and the following disclaimer. | |||
12 | * 2. Redistributions in binary form must reproduce the above copyright | |||
13 | * notice, this list of conditions and the following disclaimer in the | |||
14 | * documentation and/or other materials provided with the distribution. | |||
15 | * | |||
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
26 | * SUCH DAMAGE. | |||
27 | */ | |||
28 | ||||
29 | #include <sys/cdefs.h> | |||
30 | __FBSDID("$FreeBSD$")__asm__(".ident\t\"" "$FreeBSD$" "\""); | |||
31 | ||||
32 | #include "opt_inet.h" | |||
33 | #include "opt_inet6.h" | |||
34 | #include "opt_ktrace.h" | |||
35 | ||||
36 | #define __ELF_WORD_SIZE32 32 | |||
37 | ||||
38 | #ifdef COMPAT_FREEBSD111 | |||
39 | #define _WANT_FREEBSD11_KEVENT | |||
40 | #endif | |||
41 | ||||
42 | #include <sys/param.h> | |||
43 | #include <sys/bus.h> | |||
44 | #include <sys/capsicum.h> | |||
45 | #include <sys/clock.h> | |||
46 | #include <sys/exec.h> | |||
47 | #include <sys/fcntl.h> | |||
48 | #include <sys/filedesc.h> | |||
49 | #include <sys/imgact.h> | |||
50 | #include <sys/jail.h> | |||
51 | #include <sys/kernel.h> | |||
52 | #include <sys/limits.h> | |||
53 | #include <sys/linker.h> | |||
54 | #include <sys/lock.h> | |||
55 | #include <sys/malloc.h> | |||
56 | #include <sys/file.h> /* Must come after sys/malloc.h */ | |||
57 | #include <sys/imgact.h> | |||
58 | #include <sys/mbuf.h> | |||
59 | #include <sys/mman.h> | |||
60 | #include <sys/module.h> | |||
61 | #include <sys/mount.h> | |||
62 | #include <sys/mutex.h> | |||
63 | #include <sys/namei.h> | |||
64 | #include <sys/proc.h> | |||
65 | #include <sys/procctl.h> | |||
66 | #include <sys/reboot.h> | |||
67 | #include <sys/resource.h> | |||
68 | #include <sys/resourcevar.h> | |||
69 | #include <sys/selinfo.h> | |||
70 | #include <sys/eventvar.h> /* Must come after sys/selinfo.h */ | |||
71 | #include <sys/pipe.h> /* Must come after sys/selinfo.h */ | |||
72 | #include <sys/signal.h> | |||
73 | #include <sys/signalvar.h> | |||
74 | #include <sys/socket.h> | |||
75 | #include <sys/socketvar.h> | |||
76 | #include <sys/stat.h> | |||
77 | #include <sys/syscall.h> | |||
78 | #include <sys/syscallsubr.h> | |||
79 | #include <sys/sysctl.h> | |||
80 | #include <sys/sysent.h> | |||
81 | #include <sys/sysproto.h> | |||
82 | #include <sys/systm.h> | |||
83 | #include <sys/thr.h> | |||
84 | #include <sys/unistd.h> | |||
85 | #include <sys/ucontext.h> | |||
86 | #include <sys/vnode.h> | |||
87 | #include <sys/wait.h> | |||
88 | #include <sys/ipc.h> | |||
89 | #include <sys/msg.h> | |||
90 | #include <sys/sem.h> | |||
91 | #include <sys/shm.h> | |||
92 | #ifdef KTRACE1 | |||
93 | #include <sys/ktrace.h> | |||
94 | #endif | |||
95 | ||||
96 | #ifdef INET1 | |||
97 | #include <netinet/in.h> | |||
98 | #endif | |||
99 | ||||
100 | #include <vm/vm.h> | |||
101 | #include <vm/vm_param.h> | |||
102 | #include <vm/pmap.h> | |||
103 | #include <vm/vm_map.h> | |||
104 | #include <vm/vm_object.h> | |||
105 | #include <vm/vm_extern.h> | |||
106 | ||||
107 | #include <machine/cpu.h> | |||
108 | #include <machine/elf.h> | |||
109 | ||||
110 | #include <security/audit/audit.h> | |||
111 | ||||
112 | #include <compat/freebsd32/freebsd32_util.h> | |||
113 | #include <compat/freebsd32/freebsd32.h> | |||
114 | #include <compat/freebsd32/freebsd32_ipc.h> | |||
115 | #include <compat/freebsd32/freebsd32_misc.h> | |||
116 | #include <compat/freebsd32/freebsd32_signal.h> | |||
117 | #include <compat/freebsd32/freebsd32_proto.h> | |||
118 | ||||
119 | FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD")static struct sysctl_oid sysctl___kern_features_compat_freebsd_32bit = { .oid_parent = ((&(&sysctl___kern_features)->oid_children )), .oid_children = { ((void *)0) }, .oid_number = ((-1)), .oid_kind = (2 | 0x00040000 | (0x80000000 | 0x00008000)), .oid_arg1 = ( ((int *)((void *)0))), .oid_arg2 = (1), .oid_name = ("compat_freebsd_32bit" ), .oid_handler = (sysctl_handle_int), .oid_fmt = ("I"), .oid_descr = "Compatible with 32-bit FreeBSD", .oid_label = ("feature") , }; __asm__(".globl " "__start_set_sysctl_set"); __asm__(".globl " "__stop_set_sysctl_set"); static void const * const __set_sysctl_set_sym_sysctl___kern_features_compat_freebsd_32bit __attribute__((__section__("set_" "sysctl_set"))) __attribute__ ((__used__)) = &(sysctl___kern_features_compat_freebsd_32bit ); _Static_assert((((0x80000000 | 0x00008000) & 0xf) == 0 || ((0x80000000 | 0x00008000) & 0) == 2) && sizeof (int) == sizeof(*(((int *)((void *)0)))), "compile-time assertion failed" ); | |||
120 | ||||
121 | #ifdef __amd64__1 | |||
122 | CTASSERT(sizeof(struct timeval32) == 8)_Static_assert(sizeof(struct timeval32) == 8, "compile-time assertion failed" ); | |||
123 | CTASSERT(sizeof(struct timespec32) == 8)_Static_assert(sizeof(struct timespec32) == 8, "compile-time assertion failed" ); | |||
124 | CTASSERT(sizeof(struct itimerval32) == 16)_Static_assert(sizeof(struct itimerval32) == 16, "compile-time assertion failed" ); | |||
125 | CTASSERT(sizeof(struct bintime32) == 12)_Static_assert(sizeof(struct bintime32) == 12, "compile-time assertion failed" ); | |||
126 | #endif | |||
127 | CTASSERT(sizeof(struct statfs32) == 256)_Static_assert(sizeof(struct statfs32) == 256, "compile-time assertion failed" ); | |||
128 | #ifdef __amd64__1 | |||
129 | CTASSERT(sizeof(struct rusage32) == 72)_Static_assert(sizeof(struct rusage32) == 72, "compile-time assertion failed" ); | |||
130 | #endif | |||
131 | CTASSERT(sizeof(struct sigaltstack32) == 12)_Static_assert(sizeof(struct sigaltstack32) == 12, "compile-time assertion failed" ); | |||
132 | #ifdef __amd64__1 | |||
133 | CTASSERT(sizeof(struct kevent32) == 56)_Static_assert(sizeof(struct kevent32) == 56, "compile-time assertion failed" ); | |||
134 | #else | |||
135 | CTASSERT(sizeof(struct kevent32) == 64)_Static_assert(sizeof(struct kevent32) == 64, "compile-time assertion failed" ); | |||
136 | #endif | |||
137 | CTASSERT(sizeof(struct iovec32) == 8)_Static_assert(sizeof(struct iovec32) == 8, "compile-time assertion failed" ); | |||
138 | CTASSERT(sizeof(struct msghdr32) == 28)_Static_assert(sizeof(struct msghdr32) == 28, "compile-time assertion failed" ); | |||
139 | #ifdef __amd64__1 | |||
140 | CTASSERT(sizeof(struct stat32) == 208)_Static_assert(sizeof(struct stat32) == 208, "compile-time assertion failed" ); | |||
141 | CTASSERT(sizeof(struct freebsd11_stat32) == 96)_Static_assert(sizeof(struct freebsd11_stat32) == 96, "compile-time assertion failed" ); | |||
142 | #endif | |||
143 | CTASSERT(sizeof(struct sigaction32) == 24)_Static_assert(sizeof(struct sigaction32) == 24, "compile-time assertion failed" ); | |||
144 | ||||
145 | static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); | |||
146 | static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); | |||
147 | static int freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id, | |||
148 | int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp); | |||
149 | ||||
150 | void | |||
151 | freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32) | |||
152 | { | |||
153 | ||||
154 | TV_CP(*s, *s32, ru_utime)do { do { ((*s32).ru_utime).tv_sec = ((*s).ru_utime).tv_sec; } while (0); do { ((*s32).ru_utime).tv_usec = ((*s).ru_utime). tv_usec; } while (0); } while (0); | |||
155 | TV_CP(*s, *s32, ru_stime)do { do { ((*s32).ru_stime).tv_sec = ((*s).ru_stime).tv_sec; } while (0); do { ((*s32).ru_stime).tv_usec = ((*s).ru_stime). tv_usec; } while (0); } while (0); | |||
156 | CP(*s, *s32, ru_maxrss)do { (*s32).ru_maxrss = (*s).ru_maxrss; } while (0); | |||
157 | CP(*s, *s32, ru_ixrss)do { (*s32).ru_ixrss = (*s).ru_ixrss; } while (0); | |||
158 | CP(*s, *s32, ru_idrss)do { (*s32).ru_idrss = (*s).ru_idrss; } while (0); | |||
159 | CP(*s, *s32, ru_isrss)do { (*s32).ru_isrss = (*s).ru_isrss; } while (0); | |||
160 | CP(*s, *s32, ru_minflt)do { (*s32).ru_minflt = (*s).ru_minflt; } while (0); | |||
161 | CP(*s, *s32, ru_majflt)do { (*s32).ru_majflt = (*s).ru_majflt; } while (0); | |||
162 | CP(*s, *s32, ru_nswap)do { (*s32).ru_nswap = (*s).ru_nswap; } while (0); | |||
163 | CP(*s, *s32, ru_inblock)do { (*s32).ru_inblock = (*s).ru_inblock; } while (0); | |||
164 | CP(*s, *s32, ru_oublock)do { (*s32).ru_oublock = (*s).ru_oublock; } while (0); | |||
165 | CP(*s, *s32, ru_msgsnd)do { (*s32).ru_msgsnd = (*s).ru_msgsnd; } while (0); | |||
166 | CP(*s, *s32, ru_msgrcv)do { (*s32).ru_msgrcv = (*s).ru_msgrcv; } while (0); | |||
167 | CP(*s, *s32, ru_nsignals)do { (*s32).ru_nsignals = (*s).ru_nsignals; } while (0); | |||
168 | CP(*s, *s32, ru_nvcsw)do { (*s32).ru_nvcsw = (*s).ru_nvcsw; } while (0); | |||
169 | CP(*s, *s32, ru_nivcsw)do { (*s32).ru_nivcsw = (*s).ru_nivcsw; } while (0); | |||
170 | } | |||
171 | ||||
172 | int | |||
173 | freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) | |||
174 | { | |||
175 | int error, status; | |||
176 | struct rusage32 ru32; | |||
177 | struct rusage ru, *rup; | |||
178 | ||||
179 | if (uap->rusage != NULL((void *)0)) | |||
180 | rup = &ru; | |||
181 | else | |||
182 | rup = NULL((void *)0); | |||
183 | error = kern_wait(td, uap->pid, &status, uap->options, rup); | |||
184 | if (error) | |||
185 | return (error); | |||
186 | if (uap->status != NULL((void *)0)) | |||
187 | error = copyout(&status, uap->status, sizeof(status)); | |||
188 | if (uap->rusage != NULL((void *)0) && error == 0) { | |||
189 | freebsd32_rusage_out(&ru, &ru32); | |||
190 | error = copyout(&ru32, uap->rusage, sizeof(ru32)); | |||
191 | } | |||
192 | return (error); | |||
193 | } | |||
194 | ||||
195 | int | |||
196 | freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap) | |||
197 | { | |||
198 | struct wrusage32 wru32; | |||
199 | struct __wrusage wru, *wrup; | |||
200 | struct siginfo32 si32; | |||
201 | struct __siginfo si, *sip; | |||
202 | int error, status; | |||
203 | ||||
204 | if (uap->wrusage != NULL((void *)0)) | |||
205 | wrup = &wru; | |||
206 | else | |||
207 | wrup = NULL((void *)0); | |||
208 | if (uap->info != NULL((void *)0)) { | |||
209 | sip = &si; | |||
210 | bzero(sip, sizeof(*sip))__builtin_memset((sip), 0, (sizeof(*sip))); | |||
211 | } else | |||
212 | sip = NULL((void *)0); | |||
213 | error = kern_wait6(td, uap->idtype, PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), | |||
214 | &status, uap->options, wrup, sip); | |||
215 | if (error != 0) | |||
216 | return (error); | |||
217 | if (uap->status != NULL((void *)0)) | |||
218 | error = copyout(&status, uap->status, sizeof(status)); | |||
219 | if (uap->wrusage != NULL((void *)0) && error == 0) { | |||
220 | freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self); | |||
221 | freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children); | |||
222 | error = copyout(&wru32, uap->wrusage, sizeof(wru32)); | |||
223 | } | |||
224 | if (uap->info != NULL((void *)0) && error == 0) { | |||
225 | siginfo_to_siginfo32 (&si, &si32); | |||
226 | error = copyout(&si32, uap->info, sizeof(si32)); | |||
227 | } | |||
228 | return (error); | |||
229 | } | |||
230 | ||||
231 | #ifdef COMPAT_FREEBSD41 | |||
232 | static void | |||
233 | copy_statfs(struct statfs *in, struct statfs32 *out) | |||
234 | { | |||
235 | ||||
236 | statfs_scale_blocks(in, INT32_MAX0x7fffffff); | |||
237 | bzero(out, sizeof(*out))__builtin_memset((out), 0, (sizeof(*out))); | |||
238 | CP(*in, *out, f_bsize)do { (*out).f_bsize = (*in).f_bsize; } while (0); | |||
239 | out->f_iosize = MIN(in->f_iosize, INT32_MAX)(((in->f_iosize)<(0x7fffffff))?(in->f_iosize):(0x7fffffff )); | |||
240 | CP(*in, *out, f_blocks)do { (*out).f_blocks = (*in).f_blocks; } while (0); | |||
241 | CP(*in, *out, f_bfree)do { (*out).f_bfree = (*in).f_bfree; } while (0); | |||
242 | CP(*in, *out, f_bavail)do { (*out).f_bavail = (*in).f_bavail; } while (0); | |||
243 | out->f_files = MIN(in->f_files, INT32_MAX)(((in->f_files)<(0x7fffffff))?(in->f_files):(0x7fffffff )); | |||
244 | out->f_ffree = MIN(in->f_ffree, INT32_MAX)(((in->f_ffree)<(0x7fffffff))?(in->f_ffree):(0x7fffffff )); | |||
245 | CP(*in, *out, f_fsid)do { (*out).f_fsid = (*in).f_fsid; } while (0); | |||
246 | CP(*in, *out, f_owner)do { (*out).f_owner = (*in).f_owner; } while (0); | |||
247 | CP(*in, *out, f_type)do { (*out).f_type = (*in).f_type; } while (0); | |||
248 | CP(*in, *out, f_flags)do { (*out).f_flags = (*in).f_flags; } while (0); | |||
249 | out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX)(((in->f_syncwrites)<(0x7fffffff))?(in->f_syncwrites ):(0x7fffffff)); | |||
250 | out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX)(((in->f_asyncwrites)<(0x7fffffff))?(in->f_asyncwrites ):(0x7fffffff)); | |||
251 | strlcpy(out->f_fstypename, | |||
252 | in->f_fstypename, MFSNAMELEN16); | |||
253 | strlcpy(out->f_mntonname, | |||
254 | in->f_mntonname, min(MNAMELEN1024, FREEBSD4_MNAMELEN(88 - 2 * sizeof(int32_t)))); | |||
255 | out->f_syncreads = MIN(in->f_syncreads, INT32_MAX)(((in->f_syncreads)<(0x7fffffff))?(in->f_syncreads): (0x7fffffff)); | |||
256 | out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX)(((in->f_asyncreads)<(0x7fffffff))?(in->f_asyncreads ):(0x7fffffff)); | |||
257 | strlcpy(out->f_mntfromname, | |||
258 | in->f_mntfromname, min(MNAMELEN1024, FREEBSD4_MNAMELEN(88 - 2 * sizeof(int32_t)))); | |||
259 | } | |||
260 | #endif | |||
261 | ||||
262 | #ifdef COMPAT_FREEBSD41 | |||
263 | int | |||
264 | freebsd4_freebsd32_getfsstat(struct thread *td, | |||
265 | struct freebsd4_freebsd32_getfsstat_args *uap) | |||
266 | { | |||
267 | struct statfs *buf, *sp; | |||
268 | struct statfs32 stat32; | |||
269 | size_t count, size, copycount; | |||
270 | int error; | |||
271 | ||||
272 | count = uap->bufsize / sizeof(struct statfs32); | |||
273 | size = count * sizeof(struct statfs); | |||
274 | error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode); | |||
275 | if (size > 0) { | |||
276 | sp = buf; | |||
277 | copycount = count; | |||
278 | while (copycount > 0 && error == 0) { | |||
279 | copy_statfs(sp, &stat32); | |||
280 | error = copyout(&stat32, uap->buf, sizeof(stat32)); | |||
281 | sp++; | |||
282 | uap->buf++; | |||
283 | copycount--; | |||
284 | } | |||
285 | free(buf, M_STATFS); | |||
286 | } | |||
287 | if (error == 0) | |||
288 | td->td_retvaltd_uretoff.tdu_retval[0] = count; | |||
289 | return (error); | |||
290 | } | |||
291 | #endif | |||
292 | ||||
293 | #ifdef COMPAT_FREEBSD101 | |||
294 | int | |||
295 | freebsd10_freebsd32_pipe(struct thread *td, | |||
296 | struct freebsd10_freebsd32_pipe_args *uap) { | |||
297 | ||||
298 | return (freebsd10_pipe(td, (struct freebsd10_pipe_args*)uap)); | |||
299 | } | |||
300 | #endif | |||
301 | ||||
302 | int | |||
303 | freebsd32_sigaltstack(struct thread *td, | |||
304 | struct freebsd32_sigaltstack_args *uap) | |||
305 | { | |||
306 | struct sigaltstack32 s32; | |||
307 | struct sigaltstack ss, oss, *ssp; | |||
308 | int error; | |||
309 | ||||
310 | if (uap->ss != NULL((void *)0)) { | |||
311 | error = copyin(uap->ss, &s32, sizeof(s32)); | |||
312 | if (error) | |||
313 | return (error); | |||
314 | PTRIN_CP(s32, ss, ss_sp)do { (ss).ss_sp = (void *)(uintptr_t) ((s32).ss_sp); } while ( 0); | |||
315 | CP(s32, ss, ss_size)do { (ss).ss_size = (s32).ss_size; } while (0); | |||
316 | CP(s32, ss, ss_flags)do { (ss).ss_flags = (s32).ss_flags; } while (0); | |||
317 | ssp = &ss; | |||
318 | } else | |||
319 | ssp = NULL((void *)0); | |||
320 | error = kern_sigaltstack(td, ssp, &oss); | |||
321 | if (error == 0 && uap->oss != NULL((void *)0)) { | |||
322 | PTROUT_CP(oss, s32, ss_sp)do { (s32).ss_sp = (u_int32_t)(uintptr_t) ((oss).ss_sp); } while (0); | |||
323 | CP(oss, s32, ss_size)do { (s32).ss_size = (oss).ss_size; } while (0); | |||
324 | CP(oss, s32, ss_flags)do { (s32).ss_flags = (oss).ss_flags; } while (0); | |||
325 | error = copyout(&s32, uap->oss, sizeof(s32)); | |||
326 | } | |||
327 | return (error); | |||
328 | } | |||
329 | ||||
330 | /* | |||
331 | * Custom version of exec_copyin_args() so that we can translate | |||
332 | * the pointers. | |||
333 | */ | |||
334 | int | |||
335 | freebsd32_exec_copyin_args(struct image_args *args, const char *fname, | |||
336 | enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) | |||
337 | { | |||
338 | char *argp, *envp; | |||
339 | u_int32_t *p32, arg; | |||
340 | int error; | |||
341 | ||||
342 | bzero(args, sizeof(*args))__builtin_memset((args), 0, (sizeof(*args))); | |||
343 | if (argv == NULL((void *)0)) | |||
344 | return (EFAULT14); | |||
345 | ||||
346 | /* | |||
347 | * Allocate demand-paged memory for the file name, argument, and | |||
348 | * environment strings. | |||
349 | */ | |||
350 | error = exec_alloc_args(args); | |||
351 | if (error != 0) | |||
352 | return (error); | |||
353 | ||||
354 | /* | |||
355 | * Copy the file name. | |||
356 | */ | |||
357 | error = exec_args_add_fname(args, fname, segflg); | |||
358 | if (error != 0) | |||
359 | goto err_exit; | |||
360 | ||||
361 | /* | |||
362 | * extract arguments first | |||
363 | */ | |||
364 | p32 = argv; | |||
365 | for (;;) { | |||
366 | error = copyin(p32++, &arg, sizeof(arg)); | |||
367 | if (error) | |||
368 | goto err_exit; | |||
369 | if (arg == 0) | |||
370 | break; | |||
371 | argp = PTRIN(arg)(void *)(uintptr_t) (arg); | |||
372 | error = exec_args_add_arg(args, argp, UIO_USERSPACE); | |||
373 | if (error != 0) | |||
374 | goto err_exit; | |||
375 | } | |||
376 | ||||
377 | /* | |||
378 | * extract environment strings | |||
379 | */ | |||
380 | if (envv) { | |||
381 | p32 = envv; | |||
382 | for (;;) { | |||
383 | error = copyin(p32++, &arg, sizeof(arg)); | |||
384 | if (error) | |||
385 | goto err_exit; | |||
386 | if (arg == 0) | |||
387 | break; | |||
388 | envp = PTRIN(arg)(void *)(uintptr_t) (arg); | |||
389 | error = exec_args_add_env(args, envp, UIO_USERSPACE); | |||
390 | if (error != 0) | |||
391 | goto err_exit; | |||
392 | } | |||
393 | } | |||
394 | ||||
395 | return (0); | |||
396 | ||||
397 | err_exit: | |||
398 | exec_free_args(args); | |||
399 | return (error); | |||
400 | } | |||
401 | ||||
402 | int | |||
403 | freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) | |||
404 | { | |||
405 | struct image_args eargs; | |||
406 | struct vmspace *oldvmspace; | |||
407 | int error; | |||
408 | ||||
409 | error = pre_execve(td, &oldvmspace); | |||
410 | if (error != 0) | |||
411 | return (error); | |||
412 | error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, | |||
413 | uap->argv, uap->envv); | |||
414 | if (error == 0) | |||
415 | error = kern_execve(td, &eargs, NULL((void *)0)); | |||
416 | post_execve(td, error, oldvmspace); | |||
417 | return (error); | |||
418 | } | |||
419 | ||||
420 | int | |||
421 | freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap) | |||
422 | { | |||
423 | struct image_args eargs; | |||
424 | struct vmspace *oldvmspace; | |||
425 | int error; | |||
426 | ||||
427 | error = pre_execve(td, &oldvmspace); | |||
428 | if (error != 0) | |||
429 | return (error); | |||
430 | error = freebsd32_exec_copyin_args(&eargs, NULL((void *)0), UIO_SYSSPACE, | |||
431 | uap->argv, uap->envv); | |||
432 | if (error == 0) { | |||
433 | eargs.fd = uap->fd; | |||
434 | error = kern_execve(td, &eargs, NULL((void *)0)); | |||
435 | } | |||
436 | post_execve(td, error, oldvmspace); | |||
437 | return (error); | |||
438 | } | |||
439 | ||||
440 | ||||
441 | int | |||
442 | freebsd32_mknodat(struct thread *td, struct freebsd32_mknodat_args *uap) | |||
443 | { | |||
444 | ||||
445 | return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, | |||
446 | uap->mode, PAIR32TO64(dev_t, uap->dev)((uap->dev1) | ((dev_t)(uap->dev2) << 32)))); | |||
447 | } | |||
448 | ||||
449 | int | |||
450 | freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap) | |||
451 | { | |||
452 | int prot; | |||
453 | ||||
454 | prot = uap->prot; | |||
455 | #if defined(__amd64__1) | |||
456 | if (i386_read_exec && (prot & PROT_READ0x01) != 0) | |||
457 | prot |= PROT_EXEC0x04; | |||
458 | #endif | |||
459 | return (kern_mprotect(td, (uintptr_t)PTRIN(uap->addr)(void *)(uintptr_t) (uap->addr), uap->len, | |||
460 | prot)); | |||
461 | } | |||
462 | ||||
463 | int | |||
464 | freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) | |||
465 | { | |||
466 | int prot; | |||
467 | ||||
468 | prot = uap->prot; | |||
469 | #if defined(__amd64__1) | |||
470 | if (i386_read_exec && (prot & PROT_READ0x01)) | |||
471 | prot |= PROT_EXEC0x04; | |||
472 | #endif | |||
473 | ||||
474 | return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot, | |||
475 | uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos)((uap->pos1) | ((off_t)(uap->pos2) << 32)))); | |||
476 | } | |||
477 | ||||
478 | #ifdef COMPAT_FREEBSD61 | |||
479 | int | |||
480 | freebsd6_freebsd32_mmap(struct thread *td, | |||
481 | struct freebsd6_freebsd32_mmap_args *uap) | |||
482 | { | |||
483 | int prot; | |||
484 | ||||
485 | prot = uap->prot; | |||
486 | #if defined(__amd64__1) | |||
487 | if (i386_read_exec && (prot & PROT_READ0x01)) | |||
488 | prot |= PROT_EXEC0x04; | |||
489 | #endif | |||
490 | ||||
491 | return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot, | |||
492 | uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos)((uap->pos1) | ((off_t)(uap->pos2) << 32)))); | |||
493 | } | |||
494 | #endif | |||
495 | ||||
496 | int | |||
497 | freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) | |||
498 | { | |||
499 | struct itimerval itv, oitv, *itvp; | |||
500 | struct itimerval32 i32; | |||
501 | int error; | |||
502 | ||||
503 | if (uap->itv != NULL((void *)0)) { | |||
504 | error = copyin(uap->itv, &i32, sizeof(i32)); | |||
505 | if (error) | |||
506 | return (error); | |||
507 | TV_CP(i32, itv, it_interval)do { do { ((itv).it_interval).tv_sec = ((i32).it_interval).tv_sec ; } while (0); do { ((itv).it_interval).tv_usec = ((i32).it_interval ).tv_usec; } while (0); } while (0); | |||
508 | TV_CP(i32, itv, it_value)do { do { ((itv).it_value).tv_sec = ((i32).it_value).tv_sec; } while (0); do { ((itv).it_value).tv_usec = ((i32).it_value). tv_usec; } while (0); } while (0); | |||
509 | itvp = &itv; | |||
510 | } else | |||
511 | itvp = NULL((void *)0); | |||
512 | error = kern_setitimer(td, uap->which, itvp, &oitv); | |||
513 | if (error || uap->oitv == NULL((void *)0)) | |||
514 | return (error); | |||
515 | TV_CP(oitv, i32, it_interval)do { do { ((i32).it_interval).tv_sec = ((oitv).it_interval).tv_sec ; } while (0); do { ((i32).it_interval).tv_usec = ((oitv).it_interval ).tv_usec; } while (0); } while (0); | |||
516 | TV_CP(oitv, i32, it_value)do { do { ((i32).it_value).tv_sec = ((oitv).it_value).tv_sec; } while (0); do { ((i32).it_value).tv_usec = ((oitv).it_value ).tv_usec; } while (0); } while (0); | |||
517 | return (copyout(&i32, uap->oitv, sizeof(i32))); | |||
518 | } | |||
519 | ||||
520 | int | |||
521 | freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) | |||
522 | { | |||
523 | struct itimerval itv; | |||
524 | struct itimerval32 i32; | |||
525 | int error; | |||
526 | ||||
527 | error = kern_getitimer(td, uap->which, &itv); | |||
528 | if (error || uap->itv == NULL((void *)0)) | |||
529 | return (error); | |||
530 | TV_CP(itv, i32, it_interval)do { do { ((i32).it_interval).tv_sec = ((itv).it_interval).tv_sec ; } while (0); do { ((i32).it_interval).tv_usec = ((itv).it_interval ).tv_usec; } while (0); } while (0); | |||
531 | TV_CP(itv, i32, it_value)do { do { ((i32).it_value).tv_sec = ((itv).it_value).tv_sec; } while (0); do { ((i32).it_value).tv_usec = ((itv).it_value). tv_usec; } while (0); } while (0); | |||
532 | return (copyout(&i32, uap->itv, sizeof(i32))); | |||
533 | } | |||
534 | ||||
535 | int | |||
536 | freebsd32_select(struct thread *td, struct freebsd32_select_args *uap) | |||
537 | { | |||
538 | struct timeval32 tv32; | |||
539 | struct timeval tv, *tvp; | |||
540 | int error; | |||
541 | ||||
542 | if (uap->tv != NULL((void *)0)) { | |||
543 | error = copyin(uap->tv, &tv32, sizeof(tv32)); | |||
544 | if (error) | |||
545 | return (error); | |||
546 | CP(tv32, tv, tv_sec)do { (tv).tv_sec = (tv32).tv_sec; } while (0); | |||
547 | CP(tv32, tv, tv_usec)do { (tv).tv_usec = (tv32).tv_usec; } while (0); | |||
548 | tvp = &tv; | |||
549 | } else | |||
550 | tvp = NULL((void *)0); | |||
551 | /* | |||
552 | * XXX Do pointers need PTRIN()? | |||
553 | */ | |||
554 | return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, | |||
555 | sizeof(int32_t) * 8)); | |||
556 | } | |||
557 | ||||
558 | int | |||
559 | freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap) | |||
560 | { | |||
561 | struct timespec32 ts32; | |||
562 | struct timespec ts; | |||
563 | struct timeval tv, *tvp; | |||
564 | sigset_t set, *uset; | |||
565 | int error; | |||
566 | ||||
567 | if (uap->ts != NULL((void *)0)) { | |||
568 | error = copyin(uap->ts, &ts32, sizeof(ts32)); | |||
569 | if (error != 0) | |||
570 | return (error); | |||
571 | CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0); | |||
572 | CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0); | |||
573 | TIMESPEC_TO_TIMEVAL(&tv, &ts)do { (&tv)->tv_sec = (&ts)->tv_sec; (&tv)-> tv_usec = (&ts)->tv_nsec / 1000; } while (0); | |||
574 | tvp = &tv; | |||
575 | } else | |||
576 | tvp = NULL((void *)0); | |||
577 | if (uap->sm != NULL((void *)0)) { | |||
578 | error = copyin(uap->sm, &set, sizeof(set)); | |||
579 | if (error != 0) | |||
580 | return (error); | |||
581 | uset = &set; | |||
582 | } else | |||
583 | uset = NULL((void *)0); | |||
584 | /* | |||
585 | * XXX Do pointers need PTRIN()? | |||
586 | */ | |||
587 | error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, | |||
588 | uset, sizeof(int32_t) * 8); | |||
589 | return (error); | |||
590 | } | |||
591 | ||||
592 | /* | |||
593 | * Copy 'count' items into the destination list pointed to by uap->eventlist. | |||
594 | */ | |||
595 | static int | |||
596 | freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) | |||
597 | { | |||
598 | struct freebsd32_kevent_args *uap; | |||
599 | struct kevent32 ks32[KQ_NEVENTS8]; | |||
600 | uint64_t e; | |||
601 | int i, j, error; | |||
602 | ||||
603 | KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS" , count); } while (0); | |||
604 | uap = (struct freebsd32_kevent_args *)arg; | |||
605 | ||||
606 | for (i = 0; i < count; i++) { | |||
607 | CP(kevp[i], ks32[i], ident)do { (ks32[i]).ident = (kevp[i]).ident; } while (0); | |||
608 | CP(kevp[i], ks32[i], filter)do { (ks32[i]).filter = (kevp[i]).filter; } while (0); | |||
609 | CP(kevp[i], ks32[i], flags)do { (ks32[i]).flags = (kevp[i]).flags; } while (0); | |||
610 | CP(kevp[i], ks32[i], fflags)do { (ks32[i]).fflags = (kevp[i]).fflags; } while (0); | |||
611 | #if BYTE_ORDER1234 == LITTLE_ENDIAN1234 | |||
612 | ks32[i].data1 = kevp[i].data; | |||
613 | ks32[i].data2 = kevp[i].data >> 32; | |||
614 | #else | |||
615 | ks32[i].data1 = kevp[i].data >> 32; | |||
616 | ks32[i].data2 = kevp[i].data; | |||
617 | #endif | |||
618 | PTROUT_CP(kevp[i], ks32[i], udata)do { (ks32[i]).udata = (u_int32_t)(uintptr_t) ((kevp[i]).udata ); } while (0); | |||
619 | for (j = 0; j < nitems(kevp->ext)(sizeof((kevp->ext)) / sizeof((kevp->ext)[0])); j++) { | |||
620 | e = kevp[i].ext[j]; | |||
621 | #if BYTE_ORDER1234 == LITTLE_ENDIAN1234 | |||
622 | ks32[i].ext64[2 * j] = e; | |||
623 | ks32[i].ext64[2 * j + 1] = e >> 32; | |||
624 | #else | |||
625 | ks32[i].ext64[2 * j] = e >> 32; | |||
626 | ks32[i].ext64[2 * j + 1] = e; | |||
627 | #endif | |||
628 | } | |||
629 | } | |||
630 | error = copyout(ks32, uap->eventlist, count * sizeof *ks32); | |||
631 | if (error == 0) | |||
632 | uap->eventlist += count; | |||
633 | return (error); | |||
634 | } | |||
635 | ||||
636 | /* | |||
637 | * Copy 'count' items from the list pointed to by uap->changelist. | |||
638 | */ | |||
639 | static int | |||
640 | freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) | |||
641 | { | |||
642 | struct freebsd32_kevent_args *uap; | |||
643 | struct kevent32 ks32[KQ_NEVENTS8]; | |||
644 | uint64_t e; | |||
645 | int i, j, error; | |||
646 | ||||
647 | KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS" , count); } while (0); | |||
648 | uap = (struct freebsd32_kevent_args *)arg; | |||
649 | ||||
650 | error = copyin(uap->changelist, ks32, count * sizeof *ks32); | |||
651 | if (error) | |||
652 | goto done; | |||
653 | uap->changelist += count; | |||
654 | ||||
655 | for (i = 0; i < count; i++) { | |||
656 | CP(ks32[i], kevp[i], ident)do { (kevp[i]).ident = (ks32[i]).ident; } while (0); | |||
657 | CP(ks32[i], kevp[i], filter)do { (kevp[i]).filter = (ks32[i]).filter; } while (0); | |||
658 | CP(ks32[i], kevp[i], flags)do { (kevp[i]).flags = (ks32[i]).flags; } while (0); | |||
659 | CP(ks32[i], kevp[i], fflags)do { (kevp[i]).fflags = (ks32[i]).fflags; } while (0); | |||
660 | kevp[i].data = PAIR32TO64(uint64_t, ks32[i].data)((ks32[i].data1) | ((uint64_t)(ks32[i].data2) << 32)); | |||
661 | PTRIN_CP(ks32[i], kevp[i], udata)do { (kevp[i]).udata = (void *)(uintptr_t) ((ks32[i]).udata); } while (0); | |||
662 | for (j = 0; j < nitems(kevp->ext)(sizeof((kevp->ext)) / sizeof((kevp->ext)[0])); j++) { | |||
663 | #if BYTE_ORDER1234 == LITTLE_ENDIAN1234 | |||
664 | e = ks32[i].ext64[2 * j + 1]; | |||
665 | e <<= 32; | |||
666 | e += ks32[i].ext64[2 * j]; | |||
667 | #else | |||
668 | e = ks32[i].ext64[2 * j]; | |||
669 | e <<= 32; | |||
670 | e += ks32[i].ext64[2 * j + 1]; | |||
671 | #endif | |||
672 | kevp[i].ext[j] = e; | |||
673 | } | |||
674 | } | |||
675 | done: | |||
676 | return (error); | |||
677 | } | |||
678 | ||||
679 | int | |||
680 | freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) | |||
681 | { | |||
682 | struct timespec32 ts32; | |||
683 | struct timespec ts, *tsp; | |||
684 | struct kevent_copyops k_ops = { | |||
685 | .arg = uap, | |||
686 | .k_copyout = freebsd32_kevent_copyout, | |||
687 | .k_copyin = freebsd32_kevent_copyin, | |||
688 | }; | |||
689 | #ifdef KTRACE1 | |||
690 | struct kevent32 *eventlist = uap->eventlist; | |||
691 | #endif | |||
692 | int error; | |||
693 | ||||
694 | if (uap->timeout) { | |||
695 | error = copyin(uap->timeout, &ts32, sizeof(ts32)); | |||
696 | if (error) | |||
697 | return (error); | |||
698 | CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0); | |||
699 | CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0); | |||
700 | tsp = &ts; | |||
701 | } else | |||
702 | tsp = NULL((void *)0); | |||
703 | #ifdef KTRACE1 | |||
704 | if (KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & ( 1 << (15)))), 0))) | |||
705 | ktrstructarray("kevent32", UIO_USERSPACE, uap->changelist, | |||
706 | uap->nchanges, sizeof(struct kevent32)); | |||
707 | #endif | |||
708 | error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, | |||
709 | &k_ops, tsp); | |||
710 | #ifdef KTRACE1 | |||
711 | if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & ( 1 << (15)))), 0))) | |||
712 | ktrstructarray("kevent32", UIO_USERSPACE, eventlist, | |||
713 | td->td_retvaltd_uretoff.tdu_retval[0], sizeof(struct kevent32)); | |||
714 | #endif | |||
715 | return (error); | |||
716 | } | |||
717 | ||||
718 | #ifdef COMPAT_FREEBSD111 | |||
719 | static int | |||
720 | freebsd32_kevent11_copyout(void *arg, struct kevent *kevp, int count) | |||
721 | { | |||
722 | struct freebsd11_freebsd32_kevent_args *uap; | |||
723 | struct kevent32_freebsd11 ks32[KQ_NEVENTS8]; | |||
724 | int i, error; | |||
725 | ||||
726 | KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS" , count); } while (0); | |||
727 | uap = (struct freebsd11_freebsd32_kevent_args *)arg; | |||
728 | ||||
729 | for (i = 0; i < count; i++) { | |||
730 | CP(kevp[i], ks32[i], ident)do { (ks32[i]).ident = (kevp[i]).ident; } while (0); | |||
731 | CP(kevp[i], ks32[i], filter)do { (ks32[i]).filter = (kevp[i]).filter; } while (0); | |||
732 | CP(kevp[i], ks32[i], flags)do { (ks32[i]).flags = (kevp[i]).flags; } while (0); | |||
733 | CP(kevp[i], ks32[i], fflags)do { (ks32[i]).fflags = (kevp[i]).fflags; } while (0); | |||
734 | CP(kevp[i], ks32[i], data)do { (ks32[i]).data = (kevp[i]).data; } while (0); | |||
735 | PTROUT_CP(kevp[i], ks32[i], udata)do { (ks32[i]).udata = (u_int32_t)(uintptr_t) ((kevp[i]).udata ); } while (0); | |||
736 | } | |||
737 | error = copyout(ks32, uap->eventlist, count * sizeof *ks32); | |||
738 | if (error == 0) | |||
739 | uap->eventlist += count; | |||
740 | return (error); | |||
741 | } | |||
742 | ||||
743 | /* | |||
744 | * Copy 'count' items from the list pointed to by uap->changelist. | |||
745 | */ | |||
746 | static int | |||
747 | freebsd32_kevent11_copyin(void *arg, struct kevent *kevp, int count) | |||
748 | { | |||
749 | struct freebsd11_freebsd32_kevent_args *uap; | |||
750 | struct kevent32_freebsd11 ks32[KQ_NEVENTS8]; | |||
751 | int i, j, error; | |||
752 | ||||
753 | KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS" , count); } while (0); | |||
754 | uap = (struct freebsd11_freebsd32_kevent_args *)arg; | |||
755 | ||||
756 | error = copyin(uap->changelist, ks32, count * sizeof *ks32); | |||
757 | if (error) | |||
758 | goto done; | |||
759 | uap->changelist += count; | |||
760 | ||||
761 | for (i = 0; i < count; i++) { | |||
762 | CP(ks32[i], kevp[i], ident)do { (kevp[i]).ident = (ks32[i]).ident; } while (0); | |||
763 | CP(ks32[i], kevp[i], filter)do { (kevp[i]).filter = (ks32[i]).filter; } while (0); | |||
764 | CP(ks32[i], kevp[i], flags)do { (kevp[i]).flags = (ks32[i]).flags; } while (0); | |||
765 | CP(ks32[i], kevp[i], fflags)do { (kevp[i]).fflags = (ks32[i]).fflags; } while (0); | |||
766 | CP(ks32[i], kevp[i], data)do { (kevp[i]).data = (ks32[i]).data; } while (0); | |||
767 | PTRIN_CP(ks32[i], kevp[i], udata)do { (kevp[i]).udata = (void *)(uintptr_t) ((ks32[i]).udata); } while (0); | |||
768 | for (j = 0; j < nitems(kevp->ext)(sizeof((kevp->ext)) / sizeof((kevp->ext)[0])); j++) | |||
769 | kevp[i].ext[j] = 0; | |||
770 | } | |||
771 | done: | |||
772 | return (error); | |||
773 | } | |||
774 | ||||
775 | int | |||
776 | freebsd11_freebsd32_kevent(struct thread *td, | |||
777 | struct freebsd11_freebsd32_kevent_args *uap) | |||
778 | { | |||
779 | struct timespec32 ts32; | |||
780 | struct timespec ts, *tsp; | |||
781 | struct kevent_copyops k_ops = { | |||
782 | .arg = uap, | |||
783 | .k_copyout = freebsd32_kevent11_copyout, | |||
784 | .k_copyin = freebsd32_kevent11_copyin, | |||
785 | }; | |||
786 | #ifdef KTRACE1 | |||
787 | struct kevent32_freebsd11 *eventlist = uap->eventlist; | |||
788 | #endif | |||
789 | int error; | |||
790 | ||||
791 | if (uap->timeout) { | |||
792 | error = copyin(uap->timeout, &ts32, sizeof(ts32)); | |||
793 | if (error) | |||
794 | return (error); | |||
795 | CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0); | |||
796 | CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0); | |||
797 | tsp = &ts; | |||
798 | } else | |||
799 | tsp = NULL((void *)0); | |||
800 | #ifdef KTRACE1 | |||
801 | if (KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & ( 1 << (15)))), 0))) | |||
802 | ktrstructarray("kevent32_freebsd11", UIO_USERSPACE, | |||
803 | uap->changelist, uap->nchanges, | |||
804 | sizeof(struct kevent32_freebsd11)); | |||
805 | #endif | |||
806 | error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, | |||
807 | &k_ops, tsp); | |||
808 | #ifdef KTRACE1 | |||
809 | if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & ( 1 << (15)))), 0))) | |||
810 | ktrstructarray("kevent32_freebsd11", UIO_USERSPACE, | |||
811 | eventlist, td->td_retvaltd_uretoff.tdu_retval[0], | |||
812 | sizeof(struct kevent32_freebsd11)); | |||
813 | #endif | |||
814 | return (error); | |||
815 | } | |||
816 | #endif | |||
817 | ||||
818 | int | |||
819 | freebsd32_gettimeofday(struct thread *td, | |||
820 | struct freebsd32_gettimeofday_args *uap) | |||
821 | { | |||
822 | struct timeval atv; | |||
823 | struct timeval32 atv32; | |||
824 | struct timezone rtz; | |||
825 | int error = 0; | |||
826 | ||||
827 | if (uap->tp) { | |||
828 | microtime(&atv); | |||
829 | CP(atv, atv32, tv_sec)do { (atv32).tv_sec = (atv).tv_sec; } while (0); | |||
830 | CP(atv, atv32, tv_usec)do { (atv32).tv_usec = (atv).tv_usec; } while (0); | |||
831 | error = copyout(&atv32, uap->tp, sizeof (atv32)); | |||
832 | } | |||
833 | if (error == 0 && uap->tzp != NULL((void *)0)) { | |||
834 | rtz.tz_minuteswest = tz_minuteswest; | |||
835 | rtz.tz_dsttime = tz_dsttime; | |||
836 | error = copyout(&rtz, uap->tzp, sizeof (rtz)); | |||
837 | } | |||
838 | return (error); | |||
839 | } | |||
840 | ||||
841 | int | |||
842 | freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) | |||
843 | { | |||
844 | struct rusage32 s32; | |||
845 | struct rusage s; | |||
846 | int error; | |||
847 | ||||
848 | error = kern_getrusage(td, uap->who, &s); | |||
849 | if (error == 0) { | |||
850 | freebsd32_rusage_out(&s, &s32); | |||
851 | error = copyout(&s32, uap->rusage, sizeof(s32)); | |||
852 | } | |||
853 | return (error); | |||
854 | } | |||
855 | ||||
856 | static int | |||
857 | freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) | |||
858 | { | |||
859 | struct iovec32 iov32; | |||
860 | struct iovec *iov; | |||
861 | struct uio *uio; | |||
862 | u_int iovlen; | |||
863 | int error, i; | |||
864 | ||||
865 | *uiop = NULL((void *)0); | |||
866 | if (iovcnt > UIO_MAXIOV1024) | |||
867 | return (EINVAL22); | |||
868 | iovlen = iovcnt * sizeof(struct iovec); | |||
869 | uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK0x0002); | |||
870 | iov = (struct iovec *)(uio + 1); | |||
871 | for (i = 0; i < iovcnt; i++) { | |||
872 | error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); | |||
873 | if (error) { | |||
874 | free(uio, M_IOV); | |||
875 | return (error); | |||
876 | } | |||
877 | iov[i].iov_base = PTRIN(iov32.iov_base)(void *)(uintptr_t) (iov32.iov_base); | |||
878 | iov[i].iov_len = iov32.iov_len; | |||
879 | } | |||
880 | uio->uio_iov = iov; | |||
881 | uio->uio_iovcnt = iovcnt; | |||
882 | uio->uio_segflg = UIO_USERSPACE; | |||
883 | uio->uio_offset = -1; | |||
884 | uio->uio_resid = 0; | |||
885 | for (i = 0; i < iovcnt; i++) { | |||
886 | if (iov->iov_len > INT_MAX0x7fffffff - uio->uio_resid) { | |||
887 | free(uio, M_IOV); | |||
888 | return (EINVAL22); | |||
889 | } | |||
890 | uio->uio_resid += iov->iov_len; | |||
891 | iov++; | |||
892 | } | |||
893 | *uiop = uio; | |||
894 | return (0); | |||
895 | } | |||
896 | ||||
897 | int | |||
898 | freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) | |||
899 | { | |||
900 | struct uio *auio; | |||
901 | int error; | |||
902 | ||||
903 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
904 | if (error) | |||
905 | return (error); | |||
906 | error = kern_readv(td, uap->fd, auio); | |||
907 | free(auio, M_IOV); | |||
908 | return (error); | |||
909 | } | |||
910 | ||||
911 | int | |||
912 | freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) | |||
913 | { | |||
914 | struct uio *auio; | |||
915 | int error; | |||
916 | ||||
917 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
918 | if (error) | |||
919 | return (error); | |||
920 | error = kern_writev(td, uap->fd, auio); | |||
921 | free(auio, M_IOV); | |||
922 | return (error); | |||
923 | } | |||
924 | ||||
925 | int | |||
926 | freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) | |||
927 | { | |||
928 | struct uio *auio; | |||
929 | int error; | |||
930 | ||||
931 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
932 | if (error) | |||
933 | return (error); | |||
934 | error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32))); | |||
935 | free(auio, M_IOV); | |||
936 | return (error); | |||
937 | } | |||
938 | ||||
939 | int | |||
940 | freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) | |||
941 | { | |||
942 | struct uio *auio; | |||
943 | int error; | |||
944 | ||||
945 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
946 | if (error) | |||
947 | return (error); | |||
948 | error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32))); | |||
949 | free(auio, M_IOV); | |||
950 | return (error); | |||
951 | } | |||
952 | ||||
953 | int | |||
954 | freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, | |||
955 | int error) | |||
956 | { | |||
957 | struct iovec32 iov32; | |||
958 | struct iovec *iov; | |||
959 | u_int iovlen; | |||
960 | int i; | |||
961 | ||||
962 | *iovp = NULL((void *)0); | |||
963 | if (iovcnt > UIO_MAXIOV1024) | |||
964 | return (error); | |||
965 | iovlen = iovcnt * sizeof(struct iovec); | |||
966 | iov = malloc(iovlen, M_IOV, M_WAITOK0x0002); | |||
967 | for (i = 0; i < iovcnt; i++) { | |||
968 | error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32)); | |||
969 | if (error) { | |||
970 | free(iov, M_IOV); | |||
971 | return (error); | |||
972 | } | |||
973 | iov[i].iov_base = PTRIN(iov32.iov_base)(void *)(uintptr_t) (iov32.iov_base); | |||
974 | iov[i].iov_len = iov32.iov_len; | |||
975 | } | |||
976 | *iovp = iov; | |||
977 | return (0); | |||
978 | } | |||
979 | ||||
980 | static int | |||
981 | freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) | |||
982 | { | |||
983 | struct msghdr32 m32; | |||
984 | int error; | |||
985 | ||||
986 | error = copyin(msg32, &m32, sizeof(m32)); | |||
987 | if (error) | |||
988 | return (error); | |||
989 | msg->msg_name = PTRIN(m32.msg_name)(void *)(uintptr_t) (m32.msg_name); | |||
990 | msg->msg_namelen = m32.msg_namelen; | |||
991 | msg->msg_iov = PTRIN(m32.msg_iov)(void *)(uintptr_t) (m32.msg_iov); | |||
992 | msg->msg_iovlen = m32.msg_iovlen; | |||
993 | msg->msg_control = PTRIN(m32.msg_control)(void *)(uintptr_t) (m32.msg_control); | |||
994 | msg->msg_controllen = m32.msg_controllen; | |||
995 | msg->msg_flags = m32.msg_flags; | |||
996 | return (0); | |||
997 | } | |||
998 | ||||
999 | static int | |||
1000 | freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) | |||
1001 | { | |||
1002 | struct msghdr32 m32; | |||
1003 | int error; | |||
1004 | ||||
1005 | m32.msg_name = PTROUT(msg->msg_name)(u_int32_t)(uintptr_t) (msg->msg_name); | |||
1006 | m32.msg_namelen = msg->msg_namelen; | |||
1007 | m32.msg_iov = PTROUT(msg->msg_iov)(u_int32_t)(uintptr_t) (msg->msg_iov); | |||
1008 | m32.msg_iovlen = msg->msg_iovlen; | |||
1009 | m32.msg_control = PTROUT(msg->msg_control)(u_int32_t)(uintptr_t) (msg->msg_control); | |||
1010 | m32.msg_controllen = msg->msg_controllen; | |||
1011 | m32.msg_flags = msg->msg_flags; | |||
1012 | error = copyout(&m32, msg32, sizeof(m32)); | |||
1013 | return (error); | |||
1014 | } | |||
1015 | ||||
1016 | #ifndef __mips__ | |||
1017 | #define FREEBSD32_ALIGNBYTES(sizeof(int) - 1) (sizeof(int) - 1) | |||
1018 | #else | |||
1019 | #define FREEBSD32_ALIGNBYTES(sizeof(int) - 1) (sizeof(long) - 1) | |||
1020 | #endif | |||
1021 | #define FREEBSD32_ALIGN(p)(((u_long)(p) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) \ | |||
1022 | (((u_long)(p) + FREEBSD32_ALIGNBYTES(sizeof(int) - 1)) & ~FREEBSD32_ALIGNBYTES(sizeof(int) - 1)) | |||
1023 | #define FREEBSD32_CMSG_SPACE(l)((((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) + (((u_long)(l) + (sizeof(int) - 1)) & ~(sizeof(int) - 1))) \ | |||
1024 | (FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) + FREEBSD32_ALIGN(l)(((u_long)(l) + (sizeof(int) - 1)) & ~(sizeof(int) - 1))) | |||
1025 | ||||
1026 | #define FREEBSD32_CMSG_DATA(cmsg)((unsigned char *)(cmsg) + (((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1))) ((unsigned char *)(cmsg) + \ | |||
1027 | FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1))) | |||
1028 | ||||
1029 | static size_t | |||
1030 | freebsd32_cmsg_convert(const struct cmsghdr *cm, void *data, socklen_t datalen) | |||
1031 | { | |||
1032 | size_t copylen; | |||
1033 | union { | |||
1034 | struct timespec32 ts; | |||
1035 | struct timeval32 tv; | |||
1036 | struct bintime32 bt; | |||
1037 | } tmp32; | |||
1038 | ||||
1039 | union { | |||
1040 | struct timespec ts; | |||
1041 | struct timeval tv; | |||
1042 | struct bintime bt; | |||
1043 | } *in; | |||
1044 | ||||
1045 | in = data; | |||
1046 | copylen = 0; | |||
1047 | switch (cm->cmsg_level) { | |||
1048 | case SOL_SOCKET0xffff: | |||
1049 | switch (cm->cmsg_type) { | |||
1050 | case SCM_TIMESTAMP0x02: | |||
1051 | TV_CP(*in, tmp32, tv)do { do { ((tmp32).tv).tv_sec = ((*in).tv).tv_sec; } while (0 ); do { ((tmp32).tv).tv_usec = ((*in).tv).tv_usec; } while (0 ); } while (0); | |||
1052 | copylen = sizeof(tmp32.tv); | |||
1053 | break; | |||
1054 | ||||
1055 | case SCM_BINTIME0x04: | |||
1056 | BT_CP(*in, tmp32, bt)do { do { ((tmp32).bt).sec = ((*in).bt).sec; } while (0); *(uint64_t *)&(tmp32).bt.frac[0] = (*in).bt.frac; } while (0); | |||
1057 | copylen = sizeof(tmp32.bt); | |||
1058 | break; | |||
1059 | ||||
1060 | case SCM_REALTIME0x05: | |||
1061 | case SCM_MONOTONIC0x06: | |||
1062 | TS_CP(*in, tmp32, ts)do { do { ((tmp32).ts).tv_sec = ((*in).ts).tv_sec; } while (0 ); do { ((tmp32).ts).tv_nsec = ((*in).ts).tv_nsec; } while (0 ); } while (0); | |||
1063 | copylen = sizeof(tmp32.ts); | |||
1064 | break; | |||
1065 | ||||
1066 | default: | |||
1067 | break; | |||
1068 | } | |||
1069 | ||||
1070 | default: | |||
1071 | break; | |||
1072 | } | |||
1073 | ||||
1074 | if (copylen == 0) | |||
1075 | return (datalen); | |||
1076 | ||||
1077 | KASSERT((datalen >= copylen), ("corrupted cmsghdr"))do { if (__builtin_expect((!((datalen >= copylen))), 0)) panic ("corrupted cmsghdr"); } while (0); | |||
1078 | ||||
1079 | bcopy(&tmp32, data, copylen)__builtin_memmove((data), (&tmp32), (copylen)); | |||
1080 | return (copylen); | |||
1081 | } | |||
1082 | ||||
1083 | static int | |||
1084 | freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control) | |||
1085 | { | |||
1086 | struct cmsghdr *cm; | |||
1087 | void *data; | |||
1088 | socklen_t clen, datalen, datalen_out, oldclen; | |||
1089 | int error; | |||
1090 | caddr_t ctlbuf; | |||
1091 | int len, maxlen, copylen; | |||
1092 | struct mbuf *m; | |||
1093 | error = 0; | |||
1094 | ||||
1095 | len = msg->msg_controllen; | |||
1096 | maxlen = msg->msg_controllen; | |||
1097 | msg->msg_controllen = 0; | |||
1098 | ||||
1099 | ctlbuf = msg->msg_control; | |||
1100 | for (m = control; m != NULL((void *)0) && len > 0; m = m->m_next) { | |||
1101 | cm = mtod(m, struct cmsghdr *)((struct cmsghdr *)((m)->m_data)); | |||
1102 | clen = m->m_len; | |||
1103 | while (cm != NULL((void *)0)) { | |||
1104 | if (sizeof(struct cmsghdr) > clen || | |||
1105 | cm->cmsg_len > clen) { | |||
1106 | error = EINVAL22; | |||
1107 | break; | |||
1108 | } | |||
1109 | ||||
1110 | data = CMSG_DATA(cm)((unsigned char *)(cm) + (((__uintptr_t)(sizeof(struct cmsghdr )) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t) - 1))); | |||
1111 | datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; | |||
1112 | datalen_out = freebsd32_cmsg_convert(cm, data, datalen); | |||
1113 | ||||
1114 | /* | |||
1115 | * Copy out the message header. Preserve the native | |||
1116 | * message size in case we need to inspect the message | |||
1117 | * contents later. | |||
1118 | */ | |||
1119 | copylen = sizeof(struct cmsghdr); | |||
1120 | if (len < copylen) { | |||
1121 | msg->msg_flags |= MSG_CTRUNC0x00000020; | |||
1122 | m_dispose_extcontrolm(m); | |||
1123 | goto exit; | |||
1124 | } | |||
1125 | oldclen = cm->cmsg_len; | |||
1126 | cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) + | |||
1127 | datalen_out; | |||
1128 | error = copyout(cm, ctlbuf, copylen); | |||
1129 | cm->cmsg_len = oldclen; | |||
1130 | if (error != 0) | |||
1131 | goto exit; | |||
1132 | ||||
1133 | ctlbuf += FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1134 | len -= FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1135 | ||||
1136 | copylen = datalen_out; | |||
1137 | if (len < copylen) { | |||
1138 | msg->msg_flags |= MSG_CTRUNC0x00000020; | |||
1139 | m_dispose_extcontrolm(m); | |||
1140 | break; | |||
1141 | } | |||
1142 | ||||
1143 | /* Copy out the message data. */ | |||
1144 | error = copyout(data, ctlbuf, copylen); | |||
1145 | if (error) | |||
1146 | goto exit; | |||
1147 | ||||
1148 | ctlbuf += FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1149 | len -= FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1150 | ||||
1151 | if (CMSG_SPACE(datalen)((((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t ) - 1)) & ~(sizeof(__register_t) - 1)) + (((__uintptr_t)( datalen) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t ) - 1))) < clen) { | |||
1152 | clen -= CMSG_SPACE(datalen)((((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t ) - 1)) & ~(sizeof(__register_t) - 1)) + (((__uintptr_t)( datalen) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t ) - 1))); | |||
1153 | cm = (struct cmsghdr *) | |||
1154 | ((caddr_t)cm + CMSG_SPACE(datalen)((((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t ) - 1)) & ~(sizeof(__register_t) - 1)) + (((__uintptr_t)( datalen) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t ) - 1)))); | |||
1155 | } else { | |||
1156 | clen = 0; | |||
1157 | cm = NULL((void *)0); | |||
1158 | } | |||
1159 | ||||
1160 | msg->msg_controllen += FREEBSD32_ALIGN(sizeof(*cm))(((u_long)(sizeof(*cm)) + (sizeof(int) - 1)) & ~(sizeof(int ) - 1)) + | |||
1161 | datalen_out; | |||
1162 | } | |||
1163 | } | |||
1164 | if (len == 0 && m != NULL((void *)0)) { | |||
1165 | msg->msg_flags |= MSG_CTRUNC0x00000020; | |||
1166 | m_dispose_extcontrolm(m); | |||
1167 | } | |||
1168 | ||||
1169 | exit: | |||
1170 | return (error); | |||
1171 | } | |||
1172 | ||||
1173 | int | |||
1174 | freebsd32_recvmsg(td, uap) | |||
1175 | struct thread *td; | |||
1176 | struct freebsd32_recvmsg_args /* { | |||
1177 | int s; | |||
1178 | struct msghdr32 *msg; | |||
1179 | int flags; | |||
1180 | } */ *uap; | |||
1181 | { | |||
1182 | struct msghdr msg; | |||
1183 | struct msghdr32 m32; | |||
1184 | struct iovec *uiov, *iov; | |||
1185 | struct mbuf *control = NULL((void *)0); | |||
1186 | struct mbuf **controlp; | |||
1187 | ||||
1188 | int error; | |||
1189 | error = copyin(uap->msg, &m32, sizeof(m32)); | |||
1190 | if (error) | |||
1191 | return (error); | |||
1192 | error = freebsd32_copyinmsghdr(uap->msg, &msg); | |||
1193 | if (error) | |||
1194 | return (error); | |||
1195 | error = freebsd32_copyiniov(PTRIN(m32.msg_iov)(void *)(uintptr_t) (m32.msg_iov), m32.msg_iovlen, &iov, | |||
1196 | EMSGSIZE40); | |||
1197 | if (error) | |||
1198 | return (error); | |||
1199 | msg.msg_flags = uap->flags; | |||
1200 | uiov = msg.msg_iov; | |||
1201 | msg.msg_iov = iov; | |||
1202 | ||||
1203 | controlp = (msg.msg_control != NULL((void *)0)) ? &control : NULL((void *)0); | |||
1204 | error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp); | |||
1205 | if (error == 0) { | |||
1206 | msg.msg_iov = uiov; | |||
1207 | ||||
1208 | if (control != NULL((void *)0)) | |||
1209 | error = freebsd32_copy_msg_out(&msg, control); | |||
1210 | else | |||
1211 | msg.msg_controllen = 0; | |||
1212 | ||||
1213 | if (error == 0) | |||
1214 | error = freebsd32_copyoutmsghdr(&msg, uap->msg); | |||
1215 | } | |||
1216 | free(iov, M_IOV); | |||
1217 | ||||
1218 | if (control != NULL((void *)0)) { | |||
1219 | if (error != 0) | |||
1220 | m_dispose_extcontrolm(control); | |||
1221 | m_freem(control); | |||
1222 | } | |||
1223 | ||||
1224 | return (error); | |||
1225 | } | |||
1226 | ||||
1227 | /* | |||
1228 | * Copy-in the array of control messages constructed using alignment | |||
1229 | * and padding suitable for a 32-bit environment and construct an | |||
1230 | * mbuf using alignment and padding suitable for a 64-bit kernel. | |||
1231 | * The alignment and padding are defined indirectly by CMSG_DATA(), | |||
1232 | * CMSG_SPACE() and CMSG_LEN(). | |||
1233 | */ | |||
1234 | static int | |||
1235 | freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen) | |||
1236 | { | |||
1237 | struct mbuf *m; | |||
1238 | void *md; | |||
1239 | u_int idx, len, msglen; | |||
1240 | int error; | |||
1241 | ||||
1242 | buflen = FREEBSD32_ALIGN(buflen)(((u_long)(buflen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1243 | ||||
1244 | if (buflen > MCLBYTES(1 << 11)) | |||
1245 | return (EINVAL22); | |||
1246 | ||||
1247 | /* | |||
1248 | * Iterate over the buffer and get the length of each message | |||
1249 | * in there. This has 32-bit alignment and padding. Use it to | |||
1250 | * determine the length of these messages when using 64-bit | |||
1251 | * alignment and padding. | |||
1252 | */ | |||
1253 | idx = 0; | |||
1254 | len = 0; | |||
1255 | while (idx < buflen) { | |||
1256 | error = copyin(buf + idx, &msglen, sizeof(msglen)); | |||
1257 | if (error) | |||
1258 | return (error); | |||
1259 | if (msglen < sizeof(struct cmsghdr)) | |||
1260 | return (EINVAL22); | |||
1261 | msglen = FREEBSD32_ALIGN(msglen)(((u_long)(msglen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1262 | if (idx + msglen > buflen) | |||
1263 | return (EINVAL22); | |||
1264 | idx += msglen; | |||
1265 | msglen += CMSG_ALIGN(sizeof(struct cmsghdr))(((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t ) - 1)) & ~(sizeof(__register_t) - 1)) - | |||
1266 | FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1267 | len += CMSG_ALIGN(msglen)(((__uintptr_t)(msglen) + (sizeof(__register_t) - 1)) & ~ (sizeof(__register_t) - 1)); | |||
1268 | } | |||
1269 | ||||
1270 | if (len > MCLBYTES(1 << 11)) | |||
1271 | return (EINVAL22); | |||
1272 | ||||
1273 | m = m_get(M_WAITOK0x0002, MT_CONTROL14); | |||
1274 | if (len > MLEN((int)(256 - __builtin_offsetof(struct mbuf, m_dat)))) | |||
1275 | MCLGET(m, M_WAITOK)m_clget((m), (0x0002)); | |||
1276 | m->m_len = len; | |||
1277 | ||||
1278 | md = mtod(m, void *)((void *)((m)->m_data)); | |||
1279 | while (buflen > 0) { | |||
1280 | error = copyin(buf, md, sizeof(struct cmsghdr)); | |||
1281 | if (error) | |||
1282 | break; | |||
1283 | msglen = *(u_int *)md; | |||
1284 | msglen = FREEBSD32_ALIGN(msglen)(((u_long)(msglen) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1285 | ||||
1286 | /* Modify the message length to account for alignment. */ | |||
1287 | *(u_int *)md = msglen + CMSG_ALIGN(sizeof(struct cmsghdr))(((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t ) - 1)) & ~(sizeof(__register_t) - 1)) - | |||
1288 | FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1289 | ||||
1290 | md = (char *)md + CMSG_ALIGN(sizeof(struct cmsghdr))(((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t ) - 1)) & ~(sizeof(__register_t) - 1)); | |||
1291 | buf += FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1292 | buflen -= FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1293 | ||||
1294 | msglen -= FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)); | |||
1295 | if (msglen > 0) { | |||
1296 | error = copyin(buf, md, msglen); | |||
1297 | if (error) | |||
1298 | break; | |||
1299 | md = (char *)md + CMSG_ALIGN(msglen)(((__uintptr_t)(msglen) + (sizeof(__register_t) - 1)) & ~ (sizeof(__register_t) - 1)); | |||
1300 | buf += msglen; | |||
1301 | buflen -= msglen; | |||
1302 | } | |||
1303 | } | |||
1304 | ||||
1305 | if (error) | |||
1306 | m_free(m); | |||
1307 | else | |||
1308 | *mp = m; | |||
1309 | return (error); | |||
1310 | } | |||
1311 | ||||
1312 | int | |||
1313 | freebsd32_sendmsg(struct thread *td, | |||
1314 | struct freebsd32_sendmsg_args *uap) | |||
1315 | { | |||
1316 | struct msghdr msg; | |||
1317 | struct msghdr32 m32; | |||
1318 | struct iovec *iov; | |||
1319 | struct mbuf *control = NULL((void *)0); | |||
1320 | struct sockaddr *to = NULL((void *)0); | |||
1321 | int error; | |||
1322 | ||||
1323 | error = copyin(uap->msg, &m32, sizeof(m32)); | |||
1324 | if (error) | |||
1325 | return (error); | |||
1326 | error = freebsd32_copyinmsghdr(uap->msg, &msg); | |||
1327 | if (error) | |||
1328 | return (error); | |||
1329 | error = freebsd32_copyiniov(PTRIN(m32.msg_iov)(void *)(uintptr_t) (m32.msg_iov), m32.msg_iovlen, &iov, | |||
1330 | EMSGSIZE40); | |||
1331 | if (error) | |||
1332 | return (error); | |||
1333 | msg.msg_iov = iov; | |||
1334 | if (msg.msg_name != NULL((void *)0)) { | |||
1335 | error = getsockaddr(&to, msg.msg_name, msg.msg_namelen); | |||
1336 | if (error) { | |||
1337 | to = NULL((void *)0); | |||
1338 | goto out; | |||
1339 | } | |||
1340 | msg.msg_name = to; | |||
1341 | } | |||
1342 | ||||
1343 | if (msg.msg_control) { | |||
1344 | if (msg.msg_controllen < sizeof(struct cmsghdr)) { | |||
1345 | error = EINVAL22; | |||
1346 | goto out; | |||
1347 | } | |||
1348 | ||||
1349 | error = freebsd32_copyin_control(&control, msg.msg_control, | |||
1350 | msg.msg_controllen); | |||
1351 | if (error) | |||
1352 | goto out; | |||
1353 | ||||
1354 | msg.msg_control = NULL((void *)0); | |||
1355 | msg.msg_controllen = 0; | |||
1356 | } | |||
1357 | ||||
1358 | error = kern_sendit(td, uap->s, &msg, uap->flags, control, | |||
1359 | UIO_USERSPACE); | |||
1360 | ||||
1361 | out: | |||
1362 | free(iov, M_IOV); | |||
1363 | if (to) | |||
1364 | free(to, M_SONAME); | |||
1365 | return (error); | |||
1366 | } | |||
1367 | ||||
1368 | int | |||
1369 | freebsd32_recvfrom(struct thread *td, | |||
1370 | struct freebsd32_recvfrom_args *uap) | |||
1371 | { | |||
1372 | struct msghdr msg; | |||
1373 | struct iovec aiov; | |||
1374 | int error; | |||
1375 | ||||
1376 | if (uap->fromlenaddr) { | |||
1377 | error = copyin(PTRIN(uap->fromlenaddr)(void *)(uintptr_t) (uap->fromlenaddr), &msg.msg_namelen, | |||
1378 | sizeof(msg.msg_namelen)); | |||
1379 | if (error) | |||
1380 | return (error); | |||
1381 | } else { | |||
1382 | msg.msg_namelen = 0; | |||
1383 | } | |||
1384 | ||||
1385 | msg.msg_name = PTRIN(uap->from)(void *)(uintptr_t) (uap->from); | |||
1386 | msg.msg_iov = &aiov; | |||
1387 | msg.msg_iovlen = 1; | |||
1388 | aiov.iov_base = PTRIN(uap->buf)(void *)(uintptr_t) (uap->buf); | |||
1389 | aiov.iov_len = uap->len; | |||
1390 | msg.msg_control = NULL((void *)0); | |||
1391 | msg.msg_flags = uap->flags; | |||
1392 | error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL((void *)0)); | |||
1393 | if (error == 0 && uap->fromlenaddr) | |||
1394 | error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr)(void *)(uintptr_t) (uap->fromlenaddr), | |||
1395 | sizeof (msg.msg_namelen)); | |||
1396 | return (error); | |||
1397 | } | |||
1398 | ||||
1399 | int | |||
1400 | freebsd32_settimeofday(struct thread *td, | |||
1401 | struct freebsd32_settimeofday_args *uap) | |||
1402 | { | |||
1403 | struct timeval32 tv32; | |||
1404 | struct timeval tv, *tvp; | |||
1405 | struct timezone tz, *tzp; | |||
1406 | int error; | |||
1407 | ||||
1408 | if (uap->tv) { | |||
1409 | error = copyin(uap->tv, &tv32, sizeof(tv32)); | |||
1410 | if (error) | |||
1411 | return (error); | |||
1412 | CP(tv32, tv, tv_sec)do { (tv).tv_sec = (tv32).tv_sec; } while (0); | |||
1413 | CP(tv32, tv, tv_usec)do { (tv).tv_usec = (tv32).tv_usec; } while (0); | |||
1414 | tvp = &tv; | |||
1415 | } else | |||
1416 | tvp = NULL((void *)0); | |||
1417 | if (uap->tzp) { | |||
1418 | error = copyin(uap->tzp, &tz, sizeof(tz)); | |||
1419 | if (error) | |||
1420 | return (error); | |||
1421 | tzp = &tz; | |||
1422 | } else | |||
1423 | tzp = NULL((void *)0); | |||
1424 | return (kern_settimeofday(td, tvp, tzp)); | |||
1425 | } | |||
1426 | ||||
1427 | int | |||
1428 | freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) | |||
1429 | { | |||
1430 | struct timeval32 s32[2]; | |||
1431 | struct timeval s[2], *sp; | |||
1432 | int error; | |||
1433 | ||||
1434 | if (uap->tptr != NULL((void *)0)) { | |||
1435 | error = copyin(uap->tptr, s32, sizeof(s32)); | |||
1436 | if (error) | |||
1437 | return (error); | |||
1438 | CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0); | |||
1439 | CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0); | |||
1440 | CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0); | |||
1441 | CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0); | |||
1442 | sp = s; | |||
1443 | } else | |||
1444 | sp = NULL((void *)0); | |||
1445 | return (kern_utimesat(td, AT_FDCWD-100, uap->path, UIO_USERSPACE, | |||
1446 | sp, UIO_SYSSPACE)); | |||
1447 | } | |||
1448 | ||||
1449 | int | |||
1450 | freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap) | |||
1451 | { | |||
1452 | struct timeval32 s32[2]; | |||
1453 | struct timeval s[2], *sp; | |||
1454 | int error; | |||
1455 | ||||
1456 | if (uap->tptr != NULL((void *)0)) { | |||
1457 | error = copyin(uap->tptr, s32, sizeof(s32)); | |||
1458 | if (error) | |||
1459 | return (error); | |||
1460 | CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0); | |||
1461 | CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0); | |||
1462 | CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0); | |||
1463 | CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0); | |||
1464 | sp = s; | |||
1465 | } else | |||
1466 | sp = NULL((void *)0); | |||
1467 | return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); | |||
1468 | } | |||
1469 | ||||
1470 | int | |||
1471 | freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap) | |||
1472 | { | |||
1473 | struct timeval32 s32[2]; | |||
1474 | struct timeval s[2], *sp; | |||
1475 | int error; | |||
1476 | ||||
1477 | if (uap->tptr != NULL((void *)0)) { | |||
1478 | error = copyin(uap->tptr, s32, sizeof(s32)); | |||
1479 | if (error) | |||
1480 | return (error); | |||
1481 | CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0); | |||
1482 | CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0); | |||
1483 | CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0); | |||
1484 | CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0); | |||
1485 | sp = s; | |||
1486 | } else | |||
1487 | sp = NULL((void *)0); | |||
1488 | return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE)); | |||
1489 | } | |||
1490 | ||||
1491 | int | |||
1492 | freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap) | |||
1493 | { | |||
1494 | struct timeval32 s32[2]; | |||
1495 | struct timeval s[2], *sp; | |||
1496 | int error; | |||
1497 | ||||
1498 | if (uap->times != NULL((void *)0)) { | |||
1499 | error = copyin(uap->times, s32, sizeof(s32)); | |||
1500 | if (error) | |||
1501 | return (error); | |||
1502 | CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0); | |||
1503 | CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0); | |||
1504 | CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0); | |||
1505 | CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0); | |||
1506 | sp = s; | |||
1507 | } else | |||
1508 | sp = NULL((void *)0); | |||
1509 | return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, | |||
1510 | sp, UIO_SYSSPACE)); | |||
1511 | } | |||
1512 | ||||
1513 | int | |||
1514 | freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap) | |||
1515 | { | |||
1516 | struct timespec32 ts32[2]; | |||
1517 | struct timespec ts[2], *tsp; | |||
1518 | int error; | |||
1519 | ||||
1520 | if (uap->times != NULL((void *)0)) { | |||
1521 | error = copyin(uap->times, ts32, sizeof(ts32)); | |||
1522 | if (error) | |||
1523 | return (error); | |||
1524 | CP(ts32[0], ts[0], tv_sec)do { (ts[0]).tv_sec = (ts32[0]).tv_sec; } while (0); | |||
1525 | CP(ts32[0], ts[0], tv_nsec)do { (ts[0]).tv_nsec = (ts32[0]).tv_nsec; } while (0); | |||
1526 | CP(ts32[1], ts[1], tv_sec)do { (ts[1]).tv_sec = (ts32[1]).tv_sec; } while (0); | |||
1527 | CP(ts32[1], ts[1], tv_nsec)do { (ts[1]).tv_nsec = (ts32[1]).tv_nsec; } while (0); | |||
1528 | tsp = ts; | |||
1529 | } else | |||
1530 | tsp = NULL((void *)0); | |||
1531 | return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE)); | |||
1532 | } | |||
1533 | ||||
1534 | int | |||
1535 | freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap) | |||
1536 | { | |||
1537 | struct timespec32 ts32[2]; | |||
1538 | struct timespec ts[2], *tsp; | |||
1539 | int error; | |||
1540 | ||||
1541 | if (uap->times != NULL((void *)0)) { | |||
1542 | error = copyin(uap->times, ts32, sizeof(ts32)); | |||
1543 | if (error) | |||
1544 | return (error); | |||
1545 | CP(ts32[0], ts[0], tv_sec)do { (ts[0]).tv_sec = (ts32[0]).tv_sec; } while (0); | |||
1546 | CP(ts32[0], ts[0], tv_nsec)do { (ts[0]).tv_nsec = (ts32[0]).tv_nsec; } while (0); | |||
1547 | CP(ts32[1], ts[1], tv_sec)do { (ts[1]).tv_sec = (ts32[1]).tv_sec; } while (0); | |||
1548 | CP(ts32[1], ts[1], tv_nsec)do { (ts[1]).tv_nsec = (ts32[1]).tv_nsec; } while (0); | |||
1549 | tsp = ts; | |||
1550 | } else | |||
1551 | tsp = NULL((void *)0); | |||
1552 | return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE, | |||
1553 | tsp, UIO_SYSSPACE, uap->flag)); | |||
1554 | } | |||
1555 | ||||
1556 | int | |||
1557 | freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) | |||
1558 | { | |||
1559 | struct timeval32 tv32; | |||
1560 | struct timeval delta, olddelta, *deltap; | |||
1561 | int error; | |||
1562 | ||||
1563 | if (uap->delta) { | |||
1564 | error = copyin(uap->delta, &tv32, sizeof(tv32)); | |||
1565 | if (error) | |||
1566 | return (error); | |||
1567 | CP(tv32, delta, tv_sec)do { (delta).tv_sec = (tv32).tv_sec; } while (0); | |||
1568 | CP(tv32, delta, tv_usec)do { (delta).tv_usec = (tv32).tv_usec; } while (0); | |||
1569 | deltap = δ | |||
1570 | } else | |||
1571 | deltap = NULL((void *)0); | |||
1572 | error = kern_adjtime(td, deltap, &olddelta); | |||
1573 | if (uap->olddelta && error == 0) { | |||
1574 | CP(olddelta, tv32, tv_sec)do { (tv32).tv_sec = (olddelta).tv_sec; } while (0); | |||
1575 | CP(olddelta, tv32, tv_usec)do { (tv32).tv_usec = (olddelta).tv_usec; } while (0); | |||
1576 | error = copyout(&tv32, uap->olddelta, sizeof(tv32)); | |||
1577 | } | |||
1578 | return (error); | |||
1579 | } | |||
1580 | ||||
1581 | #ifdef COMPAT_FREEBSD41 | |||
1582 | int | |||
1583 | freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) | |||
1584 | { | |||
1585 | struct statfs32 s32; | |||
1586 | struct statfs *sp; | |||
1587 | int error; | |||
1588 | ||||
1589 | sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK0x0002); | |||
1590 | error = kern_statfs(td, uap->path, UIO_USERSPACE, sp); | |||
1591 | if (error == 0) { | |||
1592 | copy_statfs(sp, &s32); | |||
1593 | error = copyout(&s32, uap->buf, sizeof(s32)); | |||
1594 | } | |||
1595 | free(sp, M_STATFS); | |||
1596 | return (error); | |||
1597 | } | |||
1598 | #endif | |||
1599 | ||||
1600 | #ifdef COMPAT_FREEBSD41 | |||
1601 | int | |||
1602 | freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) | |||
1603 | { | |||
1604 | struct statfs32 s32; | |||
1605 | struct statfs *sp; | |||
1606 | int error; | |||
1607 | ||||
1608 | sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK0x0002); | |||
1609 | error = kern_fstatfs(td, uap->fd, sp); | |||
1610 | if (error == 0) { | |||
1611 | copy_statfs(sp, &s32); | |||
1612 | error = copyout(&s32, uap->buf, sizeof(s32)); | |||
1613 | } | |||
1614 | free(sp, M_STATFS); | |||
1615 | return (error); | |||
1616 | } | |||
1617 | #endif | |||
1618 | ||||
1619 | #ifdef COMPAT_FREEBSD41 | |||
1620 | int | |||
1621 | freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) | |||
1622 | { | |||
1623 | struct statfs32 s32; | |||
1624 | struct statfs *sp; | |||
1625 | fhandle_t fh; | |||
1626 | int error; | |||
1627 | ||||
1628 | if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) | |||
1629 | return (error); | |||
1630 | sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK0x0002); | |||
1631 | error = kern_fhstatfs(td, fh, sp); | |||
1632 | if (error == 0) { | |||
1633 | copy_statfs(sp, &s32); | |||
1634 | error = copyout(&s32, uap->buf, sizeof(s32)); | |||
1635 | } | |||
1636 | free(sp, M_STATFS); | |||
1637 | return (error); | |||
1638 | } | |||
1639 | #endif | |||
1640 | ||||
1641 | int | |||
1642 | freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) | |||
1643 | { | |||
1644 | ||||
1645 | return (kern_pread(td, uap->fd, uap->buf, uap->nbyte, | |||
1646 | PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)))); | |||
1647 | } | |||
1648 | ||||
1649 | int | |||
1650 | freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) | |||
1651 | { | |||
1652 | ||||
1653 | return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, | |||
1654 | PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)))); | |||
1655 | } | |||
1656 | ||||
1657 | #ifdef COMPAT_43 | |||
1658 | int | |||
1659 | ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap) | |||
1660 | { | |||
1661 | ||||
1662 | return (kern_lseek(td, uap->fd, uap->offset, uap->whence)); | |||
1663 | } | |||
1664 | #endif | |||
1665 | ||||
1666 | int | |||
1667 | freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) | |||
1668 | { | |||
1669 | int error; | |||
1670 | off_t pos; | |||
1671 | ||||
1672 | error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)), | |||
1673 | uap->whence); | |||
1674 | /* Expand the quad return into two parts for eax and edx */ | |||
1675 | pos = td->td_uretoff.tdu_off; | |||
1676 | td->td_retvaltd_uretoff.tdu_retval[RETVAL_LO0] = pos & 0xffffffff; /* %eax */ | |||
1677 | td->td_retvaltd_uretoff.tdu_retval[RETVAL_HI1] = pos >> 32; /* %edx */ | |||
1678 | return error; | |||
1679 | } | |||
1680 | ||||
1681 | int | |||
1682 | freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) | |||
1683 | { | |||
1684 | ||||
1685 | return (kern_truncate(td, uap->path, UIO_USERSPACE, | |||
1686 | PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32)))); | |||
1687 | } | |||
1688 | ||||
1689 | int | |||
1690 | freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) | |||
1691 | { | |||
1692 | ||||
1693 | return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32)))); | |||
1694 | } | |||
1695 | ||||
1696 | #ifdef COMPAT_43 | |||
1697 | int | |||
1698 | ofreebsd32_getdirentries(struct thread *td, | |||
1699 | struct ofreebsd32_getdirentries_args *uap) | |||
1700 | { | |||
1701 | struct ogetdirentries_args ap; | |||
1702 | int error; | |||
1703 | long loff; | |||
1704 | int32_t loff_cut; | |||
1705 | ||||
1706 | ap.fd = uap->fd; | |||
1707 | ap.buf = uap->buf; | |||
1708 | ap.count = uap->count; | |||
1709 | ap.basep = NULL((void *)0); | |||
1710 | error = kern_ogetdirentries(td, &ap, &loff); | |||
1711 | if (error == 0) { | |||
1712 | loff_cut = loff; | |||
1713 | error = copyout(&loff_cut, uap->basep, sizeof(int32_t)); | |||
1714 | } | |||
1715 | return (error); | |||
1716 | } | |||
1717 | #endif | |||
1718 | ||||
1719 | #if defined(COMPAT_FREEBSD111) | |||
1720 | int | |||
1721 | freebsd11_freebsd32_getdirentries(struct thread *td, | |||
1722 | struct freebsd11_freebsd32_getdirentries_args *uap) | |||
1723 | { | |||
1724 | long base; | |||
1725 | int32_t base32; | |||
1726 | int error; | |||
1727 | ||||
1728 | error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count, | |||
1729 | &base, NULL((void *)0)); | |||
1730 | if (error) | |||
1731 | return (error); | |||
1732 | if (uap->basep != NULL((void *)0)) { | |||
1733 | base32 = base; | |||
1734 | error = copyout(&base32, uap->basep, sizeof(int32_t)); | |||
1735 | } | |||
1736 | return (error); | |||
1737 | } | |||
1738 | ||||
1739 | int | |||
1740 | freebsd11_freebsd32_getdents(struct thread *td, | |||
1741 | struct freebsd11_freebsd32_getdents_args *uap) | |||
1742 | { | |||
1743 | struct freebsd11_freebsd32_getdirentries_args ap; | |||
1744 | ||||
1745 | ap.fd = uap->fd; | |||
1746 | ap.buf = uap->buf; | |||
1747 | ap.count = uap->count; | |||
1748 | ap.basep = NULL((void *)0); | |||
1749 | return (freebsd11_freebsd32_getdirentries(td, &ap)); | |||
1750 | } | |||
1751 | #endif /* COMPAT_FREEBSD11 */ | |||
1752 | ||||
1753 | #ifdef COMPAT_FREEBSD61 | |||
1754 | /* versions with the 'int pad' argument */ | |||
1755 | int | |||
1756 | freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap) | |||
1757 | { | |||
1758 | ||||
1759 | return (kern_pread(td, uap->fd, uap->buf, uap->nbyte, | |||
1760 | PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)))); | |||
1761 | } | |||
1762 | ||||
1763 | int | |||
1764 | freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap) | |||
1765 | { | |||
1766 | ||||
1767 | return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, | |||
1768 | PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)))); | |||
1769 | } | |||
1770 | ||||
1771 | int | |||
1772 | freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap) | |||
1773 | { | |||
1774 | int error; | |||
1775 | off_t pos; | |||
1776 | ||||
1777 | error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)), | |||
1778 | uap->whence); | |||
1779 | /* Expand the quad return into two parts for eax and edx */ | |||
1780 | pos = *(off_t *)(td->td_retvaltd_uretoff.tdu_retval); | |||
1781 | td->td_retvaltd_uretoff.tdu_retval[RETVAL_LO0] = pos & 0xffffffff; /* %eax */ | |||
1782 | td->td_retvaltd_uretoff.tdu_retval[RETVAL_HI1] = pos >> 32; /* %edx */ | |||
1783 | return error; | |||
1784 | } | |||
1785 | ||||
1786 | int | |||
1787 | freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap) | |||
1788 | { | |||
1789 | ||||
1790 | return (kern_truncate(td, uap->path, UIO_USERSPACE, | |||
1791 | PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32)))); | |||
1792 | } | |||
1793 | ||||
1794 | int | |||
1795 | freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap) | |||
1796 | { | |||
1797 | ||||
1798 | return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32)))); | |||
1799 | } | |||
1800 | #endif /* COMPAT_FREEBSD6 */ | |||
1801 | ||||
1802 | struct sf_hdtr32 { | |||
1803 | uint32_t headers; | |||
1804 | int hdr_cnt; | |||
1805 | uint32_t trailers; | |||
1806 | int trl_cnt; | |||
1807 | }; | |||
1808 | ||||
1809 | static int | |||
1810 | freebsd32_do_sendfile(struct thread *td, | |||
1811 | struct freebsd32_sendfile_args *uap, int compat) | |||
1812 | { | |||
1813 | struct sf_hdtr32 hdtr32; | |||
1814 | struct sf_hdtr hdtr; | |||
1815 | struct uio *hdr_uio, *trl_uio; | |||
1816 | struct file *fp; | |||
1817 | cap_rights_t rights; | |||
1818 | struct iovec32 *iov32; | |||
1819 | off_t offset, sbytes; | |||
1820 | int error; | |||
1821 | ||||
1822 | offset = PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)); | |||
1823 | if (offset < 0) | |||
1824 | return (EINVAL22); | |||
1825 | ||||
1826 | hdr_uio = trl_uio = NULL((void *)0); | |||
1827 | ||||
1828 | if (uap->hdtr != NULL((void *)0)) { | |||
1829 | error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); | |||
1830 | if (error) | |||
1831 | goto out; | |||
1832 | PTRIN_CP(hdtr32, hdtr, headers)do { (hdtr).headers = (void *)(uintptr_t) ((hdtr32).headers); } while (0); | |||
1833 | CP(hdtr32, hdtr, hdr_cnt)do { (hdtr).hdr_cnt = (hdtr32).hdr_cnt; } while (0); | |||
1834 | PTRIN_CP(hdtr32, hdtr, trailers)do { (hdtr).trailers = (void *)(uintptr_t) ((hdtr32).trailers ); } while (0); | |||
1835 | CP(hdtr32, hdtr, trl_cnt)do { (hdtr).trl_cnt = (hdtr32).trl_cnt; } while (0); | |||
1836 | ||||
1837 | if (hdtr.headers != NULL((void *)0)) { | |||
1838 | iov32 = PTRIN(hdtr32.headers)(void *)(uintptr_t) (hdtr32.headers); | |||
1839 | error = freebsd32_copyinuio(iov32, | |||
1840 | hdtr32.hdr_cnt, &hdr_uio); | |||
1841 | if (error) | |||
1842 | goto out; | |||
1843 | #ifdef COMPAT_FREEBSD41 | |||
1844 | /* | |||
1845 | * In FreeBSD < 5.0 the nbytes to send also included | |||
1846 | * the header. If compat is specified subtract the | |||
1847 | * header size from nbytes. | |||
1848 | */ | |||
1849 | if (compat) { | |||
1850 | if (uap->nbytes > hdr_uio->uio_resid) | |||
1851 | uap->nbytes -= hdr_uio->uio_resid; | |||
1852 | else | |||
1853 | uap->nbytes = 0; | |||
1854 | } | |||
1855 | #endif | |||
1856 | } | |||
1857 | if (hdtr.trailers != NULL((void *)0)) { | |||
1858 | iov32 = PTRIN(hdtr32.trailers)(void *)(uintptr_t) (hdtr32.trailers); | |||
1859 | error = freebsd32_copyinuio(iov32, | |||
1860 | hdtr32.trl_cnt, &trl_uio); | |||
1861 | if (error) | |||
1862 | goto out; | |||
1863 | } | |||
1864 | } | |||
1865 | ||||
1866 | AUDIT_ARG_FD(uap->fd)do { if ((__builtin_expect((((__curthread()))->td_pflags & 0x01000000), 0))) audit_arg_fd((uap->fd)); } while (0); | |||
1867 | ||||
1868 | if ((error = fget_read(td, uap->fd, | |||
1869 | cap_rights_init(&rights, CAP_PREAD)__cap_rights_init(0, &rights, ((((1ULL << (57 + (0) )) | (0x0000000000000004ULL)) | 0x0000000000000008ULL) | ((1ULL << (57 + (0))) | (0x0000000000000001ULL))), 0ULL), &fp)) != 0) | |||
1870 | goto out; | |||
1871 | ||||
1872 | error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, | |||
1873 | uap->nbytes, &sbytes, uap->flags, td); | |||
1874 | fdrop(fp, td)(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop()); | |||
1875 | ||||
1876 | if (uap->sbytes != NULL((void *)0)) | |||
1877 | copyout(&sbytes, uap->sbytes, sizeof(off_t)); | |||
1878 | ||||
1879 | out: | |||
1880 | if (hdr_uio) | |||
1881 | free(hdr_uio, M_IOV); | |||
1882 | if (trl_uio) | |||
1883 | free(trl_uio, M_IOV); | |||
1884 | return (error); | |||
1885 | } | |||
1886 | ||||
1887 | #ifdef COMPAT_FREEBSD41 | |||
1888 | int | |||
1889 | freebsd4_freebsd32_sendfile(struct thread *td, | |||
1890 | struct freebsd4_freebsd32_sendfile_args *uap) | |||
1891 | { | |||
1892 | return (freebsd32_do_sendfile(td, | |||
1893 | (struct freebsd32_sendfile_args *)uap, 1)); | |||
1894 | } | |||
1895 | #endif | |||
1896 | ||||
1897 | int | |||
1898 | freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) | |||
1899 | { | |||
1900 | ||||
1901 | return (freebsd32_do_sendfile(td, uap, 0)); | |||
1902 | } | |||
1903 | ||||
1904 | static void | |||
1905 | copy_stat(struct stat *in, struct stat32 *out) | |||
1906 | { | |||
1907 | ||||
1908 | CP(*in, *out, st_dev)do { (*out).st_dev = (*in).st_dev; } while (0); | |||
1909 | CP(*in, *out, st_ino)do { (*out).st_ino = (*in).st_ino; } while (0); | |||
1910 | CP(*in, *out, st_mode)do { (*out).st_mode = (*in).st_mode; } while (0); | |||
1911 | CP(*in, *out, st_nlink)do { (*out).st_nlink = (*in).st_nlink; } while (0); | |||
1912 | CP(*in, *out, st_uid)do { (*out).st_uid = (*in).st_uid; } while (0); | |||
1913 | CP(*in, *out, st_gid)do { (*out).st_gid = (*in).st_gid; } while (0); | |||
1914 | CP(*in, *out, st_rdev)do { (*out).st_rdev = (*in).st_rdev; } while (0); | |||
1915 | TS_CP(*in, *out, st_atim)do { do { ((*out).st_atim).tv_sec = ((*in).st_atim).tv_sec; } while (0); do { ((*out).st_atim).tv_nsec = ((*in).st_atim).tv_nsec ; } while (0); } while (0); | |||
1916 | TS_CP(*in, *out, st_mtim)do { do { ((*out).st_mtim).tv_sec = ((*in).st_mtim).tv_sec; } while (0); do { ((*out).st_mtim).tv_nsec = ((*in).st_mtim).tv_nsec ; } while (0); } while (0); | |||
1917 | TS_CP(*in, *out, st_ctim)do { do { ((*out).st_ctim).tv_sec = ((*in).st_ctim).tv_sec; } while (0); do { ((*out).st_ctim).tv_nsec = ((*in).st_ctim).tv_nsec ; } while (0); } while (0); | |||
1918 | CP(*in, *out, st_size)do { (*out).st_size = (*in).st_size; } while (0); | |||
1919 | CP(*in, *out, st_blocks)do { (*out).st_blocks = (*in).st_blocks; } while (0); | |||
1920 | CP(*in, *out, st_blksize)do { (*out).st_blksize = (*in).st_blksize; } while (0); | |||
1921 | CP(*in, *out, st_flags)do { (*out).st_flags = (*in).st_flags; } while (0); | |||
1922 | CP(*in, *out, st_gen)do { (*out).st_gen = (*in).st_gen; } while (0); | |||
1923 | TS_CP(*in, *out, st_birthtim)do { do { ((*out).st_birthtim).tv_sec = ((*in).st_birthtim).tv_sec ; } while (0); do { ((*out).st_birthtim).tv_nsec = ((*in).st_birthtim ).tv_nsec; } while (0); } while (0); | |||
1924 | out->st_padding0 = 0; | |||
1925 | out->st_padding1 = 0; | |||
1926 | #ifdef __STAT32_TIME_T_EXT1 | |||
1927 | out->st_atim_ext = 0; | |||
1928 | out->st_mtim_ext = 0; | |||
1929 | out->st_ctim_ext = 0; | |||
1930 | out->st_btim_ext = 0; | |||
1931 | #endif | |||
1932 | bzero(out->st_spare, sizeof(out->st_spare))__builtin_memset((out->st_spare), 0, (sizeof(out->st_spare ))); | |||
1933 | } | |||
1934 | ||||
1935 | #ifdef COMPAT_43 | |||
1936 | static void | |||
1937 | copy_ostat(struct stat *in, struct ostat32 *out) | |||
1938 | { | |||
1939 | ||||
1940 | bzero(out, sizeof(*out))__builtin_memset((out), 0, (sizeof(*out))); | |||
1941 | CP(*in, *out, st_dev)do { (*out).st_dev = (*in).st_dev; } while (0); | |||
1942 | CP(*in, *out, st_ino)do { (*out).st_ino = (*in).st_ino; } while (0); | |||
1943 | CP(*in, *out, st_mode)do { (*out).st_mode = (*in).st_mode; } while (0); | |||
1944 | CP(*in, *out, st_nlink)do { (*out).st_nlink = (*in).st_nlink; } while (0); | |||
1945 | CP(*in, *out, st_uid)do { (*out).st_uid = (*in).st_uid; } while (0); | |||
1946 | CP(*in, *out, st_gid)do { (*out).st_gid = (*in).st_gid; } while (0); | |||
1947 | CP(*in, *out, st_rdev)do { (*out).st_rdev = (*in).st_rdev; } while (0); | |||
1948 | out->st_size = MIN(in->st_size, INT32_MAX)(((in->st_size)<(0x7fffffff))?(in->st_size):(0x7fffffff )); | |||
1949 | TS_CP(*in, *out, st_atim)do { do { ((*out).st_atim).tv_sec = ((*in).st_atim).tv_sec; } while (0); do { ((*out).st_atim).tv_nsec = ((*in).st_atim).tv_nsec ; } while (0); } while (0); | |||
1950 | TS_CP(*in, *out, st_mtim)do { do { ((*out).st_mtim).tv_sec = ((*in).st_mtim).tv_sec; } while (0); do { ((*out).st_mtim).tv_nsec = ((*in).st_mtim).tv_nsec ; } while (0); } while (0); | |||
1951 | TS_CP(*in, *out, st_ctim)do { do { ((*out).st_ctim).tv_sec = ((*in).st_ctim).tv_sec; } while (0); do { ((*out).st_ctim).tv_nsec = ((*in).st_ctim).tv_nsec ; } while (0); } while (0); | |||
1952 | CP(*in, *out, st_blksize)do { (*out).st_blksize = (*in).st_blksize; } while (0); | |||
1953 | CP(*in, *out, st_blocks)do { (*out).st_blocks = (*in).st_blocks; } while (0); | |||
1954 | CP(*in, *out, st_flags)do { (*out).st_flags = (*in).st_flags; } while (0); | |||
1955 | CP(*in, *out, st_gen)do { (*out).st_gen = (*in).st_gen; } while (0); | |||
1956 | } | |||
1957 | #endif | |||
1958 | ||||
1959 | #ifdef COMPAT_43 | |||
1960 | int | |||
1961 | ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap) | |||
1962 | { | |||
1963 | struct stat sb; | |||
1964 | struct ostat32 sb32; | |||
1965 | int error; | |||
1966 | ||||
1967 | error = kern_statat(td, 0, AT_FDCWD-100, uap->path, UIO_USERSPACE, | |||
1968 | &sb, NULL((void *)0)); | |||
1969 | if (error) | |||
1970 | return (error); | |||
1971 | copy_ostat(&sb, &sb32); | |||
1972 | error = copyout(&sb32, uap->ub, sizeof (sb32)); | |||
1973 | return (error); | |||
1974 | } | |||
1975 | #endif | |||
1976 | ||||
1977 | int | |||
1978 | freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) | |||
1979 | { | |||
1980 | struct stat ub; | |||
1981 | struct stat32 ub32; | |||
1982 | int error; | |||
1983 | ||||
1984 | error = kern_fstat(td, uap->fd, &ub); | |||
1985 | if (error) | |||
1986 | return (error); | |||
1987 | copy_stat(&ub, &ub32); | |||
1988 | error = copyout(&ub32, uap->ub, sizeof(ub32)); | |||
1989 | return (error); | |||
1990 | } | |||
1991 | ||||
1992 | #ifdef COMPAT_43 | |||
1993 | int | |||
1994 | ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap) | |||
1995 | { | |||
1996 | struct stat ub; | |||
1997 | struct ostat32 ub32; | |||
1998 | int error; | |||
1999 | ||||
2000 | error = kern_fstat(td, uap->fd, &ub); | |||
2001 | if (error) | |||
2002 | return (error); | |||
2003 | copy_ostat(&ub, &ub32); | |||
2004 | error = copyout(&ub32, uap->ub, sizeof(ub32)); | |||
2005 | return (error); | |||
2006 | } | |||
2007 | #endif | |||
2008 | ||||
2009 | int | |||
2010 | freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap) | |||
2011 | { | |||
2012 | struct stat ub; | |||
2013 | struct stat32 ub32; | |||
2014 | int error; | |||
2015 | ||||
2016 | error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, | |||
2017 | &ub, NULL((void *)0)); | |||
2018 | if (error) | |||
2019 | return (error); | |||
2020 | copy_stat(&ub, &ub32); | |||
2021 | error = copyout(&ub32, uap->buf, sizeof(ub32)); | |||
2022 | return (error); | |||
2023 | } | |||
2024 | ||||
2025 | #ifdef COMPAT_43 | |||
2026 | int | |||
2027 | ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap) | |||
2028 | { | |||
2029 | struct stat sb; | |||
2030 | struct ostat32 sb32; | |||
2031 | int error; | |||
2032 | ||||
2033 | error = kern_statat(td, AT_SYMLINK_NOFOLLOW0x0200, AT_FDCWD-100, uap->path, | |||
2034 | UIO_USERSPACE, &sb, NULL((void *)0)); | |||
2035 | if (error) | |||
2036 | return (error); | |||
2037 | copy_ostat(&sb, &sb32); | |||
2038 | error = copyout(&sb32, uap->ub, sizeof (sb32)); | |||
2039 | return (error); | |||
2040 | } | |||
2041 | #endif | |||
2042 | ||||
2043 | int | |||
2044 | freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap) | |||
2045 | { | |||
2046 | struct stat sb; | |||
2047 | struct stat32 sb32; | |||
2048 | struct fhandle fh; | |||
2049 | int error; | |||
2050 | ||||
2051 | error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); | |||
2052 | if (error != 0) | |||
2053 | return (error); | |||
2054 | error = kern_fhstat(td, fh, &sb); | |||
2055 | if (error != 0) | |||
2056 | return (error); | |||
2057 | copy_stat(&sb, &sb32); | |||
2058 | error = copyout(&sb32, uap->sb, sizeof (sb32)); | |||
2059 | return (error); | |||
2060 | } | |||
2061 | ||||
2062 | #if defined(COMPAT_FREEBSD111) | |||
2063 | extern int ino64_trunc_error; | |||
2064 | ||||
2065 | static int | |||
2066 | freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out) | |||
2067 | { | |||
2068 | ||||
2069 | CP(*in, *out, st_ino)do { (*out).st_ino = (*in).st_ino; } while (0); | |||
2070 | if (in->st_ino != out->st_ino) { | |||
2071 | switch (ino64_trunc_error) { | |||
2072 | default: | |||
2073 | case 0: | |||
2074 | break; | |||
2075 | case 1: | |||
2076 | return (EOVERFLOW84); | |||
2077 | case 2: | |||
2078 | out->st_ino = UINT32_MAX0xffffffffU; | |||
2079 | break; | |||
2080 | } | |||
2081 | } | |||
2082 | CP(*in, *out, st_nlink)do { (*out).st_nlink = (*in).st_nlink; } while (0); | |||
2083 | if (in->st_nlink != out->st_nlink) { | |||
2084 | switch (ino64_trunc_error) { | |||
2085 | default: | |||
2086 | case 0: | |||
2087 | break; | |||
2088 | case 1: | |||
2089 | return (EOVERFLOW84); | |||
2090 | case 2: | |||
2091 | out->st_nlink = UINT16_MAX0xffff; | |||
2092 | break; | |||
2093 | } | |||
2094 | } | |||
2095 | out->st_dev = in->st_dev; | |||
2096 | if (out->st_dev != in->st_dev) { | |||
2097 | switch (ino64_trunc_error) { | |||
2098 | default: | |||
2099 | break; | |||
2100 | case 1: | |||
2101 | return (EOVERFLOW84); | |||
2102 | } | |||
2103 | } | |||
2104 | CP(*in, *out, st_mode)do { (*out).st_mode = (*in).st_mode; } while (0); | |||
2105 | CP(*in, *out, st_uid)do { (*out).st_uid = (*in).st_uid; } while (0); | |||
2106 | CP(*in, *out, st_gid)do { (*out).st_gid = (*in).st_gid; } while (0); | |||
2107 | out->st_rdev = in->st_rdev; | |||
2108 | if (out->st_rdev != in->st_rdev) { | |||
2109 | switch (ino64_trunc_error) { | |||
2110 | default: | |||
2111 | break; | |||
2112 | case 1: | |||
2113 | return (EOVERFLOW84); | |||
2114 | } | |||
2115 | } | |||
2116 | TS_CP(*in, *out, st_atim)do { do { ((*out).st_atim).tv_sec = ((*in).st_atim).tv_sec; } while (0); do { ((*out).st_atim).tv_nsec = ((*in).st_atim).tv_nsec ; } while (0); } while (0); | |||
2117 | TS_CP(*in, *out, st_mtim)do { do { ((*out).st_mtim).tv_sec = ((*in).st_mtim).tv_sec; } while (0); do { ((*out).st_mtim).tv_nsec = ((*in).st_mtim).tv_nsec ; } while (0); } while (0); | |||
2118 | TS_CP(*in, *out, st_ctim)do { do { ((*out).st_ctim).tv_sec = ((*in).st_ctim).tv_sec; } while (0); do { ((*out).st_ctim).tv_nsec = ((*in).st_ctim).tv_nsec ; } while (0); } while (0); | |||
2119 | CP(*in, *out, st_size)do { (*out).st_size = (*in).st_size; } while (0); | |||
2120 | CP(*in, *out, st_blocks)do { (*out).st_blocks = (*in).st_blocks; } while (0); | |||
2121 | CP(*in, *out, st_blksize)do { (*out).st_blksize = (*in).st_blksize; } while (0); | |||
2122 | CP(*in, *out, st_flags)do { (*out).st_flags = (*in).st_flags; } while (0); | |||
2123 | CP(*in, *out, st_gen)do { (*out).st_gen = (*in).st_gen; } while (0); | |||
2124 | TS_CP(*in, *out, st_birthtim)do { do { ((*out).st_birthtim).tv_sec = ((*in).st_birthtim).tv_sec ; } while (0); do { ((*out).st_birthtim).tv_nsec = ((*in).st_birthtim ).tv_nsec; } while (0); } while (0); | |||
2125 | out->st_lspare = 0; | |||
2126 | bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),__builtin_memset(((char *)&out->st_birthtim + sizeof(out ->st_birthtim)), 0, (sizeof(*out) - __builtin_offsetof(struct freebsd11_stat32, st_birthtim) - sizeof(out->st_birthtim) )) | |||
2127 | sizeof(*out) - offsetof(struct freebsd11_stat32,__builtin_memset(((char *)&out->st_birthtim + sizeof(out ->st_birthtim)), 0, (sizeof(*out) - __builtin_offsetof(struct freebsd11_stat32, st_birthtim) - sizeof(out->st_birthtim) )) | |||
2128 | st_birthtim) - sizeof(out->st_birthtim))__builtin_memset(((char *)&out->st_birthtim + sizeof(out ->st_birthtim)), 0, (sizeof(*out) - __builtin_offsetof(struct freebsd11_stat32, st_birthtim) - sizeof(out->st_birthtim) )); | |||
2129 | return (0); | |||
2130 | } | |||
2131 | ||||
2132 | int | |||
2133 | freebsd11_freebsd32_stat(struct thread *td, | |||
2134 | struct freebsd11_freebsd32_stat_args *uap) | |||
2135 | { | |||
2136 | struct stat sb; | |||
2137 | struct freebsd11_stat32 sb32; | |||
2138 | int error; | |||
2139 | ||||
2140 | error = kern_statat(td, 0, AT_FDCWD-100, uap->path, UIO_USERSPACE, | |||
2141 | &sb, NULL((void *)0)); | |||
2142 | if (error != 0) | |||
2143 | return (error); | |||
2144 | error = freebsd11_cvtstat32(&sb, &sb32); | |||
2145 | if (error == 0) | |||
2146 | error = copyout(&sb32, uap->ub, sizeof (sb32)); | |||
2147 | return (error); | |||
2148 | } | |||
2149 | ||||
2150 | int | |||
2151 | freebsd11_freebsd32_fstat(struct thread *td, | |||
2152 | struct freebsd11_freebsd32_fstat_args *uap) | |||
2153 | { | |||
2154 | struct stat sb; | |||
2155 | struct freebsd11_stat32 sb32; | |||
2156 | int error; | |||
2157 | ||||
2158 | error = kern_fstat(td, uap->fd, &sb); | |||
2159 | if (error != 0) | |||
2160 | return (error); | |||
2161 | error = freebsd11_cvtstat32(&sb, &sb32); | |||
2162 | if (error == 0) | |||
2163 | error = copyout(&sb32, uap->ub, sizeof (sb32)); | |||
2164 | return (error); | |||
2165 | } | |||
2166 | ||||
2167 | int | |||
2168 | freebsd11_freebsd32_fstatat(struct thread *td, | |||
2169 | struct freebsd11_freebsd32_fstatat_args *uap) | |||
2170 | { | |||
2171 | struct stat sb; | |||
2172 | struct freebsd11_stat32 sb32; | |||
2173 | int error; | |||
2174 | ||||
2175 | error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, | |||
2176 | &sb, NULL((void *)0)); | |||
2177 | if (error != 0) | |||
2178 | return (error); | |||
2179 | error = freebsd11_cvtstat32(&sb, &sb32); | |||
2180 | if (error == 0) | |||
2181 | error = copyout(&sb32, uap->buf, sizeof (sb32)); | |||
2182 | return (error); | |||
2183 | } | |||
2184 | ||||
2185 | int | |||
2186 | freebsd11_freebsd32_lstat(struct thread *td, | |||
2187 | struct freebsd11_freebsd32_lstat_args *uap) | |||
2188 | { | |||
2189 | struct stat sb; | |||
2190 | struct freebsd11_stat32 sb32; | |||
2191 | int error; | |||
2192 | ||||
2193 | error = kern_statat(td, AT_SYMLINK_NOFOLLOW0x0200, AT_FDCWD-100, uap->path, | |||
2194 | UIO_USERSPACE, &sb, NULL((void *)0)); | |||
2195 | if (error != 0) | |||
| ||||
2196 | return (error); | |||
2197 | error = freebsd11_cvtstat32(&sb, &sb32); | |||
2198 | if (error == 0) | |||
2199 | error = copyout(&sb32, uap->ub, sizeof (sb32)); | |||
| ||||
2200 | return (error); | |||
2201 | } | |||
2202 | ||||
2203 | int | |||
2204 | freebsd11_freebsd32_fhstat(struct thread *td, | |||
2205 | struct freebsd11_freebsd32_fhstat_args *uap) | |||
2206 | { | |||
2207 | struct stat sb; | |||
2208 | struct freebsd11_stat32 sb32; | |||
2209 | struct fhandle fh; | |||
2210 | int error; | |||
2211 | ||||
2212 | error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); | |||
2213 | if (error != 0) | |||
2214 | return (error); | |||
2215 | error = kern_fhstat(td, fh, &sb); | |||
2216 | if (error != 0) | |||
2217 | return (error); | |||
2218 | error = freebsd11_cvtstat32(&sb, &sb32); | |||
2219 | if (error == 0) | |||
2220 | error = copyout(&sb32, uap->sb, sizeof (sb32)); | |||
2221 | return (error); | |||
2222 | } | |||
2223 | #endif | |||
2224 | ||||
2225 | int | |||
2226 | freebsd32___sysctl(struct thread *td, struct freebsd32___sysctl_args *uap) | |||
2227 | { | |||
2228 | int error, name[CTL_MAXNAME24]; | |||
2229 | size_t j, oldlen; | |||
2230 | uint32_t tmp; | |||
2231 | ||||
2232 | if (uap->namelen > CTL_MAXNAME24 || uap->namelen < 2) | |||
2233 | return (EINVAL22); | |||
2234 | error = copyin(uap->name, name, uap->namelen * sizeof(int)); | |||
2235 | if (error) | |||
2236 | return (error); | |||
2237 | if (uap->oldlenp) { | |||
2238 | error = fueword32(uap->oldlenp, &tmp); | |||
2239 | oldlen = tmp; | |||
2240 | } else { | |||
2241 | oldlen = 0; | |||
2242 | } | |||
2243 | if (error != 0) | |||
2244 | return (EFAULT14); | |||
2245 | error = userland_sysctl(td, name, uap->namelen, | |||
2246 | uap->old, &oldlen, 1, | |||
2247 | uap->new, uap->newlen, &j, SCTL_MASK321); | |||
2248 | if (error) | |||
2249 | return (error); | |||
2250 | if (uap->oldlenp) | |||
2251 | suword32(uap->oldlenp, j); | |||
2252 | return (0); | |||
2253 | } | |||
2254 | ||||
2255 | int | |||
2256 | freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap) | |||
2257 | { | |||
2258 | uint32_t version; | |||
2259 | int error; | |||
2260 | struct jail j; | |||
2261 | ||||
2262 | error = copyin(uap->jail, &version, sizeof(uint32_t)); | |||
2263 | if (error) | |||
2264 | return (error); | |||
2265 | ||||
2266 | switch (version) { | |||
2267 | case 0: | |||
2268 | { | |||
2269 | /* FreeBSD single IPv4 jails. */ | |||
2270 | struct jail32_v0 j32_v0; | |||
2271 | ||||
2272 | bzero(&j, sizeof(struct jail))__builtin_memset((&j), 0, (sizeof(struct jail))); | |||
2273 | error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0)); | |||
2274 | if (error) | |||
2275 | return (error); | |||
2276 | CP(j32_v0, j, version)do { (j).version = (j32_v0).version; } while (0); | |||
2277 | PTRIN_CP(j32_v0, j, path)do { (j).path = (void *)(uintptr_t) ((j32_v0).path); } while ( 0); | |||
2278 | PTRIN_CP(j32_v0, j, hostname)do { (j).hostname = (void *)(uintptr_t) ((j32_v0).hostname); } while (0); | |||
2279 | j.ip4s = htonl(j32_v0.ip_number)(__builtin_constant_p(j32_v0.ip_number) ? (((__uint32_t)((__uint16_t )(__builtin_constant_p(((__uint32_t)(j32_v0.ip_number)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(j32_v0.ip_number )) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(j32_v0 .ip_number)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t )(j32_v0.ip_number)) & 0xffff))) << 16) | ((__uint16_t )(__builtin_constant_p(((__uint32_t)(j32_v0.ip_number)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(j32_v0.ip_number )) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(j32_v0 .ip_number)) >> 16)) >> 8) : __bswap16_var(((__uint32_t )(j32_v0.ip_number)) >> 16)))) : __bswap32_var(j32_v0.ip_number )); /* jail_v0 is host order */ | |||
2280 | break; | |||
2281 | } | |||
2282 | ||||
2283 | case 1: | |||
2284 | /* | |||
2285 | * Version 1 was used by multi-IPv4 jail implementations | |||
2286 | * that never made it into the official kernel. | |||
2287 | */ | |||
2288 | return (EINVAL22); | |||
2289 | ||||
2290 | case 2: /* JAIL_API_VERSION */ | |||
2291 | { | |||
2292 | /* FreeBSD multi-IPv4/IPv6,noIP jails. */ | |||
2293 | struct jail32 j32; | |||
2294 | ||||
2295 | error = copyin(uap->jail, &j32, sizeof(struct jail32)); | |||
2296 | if (error) | |||
2297 | return (error); | |||
2298 | CP(j32, j, version)do { (j).version = (j32).version; } while (0); | |||
2299 | PTRIN_CP(j32, j, path)do { (j).path = (void *)(uintptr_t) ((j32).path); } while (0); | |||
2300 | PTRIN_CP(j32, j, hostname)do { (j).hostname = (void *)(uintptr_t) ((j32).hostname); } while (0); | |||
2301 | PTRIN_CP(j32, j, jailname)do { (j).jailname = (void *)(uintptr_t) ((j32).jailname); } while (0); | |||
2302 | CP(j32, j, ip4s)do { (j).ip4s = (j32).ip4s; } while (0); | |||
2303 | CP(j32, j, ip6s)do { (j).ip6s = (j32).ip6s; } while (0); | |||
2304 | PTRIN_CP(j32, j, ip4)do { (j).ip4 = (void *)(uintptr_t) ((j32).ip4); } while (0); | |||
2305 | PTRIN_CP(j32, j, ip6)do { (j).ip6 = (void *)(uintptr_t) ((j32).ip6); } while (0); | |||
2306 | break; | |||
2307 | } | |||
2308 | ||||
2309 | default: | |||
2310 | /* Sci-Fi jails are not supported, sorry. */ | |||
2311 | return (EINVAL22); | |||
2312 | } | |||
2313 | return (kern_jail(td, &j)); | |||
2314 | } | |||
2315 | ||||
2316 | int | |||
2317 | freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap) | |||
2318 | { | |||
2319 | struct uio *auio; | |||
2320 | int error; | |||
2321 | ||||
2322 | /* Check that we have an even number of iovecs. */ | |||
2323 | if (uap->iovcnt & 1) | |||
2324 | return (EINVAL22); | |||
2325 | ||||
2326 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
2327 | if (error) | |||
2328 | return (error); | |||
2329 | error = kern_jail_set(td, auio, uap->flags); | |||
2330 | free(auio, M_IOV); | |||
2331 | return (error); | |||
2332 | } | |||
2333 | ||||
2334 | int | |||
2335 | freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap) | |||
2336 | { | |||
2337 | struct iovec32 iov32; | |||
2338 | struct uio *auio; | |||
2339 | int error, i; | |||
2340 | ||||
2341 | /* Check that we have an even number of iovecs. */ | |||
2342 | if (uap->iovcnt & 1) | |||
2343 | return (EINVAL22); | |||
2344 | ||||
2345 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
2346 | if (error) | |||
2347 | return (error); | |||
2348 | error = kern_jail_get(td, auio, uap->flags); | |||
2349 | if (error == 0) | |||
2350 | for (i = 0; i < uap->iovcnt; i++) { | |||
2351 | PTROUT_CP(auio->uio_iov[i], iov32, iov_base)do { (iov32).iov_base = (u_int32_t)(uintptr_t) ((auio->uio_iov [i]).iov_base); } while (0); | |||
2352 | CP(auio->uio_iov[i], iov32, iov_len)do { (iov32).iov_len = (auio->uio_iov[i]).iov_len; } while (0); | |||
2353 | error = copyout(&iov32, uap->iovp + i, sizeof(iov32)); | |||
2354 | if (error != 0) | |||
2355 | break; | |||
2356 | } | |||
2357 | free(auio, M_IOV); | |||
2358 | return (error); | |||
2359 | } | |||
2360 | ||||
2361 | int | |||
2362 | freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) | |||
2363 | { | |||
2364 | struct sigaction32 s32; | |||
2365 | struct sigaction sa, osa, *sap; | |||
2366 | int error; | |||
2367 | ||||
2368 | if (uap->act) { | |||
2369 | error = copyin(uap->act, &s32, sizeof(s32)); | |||
2370 | if (error) | |||
2371 | return (error); | |||
2372 | sa.sa_handler__sigaction_u.__sa_handler = PTRIN(s32.sa_u)(void *)(uintptr_t) (s32.sa_u); | |||
2373 | CP(s32, sa, sa_flags)do { (sa).sa_flags = (s32).sa_flags; } while (0); | |||
2374 | CP(s32, sa, sa_mask)do { (sa).sa_mask = (s32).sa_mask; } while (0); | |||
2375 | sap = &sa; | |||
2376 | } else | |||
2377 | sap = NULL((void *)0); | |||
2378 | error = kern_sigaction(td, uap->sig, sap, &osa, 0); | |||
2379 | if (error == 0 && uap->oact != NULL((void *)0)) { | |||
2380 | s32.sa_u = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler); | |||
2381 | CP(osa, s32, sa_flags)do { (s32).sa_flags = (osa).sa_flags; } while (0); | |||
2382 | CP(osa, s32, sa_mask)do { (s32).sa_mask = (osa).sa_mask; } while (0); | |||
2383 | error = copyout(&s32, uap->oact, sizeof(s32)); | |||
2384 | } | |||
2385 | return (error); | |||
2386 | } | |||
2387 | ||||
2388 | #ifdef COMPAT_FREEBSD41 | |||
2389 | int | |||
2390 | freebsd4_freebsd32_sigaction(struct thread *td, | |||
2391 | struct freebsd4_freebsd32_sigaction_args *uap) | |||
2392 | { | |||
2393 | struct sigaction32 s32; | |||
2394 | struct sigaction sa, osa, *sap; | |||
2395 | int error; | |||
2396 | ||||
2397 | if (uap->act) { | |||
2398 | error = copyin(uap->act, &s32, sizeof(s32)); | |||
2399 | if (error) | |||
2400 | return (error); | |||
2401 | sa.sa_handler__sigaction_u.__sa_handler = PTRIN(s32.sa_u)(void *)(uintptr_t) (s32.sa_u); | |||
2402 | CP(s32, sa, sa_flags)do { (sa).sa_flags = (s32).sa_flags; } while (0); | |||
2403 | CP(s32, sa, sa_mask)do { (sa).sa_mask = (s32).sa_mask; } while (0); | |||
2404 | sap = &sa; | |||
2405 | } else | |||
2406 | sap = NULL((void *)0); | |||
2407 | error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD40x0002); | |||
2408 | if (error == 0 && uap->oact != NULL((void *)0)) { | |||
2409 | s32.sa_u = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler); | |||
2410 | CP(osa, s32, sa_flags)do { (s32).sa_flags = (osa).sa_flags; } while (0); | |||
2411 | CP(osa, s32, sa_mask)do { (s32).sa_mask = (osa).sa_mask; } while (0); | |||
2412 | error = copyout(&s32, uap->oact, sizeof(s32)); | |||
2413 | } | |||
2414 | return (error); | |||
2415 | } | |||
2416 | #endif | |||
2417 | ||||
2418 | #ifdef COMPAT_43 | |||
2419 | struct osigaction32 { | |||
2420 | u_int32_t sa_u; | |||
2421 | osigset_t sa_mask; | |||
2422 | int sa_flags; | |||
2423 | }; | |||
2424 | ||||
2425 | #define ONSIG 32 | |||
2426 | ||||
2427 | int | |||
2428 | ofreebsd32_sigaction(struct thread *td, | |||
2429 | struct ofreebsd32_sigaction_args *uap) | |||
2430 | { | |||
2431 | struct osigaction32 s32; | |||
2432 | struct sigaction sa, osa, *sap; | |||
2433 | int error; | |||
2434 | ||||
2435 | if (uap->signum <= 0 || uap->signum >= ONSIG) | |||
2436 | return (EINVAL22); | |||
2437 | ||||
2438 | if (uap->nsa) { | |||
2439 | error = copyin(uap->nsa, &s32, sizeof(s32)); | |||
2440 | if (error) | |||
2441 | return (error); | |||
2442 | sa.sa_handler__sigaction_u.__sa_handler = PTRIN(s32.sa_u)(void *)(uintptr_t) (s32.sa_u); | |||
2443 | CP(s32, sa, sa_flags)do { (sa).sa_flags = (s32).sa_flags; } while (0); | |||
2444 | OSIG2SIG(s32.sa_mask, sa.sa_mask)do { int __i; for (__i = 0; __i < 4; __i++) (sa.sa_mask).__bits [__i] = 0; } while (0); (sa.sa_mask).__bits[0] = s32.sa_mask; | |||
2445 | sap = &sa; | |||
2446 | } else | |||
2447 | sap = NULL((void *)0); | |||
2448 | error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET0x0001); | |||
2449 | if (error == 0 && uap->osa != NULL((void *)0)) { | |||
2450 | s32.sa_u = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler); | |||
2451 | CP(osa, s32, sa_flags)do { (s32).sa_flags = (osa).sa_flags; } while (0); | |||
2452 | SIG2OSIG(osa.sa_mask, s32.sa_mask)(s32.sa_mask = (osa.sa_mask).__bits[0]); | |||
2453 | error = copyout(&s32, uap->osa, sizeof(s32)); | |||
2454 | } | |||
2455 | return (error); | |||
2456 | } | |||
2457 | ||||
2458 | int | |||
2459 | ofreebsd32_sigprocmask(struct thread *td, | |||
2460 | struct ofreebsd32_sigprocmask_args *uap) | |||
2461 | { | |||
2462 | sigset_t set, oset; | |||
2463 | int error; | |||
2464 | ||||
2465 | OSIG2SIG(uap->mask, set)do { int __i; for (__i = 0; __i < 4; __i++) (set).__bits[__i ] = 0; } while (0); (set).__bits[0] = uap->mask; | |||
2466 | error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD0x0001); | |||
2467 | SIG2OSIG(oset, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (oset).__bits[0]); | |||
2468 | return (error); | |||
2469 | } | |||
2470 | ||||
2471 | int | |||
2472 | ofreebsd32_sigpending(struct thread *td, | |||
2473 | struct ofreebsd32_sigpending_args *uap) | |||
2474 | { | |||
2475 | struct proc *p = td->td_proc; | |||
2476 | sigset_t siglist; | |||
2477 | ||||
2478 | PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock , ((0)), ("/root/freebsd/sys/compat/freebsd32/freebsd32_misc.c" ), (2478)); | |||
2479 | siglist = p->p_siglistp_sigqueue.sq_signals; | |||
2480 | SIGSETOR(siglist, td->td_siglist)do { int __i; for (__i = 0; __i < 4; __i++) (siglist).__bits [__i] |= (td->td_sigqueue.sq_signals).__bits[__i]; } while (0); | |||
2481 | PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock , ((0)), ("/root/freebsd/sys/compat/freebsd32/freebsd32_misc.c" ), (2481)); | |||
2482 | SIG2OSIG(siglist, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (siglist).__bits[0]); | |||
2483 | return (0); | |||
2484 | } | |||
2485 | ||||
2486 | struct sigvec32 { | |||
2487 | u_int32_t sv_handler; | |||
2488 | int sv_mask; | |||
2489 | int sv_flags; | |||
2490 | }; | |||
2491 | ||||
2492 | int | |||
2493 | ofreebsd32_sigvec(struct thread *td, | |||
2494 | struct ofreebsd32_sigvec_args *uap) | |||
2495 | { | |||
2496 | struct sigvec32 vec; | |||
2497 | struct sigaction sa, osa, *sap; | |||
2498 | int error; | |||
2499 | ||||
2500 | if (uap->signum <= 0 || uap->signum >= ONSIG) | |||
2501 | return (EINVAL22); | |||
2502 | ||||
2503 | if (uap->nsv) { | |||
2504 | error = copyin(uap->nsv, &vec, sizeof(vec)); | |||
2505 | if (error) | |||
2506 | return (error); | |||
2507 | sa.sa_handler__sigaction_u.__sa_handler = PTRIN(vec.sv_handler)(void *)(uintptr_t) (vec.sv_handler); | |||
2508 | OSIG2SIG(vec.sv_mask, sa.sa_mask)do { int __i; for (__i = 0; __i < 4; __i++) (sa.sa_mask).__bits [__i] = 0; } while (0); (sa.sa_mask).__bits[0] = vec.sv_mask; | |||
2509 | sa.sa_flags = vec.sv_flags; | |||
2510 | sa.sa_flags ^= SA_RESTART0x0002; | |||
2511 | sap = &sa; | |||
2512 | } else | |||
2513 | sap = NULL((void *)0); | |||
2514 | error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET0x0001); | |||
2515 | if (error == 0 && uap->osv != NULL((void *)0)) { | |||
2516 | vec.sv_handler = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler); | |||
2517 | SIG2OSIG(osa.sa_mask, vec.sv_mask)(vec.sv_mask = (osa.sa_mask).__bits[0]); | |||
2518 | vec.sv_flags = osa.sa_flags; | |||
2519 | vec.sv_flags &= ~SA_NOCLDWAIT0x0020; | |||
2520 | vec.sv_flags ^= SA_RESTART0x0002; | |||
2521 | error = copyout(&vec, uap->osv, sizeof(vec)); | |||
2522 | } | |||
2523 | return (error); | |||
2524 | } | |||
2525 | ||||
2526 | int | |||
2527 | ofreebsd32_sigblock(struct thread *td, | |||
2528 | struct ofreebsd32_sigblock_args *uap) | |||
2529 | { | |||
2530 | sigset_t set, oset; | |||
2531 | ||||
2532 | OSIG2SIG(uap->mask, set)do { int __i; for (__i = 0; __i < 4; __i++) (set).__bits[__i ] = 0; } while (0); (set).__bits[0] = uap->mask; | |||
2533 | kern_sigprocmask(td, SIG_BLOCK1, &set, &oset, 0); | |||
2534 | SIG2OSIG(oset, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (oset).__bits[0]); | |||
2535 | return (0); | |||
2536 | } | |||
2537 | ||||
2538 | int | |||
2539 | ofreebsd32_sigsetmask(struct thread *td, | |||
2540 | struct ofreebsd32_sigsetmask_args *uap) | |||
2541 | { | |||
2542 | sigset_t set, oset; | |||
2543 | ||||
2544 | OSIG2SIG(uap->mask, set)do { int __i; for (__i = 0; __i < 4; __i++) (set).__bits[__i ] = 0; } while (0); (set).__bits[0] = uap->mask; | |||
2545 | kern_sigprocmask(td, SIG_SETMASK3, &set, &oset, 0); | |||
2546 | SIG2OSIG(oset, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (oset).__bits[0]); | |||
2547 | return (0); | |||
2548 | } | |||
2549 | ||||
2550 | int | |||
2551 | ofreebsd32_sigsuspend(struct thread *td, | |||
2552 | struct ofreebsd32_sigsuspend_args *uap) | |||
2553 | { | |||
2554 | sigset_t mask; | |||
2555 | ||||
2556 | OSIG2SIG(uap->mask, mask)do { int __i; for (__i = 0; __i < 4; __i++) (mask).__bits[ __i] = 0; } while (0); (mask).__bits[0] = uap->mask; | |||
2557 | return (kern_sigsuspend(td, mask)); | |||
2558 | } | |||
2559 | ||||
2560 | struct sigstack32 { | |||
2561 | u_int32_t ss_sp; | |||
2562 | int ss_onstack; | |||
2563 | }; | |||
2564 | ||||
2565 | int | |||
2566 | ofreebsd32_sigstack(struct thread *td, | |||
2567 | struct ofreebsd32_sigstack_args *uap) | |||
2568 | { | |||
2569 | struct sigstack32 s32; | |||
2570 | struct sigstack nss, oss; | |||
2571 | int error = 0, unss; | |||
2572 | ||||
2573 | if (uap->nss != NULL((void *)0)) { | |||
2574 | error = copyin(uap->nss, &s32, sizeof(s32)); | |||
2575 | if (error) | |||
2576 | return (error); | |||
2577 | nss.ss_sp = PTRIN(s32.ss_sp)(void *)(uintptr_t) (s32.ss_sp); | |||
2578 | CP(s32, nss, ss_onstack)do { (nss).ss_onstack = (s32).ss_onstack; } while (0); | |||
2579 | unss = 1; | |||
2580 | } else { | |||
2581 | unss = 0; | |||
2582 | } | |||
2583 | oss.ss_sp = td->td_sigstk.ss_sp; | |||
2584 | oss.ss_onstack = sigonstack(cpu_getstack(td)((td)->td_frame->tf_rsp)); | |||
2585 | if (unss) { | |||
2586 | td->td_sigstk.ss_sp = nss.ss_sp; | |||
2587 | td->td_sigstk.ss_size = 0; | |||
2588 | td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK0x0001); | |||
2589 | td->td_pflags |= TDP_ALTSTACK0x00000020; | |||
2590 | } | |||
2591 | if (uap->oss != NULL((void *)0)) { | |||
2592 | s32.ss_sp = PTROUT(oss.ss_sp)(u_int32_t)(uintptr_t) (oss.ss_sp); | |||
2593 | CP(oss, s32, ss_onstack)do { (s32).ss_onstack = (oss).ss_onstack; } while (0); | |||
2594 | error = copyout(&s32, uap->oss, sizeof(s32)); | |||
2595 | } | |||
2596 | return (error); | |||
2597 | } | |||
2598 | #endif | |||
2599 | ||||
2600 | int | |||
2601 | freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) | |||
2602 | { | |||
2603 | ||||
2604 | return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME0, | |||
2605 | TIMER_RELTIME0x0, uap->rqtp, uap->rmtp)); | |||
2606 | } | |||
2607 | ||||
2608 | int | |||
2609 | freebsd32_clock_nanosleep(struct thread *td, | |||
2610 | struct freebsd32_clock_nanosleep_args *uap) | |||
2611 | { | |||
2612 | int error; | |||
2613 | ||||
2614 | error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags, | |||
2615 | uap->rqtp, uap->rmtp); | |||
2616 | return (kern_posix_error(td, error)); | |||
2617 | } | |||
2618 | ||||
2619 | static int | |||
2620 | freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id, | |||
2621 | int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp) | |||
2622 | { | |||
2623 | struct timespec32 rmt32, rqt32; | |||
2624 | struct timespec rmt, rqt; | |||
2625 | int error; | |||
2626 | ||||
2627 | error = copyin(ua_rqtp, &rqt32, sizeof(rqt32)); | |||
2628 | if (error) | |||
2629 | return (error); | |||
2630 | ||||
2631 | CP(rqt32, rqt, tv_sec)do { (rqt).tv_sec = (rqt32).tv_sec; } while (0); | |||
2632 | CP(rqt32, rqt, tv_nsec)do { (rqt).tv_nsec = (rqt32).tv_nsec; } while (0); | |||
2633 | ||||
2634 | if (ua_rmtp != NULL((void *)0) && (flags & TIMER_ABSTIME0x1) == 0 && | |||
2635 | !useracc(ua_rmtp, sizeof(rmt32), VM_PROT_WRITE((vm_prot_t) 0x02))) | |||
2636 | return (EFAULT14); | |||
2637 | error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt); | |||
2638 | if (error == EINTR4 && ua_rmtp != NULL((void *)0) && (flags & TIMER_ABSTIME0x1) == 0) { | |||
2639 | int error2; | |||
2640 | ||||
2641 | CP(rmt, rmt32, tv_sec)do { (rmt32).tv_sec = (rmt).tv_sec; } while (0); | |||
2642 | CP(rmt, rmt32, tv_nsec)do { (rmt32).tv_nsec = (rmt).tv_nsec; } while (0); | |||
2643 | ||||
2644 | error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32)); | |||
2645 | if (error2) | |||
2646 | error = error2; | |||
2647 | } | |||
2648 | return (error); | |||
2649 | } | |||
2650 | ||||
2651 | int | |||
2652 | freebsd32_clock_gettime(struct thread *td, | |||
2653 | struct freebsd32_clock_gettime_args *uap) | |||
2654 | { | |||
2655 | struct timespec ats; | |||
2656 | struct timespec32 ats32; | |||
2657 | int error; | |||
2658 | ||||
2659 | error = kern_clock_gettime(td, uap->clock_id, &ats); | |||
2660 | if (error == 0) { | |||
2661 | CP(ats, ats32, tv_sec)do { (ats32).tv_sec = (ats).tv_sec; } while (0); | |||
2662 | CP(ats, ats32, tv_nsec)do { (ats32).tv_nsec = (ats).tv_nsec; } while (0); | |||
2663 | error = copyout(&ats32, uap->tp, sizeof(ats32)); | |||
2664 | } | |||
2665 | return (error); | |||
2666 | } | |||
2667 | ||||
2668 | int | |||
2669 | freebsd32_clock_settime(struct thread *td, | |||
2670 | struct freebsd32_clock_settime_args *uap) | |||
2671 | { | |||
2672 | struct timespec ats; | |||
2673 | struct timespec32 ats32; | |||
2674 | int error; | |||
2675 | ||||
2676 | error = copyin(uap->tp, &ats32, sizeof(ats32)); | |||
2677 | if (error) | |||
2678 | return (error); | |||
2679 | CP(ats32, ats, tv_sec)do { (ats).tv_sec = (ats32).tv_sec; } while (0); | |||
2680 | CP(ats32, ats, tv_nsec)do { (ats).tv_nsec = (ats32).tv_nsec; } while (0); | |||
2681 | ||||
2682 | return (kern_clock_settime(td, uap->clock_id, &ats)); | |||
2683 | } | |||
2684 | ||||
2685 | int | |||
2686 | freebsd32_clock_getres(struct thread *td, | |||
2687 | struct freebsd32_clock_getres_args *uap) | |||
2688 | { | |||
2689 | struct timespec ts; | |||
2690 | struct timespec32 ts32; | |||
2691 | int error; | |||
2692 | ||||
2693 | if (uap->tp == NULL((void *)0)) | |||
2694 | return (0); | |||
2695 | error = kern_clock_getres(td, uap->clock_id, &ts); | |||
2696 | if (error == 0) { | |||
2697 | CP(ts, ts32, tv_sec)do { (ts32).tv_sec = (ts).tv_sec; } while (0); | |||
2698 | CP(ts, ts32, tv_nsec)do { (ts32).tv_nsec = (ts).tv_nsec; } while (0); | |||
2699 | error = copyout(&ts32, uap->tp, sizeof(ts32)); | |||
2700 | } | |||
2701 | return (error); | |||
2702 | } | |||
2703 | ||||
2704 | int freebsd32_ktimer_create(struct thread *td, | |||
2705 | struct freebsd32_ktimer_create_args *uap) | |||
2706 | { | |||
2707 | struct sigevent32 ev32; | |||
2708 | struct sigevent ev, *evp; | |||
2709 | int error, id; | |||
2710 | ||||
2711 | if (uap->evp == NULL((void *)0)) { | |||
2712 | evp = NULL((void *)0); | |||
2713 | } else { | |||
2714 | evp = &ev; | |||
2715 | error = copyin(uap->evp, &ev32, sizeof(ev32)); | |||
2716 | if (error != 0) | |||
2717 | return (error); | |||
2718 | error = convert_sigevent32(&ev32, &ev); | |||
2719 | if (error != 0) | |||
2720 | return (error); | |||
2721 | } | |||
2722 | error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1); | |||
2723 | if (error == 0) { | |||
2724 | error = copyout(&id, uap->timerid, sizeof(int)); | |||
2725 | if (error != 0) | |||
2726 | kern_ktimer_delete(td, id); | |||
2727 | } | |||
2728 | return (error); | |||
2729 | } | |||
2730 | ||||
2731 | int | |||
2732 | freebsd32_ktimer_settime(struct thread *td, | |||
2733 | struct freebsd32_ktimer_settime_args *uap) | |||
2734 | { | |||
2735 | struct itimerspec32 val32, oval32; | |||
2736 | struct itimerspec val, oval, *ovalp; | |||
2737 | int error; | |||
2738 | ||||
2739 | error = copyin(uap->value, &val32, sizeof(val32)); | |||
2740 | if (error != 0) | |||
2741 | return (error); | |||
2742 | ITS_CP(val32, val)do { do { do { (((val)).it_interval).tv_sec = (((val32)).it_interval ).tv_sec; } while (0); do { (((val)).it_interval).tv_nsec = ( ((val32)).it_interval).tv_nsec; } while (0); } while (0); do { do { (((val)).it_value).tv_sec = (((val32)).it_value).tv_sec ; } while (0); do { (((val)).it_value).tv_nsec = (((val32)).it_value ).tv_nsec; } while (0); } while (0); } while (0); | |||
2743 | ovalp = uap->ovalue != NULL((void *)0) ? &oval : NULL((void *)0); | |||
2744 | error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp); | |||
2745 | if (error == 0 && uap->ovalue != NULL((void *)0)) { | |||
2746 | ITS_CP(oval, oval32)do { do { do { (((oval32)).it_interval).tv_sec = (((oval)).it_interval ).tv_sec; } while (0); do { (((oval32)).it_interval).tv_nsec = (((oval)).it_interval).tv_nsec; } while (0); } while (0); do { do { (((oval32)).it_value).tv_sec = (((oval)).it_value).tv_sec ; } while (0); do { (((oval32)).it_value).tv_nsec = (((oval)) .it_value).tv_nsec; } while (0); } while (0); } while (0); | |||
2747 | error = copyout(&oval32, uap->ovalue, sizeof(oval32)); | |||
2748 | } | |||
2749 | return (error); | |||
2750 | } | |||
2751 | ||||
2752 | int | |||
2753 | freebsd32_ktimer_gettime(struct thread *td, | |||
2754 | struct freebsd32_ktimer_gettime_args *uap) | |||
2755 | { | |||
2756 | struct itimerspec32 val32; | |||
2757 | struct itimerspec val; | |||
2758 | int error; | |||
2759 | ||||
2760 | error = kern_ktimer_gettime(td, uap->timerid, &val); | |||
2761 | if (error == 0) { | |||
2762 | ITS_CP(val, val32)do { do { do { (((val32)).it_interval).tv_sec = (((val)).it_interval ).tv_sec; } while (0); do { (((val32)).it_interval).tv_nsec = (((val)).it_interval).tv_nsec; } while (0); } while (0); do { do { (((val32)).it_value).tv_sec = (((val)).it_value).tv_sec ; } while (0); do { (((val32)).it_value).tv_nsec = (((val)).it_value ).tv_nsec; } while (0); } while (0); } while (0); | |||
2763 | error = copyout(&val32, uap->value, sizeof(val32)); | |||
2764 | } | |||
2765 | return (error); | |||
2766 | } | |||
2767 | ||||
2768 | int | |||
2769 | freebsd32_clock_getcpuclockid2(struct thread *td, | |||
2770 | struct freebsd32_clock_getcpuclockid2_args *uap) | |||
2771 | { | |||
2772 | clockid_t clk_id; | |||
2773 | int error; | |||
2774 | ||||
2775 | error = kern_clock_getcpuclockid2(td, PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), | |||
2776 | uap->which, &clk_id); | |||
2777 | if (error == 0) | |||
2778 | error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t)); | |||
2779 | return (error); | |||
2780 | } | |||
2781 | ||||
2782 | int | |||
2783 | freebsd32_thr_new(struct thread *td, | |||
2784 | struct freebsd32_thr_new_args *uap) | |||
2785 | { | |||
2786 | struct thr_param32 param32; | |||
2787 | struct thr_param param; | |||
2788 | int error; | |||
2789 | ||||
2790 | if (uap->param_size < 0 || | |||
2791 | uap->param_size > sizeof(struct thr_param32)) | |||
2792 | return (EINVAL22); | |||
2793 | bzero(¶m, sizeof(struct thr_param))__builtin_memset((¶m), 0, (sizeof(struct thr_param))); | |||
2794 | bzero(¶m32, sizeof(struct thr_param32))__builtin_memset((¶m32), 0, (sizeof(struct thr_param32 ))); | |||
2795 | error = copyin(uap->param, ¶m32, uap->param_size); | |||
2796 | if (error != 0) | |||
2797 | return (error); | |||
2798 | param.start_func = PTRIN(param32.start_func)(void *)(uintptr_t) (param32.start_func); | |||
2799 | param.arg = PTRIN(param32.arg)(void *)(uintptr_t) (param32.arg); | |||
2800 | param.stack_base = PTRIN(param32.stack_base)(void *)(uintptr_t) (param32.stack_base); | |||
2801 | param.stack_size = param32.stack_size; | |||
2802 | param.tls_base = PTRIN(param32.tls_base)(void *)(uintptr_t) (param32.tls_base); | |||
2803 | param.tls_size = param32.tls_size; | |||
2804 | param.child_tid = PTRIN(param32.child_tid)(void *)(uintptr_t) (param32.child_tid); | |||
2805 | param.parent_tid = PTRIN(param32.parent_tid)(void *)(uintptr_t) (param32.parent_tid); | |||
2806 | param.flags = param32.flags; | |||
2807 | param.rtp = PTRIN(param32.rtp)(void *)(uintptr_t) (param32.rtp); | |||
2808 | param.spare[0] = PTRIN(param32.spare[0])(void *)(uintptr_t) (param32.spare[0]); | |||
2809 | param.spare[1] = PTRIN(param32.spare[1])(void *)(uintptr_t) (param32.spare[1]); | |||
2810 | param.spare[2] = PTRIN(param32.spare[2])(void *)(uintptr_t) (param32.spare[2]); | |||
2811 | ||||
2812 | return (kern_thr_new(td, ¶m)); | |||
2813 | } | |||
2814 | ||||
2815 | int | |||
2816 | freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap) | |||
2817 | { | |||
2818 | struct timespec32 ts32; | |||
2819 | struct timespec ts, *tsp; | |||
2820 | int error; | |||
2821 | ||||
2822 | error = 0; | |||
2823 | tsp = NULL((void *)0); | |||
2824 | if (uap->timeout != NULL((void *)0)) { | |||
2825 | error = copyin((const void *)uap->timeout, (void *)&ts32, | |||
2826 | sizeof(struct timespec32)); | |||
2827 | if (error != 0) | |||
2828 | return (error); | |||
2829 | ts.tv_sec = ts32.tv_sec; | |||
2830 | ts.tv_nsec = ts32.tv_nsec; | |||
2831 | tsp = &ts; | |||
2832 | } | |||
2833 | return (kern_thr_suspend(td, tsp)); | |||
2834 | } | |||
2835 | ||||
2836 | void | |||
2837 | siginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst) | |||
2838 | { | |||
2839 | bzero(dst, sizeof(*dst))__builtin_memset((dst), 0, (sizeof(*dst))); | |||
2840 | dst->si_signo = src->si_signo; | |||
2841 | dst->si_errno = src->si_errno; | |||
2842 | dst->si_code = src->si_code; | |||
2843 | dst->si_pid = src->si_pid; | |||
2844 | dst->si_uid = src->si_uid; | |||
2845 | dst->si_status = src->si_status; | |||
2846 | dst->si_addr = (uintptr_t)src->si_addr; | |||
2847 | dst->si_value.sival_int = src->si_value.sival_int; | |||
2848 | dst->si_timerid_reason._timer._timerid = src->si_timerid_reason._timer._timerid; | |||
2849 | dst->si_overrun_reason._timer._overrun = src->si_overrun_reason._timer._overrun; | |||
2850 | } | |||
2851 | ||||
2852 | #ifndef _FREEBSD32_SYSPROTO_H_ | |||
2853 | struct freebsd32_sigqueue_args { | |||
2854 | pid_t pid; | |||
2855 | int signum; | |||
2856 | /* union sigval32 */ int value; | |||
2857 | }; | |||
2858 | #endif | |||
2859 | int | |||
2860 | freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap) | |||
2861 | { | |||
2862 | union sigval sv; | |||
2863 | ||||
2864 | /* | |||
2865 | * On 32-bit ABIs, sival_int and sival_ptr are the same. | |||
2866 | * On 64-bit little-endian ABIs, the low bits are the same. | |||
2867 | * In 64-bit big-endian ABIs, sival_int overlaps with | |||
2868 | * sival_ptr's HIGH bits. We choose to support sival_int | |||
2869 | * rather than sival_ptr in this case as it seems to be | |||
2870 | * more common. | |||
2871 | */ | |||
2872 | bzero(&sv, sizeof(sv))__builtin_memset((&sv), 0, (sizeof(sv))); | |||
2873 | sv.sival_int = uap->value; | |||
2874 | ||||
2875 | return (kern_sigqueue(td, uap->pid, uap->signum, &sv)); | |||
2876 | } | |||
2877 | ||||
2878 | int | |||
2879 | freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap) | |||
2880 | { | |||
2881 | struct timespec32 ts32; | |||
2882 | struct timespec ts; | |||
2883 | struct timespec *timeout; | |||
2884 | sigset_t set; | |||
2885 | ksiginfo_t ksi; | |||
2886 | struct siginfo32 si32; | |||
2887 | int error; | |||
2888 | ||||
2889 | if (uap->timeout) { | |||
2890 | error = copyin(uap->timeout, &ts32, sizeof(ts32)); | |||
2891 | if (error) | |||
2892 | return (error); | |||
2893 | ts.tv_sec = ts32.tv_sec; | |||
2894 | ts.tv_nsec = ts32.tv_nsec; | |||
2895 | timeout = &ts; | |||
2896 | } else | |||
2897 | timeout = NULL((void *)0); | |||
2898 | ||||
2899 | error = copyin(uap->set, &set, sizeof(set)); | |||
2900 | if (error) | |||
2901 | return (error); | |||
2902 | ||||
2903 | error = kern_sigtimedwait(td, set, &ksi, timeout); | |||
2904 | if (error) | |||
2905 | return (error); | |||
2906 | ||||
2907 | if (uap->info) { | |||
2908 | siginfo_to_siginfo32(&ksi.ksi_info, &si32); | |||
2909 | error = copyout(&si32, uap->info, sizeof(struct siginfo32)); | |||
2910 | } | |||
2911 | ||||
2912 | if (error == 0) | |||
2913 | td->td_retvaltd_uretoff.tdu_retval[0] = ksi.ksi_signoksi_info.si_signo; | |||
2914 | return (error); | |||
2915 | } | |||
2916 | ||||
2917 | /* | |||
2918 | * MPSAFE | |||
2919 | */ | |||
2920 | int | |||
2921 | freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap) | |||
2922 | { | |||
2923 | ksiginfo_t ksi; | |||
2924 | struct siginfo32 si32; | |||
2925 | sigset_t set; | |||
2926 | int error; | |||
2927 | ||||
2928 | error = copyin(uap->set, &set, sizeof(set)); | |||
2929 | if (error) | |||
2930 | return (error); | |||
2931 | ||||
2932 | error = kern_sigtimedwait(td, set, &ksi, NULL((void *)0)); | |||
2933 | if (error) | |||
2934 | return (error); | |||
2935 | ||||
2936 | if (uap->info) { | |||
2937 | siginfo_to_siginfo32(&ksi.ksi_info, &si32); | |||
2938 | error = copyout(&si32, uap->info, sizeof(struct siginfo32)); | |||
2939 | } | |||
2940 | if (error == 0) | |||
2941 | td->td_retvaltd_uretoff.tdu_retval[0] = ksi.ksi_signoksi_info.si_signo; | |||
2942 | return (error); | |||
2943 | } | |||
2944 | ||||
2945 | int | |||
2946 | freebsd32_cpuset_setid(struct thread *td, | |||
2947 | struct freebsd32_cpuset_setid_args *uap) | |||
2948 | { | |||
2949 | ||||
2950 | return (kern_cpuset_setid(td, uap->which, | |||
2951 | PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->setid)); | |||
2952 | } | |||
2953 | ||||
2954 | int | |||
2955 | freebsd32_cpuset_getid(struct thread *td, | |||
2956 | struct freebsd32_cpuset_getid_args *uap) | |||
2957 | { | |||
2958 | ||||
2959 | return (kern_cpuset_getid(td, uap->level, uap->which, | |||
2960 | PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->setid)); | |||
2961 | } | |||
2962 | ||||
2963 | int | |||
2964 | freebsd32_cpuset_getaffinity(struct thread *td, | |||
2965 | struct freebsd32_cpuset_getaffinity_args *uap) | |||
2966 | { | |||
2967 | ||||
2968 | return (kern_cpuset_getaffinity(td, uap->level, uap->which, | |||
2969 | PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->cpusetsize, uap->mask)); | |||
2970 | } | |||
2971 | ||||
2972 | int | |||
2973 | freebsd32_cpuset_setaffinity(struct thread *td, | |||
2974 | struct freebsd32_cpuset_setaffinity_args *uap) | |||
2975 | { | |||
2976 | ||||
2977 | return (kern_cpuset_setaffinity(td, uap->level, uap->which, | |||
2978 | PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->cpusetsize, uap->mask)); | |||
2979 | } | |||
2980 | ||||
2981 | int | |||
2982 | freebsd32_cpuset_getdomain(struct thread *td, | |||
2983 | struct freebsd32_cpuset_getdomain_args *uap) | |||
2984 | { | |||
2985 | ||||
2986 | return (kern_cpuset_getdomain(td, uap->level, uap->which, | |||
2987 | PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->domainsetsize, uap->mask, uap->policy)); | |||
2988 | } | |||
2989 | ||||
2990 | int | |||
2991 | freebsd32_cpuset_setdomain(struct thread *td, | |||
2992 | struct freebsd32_cpuset_setdomain_args *uap) | |||
2993 | { | |||
2994 | ||||
2995 | return (kern_cpuset_setdomain(td, uap->level, uap->which, | |||
2996 | PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->domainsetsize, uap->mask, uap->policy)); | |||
2997 | } | |||
2998 | ||||
2999 | int | |||
3000 | freebsd32_nmount(struct thread *td, | |||
3001 | struct freebsd32_nmount_args /* { | |||
3002 | struct iovec *iovp; | |||
3003 | unsigned int iovcnt; | |||
3004 | int flags; | |||
3005 | } */ *uap) | |||
3006 | { | |||
3007 | struct uio *auio; | |||
3008 | uint64_t flags; | |||
3009 | int error; | |||
3010 | ||||
3011 | /* | |||
3012 | * Mount flags are now 64-bits. On 32-bit archtectures only | |||
3013 | * 32-bits are passed in, but from here on everything handles | |||
3014 | * 64-bit flags correctly. | |||
3015 | */ | |||
3016 | flags = uap->flags; | |||
3017 | ||||
3018 | AUDIT_ARG_FFLAGS(flags)do { if ((__builtin_expect((((__curthread()))->td_pflags & 0x01000000), 0))) audit_arg_fflags((flags)); } while (0); | |||
3019 | ||||
3020 | /* | |||
3021 | * Filter out MNT_ROOTFS. We do not want clients of nmount() in | |||
3022 | * userspace to set this flag, but we must filter it out if we want | |||
3023 | * MNT_UPDATE on the root file system to work. | |||
3024 | * MNT_ROOTFS should only be set by the kernel when mounting its | |||
3025 | * root file system. | |||
3026 | */ | |||
3027 | flags &= ~MNT_ROOTFS0x0000000000004000ULL; | |||
3028 | ||||
3029 | /* | |||
3030 | * check that we have an even number of iovec's | |||
3031 | * and that we have at least two options. | |||
3032 | */ | |||
3033 | if ((uap->iovcnt & 1) || (uap->iovcnt < 4)) | |||
3034 | return (EINVAL22); | |||
3035 | ||||
3036 | error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); | |||
3037 | if (error) | |||
3038 | return (error); | |||
3039 | error = vfs_donmount(td, flags, auio); | |||
3040 | ||||
3041 | free(auio, M_IOV); | |||
3042 | return error; | |||
3043 | } | |||
3044 | ||||
3045 | #if 0 | |||
3046 | int | |||
3047 | freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) | |||
3048 | { | |||
3049 | struct yyy32 *p32, s32; | |||
3050 | struct yyy *p = NULL((void *)0), s; | |||
3051 | struct xxx_arg ap; | |||
3052 | int error; | |||
3053 | ||||
3054 | if (uap->zzz) { | |||
3055 | error = copyin(uap->zzz, &s32, sizeof(s32)); | |||
3056 | if (error) | |||
3057 | return (error); | |||
3058 | /* translate in */ | |||
3059 | p = &s; | |||
3060 | } | |||
3061 | error = kern_xxx(td, p); | |||
3062 | if (error) | |||
3063 | return (error); | |||
3064 | if (uap->zzz) { | |||
3065 | /* translate out */ | |||
3066 | error = copyout(&s32, p32, sizeof(s32)); | |||
3067 | } | |||
3068 | return (error); | |||
3069 | } | |||
3070 | #endif | |||
3071 | ||||
3072 | int | |||
3073 | syscall32_module_handler(struct module *mod, int what, void *arg) | |||
3074 | { | |||
3075 | ||||
3076 | return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg)); | |||
3077 | } | |||
3078 | ||||
3079 | int | |||
3080 | syscall32_helper_register(struct syscall_helper_data *sd, int flags) | |||
3081 | { | |||
3082 | ||||
3083 | return (kern_syscall_helper_register(freebsd32_sysent, sd, flags)); | |||
3084 | } | |||
3085 | ||||
3086 | int | |||
3087 | syscall32_helper_unregister(struct syscall_helper_data *sd) | |||
3088 | { | |||
3089 | ||||
3090 | return (kern_syscall_helper_unregister(freebsd32_sysent, sd)); | |||
3091 | } | |||
3092 | ||||
3093 | register_t * | |||
3094 | freebsd32_copyout_strings(struct image_params *imgp) | |||
3095 | { | |||
3096 | int argc, envc, i; | |||
3097 | u_int32_t *vectp; | |||
3098 | char *stringp; | |||
3099 | uintptr_t destp; | |||
3100 | u_int32_t *stack_base; | |||
3101 | struct freebsd32_ps_strings *arginfo; | |||
3102 | char canary[sizeof(long) * 8]; | |||
3103 | int32_t pagesizes32[MAXPAGESIZES3]; | |||
3104 | size_t execpath_len; | |||
3105 | int szsigcode; | |||
3106 | ||||
3107 | /* | |||
3108 | * Calculate string base and vector table pointers. | |||
3109 | * Also deal with signal trampoline code for this exec type. | |||
3110 | */ | |||
3111 | if (imgp->execpath != NULL((void *)0) && imgp->auxargs != NULL((void *)0)) | |||
3112 | execpath_len = strlen(imgp->execpath) + 1; | |||
3113 | else | |||
3114 | execpath_len = 0; | |||
3115 | arginfo = (struct freebsd32_ps_strings *)curproc((__curthread())->td_proc)->p_sysent-> | |||
3116 | sv_psstrings; | |||
3117 | if (imgp->proc->p_sysent->sv_sigcode_base == 0) | |||
3118 | szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); | |||
3119 | else | |||
3120 | szsigcode = 0; | |||
3121 | destp = (uintptr_t)arginfo; | |||
3122 | ||||
3123 | /* | |||
3124 | * install sigcode | |||
3125 | */ | |||
3126 | if (szsigcode != 0) { | |||
3127 | destp -= szsigcode; | |||
3128 | destp = rounddown2(destp, sizeof(uint32_t))((destp)&(~((sizeof(uint32_t))-1))); | |||
3129 | copyout(imgp->proc->p_sysent->sv_sigcode, (void *)destp, | |||
3130 | szsigcode); | |||
3131 | } | |||
3132 | ||||
3133 | /* | |||
3134 | * Copy the image path for the rtld. | |||
3135 | */ | |||
3136 | if (execpath_len != 0) { | |||
3137 | destp -= execpath_len; | |||
3138 | imgp->execpathp = destp; | |||
3139 | copyout(imgp->execpath, (void *)destp, execpath_len); | |||
3140 | } | |||
3141 | ||||
3142 | /* | |||
3143 | * Prepare the canary for SSP. | |||
3144 | */ | |||
3145 | arc4rand(canary, sizeof(canary), 0); | |||
3146 | destp -= sizeof(canary); | |||
3147 | imgp->canary = destp; | |||
3148 | copyout(canary, (void *)destp, sizeof(canary)); | |||
3149 | imgp->canarylen = sizeof(canary); | |||
3150 | ||||
3151 | /* | |||
3152 | * Prepare the pagesizes array. | |||
3153 | */ | |||
3154 | for (i = 0; i < MAXPAGESIZES3; i++) | |||
3155 | pagesizes32[i] = (uint32_t)pagesizes[i]; | |||
3156 | destp -= sizeof(pagesizes32); | |||
3157 | destp = rounddown2(destp, sizeof(uint32_t))((destp)&(~((sizeof(uint32_t))-1))); | |||
3158 | imgp->pagesizes = destp; | |||
3159 | copyout(pagesizes32, (void *)destp, sizeof(pagesizes32)); | |||
3160 | imgp->pagesizeslen = sizeof(pagesizes32); | |||
3161 | ||||
3162 | destp -= ARG_MAX262144 - imgp->args->stringspace; | |||
3163 | destp = rounddown2(destp, sizeof(uint32_t))((destp)&(~((sizeof(uint32_t))-1))); | |||
3164 | ||||
3165 | vectp = (uint32_t *)destp; | |||
3166 | if (imgp->auxargs) { | |||
3167 | /* | |||
3168 | * Allocate room on the stack for the ELF auxargs | |||
3169 | * array. It has up to AT_COUNT entries. | |||
3170 | */ | |||
3171 | vectp -= howmany(AT_COUNT * sizeof(Elf32_Auxinfo),(((27 * sizeof(Elf32_Auxinfo))+((sizeof(*vectp))-1))/(sizeof( *vectp))) | |||
3172 | sizeof(*vectp))(((27 * sizeof(Elf32_Auxinfo))+((sizeof(*vectp))-1))/(sizeof( *vectp))); | |||
3173 | } | |||
3174 | ||||
3175 | /* | |||
3176 | * Allocate room for the argv[] and env vectors including the | |||
3177 | * terminating NULL pointers. | |||
3178 | */ | |||
3179 | vectp -= imgp->args->argc + 1 + imgp->args->envc + 1; | |||
3180 | ||||
3181 | /* | |||
3182 | * vectp also becomes our initial stack base | |||
3183 | */ | |||
3184 | stack_base = vectp; | |||
3185 | ||||
3186 | stringp = imgp->args->begin_argv; | |||
3187 | argc = imgp->args->argc; | |||
3188 | envc = imgp->args->envc; | |||
3189 | /* | |||
3190 | * Copy out strings - arguments and environment. | |||
3191 | */ | |||
3192 | copyout(stringp, (void *)destp, ARG_MAX262144 - imgp->args->stringspace); | |||
3193 | ||||
3194 | /* | |||
3195 | * Fill in "ps_strings" struct for ps, w, etc. | |||
3196 | */ | |||
3197 | suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); | |||
3198 | suword32(&arginfo->ps_nargvstr, argc); | |||
3199 | ||||
3200 | /* | |||
3201 | * Fill in argument portion of vector table. | |||
3202 | */ | |||
3203 | for (; argc > 0; --argc) { | |||
3204 | suword32(vectp++, (u_int32_t)(intptr_t)destp); | |||
3205 | while (*stringp++ != 0) | |||
3206 | destp++; | |||
3207 | destp++; | |||
3208 | } | |||
3209 | ||||
3210 | /* a null vector table pointer separates the argp's from the envp's */ | |||
3211 | suword32(vectp++, 0); | |||
3212 | ||||
3213 | suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); | |||
3214 | suword32(&arginfo->ps_nenvstr, envc); | |||
3215 | ||||
3216 | /* | |||
3217 | * Fill in environment portion of vector table. | |||
3218 | */ | |||
3219 | for (; envc > 0; --envc) { | |||
3220 | suword32(vectp++, (u_int32_t)(intptr_t)destp); | |||
3221 | while (*stringp++ != 0) | |||
3222 | destp++; | |||
3223 | destp++; | |||
3224 | } | |||
3225 | ||||
3226 | /* end of vector table is a null pointer */ | |||
3227 | suword32(vectp, 0); | |||
3228 | ||||
3229 | return ((register_t *)stack_base); | |||
3230 | } | |||
3231 | ||||
3232 | int | |||
3233 | freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap) | |||
3234 | { | |||
3235 | struct kld_file_stat *stat; | |||
3236 | struct kld32_file_stat *stat32; | |||
3237 | int error, version; | |||
3238 | ||||
3239 | if ((error = copyin(&uap->stat->version, &version, sizeof(version))) | |||
3240 | != 0) | |||
3241 | return (error); | |||
3242 | if (version != sizeof(struct kld32_file_stat_1) && | |||
3243 | version != sizeof(struct kld32_file_stat)) | |||
3244 | return (EINVAL22); | |||
3245 | ||||
3246 | stat = malloc(sizeof(*stat), M_TEMP, M_WAITOK0x0002 | M_ZERO0x0100); | |||
3247 | stat32 = malloc(sizeof(*stat32), M_TEMP, M_WAITOK0x0002 | M_ZERO0x0100); | |||
3248 | error = kern_kldstat(td, uap->fileid, stat); | |||
3249 | if (error == 0) { | |||
3250 | bcopy(&stat->name[0], &stat32->name[0], sizeof(stat->name))__builtin_memmove((&stat32->name[0]), (&stat->name [0]), (sizeof(stat->name))); | |||
3251 | CP(*stat, *stat32, refs)do { (*stat32).refs = (*stat).refs; } while (0); | |||
3252 | CP(*stat, *stat32, id)do { (*stat32).id = (*stat).id; } while (0); | |||
3253 | PTROUT_CP(*stat, *stat32, address)do { (*stat32).address = (u_int32_t)(uintptr_t) ((*stat).address ); } while (0); | |||
3254 | CP(*stat, *stat32, size)do { (*stat32).size = (*stat).size; } while (0); | |||
3255 | bcopy(&stat->pathname[0], &stat32->pathname[0],__builtin_memmove((&stat32->pathname[0]), (&stat-> pathname[0]), (sizeof(stat->pathname))) | |||
3256 | sizeof(stat->pathname))__builtin_memmove((&stat32->pathname[0]), (&stat-> pathname[0]), (sizeof(stat->pathname))); | |||
3257 | stat32->version = version; | |||
3258 | error = copyout(stat32, uap->stat, version); | |||
3259 | } | |||
3260 | free(stat, M_TEMP); | |||
3261 | free(stat32, M_TEMP); | |||
3262 | return (error); | |||
3263 | } | |||
3264 | ||||
3265 | int | |||
3266 | freebsd32_posix_fallocate(struct thread *td, | |||
3267 | struct freebsd32_posix_fallocate_args *uap) | |||
3268 | { | |||
3269 | int error; | |||
3270 | ||||
3271 | error = kern_posix_fallocate(td, uap->fd, | |||
3272 | PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)), PAIR32TO64(off_t, uap->len)((uap->len1) | ((off_t)(uap->len2) << 32))); | |||
3273 | return (kern_posix_error(td, error)); | |||
3274 | } | |||
3275 | ||||
3276 | int | |||
3277 | freebsd32_posix_fadvise(struct thread *td, | |||
3278 | struct freebsd32_posix_fadvise_args *uap) | |||
3279 | { | |||
3280 | int error; | |||
3281 | ||||
3282 | error = kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)), | |||
3283 | PAIR32TO64(off_t, uap->len)((uap->len1) | ((off_t)(uap->len2) << 32)), uap->advice); | |||
3284 | return (kern_posix_error(td, error)); | |||
3285 | } | |||
3286 | ||||
3287 | int | |||
3288 | convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig) | |||
3289 | { | |||
3290 | ||||
3291 | CP(*sig32, *sig, sigev_notify)do { (*sig).sigev_notify = (*sig32).sigev_notify; } while (0); | |||
3292 | switch (sig->sigev_notify) { | |||
3293 | case SIGEV_NONE0: | |||
3294 | break; | |||
3295 | case SIGEV_THREAD_ID4: | |||
3296 | CP(*sig32, *sig, sigev_notify_thread_id)do { (*sig)._sigev_un._threadid = (*sig32)._sigev_un._threadid ; } while (0); | |||
3297 | /* FALLTHROUGH */ | |||
3298 | case SIGEV_SIGNAL1: | |||
3299 | CP(*sig32, *sig, sigev_signo)do { (*sig).sigev_signo = (*sig32).sigev_signo; } while (0); | |||
3300 | PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr)do { (*sig).sigev_value.sival_ptr = (void *)(uintptr_t) ((*sig32 ).sigev_value.sival_ptr); } while (0); | |||
3301 | break; | |||
3302 | case SIGEV_KEVENT3: | |||
3303 | CP(*sig32, *sig, sigev_notify_kqueue)do { (*sig).sigev_signo = (*sig32).sigev_signo; } while (0); | |||
3304 | CP(*sig32, *sig, sigev_notify_kevent_flags)do { (*sig)._sigev_un._kevent_flags = (*sig32)._sigev_un._kevent_flags ; } while (0); | |||
3305 | PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr)do { (*sig).sigev_value.sival_ptr = (void *)(uintptr_t) ((*sig32 ).sigev_value.sival_ptr); } while (0); | |||
3306 | break; | |||
3307 | default: | |||
3308 | return (EINVAL22); | |||
3309 | } | |||
3310 | return (0); | |||
3311 | } | |||
3312 | ||||
3313 | int | |||
3314 | freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap) | |||
3315 | { | |||
3316 | void *data; | |||
3317 | union { | |||
3318 | struct procctl_reaper_status rs; | |||
3319 | struct procctl_reaper_pids rp; | |||
3320 | struct procctl_reaper_kill rk; | |||
3321 | } x; | |||
3322 | union { | |||
3323 | struct procctl_reaper_pids32 rp; | |||
3324 | } x32; | |||
3325 | int error, error1, flags, signum; | |||
3326 | ||||
3327 | switch (uap->com) { | |||
3328 | case PROC_SPROTECT1: | |||
3329 | case PROC_TRACE_CTL7: | |||
3330 | case PROC_TRAPCAP_CTL9: | |||
3331 | error = copyin(PTRIN(uap->data)(void *)(uintptr_t) (uap->data), &flags, sizeof(flags)); | |||
3332 | if (error != 0) | |||
3333 | return (error); | |||
3334 | data = &flags; | |||
3335 | break; | |||
3336 | case PROC_REAP_ACQUIRE2: | |||
3337 | case PROC_REAP_RELEASE3: | |||
3338 | if (uap->data != NULL((void *)0)) | |||
3339 | return (EINVAL22); | |||
3340 | data = NULL((void *)0); | |||
3341 | break; | |||
3342 | case PROC_REAP_STATUS4: | |||
3343 | data = &x.rs; | |||
3344 | break; | |||
3345 | case PROC_REAP_GETPIDS5: | |||
3346 | error = copyin(uap->data, &x32.rp, sizeof(x32.rp)); | |||
3347 | if (error != 0) | |||
3348 | return (error); | |||
3349 | CP(x32.rp, x.rp, rp_count)do { (x.rp).rp_count = (x32.rp).rp_count; } while (0); | |||
3350 | PTRIN_CP(x32.rp, x.rp, rp_pids)do { (x.rp).rp_pids = (void *)(uintptr_t) ((x32.rp).rp_pids); } while (0); | |||
3351 | data = &x.rp; | |||
3352 | break; | |||
3353 | case PROC_REAP_KILL6: | |||
3354 | error = copyin(uap->data, &x.rk, sizeof(x.rk)); | |||
3355 | if (error != 0) | |||
3356 | return (error); | |||
3357 | data = &x.rk; | |||
3358 | break; | |||
3359 | case PROC_TRACE_STATUS8: | |||
3360 | case PROC_TRAPCAP_STATUS10: | |||
3361 | data = &flags; | |||
3362 | break; | |||
3363 | case PROC_PDEATHSIG_CTL11: | |||
3364 | error = copyin(uap->data, &signum, sizeof(signum)); | |||
3365 | if (error != 0) | |||
3366 | return (error); | |||
3367 | data = &signum; | |||
3368 | break; | |||
3369 | case PROC_PDEATHSIG_STATUS12: | |||
3370 | data = &signum; | |||
3371 | break; | |||
3372 | default: | |||
3373 | return (EINVAL22); | |||
3374 | } | |||
3375 | error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), | |||
3376 | uap->com, data); | |||
3377 | switch (uap->com) { | |||
3378 | case PROC_REAP_STATUS4: | |||
3379 | if (error == 0) | |||
3380 | error = copyout(&x.rs, uap->data, sizeof(x.rs)); | |||
3381 | break; | |||
3382 | case PROC_REAP_KILL6: | |||
3383 | error1 = copyout(&x.rk, uap->data, sizeof(x.rk)); | |||
3384 | if (error == 0) | |||
3385 | error = error1; | |||
3386 | break; | |||
3387 | case PROC_TRACE_STATUS8: | |||
3388 | case PROC_TRAPCAP_STATUS10: | |||
3389 | if (error == 0) | |||
3390 | error = copyout(&flags, uap->data, sizeof(flags)); | |||
3391 | break; | |||
3392 | case PROC_PDEATHSIG_STATUS12: | |||
3393 | if (error == 0) | |||
3394 | error = copyout(&signum, uap->data, sizeof(signum)); | |||
3395 | break; | |||
3396 | } | |||
3397 | return (error); | |||
3398 | } | |||
3399 | ||||
3400 | int | |||
3401 | freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap) | |||
3402 | { | |||
3403 | long tmp; | |||
3404 | ||||
3405 | switch (uap->cmd) { | |||
3406 | /* | |||
3407 | * Do unsigned conversion for arg when operation | |||
3408 | * interprets it as flags or pointer. | |||
3409 | */ | |||
3410 | case F_SETLK_REMOTE14: | |||
3411 | case F_SETLKW13: | |||
3412 | case F_SETLK12: | |||
3413 | case F_GETLK11: | |||
3414 | case F_SETFD2: | |||
3415 | case F_SETFL4: | |||
3416 | case F_OGETLK7: | |||
3417 | case F_OSETLK8: | |||
3418 | case F_OSETLKW9: | |||
3419 | tmp = (unsigned int)(uap->arg); | |||
3420 | break; | |||
3421 | default: | |||
3422 | tmp = uap->arg; | |||
3423 | break; | |||
3424 | } | |||
3425 | return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp)); | |||
3426 | } | |||
3427 | ||||
3428 | int | |||
3429 | freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap) | |||
3430 | { | |||
3431 | struct timespec32 ts32; | |||
3432 | struct timespec ts, *tsp; | |||
3433 | sigset_t set, *ssp; | |||
3434 | int error; | |||
3435 | ||||
3436 | if (uap->ts != NULL((void *)0)) { | |||
3437 | error = copyin(uap->ts, &ts32, sizeof(ts32)); | |||
3438 | if (error != 0) | |||
3439 | return (error); | |||
3440 | CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0); | |||
3441 | CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0); | |||
3442 | tsp = &ts; | |||
3443 | } else | |||
3444 | tsp = NULL((void *)0); | |||
3445 | if (uap->set != NULL((void *)0)) { | |||
3446 | error = copyin(uap->set, &set, sizeof(set)); | |||
3447 | if (error != 0) | |||
3448 | return (error); | |||
3449 | ssp = &set; | |||
3450 | } else | |||
3451 | ssp = NULL((void *)0); | |||
3452 | ||||
3453 | return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp)); | |||
3454 | } | |||
3455 | ||||
3456 | int | |||
3457 | freebsd32_sched_rr_get_interval(struct thread *td, | |||
3458 | struct freebsd32_sched_rr_get_interval_args *uap) | |||
3459 | { | |||
3460 | struct timespec ts; | |||
3461 | struct timespec32 ts32; | |||
3462 | int error; | |||
3463 | ||||
3464 | error = kern_sched_rr_get_interval(td, uap->pid, &ts); | |||
3465 | if (error == 0) { | |||
3466 | CP(ts, ts32, tv_sec)do { (ts32).tv_sec = (ts).tv_sec; } while (0); | |||
3467 | CP(ts, ts32, tv_nsec)do { (ts32).tv_nsec = (ts).tv_nsec; } while (0); | |||
3468 | error = copyout(&ts32, uap->interval, sizeof(ts32)); | |||
3469 | } | |||
3470 | return (error); | |||
3471 | } |