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