]>
Commit | Line | Data |
---|---|---|
e2e5d75f PF |
1 | /*--------------------------------------------------------------------*/ |
2 | /*--- FreeBSD-specific syscalls, etc. syswrap-freebsd.c ---*/ | |
3 | /*--------------------------------------------------------------------*/ | |
4 | ||
5 | /* | |
6 | This file is part of Valgrind, a dynamic binary instrumentation | |
7 | framework. | |
8 | ||
9 | Copyright (C) 2000-2008 Nicholas Nethercote | |
10 | njn@valgrind.org | |
11 | Copyright (C) 2018-2021 Paul Floyd | |
12 | pjfloyd@wanadoo.fr | |
13 | ||
14 | This program is free software; you can redistribute it and/or | |
15 | modify it under the terms of the GNU General Public License as | |
16 | published by the Free Software Foundation; either version 2 of the | |
17 | License, or (at your option) any later version. | |
18 | ||
19 | This program is distributed in the hope that it will be useful, but | |
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
22 | General Public License for more details. | |
23 | ||
24 | You should have received a copy of the GNU General Public License | |
25 | along with this program; if not, see <http://www.gnu.org/licenses/>. | |
26 | ||
27 | The GNU General Public License is contained in the file COPYING. | |
28 | */ | |
29 | ||
30 | #if defined(VGO_freebsd) | |
31 | ||
bf347551 | 32 | #include "pub_core_basics.h" |
76d6b459 PF |
33 | #include "pub_core_vki.h" |
34 | #include "pub_core_vkiscnums.h" | |
35 | #include "pub_core_threadstate.h" | |
36 | #include "pub_core_aspacemgr.h" | |
37 | #include "pub_core_debuginfo.h" // VG_(di_notify_*) | |
38 | #include "pub_core_transtab.h" // VG_(discard_translations) | |
39 | #include "pub_core_xarray.h" | |
e2e5d75f PF |
40 | #include "pub_core_clientstate.h" |
41 | #include "pub_core_debuglog.h" | |
bf347551 | 42 | #include "pub_core_libcbase.h" |
76d6b459 | 43 | #include "pub_core_libcassert.h" |
e2e5d75f PF |
44 | #include "pub_core_libcfile.h" |
45 | #include "pub_core_libcprint.h" | |
46 | #include "pub_core_libcproc.h" | |
47 | #include "pub_core_libcsignal.h" | |
48 | #include "pub_core_machine.h" | |
49 | #include "pub_core_mallocfree.h" | |
76d6b459 | 50 | #include "pub_core_tooliface.h" |
e2e5d75f PF |
51 | #include "pub_core_options.h" |
52 | #include "pub_core_scheduler.h" | |
53 | #include "pub_core_signals.h" | |
54 | #include "pub_core_stacks.h" | |
55 | #include "pub_core_syscall.h" | |
56 | #include "pub_core_syswrap.h" | |
76d6b459 PF |
57 | #include "pub_core_inner.h" |
58 | #include "pub_core_pathscan.h" | |
a15b387e | 59 | #include "pub_core_oset.h" |
e2e5d75f PF |
60 | #if defined(ENABLE_INNER_CLIENT_REQUEST) |
61 | #include "pub_core_clreq.h" | |
62 | #endif | |
63 | ||
76d6b459 | 64 | #include "priv_types_n_macros.h" |
e2e5d75f PF |
65 | #include "priv_syswrap-generic.h" |
66 | #include "priv_syswrap-main.h" | |
76d6b459 | 67 | #include "priv_syswrap-freebsd.h" |
e2e5d75f PF |
68 | |
69 | static Bool capabiltyMode = False; | |
70 | ||
76d6b459 PF |
71 | Bool VG_(get_capability_mode)(void) |
72 | { | |
73 | return capabiltyMode; | |
74 | } | |
75 | ||
e2e5d75f PF |
76 | |
77 | // Run a thread from beginning to end and return the thread's | |
78 | // scheduler-return-code. | |
79 | static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW) | |
80 | { | |
81 | VgSchedReturnCode ret; | |
76d6b459 PF |
82 | ThreadId tid = (ThreadId)tidW; |
83 | Int lwpid = VG_(gettid)(); | |
84 | ThreadState* tst = VG_(get_ThreadState)(tid); | |
e2e5d75f PF |
85 | |
86 | VG_(debugLog)(1, "syswrap-freebsd", | |
76d6b459 PF |
87 | "thread_wrapper(tid=%u,lwpid=%d): entry\n", |
88 | tid, lwpid); | |
e2e5d75f PF |
89 | |
90 | vg_assert(tst->status == VgTs_Init); | |
91 | ||
92 | /* make sure we get the CPU lock before doing anything significant */ | |
93 | VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)"); | |
94 | ||
227fa1d5 | 95 | if (0) { |
76d6b459 PF |
96 | VG_(printf)("thread tid %u started: stack = %p\n", |
97 | tid, (void*)&tid); | |
227fa1d5 | 98 | } |
e2e5d75f PF |
99 | |
100 | /* Make sure error reporting is enabled in the new thread. */ | |
101 | tst->err_disablement_level = 0; | |
102 | ||
103 | VG_TRACK(pre_thread_first_insn, tid); | |
104 | ||
e489f319 | 105 | tst->os_state.lwpid = lwpid; |
e2e5d75f PF |
106 | /* Set the threadgroup for real. This overwrites the provisional value set |
107 | in do_clone(). See comments in do_clone for background, also #226116. */ | |
108 | tst->os_state.threadgroup = VG_(getpid)(); | |
109 | ||
110 | /* Thread created with all signals blocked; scheduler will set the | |
111 | appropriate mask */ | |
112 | ||
113 | ret = VG_(scheduler)(tid); | |
114 | ||
115 | vg_assert(VG_(is_exiting)(tid)); | |
116 | ||
117 | vg_assert(tst->status == VgTs_Runnable); | |
118 | vg_assert(VG_(is_running_thread)(tid)); | |
119 | ||
120 | VG_(debugLog)(1, "syswrap-freebsd", | |
e489f319 PW |
121 | "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n", |
122 | tid, lwpid, VG_(name_of_VgSchedReturnCode)(ret)); | |
e2e5d75f PF |
123 | |
124 | /* Return to caller, still holding the lock. */ | |
125 | return ret; | |
126 | } | |
127 | ||
76d6b459 | 128 | |
e2e5d75f PF |
129 | /* --------------------------------------------------------------------- |
130 | clone-related stuff | |
131 | ------------------------------------------------------------------ */ | |
132 | ||
133 | /* Run a thread all the way to the end, then do appropriate exit actions | |
57dc8fd6 PF |
134 | * (this is the last-one-out-turn-off-the-lights bit). |
135 | * | |
136 | * This is marked as __attribute__((noreturn)). That has the effect of | |
137 | * making clang++ no longer emit the function prologue and epilogue | |
138 | * to save the base pointer. | |
139 | * | |
140 | * As far as I can tell clang -O2 does not include -fomit-frame-pointer | |
141 | * However, since from here on the saved base pointer values are | |
142 | * junk tools like FreeBSD pstack that only rely on base pointer | |
143 | * walking will not work. FreeBSD bstack does work, based on GDB and | |
144 | * reading debuginfo. | |
145 | * | |
146 | * If you really need a working base pointer modify Makefile.all.am | |
147 | * and add -fno-omit-frame-pointer to AM_CFLAGS_BASE. | |
148 | */ | |
76d6b459 PF |
149 | __attribute__((noreturn)) |
150 | static void run_a_thread_NORETURN ( Word tidW ) | |
e2e5d75f PF |
151 | { |
152 | ThreadId tid = (ThreadId)tidW; | |
153 | VgSchedReturnCode src; | |
154 | Int c; | |
155 | ThreadState* tst; | |
156 | #ifdef ENABLE_INNER_CLIENT_REQUEST | |
76d6b459 | 157 | Int registered_vgstack_id; |
e2e5d75f PF |
158 | #endif |
159 | ||
160 | VG_(debugLog)(1, "syswrap-freebsd", | |
76d6b459 PF |
161 | "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n", |
162 | tid); | |
e2e5d75f PF |
163 | |
164 | tst = VG_(get_ThreadState)(tid); | |
165 | vg_assert(tst); | |
166 | ||
167 | /* An thread has two stacks: | |
168 | * the simulated stack (used by the synthetic cpu. Guest process | |
169 | is using this stack). | |
170 | * the valgrind stack (used by the real cpu. Valgrind code is running | |
171 | on this stack). | |
172 | When Valgrind runs as an inner, it must signals that its (real) stack | |
173 | is the stack to use by the outer to e.g. do stacktraces. | |
174 | */ | |
76d6b459 PF |
175 | INNER_REQUEST |
176 | (registered_vgstack_id | |
177 | = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, | |
178 | tst->os_state.valgrind_stack_init_SP)); | |
e2e5d75f PF |
179 | |
180 | /* Run the thread all the way through. */ | |
181 | src = thread_wrapper(tid); | |
182 | ||
183 | VG_(debugLog)(1, "syswrap-freebsd", | |
76d6b459 PF |
184 | "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n", |
185 | tid); | |
e2e5d75f PF |
186 | |
187 | c = VG_(count_living_threads)(); | |
188 | vg_assert(c >= 1); /* stay sane */ | |
189 | ||
190 | /* Deregister thread's stack. */ | |
227fa1d5 | 191 | if (tst->os_state.stk_id != NULL_STK_ID) { |
e2e5d75f | 192 | VG_(deregister_stack)(tst->os_state.stk_id); |
227fa1d5 | 193 | } |
e2e5d75f PF |
194 | |
195 | // Tell the tool this thread is exiting | |
76d6b459 | 196 | VG_TRACK( pre_thread_ll_exit, tid ); |
e2e5d75f PF |
197 | |
198 | /* If the thread is exiting with errors disabled, complain loudly; | |
199 | doing so is bad (does the user know this has happened?) Also, | |
200 | in all cases, be paranoid and clear the flag anyway so that the | |
201 | thread slot is safe in this respect if later reallocated. This | |
202 | should be unnecessary since the flag should be cleared when the | |
203 | slot is reallocated, in thread_wrapper(). */ | |
204 | if (tst->err_disablement_level > 0) { | |
76d6b459 PF |
205 | VG_(umsg)( |
206 | "WARNING: exiting thread has error reporting disabled.\n" | |
207 | "WARNING: possibly as a result of some mistake in the use\n" | |
208 | "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n" | |
209 | ); | |
210 | VG_(debugLog)( | |
211 | 1, "syswrap-freebsd", | |
212 | "run_a_thread_NORETURN(tid=%u): " | |
213 | "WARNING: exiting thread has err_disablement_level = %u\n", | |
214 | tid, tst->err_disablement_level | |
215 | ); | |
e2e5d75f PF |
216 | } |
217 | tst->err_disablement_level = 0; | |
218 | ||
219 | if (c == 1) { | |
220 | ||
221 | VG_(debugLog)(1, "syswrap-freebsd", | |
222 | "run_a_thread_NORETURN(tid=%u): " | |
223 | "last one standing\n", | |
224 | tid); | |
225 | ||
226 | /* We are the last one standing. Keep hold of the lock and | |
227 | carry on to show final tool results, then exit the entire system. | |
228 | Use the continuation pointer set at startup in m_main. */ | |
76d6b459 | 229 | ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src); |
e2e5d75f PF |
230 | } else { |
231 | ||
232 | VG_(debugLog)(1, "syswrap-freebsd", | |
233 | "run_a_thread_NORETURN(tid=%u): " | |
234 | "not last one standing\n", | |
235 | tid); | |
236 | ||
237 | /* OK, thread is dead, but others still exist. Just exit. */ | |
238 | ||
239 | /* This releases the run lock */ | |
240 | VG_(exit_thread)(tid); | |
241 | vg_assert(tst->status == VgTs_Zombie); | |
242 | vg_assert(sizeof(tst->status) == 4); | |
243 | vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word)); | |
244 | ||
76d6b459 | 245 | INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id)); |
e2e5d75f PF |
246 | |
247 | /* We have to use this sequence to terminate the thread to | |
248 | prevent a subtle race. If VG_(exit_thread)() had left the | |
249 | ThreadState as Empty, then it could have been reallocated, | |
250 | reusing the stack while we're doing these last cleanups. | |
251 | Instead, VG_(exit_thread) leaves it as Zombie to prevent | |
252 | reallocation. We need to make sure we don't touch the stack | |
253 | between marking it Empty and exiting. Hence the | |
254 | assembler. */ | |
76d6b459 PF |
255 | #if defined(VGP_x86_freebsd) /* FreeBSD has args on the stack */ |
256 | __asm__ volatile ( | |
e2e5d75f | 257 | "movl %1, %0\n" /* set tst->status = VgTs_Empty */ |
76d6b459 PF |
258 | "movl %2, %%eax\n" /* set %eax = __NR_thr_exit */ |
259 | "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */ | |
260 | "pushl %%ebx\n" /* arg on stack */ | |
261 | "pushl %%ebx\n" /* fake return address */ | |
262 | "int $0x80\n" /* thr_exit(tst->os_state.exitcode) */ | |
263 | "popl %%ebx\n" /* fake return address */ | |
264 | "popl %%ebx\n" /* arg off stack */ | |
265 | : "=m" (tst->status) | |
266 | : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) | |
267 | : "eax", "ebx" | |
268 | ); | |
e2e5d75f | 269 | #elif defined(VGP_amd64_freebsd) |
76d6b459 | 270 | __asm__ volatile ( |
e2e5d75f | 271 | "movl %1, %0\n" /* set tst->status = VgTs_Empty */ |
76d6b459 PF |
272 | "movq %2, %%rax\n" /* set %rax = __NR_thr_exit */ |
273 | "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */ | |
274 | "pushq %%rdi\n" /* fake return address */ | |
275 | "syscall\n" /* thr_exit(tst->os_state.exitcode) */ | |
276 | "popq %%rdi\n" /* fake return address */ | |
277 | : "=m" (tst->status) | |
278 | : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) | |
279 | : "rax", "rdi" | |
280 | ); | |
26924849 PF |
281 | #elif defined(VGP_arm64_freebsd) |
282 | __asm__ volatile ( | |
283 | "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */ | |
284 | "mov x8, %2\n" /* set %x8 = __NR_thr_exit */ | |
285 | "ldr x0, %3\n" /* set %x0 = tst->os_state.exitcode */ | |
286 | "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */ | |
287 | : "=m" (tst->status) | |
288 | : "r" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) | |
289 | : "x0", "x8" | |
290 | ); | |
e2e5d75f | 291 | #else |
76d6b459 | 292 | # error Unknown platform |
e2e5d75f PF |
293 | #endif |
294 | ||
295 | VG_(core_panic)("Thread exit failed?\n"); | |
296 | } | |
297 | ||
298 | /*NOTREACHED*/ | |
299 | vg_assert(0); | |
300 | } | |
301 | ||
76d6b459 | 302 | Word ML_(start_thread_NORETURN) ( void* arg ) |
e2e5d75f PF |
303 | { |
304 | ThreadState* tst = (ThreadState*)arg; | |
305 | ThreadId tid = tst->tid; | |
306 | ||
76d6b459 | 307 | run_a_thread_NORETURN ( (Word)tid ); |
e2e5d75f PF |
308 | /*NOTREACHED*/ |
309 | vg_assert(0); | |
310 | } | |
311 | ||
312 | /* Allocate a stack for this thread, if it doesn't already have one. | |
313 | They're allocated lazily, and never freed. Returns the initial stack | |
314 | pointer value to use, or 0 if allocation failed. */ | |
315 | Addr ML_(allocstack)(ThreadId tid) | |
316 | { | |
317 | ThreadState* tst = VG_(get_ThreadState)(tid); | |
318 | VgStack* stack; | |
319 | Addr initial_SP; | |
320 | ||
321 | /* Either the stack_base and stack_init_SP are both zero (in which | |
322 | case a stack hasn't been allocated) or they are both non-zero, | |
323 | in which case it has. */ | |
324 | ||
29cfa77b | 325 | if (tst->os_state.valgrind_stack_base == 0) { |
e2e5d75f | 326 | vg_assert(tst->os_state.valgrind_stack_init_SP == 0); |
29cfa77b | 327 | } |
e2e5d75f | 328 | |
29cfa77b | 329 | if (tst->os_state.valgrind_stack_base != 0) { |
e2e5d75f | 330 | vg_assert(tst->os_state.valgrind_stack_init_SP != 0); |
29cfa77b | 331 | } |
e2e5d75f PF |
332 | |
333 | /* If no stack is present, allocate one. */ | |
334 | ||
335 | if (tst->os_state.valgrind_stack_base == 0) { | |
76d6b459 | 336 | stack = VG_(am_alloc_VgStack)( &initial_SP ); |
e2e5d75f PF |
337 | if (stack) { |
338 | tst->os_state.valgrind_stack_base = (Addr)stack; | |
339 | tst->os_state.valgrind_stack_init_SP = initial_SP; | |
340 | } | |
341 | } | |
342 | ||
227fa1d5 | 343 | if (0) { |
76d6b459 PF |
344 | VG_(printf)( "stack for tid %u at %p; init_SP=%p\n", |
345 | tid, | |
346 | (void*)tst->os_state.valgrind_stack_base, | |
347 | (void*)tst->os_state.valgrind_stack_init_SP ); | |
227fa1d5 | 348 | } |
e2e5d75f PF |
349 | |
350 | return tst->os_state.valgrind_stack_init_SP; | |
351 | } | |
352 | ||
353 | /* Allocate a stack for the main thread, and run it all the way to the | |
354 | end. Although we already have a working VgStack | |
355 | (VG_(interim_stack)) it's better to allocate a new one, so that | |
356 | overflow detection works uniformly for all threads. | |
357 | */ | |
76d6b459 PF |
358 | __attribute__((noreturn)) |
359 | void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) | |
e2e5d75f PF |
360 | { |
361 | Addr sp; | |
362 | VG_(debugLog)(1, "syswrap-freebsd", | |
363 | "entering VG_(main_thread_wrapper_NORETURN)\n"); | |
364 | ||
365 | sp = ML_(allocstack)(tid); | |
366 | #if defined(ENABLE_INNER_CLIENT_REQUEST) | |
367 | { | |
368 | // we must register the main thread stack before the call | |
369 | // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind | |
370 | // reports 'write error' on the non registered stack. | |
371 | ThreadState* tst = VG_(get_ThreadState)(tid); | |
76d6b459 PF |
372 | INNER_REQUEST |
373 | ((void) | |
374 | VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, | |
375 | tst->os_state.valgrind_stack_init_SP)); | |
e2e5d75f PF |
376 | } |
377 | #endif | |
378 | ||
379 | /* If we can't even allocate the first thread's stack, we're hosed. | |
380 | Give up. */ | |
381 | vg_assert2(sp != 0, "%s", "Cannot allocate main thread's stack."); | |
382 | ||
383 | /* shouldn't be any other threads around yet */ | |
76d6b459 | 384 | vg_assert( VG_(count_living_threads)() == 1 ); |
e2e5d75f | 385 | |
76d6b459 PF |
386 | ML_(call_on_new_stack_0_1)( |
387 | (Addr)sp, /* stack */ | |
388 | 0, /* bogus return address */ | |
389 | run_a_thread_NORETURN, /* fn to call */ | |
390 | (Word)tid /* arg to give it */ | |
e2e5d75f PF |
391 | ); |
392 | ||
393 | /*NOTREACHED*/ | |
394 | vg_assert(0); | |
395 | } | |
396 | ||
76d6b459 | 397 | |
e2e5d75f | 398 | /* Do a fork() */ |
76d6b459 | 399 | SysRes ML_(do_fork) ( ThreadId tid ) |
e2e5d75f PF |
400 | { |
401 | vki_sigset_t fork_saved_mask; | |
402 | vki_sigset_t mask; | |
403 | SysRes res; | |
404 | ||
405 | /* Block all signals during fork, so that we can fix things up in | |
406 | the child without being interrupted. */ | |
407 | VG_(sigfillset)(&mask); | |
408 | VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask); | |
409 | ||
410 | VG_(do_atfork_pre)(tid); | |
411 | ||
76d6b459 | 412 | res = VG_(do_syscall0)( __NR_fork ); |
e2e5d75f PF |
413 | |
414 | if (!sr_isError(res)) { | |
415 | if (sr_Res(res) == 0) { | |
416 | /* child */ | |
417 | VG_(do_atfork_child)(tid); | |
418 | ||
419 | /* restore signal mask */ | |
420 | VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); | |
421 | ||
422 | } else { | |
423 | /* parent */ | |
424 | VG_(do_atfork_parent)(tid); | |
425 | ||
227fa1d5 | 426 | if (VG_(clo_trace_syscalls)) { |
e2e5d75f PF |
427 | VG_(printf)(" clone(fork): process %d created child %lu\n", |
428 | VG_(getpid)(), sr_Res(res)); | |
227fa1d5 | 429 | } |
e2e5d75f PF |
430 | |
431 | /* restore signal mask */ | |
432 | VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); | |
433 | } | |
434 | } | |
435 | ||
436 | return res; | |
437 | } | |
438 | ||
76d6b459 | 439 | static Addr ML_(make_safe_mask) ( const HChar* malloc_message, Addr mask_pointer ) |
e2e5d75f | 440 | { |
76d6b459 PF |
441 | vki_sigset_t* new_mask; |
442 | const vki_sigset_t* old_mask = (vki_sigset_t *)mask_pointer; | |
e2e5d75f PF |
443 | |
444 | if (!ML_(safe_to_deref)(old_mask, sizeof(vki_sigset_t))) { | |
445 | new_mask = (vki_sigset_t*)1; /* Something recognisable to POST() hook. */ | |
446 | } else { | |
76d6b459 | 447 | new_mask = VG_(malloc)(malloc_message, sizeof(vki_sigset_t)); |
e2e5d75f PF |
448 | *new_mask = *old_mask; |
449 | VG_(sanitize_client_sigmask)(new_mask); | |
450 | } | |
451 | ||
452 | return (Addr)new_mask; | |
453 | } | |
454 | ||
76d6b459 | 455 | static void ML_(free_safe_mask) ( Addr mask_pointer ) |
e2e5d75f PF |
456 | { |
457 | if (mask_pointer != 0 && mask_pointer != 1) { | |
76d6b459 | 458 | VG_(free)((vki_sigset_t *) mask_pointer); |
e2e5d75f PF |
459 | } |
460 | } | |
461 | ||
76d6b459 | 462 | |
e2e5d75f PF |
463 | /* --------------------------------------------------------------------- |
464 | PRE/POST wrappers for arch-generic, FreeBSD-specific syscalls | |
465 | ------------------------------------------------------------------ */ | |
466 | ||
467 | // Nb: See the comment above the generic PRE/POST wrappers in | |
468 | // m_syswrap/syswrap-generic.c for notes about how they work. | |
469 | ||
76d6b459 PF |
470 | #define PRE(name) DEFN_PRE_TEMPLATE(freebsd, name) |
471 | #define POST(name) DEFN_POST_TEMPLATE(freebsd, name) | |
e2e5d75f PF |
472 | |
473 | /* On FreeBSD, if any thread calls exit(2), then they are all shut down, pretty | |
474 | * much like linux's exit_group(). | |
475 | */ | |
476 | // SYS_exit 1 | |
477 | // void exit(int status); | |
478 | PRE(sys_exit) | |
479 | { | |
76d6b459 | 480 | ThreadId t; |
e2e5d75f PF |
481 | |
482 | PRINT("exit( %" FMT_REGWORD "u )", ARG1); | |
483 | PRE_REG_READ1(void, "exit", int, status); | |
484 | ||
485 | /* Mark all threads (including this one) to exit. */ | |
486 | for (t = 1; t < VG_N_THREADS; t++) { | |
76d6b459 | 487 | if ( /* not alive */ VG_(threads)[t].status == VgTs_Empty ) { |
e2e5d75f | 488 | continue; |
227fa1d5 | 489 | } |
e2e5d75f | 490 | |
76d6b459 | 491 | //VG_(threads)[t].exitreason = VgSrc_ExitThread; |
e2e5d75f PF |
492 | VG_(threads)[t].os_state.exitcode = ARG1; |
493 | ||
494 | // if (t != tid) | |
495 | // VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */ | |
496 | } | |
497 | ||
76d6b459 | 498 | VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess ); |
e2e5d75f PF |
499 | VG_(reap_threads)(tid); |
500 | VG_(threads)[tid].exitreason = VgSrc_ExitThread; | |
501 | ||
502 | /* We have to claim the syscall already succeeded. */ | |
503 | SET_STATUS_Success(0); | |
504 | } | |
505 | ||
506 | // SYS_fork 2 | |
507 | // pid_t fork(void); | |
508 | PRE(sys_fork) | |
509 | { | |
510 | PRINT("%s", "sys_fork ()"); | |
511 | PRE_REG_READ0(pid_t, "fork"); | |
512 | ||
76d6b459 | 513 | SET_STATUS_from_SysRes( ML_(do_fork)(tid) ); |
e2e5d75f PF |
514 | if (SUCCESS) { |
515 | /* Thread creation was successful; let the child have the chance | |
516 | to run */ | |
517 | *flags |= SfYieldAfter; | |
518 | } | |
519 | } | |
520 | ||
521 | // SYS_read 3 | |
522 | // generic | |
523 | ||
524 | // SYS_write 4 | |
525 | // generic | |
526 | ||
527 | // SYS_open 5 | |
528 | // generic | |
529 | ||
530 | // SYS_close 6 | |
531 | // generic | |
532 | ||
533 | // SYS_wait4 7 | |
534 | // generic | |
535 | ||
536 | // SYS_link 9 | |
537 | // generic | |
538 | ||
539 | // SYS_unlink 10 | |
540 | // generic | |
541 | ||
542 | // SYS_chdir 12 | |
543 | ||
544 | // SYS_fchdir 13 | |
545 | // generic | |
546 | ||
547 | // SYS_freebsd11_mknod 14 | |
548 | // generic | |
549 | ||
550 | // SYS_chmod 15 | |
551 | // generic | |
552 | ||
553 | // SYS_chown 16 | |
554 | // generic | |
555 | ||
556 | // SYS_break 17 | |
557 | // generic | |
558 | ||
559 | // SYS_getpid 20 | |
560 | // generic | |
561 | ||
562 | // SYS_mount 21 | |
563 | // int mount(const char *type, const char *dir, int flags, void *data); | |
564 | PRE(sys_mount) | |
565 | { | |
566 | // Nb: depending on 'flags', the 'type' and 'data' args may be ignored. | |
567 | // We are conservative and check everything, except the memory pointed to | |
568 | // by 'data'. | |
569 | *flags |= SfMayBlock; | |
76d6b459 PF |
570 | PRINT( "sys_mount( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); |
571 | PRE_REG_READ4(int, "mount", | |
572 | const char *, type, char *, dir, int, flags, | |
573 | void *, data); | |
574 | PRE_MEM_RASCIIZ( "mount(type)", ARG1); | |
575 | PRE_MEM_RASCIIZ( "mount(path)", ARG2); | |
e2e5d75f PF |
576 | } |
577 | ||
578 | // SYS_unmount 22 | |
579 | // int unmount(const char *dir, int flags); | |
580 | PRE(sys_unmount) | |
581 | { | |
582 | PRINT("sys_umount( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); | |
76d6b459 PF |
583 | PRE_REG_READ2(int, "unmount", const char *, dir, int, flags); |
584 | PRE_MEM_RASCIIZ( "unmount(path)", ARG1); | |
e2e5d75f PF |
585 | } |
586 | ||
587 | // SYS_setuid 23 | |
588 | // generic | |
589 | ||
590 | // SYS_getuid 24 | |
591 | // generic | |
592 | ||
593 | // SYS_geteuid 25 | |
594 | // generic | |
595 | ||
596 | // SYS_ptrace 26 | |
597 | // int ptrace(int request, pid_t pid, caddr_t addr, int data); | |
598 | PRE(sys_ptrace) | |
599 | { | |
76d6b459 PF |
600 | struct vki_ptrace_io_desc *io_desc; |
601 | PRINT("sys_ptrace ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %" FMT_REGWORD "u)", ARG1, ARG2, ARG3, ARG4); | |
e2e5d75f | 602 | |
76d6b459 | 603 | PRE_REG_READ4(int, "ptrace", int, request, pid_t, pid, caddr_t, addr, int, data); |
e2e5d75f PF |
604 | |
605 | switch (ARG1) { | |
606 | case VKI_PTRACE_TRACEME: | |
e2e5d75f PF |
607 | case VKI_PTRACE_READ_I: |
608 | case VKI_PTRACE_READ_D: | |
e2e5d75f PF |
609 | case VKI_PTRACE_WRITE_I: |
610 | case VKI_PTRACE_WRITE_D: | |
611 | break; | |
612 | ||
613 | case VKI_PTRACE_IO: | |
614 | PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_ptrace_io_desc)); | |
76d6b459 | 615 | io_desc = (struct vki_ptrace_io_desc *)ARG3; |
e2e5d75f PF |
616 | switch (io_desc->piod_op) { |
617 | case VKI_PIOD_READ_D: | |
618 | case VKI_PIOD_READ_I: | |
76d6b459 | 619 | PRE_MEM_WRITE( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len); |
e2e5d75f PF |
620 | break; |
621 | case VKI_PIOD_WRITE_D: | |
622 | case VKI_PIOD_WRITE_I: | |
76d6b459 | 623 | PRE_MEM_READ( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len); |
e2e5d75f PF |
624 | break; |
625 | } | |
626 | break; | |
627 | ||
628 | case VKI_PTRACE_CONTINUE: | |
e2e5d75f | 629 | case VKI_PTRACE_STEP: |
e2e5d75f | 630 | case VKI_PTRACE_KILL: |
e2e5d75f | 631 | case VKI_PTRACE_ATTACH: |
e2e5d75f PF |
632 | case VKI_PTRACE_DETACH: |
633 | break; | |
634 | ||
635 | case VKI_PTRACE_GETREGS: | |
227fa1d5 | 636 | PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); |
e2e5d75f PF |
637 | break; |
638 | ||
639 | case VKI_PTRACE_SETREGS: | |
227fa1d5 | 640 | PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); |
e2e5d75f PF |
641 | break; |
642 | ||
643 | case VKI_PTRACE_GETFPREGS: | |
227fa1d5 | 644 | PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_fpreg)); |
e2e5d75f PF |
645 | break; |
646 | ||
647 | case VKI_PTRACE_SETFPREGS: | |
227fa1d5 | 648 | PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_fpreg)); |
e2e5d75f PF |
649 | break; |
650 | ||
651 | case VKI_PTRACE_GETDBREGS: | |
227fa1d5 | 652 | PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_dbreg)); |
e2e5d75f PF |
653 | break; |
654 | ||
655 | case VKI_PTRACE_SETDBREGS: | |
227fa1d5 | 656 | PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_dbreg)); |
e2e5d75f PF |
657 | break; |
658 | ||
659 | case VKI_PTRACE_LWPINFO: | |
227fa1d5 | 660 | PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_ptrace_lwpinfo)); |
e2e5d75f PF |
661 | break; |
662 | ||
663 | case VKI_PTRACE_GETNUMLWPS: | |
664 | break; | |
665 | ||
666 | case VKI_PTRACE_GETLWPLIST: | |
76d6b459 | 667 | PRE_MEM_WRITE( "ptrace", ARG3, sizeof(vki_lwpid_t) * ARG4); |
e2e5d75f PF |
668 | break; |
669 | ||
670 | case VKI_PTRACE_SETSTEP: | |
e2e5d75f | 671 | case VKI_PTRACE_CLEARSTEP: |
e2e5d75f | 672 | case VKI_PTRACE_SUSPEND: |
e2e5d75f | 673 | case VKI_PTRACE_RESUME: |
e2e5d75f | 674 | case VKI_PTRACE_TO_SCE: |
e2e5d75f | 675 | case VKI_PTRACE_TO_SCX: |
e2e5d75f | 676 | case VKI_PTRACE_SYSCALL: |
e2e5d75f PF |
677 | case VKI_PTRACE_VM_TIMESTAMP: |
678 | break; | |
e2e5d75f | 679 | case VKI_PTRACE_VM_ENTRY: |
76d6b459 | 680 | PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_ptrace_vm_entry)); |
e2e5d75f PF |
681 | break; |
682 | } | |
683 | } | |
684 | ||
685 | POST(sys_ptrace) | |
686 | { | |
76d6b459 | 687 | struct vki_ptrace_io_desc *io_desc; |
e2e5d75f PF |
688 | |
689 | switch (ARG1) { | |
690 | case VKI_PTRACE_TRACEME: | |
e2e5d75f PF |
691 | case VKI_PTRACE_READ_I: |
692 | case VKI_PTRACE_READ_D: | |
e2e5d75f PF |
693 | case VKI_PTRACE_WRITE_I: |
694 | case VKI_PTRACE_WRITE_D: | |
695 | break; | |
696 | ||
697 | case VKI_PTRACE_IO: | |
76d6b459 | 698 | io_desc = (struct vki_ptrace_io_desc *)ARG3; |
e2e5d75f PF |
699 | switch (io_desc->piod_op) { |
700 | case VKI_PIOD_READ_D: | |
701 | case VKI_PIOD_READ_I: | |
227fa1d5 | 702 | if ((Word)RES != -1) { |
e2e5d75f | 703 | POST_MEM_WRITE((UWord)io_desc->piod_addr, io_desc->piod_len); |
227fa1d5 | 704 | } |
e2e5d75f PF |
705 | break; |
706 | case VKI_PIOD_WRITE_D: | |
707 | case VKI_PIOD_WRITE_I: | |
708 | break; | |
709 | } | |
710 | break; | |
711 | ||
712 | case VKI_PTRACE_CONTINUE: | |
e2e5d75f | 713 | case VKI_PTRACE_STEP: |
e2e5d75f | 714 | case VKI_PTRACE_KILL: |
e2e5d75f | 715 | case VKI_PTRACE_ATTACH: |
e2e5d75f PF |
716 | case VKI_PTRACE_DETACH: |
717 | break; | |
718 | ||
719 | case VKI_PTRACE_GETREGS: | |
227fa1d5 | 720 | if ((Word)RES != -1) { |
e2e5d75f | 721 | POST_MEM_WRITE(ARG3, sizeof(struct vki_user_regs_struct)); |
227fa1d5 | 722 | } |
e2e5d75f PF |
723 | break; |
724 | ||
725 | case VKI_PTRACE_SETREGS: | |
726 | break; | |
727 | ||
728 | case VKI_PTRACE_GETFPREGS: | |
227fa1d5 | 729 | if ((Word)RES != -1) { |
e2e5d75f | 730 | POST_MEM_WRITE(ARG3, sizeof(struct vki_fpreg)); |
227fa1d5 | 731 | } |
e2e5d75f PF |
732 | break; |
733 | ||
734 | case VKI_PTRACE_SETFPREGS: | |
735 | break; | |
736 | ||
737 | case VKI_PTRACE_GETDBREGS: | |
227fa1d5 | 738 | if ((Word)RES != -1) { |
e2e5d75f | 739 | POST_MEM_WRITE(ARG3, sizeof(struct vki_dbreg)); |
227fa1d5 | 740 | } |
e2e5d75f PF |
741 | break; |
742 | ||
743 | case VKI_PTRACE_SETDBREGS: | |
744 | break; | |
745 | ||
746 | case VKI_PTRACE_LWPINFO: | |
227fa1d5 | 747 | if ((Word)RES != -1) { |
e2e5d75f | 748 | POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_lwpinfo)); |
227fa1d5 | 749 | } |
e2e5d75f PF |
750 | break; |
751 | ||
752 | case VKI_PTRACE_GETNUMLWPS: | |
753 | break; | |
754 | ||
755 | case VKI_PTRACE_GETLWPLIST: | |
227fa1d5 | 756 | if ((Word)RES != -1) { |
e2e5d75f | 757 | POST_MEM_WRITE(ARG3, sizeof(vki_lwpid_t) * RES); |
227fa1d5 | 758 | } |
e2e5d75f PF |
759 | break; |
760 | ||
761 | case VKI_PTRACE_SETSTEP: | |
e2e5d75f | 762 | case VKI_PTRACE_CLEARSTEP: |
e2e5d75f | 763 | case VKI_PTRACE_SUSPEND: |
e2e5d75f | 764 | case VKI_PTRACE_RESUME: |
e2e5d75f | 765 | case VKI_PTRACE_TO_SCE: |
e2e5d75f | 766 | case VKI_PTRACE_TO_SCX: |
e2e5d75f | 767 | case VKI_PTRACE_SYSCALL: |
e2e5d75f PF |
768 | case VKI_PTRACE_VM_TIMESTAMP: |
769 | break; | |
770 | ||
771 | case VKI_PTRACE_VM_ENTRY: | |
227fa1d5 | 772 | if ((Word)RES != -1) { |
e2e5d75f | 773 | POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_vm_entry)); |
227fa1d5 | 774 | } |
e2e5d75f PF |
775 | break; |
776 | } | |
777 | } | |
778 | ||
779 | // SYS_recvmsg 27 | |
780 | // ssize_t recvmsg(int s, struct msghdr *msg, int flags); | |
781 | PRE(sys_recvmsg) | |
782 | { | |
783 | *flags |= SfMayBlock; | |
76d6b459 PF |
784 | PRINT("sys_recvmsg ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )",SARG1,ARG2,SARG3); |
785 | PRE_REG_READ3(vki_ssize_t, "recvmsg", int, s, struct msghdr *, msg, int, flags); | |
786 | ML_(generic_PRE_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2); | |
e2e5d75f PF |
787 | } |
788 | ||
789 | POST(sys_recvmsg) | |
790 | { | |
791 | ||
76d6b459 | 792 | ML_(generic_POST_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2, RES); |
e2e5d75f PF |
793 | } |
794 | ||
795 | // SYS_sendmsg 28 | |
796 | // ssize_t sendmsg(int s, const struct msghdr *msg, int flags); | |
797 | PRE(sys_sendmsg) | |
798 | { | |
799 | *flags |= SfMayBlock; | |
76d6b459 PF |
800 | PRINT("sys_sendmsg ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
801 | PRE_REG_READ3(ssize_t, "sendmsg", | |
802 | int, s, const struct msghdr *, msg, int, flags); | |
803 | ML_(generic_PRE_sys_sendmsg)(tid, "sendmsg", (struct vki_msghdr *)ARG2); | |
e2e5d75f PF |
804 | } |
805 | ||
806 | // SYS_recvfrom 29 | |
807 | // ssize_t recvfrom(int s, void *buf, size_t len, int flags, | |
76d6b459 | 808 | // struct sockaddr * restrict from, socklen_t * restrict fromlen); |
e2e5d75f PF |
809 | PRE(sys_recvfrom) |
810 | { | |
811 | *flags |= SfMayBlock; | |
76d6b459 PF |
812 | PRINT("sys_recvfrom ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,ARG3,SARG4,ARG5,ARG6); |
813 | PRE_REG_READ6(ssize_t, "recvfrom", | |
814 | int, s, void *, buf, size_t, len, int, flags, | |
815 | struct sockaddr *, from, int *, fromlen); | |
816 | ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); | |
e2e5d75f PF |
817 | } |
818 | ||
819 | POST(sys_recvfrom) | |
820 | { | |
821 | vg_assert(SUCCESS); | |
76d6b459 PF |
822 | ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES), |
823 | ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); | |
e2e5d75f PF |
824 | } |
825 | ||
826 | // SYS_accept 30 | |
827 | // int accept(int s, struct sockaddr * restrict addr, | |
828 | // socklen_t * restrict addrlen); | |
829 | PRE(sys_accept) | |
830 | { | |
831 | *flags |= SfMayBlock; | |
76d6b459 PF |
832 | PRINT("sys_accept ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
833 | PRE_REG_READ3(int, "accept", | |
834 | int, s, struct sockaddr *, addr, int, *addrlen); | |
835 | ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
836 | } |
837 | ||
838 | POST(sys_accept) | |
839 | { | |
840 | SysRes r; | |
841 | vg_assert(SUCCESS); | |
76d6b459 PF |
842 | r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), |
843 | ARG1,ARG2,ARG3); | |
e2e5d75f PF |
844 | SET_STATUS_from_SysRes(r); |
845 | } | |
846 | ||
847 | // SYS_getpeername 31 | |
848 | // int getpeername(int s, struct sockaddr * restrict name, | |
849 | // socklen_t * restrict namelen); | |
850 | PRE(sys_getpeername) | |
851 | { | |
76d6b459 PF |
852 | PRINT("sys_getpeername ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); |
853 | PRE_REG_READ3(int, "getpeername", | |
854 | int, s, struct sockaddr *, name, socklen_t *, namelen); | |
855 | ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
856 | } |
857 | ||
858 | POST(sys_getpeername) | |
859 | { | |
860 | vg_assert(SUCCESS); | |
76d6b459 PF |
861 | ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES), |
862 | ARG1,ARG2,ARG3); | |
e2e5d75f PF |
863 | } |
864 | ||
865 | // SYS_getsockname 32 | |
866 | // int getsockname(int s, struct sockaddr * restrict name, | |
867 | // socklen_t * restrict namelen); | |
868 | PRE(sys_getsockname) | |
869 | { | |
76d6b459 PF |
870 | PRINT("sys_getsockname ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,ARG3); |
871 | PRE_REG_READ3(long, "getsockname", | |
872 | int, s, struct sockaddr *, name, int *, namelen); | |
873 | ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
874 | } |
875 | ||
876 | POST(sys_getsockname) | |
877 | { | |
878 | vg_assert(SUCCESS); | |
76d6b459 PF |
879 | ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES), |
880 | ARG1,ARG2,ARG3); | |
e2e5d75f PF |
881 | } |
882 | ||
883 | // SYS_access 33 | |
884 | // generic | |
885 | ||
886 | // SYS_chflags 34 | |
0fe27992 | 887 | // int chflags(const char *path, unsigned long flags) |
e2e5d75f PF |
888 | PRE(sys_chflags) |
889 | { | |
76d6b459 PF |
890 | PRINT("sys_chflags ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2); |
891 | PRE_REG_READ2(int, "chflags", | |
892 | const char *, path, unsigned long, flags); | |
893 | PRE_MEM_RASCIIZ( "chflags(path)", ARG1 ); | |
e2e5d75f PF |
894 | } |
895 | ||
896 | // SYS_fchflags 35 | |
897 | // int fchflags(int fd, unsigned long flags); | |
898 | PRE(sys_fchflags) | |
899 | { | |
76d6b459 | 900 | PRINT("sys_fchflags ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2); |
e2e5d75f PF |
901 | PRE_REG_READ2(int, "fchflags", int, fd, unsigned long, flags); |
902 | } | |
903 | ||
904 | // SYS_sync 36 | |
905 | // generic | |
906 | ||
907 | // SYS_kill 37 | |
908 | // generic | |
909 | ||
910 | // SYS_getppid 39 | |
911 | // generic | |
912 | ||
913 | // SYS_dup 41 | |
914 | // generic | |
915 | ||
916 | // Pipe on freebsd doesn't have args, and uses dual returns! | |
917 | // SYS_freebsd10_pipe 42 | |
918 | // int pipe(void); | |
76d6b459 PF |
919 | PRE(sys_pipe) |
920 | { | |
921 | PRINT("%s", "sys_pipe ()"); | |
922 | } | |
e2e5d75f PF |
923 | |
924 | POST(sys_pipe) | |
925 | { | |
926 | if (!ML_(fd_allowed)(RES, "pipe", tid, True) || | |
76d6b459 | 927 | !ML_(fd_allowed)(RESHI, "pipe", tid, True)) { |
e2e5d75f PF |
928 | VG_(close)(RES); |
929 | VG_(close)(RESHI); | |
76d6b459 | 930 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f PF |
931 | } else { |
932 | if (VG_(clo_track_fds)) { | |
933 | ML_(record_fd_open_nameless)(tid, RES); | |
934 | ML_(record_fd_open_nameless)(tid, RESHI); | |
935 | } | |
936 | } | |
937 | } | |
938 | ||
939 | // SYS_getegid 43 | |
940 | // generic | |
941 | ||
942 | // SYS_profil 44 | |
943 | // generic | |
944 | ||
945 | // SYS_ktrace 45 | |
946 | // generic | |
947 | ||
948 | // SYS_getgid 47 | |
949 | // generic | |
950 | ||
951 | // SYS_getlogin 49 | |
952 | // syscall.master refers to namelen and namebuf for the argument names | |
953 | // man getlogin has just getlogin(void) but also | |
954 | // int getlogin_r(char *name, int len); | |
955 | // so let's go with those names | |
956 | PRE(sys_getlogin) | |
957 | { | |
76d6b459 PF |
958 | PRINT("sys_getlogin ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); |
959 | PRE_REG_READ2(int, "getlogin", char *, buf, u_int, len); | |
960 | PRE_MEM_WRITE( "getlogin(name)", ARG1, ARG2 ); | |
e2e5d75f PF |
961 | } |
962 | ||
76d6b459 PF |
963 | POST(sys_getlogin) |
964 | { | |
965 | POST_MEM_WRITE(ARG1, ARG2 ); | |
966 | } | |
e2e5d75f PF |
967 | |
968 | // SYS_setlogin 50 | |
969 | // int setlogin(const char *name); | |
970 | PRE(sys_setlogin) | |
971 | { | |
76d6b459 PF |
972 | PRINT("sys_setlogin ( %#" FMT_REGWORD "x )",ARG1); |
973 | PRE_REG_READ1(long, "setlogin", char *, buf); | |
974 | PRE_MEM_RASCIIZ( "setlogin(buf)", ARG1 ); | |
e2e5d75f PF |
975 | } |
976 | ||
977 | // SYS_acct 51 | |
978 | // generic | |
979 | ||
980 | // SYS_sigaltstack 53 | |
981 | // generic | |
982 | ||
983 | // SYS_ioctl 54 | |
984 | // int ioctl(int fd, unsigned long request, ...); | |
985 | PRE(sys_ioctl) | |
986 | { | |
e2e5d75f PF |
987 | *flags |= SfMayBlock; |
988 | // @todo PJF presumably the presence of ARG3 depends on ARG2 | |
76d6b459 PF |
989 | PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); |
990 | PRE_REG_READ3(int, "ioctl", | |
991 | int, fd, unsigned long, request, unsigned long, arg); | |
e2e5d75f | 992 | |
4d810715 PF |
993 | switch (ARG2 /* request */) { |
994 | /* Handle specific ioctls which pass structures which may have pointers to other | |
995 | buffers */ | |
996 | case VKI_FIODGNAME: | |
997 | // #define FIODGNAME _IOW('f', 120, struct fiodgname_arg) /* get dev. name */ | |
998 | // has a regression test | |
999 | if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_fiodgname_arg))) { | |
1000 | struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3; | |
1001 | PRE_FIELD_READ("ioctl(FIODGNAME).len", data->len); | |
1002 | PRE_FIELD_READ("ioctl(FIODGNAME).buf", data->buf); | |
1003 | PRE_MEM_WRITE("ioctl(FIODGNAME).buf", (Addr)data->buf, data->len); | |
1004 | } | |
d0c17b54 | 1005 | break; |
e2e5d75f PF |
1006 | // The block below is from Ryan Stone |
1007 | // https://bitbucket.org/rysto32/valgrind-freebsd/commits/5323c22be9f6c71a00e842c3ddfa1fa8a7feb279 | |
e2e5d75f | 1008 | case VKI_SIOCGIFMEDIA: |
4d810715 PF |
1009 | // #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ |
1010 | // test with "ifconfig -m" | |
1011 | if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifmediareq))) { | |
e2e5d75f PF |
1012 | struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; |
1013 | if (imr->ifm_ulist) { | |
1014 | PRE_MEM_WRITE("ioctl(SIOCGIFMEDIA).ifm_ulist", | |
1015 | (Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int)); | |
1016 | } | |
1017 | } | |
1018 | break; | |
1019 | ||
1020 | case VKI_PCIOCGETCONF: | |
4d810715 PF |
1021 | // #define PCIOCGETCONF _IOWR('p', 5, struct pci_conf_io) |
1022 | // test with "pciconf -l" | |
1023 | if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_pci_conf_io))) { | |
e2e5d75f PF |
1024 | struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; |
1025 | PRE_MEM_READ("ioctl(PCIOCGETCONF).patterns", | |
1026 | (Addr)(pci->patterns), pci->pat_buf_len); | |
1027 | PRE_MEM_WRITE("ioctl(PCIOCGETCONF).matches", | |
1028 | (Addr)(pci->matches), pci->match_buf_len); | |
1029 | } | |
1030 | break; | |
e2e5d75f | 1031 | case VKI_CAMIOCOMMAND: |
4d810715 PF |
1032 | // #define CAMIOCOMMAND _IOWR(CAM_VERSION, 2, union ccb) |
1033 | if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(union vki_ccb))) { | |
1034 | // test with "camcontrol devlist" (as root) | |
1035 | // (many errors at present) | |
e2e5d75f PF |
1036 | union vki_ccb* ccb = (union vki_ccb*)ARG3; |
1037 | if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { | |
4d810715 PF |
1038 | PRE_FIELD_READ("ioctl(CAMIOCOMMAND).cdm.match_buf_len", ccb->cdm.match_buf_len); |
1039 | PRE_FIELD_READ("ioctl(CAMIOCOMMAND).cdm.matches", ccb->cdm.matches); | |
e2e5d75f PF |
1040 | PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_DEV_MATCH).matches", |
1041 | (Addr)(ccb->cdm.matches), ccb->cdm.match_buf_len); | |
1042 | } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { | |
1043 | struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb; | |
1044 | if (scsiio->dxfer_len) { | |
1045 | if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) { | |
1046 | PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr", | |
1047 | (Addr)(scsiio->data_ptr), scsiio->dxfer_len); | |
1048 | } else if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_OUT) { | |
1049 | PRE_MEM_READ("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr", | |
1050 | (Addr)(scsiio->data_ptr), scsiio->dxfer_len); | |
1051 | } | |
1052 | } | |
1053 | } else if (ccb->ccb_h.func_code == VKI_XPT_GDEV_TYPE || | |
1054 | ccb->ccb_h.func_code == VKI_XPT_PATH_INQ || | |
1055 | ccb->ccb_h.func_code == VKI_XPT_GET_TRAN_SETTINGS) { | |
1056 | // do nothing | |
1057 | } else { | |
1058 | VG_(message)(Vg_UserMsg, | |
4d810715 | 1059 | "Warning: unhandled ioctl CAMIOCOMMAND function 0x%x\n", |
e2e5d75f PF |
1060 | ccb->ccb_h.func_code); |
1061 | } | |
1062 | } | |
1063 | break; | |
4d810715 PF |
1064 | case VKI_SIOCGIFSTATUS: |
1065 | // #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ | |
1066 | // test with "ifconfig -a" | |
1067 | if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifstat))) { | |
1068 | struct vki_ifstat* data = (struct vki_ifstat*)(Addr)ARG3; | |
1069 | PRE_MEM_RASCIIZ("ioctl(SIOCGIFSTATUS).ifs_name", (Addr)data->ifs_name); | |
1070 | PRE_MEM_WRITE("ioctl(SIOCGIFSTATUS).ascii", (Addr)data->ascii, sizeof(data->ascii)); | |
1071 | } | |
1072 | break; | |
1073 | default: | |
1074 | ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3); | |
1075 | break; | |
e2e5d75f | 1076 | } |
e2e5d75f PF |
1077 | } |
1078 | ||
1079 | POST(sys_ioctl) | |
1080 | { | |
4d810715 PF |
1081 | switch (ARG2/* request */) { |
1082 | /* Handle specific ioctls which pass structures which may have pointers to other | |
1083 | buffers */ | |
1084 | case VKI_FIODGNAME: | |
1085 | if (ARG3) { | |
d0c17b54 | 1086 | struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3; |
4d810715 PF |
1087 | POST_MEM_WRITE((Addr)data->buf, data->len); |
1088 | } | |
d0c17b54 | 1089 | break; |
4d810715 PF |
1090 | case VKI_SIOCGIFSTATUS: { |
1091 | // #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ | |
1092 | struct vki_ifstat* data = (struct vki_ifstat*)(Addr)ARG3; | |
1093 | POST_MEM_WRITE((Addr)data->ascii, sizeof(data->ascii)); | |
d0c17b54 | 1094 | break; |
227fa1d5 | 1095 | } |
e2e5d75f PF |
1096 | case VKI_SIOCGIFMEDIA: |
1097 | if (ARG3) { | |
1098 | struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; | |
1099 | if (imr->ifm_ulist) { | |
1100 | POST_MEM_WRITE((Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int)); | |
1101 | } | |
1102 | } | |
1103 | break; | |
e2e5d75f PF |
1104 | case VKI_PCIOCGETCONF: |
1105 | if (ARG3) { | |
1106 | struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; | |
1107 | POST_MEM_WRITE((Addr)(pci->matches), pci->num_matches * sizeof(struct vki_pci_conf)); | |
1108 | } | |
1109 | break; | |
1110 | ||
1111 | case VKI_CAMIOCOMMAND: | |
1112 | if (ARG3) { | |
1113 | union vki_ccb* ccb = (union vki_ccb*)ARG3; | |
1114 | if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { | |
1115 | POST_MEM_WRITE((Addr)(ccb->cdm.matches), ccb->cdm.num_matches*sizeof(struct vki_dev_match_result)); | |
1116 | } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { | |
1117 | struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb; | |
1118 | if (scsiio->dxfer_len) { | |
1119 | if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) { | |
1120 | POST_MEM_WRITE((Addr)(scsiio->data_ptr), scsiio->dxfer_len); | |
1121 | } | |
1122 | } | |
1123 | } | |
1124 | } | |
1125 | break; | |
4d810715 PF |
1126 | default: |
1127 | ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3); | |
1128 | break; | |
e2e5d75f | 1129 | } |
e2e5d75f PF |
1130 | } |
1131 | ||
1132 | // SYS_reboot 55 | |
1133 | // int reboot(int howto); | |
1134 | PRE(sys_reboot) | |
1135 | { | |
1136 | PRINT("sys_reboot ( %" FMT_REGWORD "d )", SARG1); | |
1137 | PRE_REG_READ1(int, "reboot", int, howto); | |
1138 | } | |
1139 | ||
1140 | // SYS_revoke 56 | |
1141 | // int revoke(const char *path); | |
1142 | PRE(sys_revoke) | |
1143 | { | |
1144 | PRINT("sys_revoke ( %#" FMT_REGWORD "x(%s) )", ARG1, (char*)ARG1); | |
76d6b459 PF |
1145 | PRE_REG_READ1(long, "revoke", const char *, path); |
1146 | PRE_MEM_RASCIIZ( "revoke(path)", ARG1); | |
e2e5d75f PF |
1147 | } |
1148 | ||
1149 | // SYS_symlink 57 | |
1150 | // generic | |
1151 | ||
76d6b459 | 1152 | static void do_readlink(const HChar* path, HChar *buf, SizeT bufsize, SyscallStatus* status, Bool* curproc_file) |
b1aba911 PF |
1153 | { |
1154 | HChar name[30]; | |
1155 | VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)()); | |
76d6b459 PF |
1156 | if (ML_(safe_to_deref)(path, 1) |
1157 | && (VG_(strcmp)(path, name) == 0 | |
1158 | || VG_(strcmp)(path, "/proc/curproc/file") == 0)) { | |
b1aba911 | 1159 | vg_assert(VG_(resolved_exename)); |
76d6b459 | 1160 | Int len = VG_(snprintf)(buf, bufsize, "%s", VG_(resolved_exename)); |
b1aba911 PF |
1161 | SET_STATUS_Success(len); |
1162 | *curproc_file = True; | |
1163 | } | |
1164 | } | |
1165 | ||
e2e5d75f | 1166 | // SYS_readlink 58 |
76d6b459 | 1167 | // ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsiz); |
b1aba911 PF |
1168 | PRE(sys_readlink) |
1169 | { | |
1170 | FUSE_COMPATIBLE_MAY_BLOCK(); | |
76d6b459 | 1171 | Word saved = SYSNO; |
b1aba911 PF |
1172 | Bool curproc_file = False; |
1173 | ||
1174 | PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", | |
1175 | ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3); | |
76d6b459 PF |
1176 | PRE_REG_READ3(long, "readlink", |
1177 | const char *, path, char *, buf, int, bufsiz); | |
1178 | PRE_MEM_RASCIIZ( "readlink(path)", ARG1 ); | |
1179 | PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 ); | |
b1aba911 | 1180 | |
76d6b459 PF |
1181 | if (VG_(have_slash_proc) == True) |
1182 | { | |
b1aba911 PF |
1183 | /* |
1184 | * Handle the case where readlink is looking at /proc/curproc/file or | |
1185 | * /proc/<pid>/file | |
1186 | */ | |
76d6b459 | 1187 | do_readlink((const HChar *)ARG1, (HChar *)ARG2, (SizeT)ARG3, status, &curproc_file); |
b1aba911 PF |
1188 | } |
1189 | ||
1190 | if (!curproc_file) { | |
1191 | /* Normal case */ | |
76d6b459 | 1192 | SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3)); |
b1aba911 PF |
1193 | } |
1194 | if (SUCCESS && RES > 0) { | |
76d6b459 | 1195 | POST_MEM_WRITE( ARG2, RES ); |
b1aba911 PF |
1196 | } |
1197 | } | |
e2e5d75f PF |
1198 | |
1199 | // SYS_execve 59 | |
1200 | // generic | |
1201 | ||
1202 | // SYS_umask 60 | |
1203 | // generic | |
1204 | ||
1205 | // SYS_chroot 61 | |
1206 | // generic | |
1207 | ||
1208 | // SYS_msync 65 | |
1209 | // generic | |
1210 | ||
1211 | // SYS_vfork 66 | |
1212 | // pid_t vfork(void); | |
1213 | PRE(sys_vfork) | |
1214 | { | |
1215 | PRINT("%s", "sys_vfork ()"); | |
1216 | PRE_REG_READ0(pid_t, "vfork"); | |
1217 | ||
1218 | /* Pretend vfork == fork. Not true, but will have to do. */ | |
76d6b459 | 1219 | SET_STATUS_from_SysRes( ML_(do_fork)(tid) ); |
e2e5d75f PF |
1220 | if (SUCCESS) { |
1221 | /* Thread creation was successful; let the child have the chance | |
1222 | to run */ | |
1223 | *flags |= SfYieldAfter; | |
1224 | } | |
1225 | } | |
1226 | ||
1227 | // SYS_sbrk 69 | |
1228 | // void * sbrk(intptr_t incr); | |
1229 | PRE(sys_sbrk) | |
1230 | { | |
76d6b459 | 1231 | PRINT("sys_sbrk ( %#" FMT_REGWORD "x )",ARG1); |
e2e5d75f PF |
1232 | PRE_REG_READ1(void*, "sbrk", vki_intptr_t, incr); |
1233 | } | |
1234 | ||
1235 | // SYS_freebsd11_vadvise 72 | |
1236 | // @todo maybe | |
1237 | ||
1238 | // SYS_munmap 73 | |
1239 | // generic | |
1240 | ||
1241 | // SYS_mprotect 74 | |
1242 | // generic | |
1243 | ||
1244 | // SYS_madvise 75 | |
1245 | // generic | |
1246 | ||
1247 | // SYS_mincore 78 | |
1248 | // generic | |
1249 | ||
1250 | // SYS_getgroups 79 | |
1251 | // generic | |
1252 | ||
1253 | // SYS_setgroups 80 | |
1254 | // generic | |
1255 | ||
1256 | // SYS_getpgrp 81 | |
1257 | // generic | |
1258 | ||
1259 | // SYS_setpgid 82 | |
1260 | // generic | |
1261 | ||
1262 | // SYS_setitimer 83 | |
1263 | // generic | |
1264 | ||
1265 | // SYS_swapon 85 | |
1266 | // int swapon(const char *special); | |
1267 | PRE(sys_swapon) | |
1268 | { | |
76d6b459 PF |
1269 | PRINT("sys_swapon ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)ARG1); |
1270 | PRE_REG_READ1(int, "swapon", const char*, special ); | |
1271 | PRE_MEM_RASCIIZ( "swapon(special)", ARG1 ); | |
e2e5d75f PF |
1272 | } |
1273 | ||
1274 | // SYS_getitimer 86 | |
1275 | // generic | |
1276 | ||
1277 | // SYS_getdtablesize 89 | |
1278 | // int getdtablesize(void); | |
1279 | PRE(sys_getdtablesize) | |
1280 | { | |
1281 | PRINT("%s", "sys_getdtablesize ( )"); | |
1282 | PRE_REG_READ0(long, "getdtablesize"); | |
1283 | } | |
1284 | ||
1285 | // SYS_dup2 90 | |
1286 | // generic | |
1287 | ||
1288 | // SYS_fcntl 92 | |
1289 | // int fcntl(int fd, int cmd, ...); | |
1290 | PRE(sys_fcntl) | |
1291 | { | |
1292 | switch (ARG2) { | |
1293 | // These ones ignore ARG3. | |
1294 | case VKI_F_GETFD: | |
1295 | case VKI_F_GETFL: | |
1296 | case VKI_F_GETOWN: | |
1297 | case VKI_F_GET_SEALS: | |
1298 | case VKI_F_ISUNIONSTACK: | |
76d6b459 | 1299 | PRINT("sys_fcntl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2); |
e2e5d75f PF |
1300 | PRE_REG_READ2(int, "fcntl", int, fd, int, cmd); |
1301 | break; | |
1302 | ||
1303 | // These ones use ARG3 as "arg". | |
1304 | case VKI_F_DUPFD: | |
1305 | case VKI_F_DUPFD_CLOEXEC: | |
1306 | case VKI_F_SETFD: | |
1307 | case VKI_F_SETFL: | |
1308 | case VKI_F_SETOWN: | |
1309 | case VKI_F_READAHEAD: | |
1310 | case VKI_F_RDAHEAD: | |
1311 | case VKI_F_ADD_SEALS: | |
76d6b459 PF |
1312 | PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2,SARG3); |
1313 | PRE_REG_READ3(int, "fcntl", | |
1314 | int, fd, int, cmd, int, arg); | |
e2e5d75f PF |
1315 | break; |
1316 | ||
1317 | // These ones use ARG3 as "lock" - obsolete. | |
1318 | case VKI_F_OSETLKW: | |
1319 | *flags |= SfMayBlock; | |
1320 | /* FALLTHROUGH */ | |
1321 | case VKI_F_OGETLK: | |
1322 | case VKI_F_OSETLK: | |
76d6b459 PF |
1323 | PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
1324 | PRE_REG_READ3(int, "fcntl", | |
1325 | int, fd, int, cmd, | |
1326 | struct oflock *, lock); | |
e2e5d75f PF |
1327 | break; |
1328 | ||
1329 | // This one uses ARG3 as "oldd" and ARG4 as "newd". | |
1330 | case VKI_F_DUP2FD: | |
1331 | case VKI_F_DUP2FD_CLOEXEC: | |
76d6b459 PF |
1332 | PRINT("sys_fcntl[ARG3=='oldd', ARG4=='newd'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", |
1333 | ARG1,ARG2,ARG3,ARG4); | |
1334 | PRE_REG_READ4(int, "fcntl", | |
1335 | int, fd, int, cmd, | |
1336 | unsigned long, oldd, unsigned long, newd); | |
e2e5d75f PF |
1337 | break; |
1338 | ||
1339 | // These ones use ARG3 as "lock". | |
1340 | case VKI_F_SETLKW: | |
1341 | *flags |= SfMayBlock; | |
1342 | /* FALLTHROUGH */ | |
1343 | case VKI_F_GETLK: | |
1344 | case VKI_F_SETLK: | |
1345 | case VKI_F_SETLK_REMOTE: | |
76d6b459 PF |
1346 | PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
1347 | PRE_REG_READ3(int, "fcntl", | |
1348 | int, fd, int, cmd, | |
1349 | struct flock *, lock); | |
e2e5d75f | 1350 | break; |
6cb8e52c | 1351 | case VKI_F_KINFO: |
76d6b459 PF |
1352 | PRINT("sys_fcntl[ARG3=='kinfo_file'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
1353 | PRE_REG_READ3(int, "fcntl", | |
1354 | int, fd, int, cmd, | |
1355 | struct vki_kinfo_file *, kinfo); | |
6cb8e52c PF |
1356 | if (ARG3) { |
1357 | struct vki_kinfo_file* p_kinfo_file = (struct vki_kinfo_file*)ARG3; | |
76d6b459 | 1358 | PRE_MEM_WRITE("fcntl(ARG3=='kinfo_file)", ARG3, p_kinfo_file->vki_kf_structsize); |
6cb8e52c | 1359 | } |
145fb72d | 1360 | break; |
e2e5d75f PF |
1361 | |
1362 | default: | |
76d6b459 | 1363 | PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1,ARG2,ARG3); |
e2e5d75f PF |
1364 | I_die_here; |
1365 | } | |
1366 | } | |
1367 | ||
1368 | POST(sys_fcntl) | |
1369 | { | |
1370 | vg_assert(SUCCESS); | |
1371 | if (ARG2 == VKI_F_DUPFD) { | |
1372 | if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) { | |
1373 | VG_(close)(RES); | |
76d6b459 | 1374 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f | 1375 | } else { |
227fa1d5 | 1376 | if (VG_(clo_track_fds)) { |
e2e5d75f | 1377 | ML_(record_fd_open_named)(tid, RES); |
227fa1d5 | 1378 | } |
e2e5d75f PF |
1379 | } |
1380 | } else if (ARG2 == VKI_F_DUPFD_CLOEXEC) { | |
1381 | if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) { | |
1382 | VG_(close)(RES); | |
76d6b459 | 1383 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f | 1384 | } else { |
227fa1d5 | 1385 | if (VG_(clo_track_fds)) { |
e2e5d75f | 1386 | ML_(record_fd_open_named)(tid, RES); |
227fa1d5 | 1387 | } |
e2e5d75f PF |
1388 | } |
1389 | } | |
1390 | } | |
1391 | ||
1392 | // SYS_select 93 | |
1393 | // generic | |
1394 | ||
1395 | // SYS_fsync 95 | |
1396 | // generic | |
1397 | ||
1398 | // SYS_setpriority 9 | |
1399 | // generic | |
1400 | ||
1401 | // SYS_socket 97 | |
1402 | // int socket(int domain, int type, int protocol); | |
1403 | PRE(sys_socket) | |
1404 | { | |
76d6b459 | 1405 | PRINT("sys_socket ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2,SARG3); |
e2e5d75f PF |
1406 | PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol); |
1407 | } | |
1408 | ||
1409 | POST(sys_socket) | |
1410 | { | |
1411 | SysRes r; | |
1412 | vg_assert(SUCCESS); | |
1413 | r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES)); | |
1414 | SET_STATUS_from_SysRes(r); | |
1415 | } | |
1416 | ||
1417 | // SYS_connect 98 | |
1418 | // int connect(int s, const struct sockaddr *name, socklen_t namelen); | |
1419 | PRE(sys_connect) | |
1420 | { | |
1421 | *flags |= SfMayBlock; | |
76d6b459 PF |
1422 | PRINT("sys_connect ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
1423 | PRE_REG_READ3(int, "connect", | |
1424 | int, s, const struct sockaddr *, name, int, namelen); | |
1425 | ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
1426 | } |
1427 | ||
1428 | // SYS_getpriority 100 | |
1429 | // generic | |
1430 | ||
1431 | // SYS_bind 104 | |
1432 | // int bind(int s, const struct sockaddr *addr, socklen_t addrlen); | |
1433 | PRE(sys_bind) | |
1434 | { | |
76d6b459 PF |
1435 | PRINT("sys_bind ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
1436 | PRE_REG_READ3(int, "bind", | |
1437 | int, s, struct sockaddr *, addr, int, addrlen); | |
1438 | ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
1439 | } |
1440 | ||
1441 | // SYS_setsockopt 105 | |
1442 | // int setsockopt(int s, int level, int optname, const void *optval, | |
1443 | // socklen_t optlen); | |
1444 | PRE(sys_setsockopt) | |
1445 | { | |
76d6b459 PF |
1446 | PRINT("sys_setsockopt ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",SARG1,SARG2,SARG3,ARG4,ARG5); |
1447 | PRE_REG_READ5(int, "setsockopt", | |
1448 | int, s, int, level, int, optname, | |
1449 | const void *, optval, vki_socklen_t, optlen); | |
1450 | ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); | |
e2e5d75f PF |
1451 | } |
1452 | ||
1453 | // SYS_listen 106 | |
1454 | // int listen(int s, int backlog); | |
1455 | PRE(sys_listen) | |
1456 | { | |
76d6b459 | 1457 | PRINT("sys_listen ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2); |
e2e5d75f PF |
1458 | PRE_REG_READ2(int, "listen", int, s, int, backlog); |
1459 | } | |
1460 | ||
76d6b459 PF |
1461 | //SYS_gettimeofday 116 |
1462 | // generic | |
e2e5d75f PF |
1463 | |
1464 | // SYS_getrusage 117 | |
1465 | // generic | |
1466 | ||
1467 | // SYS_getsockopt 118 | |
1468 | // int getsockopt(int s, int level, int optname, void * restrict optval, | |
1469 | // socklen_t * restrict optlen); | |
1470 | PRE(sys_getsockopt) | |
1471 | { | |
1472 | Addr optval_p = ARG4; | |
1473 | Addr optlen_p = ARG5; | |
76d6b459 PF |
1474 | PRINT("sys_getsockopt ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4,ARG5); |
1475 | PRE_REG_READ5(int, "getsockopt", | |
1476 | int, s, int, level, int, optname, | |
1477 | void *, optval, int, *optlen); | |
e2e5d75f | 1478 | if (optval_p != (Addr)NULL) { |
76d6b459 PF |
1479 | ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p, |
1480 | "getsockopt(optval)", | |
1481 | "getsockopt(optlen)" ); | |
e2e5d75f PF |
1482 | } |
1483 | } | |
1484 | ||
1485 | POST(sys_getsockopt) | |
1486 | { | |
1487 | Addr optval_p = ARG4; | |
1488 | Addr optlen_p = ARG5; | |
1489 | vg_assert(SUCCESS); | |
1490 | if (optval_p != (Addr)NULL) { | |
76d6b459 PF |
1491 | ML_(buf_and_len_post_check) ( tid, VG_(mk_SysRes_Success)(RES), |
1492 | optval_p, optlen_p, | |
1493 | "getsockopt(optlen_out)" ); | |
e2e5d75f PF |
1494 | } |
1495 | } | |
1496 | ||
1497 | // SYS_readv 120 | |
1498 | // generic | |
1499 | ||
1500 | // SYS_writev 121 | |
1501 | // generic | |
1502 | ||
1503 | // SYS_settimeofday 122 | |
1504 | // generic | |
1505 | ||
1506 | // SYS_fchown 123 | |
1507 | // generic | |
1508 | ||
1509 | // SYS_fchmod 124 | |
1510 | // generic | |
1511 | ||
1512 | // SYS_setreuid 126 | |
1513 | // generic | |
1514 | ||
1515 | // SYS_setregid 127 | |
1516 | // generic | |
1517 | ||
1518 | // SYS_rename 128 | |
1519 | // generic | |
1520 | ||
1521 | // SYS_flock 131 | |
1522 | // generic | |
1523 | ||
1524 | // SYS_mkfifo 132 | |
1525 | // int mkfifo(const char *path, mode_t mode); | |
1526 | PRE(sys_mkfifo) | |
1527 | { | |
76d6b459 PF |
1528 | PRINT("sys_mkfifo ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, (char *)ARG1, ARG2, ARG3 ); |
1529 | PRE_REG_READ2(int, "mkfifo", const char *, path, int, mode); | |
1530 | PRE_MEM_RASCIIZ( "mkfifo(path)", ARG1 ); | |
e2e5d75f PF |
1531 | } |
1532 | ||
1533 | // SYS_sendto 133 | |
1534 | // ssize_t sendto(int s, const void *msg, size_t len, int flags, | |
1535 | // const struct sockaddr *to, socklen_t tolen); | |
1536 | PRE(sys_sendto) | |
1537 | { | |
1538 | *flags |= SfMayBlock; | |
76d6b459 PF |
1539 | PRINT("sys_sendto ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); |
1540 | PRE_REG_READ6(ssize_t, "sendto", | |
1541 | int, s, const void *, msg, int, len, | |
1542 | int, flags, | |
1543 | const struct sockaddr *, to, socklen_t, tolen); | |
1544 | ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); | |
e2e5d75f PF |
1545 | } |
1546 | ||
1547 | // SYS_shutdown 134 | |
1548 | // int shutdown(int s, int how); | |
1549 | PRE(sys_shutdown) | |
1550 | { | |
1551 | *flags |= SfMayBlock; | |
76d6b459 | 1552 | PRINT("sys_shutdown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2); |
e2e5d75f PF |
1553 | PRE_REG_READ2(int, "shutdown", int, s, int, how); |
1554 | } | |
1555 | ||
1556 | // SYS_socketpair 135 | |
1557 | // int socketpair(int domain, int type, int protocol, int *sv); | |
1558 | PRE(sys_socketpair) | |
1559 | { | |
76d6b459 PF |
1560 | PRINT("sys_socketpair ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); |
1561 | PRE_REG_READ4(int, "socketpair", | |
1562 | int, domain, int, type, int, protocol, int *, sv); | |
1563 | ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4); | |
e2e5d75f PF |
1564 | } |
1565 | ||
1566 | POST(sys_socketpair) | |
1567 | { | |
1568 | vg_assert(SUCCESS); | |
76d6b459 PF |
1569 | ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES), |
1570 | ARG1,ARG2,ARG3,ARG4); | |
e2e5d75f PF |
1571 | } |
1572 | ||
1573 | // SYS_mkdir 136 | |
1574 | // generic | |
1575 | ||
1576 | // SYS_rmdir 137 | |
1577 | // generic | |
1578 | ||
1579 | // SYS_utimes 138 | |
1580 | // generic | |
1581 | ||
1582 | // SYS_adjtime 140 | |
1583 | // int adjtime(const struct timeval *delta, struct timeval *olddelta); | |
1584 | PRE(sys_adjtime) | |
1585 | { | |
76d6b459 PF |
1586 | PRINT("sys_adjtime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
1587 | PRE_REG_READ2(int, "adjtime", | |
1588 | const struct vki_timeval *, delta, struct vki_timeval *, olddelta); | |
e2e5d75f PF |
1589 | PRE_MEM_READ("adjtime(delta)", ARG1, sizeof(struct vki_timeval)); |
1590 | if (ARG2) { | |
1591 | PRE_MEM_WRITE("adjtime(olddelta)", ARG1, sizeof(struct vki_timeval)); | |
1592 | } | |
1593 | } | |
1594 | ||
1595 | POST(sys_adjtime) | |
1596 | { | |
1597 | if (ARG2) { | |
1598 | POST_MEM_WRITE(ARG1, sizeof(struct vki_timeval)); | |
1599 | } | |
1600 | } | |
1601 | ||
1602 | // SYS_setsid 147 | |
1603 | // generic | |
1604 | ||
1605 | // SYS_quotactl 148 | |
1606 | /* int quotactl(const char *path, int cmd, int id, void *addr); */ | |
1607 | PRE(sys_quotactl) | |
1608 | { | |
76d6b459 | 1609 | PRINT("sys_quotactl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3, ARG4); |
e2e5d75f PF |
1610 | switch (ARG2) { |
1611 | case VKI_Q_QUOTAON: | |
1612 | case VKI_Q_SETQUOTA: | |
1613 | case VKI_Q_SETUSE: | |
1614 | ||
1615 | case VKI_Q_GETQUOTASIZE: | |
76d6b459 PF |
1616 | PRE_REG_READ4(int, "quotactl", |
1617 | const char *, path, int, cmd, int, id, | |
1618 | void *, addr); | |
1619 | PRE_MEM_RASCIIZ( "quotactl(path)", ARG1 ); | |
e2e5d75f PF |
1620 | break; |
1621 | case VKI_Q_GETQUOTA: | |
1622 | if (VG_(tdict).track_pre_reg_read) { | |
76d6b459 | 1623 | \ |
e2e5d75f | 1624 | PRRSN; |
76d6b459 PF |
1625 | PRA1("quotactl",const char*,path); |
1626 | PRA2("quotactl",int,cmd); | |
1627 | PRA4("quotactl",void*,addr); | |
e2e5d75f PF |
1628 | } |
1629 | break; | |
1630 | case VKI_Q_QUOTAOFF: | |
1631 | case VKI_Q_SYNC: | |
76d6b459 PF |
1632 | PRE_REG_READ2(int, "quotactl", |
1633 | const char *, path, int, cmd); | |
e2e5d75f PF |
1634 | break; |
1635 | default: | |
1636 | break; | |
1637 | } | |
1638 | } | |
1639 | ||
1640 | // SYS_nlm_syscall 154 | |
1641 | // syscall.master says ; 154 is initialised by the NLM code, if present. | |
1642 | // @todo | |
1643 | ||
1644 | // SYS_nfssvc 155 | |
1645 | // int nfssvc(int flags, void *argstructp); | |
1646 | // lengthy manpage, at least 3 types of struct that argstructp can point to | |
1647 | // @todo | |
1648 | ||
1649 | // SYS_lgetfh 160 | |
1650 | // int lgetfh(const char *path, fhandle_t *fhp); | |
1651 | PRE(sys_lgetfh) | |
1652 | { | |
1653 | PRINT("sys_lgetfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2); | |
1654 | PRE_REG_READ2(int, "lgetfh", const char*, path, vki_fhandle_t*, fhp); | |
76d6b459 | 1655 | PRE_MEM_RASCIIZ( "lgetfh(path)", ARG1 ); |
e2e5d75f PF |
1656 | PRE_MEM_WRITE("lgetfh(fhp)", ARG2, sizeof(vki_fhandle_t)); |
1657 | } | |
1658 | ||
76d6b459 PF |
1659 | POST(sys_lgetfh) |
1660 | { | |
1661 | POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t)); | |
1662 | } | |
e2e5d75f PF |
1663 | |
1664 | // SYS_getfh 161 | |
1665 | // int getfh(const char *path, fhandle_t *fhp); | |
1666 | PRE(sys_getfh) | |
1667 | { | |
1668 | PRINT("sys_getfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2); | |
1669 | PRE_REG_READ2(int, "getfh", const char*, path, vki_fhandle_t*, fhp); | |
76d6b459 | 1670 | PRE_MEM_RASCIIZ( "getfh(path)", ARG1 ); |
e2e5d75f PF |
1671 | PRE_MEM_WRITE("getfh(fhp)", ARG2, sizeof(vki_fhandle_t)); |
1672 | } | |
1673 | ||
76d6b459 PF |
1674 | POST(sys_getfh) |
1675 | { | |
1676 | POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t)); | |
1677 | } | |
e2e5d75f PF |
1678 | |
1679 | #if (FREEBSD_VERS <= FREEBSD_10) | |
1680 | // 162 | |
1681 | // int getdomainname(char *domainname, int len); | |
1682 | PRE(sys_freebsd4_getdomainname) | |
1683 | { | |
76d6b459 PF |
1684 | PRINT("sys_freebsd4_getdomainname ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); |
1685 | PRE_REG_READ2(int, "getdomainname", | |
1686 | char *, domainname, int, len); | |
1687 | PRE_MEM_WRITE( "getdomainname(domainname)", ARG1, ARG2 ); | |
e2e5d75f PF |
1688 | } |
1689 | ||
1690 | POST(sys_freebsd4_getdomainname) | |
1691 | { | |
1692 | if (ARG1 != 0) { | |
76d6b459 | 1693 | POST_MEM_WRITE( ARG1, ARG2 ); |
e2e5d75f PF |
1694 | } |
1695 | } | |
1696 | ||
1697 | // 163 | |
1698 | // int setdomainname(char *domainname, int len); | |
1699 | PRE(sys_freebsd4_setdomainname) | |
1700 | { | |
76d6b459 PF |
1701 | PRINT("sys_freebsd4_setdomainname ( %#" FMT_REGWORD "x )",ARG1); |
1702 | PRE_REG_READ2(int, "setdomainname", char *, domainname, int, len); | |
1703 | PRE_MEM_RASCIIZ( "setdomainname(domainname)", ARG1 ); | |
e2e5d75f PF |
1704 | } |
1705 | ||
1706 | // 164 | |
1707 | // int uname(struct utsname *name); | |
1708 | PRE(sys_freebsd4_uname) | |
1709 | { | |
1710 | PRINT("sys_freebsd4_uname ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 PF |
1711 | PRE_REG_READ1(int, "uname", struct utsname *, name); |
1712 | PRE_MEM_WRITE( "uname(name)", ARG1, sizeof(struct vki_utsname) ); | |
e2e5d75f PF |
1713 | } |
1714 | ||
1715 | POST(sys_freebsd4_uname) | |
1716 | { | |
1717 | if (ARG1 != 0) { | |
76d6b459 | 1718 | POST_MEM_WRITE( ARG1, sizeof(struct vki_utsname) ); |
e2e5d75f PF |
1719 | } |
1720 | } | |
1721 | #endif | |
1722 | ||
1723 | // SYS_sysarch 165 | |
1724 | // x86/amd64 | |
1725 | ||
1726 | // SYS_rtprio 166 | |
1727 | PRE(sys_rtprio) | |
1728 | { | |
76d6b459 PF |
1729 | PRINT( "sys_rtprio ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3 ); |
1730 | PRE_REG_READ3(int, "rtprio", | |
1731 | int, function, pid_t, pid, struct rtprio *, rtp); | |
e2e5d75f | 1732 | if (ARG1 == VKI_RTP_SET) { |
76d6b459 | 1733 | PRE_MEM_READ( "rtprio(rtp#set)", ARG3, sizeof(struct vki_rtprio)); |
e2e5d75f | 1734 | } else if (ARG1 == VKI_RTP_LOOKUP) { |
76d6b459 | 1735 | PRE_MEM_WRITE( "rtprio(rtp#lookup)", ARG3, sizeof(struct vki_rtprio)); |
e2e5d75f PF |
1736 | } else { |
1737 | /* PHK ?? */ | |
1738 | } | |
1739 | } | |
1740 | ||
1741 | POST(sys_rtprio) | |
1742 | { | |
227fa1d5 | 1743 | if (ARG1 == VKI_RTP_LOOKUP && RES == 0) { |
76d6b459 | 1744 | POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio)); |
227fa1d5 | 1745 | } |
e2e5d75f PF |
1746 | } |
1747 | ||
1748 | // freebsd6_pread 173 FREEBSD_VERS <= 10 | |
1749 | // x86/amd64 | |
1750 | ||
1751 | // freebsd6_pwrite 174 FREEBSD_VERS <= 10 | |
1752 | // x86/amd64 | |
1753 | ||
1754 | // SYS_setfib 175 | |
1755 | // int setfib(int fib); | |
1756 | PRE(sys_setfib) | |
1757 | { | |
1758 | PRINT("sys_setfib ( %" FMT_REGWORD "d )", SARG1); | |
1759 | PRE_REG_READ1(int, "setfib", int, fib); | |
1760 | } | |
1761 | ||
1762 | // SYS_ntp_adjtime 176 | |
1763 | // int ntp_adjtime(struct timex *); | |
1764 | // @todo | |
1765 | ||
1766 | // SYS_setgid 181 | |
1767 | // generic | |
1768 | ||
1769 | // SYS_setegid 182 | |
1770 | // int setegid(gid_t egid); | |
1771 | PRE(sys_setegid) | |
1772 | { | |
1773 | PRINT("sys_setegid ( %" FMT_REGWORD "u )", ARG1); | |
1774 | PRE_REG_READ1(int, "setegid", vki_gid_t, gid); | |
1775 | } | |
1776 | ||
1777 | // SYS_seteuid 183 | |
1778 | // int seteuid(uid_t euid); | |
1779 | PRE(sys_seteuid) | |
1780 | { | |
1781 | PRINT("sys_seteuid ( %" FMT_REGWORD "u )", ARG1); | |
1782 | PRE_REG_READ1(long, "seteuid", vki_uid_t, uid); | |
1783 | } | |
1784 | ||
76d6b459 | 1785 | |
e2e5d75f PF |
1786 | #if (FREEBSD_VERS >= FREEBSD_12) |
1787 | ||
1788 | // SYS_freebsd11_stat 188 | |
1789 | // int stat(char *path, struct freebsd11_stat *sb); | |
1790 | PRE(sys_freebsd11_stat) | |
1791 | { | |
76d6b459 PF |
1792 | PRINT("sys_freebsd11_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
1793 | PRE_REG_READ2(int, "stat", char *, path, struct freebsd11_stat *, sb); | |
1794 | PRE_MEM_RASCIIZ( "stat(path)", ARG1 ); | |
1795 | PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
1796 | } |
1797 | ||
1798 | POST(sys_freebsd11_stat) | |
1799 | { | |
76d6b459 | 1800 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); |
e2e5d75f PF |
1801 | } |
1802 | ||
1803 | // SYS_freebsd11_fstat 189 | |
1804 | // int fstat(int fd, struct stat *sb); | |
1805 | PRE(sys_freebsd11_fstat) | |
1806 | { | |
76d6b459 PF |
1807 | PRINT("sys_freebsd11_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); |
1808 | PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); | |
1809 | PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
1810 | } |
1811 | ||
1812 | POST(sys_freebsd11_fstat) | |
1813 | { | |
76d6b459 | 1814 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); |
e2e5d75f PF |
1815 | } |
1816 | ||
1817 | // SYS_freebsd11_lstat 190 | |
1818 | // int lstat(const char * restrict path, struct stat * restrict sb); | |
1819 | PRE(sys_freebsd11_lstat) | |
1820 | { | |
76d6b459 PF |
1821 | PRINT("sys_freebsd11_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
1822 | PRE_REG_READ2(sb, "lstat", const char *, path, struct freebsd11_stat *, sb); | |
1823 | PRE_MEM_RASCIIZ( "lstat(path)", ARG1 ); | |
1824 | PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
1825 | } |
1826 | ||
1827 | POST(sys_freebsd11_lstat) | |
1828 | { | |
1829 | vg_assert(SUCCESS); | |
1830 | if (RES == 0) { | |
76d6b459 | 1831 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); |
e2e5d75f PF |
1832 | } |
1833 | } | |
1834 | ||
1835 | #else | |
1836 | ||
1837 | PRE(sys_stat) | |
1838 | { | |
76d6b459 PF |
1839 | PRINT("sys_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
1840 | PRE_REG_READ2(int, "stat", char *, path, struct stat *, sb); | |
1841 | PRE_MEM_RASCIIZ( "stat(path)", ARG1 ); | |
1842 | PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
1843 | } | |
1844 | ||
1845 | POST(sys_stat) | |
1846 | { | |
1847 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
1848 | } |
1849 | ||
1850 | ||
1851 | PRE(sys_fstat) | |
1852 | { | |
76d6b459 PF |
1853 | PRINT("sys_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); |
1854 | PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); | |
1855 | PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
1856 | } |
1857 | ||
76d6b459 PF |
1858 | POST(sys_fstat) |
1859 | { | |
1860 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); | |
1861 | } | |
e2e5d75f PF |
1862 | |
1863 | PRE(sys_lstat) | |
1864 | { | |
76d6b459 PF |
1865 | PRINT("sys_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
1866 | PRE_REG_READ2(int, "lstat", const char *, path, struct stat *, sb); | |
1867 | PRE_MEM_RASCIIZ( "lstat(path)", ARG1 ); | |
1868 | PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
1869 | } |
1870 | ||
1871 | POST(sys_lstat) | |
1872 | { | |
1873 | vg_assert(SUCCESS); | |
1874 | if (RES == 0) { | |
76d6b459 | 1875 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); |
e2e5d75f PF |
1876 | } |
1877 | } | |
1878 | ||
1879 | #endif | |
1880 | ||
1881 | // SYS_pathconf 191 | |
1882 | // long pathconf(const char *path, int name); | |
1883 | PRE(sys_pathconf) | |
1884 | { | |
76d6b459 PF |
1885 | PRINT("sys_pathconf ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,(char *)ARG1,ARG2); |
1886 | PRE_REG_READ2(long, "pathconf", char *, path, int, name); | |
1887 | PRE_MEM_RASCIIZ( "pathconf(path)", ARG1 ); | |
e2e5d75f PF |
1888 | } |
1889 | ||
1890 | // SYS_fpathconf 192 | |
1891 | // long fpathconf(int fd, int name); | |
1892 | PRE(sys_fpathconf) | |
1893 | { | |
76d6b459 | 1894 | PRINT("sys_fpathconf ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2); |
e2e5d75f PF |
1895 | PRE_REG_READ2(long, "fpathconf", int, fd, int, name); |
1896 | } | |
1897 | ||
1898 | // SYS_getrlimit 194 | |
1899 | // generic | |
1900 | ||
1901 | // SYS_setrlimit 195 | |
1902 | // generic | |
1903 | ||
76d6b459 | 1904 | |
e2e5d75f PF |
1905 | // SYS_freebsd11_getdirentries 196 |
1906 | // int getdirentries(int fd, char *buf, int nbytes, long *basep); | |
1907 | #if (FREEBSD_VERS >= FREEBSD_12) | |
1908 | PRE(sys_freebsd11_getdirentries) | |
1909 | { | |
1910 | *flags |= SfMayBlock; | |
76d6b459 PF |
1911 | PRINT("sys_freebsd11_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); |
1912 | PRE_REG_READ4(int, "getdirentries", | |
1913 | int, fd, char *, buf, | |
1914 | int, nbytes, | |
1915 | long *, basep); | |
1916 | PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); | |
227fa1d5 | 1917 | if (ARG4) { |
76d6b459 | 1918 | PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); |
227fa1d5 | 1919 | } |
e2e5d75f PF |
1920 | } |
1921 | ||
1922 | POST(sys_freebsd11_getdirentries) | |
1923 | { | |
1924 | vg_assert(SUCCESS); | |
1925 | if (RES > 0) { | |
76d6b459 PF |
1926 | POST_MEM_WRITE( ARG2, RES ); |
1927 | if ( ARG4 != 0 ) { | |
1928 | POST_MEM_WRITE( ARG4, sizeof (long)); | |
227fa1d5 | 1929 | } |
e2e5d75f PF |
1930 | } |
1931 | } | |
1932 | #else | |
1933 | PRE(sys_getdirentries) | |
1934 | { | |
1935 | *flags |= SfMayBlock; | |
76d6b459 PF |
1936 | PRINT("sys_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); |
1937 | PRE_REG_READ4(int, "getdirentries", | |
1938 | int, fd, char *, buf, | |
1939 | int, nbytes, | |
1940 | long *, basep); | |
1941 | PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); | |
e2e5d75f | 1942 | if (ARG4) |
76d6b459 | 1943 | PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); |
e2e5d75f PF |
1944 | } |
1945 | ||
1946 | POST(sys_getdirentries) | |
1947 | { | |
1948 | vg_assert(SUCCESS); | |
1949 | if (RES > 0) { | |
76d6b459 PF |
1950 | POST_MEM_WRITE( ARG2, RES ); |
1951 | if ( ARG4 != 0 ) | |
1952 | POST_MEM_WRITE( ARG4, sizeof (long)); | |
e2e5d75f PF |
1953 | } |
1954 | } | |
1955 | #endif | |
1956 | ||
1957 | // SYS_freebsd6_mmap 197 | |
1958 | // amd64 / x86 | |
1959 | ||
76d6b459 | 1960 | |
e2e5d75f PF |
1961 | // SYS___syscall 198 |
1962 | // special handling | |
1963 | ||
1964 | // freebsd6_lseek 199 FREEBSD_VERS <= 10 | |
1965 | // x86/amd64 | |
1966 | ||
1967 | // freebsd6_truncate 200 FREEBSD_VERS <= 10 | |
1968 | // x86/amd64 | |
1969 | ||
1970 | // freebsd6_ftruncate 201 FREEBSD_VERS <= 10 | |
1971 | // x86/amd64 | |
1972 | ||
9f27d8fb PF |
1973 | static Bool sysctl_kern_ps_strings(SizeT* out, SizeT* outlen) |
1974 | { | |
76d6b459 PF |
1975 | Word tmp = -1; |
1976 | const struct auxv *cauxv; | |
9f27d8fb | 1977 | |
76d6b459 | 1978 | for (cauxv = (struct auxv*)VG_(client_auxv); cauxv->a_type != VKI_AT_NULL; cauxv++) { |
9f27d8fb PF |
1979 | if (cauxv->a_type == VKI_AT_PS_STRINGS) { |
1980 | tmp = (Word)cauxv->u.a_ptr; | |
1981 | ||
76d6b459 | 1982 | *out = tmp; |
9f27d8fb PF |
1983 | *outlen = sizeof(size_t); |
1984 | return True; | |
1985 | } | |
1986 | } | |
1987 | return False; | |
1988 | } | |
1989 | ||
b29a1e1c PF |
1990 | static void sysctl_kern_usrstack(SizeT* out, SizeT* outlen) |
1991 | { | |
76d6b459 | 1992 | *out = VG_(get_usrstack)(); |
b29a1e1c PF |
1993 | *outlen = sizeof(ULong); |
1994 | } | |
1995 | ||
76d6b459 | 1996 | static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len) |
5d387642 | 1997 | { |
76d6b459 | 1998 | const HChar *exe_name = VG_(resolved_exename); |
5d387642 | 1999 | |
840ccb99 PF |
2000 | if (!len) { |
2001 | return False; | |
2002 | } | |
2003 | ||
2004 | if (!out) { | |
2005 | HChar tmp[VKI_PATH_MAX]; | |
2006 | if (!VG_(realpath)(exe_name, tmp)) { | |
2007 | return False; | |
2008 | } | |
2009 | *len = VG_(strlen)(tmp)+1; | |
2010 | return True; | |
2011 | } | |
2012 | ||
a526bbd0 | 2013 | if (!VG_(realpath)(exe_name, out)) { |
5d387642 | 2014 | return False; |
5d387642 PF |
2015 | } |
2016 | ||
76d6b459 | 2017 | *len = VG_(strlen)(out)+1; |
5d387642 | 2018 | return True; |
5d387642 PF |
2019 | } |
2020 | ||
e2e5d75f | 2021 | // SYS___sysctl 202 |
76d6b459 PF |
2022 | /* int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); */ |
2023 | /* ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 */ | |
e2e5d75f PF |
2024 | PRE(sys___sysctl) |
2025 | { | |
76d6b459 | 2026 | PRINT("sys_sysctl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5,ARG6 ); |
e2e5d75f PF |
2027 | |
2028 | int* name = (int*)ARG1; | |
2029 | if (ML_(safe_to_deref)(name, sizeof(int))) { | |
2030 | PRINT("\nmib[0]: "); | |
2031 | if (SARG2 >= 1) { | |
2032 | switch (name[0]) { | |
2033 | case 0: // CTL_UNSPEC | |
2034 | PRINT("unspec"); | |
2035 | break; | |
2036 | case 1: // CTL_KERN | |
2037 | PRINT("kern"); | |
2038 | break; | |
2039 | case 2: // CTL_VM | |
2040 | PRINT("vm"); | |
2041 | break; | |
2042 | case 3: // CTL_VFS | |
2043 | PRINT("vfs"); | |
2044 | break; | |
2045 | case 4: // CTL_NET | |
2046 | PRINT("net"); | |
2047 | break; | |
2048 | case 5: // CTL_DEBUG | |
2049 | PRINT("debug"); | |
2050 | break; | |
2051 | case 6: // CTL_HW | |
2052 | PRINT("hw"); | |
2053 | break; | |
2054 | case 7: // CTL_MACHDEP | |
2055 | PRINT("machdep"); | |
2056 | break; | |
2057 | case 8: // CTL _USER | |
2058 | PRINT("user"); | |
2059 | break; | |
76d6b459 | 2060 | case 9: //CTL_P1003_1B |
e2e5d75f PF |
2061 | PRINT("p1003_b1b"); |
2062 | break; | |
2063 | default: | |
2064 | PRINT("unrecognized (%d)", ((int*)ARG1)[0]); | |
2065 | break; | |
2066 | } | |
2067 | } | |
76d6b459 | 2068 | if (SARG2 >= 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) { |
e2e5d75f PF |
2069 | PRINT(" mib[1]: %d\n", name[1]); |
2070 | } | |
2071 | } | |
2072 | ||
2073 | /* | |
2074 | * Special handling cases | |
2075 | * | |
802f2d21 | 2076 | * 1. kern.usrstack |
e2e5d75f PF |
2077 | * This sysctl returns the address of the bottom of the user stack |
2078 | * (that is the highest user stack address, since the stack grows | |
2079 | * downwards). Without any special handling this would return the | |
2080 | * address of the host userstack. We have created a stack for the | |
2081 | * guest (in aspacemgr) and that is the one that we want the guest | |
2082 | * to see. Aspacemgr is setup in m_main.c with the adresses and sizes | |
2083 | * saved to file static variables in that file, so we call | |
2084 | * VG_(get_usrstack)() to retrieve them from there. | |
2085 | */ | |
76d6b459 | 2086 | if (SARG2 == 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) { |
e2e5d75f | 2087 | if (name[0] == 1 && name[1] == 33) { |
802f2d21 | 2088 | // kern.usrstack |
db0bfcc6 | 2089 | sysctl_kern_usrstack((SizeT*)ARG3, (SizeT*)ARG4); |
e2e5d75f PF |
2090 | SET_STATUS_Success(0); |
2091 | } | |
2092 | } | |
2093 | ||
9f27d8fb PF |
2094 | /* |
2095 | * 2. kern.ps_strings | |
2096 | */ | |
76d6b459 | 2097 | if (SARG2 == 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) { |
9f27d8fb PF |
2098 | if (name[0] == 1 && name[1] == 32) { |
2099 | if (sysctl_kern_ps_strings((SizeT*)ARG3, (SizeT*)ARG4)) { | |
76d6b459 | 2100 | SET_STATUS_Success(0); |
9f27d8fb PF |
2101 | } |
2102 | } | |
2103 | } | |
e2e5d75f | 2104 | |
5d387642 PF |
2105 | /* |
2106 | * 3. kern.proc.pathname | |
2107 | */ | |
76d6b459 | 2108 | if (SARG2 == 4 && ML_(safe_to_deref)(name, 4*sizeof(int))) { |
5d387642 PF |
2109 | if (name[0] == 1 && name[1] == 14 && name[2] == 12) { |
2110 | vki_pid_t pid = (vki_pid_t)name[3]; | |
2111 | if (pid == -1 || pid == VG_(getpid)()) { | |
76d6b459 | 2112 | sysctl_kern_proc_pathname((HChar *)ARG3, (SizeT *)ARG4); |
5d387642 PF |
2113 | SET_STATUS_Success(0); |
2114 | } | |
2115 | } | |
2116 | } | |
2117 | ||
76d6b459 PF |
2118 | PRE_REG_READ6(int, "__sysctl", int *, name, vki_u_int32_t, namelen, void *, oldp, |
2119 | vki_size_t *, oldlenp, void *, newp, vki_size_t, newlen); | |
e2e5d75f PF |
2120 | |
2121 | // read number of ints specified in ARG2 from mem pointed to by ARG1 | |
2122 | PRE_MEM_READ("sysctl(name)", (Addr)ARG1, ARG2 * sizeof(int)); | |
2123 | ||
2124 | // if 'newp' is not NULL can read namelen bytes from that address | |
227fa1d5 | 2125 | if (ARG5 != (UWord)NULL) { |
e2e5d75f | 2126 | PRE_MEM_READ("sysctl(newp)", (Addr)ARG5, ARG6); |
227fa1d5 | 2127 | } |
e2e5d75f PF |
2128 | |
2129 | // there are two scenarios for oldlenp/oldp | |
2130 | // 1. oldval is NULL and oldlenp is non-NULL | |
2131 | // this is a query of oldlenp so oldlenp will be written | |
2132 | // 2. Both are non-NULL | |
2133 | // this is a query of oldp, oldlenp will be read and oldp will | |
2134 | // be written | |
5d387642 PF |
2135 | // |
2136 | // More thoughts on this | |
2137 | // if say oldp is a string buffer | |
2138 | // oldlenp will point to the length of the buffer | |
2139 | // | |
2140 | // but on return does oldlenp also get updated? | |
e2e5d75f PF |
2141 | |
2142 | // is oldlenp is not NULL, can write | |
2143 | if (ARG4 != (UWord)NULL) { | |
2144 | if (ARG3 != (UWord)NULL) { | |
2145 | // case 2 above | |
2146 | PRE_MEM_READ("sysctl(oldlenp)", (Addr)ARG4, sizeof(vki_size_t)); | |
5d387642 | 2147 | PRE_MEM_WRITE("sysctl(oldlenp)", (Addr)ARG4, sizeof(vki_size_t)); |
e2e5d75f | 2148 | if (ML_(safe_to_deref)((void*)(Addr)ARG4, sizeof(vki_size_t))) { |
76d6b459 | 2149 | PRE_MEM_WRITE("sysctl(oldp)", (Addr)ARG3, *(vki_size_t *)ARG4); |
e2e5d75f PF |
2150 | } else { |
2151 | VG_(dmsg)("Warning: Bad oldlenp address %p in sysctl\n", | |
76d6b459 PF |
2152 | (void *)(Addr)ARG4); |
2153 | SET_STATUS_Failure ( VKI_EFAULT ); | |
e2e5d75f PF |
2154 | } |
2155 | } else { | |
2156 | // case 1 above | |
2157 | PRE_MEM_WRITE("sysctl(oldlenp)", (Addr)ARG4, sizeof(vki_size_t)); | |
2158 | } | |
2159 | } | |
2160 | } | |
2161 | ||
2162 | POST(sys___sysctl) | |
2163 | { | |
2164 | if (ARG4 != (UWord)NULL) { | |
2165 | if (ARG3 != (UWord)NULL) { | |
5d387642 | 2166 | POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); |
76d6b459 | 2167 | POST_MEM_WRITE((Addr)ARG3, *(vki_size_t *)ARG4); |
227fa1d5 | 2168 | } else { |
e2e5d75f | 2169 | POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); |
227fa1d5 | 2170 | } |
e2e5d75f PF |
2171 | } |
2172 | } | |
2173 | ||
2174 | // SYS_mlock 203 | |
2175 | // generic | |
2176 | ||
2177 | // SYS_munlock 204 | |
2178 | // generic | |
2179 | ||
2180 | // SYS_undelete 205 | |
2181 | // int undelete(const char *path); | |
2182 | PRE(sys_undelete) | |
2183 | { | |
2184 | *flags |= SfMayBlock; | |
76d6b459 PF |
2185 | PRINT("sys_undelete ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1); |
2186 | PRE_REG_READ1(int, "undelete", const char *, path); | |
2187 | PRE_MEM_RASCIIZ( "undelete(path)", ARG1 ); | |
e2e5d75f PF |
2188 | } |
2189 | ||
2190 | // SYS_futimes 206 | |
2191 | // int futimes(int fd, const struct timeval *times); | |
2192 | PRE(sys_futimes) | |
2193 | { | |
76d6b459 PF |
2194 | PRINT("sys_lutimes ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2); |
2195 | PRE_REG_READ2(long, "futimes", int, fd, struct timeval *, times); | |
227fa1d5 | 2196 | if (ARG2 != 0) { |
76d6b459 | 2197 | PRE_MEM_READ( "futimes(times)", ARG2, sizeof(struct vki_timeval) ); |
227fa1d5 | 2198 | } |
e2e5d75f PF |
2199 | } |
2200 | ||
2201 | // SYS_getpgid 207 | |
2202 | // generic | |
2203 | ||
2204 | // SYS_poll 209 | |
2205 | // generic | |
2206 | ||
2207 | // SYS_freebsd7___semctl 220 | |
2208 | // int semctl(int semid, int semnum, int cmd, ...); | |
2209 | PRE(sys_freebsd7___semctl) | |
2210 | { | |
d6abe92a | 2211 | union vki_semun* semun; |
e2e5d75f | 2212 | switch (ARG3) { |
e2e5d75f PF |
2213 | case VKI_IPC_STAT: |
2214 | case VKI_SEM_STAT: | |
2215 | case VKI_IPC_SET: | |
e2e5d75f PF |
2216 | case VKI_GETALL: |
2217 | case VKI_SETALL: | |
d6abe92a | 2218 | PRINT("sys_freebsd7___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); |
76d6b459 | 2219 | PRE_REG_READ4(int, "semctl", |
d6abe92a PF |
2220 | int, semid, int, semnum, int, cmd, union vki_semun *, arg); |
2221 | PRE_MEM_READ("sys_freebsd7___semctl(arg)", ARG4, sizeof(union vki_semun)); | |
2222 | semun = (union vki_semun*)ARG4; | |
2223 | if (ML_(safe_to_deref)(semun, sizeof(*semun))) { | |
2224 | ARG4 = (RegWord)semun; | |
2225 | ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4); | |
2226 | } | |
e2e5d75f PF |
2227 | break; |
2228 | default: | |
d6abe92a | 2229 | PRINT("sys_freebsd7___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
76d6b459 PF |
2230 | PRE_REG_READ3(long, "semctl", |
2231 | int, semid, int, semnum, int, cmd); | |
e2e5d75f PF |
2232 | break; |
2233 | } | |
e2e5d75f PF |
2234 | } |
2235 | ||
2236 | POST(sys_freebsd7___semctl) | |
2237 | { | |
d6abe92a PF |
2238 | union vki_semun* semun = (union vki_semun*)ARG4; |
2239 | if (ML_(safe_to_deref)(semun, sizeof(*semun))) { | |
2240 | ARG4 = (RegWord)semun; | |
2241 | ML_(generic_POST_sys_semctl)(tid, RES, ARG1,ARG2,ARG3,ARG4); | |
2242 | } | |
e2e5d75f PF |
2243 | } |
2244 | ||
2245 | // SYS_semget 221 | |
2246 | // int semget(key_t key, int nsems, int flag); | |
2247 | PRE(sys_semget) | |
2248 | { | |
76d6b459 | 2249 | PRINT("sys_semget ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
e2e5d75f PF |
2250 | PRE_REG_READ3(int, "semget", vki_key_t, key, int, nsems, int, flag); |
2251 | } | |
2252 | ||
2253 | // SYS_semop 222 | |
2254 | // int semop(int semid, struct sembuf *array, size_t nops); | |
2255 | PRE(sys_semop) | |
2256 | { | |
2257 | *flags |= SfMayBlock; | |
76d6b459 PF |
2258 | PRINT("sys_semop ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
2259 | PRE_REG_READ3(int, "semop", | |
2260 | int, semid, struct sembuf *, array, unsigned, nops); | |
2261 | ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
2262 | } |
2263 | ||
2264 | // SYS_freebsd7_msgctl 224 | |
2265 | // int msgctl(int msqid, int cmd, struct msqid_ds_old *buf); | |
2266 | PRE(sys_freebsd7_msgctl) | |
2267 | { | |
76d6b459 | 2268 | PRINT("sys_freebsd7_msgctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3 ); |
e2e5d75f | 2269 | |
76d6b459 | 2270 | PRE_REG_READ3(int, "msgctl", int, msqid, int, cmd, struct msqid_ds_old *, buf); |
e2e5d75f PF |
2271 | |
2272 | switch (ARG2 /* cmd */) { | |
2273 | case VKI_IPC_STAT: | |
76d6b459 PF |
2274 | PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", |
2275 | ARG3, sizeof(struct vki_msqid_ds_old) ); | |
e2e5d75f PF |
2276 | break; |
2277 | case VKI_IPC_SET: | |
76d6b459 PF |
2278 | PRE_MEM_READ( "msgctl(IPC_SET, buf)", |
2279 | ARG3, sizeof(struct vki_msqid_ds_old) ); | |
e2e5d75f PF |
2280 | break; |
2281 | } | |
2282 | } | |
2283 | ||
2284 | POST(sys_freebsd7_msgctl) | |
2285 | { | |
2286 | switch (ARG2 /* cmd */) { | |
2287 | case VKI_IPC_STAT: | |
76d6b459 | 2288 | POST_MEM_WRITE( ARG3, sizeof(struct vki_msqid_ds_old) ); |
e2e5d75f PF |
2289 | break; |
2290 | } | |
2291 | } | |
2292 | ||
2293 | // SYS_msgget 225 | |
2294 | // int msgget(key_t key, int msgflg); | |
2295 | PRE(sys_msgget) | |
2296 | { | |
76d6b459 | 2297 | PRINT("sys_msgget ( %" FMT_REGWORD"d, %" FMT_REGWORD"d )",SARG1,SARG2); |
e2e5d75f PF |
2298 | PRE_REG_READ2(int, "msgget", key_t, key, int, msgflg); |
2299 | } | |
2300 | ||
2301 | // SYS_msgsnd 226 | |
2302 | // int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); | |
2303 | PRE(sys_msgsnd) | |
2304 | { | |
76d6b459 PF |
2305 | PRINT("sys_msgsnd ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,ARG2,SARG3,SARG4 ); |
2306 | PRE_REG_READ4(int, "msgsnd", int, msqid, struct msgbuf *, msgp, size_t, msgsz, int, msgflg); | |
2307 | struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG2; | |
2308 | PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) ); | |
2309 | PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, ARG3 ); | |
e2e5d75f PF |
2310 | } |
2311 | // SYS_msgrcv 227 | |
76d6b459 | 2312 | // ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg); |
e2e5d75f PF |
2313 | PRE(sys_msgrcv) |
2314 | { | |
2315 | *flags |= SfMayBlock; | |
2316 | ||
76d6b459 PF |
2317 | PRINT("sys_msgrcv ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,ARG2,ARG3,SARG4,SARG5 ); |
2318 | PRE_REG_READ5(ssize_t, "msgrcv", int, msqid, struct msgbuf *, msgp, size_t, msgsz, | |
2319 | long, msgtyp, int, msgflg); | |
2320 | struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG2; | |
2321 | PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) ); | |
2322 | PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, ARG3 ); | |
e2e5d75f PF |
2323 | } |
2324 | ||
2325 | POST(sys_msgrcv) | |
2326 | { | |
76d6b459 PF |
2327 | struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG2; |
2328 | POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) ); | |
2329 | POST_MEM_WRITE( (Addr)&msgp->mtext, RES ); | |
e2e5d75f PF |
2330 | } |
2331 | ||
2332 | // SYS_shmat 228 | |
2333 | // void * shmat(int shmid, const void *addr, int flag); | |
2334 | PRE(sys_shmat) | |
2335 | { | |
2336 | UWord arg2tmp; | |
76d6b459 PF |
2337 | PRINT("sys_shmat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
2338 | PRE_REG_READ3(void *, "shmat", | |
2339 | int, shmid, const void *, addr, int, flag); | |
2340 | arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3); | |
227fa1d5 | 2341 | if (arg2tmp == 0) { |
76d6b459 | 2342 | SET_STATUS_Failure( VKI_EINVAL ); |
227fa1d5 | 2343 | } else { |
e2e5d75f | 2344 | ARG2 = arg2tmp; |
227fa1d5 | 2345 | } |
e2e5d75f PF |
2346 | } |
2347 | ||
76d6b459 PF |
2348 | POST(sys_shmat) |
2349 | { | |
2350 | ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3); | |
2351 | } | |
e2e5d75f PF |
2352 | |
2353 | // SYS_freebsd7_shmctl 229 | |
2354 | // int shmctl(int shmid, int cmd, struct shmid_ds *buf); | |
2355 | PRE(sys_freebsd7_shmctl) | |
2356 | { | |
76d6b459 PF |
2357 | PRINT("sys_freebsd7_shmctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,SARG2,ARG3); |
2358 | PRE_REG_READ3(int, "shmctl", | |
2359 | int, shmid, int, cmd, struct vki_shmid_ds_old *, buf); | |
e2e5d75f PF |
2360 | switch (ARG2 /* cmd */) { |
2361 | case VKI_IPC_STAT: | |
76d6b459 PF |
2362 | PRE_MEM_WRITE( "shmctl7(IPC_STAT, buf)", |
2363 | ARG3, sizeof(struct vki_shmid_ds_old) ); | |
e2e5d75f PF |
2364 | break; |
2365 | case VKI_IPC_SET: | |
76d6b459 PF |
2366 | PRE_MEM_READ( "shmctl7(IPC_SET, buf)", |
2367 | ARG3, sizeof(struct vki_shmid_ds_old) ); | |
e2e5d75f PF |
2368 | break; |
2369 | } | |
2370 | } | |
2371 | ||
2372 | POST(sys_freebsd7_shmctl) | |
2373 | { | |
2374 | if (ARG2 == VKI_IPC_STAT) { | |
76d6b459 | 2375 | POST_MEM_WRITE( ARG3, sizeof(struct vki_shmid_ds_old) ); |
e2e5d75f PF |
2376 | } |
2377 | } | |
2378 | ||
2379 | // SYS_shmdt 230 | |
2380 | // int shmdt(const void *addr); | |
2381 | PRE(sys_shmdt) | |
2382 | { | |
76d6b459 PF |
2383 | PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1); |
2384 | PRE_REG_READ1(int, "shmdt", const void *, addr); | |
227fa1d5 | 2385 | if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1)) { |
76d6b459 | 2386 | SET_STATUS_Failure( VKI_EINVAL ); |
227fa1d5 | 2387 | } |
e2e5d75f PF |
2388 | } |
2389 | ||
76d6b459 PF |
2390 | POST(sys_shmdt) |
2391 | { | |
2392 | ML_(generic_POST_sys_shmdt)(tid, RES,ARG1); | |
2393 | } | |
e2e5d75f PF |
2394 | |
2395 | // SYS_shmget 231 | |
2396 | // int shmget(key_t key, size_t size, int flag); | |
2397 | PRE(sys_shmget) | |
2398 | { | |
76d6b459 | 2399 | PRINT("sys_shmget ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
e2e5d75f PF |
2400 | PRE_REG_READ3(int, "shmget", vki_key_t, key, vki_size_t, size, int, flag); |
2401 | } | |
2402 | ||
76d6b459 | 2403 | |
e2e5d75f PF |
2404 | // SYS_clock_gettime 232 |
2405 | // int clock_gettime(clockid_t clock_id, struct timespec *tp); | |
2406 | PRE(sys_clock_gettime) | |
2407 | { | |
76d6b459 PF |
2408 | PRINT("sys_clock_gettime( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2); |
2409 | PRE_REG_READ2(int, "clock_gettime", | |
2410 | vki_clockid_t, clk_id, struct timespec *, tp); | |
2411 | PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) ); | |
e2e5d75f PF |
2412 | } |
2413 | ||
76d6b459 PF |
2414 | POST(sys_clock_gettime) |
2415 | { | |
2416 | POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) ); | |
2417 | } | |
e2e5d75f PF |
2418 | |
2419 | // SYS_clock_settime 233 | |
2420 | // int clock_settime(clockid_t clock_id, const struct timespec *tp); | |
2421 | PRE(sys_clock_settime) | |
2422 | { | |
76d6b459 PF |
2423 | PRINT("sys_clock_settime( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2); |
2424 | PRE_REG_READ2(int, "clock_settime", | |
2425 | vki_clockid_t, clk_id, const struct timespec *, tp); | |
2426 | PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) ); | |
e2e5d75f PF |
2427 | } |
2428 | ||
2429 | // SYS_clock_getres 234 | |
2430 | // int clock_getres(clockid_t clock_id, struct timespec *tp); | |
2431 | PRE(sys_clock_getres) | |
2432 | { | |
76d6b459 | 2433 | PRINT("sys_clock_getres( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2); |
e2e5d75f PF |
2434 | // Nb: we can't use "RES" as the param name because that's a macro |
2435 | // defined above! | |
76d6b459 PF |
2436 | PRE_REG_READ2(int, "clock_getres", |
2437 | vki_clockid_t, clock_id, struct timespec *, tp); | |
227fa1d5 | 2438 | if (ARG2 != 0) { |
76d6b459 | 2439 | PRE_MEM_WRITE( "clock_getres(tp)", ARG2, sizeof(struct vki_timespec) ); |
227fa1d5 | 2440 | } |
e2e5d75f PF |
2441 | } |
2442 | ||
2443 | POST(sys_clock_getres) | |
2444 | { | |
227fa1d5 | 2445 | if (ARG2 != 0) { |
76d6b459 | 2446 | POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) ); |
227fa1d5 | 2447 | } |
e2e5d75f PF |
2448 | } |
2449 | ||
2450 | // SYS_ktimer_create 235 | |
2451 | // int timer_create(clockid_t clockid, struct sigevent *restrict evp, | |
2452 | // timer_t *restrict timerid); | |
2453 | PRE(sys_timer_create) | |
2454 | { | |
76d6b459 PF |
2455 | PRINT("sys_timer_create( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,ARG2,ARG3); |
2456 | PRE_REG_READ3(int, "timer_create", | |
2457 | vki_clockid_t, clockid, struct sigevent *, evp, | |
2458 | vki_timer_t *, timerid); | |
227fa1d5 | 2459 | if (ARG2 != 0) { |
76d6b459 | 2460 | PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) ); |
227fa1d5 | 2461 | } |
76d6b459 | 2462 | PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) ); |
e2e5d75f PF |
2463 | } |
2464 | ||
76d6b459 PF |
2465 | POST(sys_timer_create) |
2466 | { | |
2467 | POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) ); | |
2468 | } | |
e2e5d75f PF |
2469 | |
2470 | // SYS_ktimer_delete 236 | |
2471 | // int timer_delete(timer_t timerid); | |
2472 | PRE(sys_timer_delete) | |
2473 | { | |
2474 | PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1); | |
2475 | PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid); | |
2476 | } | |
2477 | ||
2478 | // SYS_ktimer_settime 237 | |
2479 | // int timer_settime(timer_t timerid, int flags, | |
2480 | // const struct itimerspec *restrict value, | |
2481 | // struct itimerspec *restrict ovalue); | |
2482 | PRE(sys_timer_settime) | |
2483 | { | |
76d6b459 PF |
2484 | PRINT("sys_timer_settime( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3,ARG4); |
2485 | PRE_REG_READ4(int, "timer_settime", | |
2486 | vki_timer_t, timerid, int, flags, | |
2487 | const struct itimerspec *, value, | |
2488 | struct itimerspec *, ovalue); | |
2489 | PRE_MEM_READ( "timer_settime(value)", ARG3, | |
2490 | sizeof(struct vki_itimerspec) ); | |
227fa1d5 | 2491 | if (ARG4 != 0) { |
76d6b459 PF |
2492 | PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4, |
2493 | sizeof(struct vki_itimerspec) ); | |
227fa1d5 | 2494 | } |
e2e5d75f PF |
2495 | } |
2496 | ||
2497 | POST(sys_timer_settime) | |
2498 | { | |
227fa1d5 | 2499 | if (ARG4 != 0) { |
76d6b459 | 2500 | POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) ); |
227fa1d5 | 2501 | } |
e2e5d75f PF |
2502 | } |
2503 | ||
2504 | // SYS_ktimer_gettime 238 | |
2505 | // int timer_gettime(timer_t timerid, struct itimerspec *value); | |
2506 | PRE(sys_timer_gettime) | |
2507 | { | |
76d6b459 PF |
2508 | PRINT("sys_timer_gettime( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2); |
2509 | PRE_REG_READ2(long, "timer_gettime", | |
2510 | vki_timer_t, timerid, struct itimerspec *, value); | |
2511 | PRE_MEM_WRITE( "timer_gettime(value)", ARG2, | |
2512 | sizeof(struct vki_itimerspec)); | |
e2e5d75f PF |
2513 | } |
2514 | ||
76d6b459 PF |
2515 | POST(sys_timer_gettime) |
2516 | { | |
2517 | POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) ); | |
2518 | } | |
e2e5d75f PF |
2519 | |
2520 | // SYS_ktimer_getoverrun 239 | |
2521 | // int timer_getoverrun(timer_t timerid); | |
2522 | PRE(sys_timer_getoverrun) | |
2523 | { | |
2524 | PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1); | |
2525 | PRE_REG_READ1(int, "timer_getoverrun", vki_timer_t, timerid); | |
2526 | } | |
2527 | ||
2528 | // SYS_nanosleep 240 | |
2529 | // generic | |
2530 | ||
2531 | // SYS_ffclock_getcounter 241 | |
2532 | // int ffclock_getcounter(ffcounter *ffcount); | |
2533 | // @todo | |
2534 | ||
2535 | // SYS_ffclock_setestimate 242 | |
2536 | // int ffclock_setestimate(struct ffclock_estimate *cest); | |
2537 | // @todo | |
2538 | ||
2539 | // SYS_ffclock_getestimate 243 | |
2540 | // int ffclock_getestimate(struct ffclock_estimate *cest); | |
2541 | // @todo | |
2542 | ||
2543 | // SYS_clock_nanosleep 244 | |
2544 | // int clock_nanosleep(clockid_t clock_id, int flags, | |
2545 | // const struct timespec *rqtp, struct timespec *rmtp); | |
2546 | PRE(sys_clock_nanosleep) | |
2547 | { | |
76d6b459 PF |
2548 | *flags |= SfMayBlock|SfPostOnFail; |
2549 | PRINT("sys_clock_nanosleep ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", | |
e2e5d75f | 2550 | SARG1, SARG2, ARG3, ARG4); |
8d8e4a88 | 2551 | PRE_REG_READ4(int, "clock_nanosleep", vki_clockid_t, clock_id, int, flags, |
76d6b459 | 2552 | const struct timespec *, rqtp, struct timespec *, rmtp); |
8d8e4a88 PF |
2553 | PRE_MEM_READ("clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec)); |
2554 | if (ARG4 != 0) { | |
2555 | PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) ); | |
227fa1d5 | 2556 | } |
e2e5d75f PF |
2557 | } |
2558 | ||
2559 | POST(sys_clock_nanosleep) | |
2560 | { | |
8d8e4a88 PF |
2561 | if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR) { |
2562 | POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) ); | |
227fa1d5 | 2563 | } |
e2e5d75f PF |
2564 | } |
2565 | ||
2566 | // SYS_clock_getcpuclockid2 247 | |
f13667b1 PF |
2567 | // x86/amd64 |
2568 | ||
76d6b459 PF |
2569 | POST(sys_clock_getcpuclockid2) |
2570 | { | |
2571 | POST_MEM_WRITE(ARG3, sizeof(vki_clockid_t)); | |
2572 | } | |
2573 | ||
e2e5d75f PF |
2574 | |
2575 | // SYS_ntp_gettime 248 | |
2576 | // int ntp_gettime(struct ntptimeval *); | |
2577 | // @todo | |
2578 | ||
2579 | // SYS_minherit 250 | |
2580 | // int minherit(void *addr, size_t len, int inherit); | |
2581 | PRE(sys_minherit) | |
2582 | { | |
76d6b459 PF |
2583 | PRINT("sys_minherit( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); |
2584 | PRE_REG_READ3(int, "minherit", | |
2585 | void *, addr, vki_size_t, len, int, inherit); | |
227fa1d5 | 2586 | if (ARG2 != 0) { |
76d6b459 | 2587 | PRE_MEM_WRITE( "minherit(addr)", ARG1,ARG2 ); |
227fa1d5 | 2588 | } |
e2e5d75f PF |
2589 | } |
2590 | ||
2591 | POST(sys_minherit) | |
2592 | { | |
227fa1d5 | 2593 | if (ARG2 != 0) { |
76d6b459 | 2594 | POST_MEM_WRITE( ARG1, ARG2 ); |
227fa1d5 | 2595 | } |
e2e5d75f PF |
2596 | } |
2597 | ||
2598 | // SYS_rfork 251 | |
2599 | // x86/amd64 not functional | |
2600 | ||
2601 | // SYS_issetugid 253 | |
2602 | // int issetugid(void); | |
2603 | PRE(sys_issetugid) | |
2604 | { | |
2605 | PRINT("%s", "sys_issetugid ()"); | |
2606 | PRE_REG_READ0(long, "issetugid"); | |
2607 | } | |
2608 | ||
2609 | // SYS_lchown 254 | |
2610 | // generic | |
2611 | ||
a15b387e PF |
2612 | // We must record the iocb for each aio_read() in a table so that when |
2613 | // aio_return() is called we can mark the memory written asynchronously by | |
2614 | // aio_read() as having been written. We don't have to do this for | |
2615 | // aio_write(). See bug 197227 for more details. | |
2616 | static OSet* iocb_table = NULL; | |
2617 | static Bool aio_init_done = False; | |
2618 | ||
2619 | static void aio_init(void) | |
2620 | { | |
2621 | iocb_table = VG_(OSetWord_Create)(VG_(malloc), "syswrap.aio", VG_(free)); | |
2622 | aio_init_done = True; | |
2623 | } | |
2624 | ||
2625 | // and the same thing for vector reads | |
2626 | static OSet* iocbv_table = NULL; | |
2627 | static Bool aiov_init_done = False; | |
2628 | ||
2629 | static void aiov_init(void) | |
2630 | { | |
2631 | iocbv_table = VG_(OSetWord_Create)(VG_(malloc), "syswrap.aiov", VG_(free)); | |
2632 | aiov_init_done = True; | |
2633 | } | |
2634 | ||
2635 | ||
e2e5d75f PF |
2636 | // SYS_aio_read 255 |
2637 | // int aio_read(struct aiocb *iocb); | |
2638 | PRE(sys_aio_read) | |
2639 | { | |
2640 | PRINT("sys_aio_read ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 2641 | PRE_REG_READ1(int, "aio_read", struct vki_aiocb *, iocb); |
e2e5d75f | 2642 | PRE_MEM_READ("aio_read(iocb)", ARG1, sizeof(struct vki_aiocb)); |
76d6b459 PF |
2643 | if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) { |
2644 | struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1; | |
a15b387e PF |
2645 | if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_read", tid, False)) { |
2646 | SET_STATUS_Failure(VKI_EBADF); | |
2647 | } else { | |
2648 | PRE_MEM_WRITE("aio_read(aiocbp->aio_buf)", | |
2649 | (Addr)iocb->aio_buf, iocb->aio_nbytes); | |
2650 | // @todo PJF there is a difference between FreeBSD and | |
2651 | // Darwin here. On Darwin, if aio_buf is NULL the syscall | |
2652 | // will fail, on FreeBSD it doesn't fail. | |
2653 | } | |
2654 | } else { | |
2655 | SET_STATUS_Failure(VKI_EINVAL); | |
e2e5d75f PF |
2656 | } |
2657 | } | |
2658 | ||
2659 | POST(sys_aio_read) | |
2660 | { | |
a15b387e PF |
2661 | struct vki_aiocb* iocb = (struct vki_aiocb*)ARG1; |
2662 | ||
2663 | if (iocb->aio_buf) { | |
2664 | if (!aio_init_done) { | |
2665 | aio_init(); | |
2666 | } | |
2667 | // see also POST(sys_aio_readv) | |
2668 | if (!VG_(OSetWord_Contains)(iocb_table, (UWord)iocb)) { | |
2669 | VG_(OSetWord_Insert)(iocb_table, (UWord)iocb); | |
2670 | } else { | |
60c8821f | 2671 | // @todo PJF this warns without callstack |
a15b387e PF |
2672 | VG_(dmsg)("Warning: Duplicate control block %p in aio_read\n", |
2673 | (void *)(Addr)ARG1); | |
2674 | VG_(dmsg)("Warning: Ensure 'aio_return' is called when 'aio_read' has completed\n"); | |
2675 | } | |
e2e5d75f PF |
2676 | } |
2677 | } | |
2678 | ||
2679 | // SYS_aio_write 256 | |
2680 | // int aio_write(struct aiocb *iocb); | |
2681 | PRE(sys_aio_write) | |
2682 | { | |
2683 | PRINT("sys_aio_write ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 2684 | PRE_REG_READ1(int, "aio_write", struct vki_aiocb *, iocb); |
a15b387e | 2685 | PRE_MEM_READ("aio_write(iocb)", ARG1, sizeof(struct vki_aiocb)); |
76d6b459 PF |
2686 | if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) { |
2687 | struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1; | |
a15b387e PF |
2688 | if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_write", tid, False)) { |
2689 | SET_STATUS_Failure( VKI_EBADF ); | |
2690 | } else { | |
2691 | PRE_MEM_READ("aio_write(iocb->aio_buf)", | |
2692 | (Addr)iocb->aio_buf, iocb->aio_nbytes); | |
2693 | // @todo PJF there is a difference between FreeBSD and | |
2694 | // Darwin here. On Darwin, if aio_buf is NULL the syscall | |
2695 | // will fail, on FreeBSD it doesn't fail. | |
2696 | } | |
2697 | } else { | |
2698 | SET_STATUS_Failure(VKI_EINVAL); | |
e2e5d75f PF |
2699 | } |
2700 | } | |
2701 | ||
2702 | // SYS_lio_listio 257 | |
2703 | // int lio_listio(int mode, struct aiocb * const list[], int nent, | |
2704 | // struct sigevent *sig); | |
2705 | PRE(sys_lio_listio) | |
2706 | { | |
76d6b459 | 2707 | PRINT("sys_lio_listio ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", |
e2e5d75f | 2708 | SARG1, ARG2, SARG3, ARG4); |
76d6b459 PF |
2709 | PRE_REG_READ4(int, "lio_listio", int, mode, struct aiocb * const *, list, int, nent, |
2710 | struct sigevent *,sig); | |
2711 | PRE_MEM_READ("lio_listio(list)", ARG2, ARG3*sizeof(struct vki_aiocb *)); | |
e2e5d75f | 2712 | // loop check elements |
76d6b459 PF |
2713 | if (ML_(safe_to_deref)((struct vki_aiocb **)ARG2, ARG3*sizeof(struct vki_aiocb *))) { |
2714 | struct vki_aiocb** list = (struct vki_aiocb **)ARG2; | |
e2e5d75f PF |
2715 | for (int i = 0; i < (int)ARG3; ++i) { |
2716 | if (list[i]) { | |
76d6b459 | 2717 | PRE_MEM_READ("lio_listio(list[?])", (Addr)list[i], ARG3*sizeof(struct vki_aiocb)); |
e2e5d75f PF |
2718 | } |
2719 | // @todo | |
2720 | // figure out what gets read/written | |
2721 | // when list[i]->aio_lio_opcode == VKI_LIO_READ and | |
2722 | // when list[i]->aio_lio_opcode == VKI_LIO_WRITE | |
76d6b459 | 2723 | //if (ML_(safe_to_deref)(list[i], ARG3*sizeof(struct vki_aiocb))) { |
e2e5d75f PF |
2724 | //} |
2725 | } | |
2726 | } | |
2727 | ||
2728 | if (ARG1 & VKI_LIO_WAIT) { | |
2729 | *flags |= SfMayBlock; | |
2730 | } | |
2731 | ||
2732 | if (ARG4 && (ARG1 == VKI_LIO_NOWAIT)) { | |
2733 | PRE_MEM_READ("lio_listio(sig)", ARG4, sizeof(struct vki_sigevent)); | |
2734 | } | |
2735 | } | |
2736 | ||
2737 | // SYS_freebsd11_getdents 272 | |
2738 | // generic | |
2739 | ||
2740 | // SYS_lchmod 274 | |
2741 | // int lchmod(const char *path, mode_t mode); | |
2742 | PRE(sys_lchmod) | |
2743 | { | |
76d6b459 PF |
2744 | PRINT("sys_lchmod ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1,ARG2); |
2745 | PRE_REG_READ2(int, "lchmod", const char *, path, vki_mode_t, mode); | |
2746 | PRE_MEM_RASCIIZ( "lchmod(path)", ARG1 ); | |
e2e5d75f PF |
2747 | } |
2748 | ||
2749 | // SYS_lutimes 276 | |
2750 | // int lutimes(const char *path, const struct timeval *times); | |
2751 | PRE(sys_lutimes) | |
2752 | { | |
76d6b459 PF |
2753 | PRINT("sys_lutimes ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2); |
2754 | PRE_REG_READ2(int, "lutimes", char *, path, struct timeval *, times); | |
2755 | PRE_MEM_RASCIIZ( "lutimes(path)", ARG1 ); | |
227fa1d5 | 2756 | if (ARG2 != 0) { |
76d6b459 | 2757 | PRE_MEM_READ( "lutimes(times)", ARG2, sizeof(struct vki_timeval) ); |
227fa1d5 | 2758 | } |
e2e5d75f PF |
2759 | } |
2760 | ||
2761 | // SYS_freebsd11_nstat 278 | |
2762 | // @todo, maybe | |
2763 | ||
2764 | // SYS_freebsd11_nfstat 279 | |
2765 | // @todo, maybe | |
2766 | ||
2767 | // SYS_freebsd11_nlstat 280 | |
2768 | // @todo, maybe | |
2769 | ||
2770 | // SYS_preadv 289 | |
2771 | // amd64 / x86 | |
2772 | ||
2773 | // SYS_pwritev 290 | |
2774 | // amd64 / x86 | |
2775 | ||
2776 | // SYS_fhopen 298 | |
2777 | // int fhopen(const fhandle_t *fhp, int flags); | |
2778 | PRE(sys_fhopen) | |
2779 | { | |
76d6b459 PF |
2780 | PRINT("sys_open ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); |
2781 | PRE_REG_READ2(int, "fhopen", | |
2782 | struct fhandle_t *, fhp, int, flags); | |
2783 | PRE_MEM_READ( "fhopen(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
e2e5d75f PF |
2784 | |
2785 | /* Otherwise handle normally */ | |
2786 | *flags |= SfMayBlock; | |
2787 | } | |
2788 | ||
2789 | POST(sys_fhopen) | |
2790 | { | |
2791 | vg_assert(SUCCESS); | |
2792 | if (!ML_(fd_allowed)(RES, "fhopen", tid, True)) { | |
2793 | VG_(close)(RES); | |
76d6b459 | 2794 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f | 2795 | } else { |
227fa1d5 | 2796 | if (VG_(clo_track_fds)) { |
e2e5d75f | 2797 | ML_(record_fd_open_nameless)(tid, RES); |
227fa1d5 | 2798 | } |
e2e5d75f PF |
2799 | } |
2800 | } | |
2801 | ||
2802 | // SYS_freebsd11_fhstat 299 | |
2803 | // int fhstat(const fhandle_t *fhp, struct stat *sb); | |
2804 | #if (FREEBSD_VERS >= FREEBSD_12) | |
2805 | PRE(sys_freebsd11_fhstat) | |
2806 | { | |
76d6b459 PF |
2807 | PRINT("sys_freebsd11_fhstat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
2808 | PRE_REG_READ2(int, "fhstat", struct fhandle *, fhp, struct freebd11_stat *, sb); | |
2809 | PRE_MEM_READ( "fhstat(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
2810 | PRE_MEM_WRITE( "fhstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
2811 | } |
2812 | ||
2813 | POST(sys_freebsd11_fhstat) | |
2814 | { | |
76d6b459 | 2815 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); |
e2e5d75f PF |
2816 | } |
2817 | #else | |
2818 | PRE(sys_fhstat) | |
2819 | { | |
76d6b459 PF |
2820 | PRINT("sys_fhstat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
2821 | PRE_REG_READ2(int, "fhstat", struct fhandle *, fhp, struct stat *, sb); | |
2822 | PRE_MEM_READ( "fhstat(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
2823 | PRE_MEM_WRITE( "fhstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
2824 | } |
2825 | ||
76d6b459 PF |
2826 | POST(sys_fhstat) |
2827 | { | |
2828 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); | |
2829 | } | |
e2e5d75f PF |
2830 | |
2831 | #endif | |
2832 | ||
2833 | // SYS_modnext 300 | |
2834 | // int modnext(int modid); | |
2835 | PRE(sys_modnext) | |
2836 | { | |
76d6b459 | 2837 | PRINT("sys_modnext ( %" FMT_REGWORD "d )",SARG1); |
e2e5d75f PF |
2838 | PRE_REG_READ1(int, "modnext", int, modid); |
2839 | } | |
2840 | ||
2841 | // SYS_modstat 301 | |
2842 | // int modstat(int modid, struct module_stat *stat); | |
2843 | PRE(sys_modstat) | |
2844 | { | |
76d6b459 PF |
2845 | PRINT("sys_modstat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2); |
2846 | PRE_REG_READ2(int, "modstat", int, modid, struct module_stat *, buf); | |
2847 | PRE_MEM_WRITE( "modstat(stat)", ARG2, sizeof(struct vki_module_stat) ); | |
e2e5d75f PF |
2848 | } |
2849 | ||
76d6b459 PF |
2850 | POST(sys_modstat) |
2851 | { | |
2852 | POST_MEM_WRITE( ARG2, sizeof(struct vki_module_stat) ); | |
2853 | } | |
e2e5d75f PF |
2854 | |
2855 | // SYS_modfnext 302 | |
2856 | // int modfnext(int modid); | |
2857 | PRE(sys_modfnext) | |
2858 | { | |
76d6b459 | 2859 | PRINT("sys_modfnext ( %" FMT_REGWORD "d )",SARG1); |
e2e5d75f PF |
2860 | PRE_REG_READ1(int, "modfnext", int, modid); |
2861 | } | |
2862 | ||
2863 | // SYS_modfind 303 | |
2864 | // int modfind(const char *modname); | |
2865 | PRE(sys_modfind) | |
2866 | { | |
76d6b459 PF |
2867 | PRINT("sys_modfind ( %#" FMT_REGWORD "x )",ARG1); |
2868 | PRE_REG_READ1(long, "modfind", char *, modname); | |
2869 | PRE_MEM_RASCIIZ( "modfind(modname)", ARG1 ); | |
e2e5d75f PF |
2870 | } |
2871 | ||
2872 | // SYS_kldload 304 | |
2873 | // int kldload(const char *file); | |
2874 | PRE(sys_kldload) | |
2875 | { | |
76d6b459 PF |
2876 | PRINT("sys_kldload ( %#" FMT_REGWORD "x(%s) )", ARG1, (char *)ARG1); |
2877 | PRE_REG_READ1(int, "kldload", const char *, "file"); | |
2878 | PRE_MEM_RASCIIZ( "kldload(file)", ARG1 ); | |
e2e5d75f PF |
2879 | } |
2880 | ||
2881 | // SYS_kldunload 305 | |
2882 | // int kldunload(int fileid); | |
2883 | PRE(sys_kldunload) | |
2884 | { | |
2885 | PRINT("sys_kldunload ( %" FMT_REGWORD "u )", ARG1); | |
2886 | PRE_REG_READ1(int, "kldunload", int, "fileid"); | |
2887 | } | |
2888 | ||
2889 | // SYS_kldfind 306 | |
2890 | // int kldfind(const char *file); | |
2891 | PRE(sys_kldfind) | |
2892 | { | |
76d6b459 PF |
2893 | PRINT("sys_kldfind ( %#" FMT_REGWORD "x(%s) )", ARG1, (char *)ARG1); |
2894 | PRE_REG_READ1(int, "kldfind", const char *, file); | |
2895 | PRE_MEM_RASCIIZ( "kldfind(file)", ARG1 ); | |
e2e5d75f PF |
2896 | } |
2897 | ||
2898 | // SYS_kldnext 307 | |
2899 | // int kldnext(int fileid); | |
2900 | PRE(sys_kldnext) | |
2901 | { | |
2902 | PRINT("sys_kldnext ( %" FMT_REGWORD "u )", ARG1); | |
2903 | PRE_REG_READ1(int, "kldnext", int, fileid); | |
2904 | } | |
2905 | ||
2906 | // SYS_kldstat 308 | |
2907 | // int kldstat(int fileid, struct kld_file_stat *stat); | |
2908 | PRE(sys_kldstat) | |
2909 | { | |
2910 | PRINT("sys_kldstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); | |
2911 | PRE_REG_READ2(int, "kldstat", int, fileid, struct kld_file_stat*, stat); | |
2912 | PRE_MEM_WRITE("kldstat(stat)", ARG2, sizeof(struct vki_kld_file_stat)); | |
2913 | } | |
2914 | ||
76d6b459 PF |
2915 | POST(sys_kldstat) |
2916 | { | |
2917 | POST_MEM_WRITE(ARG2, sizeof(struct vki_kld_file_stat)); | |
2918 | } | |
e2e5d75f PF |
2919 | |
2920 | // SYS_kldfirstmod 309 | |
2921 | // int kldfirstmod(int fileid); | |
2922 | PRE(sys_kldfirstmod) | |
2923 | { | |
2924 | PRINT("sys_kldfirstmod ( %" FMT_REGWORD "u )", ARG1); | |
2925 | PRE_REG_READ1(int, "kldfirstmod", int, fileid); | |
2926 | } | |
2927 | ||
2928 | // SYS_setresuid 311 | |
2929 | // int setresuid(uid_t *ruid, uid_t *euid, uid_t *suid); | |
2930 | PRE(sys_setresuid) | |
2931 | { | |
76d6b459 PF |
2932 | PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); |
2933 | PRE_REG_READ3(int, "setresuid", | |
2934 | vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid); | |
e2e5d75f PF |
2935 | } |
2936 | ||
2937 | // SYS_setresgid 312 | |
2938 | // int setresgid(gid_t rgid, gid_t egid, gid_t sgid); | |
2939 | PRE(sys_setresgid) | |
2940 | { | |
76d6b459 PF |
2941 | PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); |
2942 | PRE_REG_READ3(int, "setresgid", | |
2943 | vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid); | |
e2e5d75f PF |
2944 | } |
2945 | ||
2946 | // SYS_aio_return 314 | |
2947 | // ssize_t aio_return(struct aiocb *iocb); | |
2948 | PRE(sys_aio_return) | |
2949 | { | |
2950 | PRINT("sys_aio_return ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 2951 | PRE_REG_READ1(ssize_t, "aio_return", struct aiocb *, iocb); |
e2e5d75f | 2952 | PRE_MEM_READ("aio_return(iocb)", ARG1, sizeof(struct vki_aiocb)); |
a15b387e PF |
2953 | // read or write? |
2954 | if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) { | |
2955 | SET_STATUS_from_SysRes(VG_(do_syscall1)(SYSNO, ARG1)); | |
1aa76801 | 2956 | /*if (SUCCESS)*/ { |
a15b387e PF |
2957 | struct vki_aiocb* iocb = (struct vki_aiocb*)ARG1; |
2958 | if (!aio_init_done) { | |
2959 | aio_init(); | |
2960 | } | |
2961 | if (!aiov_init_done) { | |
2962 | aiov_init(); | |
2963 | } | |
1aa76801 PF |
2964 | |
2965 | // for the happy path aio_return is supposed to be called | |
2966 | // after the io has completed (as determined by aio_error, | |
2967 | // aio_suspend or a signal). | |
2968 | ||
2969 | // but what if the aio_read failed or hasn't completed? | |
2970 | // we want to remove the read from the iocb(v)_table | |
2971 | // in the case of aio_read failing | |
2972 | // if the read hasn't completed that's a user error | |
2973 | // I don't know if it's possible to recover in that case | |
2974 | // the iocb will have been removed from the table | |
2975 | // so if the user does recover and call aio_return | |
2976 | // 'correctly' we won't do the POST_MEM_WRITE | |
2977 | // I don't think that we can tell apart a failing | |
2978 | // read from a premature aio_return | |
2979 | ||
a15b387e | 2980 | // check if it was a plain read |
1aa76801 | 2981 | if (VG_(OSetWord_Remove)(iocb_table, (UWord)iocb) && SUCCESS) { |
a15b387e PF |
2982 | POST_MEM_WRITE((Addr)iocb->aio_buf, iocb->aio_nbytes); |
2983 | } | |
1aa76801 | 2984 | if (VG_(OSetWord_Remove)(iocbv_table, (UWord)iocb) && SUCCESS) { |
a15b387e PF |
2985 | SizeT vec_count = (SizeT)iocb->aio_nbytes; |
2986 | // assume that id the read succeded p_iovec is accessible | |
2987 | volatile struct vki_iovec* p_iovec = (volatile struct vki_iovec*)iocb->aio_buf; | |
2988 | for (SizeT i = 0U; i < vec_count; ++i) { | |
2989 | POST_MEM_WRITE((Addr)p_iovec[i].iov_base, p_iovec[i].iov_len); | |
2990 | } | |
2991 | } | |
2992 | } | |
2993 | } else { | |
2994 | SET_STATUS_Failure(VKI_EINVAL); | |
2995 | } | |
e2e5d75f PF |
2996 | } |
2997 | ||
2998 | // SYS_aio_suspend 315 | |
2999 | // int aio_suspend(const struct aiocb *const iocbs[], int niocb, | |
3000 | // const struct timespec *timeout); | |
3001 | PRE(sys_aio_suspend) | |
3002 | { | |
3003 | PRINT("sys_aio_suspend ( %#" FMT_REGWORD "x )", ARG1); | |
a15b387e PF |
3004 | PRE_REG_READ3(int, "aio_suspend", const struct aiocb * const *, iocbs, int, nbiocb, const struct timespec*, timeout); |
3005 | if (ARG2 > 0) { | |
3006 | PRE_MEM_READ("aio_suspend(iocbs)", ARG1, ARG2*sizeof(struct vki_aiocb*)); | |
3007 | } | |
3008 | if (ARG3) { | |
3009 | PRE_MEM_READ("aio_suspend(timeout)", ARG3, sizeof(struct vki_timespec)); | |
3010 | } | |
e2e5d75f PF |
3011 | } |
3012 | ||
3013 | // SYS_aio_cancel 316 | |
3014 | // int aio_cancel(int fildes, struct aiocb *iocb); | |
3015 | PRE(sys_aio_cancel) | |
3016 | { | |
76d6b459 | 3017 | PRINT("sys_aio_cancel ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); |
a15b387e | 3018 | PRE_REG_READ2(int, "aio_cancel", int, fildes, struct iocb *, iocb); |
e2e5d75f PF |
3019 | if (ARG2) { |
3020 | PRE_MEM_READ("aio_cancel(iocb)", ARG2, sizeof(struct vki_aiocb)); | |
3021 | } | |
a15b387e PF |
3022 | if (!ML_(fd_allowed)(ARG1, "aio_cancel", tid, False)) { |
3023 | SET_STATUS_Failure(VKI_EBADF); | |
3024 | } else { | |
3025 | if (ARG2) { | |
3026 | if (ML_(safe_to_deref)((struct vki_aiocb *)ARG2, sizeof(struct vki_aiocb))) { | |
c1cc1f4b | 3027 | // struct vki_aiocb *iocb = (struct vki_aiocb *)ARG2; |
a15b387e PF |
3028 | // @todo PJF cancel only requests associated with |
3029 | // fildes and iocb | |
c1cc1f4b PF |
3030 | // Do I need to remove pending reads from iocb(v)_table |
3031 | // or should the user always call aio_return even after | |
3032 | // aio_cancel? | |
a15b387e PF |
3033 | } else { |
3034 | SET_STATUS_Failure(VKI_EINVAL); | |
3035 | } | |
3036 | } else { | |
c1cc1f4b | 3037 | // @todo PJF cancel all requests associated with fildes, see above |
a15b387e PF |
3038 | } |
3039 | } | |
e2e5d75f PF |
3040 | } |
3041 | ||
3042 | // SYS_aio_error 317 | |
3043 | // int aio_error(const struct aiocb *iocb); | |
3044 | PRE(sys_aio_error) | |
3045 | { | |
3046 | PRINT("sys_aio_error ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 3047 | PRE_REG_READ1(ssize_t, "aio_error", struct aiocb *, iocb); |
e2e5d75f | 3048 | PRE_MEM_READ("aio_error(iocb)", ARG1, sizeof(struct vki_aiocb)); |
e557fc2e PF |
3049 | if (ARG1) { |
3050 | if (!ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) { | |
3051 | SET_STATUS_Failure(VKI_EINVAL); | |
3052 | } | |
3053 | } | |
e2e5d75f PF |
3054 | } |
3055 | ||
3056 | // SYS_yield 321 | |
3057 | int yield(void); | |
3058 | PRE(sys_yield) | |
3059 | { | |
3060 | *flags |= SfMayBlock; | |
3061 | PRINT("%s", "yield()"); | |
3062 | PRE_REG_READ0(long, "yield"); | |
3063 | } | |
3064 | ||
3065 | // SYS_mlockall 324 | |
3066 | // generic | |
3067 | ||
3068 | // SYS_munlockall 325 | |
3069 | // int munlockall(void); | |
3070 | PRE(sys_munlockall) | |
3071 | { | |
3072 | *flags |= SfMayBlock; | |
3073 | PRINT("%s", "sys_munlockall ( )"); | |
3074 | PRE_REG_READ0(int, "munlockall"); | |
3075 | } | |
3076 | ||
3077 | // SYS___getcwd 326 | |
3078 | // int __getcwd(char *buf, size_t buflen); | |
3079 | PRE(sys___getcwd) | |
3080 | { | |
76d6b459 PF |
3081 | PRINT("sys___getcwd ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2); |
3082 | PRE_REG_READ2(long, "__getcwd", char *, buf, unsigned int, buflen); | |
3083 | PRE_MEM_WRITE( "__getcwd(buf)", ARG1, ARG2 ); | |
e2e5d75f PF |
3084 | } |
3085 | ||
3086 | POST(sys___getcwd) | |
3087 | { | |
3088 | vg_assert(SUCCESS); | |
3089 | if (RES == 0) { | |
3090 | // QQQ it is unclear if this is legal or not, but the | |
3091 | // QQQ kernel just wrote it there... | |
3092 | // QQQ Why oh why didn't phk return the length from __getcwd()? | |
76d6b459 PF |
3093 | UInt len = VG_(strlen) ( (char *)ARG1 ) + 1; |
3094 | POST_MEM_WRITE( ARG1, len ); | |
e2e5d75f PF |
3095 | } |
3096 | } | |
3097 | ||
76d6b459 PF |
3098 | //SYS_sched_setparam 327 |
3099 | // int sched_setparam(pid_t pid, const struct sched_param *param); | |
e2e5d75f PF |
3100 | PRE(sys_sched_setparam) |
3101 | { | |
76d6b459 PF |
3102 | PRINT("sched_setparam ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2 ); |
3103 | PRE_REG_READ2(int, "sched_setparam", | |
3104 | vki_pid_t, pid, struct sched_param *, param); | |
3105 | PRE_MEM_READ( "sched_setparam(param)", ARG2, sizeof(struct vki_sched_param) ); | |
e2e5d75f PF |
3106 | } |
3107 | ||
3108 | POST(sys_sched_setparam) | |
3109 | { | |
76d6b459 | 3110 | POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) ); |
e2e5d75f PF |
3111 | } |
3112 | ||
3113 | // SYS_sched_getparam 328 | |
3114 | // int sched_getparam(pid_t pid, struct sched_param *param); | |
3115 | PRE(sys_sched_getparam) | |
3116 | { | |
76d6b459 PF |
3117 | PRINT("sched_getparam ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2 ); |
3118 | PRE_REG_READ2(int, "sched_getparam", | |
3119 | vki_pid_t, pid, struct sched_param *, param); | |
3120 | PRE_MEM_WRITE( "sched_getparam(param)", ARG2, sizeof(struct vki_sched_param) ); | |
e2e5d75f PF |
3121 | } |
3122 | ||
3123 | POST(sys_sched_getparam) | |
3124 | { | |
76d6b459 | 3125 | POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) ); |
e2e5d75f PF |
3126 | } |
3127 | ||
3128 | // SYS_sched_setscheduler 329 | |
3129 | // int sched_setscheduler(pid_t pid, int policy, | |
3130 | // const struct sched_param *param); | |
3131 | PRE(sys_sched_setscheduler) | |
3132 | { | |
76d6b459 PF |
3133 | PRINT("sys_sched_setscheduler ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3); |
3134 | PRE_REG_READ3(int, "sched_setscheduler", | |
3135 | vki_pid_t, pid, int, policy, struct sched_param *, param); | |
227fa1d5 | 3136 | if (ARG3 != 0) { |
76d6b459 PF |
3137 | PRE_MEM_READ("sched_setscheduler(param)", |
3138 | ARG3, sizeof(struct vki_sched_param)); | |
227fa1d5 | 3139 | } |
e2e5d75f PF |
3140 | } |
3141 | ||
3142 | // SYS_sched_getscheduler 330 | |
3143 | // int sched_getscheduler(pid_t pid); | |
3144 | PRE(sys_sched_getscheduler) | |
3145 | { | |
3146 | PRINT("sys_sched_getscheduler ( %" FMT_REGWORD "d )", SARG1); | |
3147 | PRE_REG_READ1(int, "sched_getscheduler", vki_pid_t, pid); | |
3148 | } | |
3149 | ||
3150 | // SYS_sched_yield 331 | |
3151 | // int sched_yield(void); | |
3152 | PRE(sys_sched_yield) | |
3153 | { | |
3154 | *flags |= SfMayBlock; | |
3155 | PRINT("sched_yield()"); | |
3156 | PRE_REG_READ0(int, "sched_yield"); | |
3157 | } | |
3158 | ||
3159 | // SYS_sched_get_priority_max 332 | |
3160 | // int sched_get_priority_max(int policy); | |
3161 | PRE(sys_sched_get_priority_max) | |
3162 | { | |
3163 | PRINT("sched_get_priority_max ( %" FMT_REGWORD "u )", ARG1); | |
3164 | PRE_REG_READ1(long, "sched_get_priority_max", int, policy); | |
3165 | } | |
3166 | ||
3167 | // SYS_sched_get_priority_min 333 | |
3168 | // int sched_get_priority_min(int policy); | |
3169 | PRE(sys_sched_get_priority_min) | |
3170 | { | |
3171 | PRINT("sched_get_priority_min ( %" FMT_REGWORD "u )", ARG1); | |
3172 | PRE_REG_READ1(long, "sched_get_priority_min", int, policy); | |
3173 | } | |
3174 | ||
3175 | // SYS_sched_rr_get_interval 334 | |
3176 | // int sched_rr_get_interval(pid_t pid, struct timespec *interval); | |
3177 | PRE(sys_sched_rr_get_interval) | |
3178 | { | |
76d6b459 PF |
3179 | PRINT("sys_sched_rr_get_interval ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); |
3180 | PRE_REG_READ2(int, "sched_rr_get_interval", vki_pid_t, pid, struct vki_timespec *,interval); | |
3181 | PRE_MEM_WRITE("sys_sched_rr_get_interval(interval)", ARG2, sizeof(struct vki_timespec)); | |
e2e5d75f PF |
3182 | } |
3183 | ||
3184 | POST(sys_sched_rr_get_interval) | |
3185 | { | |
3186 | POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec)); | |
3187 | } | |
3188 | ||
3189 | // SYS_utrace 335 | |
3190 | // int utrace(const void *addr, size_t len); | |
3191 | PRE(sys_utrace) | |
3192 | { | |
3193 | PRINT("sys_utrace ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); | |
76d6b459 | 3194 | PRE_REG_READ2(int, "utrace", const void *, addr, vki_size_t, len); |
2343e5b8 | 3195 | PRE_MEM_READ( "utrace(addr)", ARG1, ARG2 ); |
e2e5d75f PF |
3196 | } |
3197 | ||
3198 | // SYS_kldsym 337 | |
3199 | // int kldsym(int fileid, int cmd, void *data); | |
3200 | PRE(sys_kldsym) | |
3201 | { | |
76d6b459 | 3202 | PRINT("sys_kldsym ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3 ); |
e2e5d75f | 3203 | PRE_REG_READ3(int, "kldsym", int, fileid, int, cmd, void*, data); |
76d6b459 PF |
3204 | PRE_MEM_READ( "kldsym(data)", ARG3, sizeof(struct vki_kld_sym_lookup) ); |
3205 | struct vki_kld_sym_lookup *kslp = (struct vki_kld_sym_lookup *)ARG3; | |
e2e5d75f | 3206 | if (ML_(safe_to_deref)(kslp, sizeof(struct vki_kld_sym_lookup))) { |
76d6b459 | 3207 | PRE_MEM_RASCIIZ( "kldsym(data.symname)", (Addr)kslp->symname ); |
e2e5d75f PF |
3208 | } |
3209 | } | |
3210 | ||
3211 | POST(sys_kldsym) | |
3212 | { | |
76d6b459 PF |
3213 | struct vki_kld_sym_lookup *kslp = (struct vki_kld_sym_lookup *)ARG3; |
3214 | POST_MEM_WRITE( (Addr)&kslp->symvalue, sizeof(kslp->symvalue) ); | |
3215 | POST_MEM_WRITE( (Addr)&kslp->symsize, sizeof(kslp->symsize) ); | |
e2e5d75f PF |
3216 | } |
3217 | ||
3218 | // SYS_jail 338 | |
3219 | // int jail(struct jail *jail); | |
3220 | PRE(sys_jail) | |
3221 | { | |
3222 | PRINT("sys_jail ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 PF |
3223 | PRE_REG_READ1(int, "jail", struct jail *, jail); |
3224 | PRE_MEM_READ( "jail(jail)", ARG1, sizeof(struct vki_jail) ); | |
e2e5d75f PF |
3225 | } |
3226 | ||
3227 | // SYS_nnpfs_syscall 338 | |
3228 | // @todo | |
3229 | ||
3230 | // SYS_sigprocmask 340 | |
3231 | // int sigprocmask(int how, const sigset_t * restrict set, | |
3232 | // sigset_t * restrict oset); | |
3233 | PRE(sys_sigprocmask) | |
3234 | { | |
76d6b459 PF |
3235 | PRINT("sys_sigprocmask ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); |
3236 | PRE_REG_READ3(int, "sigprocmask", | |
3237 | int, how, vki_sigset_t *, set, vki_sigset_t *, oset); | |
227fa1d5 | 3238 | if (ARG2 != 0) { |
76d6b459 | 3239 | PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t)); |
227fa1d5 PF |
3240 | } |
3241 | if (ARG3 != 0) { | |
76d6b459 | 3242 | PRE_MEM_WRITE( "sigprocmask(oset)", ARG3, sizeof(vki_sigset_t)); |
227fa1d5 | 3243 | } |
e2e5d75f | 3244 | |
76d6b459 PF |
3245 | if (ARG2 != 0 && |
3246 | !ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) { | |
e2e5d75f | 3247 | VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n", |
76d6b459 PF |
3248 | (void *)(Addr)ARG2); |
3249 | SET_STATUS_Failure ( VKI_EFAULT ); | |
e2e5d75f | 3250 | } else if (ARG3 != 0 && |
76d6b459 | 3251 | !ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) { |
e2e5d75f | 3252 | VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n", |
76d6b459 PF |
3253 | (void *)(Addr)ARG3); |
3254 | SET_STATUS_Failure ( VKI_EFAULT ); | |
e2e5d75f | 3255 | } else { |
76d6b459 PF |
3256 | SET_STATUS_from_SysRes(VG_(do_sys_sigprocmask)(tid, ARG1 /*how*/, |
3257 | (vki_sigset_t*)(Addr)ARG2, | |
3258 | (vki_sigset_t*)(Addr)ARG3)); | |
e2e5d75f PF |
3259 | } |
3260 | ||
227fa1d5 | 3261 | if (SUCCESS) { |
e2e5d75f | 3262 | *flags |= SfPollAfter; |
227fa1d5 | 3263 | } |
e2e5d75f PF |
3264 | } |
3265 | ||
3266 | POST(sys_sigprocmask) | |
3267 | { | |
3268 | vg_assert(SUCCESS); | |
227fa1d5 | 3269 | if (RES == 0 && ARG3 != 0) { |
76d6b459 | 3270 | POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t)); |
227fa1d5 | 3271 | } |
e2e5d75f PF |
3272 | } |
3273 | ||
3274 | // SYS_sigsuspend 341 | |
3275 | // int sigsuspend(const sigset_t *sigmask); | |
3276 | PRE(sys_sigsuspend) | |
3277 | { | |
3278 | *flags |= SfMayBlock; | |
76d6b459 PF |
3279 | PRINT("sys_sigsuspend ( %#" FMT_REGWORD "x )", ARG1 ); |
3280 | PRE_REG_READ1(int, "sigsuspend", const vki_sigset_t *, sigmask); | |
3281 | PRE_MEM_READ( "sigsuspend(sigmask)", ARG1, sizeof(vki_sigset_t) ); | |
e2e5d75f PF |
3282 | if (ARG1) { |
3283 | ARG1 = ML_(make_safe_mask)("syswrap.sigsuspend.1", (Addr)ARG1); | |
3284 | } | |
3285 | } | |
3286 | ||
76d6b459 PF |
3287 | POST(sys_sigsuspend) |
3288 | { | |
3289 | ML_(free_safe_mask) ( (Addr)ARG1 ); | |
3290 | } | |
e2e5d75f PF |
3291 | |
3292 | // SYS_sigpending 343 | |
3293 | // int sigpending(sigset_t *set); | |
3294 | PRE(sys_sigpending) | |
3295 | { | |
76d6b459 PF |
3296 | PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 ); |
3297 | PRE_REG_READ1(int, "sigpending", vki_sigset_t *, set); | |
3298 | PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_sigset_t)); | |
3299 | } | |
3300 | ||
3301 | POST(sys_sigpending) | |
3302 | { | |
3303 | POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ; | |
e2e5d75f PF |
3304 | } |
3305 | ||
3306 | ||
3307 | // SYS_sigtimedwait 345 | |
3308 | // int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, | |
3309 | // const struct timespec *restrict timeout); | |
3310 | PRE(sys_sigtimedwait) | |
3311 | { | |
3312 | *flags |= SfMayBlock; | |
76d6b459 PF |
3313 | PRINT("sys_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", |
3314 | ARG1,ARG2,ARG3); | |
3315 | PRE_REG_READ3(int, "sigtimedwait", | |
3316 | const vki_sigset_t *, set, vki_siginfo_t *, info, | |
3317 | const struct timespec *, timeout); | |
227fa1d5 | 3318 | if (ARG1 != 0) { |
76d6b459 | 3319 | PRE_MEM_READ( "sigtimedwait(set)", ARG1, sizeof(vki_sigset_t)); |
227fa1d5 PF |
3320 | } |
3321 | if (ARG2 != 0) { | |
76d6b459 | 3322 | PRE_MEM_WRITE( "sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) ); |
227fa1d5 PF |
3323 | } |
3324 | if (ARG3 != 0) { | |
76d6b459 PF |
3325 | PRE_MEM_READ( "sigtimedwait(timeout)", |
3326 | ARG3, sizeof(struct vki_timespec) ); | |
227fa1d5 | 3327 | } |
e2e5d75f PF |
3328 | } |
3329 | ||
3330 | POST(sys_sigtimedwait) | |
3331 | { | |
227fa1d5 | 3332 | if (ARG2 != 0) { |
76d6b459 | 3333 | POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) ); |
227fa1d5 | 3334 | } |
e2e5d75f PF |
3335 | } |
3336 | ||
3337 | // SYS_sigwaitinfo 346 | |
3338 | // int sigwaitinfo(const sigset_t * restrict set, siginfo_t * restrict info); | |
3339 | PRE(sys_sigwaitinfo) | |
3340 | { | |
3341 | *flags |= SfMayBlock; | |
76d6b459 PF |
3342 | PRINT("sys_sigwaitinfo ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", |
3343 | ARG1,ARG2); | |
3344 | PRE_REG_READ2(int, "sigwaitinfo", | |
3345 | const vki_sigset_t *, set, vki_siginfo_t *, info); | |
227fa1d5 | 3346 | if (ARG1 != 0) { |
76d6b459 | 3347 | PRE_MEM_READ( "sigwaitinfo(set)", ARG1, sizeof(vki_sigset_t)); |
227fa1d5 PF |
3348 | } |
3349 | if (ARG2 != 0) { | |
76d6b459 | 3350 | PRE_MEM_WRITE( "sigwaitinfo(info)", ARG2, sizeof(vki_siginfo_t) ); |
227fa1d5 | 3351 | } |
e2e5d75f PF |
3352 | } |
3353 | ||
3354 | POST(sys_sigwaitinfo) | |
3355 | { | |
227fa1d5 | 3356 | if (ARG2 != 0) { |
76d6b459 | 3357 | POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) ); |
227fa1d5 | 3358 | } |
e2e5d75f PF |
3359 | } |
3360 | ||
3361 | // SYS___acl_get_file 347 | |
3362 | // int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); | |
3363 | PRE(sys___acl_get_file) | |
3364 | { | |
76d6b459 PF |
3365 | PRINT("sys___acl_get_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3); |
3366 | PRE_REG_READ3(int, "acl_get_file", | |
3367 | const char *, path, int, type, struct vki_acl *, aclp); | |
e2e5d75f | 3368 | PRE_MEM_RASCIIZ("acl_get_file(path", ARG1); |
76d6b459 | 3369 | PRE_MEM_WRITE( "acl_get_file(aclp)", ARG3, sizeof(struct vki_acl) ); |
e2e5d75f PF |
3370 | } |
3371 | ||
3372 | POST(sys___acl_get_file) | |
3373 | { | |
3374 | vg_assert(SUCCESS); | |
3375 | if (RES == 0) { | |
76d6b459 | 3376 | POST_MEM_WRITE( ARG3, sizeof(struct vki_acl) ); |
e2e5d75f PF |
3377 | } |
3378 | } | |
3379 | ||
3380 | // SYS___acl_set_file 348 | |
3381 | // int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); | |
3382 | PRE(sys___acl_set_file) | |
3383 | { | |
76d6b459 PF |
3384 | PRINT("sys___acl_set_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3); |
3385 | PRE_REG_READ3(int, "acl_set_file", | |
3386 | const char *, path, int, type, struct vki_acl *, aclp); | |
e2e5d75f | 3387 | PRE_MEM_RASCIIZ("acl_set_file(path", ARG1); |
76d6b459 | 3388 | PRE_MEM_READ("acl_set_file(aclp)", ARG3, sizeof(struct vki_acl) ); |
e2e5d75f PF |
3389 | } |
3390 | ||
3391 | // SYS___acl_get_fd 349 | |
3392 | // int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); | |
3393 | PRE(sys___acl_get_fd) | |
3394 | { | |
76d6b459 PF |
3395 | PRINT("sys___acl_get_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
3396 | PRE_REG_READ3(int, "acl_get_fd", | |
3397 | int, fd, int, type, struct vki_acl *, aclp); | |
3398 | PRE_MEM_WRITE( "acl_get_file(aclp)", ARG3, sizeof(struct vki_acl) ); | |
e2e5d75f PF |
3399 | } |
3400 | ||
3401 | POST(sys___acl_get_fd) | |
3402 | { | |
3403 | vg_assert(SUCCESS); | |
3404 | if (RES == 0) { | |
76d6b459 | 3405 | POST_MEM_WRITE( ARG3, sizeof(struct vki_acl) ); |
e2e5d75f PF |
3406 | } |
3407 | } | |
3408 | ||
3409 | // SYS___acl_set_fd 350 | |
3410 | // int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); | |
3411 | PRE(sys___acl_set_fd) | |
3412 | { | |
76d6b459 PF |
3413 | PRINT("sys___acl_set_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
3414 | PRE_REG_READ3(int, "acl_set_fd", | |
3415 | int, filedes, int, type, struct vki_acl *, aclp); | |
3416 | PRE_MEM_READ( "acl_get_file(aclp)", ARG3, sizeof(struct vki_acl) ); | |
e2e5d75f PF |
3417 | } |
3418 | ||
3419 | // SYS___acl_delete_file 351 | |
3420 | // int __acl_delete_file(const char *path, acl_type_t type); | |
3421 | PRE(sys___acl_delete_file) | |
3422 | { | |
76d6b459 | 3423 | PRINT("sys___acl_delete_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1,ARG2); |
e2e5d75f | 3424 | PRE_MEM_RASCIIZ("acl_set_file(path", ARG1); |
76d6b459 PF |
3425 | PRE_REG_READ2(int, "acl_delete_file", |
3426 | const char *, path, int, type); | |
e2e5d75f PF |
3427 | } |
3428 | // SYS___acl_delete_fd 352 | |
3429 | // int __acl_delete_fd(int filedes, acl_type_t type); | |
3430 | PRE(sys___acl_delete_fd) | |
3431 | { | |
76d6b459 PF |
3432 | PRINT("sys___acl_delete_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2); |
3433 | PRE_REG_READ2(int, "acl_delete_fd", | |
3434 | int, filedes, int, acltype); | |
e2e5d75f PF |
3435 | } |
3436 | ||
3437 | // SYS___acl_aclcheck_file 353 | |
3438 | // int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); | |
3439 | PRE(sys___acl_aclcheck_file) | |
3440 | { | |
76d6b459 PF |
3441 | PRINT("sys___acl_aclcheck_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3); |
3442 | PRE_REG_READ3(int, "acl_aclcheck_file", | |
3443 | const char *, path, int, type, struct vki_acl *, aclp); | |
e2e5d75f | 3444 | PRE_MEM_RASCIIZ("acl_set_file(path", ARG1); |
76d6b459 | 3445 | PRE_MEM_READ( "acl_aclcheck_file(aclp)", ARG3, sizeof(struct vki_acl) ); |
e2e5d75f PF |
3446 | } |
3447 | ||
3448 | // SYS___acl_aclcheck_fd 354 | |
3449 | // int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); | |
3450 | PRE(sys___acl_aclcheck_fd) | |
3451 | { | |
76d6b459 PF |
3452 | PRINT("sys___acl_aclcheck_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
3453 | PRE_REG_READ3(int, "acl_aclcheck_fd", | |
3454 | int, fd, int, type, struct vki_acl *, aclp); | |
3455 | PRE_MEM_READ( "acl_aclcheck_fd(aclp)", ARG3, sizeof(struct vki_acl) ); | |
e2e5d75f PF |
3456 | } |
3457 | ||
3458 | // SYS_extattrctl 355 | |
3459 | // no manpage? | |
76d6b459 | 3460 | // syscalls.master: int extattrctl(_In_z_ const char *path, int cmd, _In_z_opt_ const char *filename, int attrnamespace, _In_z_ const char *attrname); |
e2e5d75f PF |
3461 | PRE(sys_extattrctl) |
3462 | { | |
76d6b459 PF |
3463 | PRINT("sys_extattrctl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3,SARG4,ARG5); |
3464 | PRE_REG_READ5(ssize_t, "extattrctl", | |
3465 | const char *, path, int, cmd, const char *, filename, int, attrnamespace, const char *, attrname); | |
e2e5d75f PF |
3466 | PRE_MEM_RASCIIZ("extattrctl(path)", ARG1); |
3467 | PRE_MEM_RASCIIZ("extattrctl(filename)", ARG3); | |
3468 | PRE_MEM_RASCIIZ("extattrctl(attrname)", ARG5); | |
3469 | } | |
3470 | ||
3471 | // SYS_extattr_set_file 356 | |
3472 | // ssize_t extattr_set_file(const char *path, int attrnamespace, | |
76d6b459 | 3473 | // const char *attrname, const void *data, size_t nbytes); |
e2e5d75f PF |
3474 | PRE(sys_extattr_set_file) |
3475 | { | |
76d6b459 PF |
3476 | PRINT("sys_extattr_set_file ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5); |
3477 | PRE_REG_READ5(ssize_t, "extattr_set_file", | |
3478 | const char *, path, int, attrnamespace, const char *, attrname, const void *, data, size_t, nbytes); | |
e2e5d75f PF |
3479 | PRE_MEM_RASCIIZ("extattr_set_file(path)", ARG1); |
3480 | PRE_MEM_RASCIIZ("extattr_set_file(attrname)", ARG3); | |
3481 | PRE_MEM_READ("extattr_set_file(data)", ARG4, ARG5); | |
3482 | } | |
3483 | ||
3484 | // SYS_extattr_get_file 357 | |
3485 | // ssize_t extattr_get_file(const char *path, int attrnamespace, | |
3486 | // const char *attrname, void *data, size_t nbytes); | |
3487 | PRE(sys_extattr_get_file) | |
3488 | { | |
76d6b459 PF |
3489 | PRINT("sys_extattr_get_file ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5); |
3490 | PRE_REG_READ5(ssize_t, "extattr_get_file", | |
3491 | const char *, path, int, attrnamespace, const char *, attrname, void *, data, size_t, nbytes); | |
e2e5d75f PF |
3492 | PRE_MEM_RASCIIZ("extattr_get_file(path)", ARG1); |
3493 | PRE_MEM_RASCIIZ("extattr_get_file(attrname)", ARG3); | |
3494 | if (ARG4) { | |
3495 | PRE_MEM_WRITE("extattr_get_file(data)", ARG4, ARG5); | |
3496 | } | |
3497 | } | |
3498 | ||
3499 | POST(sys_extattr_get_file) | |
3500 | { | |
3501 | if (ARG4) { | |
3502 | POST_MEM_WRITE(ARG4, ARG5); | |
3503 | } | |
3504 | } | |
3505 | ||
3506 | // SYS_extattr_delete_file 358 | |
3507 | // int extattr_delete_file(const char *path, int attrnamespace, | |
3508 | // const char *attrname); | |
3509 | PRE(sys_extattr_delete_file) | |
3510 | { | |
76d6b459 PF |
3511 | PRINT("sys_extattr_delete_file ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3); |
3512 | PRE_REG_READ3(ssize_t, "extattr_delete_file", | |
3513 | const char *, path, int, attrnamespace, const char *, attrname); | |
e2e5d75f PF |
3514 | PRE_MEM_RASCIIZ("extattr_delete_file(path)", ARG1); |
3515 | PRE_MEM_RASCIIZ("extattr_delete_file(attrname)", ARG3); | |
3516 | } | |
3517 | ||
3518 | // SYS_aio_waitcomplete 359 | |
3519 | // ssize_t aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout); | |
3520 | PRE(sys_aio_waitcomplete) | |
3521 | { | |
3522 | *flags |= SfMayBlock; | |
76d6b459 PF |
3523 | PRINT("sys_aio_waitcomplete ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2); |
3524 | PRE_REG_READ2(ssize_t, "aio_waitcomplete", struct aiocb **, iocbp, struct timespec *, timeout); | |
e2e5d75f | 3525 | if (ARG2) { |
76d6b459 | 3526 | PRE_MEM_READ("aio_waitcomplete(timeout", ARG2, sizeof(struct vki_timespec)); |
e2e5d75f | 3527 | } |
76d6b459 | 3528 | PRE_MEM_WRITE( "aio_waitcomplete(iocbp)", ARG1, sizeof(struct aiocb *)); |
e2e5d75f PF |
3529 | } |
3530 | ||
76d6b459 PF |
3531 | POST(sys_aio_waitcomplete) |
3532 | { | |
3533 | POST_MEM_WRITE(ARG1, sizeof(struct aiocb *)); | |
3534 | } | |
e2e5d75f PF |
3535 | |
3536 | // SYS_getresuid 360 | |
3537 | // int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); | |
3538 | PRE(sys_getresuid) | |
3539 | { | |
76d6b459 PF |
3540 | PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
3541 | PRE_REG_READ3(long, "getresuid", | |
3542 | vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid); | |
3543 | PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) ); | |
3544 | PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) ); | |
3545 | PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) ); | |
e2e5d75f PF |
3546 | } |
3547 | ||
3548 | POST(sys_getresuid) | |
3549 | { | |
3550 | vg_assert(SUCCESS); | |
3551 | if (RES == 0) { | |
76d6b459 PF |
3552 | POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) ); |
3553 | POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) ); | |
3554 | POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) ); | |
e2e5d75f PF |
3555 | } |
3556 | } | |
3557 | ||
3558 | // SYS_getresgid 361 | |
3559 | // int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); | |
3560 | PRE(sys_getresgid) | |
3561 | { | |
76d6b459 PF |
3562 | PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); |
3563 | PRE_REG_READ3(long, "getresgid", | |
3564 | vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid); | |
3565 | PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) ); | |
3566 | PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) ); | |
3567 | PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) ); | |
e2e5d75f PF |
3568 | } |
3569 | ||
3570 | POST(sys_getresgid) | |
3571 | { | |
3572 | vg_assert(SUCCESS); | |
3573 | if (RES == 0) { | |
76d6b459 PF |
3574 | POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) ); |
3575 | POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) ); | |
3576 | POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) ); | |
e2e5d75f PF |
3577 | } |
3578 | } | |
3579 | ||
3580 | // SYS_kqueue 362 | |
3581 | // int kqueue(void); | |
3582 | PRE(sys_kqueue) | |
3583 | { | |
410adb9b PF |
3584 | PRINT("%s", "sys_kqueue(void)"); |
3585 | PRE_REG_READ0(int, "kqueue"); | |
e2e5d75f PF |
3586 | } |
3587 | ||
3588 | POST(sys_kqueue) | |
3589 | { | |
3590 | if (!ML_(fd_allowed)(RES, "kqueue", tid, True)) { | |
3591 | VG_(close)(RES); | |
76d6b459 | 3592 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f PF |
3593 | } else { |
3594 | if (VG_(clo_track_fds)) { | |
3595 | ML_(record_fd_open_nameless)(tid, RES); | |
3596 | } | |
3597 | } | |
3598 | } | |
3599 | ||
3600 | // SYS_freebsd11_kevent 363 | |
3601 | // int kevent(int kq, const struct kevent *changelist, int nchanges, | |
3602 | // struct kevent *eventlist, int nevents, | |
3603 | // const struct timespec *timeout); | |
3604 | #if (FREEBSD_VERS >= FREEBSD_12) | |
3605 | PRE(sys_freebsd11_kevent) | |
3606 | { | |
76d6b459 PF |
3607 | PRINT("sys_freebsd11_kevent ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )\n", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); |
3608 | PRE_REG_READ6(int, "kevent", | |
3609 | int, fd, const struct vki_kevent_freebsd11 *, changelist, int, nchanges, | |
3610 | struct vki_kevent_freebsd11 *, eventlist, int, nevents, | |
3611 | struct timespec *, timeout); | |
227fa1d5 | 3612 | if (ARG2 != 0 && ARG3 != 0) { |
76d6b459 | 3613 | PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent_freebsd11)*ARG3 ); |
227fa1d5 PF |
3614 | } |
3615 | if (ARG4 != 0 && ARG5 != 0) { | |
76d6b459 | 3616 | PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent_freebsd11)*ARG5); |
227fa1d5 PF |
3617 | } |
3618 | if (ARG5 != 0) { | |
e2e5d75f | 3619 | *flags |= SfMayBlock; |
227fa1d5 PF |
3620 | } |
3621 | if (ARG6 != 0) { | |
76d6b459 PF |
3622 | PRE_MEM_READ( "kevent(timeout)", |
3623 | ARG6, sizeof(struct vki_timespec)); | |
227fa1d5 | 3624 | } |
e2e5d75f PF |
3625 | } |
3626 | ||
3627 | POST(sys_freebsd11_kevent) | |
3628 | { | |
3629 | vg_assert(SUCCESS); | |
3630 | if ((Word)RES != -1) { | |
227fa1d5 | 3631 | if (ARG4 != 0) { |
76d6b459 | 3632 | POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent_freebsd11)*RES) ; |
227fa1d5 | 3633 | } |
e2e5d75f PF |
3634 | } |
3635 | } | |
3636 | #else | |
3637 | PRE(sys_kevent) | |
3638 | { | |
3639 | *flags |= SfMayBlock; | |
76d6b459 PF |
3640 | PRINT("sys_kevent ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )\n", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); |
3641 | PRE_REG_READ6(int, "kevent", | |
3642 | int, fd, struct vki_kevent_freebsd11 *, changelist, int, nchanges, | |
3643 | struct vki_kevent_freebsd11 *, eventlist, int, nevents, | |
3644 | struct timespec *, timeout); | |
e2e5d75f | 3645 | if (ARG2 != 0 && ARG3 != 0) |
76d6b459 | 3646 | PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent_freebsd11)*ARG3 ); |
e2e5d75f | 3647 | if (ARG4 != 0 && ARG5 != 0) |
76d6b459 | 3648 | PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent_freebsd11)*ARG5); |
e2e5d75f | 3649 | if (ARG6 != 0) |
76d6b459 PF |
3650 | PRE_MEM_READ( "kevent(timeout)", |
3651 | ARG6, sizeof(struct vki_timespec)); | |
e2e5d75f PF |
3652 | } |
3653 | ||
3654 | POST(sys_kevent) | |
3655 | { | |
3656 | vg_assert(SUCCESS); | |
3657 | if ((Word)RES != -1) { | |
3658 | if (ARG4 != 0) | |
76d6b459 | 3659 | POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent_freebsd11)*RES) ; |
e2e5d75f PF |
3660 | } |
3661 | } | |
3662 | #endif | |
3663 | ||
3664 | // SYS_extattr_set_fd 371 | |
3665 | // ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, | |
3666 | // const void *data, size_t nbytes); | |
3667 | PRE(sys_extattr_set_fd) | |
3668 | { | |
76d6b459 PF |
3669 | PRINT("sys_extattr_set_fd ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1,SARG2,ARG3,ARG4,ARG5); |
3670 | PRE_REG_READ5(int, "extattr_set_fd", int, fd, int, attrnamespace, const char *,attrname, const void *,data, size_t, nbytes); | |
3671 | PRE_MEM_RASCIIZ( "extattr_set_fd(attrname)", ARG3 ); | |
e2e5d75f PF |
3672 | PRE_MEM_READ("extattr_set_fd(data)", ARG4, ARG5); |
3673 | } | |
3674 | ||
3675 | // SYS_extattr_get_fd 372 | |
3676 | // ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, | |
3677 | // void *data, size_t nbytes); | |
3678 | PRE(sys_extattr_get_fd) | |
3679 | { | |
76d6b459 PF |
3680 | PRINT("sys_extattr_get_fd ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1,SARG2,ARG3,ARG4,ARG5); |
3681 | PRE_REG_READ5(int, "extattr_get_fd", int, fd, int, attrnamespace, const char *,attrname, const void *,data, size_t, nbytes); | |
3682 | PRE_MEM_RASCIIZ( "extattr_get_fd(attrname)", ARG3 ); | |
e2e5d75f PF |
3683 | PRE_MEM_WRITE("extattr_get_fd(data)", ARG4, ARG5); |
3684 | } | |
3685 | ||
76d6b459 PF |
3686 | POST(sys_extattr_get_fd) |
3687 | { | |
3688 | POST_MEM_WRITE(ARG4, ARG5); | |
3689 | } | |
e2e5d75f PF |
3690 | |
3691 | // SYS_extattr_delete_fd 373 | |
3692 | // int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); | |
3693 | PRE(sys_extattr_delete_fd) | |
3694 | { | |
76d6b459 PF |
3695 | PRINT("sys_extattr_delete_fd ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3); |
3696 | PRE_REG_READ3(int, "extattr_delete_fd", int, fd, int, attrnamespace, const char *,attrname); | |
3697 | PRE_MEM_RASCIIZ( "extattr_delete_fd(attrname)", ARG3 ); | |
e2e5d75f PF |
3698 | } |
3699 | ||
3700 | // SYS___setugid 374 | |
3701 | // no manpage? | |
3702 | // syscalls.master: int __setugid(int flag); | |
3703 | PRE(sys___setugid) | |
3704 | { | |
3705 | PRINT("sys___setugid ( %" FMT_REGWORD "d )", SARG1); | |
3706 | PRE_REG_READ1(int, "__setugid", int, flag); | |
3707 | } | |
3708 | ||
3709 | // SYS_eaccess 376 | |
3710 | // int eaccess(const char *path, int mode); | |
3711 | PRE(sys_eaccess) | |
3712 | { | |
76d6b459 PF |
3713 | PRINT("sys_eaccess ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char*)ARG1,ARG2); |
3714 | PRE_REG_READ2(int, "eaccess", const char *, path, int, mode); | |
3715 | PRE_MEM_RASCIIZ( "eaccess(path)", ARG1 ); | |
e2e5d75f PF |
3716 | } |
3717 | ||
3718 | // SYS_afs3_syscall 377 | |
3719 | // @todo | |
3720 | ||
3721 | // SYS_nmount 378 | |
3722 | // int nmount(struct iovec *iov, u_int niov, int flags); | |
3723 | PRE(sys_nmount) | |
3724 | { | |
76d6b459 PF |
3725 | PRINT("sys_nmount ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d )", ARG1, ARG2, SARG3); |
3726 | PRE_REG_READ3(int, "nmount", struct iovec *, iov, u_int, niov, int, flags); | |
3727 | PRE_MEM_READ( "nmount(pathname)", ARG1, ARG2*sizeof(struct vki_iovec) ); | |
e2e5d75f PF |
3728 | } |
3729 | ||
3730 | // SYS___mac_get_proc 384 | |
3731 | // @todo | |
3732 | ||
3733 | // SYS___mac_set_proc 385 | |
3734 | // @todo | |
3735 | ||
3736 | // SYS___mac_get_fd 386 | |
3737 | // @todo | |
3738 | ||
3739 | // SYS___mac_get_file 387 | |
3740 | // @todo | |
3741 | ||
3742 | // SYS___mac_set_fd 388 | |
3743 | // @todo | |
3744 | ||
3745 | // SYS___mac_set_file 389 | |
3746 | // @todo | |
3747 | ||
3748 | // SYS_kenv 390 | |
3749 | // int kenv(int action, const char *name, char *value, int len); | |
3750 | PRE(sys_kenv) | |
3751 | { | |
76d6b459 PF |
3752 | PRINT("sys_kenv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3,ARG4); |
3753 | PRE_REG_READ4(int, "kenv", | |
3754 | int, action, const char *, name, char *, value, int, len); | |
e2e5d75f PF |
3755 | switch (ARG1) { |
3756 | case VKI_KENV_GET: | |
3757 | case VKI_KENV_SET: | |
3758 | case VKI_KENV_UNSET: | |
3759 | PRE_MEM_RASCIIZ("kenv(name)", ARG2); | |
3760 | /* FALLTHROUGH */ | |
3761 | case VKI_KENV_DUMP: | |
3762 | break; | |
3763 | default: | |
3764 | VG_(dmsg)("Warning: Bad action %" FMT_REGWORD "u in kenv\n", ARG1); | |
3765 | } | |
3766 | } | |
3767 | ||
3768 | POST(sys_kenv) | |
3769 | { | |
3770 | if (SUCCESS) { | |
3771 | switch (ARG1) { | |
3772 | case VKI_KENV_GET: | |
3773 | POST_MEM_WRITE(ARG3, ARG4); | |
3774 | break; | |
3775 | case VKI_KENV_DUMP: | |
227fa1d5 | 3776 | if (ARG3 != (Addr)NULL) { |
e2e5d75f | 3777 | POST_MEM_WRITE(ARG3, ARG4); |
227fa1d5 | 3778 | } |
e2e5d75f PF |
3779 | break; |
3780 | } | |
3781 | } | |
3782 | } | |
3783 | ||
3784 | // SYS_lchflags 391 | |
3785 | // int lchflags(const char *path, unsigned long flags); | |
3786 | PRE(sys_lchflags) | |
3787 | { | |
76d6b459 PF |
3788 | PRINT("sys_lchflags ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2); |
3789 | PRE_REG_READ2(int, "lchflags", | |
3790 | const char *, path, unsigned long, flags); | |
3791 | PRE_MEM_RASCIIZ( "lchflags(path)", ARG1 ); | |
e2e5d75f PF |
3792 | } |
3793 | ||
3794 | // SYS_uuidgen 392 | |
3795 | // int uuidgen(struct uuid *store, int count); | |
3796 | PRE(sys_uuidgen) | |
3797 | { | |
76d6b459 PF |
3798 | PRINT("sys_uuidgen ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2); |
3799 | PRE_REG_READ2(int, "uuidgen", | |
3800 | struct vki_uuid *, store, int, count); | |
3801 | PRE_MEM_WRITE( "uuidgen(store)", ARG1, ARG2 * sizeof(struct vki_uuid)); | |
e2e5d75f PF |
3802 | } |
3803 | ||
3804 | POST(sys_uuidgen) | |
3805 | { | |
227fa1d5 | 3806 | if (SUCCESS) { |
76d6b459 | 3807 | POST_MEM_WRITE( ARG1, ARG2 * sizeof(struct vki_uuid) ); |
227fa1d5 | 3808 | } |
e2e5d75f PF |
3809 | } |
3810 | ||
3811 | // SYS_sendfile 393 | |
3812 | // x86/amd64 | |
3813 | ||
3814 | // SYS_mac_syscall 394 | |
3815 | // @todo | |
3816 | ||
3817 | #if (FREEBSD_VERS >= FREEBSD_12) | |
3818 | ||
3819 | // SYS_freebsd11_getfsstat 395 | |
3820 | // int getfsstat(struct freebsd11_statfs *buf, long bufsize, int mode); | |
3821 | ||
3822 | PRE(sys_freebsd11_getfsstat) | |
3823 | { | |
76d6b459 PF |
3824 | PRINT("sys_freebsd11_getfsstat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
3825 | PRE_REG_READ3(int, "getfsstat", struct vki_freebsd11_statfs *, buf, long, bufsize, int, mode); | |
3826 | PRE_MEM_WRITE( "getfsstat(buf)", ARG1, ARG2 ); | |
e2e5d75f PF |
3827 | } |
3828 | ||
3829 | POST(sys_freebsd11_getfsstat) | |
3830 | { | |
3831 | vg_assert(SUCCESS); | |
3832 | if ((Word)RES != -1) { | |
76d6b459 | 3833 | POST_MEM_WRITE( ARG1, RES * sizeof(struct vki_freebsd11_statfs) ); |
e2e5d75f PF |
3834 | } |
3835 | } | |
3836 | ||
3837 | // SYS_freebsd11_statfs 396 | |
3838 | // int statfs(const char *path, struct statfs *buf); | |
3839 | PRE(sys_freebsd11_statfs) | |
3840 | { | |
76d6b459 PF |
3841 | PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
3842 | PRE_REG_READ2(int, "statfs", const char *, path, struct statfs *, buf); | |
3843 | PRE_MEM_RASCIIZ( "statfs(path)", ARG1 ); | |
3844 | PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
e2e5d75f PF |
3845 | } |
3846 | ||
3847 | POST(sys_freebsd11_statfs) | |
3848 | { | |
76d6b459 | 3849 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) ); |
e2e5d75f PF |
3850 | } |
3851 | ||
3852 | // SYS_freebsd11_fstatfs 397 | |
3853 | // int fstatfs(int fd, struct statfs *buf); | |
3854 | PRE(sys_freebsd11_fstatfs) | |
3855 | { | |
76d6b459 PF |
3856 | PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2); |
3857 | PRE_REG_READ2(int, "fstatfs", | |
3858 | unsigned int, fd, struct statfs *, buf); | |
3859 | PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
e2e5d75f PF |
3860 | } |
3861 | ||
3862 | POST(sys_freebsd11_fstatfs) | |
3863 | { | |
76d6b459 | 3864 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) ); |
e2e5d75f PF |
3865 | } |
3866 | ||
3867 | // SYS_freebsd11_fhstatfs 398 | |
3868 | // int fhstatfs(const fhandle_t *fhp, struct statfs *buf); | |
3869 | PRE(sys_freebsd11_fhstatfs) | |
3870 | { | |
76d6b459 PF |
3871 | PRINT("sys_fhstatfs ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
3872 | PRE_REG_READ2(int, "fhstatfs", | |
3873 | struct fhandle *, fhp, struct statfs *, buf); | |
3874 | PRE_MEM_READ( "fhstatfs(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
3875 | PRE_MEM_WRITE( "fhstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
e2e5d75f PF |
3876 | } |
3877 | ||
3878 | POST(sys_freebsd11_fhstatfs) | |
3879 | { | |
76d6b459 | 3880 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) ); |
e2e5d75f PF |
3881 | } |
3882 | ||
76d6b459 | 3883 | |
e2e5d75f PF |
3884 | #else |
3885 | ||
3886 | PRE(sys_getfsstat) | |
3887 | { | |
76d6b459 PF |
3888 | PRINT("sys_getfsstat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
3889 | PRE_REG_READ3(int, "getfsstat", struct vki_freebsd11_statfs *, buf, long, bufsize, int, mode); | |
3890 | PRE_MEM_WRITE( "getfsstat(buf)", ARG1, ARG2 ); | |
e2e5d75f PF |
3891 | } |
3892 | ||
3893 | POST(sys_getfsstat) | |
3894 | { | |
3895 | vg_assert(SUCCESS); | |
3896 | if ((Word)RES != -1) { | |
76d6b459 | 3897 | POST_MEM_WRITE( ARG1, RES * sizeof(struct vki_freebsd11_statfs) ); |
e2e5d75f PF |
3898 | } |
3899 | } | |
3900 | ||
3901 | PRE(sys_statfs) | |
3902 | { | |
76d6b459 PF |
3903 | PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
3904 | PRE_REG_READ2(int, "statfs", const char *, path, struct statfs *, buf); | |
3905 | PRE_MEM_RASCIIZ( "statfs(path)", ARG1 ); | |
3906 | PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
e2e5d75f PF |
3907 | } |
3908 | ||
76d6b459 PF |
3909 | POST(sys_statfs) |
3910 | { | |
3911 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
3912 | } | |
e2e5d75f PF |
3913 | |
3914 | PRE(sys_fstatfs) | |
3915 | { | |
76d6b459 PF |
3916 | PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2); |
3917 | PRE_REG_READ2(int, "fstatfs", | |
3918 | unsigned int, fd, struct statfs *, buf); | |
3919 | PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
e2e5d75f PF |
3920 | } |
3921 | ||
76d6b459 PF |
3922 | POST(sys_fstatfs) |
3923 | { | |
3924 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
3925 | } | |
e2e5d75f PF |
3926 | |
3927 | PRE(sys_fhstatfs) | |
3928 | { | |
76d6b459 PF |
3929 | PRINT("sys_fhstatfs ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
3930 | PRE_REG_READ2(int, "fhstatfs", | |
3931 | struct fhandle *, fhp, struct statfs *, buf); | |
3932 | PRE_MEM_READ( "fhstatfs(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
3933 | PRE_MEM_WRITE( "fhstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) ); | |
e2e5d75f PF |
3934 | } |
3935 | ||
3936 | POST(sys_fhstatfs) | |
3937 | { | |
76d6b459 | 3938 | POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) ); |
e2e5d75f PF |
3939 | } |
3940 | ||
76d6b459 | 3941 | |
e2e5d75f PF |
3942 | #endif |
3943 | ||
3944 | // SYS_ksem_close 400 | |
3945 | // @todo | |
3946 | ||
3947 | // SYS_ksem_post 401 | |
3948 | // @todo | |
3949 | ||
3950 | // SYS_ksem_wait 402 | |
3951 | // @todo | |
3952 | ||
3953 | // SYS_ksem_trywait 403 | |
3954 | // @todo | |
3955 | ||
3956 | // SYS_ksem_init 404 | |
3957 | // @todo | |
3958 | ||
3959 | // SYS_ksem_open 405 | |
3960 | // @todo | |
3961 | ||
3962 | // SYS_ksem_unlink 406 | |
3963 | // @todo | |
3964 | ||
3965 | // SYS_ksem_getvalue 407 | |
3966 | // @todo | |
3967 | ||
3968 | // SYS_ksem_destroy 408 | |
3969 | // @todo | |
3970 | ||
3971 | // SYS___mac_get_pid 409 | |
3972 | // @todo | |
3973 | ||
3974 | // SYS___mac_get_link 410 | |
3975 | // @todo | |
3976 | ||
3977 | // SYS___mac_set_link 411 | |
3978 | // @todo | |
3979 | ||
3980 | // SYS_extattr_set_link 412 | |
3981 | // ssize_t extattr_set_link(const char *path, int attrnamespace, | |
76d6b459 | 3982 | // const char *attrname, const void *data, size_t nbytes); |
e2e5d75f PF |
3983 | PRE(sys_extattr_set_link) |
3984 | { | |
76d6b459 PF |
3985 | PRINT("sys_extattr_set_link ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5); |
3986 | PRE_REG_READ5(ssize_t, "extattr_set_link", | |
3987 | const char *, path, int, attrnamespace, const char *, attrname, const void *, data, size_t, nbytes); | |
e2e5d75f PF |
3988 | PRE_MEM_RASCIIZ("extattr_set_link(path)", ARG1); |
3989 | PRE_MEM_RASCIIZ("extattr_set_link(attrname)", ARG3); | |
3990 | PRE_MEM_READ("extattr_set_link(data)", ARG4, ARG5); | |
3991 | } | |
3992 | ||
3993 | // SYS_extattr_get_link 413 | |
3994 | // ssize_t extattr_get_link(const char *path, int attrnamespace, | |
3995 | // const char *attrname, void *data, size_t nbytes); | |
3996 | PRE(sys_extattr_get_link) | |
3997 | { | |
76d6b459 PF |
3998 | PRINT("sys_extattr_get_link ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5); |
3999 | PRE_REG_READ5(ssize_t, "extattr_get_link", | |
4000 | const char *, path, int, attrnamespace, const char *, attrname, void *, data, size_t, nbytes); | |
e2e5d75f PF |
4001 | PRE_MEM_RASCIIZ("extattr_get_link(path)", ARG1); |
4002 | PRE_MEM_RASCIIZ("extattr_get_link(attrname)", ARG3); | |
4003 | if (ARG4) { | |
4004 | PRE_MEM_WRITE("extattr_get_link(data)", ARG4, ARG5); | |
4005 | } | |
4006 | } | |
4007 | ||
4008 | POST(sys_extattr_get_link) | |
4009 | { | |
4010 | if (ARG4) { | |
4011 | POST_MEM_WRITE(ARG4, ARG5); | |
4012 | } | |
4013 | } | |
4014 | ||
4015 | // SYS_extattr_delete_link 414 | |
4016 | // int extattr_delete_link(const char *path, int attrnamespace, | |
4017 | // const char *attrname); | |
4018 | PRE(sys_extattr_delete_link) | |
4019 | { | |
76d6b459 PF |
4020 | PRINT("sys_extattr_delete_link ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3); |
4021 | PRE_REG_READ3(ssize_t, "extattr_delete_link", | |
4022 | const char *, path, int, attrnamespace, const char *, attrname); | |
e2e5d75f PF |
4023 | PRE_MEM_RASCIIZ("extattr_delete_link(path)", ARG1); |
4024 | PRE_MEM_RASCIIZ("extattr_delete_link(attrname)", ARG3); | |
4025 | } | |
4026 | ||
4027 | // SYS___mac_execve 415 | |
4028 | // @todo | |
4029 | ||
4030 | // SYS_sigaction 416 | |
76d6b459 | 4031 | //int sigaction(int sig, const struct sigaction * restrict act, |
e2e5d75f PF |
4032 | // struct sigaction * restrict oact); |
4033 | PRE(sys_sigaction) | |
4034 | { | |
76d6b459 PF |
4035 | vki_sigaction_toK_t new; |
4036 | vki_sigaction_toK_t *newp; | |
4037 | vki_sigaction_fromK_t old; | |
4038 | vki_sigaction_fromK_t *oldp; | |
e2e5d75f | 4039 | |
76d6b459 PF |
4040 | PRINT("sys_sigaction ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", |
4041 | SARG1,ARG2,ARG3); | |
4042 | PRE_REG_READ3(long, "sigaction", | |
4043 | int, sign, const struct sigaction *, act, | |
4044 | struct sigaction *, oact); | |
e2e5d75f PF |
4045 | |
4046 | newp = oldp = NULL; | |
4047 | ||
4048 | if (ARG2 != 0) { | |
76d6b459 PF |
4049 | struct vki_sigaction *sa = (struct vki_sigaction *)ARG2; |
4050 | PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler)); | |
4051 | PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask)); | |
4052 | PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags)); | |
e2e5d75f PF |
4053 | } |
4054 | ||
4055 | if (ARG3 != 0) { | |
76d6b459 | 4056 | PRE_MEM_WRITE( "sigaction(oact)", ARG3, sizeof(struct vki_sigaction)); |
e2e5d75f PF |
4057 | oldp = &old; |
4058 | } | |
4059 | ||
76d6b459 PF |
4060 | if (ARG2 != 0 |
4061 | && ! ML_(safe_to_deref)((void *)(Addr)ARG2, | |
4062 | sizeof(struct vki_sigaction))) { | |
e2e5d75f | 4063 | VG_(umsg)("Warning: bad act handler address %p in sigaction()\n", |
76d6b459 PF |
4064 | (void *)(Addr)ARG2); |
4065 | SET_STATUS_Failure ( VKI_EFAULT ); | |
4066 | } else if ((ARG3 != 0 | |
4067 | && ! ML_(safe_to_deref)((void *)(Addr)ARG3, | |
4068 | sizeof(struct vki_sigaction)))) { | |
e2e5d75f | 4069 | VG_(umsg)("Warning: bad oact handler address %p in sigaction()\n", |
76d6b459 PF |
4070 | (void *)(Addr)ARG3); |
4071 | SET_STATUS_Failure ( VKI_EFAULT ); | |
e2e5d75f PF |
4072 | } else { |
4073 | if (ARG2 != 0) { | |
76d6b459 PF |
4074 | struct vki_sigaction *oldnew = |
4075 | (struct vki_sigaction *)(Addr)ARG2; | |
e2e5d75f PF |
4076 | |
4077 | new.ksa_handler = oldnew->ksa_handler; | |
76d6b459 PF |
4078 | new.sa_flags = oldnew->sa_flags; |
4079 | new.sa_mask = oldnew->sa_mask; | |
4080 | newp = &new; | |
e2e5d75f PF |
4081 | } |
4082 | ||
76d6b459 | 4083 | SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) ); |
e2e5d75f PF |
4084 | |
4085 | if (ARG3 != 0 && SUCCESS && RES == 0) { | |
76d6b459 PF |
4086 | struct vki_sigaction *oldold = |
4087 | (struct vki_sigaction *)(Addr)ARG3; | |
e2e5d75f PF |
4088 | |
4089 | oldold->ksa_handler = oldp->ksa_handler; | |
76d6b459 PF |
4090 | oldold->sa_flags = oldp->sa_flags; |
4091 | oldold->sa_mask = oldp->sa_mask; | |
e2e5d75f PF |
4092 | } |
4093 | } | |
4094 | } | |
4095 | ||
4096 | POST(sys_sigaction) | |
4097 | { | |
4098 | vg_assert(SUCCESS); | |
227fa1d5 | 4099 | if (RES == 0 && ARG3 != 0) { |
76d6b459 | 4100 | POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction)); |
227fa1d5 | 4101 | } |
e2e5d75f PF |
4102 | } |
4103 | ||
4104 | // SYS_sigreturn 417 | |
4105 | // x86/amd64 | |
4106 | ||
4107 | // SYS_getcontext 421 | |
4108 | // SYS_setcontext 422 | |
4109 | // SYS_swapcontext 423 | |
4110 | // PRE in x86/amd64 | |
4111 | ||
76d6b459 PF |
4112 | POST(sys_getcontext) |
4113 | { | |
4114 | POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) ); | |
4115 | } | |
e2e5d75f PF |
4116 | |
4117 | POST(sys_swapcontext) | |
4118 | { | |
227fa1d5 | 4119 | if (SUCCESS) { |
76d6b459 | 4120 | POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) ); |
227fa1d5 | 4121 | } |
e2e5d75f PF |
4122 | } |
4123 | ||
6cb8e52c | 4124 | #if (FREEBSD_VERS >= FREEBSD_13_1) |
cdd98111 PF |
4125 | // SYS_freebsd13_swapoff 424 |
4126 | // int swapoff(const char *special); | |
4127 | PRE(sys_freebsd13_swapoff) | |
4128 | { | |
76d6b459 PF |
4129 | PRINT("sys_freebsd13_swapoff ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1); |
4130 | PRE_REG_READ1(int, "swapoff", const char *, special); | |
4131 | PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 ); | |
cdd98111 PF |
4132 | } |
4133 | #else | |
e2e5d75f PF |
4134 | // SYS_swapoff 424 |
4135 | // int swapoff(const char *special); | |
4136 | PRE(sys_swapoff) | |
4137 | { | |
76d6b459 PF |
4138 | PRINT("sys_swapoff ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1); |
4139 | PRE_REG_READ1(int, "swapoff", const char *, special); | |
4140 | PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 ); | |
e2e5d75f | 4141 | } |
cdd98111 | 4142 | #endif |
e2e5d75f PF |
4143 | |
4144 | // SYS___acl_get_link 425 | |
4145 | // int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); | |
4146 | PRE(sys___acl_get_link) | |
4147 | { | |
76d6b459 PF |
4148 | PRINT("sys___acl_get_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3); |
4149 | PRE_REG_READ3(int, "__acl_get_link", | |
4150 | const char *, path, int, acltype, struct vki_acl *, aclp); | |
4151 | PRE_MEM_RASCIIZ( "__acl_get_link(path)", ARG1 ); | |
4152 | PRE_MEM_WRITE( "__acl_get_link(aclp)", ARG3, sizeof(struct vki_acl) ); | |
e2e5d75f PF |
4153 | } |
4154 | ||
4155 | POST(sys___acl_get_link) | |
4156 | { | |
4157 | vg_assert(SUCCESS); | |
4158 | if (RES == 0) { | |
76d6b459 | 4159 | POST_MEM_WRITE( ARG3, sizeof(struct vki_acl) ); |
e2e5d75f PF |
4160 | } |
4161 | } | |
4162 | ||
4163 | // SYS___acl_set_link 426 | |
4164 | // int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); | |
4165 | PRE(sys___acl_set_link) | |
4166 | { | |
76d6b459 PF |
4167 | PRINT("sys___acl_set_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3); |
4168 | PRE_REG_READ3(int, "__acl_set_link", | |
4169 | const char *, path, int, acltype, struct vki_acl *, aclp); | |
4170 | PRE_MEM_RASCIIZ( "__acl_set_link(path)", ARG1 ); | |
4171 | PRE_MEM_READ( "__acl_set_link(aclp)", ARG3, sizeof(struct vki_acl) ); | |
e2e5d75f PF |
4172 | } |
4173 | // SYS___acl_delete_link 427 | |
4174 | // int __acl_delete_link(const char *path, acl_type_t type); | |
4175 | PRE(sys___acl_delete_link) | |
4176 | { | |
76d6b459 PF |
4177 | PRINT("sys___acl_delete_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1,ARG2); |
4178 | PRE_MEM_RASCIIZ( "__acl_delete_link(path)", ARG1 ); | |
4179 | PRE_REG_READ2(int, "__acl_delete_link", | |
4180 | const char *, path, int, acltype); | |
e2e5d75f PF |
4181 | } |
4182 | ||
4183 | // SYS___acl_aclcheck_link 428 | |
4184 | // int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); | |
4185 | PRE(sys___acl_aclcheck_link) | |
4186 | { | |
76d6b459 PF |
4187 | PRINT("sys___acl_aclcheck_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3); |
4188 | PRE_REG_READ3(long, "__acl_aclcheck_link", | |
4189 | const char *, path, int, acltype, struct vki_acl *, aclp); | |
4190 | PRE_MEM_RASCIIZ( "__acl_check_link(path)", ARG1 ); | |
4191 | PRE_MEM_READ( "__acl_aclcheck_link(aclp)", ARG3, sizeof(struct vki_acl) ); | |
e2e5d75f PF |
4192 | } |
4193 | ||
4194 | // SYS_sigwait 429 | |
4195 | // int sigwait(const sigset_t * restrict set, int * restrict sig); | |
4196 | PRE(sys_sigwait) | |
4197 | { | |
4198 | *flags |= SfMayBlock; | |
76d6b459 PF |
4199 | PRINT("sys_sigwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", |
4200 | ARG1,ARG2); | |
4201 | PRE_REG_READ2(int, "sigwait", | |
4202 | const vki_sigset_t *, set, int *, sig); | |
227fa1d5 | 4203 | if (ARG1 != 0) { |
76d6b459 | 4204 | PRE_MEM_READ( "sigwait(set)", ARG1, sizeof(vki_sigset_t)); |
227fa1d5 PF |
4205 | } |
4206 | if (ARG2 != 0) { | |
76d6b459 | 4207 | PRE_MEM_WRITE( "sigwait(sig)", ARG2, sizeof(int)); |
227fa1d5 | 4208 | } |
e2e5d75f PF |
4209 | } |
4210 | ||
4211 | POST(sys_sigwait) | |
4212 | { | |
227fa1d5 | 4213 | if (ARG2 != 0) { |
76d6b459 | 4214 | POST_MEM_WRITE( ARG2, sizeof(int)); |
227fa1d5 | 4215 | } |
e2e5d75f PF |
4216 | } |
4217 | ||
4218 | // SYS_thr_create 430 | |
4219 | // no manpage? | |
76d6b459 | 4220 | // syscalls.master: int thr_create(_In_ ucontext_t *ctx, _Out_ long *id, int flags ); |
e2e5d75f PF |
4221 | PRE(sys_thr_create) |
4222 | { | |
76d6b459 PF |
4223 | PRINT( "sys_thr_create ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )", ARG1, ARG2, SARG3 ); |
4224 | PRE_REG_READ3(int, "thr_create", /*ucontext_t*/void *, ctx, long *, id, int, flags ); | |
e2e5d75f PF |
4225 | |
4226 | VG_(message)(Vg_UserMsg, "thr_create() not implemented"); | |
4227 | VG_(unimplemented)("Valgrind does not support thr_create()."); | |
4228 | ||
4229 | SET_STATUS_Failure(VKI_ENOSYS); | |
4230 | } | |
4231 | ||
4232 | // SYS_thr_exit 431 | |
4233 | // void thr_exit(long *state); | |
4234 | PRE(sys_thr_exit) | |
4235 | { | |
76d6b459 | 4236 | ThreadState *tst; |
e2e5d75f | 4237 | |
76d6b459 PF |
4238 | PRINT( "sys_thr_exit ( %#" FMT_REGWORD "x )", ARG1 ); |
4239 | PRE_REG_READ1(void, "thr_exit", long *, state); | |
e2e5d75f PF |
4240 | |
4241 | if (ARG1) { | |
76d6b459 | 4242 | PRE_MEM_WRITE( "thr_exit(state)", ARG1, sizeof(long) ); |
e2e5d75f PF |
4243 | } |
4244 | ||
76d6b459 PF |
4245 | tst = VG_(get_ThreadState)(tid); |
4246 | tst->exitreason = VgSrc_ExitThread; | |
e2e5d75f PF |
4247 | tst->os_state.exitcode = ARG1; |
4248 | SET_STATUS_Success(0); | |
4249 | } | |
4250 | ||
4251 | // SYS_thr_self 432 | |
4252 | // int thr_self(long *id); | |
4253 | PRE(sys_thr_self) | |
4254 | { | |
76d6b459 PF |
4255 | PRINT( "sys_thr_self ( %#" FMT_REGWORD "x )", ARG1 ); |
4256 | PRE_REG_READ1(int, "thr_self", long *, id); | |
4257 | PRE_MEM_WRITE( "thr_self()", ARG1, sizeof(long)); | |
e2e5d75f PF |
4258 | } |
4259 | ||
76d6b459 PF |
4260 | POST(sys_thr_self) |
4261 | { | |
4262 | POST_MEM_WRITE( ARG1, sizeof(long)); | |
4263 | } | |
e2e5d75f PF |
4264 | |
4265 | // SYS_thr_kill 433 | |
4266 | // int thr_kill(long id, int sig); | |
4267 | PRE(sys_thr_kill) | |
4268 | { | |
76d6b459 | 4269 | PRINT("sys_thr_kill ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2); |
e2e5d75f PF |
4270 | PRE_REG_READ2(long, "thr_kill", long, id, int, sig); |
4271 | if (!ML_(client_signal_OK)(ARG2)) { | |
76d6b459 | 4272 | SET_STATUS_Failure( VKI_EINVAL ); |
e2e5d75f PF |
4273 | return; |
4274 | } | |
4275 | ||
4276 | /* Check to see if this kill gave us a pending signal */ | |
4277 | *flags |= SfPollAfter; | |
4278 | ||
76d6b459 | 4279 | if (VG_(clo_trace_signals)) { |
e2e5d75f PF |
4280 | VG_(message)(Vg_DebugMsg, "thr_kill: sending signal %lu to tid %lu\n", |
4281 | ARG2, ARG1); | |
227fa1d5 | 4282 | } |
e2e5d75f PF |
4283 | |
4284 | /* If we're sending SIGKILL, check to see if the target is one of | |
4285 | our threads and handle it specially. */ | |
4286 | if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) { | |
4287 | SET_STATUS_Success(0); | |
4288 | return; | |
4289 | } | |
4290 | ||
4291 | /* Ask to handle this syscall via the slow route, since that's the | |
4292 | only one that sets tst->status to VgTs_WaitSys. If the result | |
4293 | of doing the syscall is an immediate run of | |
4294 | async_signalhandler() in m_signals, then we need the thread to | |
4295 | be properly tidied away. I have the impression the previous | |
4296 | version of this wrapper worked on x86/amd64 only because the | |
4297 | kernel did not immediately deliver the async signal to this | |
4298 | thread (on ppc it did, which broke the assertion re tst->status | |
4299 | at the top of async_signalhandler()). */ | |
4300 | *flags |= SfMayBlock; | |
4301 | } | |
4302 | ||
4303 | POST(sys_thr_kill) | |
4304 | { | |
227fa1d5 | 4305 | if (VG_(clo_trace_signals)) { |
76d6b459 PF |
4306 | VG_(message)(Vg_DebugMsg, "thr_kill: sent signal %lu to tid %lu\n", |
4307 | ARG2, ARG1); | |
227fa1d5 | 4308 | } |
e2e5d75f PF |
4309 | } |
4310 | ||
4311 | #if (FREEBSD_VERS <= FREEBSD_10) | |
4312 | // SYS__umtx_lock 434 | |
4313 | PRE(sys__umtx_lock) | |
4314 | { | |
76d6b459 PF |
4315 | PRINT( "sys__umtx_lock ( %#" FMT_REGWORD "x )", ARG1); |
4316 | PRE_REG_READ1(long, "_umtx_lock", struct vki_umtx *, umtx); | |
4317 | PRE_MEM_READ( "_umtx_lock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
4318 | PRE_MEM_WRITE( "_umtx_lock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
e2e5d75f PF |
4319 | } |
4320 | ||
4321 | POST(sys__umtx_lock) | |
4322 | { | |
227fa1d5 | 4323 | if (SUCCESS) { |
e2e5d75f | 4324 | POST_MEM_WRITE(ARG1, sizeof(struct vki_umtx)); |
227fa1d5 | 4325 | } |
e2e5d75f PF |
4326 | } |
4327 | ||
4328 | // SYS__umtx_unlock 434 | |
4329 | PRE(sys__umtx_unlock) | |
4330 | { | |
76d6b459 PF |
4331 | PRINT( "sys__umtx_unlock ( %#" FMT_REGWORD "x )", ARG1); |
4332 | PRE_REG_READ1(long, "_umtx_unlock", struct vki_umtx *, umtx); | |
4333 | PRE_MEM_READ( "_umtx_unlock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
4334 | PRE_MEM_WRITE( "_umtx_unlock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
e2e5d75f PF |
4335 | } |
4336 | ||
4337 | POST(sys__umtx_unlock) | |
4338 | { | |
227fa1d5 | 4339 | if (SUCCESS) { |
e2e5d75f | 4340 | POST_MEM_WRITE(ARG1, sizeof(struct vki_umtx)); |
227fa1d5 | 4341 | } |
e2e5d75f PF |
4342 | } |
4343 | #endif | |
4344 | ||
4345 | // SYS_jail_attach 436 | |
4346 | // int jail_attach(int jid); | |
4347 | PRE(sys_jail_attach) | |
4348 | { | |
4349 | PRINT("sys_jail_attach ( %" FMT_REGWORD "d )", SARG1); | |
4350 | PRE_REG_READ1(int, "jail_attach", int, jid); | |
4351 | } | |
4352 | ||
4353 | // SYS_extattr_list_fd 437 | |
76d6b459 | 4354 | // ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); |
e2e5d75f PF |
4355 | PRE(sys_extattr_list_fd) |
4356 | { | |
76d6b459 PF |
4357 | PRINT("extattr_list_fd ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, SARG2, ARG3, ARG4); |
4358 | PRE_REG_READ4(ssize_t, "extattr_list_fd", int, id, int, attrnamespace, void *,data, size_t, nbytes); | |
e2e5d75f PF |
4359 | PRE_MEM_WRITE("extattr_list_fd(data)", ARG3, ARG4); |
4360 | } | |
4361 | ||
76d6b459 PF |
4362 | POST(sys_extattr_list_fd) |
4363 | { | |
4364 | POST_MEM_WRITE(ARG3, ARG4); | |
4365 | } | |
e2e5d75f PF |
4366 | |
4367 | // SYS_extattr_list_file 438 | |
4368 | // ssize_t extattr_list_file(const char *path, int attrnamespace, void *data, | |
4369 | // size_t nbytes); | |
4370 | PRE(sys_extattr_list_file) | |
4371 | { | |
76d6b459 PF |
4372 | PRINT("extattr_list_file ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, SARG2, ARG3, ARG4); |
4373 | PRE_REG_READ4(ssize_t, "extattr_list_file", const char *, path, int, attrnamespace, void *,data, size_t, nbytes); | |
e2e5d75f PF |
4374 | PRE_MEM_RASCIIZ("extattr_list_file(path)", ARG1); |
4375 | PRE_MEM_WRITE("extattr_list_file(data)", ARG3, ARG4); | |
4376 | } | |
4377 | ||
76d6b459 PF |
4378 | POST(sys_extattr_list_file) |
4379 | { | |
4380 | POST_MEM_WRITE(ARG3, ARG4); | |
4381 | } | |
e2e5d75f PF |
4382 | |
4383 | // SYS_extattr_list_link 439 | |
4384 | // ssize_t extattr_get_link(const char *path, int attrnamespace, | |
4385 | // const char *attrname, void *data, size_t nbytes); | |
4386 | PRE(sys_extattr_list_link) | |
4387 | { | |
76d6b459 PF |
4388 | PRINT("extattr_list_link ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, SARG2, ARG3, ARG4); |
4389 | PRE_REG_READ4(ssize_t, "extattr_list_link", const char *, path, int, attrnamespace, void *,data, size_t, nbytes); | |
e2e5d75f PF |
4390 | PRE_MEM_RASCIIZ("extattr_list_link(path)", ARG1); |
4391 | PRE_MEM_WRITE("extattr_list_link(data)", ARG3, ARG4); | |
4392 | } | |
4393 | ||
76d6b459 PF |
4394 | POST(sys_extattr_list_link) |
4395 | { | |
4396 | POST_MEM_WRITE(ARG3, ARG4); | |
4397 | } | |
e2e5d75f PF |
4398 | |
4399 | // SYS_ksem_timedwait 441 | |
4400 | // @todo | |
4401 | ||
4402 | // SYS_thr_suspend 442 | |
4403 | // int thr_suspend(struct timespec *timeout); | |
4404 | PRE(sys_thr_suspend) | |
4405 | { | |
4406 | PRINT("sys_thr_suspend ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 4407 | PRE_REG_READ1(int, "thr_suspend", struct timespec *, timeout); |
e2e5d75f PF |
4408 | PRE_MEM_READ("thr_suspend(timeout)", ARG1, sizeof(struct vki_timespec)); |
4409 | ||
4410 | VG_(message)(Vg_UserMsg, "thr_supend() not implemented"); | |
4411 | VG_(unimplemented)("Valgrind does not support thr_suspend()."); | |
4412 | ||
4413 | SET_STATUS_Failure(VKI_ENOSYS); | |
4414 | } | |
4415 | ||
4416 | // SYS_thr_wake 443 | |
4417 | // int thr_wake(long id); | |
4418 | PRE(sys_thr_wake) | |
4419 | { | |
4420 | PRINT("sys_thr_wake ( %" FMT_REGWORD "d )", SARG1); | |
4421 | PRE_REG_READ1(long, "thr_wake", long, id); | |
4422 | /* | |
4423 | if (VG_(is_valid_tid)(ARG1)) { | |
4424 | VG_(threads)[ARG1].status = VgTs_Runnable; | |
4425 | } else { | |
4426 | SET_STATUS_Failure( VKI_ESRCH ); | |
4427 | } | |
4428 | */ | |
4429 | } | |
4430 | ||
4431 | // SYS_kldunloadf 444 | |
4432 | // int kldunloadf(int fileid, int flags); | |
4433 | PRE(sys_kldunloadf) | |
4434 | { | |
76d6b459 | 4435 | PRINT("sys_kldunloadf ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1, SARG2); |
e2e5d75f PF |
4436 | PRE_REG_READ2(int, "kldunloadf", int, fileid, int, flags); |
4437 | } | |
4438 | ||
4439 | // SYS_audit 445 | |
4440 | // int audit(const char *record, u_int length); | |
4441 | // @todo | |
4442 | ||
4443 | // SYS_auditon 446 | |
4444 | // int auditon(int cmd, void *data, u_int length); | |
4445 | // @todo | |
4446 | ||
4447 | // SYS_getauid 447 | |
4448 | // int getauid(au_id_t *auid); | |
4449 | // @todo | |
4450 | ||
4451 | // SYS_setauid 448 | |
4452 | // int setauid(au_id_t *auid); | |
4453 | // @todo | |
4454 | ||
4455 | // SYS_getaudit 449 | |
4456 | // int getaudit(auditinfo_t *auditinfo); | |
4457 | // @todo | |
4458 | ||
4459 | // SYS_setaudit 450 | |
4460 | // int setaudit(auditinfo_t *auditinfo); | |
4461 | // @todo | |
4462 | ||
4463 | // SYS_getaudit_addr 451 | |
4464 | // int getaudit_addr(auditinfo_addr_t *auditinfo_addr, u_int length); | |
4465 | // @todo | |
4466 | ||
4467 | // SYS_setaudit_addr 452 | |
4468 | // int setaudit_addr(auditinfo_addr_t *auditinfo_addr, u_int length); | |
4469 | // @todo | |
4470 | ||
4471 | // SYS_auditctl 453 | |
4472 | // @todo | |
4473 | ||
4474 | // SYS__umtx_op 454 | |
4475 | // int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2); | |
4476 | PRE(sys__umtx_op) | |
4477 | { | |
4478 | /* 5 args are always passed through. The last two can vary, but | |
4479 | they're always pointers. They may not be used though. */ | |
76d6b459 | 4480 | switch(ARG2) { |
e2e5d75f | 4481 | case VKI_UMTX_OP_LOCK: |
cae2118d | 4482 | // marked as COMPAT10 |
76d6b459 PF |
4483 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, LOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4484 | PRE_REG_READ5(long, "_umtx_op_lock", | |
4485 | struct umtx *, obj, int, op, unsigned long, id, | |
4486 | size_t, timeout_size, struct vki_timespec *, timeout); | |
4487 | PRE_MEM_READ( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
d8cc70f6 | 4488 | if (ARG5) { |
76d6b459 | 4489 | PRE_MEM_READ( "_umtx_op_lock(timespec)", ARG5, ARG4 ); |
d8cc70f6 | 4490 | } |
76d6b459 | 4491 | PRE_MEM_WRITE( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) ); |
e2e5d75f PF |
4492 | *flags |= SfMayBlock; |
4493 | break; | |
4494 | case VKI_UMTX_OP_UNLOCK: | |
cae2118d | 4495 | // marked as COMPAT10 |
76d6b459 PF |
4496 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, UNLOCK, %" FMT_REGWORD "u)", ARG1, ARG3); |
4497 | PRE_REG_READ3(long, "_umtx_op_unlock", | |
4498 | struct umtx *, obj, int, op, unsigned long, id); | |
4499 | PRE_MEM_READ( "_umtx_op_unlock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
4500 | PRE_MEM_WRITE( "_umtx_op_unlock(mtx)", ARG1, sizeof(struct vki_umtx) ); | |
e2e5d75f PF |
4501 | break; |
4502 | case VKI_UMTX_OP_WAIT: | |
76d6b459 PF |
4503 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4504 | PRE_REG_READ5(long, "_umtx_op_wait", | |
4505 | long *, obj, int, op, unsigned long, val, | |
4506 | size_t, timeout_size, struct vki_timespec *, timeout); | |
e2e5d75f | 4507 | if (ARG1) { |
76d6b459 | 4508 | PRE_MEM_READ( "_umtx_op_wait(val)", ARG1, sizeof(long) ); |
e2e5d75f PF |
4509 | if (*(long*)ARG1 == (long)ARG3) { |
4510 | *flags |= SfMayBlock; | |
4511 | } | |
4512 | } | |
4513 | ||
4514 | if (ARG5) { | |
76d6b459 | 4515 | PRE_MEM_READ( "_umtx_op_wait(timeout)", ARG5, ARG4 ); |
e2e5d75f PF |
4516 | } |
4517 | ||
4518 | break; | |
4519 | case VKI_UMTX_OP_WAKE: | |
76d6b459 PF |
4520 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, WAKE, %" FMT_REGWORD "u)", ARG1, ARG3); |
4521 | PRE_REG_READ3(long, "_umtx_op_wake", | |
4522 | vki_uintptr_t *, obj, int, op, int, val); | |
4523 | // PJF I don't think that the value of obj gets read, the address is being used as a key | |
4524 | //PRE_MEM_READ("_umtx_op_wake(obj)", ARG1, sizeof(vki_uintptr_t)); | |
e2e5d75f PF |
4525 | break; |
4526 | case VKI_UMTX_OP_MUTEX_TRYLOCK: | |
76d6b459 PF |
4527 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_TRYLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4528 | PRE_REG_READ2(long, "_umtx_op_mutex_trylock", struct umutex *, obj, int, op); | |
4529 | PRE_MEM_READ( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
4530 | PRE_MEM_WRITE( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
cae2118d PF |
4531 | /* not too sure about the restart here |
4532 | * it's hard to test as if the mutex is locked this returns EBUSY | |
76d6b459 | 4533 | * so there is only a small window where the syscall could be interrupted */ |
d8cc70f6 | 4534 | *flags |= SfMayBlock | SfKernelRestart; |
e2e5d75f PF |
4535 | break; |
4536 | case VKI_UMTX_OP_MUTEX_LOCK: | |
cae2118d PF |
4537 | // called by pthread_mutex_lock |
4538 | // when the atribute UMUTEX_PRIO_PROTECT or UMUTEX_PRIO_INHERIT is set | |
76d6b459 PF |
4539 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_LOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4540 | PRE_REG_READ5(long, "_umtx_op_mutex_lock", | |
4541 | struct umutex *, obj, int, op, unsigned long, noid, | |
4542 | size_t, timeout_size, struct vki_timespec *, timeout); | |
4543 | PRE_MEM_READ( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
d8cc70f6 | 4544 | if (ARG5) { |
76d6b459 | 4545 | PRE_MEM_READ( "_umtx_op_mutex_lock(timespec)", ARG5, ARG4 ); |
cae2118d PF |
4546 | } else { |
4547 | *flags |= SfKernelRestart; | |
d8cc70f6 | 4548 | } |
76d6b459 | 4549 | PRE_MEM_WRITE( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) ); |
cae2118d | 4550 | *flags |= SfMayBlock; |
e2e5d75f PF |
4551 | break; |
4552 | case VKI_UMTX_OP_MUTEX_UNLOCK: | |
76d6b459 PF |
4553 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_UNLOCK)", ARG1); |
4554 | PRE_REG_READ2(long, "_umtx_op_mutex_unlock", | |
4555 | struct umutex *, obj, int, op); | |
4556 | PRE_MEM_READ( "_umtx_op_mutex_unlock(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
4557 | PRE_MEM_WRITE( "_umtx_op_mutex_unlock(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
e2e5d75f PF |
4558 | break; |
4559 | case VKI_UMTX_OP_SET_CEILING: | |
76d6b459 PF |
4560 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SET_CEILING, %" FMT_REGWORD "u, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4); |
4561 | PRE_REG_READ4(long, "_umtx_op_set_ceiling", | |
4562 | struct umutex *, obj, int, op, unsigned int, ceiling, | |
4563 | unsigned int *, old_ceiling); | |
4564 | PRE_MEM_READ( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
4565 | PRE_MEM_WRITE( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
d8cc70f6 | 4566 | if (ARG4) { |
76d6b459 | 4567 | PRE_MEM_WRITE( "_umtx_op_set_ceiling(old_ceiling)", ARG4, sizeof(vki_uint32_t) ); |
d8cc70f6 | 4568 | } |
e2e5d75f PF |
4569 | break; |
4570 | case VKI_UMTX_OP_CV_WAIT: | |
76d6b459 PF |
4571 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4572 | PRE_REG_READ5(long, "_umtx_op_cv_wait", | |
4573 | struct ucond *, obj, int, op, unsigned long, wflags, | |
4574 | struct umutex *, umtx, struct vki_timespec *, timeout); | |
4575 | PRE_MEM_READ( "_umtx_op_cv_wait(cond)", ARG1, sizeof(struct vki_ucond) ); | |
4576 | PRE_MEM_WRITE( "_umtx_op_cv_wait(cond)", ARG1, sizeof(struct vki_ucond) ); | |
4577 | PRE_MEM_READ( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) ); | |
4578 | PRE_MEM_WRITE( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) ); | |
d8cc70f6 | 4579 | if (ARG5) { |
76d6b459 | 4580 | PRE_MEM_READ( "_umtx_op_cv_wait(timespec)", ARG5, sizeof(struct vki_timespec) ); |
d8cc70f6 | 4581 | } |
e2e5d75f PF |
4582 | *flags |= SfMayBlock; |
4583 | break; | |
4584 | case VKI_UMTX_OP_CV_SIGNAL: | |
76d6b459 PF |
4585 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_SIGNAL)", ARG1); |
4586 | PRE_REG_READ2(long, "_umtx_op_cv_signal", | |
4587 | struct ucond *, obj, int, op); | |
4588 | PRE_MEM_READ( "_umtx_op_cv_signal(cond)", ARG1, sizeof(struct vki_ucond) ); | |
4589 | PRE_MEM_WRITE( "_umtx_op_cv_signal(cond)", ARG1, sizeof(struct vki_ucond) ); | |
e2e5d75f PF |
4590 | break; |
4591 | case VKI_UMTX_OP_CV_BROADCAST: | |
76d6b459 PF |
4592 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_BROADCAST, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4593 | PRE_REG_READ2(long, "_umtx_op_cv_broadcast", | |
4594 | struct ucond *, obj, int, op); | |
4595 | PRE_MEM_READ( "_umtx_op_cv_broadcast(cond)", ARG1, sizeof(struct vki_ucond) ); | |
4596 | PRE_MEM_WRITE( "_umtx_op_cv_broadcast(cond)", ARG1, sizeof(struct vki_ucond) ); | |
e2e5d75f PF |
4597 | break; |
4598 | case VKI_UMTX_OP_WAIT_UINT: | |
76d6b459 PF |
4599 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT_UINT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4600 | PRE_REG_READ5(long, "_umtx_op_wait_uint", | |
4601 | int *, obj, int, op, unsigned long, id, | |
4602 | size_t, timeout_wait, struct vki_timespec *, timeout); | |
4603 | PRE_MEM_READ( "_umtx_op_wait(uint)", ARG1, sizeof(int) ); | |
d8cc70f6 | 4604 | if (ARG5) { |
76d6b459 | 4605 | PRE_MEM_READ( "_umtx_op_wait(timespec)", ARG5, ARG4 ); |
d8cc70f6 | 4606 | } |
e2e5d75f PF |
4607 | *flags |= SfMayBlock; |
4608 | break; | |
4609 | case VKI_UMTX_OP_RW_RDLOCK: | |
76d6b459 PF |
4610 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, RW_RDLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4611 | PRE_REG_READ5(long, "_umtx_op_rw_rdlock", | |
4612 | struct urwlock *, obj, int, op, unsigned long, noid, | |
4613 | void *, zero, struct vki_timespec *, timeout); | |
4614 | PRE_MEM_READ( "_umtx_op_rw_rdlock(rw)", ARG1, sizeof(struct vki_urwlock) ); | |
4615 | PRE_MEM_WRITE( "_umtx_op_rw_rdlock(rw)", ARG1, sizeof(struct vki_urwlock) ); | |
e2e5d75f PF |
4616 | *flags |= SfMayBlock; |
4617 | break; | |
4618 | case VKI_UMTX_OP_RW_WRLOCK: | |
76d6b459 PF |
4619 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, RW_WRLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4620 | PRE_REG_READ5(long, "_umtx_op_rw_wrlock", | |
4621 | struct urwlock *, obj, int, op, unsigned long, noid, | |
4622 | void *, zero, struct vki_timespec *, timeout); | |
4623 | PRE_MEM_READ( "_umtx_op_rw_wrlock(rw)", ARG1, sizeof(struct vki_urwlock) ); | |
4624 | PRE_MEM_WRITE( "_umtx_op_rw_wrlock(rw)", ARG1, sizeof(struct vki_urwlock) ); | |
e2e5d75f PF |
4625 | *flags |= SfMayBlock; |
4626 | break; | |
4627 | case VKI_UMTX_OP_RW_UNLOCK: | |
76d6b459 PF |
4628 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, RW_UNLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4629 | PRE_REG_READ2(long, "_umtx_op_rw_unlock", | |
4630 | struct urwlock *, obj, int, op); | |
4631 | PRE_MEM_READ( "_umtx_op_rw_unlock(rw)", ARG1, sizeof(struct vki_urwlock) ); | |
4632 | PRE_MEM_WRITE( "_umtx_op_rw_unlock(rw)", ARG1, sizeof(struct vki_urwlock) ); | |
e2e5d75f PF |
4633 | break; |
4634 | case VKI_UMTX_OP_WAIT_UINT_PRIVATE: | |
76d6b459 PF |
4635 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT_UINT_PRIVATE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4636 | PRE_REG_READ5(long, "_umtx_op_wait_uint_private", | |
4637 | int *, obj, int, op, unsigned long, id, | |
4638 | size_t, timeout_size, struct vki_timespec *, timeout); | |
4639 | PRE_MEM_READ( "_umtx_op_wait_private(uint)", ARG1, sizeof(int) ); | |
d8cc70f6 | 4640 | if (ARG5) { |
76d6b459 | 4641 | PRE_MEM_READ( "_umtx_op_wait_private(umtx_time)", ARG5, ARG4 ); |
d8cc70f6 | 4642 | } |
e2e5d75f PF |
4643 | *flags |= SfMayBlock; |
4644 | break; | |
4645 | case VKI_UMTX_OP_WAKE_PRIVATE: | |
76d6b459 PF |
4646 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAKE_PRIVATE, %" FMT_REGWORD "u)", ARG1, ARG3); |
4647 | PRE_REG_READ3(long, "_umtx_op_wake_private", | |
4648 | vki_uintptr_t *, obj, int, op, int, val); | |
5d387642 | 4649 | // PJF like OP_WAKE contents of obj not read |
76d6b459 | 4650 | //PRE_MEM_READ("_umtx_op_wake_private(obj)", ARG1, sizeof(vki_uintptr_t)); |
e2e5d75f PF |
4651 | break; |
4652 | case VKI_UMTX_OP_MUTEX_WAIT: | |
cae2118d PF |
4653 | // pthread_mutex_lock without prio flags |
4654 | // does not need to be restarted | |
76d6b459 PF |
4655 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4656 | PRE_REG_READ2(long, "_umtx_op_mutex_wait", | |
4657 | struct umutex *, obj, int, op); | |
4658 | PRE_MEM_READ( "_umtx_op_mutex_wait(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
4659 | PRE_MEM_WRITE( "_umtx_op_mutex_wait(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
e2e5d75f PF |
4660 | *flags |= SfMayBlock; |
4661 | break; | |
4662 | case VKI_UMTX_OP_MUTEX_WAKE: | |
cae2118d | 4663 | // marked as deprecated |
76d6b459 PF |
4664 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_WAKE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4665 | PRE_REG_READ2(long, "_umtx_op_mutex_wake", | |
4666 | struct umutex *, obj, int, op); | |
4667 | PRE_MEM_READ( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
4668 | PRE_MEM_WRITE( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
e2e5d75f PF |
4669 | break; |
4670 | case VKI_UMTX_OP_SEM_WAIT: | |
cae2118d | 4671 | // marked as deprecated |
76d6b459 PF |
4672 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4673 | PRE_REG_READ5(long, "_umtx_op_sem_wait", | |
4674 | struct usem *, obj, int, op, unsigned long, id, | |
4675 | size_t, timeout_size, struct vki_timespec *, timeout); | |
4676 | PRE_MEM_READ( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) ); | |
4677 | PRE_MEM_WRITE( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) ); | |
d8cc70f6 | 4678 | if (ARG5) { |
76d6b459 | 4679 | PRE_MEM_READ( "_umtx_op_sem_wait(umtx_time)", ARG5, ARG4 ); |
d8cc70f6 | 4680 | } |
e2e5d75f PF |
4681 | *flags |= SfMayBlock; |
4682 | break; | |
4683 | case VKI_UMTX_OP_SEM_WAKE: | |
cae2118d | 4684 | // marked as deprecated |
76d6b459 PF |
4685 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM_WAKE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4686 | PRE_REG_READ2(long, "_umtx_op_sem_wake", | |
4687 | struct umutex *, obj, int, op); | |
4688 | PRE_MEM_READ( "_umtx_op_sem_wake(mutex)", ARG1, sizeof(struct vki_usem) ); | |
4689 | PRE_MEM_WRITE( "_umtx_op_sem_wake(mutex)", ARG1, sizeof(struct vki_usem) ); | |
e2e5d75f PF |
4690 | break; |
4691 | case VKI_UMTX_OP_NWAKE_PRIVATE: | |
76d6b459 PF |
4692 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, NWAKE_PRIVATE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4693 | PRE_REG_READ3(long, "_umtx_op_nwake_private", | |
4694 | struct umutex *, obj, int, op, int, count); | |
4695 | PRE_MEM_READ( "_umtx_op_nwake_private(mtxs)", ARG1, ARG3 * sizeof(void *) ); | |
4696 | PRE_MEM_WRITE( "_umtx_op_mutex_wake(mtxs)", ARG1, sizeof(struct vki_umutex) ); | |
e2e5d75f PF |
4697 | break; |
4698 | case VKI_UMTX_OP_MUTEX_WAKE2: | |
76d6b459 PF |
4699 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_WAKE2, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4700 | PRE_REG_READ3(long, "_umtx_op_mutex_wake2", | |
4701 | struct umutex *, obj, int, op, unsigned long, flags); | |
4702 | PRE_MEM_READ( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
4703 | PRE_MEM_WRITE( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) ); | |
e2e5d75f PF |
4704 | break; |
4705 | case VKI_UMTX_OP_SEM2_WAIT: | |
76d6b459 PF |
4706 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM2_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4707 | PRE_REG_READ3(long, "_umtx_op_sem2_wake", | |
4708 | struct _usem2 *, obj, int, op, unsigned long, flags); | |
4709 | PRE_MEM_READ( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) ); | |
4710 | PRE_MEM_WRITE( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) ); | |
e2e5d75f PF |
4711 | *flags |= SfMayBlock; |
4712 | break; | |
4713 | case VKI_UMTX_OP_SEM2_WAKE: | |
76d6b459 PF |
4714 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM2_WAKE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4715 | PRE_REG_READ3(long, "_umtx_op_sem2_wake", | |
4716 | struct _usem2 *, obj, int, op, unsigned long, flags); | |
4717 | PRE_MEM_READ( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) ); | |
4718 | PRE_MEM_WRITE( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) ); | |
e2e5d75f PF |
4719 | break; |
4720 | case VKI_UMTX_OP_SHM: | |
76d6b459 PF |
4721 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SHM, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
4722 | PRE_REG_READ4(long, "_umtx_op_shm", | |
4723 | void *, obj, int, op, unsigned long, val, void*, uaddr); | |
e2e5d75f PF |
4724 | break; |
4725 | case VKI_UMTX_OP_ROBUST_LISTS: | |
a836d219 PF |
4726 | // strangely the obj pointer ARG1 isn't used, for instance lin libc |
4727 | // libthr/thread/thr_mutex.c: _umtx_op(NULL, UMTX_OP_ROBUST_LISTS, sizeof(rb), &rb, NULL); | |
4728 | // val (ARG3) ought to be the same as sizeof(struct vki_umtx_robust_lists_params) | |
4729 | // strangely the kernel returns EINVAL if size is larger than sizeof(struct vki_umtx_robust_lists_params) | |
4730 | // (which seems relatively harmless) | |
4731 | // but not if it is smaller (definitely dangerous, probably an overrun) | |
4732 | if (ARG3 < sizeof(struct vki_umtx_robust_lists_params)) { | |
4733 | VG_(umsg)("WARNING: _umtx_op_tobust_lists size is smaller than sizeof(struct umtx_robust_lists_params).\n"); | |
d8cc70f6 | 4734 | } |
76d6b459 | 4735 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, ROBUST_LISTS, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5); |
a836d219 PF |
4736 | PRE_REG_READ4(long, "_umtx_op_robust_lists", |
4737 | void*, obj, int, op, unsigned long, val, struct umtx_robust_lists*, uaddr); | |
4738 | PRE_MEM_READ( "_umtx_op_robust_lists(robust_lists)", ARG4, ARG3 ); | |
e2e5d75f | 4739 | break; |
32ca31e9 | 4740 | #if (FREEBSD_VERS >= FREEBSD_13_3) |
e6ee535c PF |
4741 | case VKI_UMTX_OP_GET_MIN_TIMEOUT: |
4742 | PRINT( "sys__umtx_op ( GET_MIN_TIMEOUT, %#" FMT_REGWORD "x)", ARG4); | |
4743 | // bit of a pain just reads args 2 and 4 | |
4744 | if (VG_(tdict).track_pre_reg_read) { | |
4745 | PRRSN; | |
4746 | PRA2("_umtx_op_get_min_timeout",int,op); | |
4747 | PRA4("_umtx_op_get_min_timeout",long int*,timeout); | |
4748 | } | |
4749 | PRE_MEM_WRITE( "_umtx_op_get_min_timout(uaddr)", ARG4, sizeof(long int) ); | |
4750 | break; | |
4751 | case VKI_UMTX_OP_SET_MIN_TIMEOUT: | |
4752 | PRINT( "sys__umtx_op ( SET_MIN_TIMEOUT, %" FMT_REGWORD "u)", ARG3); | |
4753 | // bit of a pain just reads args 2 and 3 | |
4754 | if (VG_(tdict).track_pre_reg_read) { | |
4755 | PRRSN; | |
4756 | PRA2("_umtx_op_set_min_timeout",int,op); | |
4757 | PRA3("_umtx_op_set_min_timeout",unsigned long,timeout); | |
4758 | } | |
4759 | break; | |
4760 | #endif | |
e2e5d75f PF |
4761 | default: |
4762 | VG_(umsg)("WARNING: _umtx_op unsupported value.\n"); | |
76d6b459 | 4763 | PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u(UNKNOWN), %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4, ARG5); |
e2e5d75f PF |
4764 | break; |
4765 | } | |
4766 | } | |
4767 | ||
4768 | POST(sys__umtx_op) | |
4769 | { | |
76d6b459 | 4770 | switch(ARG2) { |
e2e5d75f | 4771 | case VKI_UMTX_OP_LOCK: |
e2e5d75f | 4772 | case VKI_UMTX_OP_UNLOCK: |
227fa1d5 | 4773 | if (SUCCESS) { |
76d6b459 | 4774 | POST_MEM_WRITE( ARG1, sizeof(struct vki_umtx) ); |
227fa1d5 | 4775 | } |
e2e5d75f PF |
4776 | break; |
4777 | case VKI_UMTX_OP_WAIT: | |
4778 | case VKI_UMTX_OP_WAKE: | |
4779 | case VKI_UMTX_OP_WAIT_UINT: | |
4780 | case VKI_UMTX_OP_WAIT_UINT_PRIVATE: | |
4781 | case VKI_UMTX_OP_WAKE_PRIVATE: | |
4782 | break; | |
4783 | case VKI_UMTX_OP_MUTEX_TRYLOCK: | |
4784 | case VKI_UMTX_OP_MUTEX_LOCK: | |
4785 | case VKI_UMTX_OP_MUTEX_UNLOCK: | |
76d6b459 PF |
4786 | case VKI_UMTX_OP_MUTEX_WAIT: /* Sets/clears contested bits */ |
4787 | case VKI_UMTX_OP_MUTEX_WAKE: /* Sets/clears contested bits */ | |
227fa1d5 | 4788 | if (SUCCESS) { |
76d6b459 | 4789 | POST_MEM_WRITE( ARG1, sizeof(vki_uintptr_t) ); |
227fa1d5 | 4790 | } |
e2e5d75f PF |
4791 | break; |
4792 | case VKI_UMTX_OP_SET_CEILING: | |
4793 | if (SUCCESS) { | |
76d6b459 | 4794 | POST_MEM_WRITE( ARG1, sizeof(struct vki_umutex) ); |
227fa1d5 | 4795 | if (ARG4) { |
76d6b459 | 4796 | POST_MEM_WRITE( ARG4, sizeof(vki_uint32_t) ); |
227fa1d5 | 4797 | } |
e2e5d75f PF |
4798 | } |
4799 | break; | |
4800 | case VKI_UMTX_OP_CV_WAIT: | |
4801 | if (SUCCESS) { | |
76d6b459 PF |
4802 | POST_MEM_WRITE( ARG1, sizeof(struct vki_ucond) ); |
4803 | POST_MEM_WRITE( ARG4, sizeof(struct vki_umutex) ); | |
e2e5d75f PF |
4804 | } |
4805 | break; | |
4806 | case VKI_UMTX_OP_CV_SIGNAL: | |
e2e5d75f PF |
4807 | case VKI_UMTX_OP_CV_BROADCAST: |
4808 | if (SUCCESS) { | |
76d6b459 | 4809 | POST_MEM_WRITE( ARG1, sizeof(struct vki_ucond) ); |
e2e5d75f PF |
4810 | } |
4811 | break; | |
4812 | case VKI_UMTX_OP_RW_RDLOCK: | |
4813 | case VKI_UMTX_OP_RW_WRLOCK: | |
4814 | case VKI_UMTX_OP_RW_UNLOCK: | |
4815 | if (SUCCESS) { | |
76d6b459 | 4816 | POST_MEM_WRITE( ARG1, sizeof(struct vki_urwlock) ); |
e2e5d75f PF |
4817 | } |
4818 | break; | |
4819 | case VKI_UMTX_OP_SEM2_WAIT: | |
4820 | case VKI_UMTX_OP_SEM2_WAKE: | |
4821 | if (SUCCESS) { | |
76d6b459 | 4822 | POST_MEM_WRITE( ARG1, sizeof(struct vki_usem2) ); |
e2e5d75f PF |
4823 | } |
4824 | break; | |
4825 | case VKI_UMTX_OP_SHM: | |
4826 | case VKI_UMTX_OP_ROBUST_LISTS: | |
e6ee535c | 4827 | break; |
32ca31e9 | 4828 | #if (FREEBSD_VERS >= FREEBSD_13_3) |
e6ee535c PF |
4829 | case VKI_UMTX_OP_GET_MIN_TIMEOUT: |
4830 | POST_MEM_WRITE( ARG4, sizeof(long int) ); | |
4831 | break; | |
4832 | case VKI_UMTX_OP_SET_MIN_TIMEOUT: | |
4833 | break; | |
4834 | #endif | |
e2e5d75f PF |
4835 | default: |
4836 | break; | |
4837 | } | |
4838 | } | |
4839 | ||
4840 | // SYS_thr_new 455 | |
4841 | // x86/amd64 | |
4842 | ||
4843 | // SYS_sigqueue 456 | |
4844 | // int sigqueue(pid_t pid, int signo, const union sigval value); | |
4845 | PRE(sys_sigqueue) | |
4846 | { | |
76d6b459 PF |
4847 | PRINT("sys_sigqueue ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", |
4848 | SARG1,SARG2,ARG3); | |
4849 | PRE_REG_READ3(int, "sigqueue", vki_pid_t, pid, int, signo, const union vki_sigval, value); | |
e2e5d75f PF |
4850 | } |
4851 | ||
4852 | // SYS_kmq_open 457 | |
4853 | // mqd_t mq_open(const char *name, int oflag, ...); | |
76d6b459 | 4854 | // int kmq_open(_In_z_ const char *path, int flags, mode_t mode, _In_opt_ const struct mq_attr *attr); |
e2e5d75f PF |
4855 | PRE(sys_kmq_open) |
4856 | { | |
4857 | if (ARG2 & VKI_O_CREAT) { | |
76d6b459 PF |
4858 | PRINT("sys_kmq_open( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu, %#" FMT_REGWORD "x )", |
4859 | ARG1,(char *)ARG1,ARG2,(vki_mode_t)ARG3,ARG4); | |
4860 | PRE_REG_READ4(long, "mq_open", | |
4861 | const char *, name, int, oflag, vki_mode_t, mode, | |
4862 | struct mq_attr *, attr); | |
e2e5d75f PF |
4863 | } else { |
4864 | PRINT("sys_kmq_open( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu)", | |
76d6b459 PF |
4865 | ARG1,(char *)ARG1,ARG2,(vki_mode_t)ARG3); |
4866 | PRE_REG_READ3(long, "mq_open", | |
4867 | const char *, name, int, oflag, vki_mode_t, mode); | |
e2e5d75f | 4868 | } |
76d6b459 | 4869 | PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 ); |
e2e5d75f PF |
4870 | if (ARG2 & VKI_O_CREAT) { |
4871 | PRE_MEM_READ("mq_open(attr)", ARG4, sizeof(struct vki_mq_attr)); | |
76d6b459 PF |
4872 | if (ML_(safe_to_deref)((struct vki_mq_attr *)ARG4, sizeof(struct vki_mq_attr))) { |
4873 | const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4; | |
4874 | PRE_MEM_READ("mq_open(attr->mq_maxmsg)", | |
4875 | (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) ); | |
4876 | PRE_MEM_READ("mq_open(attr->mq_msgsize)", | |
4877 | (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) ); | |
e2e5d75f PF |
4878 | } |
4879 | } | |
4880 | } | |
4881 | ||
4882 | POST(sys_kmq_open) | |
4883 | { | |
4884 | vg_assert(SUCCESS); | |
4885 | if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) { | |
4886 | VG_(close)(RES); | |
76d6b459 | 4887 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f | 4888 | } else { |
227fa1d5 | 4889 | if (VG_(clo_track_fds)) { |
e2e5d75f | 4890 | ML_(record_fd_open_with_given_name)(tid, RES, (const HChar*)ARG1); |
227fa1d5 | 4891 | } |
e2e5d75f PF |
4892 | } |
4893 | } | |
4894 | ||
4895 | // SYS_kmq_setattr 458 | |
4896 | // int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat, | |
4897 | // struct mq_attr *restrict omqstat); | |
4898 | PRE(sys_kmq_setattr) | |
4899 | { | |
76d6b459 PF |
4900 | PRINT("sys_kmq_getattr( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3 ); |
4901 | PRE_REG_READ3(int, "mq_setattr", | |
4902 | vki_mqd_t, mqdes, const struct mq_attr *, mqstat, | |
4903 | struct mq_attr *, omqstat); | |
e2e5d75f | 4904 | if (!ML_(fd_allowed)(ARG1, "mq_getattr", tid, False)) { |
76d6b459 | 4905 | SET_STATUS_Failure( VKI_EBADF ); |
e2e5d75f | 4906 | } else { |
76d6b459 PF |
4907 | if (ML_(safe_to_deref)((struct vki_mq_attr *)ARG2, sizeof(struct vki_mq_attr))) { |
4908 | const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2; | |
4909 | PRE_MEM_READ( "mq_setattr(mqstat->mq_flags)", | |
4910 | (Addr)&attr->mq_flags, sizeof(attr->mq_flags) ); | |
e2e5d75f | 4911 | } |
76d6b459 PF |
4912 | PRE_MEM_WRITE( "mq_setattr(omqstat)", ARG3, |
4913 | sizeof(struct vki_mq_attr) ); | |
e2e5d75f PF |
4914 | } |
4915 | } | |
4916 | ||
4917 | // SYS_kmq_timedreceive 459 | |
4918 | // ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, | |
76d6b459 | 4919 | // unsigned *msg_prio, const struct timespec *abs_timeout); |
e2e5d75f PF |
4920 | PRE(sys_kmq_timedreceive) |
4921 | { | |
4922 | *flags |= SfMayBlock; | |
76d6b459 PF |
4923 | PRINT("sys_kmq_timedreceive( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", |
4924 | ARG1,ARG2,(ULong)ARG3,ARG4,ARG5); | |
4925 | PRE_REG_READ5(ssize_t, "mq_timedreceive", | |
4926 | vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len, | |
4927 | unsigned int *, msg_prio, | |
4928 | const struct timespec *, abs_timeout); | |
e2e5d75f | 4929 | if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) { |
76d6b459 | 4930 | SET_STATUS_Failure( VKI_EBADF ); |
e2e5d75f | 4931 | } else { |
76d6b459 | 4932 | PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 ); |
227fa1d5 | 4933 | if (ARG4 != 0) { |
76d6b459 PF |
4934 | PRE_MEM_WRITE( "mq_timedreceive(msg_prio)", |
4935 | ARG4, sizeof(unsigned int) ); | |
227fa1d5 PF |
4936 | } |
4937 | if (ARG5 != 0) { | |
76d6b459 PF |
4938 | PRE_MEM_READ( "mq_timedreceive(abs_timeout)", |
4939 | ARG5, sizeof(struct vki_timespec) ); | |
227fa1d5 | 4940 | } |
e2e5d75f PF |
4941 | } |
4942 | } | |
4943 | ||
4944 | POST(sys_kmq_timedreceive) | |
4945 | { | |
76d6b459 | 4946 | POST_MEM_WRITE( ARG2, ARG3 ); |
227fa1d5 | 4947 | if (ARG4 != 0) { |
76d6b459 | 4948 | POST_MEM_WRITE( ARG4, sizeof(unsigned int) ); |
227fa1d5 | 4949 | } |
e2e5d75f PF |
4950 | } |
4951 | ||
4952 | // SYS_kmq_timedsend 460 | |
4953 | // int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, | |
4954 | // unsigned msg_prio, const struct timespec *abs_timeout); | |
4955 | PRE(sys_kmq_timedsend) | |
4956 | { | |
4957 | *flags |= SfMayBlock; | |
76d6b459 PF |
4958 | PRINT("sys_kmq_timedsend ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %llu, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", |
4959 | ARG1,ARG2,(ULong)ARG3,ARG4,ARG5); | |
4960 | PRE_REG_READ5(int, "mq_timedsend", | |
4961 | vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len, | |
4962 | unsigned int, msg_prio, const struct timespec *, abs_timeout); | |
e2e5d75f | 4963 | if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) { |
76d6b459 | 4964 | SET_STATUS_Failure( VKI_EBADF ); |
e2e5d75f | 4965 | } else { |
76d6b459 | 4966 | PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 ); |
227fa1d5 | 4967 | if (ARG5 != 0) { |
76d6b459 PF |
4968 | PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5, |
4969 | sizeof(struct vki_timespec) ); | |
227fa1d5 | 4970 | } |
e2e5d75f PF |
4971 | } |
4972 | } | |
4973 | ||
4974 | // SYS_kmq_notify 461 | |
4975 | // int mq_notify(mqd_t mqdes, const struct sigevent *notification); | |
4976 | PRE(sys_kmq_notify) | |
4977 | { | |
76d6b459 PF |
4978 | PRINT("sys_kmq_notify( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2 ); |
4979 | PRE_REG_READ2(int, "mq_notify", | |
4980 | vki_mqd_t, mqdes, const struct sigevent *, notification); | |
227fa1d5 | 4981 | if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False)) { |
76d6b459 PF |
4982 | SET_STATUS_Failure( VKI_EBADF ); |
4983 | } | |
4984 | else if (ARG2 != 0) { | |
4985 | PRE_MEM_READ( "mq_notify(notification)", | |
4986 | ARG2, sizeof(struct vki_sigevent) ); | |
227fa1d5 | 4987 | } |
e2e5d75f PF |
4988 | } |
4989 | ||
4990 | // SYS_kmq_unlink 462 | |
4991 | // int kmq_unlink(const char *path); | |
4992 | PRE(sys_kmq_unlink) | |
4993 | { | |
76d6b459 PF |
4994 | PRINT("sys_kmq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1); |
4995 | PRE_REG_READ1(int, "mq_unlink", const char *, name); | |
4996 | PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 ); | |
e2e5d75f PF |
4997 | } |
4998 | ||
4999 | // SYS_abort2 463 | |
5000 | // void abort2(const char *why, int nargs, void **args); | |
5001 | PRE(sys_abort2) | |
5002 | { | |
76d6b459 PF |
5003 | PRINT( "sys_abort2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1, SARG2, ARG3 ); |
5004 | PRE_REG_READ3(void, "abort2", const char *, why, int, nargs, void **, args); | |
e2e5d75f | 5005 | // max length of 'why' is 128 |
76d6b459 | 5006 | PRE_MEM_RASCIIZ( "abort2(why)", ARG2); |
e2e5d75f | 5007 | // max val for nargs is 16 |
76d6b459 | 5008 | PRE_MEM_READ("abort2(args", ARG3, ARG2*sizeof(void*)); |
e2e5d75f PF |
5009 | } |
5010 | ||
5011 | // SYS_thr_set_name 464 | |
5012 | // int thr_set_name(long id, const char *name); | |
5013 | PRE(sys_thr_set_name) | |
5014 | { | |
76d6b459 PF |
5015 | PRINT( "sys_thr_set_name ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2 ); |
5016 | PRE_REG_READ2(int, "thr_set_name", long, id, const char *, name); | |
5017 | PRE_MEM_RASCIIZ( "thr_set_name(name)", ARG2); | |
e2e5d75f PF |
5018 | |
5019 | if (ML_(safe_to_deref)((void*)ARG2, 1)) { | |
76d6b459 PF |
5020 | const HChar* new_name = (const HChar*) (Addr)ARG2; |
5021 | ThreadState* tst = VG_(get_ThreadState)(tid); | |
5022 | SizeT new_len = VG_(strnlen)(new_name, VKI_MAXCOMLEN+1); | |
5023 | tst->thread_name = VG_(realloc)("syswrap.thr_set_name", tst->thread_name, new_len + 1); | |
e2e5d75f PF |
5024 | VG_(strlcpy)(tst->thread_name, new_name, new_len + 1); |
5025 | } | |
5026 | } | |
5027 | ||
5028 | // SYS_aio_fsync 465 | |
5029 | // int aio_fsync(int op, struct aiocb *iocb); | |
5030 | PRE(sys_aio_fsync) | |
5031 | { | |
76d6b459 PF |
5032 | PRINT("aio_fsync ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,ARG2); |
5033 | PRE_REG_READ2(int, "aio_fsync", int, op, struct vki_aiocb *, iocb); | |
5034 | PRE_MEM_READ( "aio_fsync(iocb)", ARG2, sizeof(struct vki_aiocb) ); | |
e2e5d75f PF |
5035 | } |
5036 | ||
5037 | // SYS_rtprio_thread 466 | |
5038 | // int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp); | |
5039 | PRE(sys_rtprio_thread) | |
5040 | { | |
76d6b459 PF |
5041 | PRINT( "sys_rtprio_thread ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3 ); |
5042 | PRE_REG_READ3(int, "rtprio_thread", | |
5043 | int, function, __vki_lwpid_t, lwpid, struct vki_rtprio *, rtp); | |
e2e5d75f | 5044 | if (ARG1 == VKI_RTP_SET) { |
76d6b459 | 5045 | PRE_MEM_READ( "rtprio_thread(rtp#set)", ARG3, sizeof(struct vki_rtprio)); |
e2e5d75f | 5046 | } else if (ARG1 == VKI_RTP_LOOKUP) { |
76d6b459 | 5047 | PRE_MEM_WRITE( "rtprio_thread(rtp#lookup)", ARG3, sizeof(struct vki_rtprio)); |
e2e5d75f PF |
5048 | } else { |
5049 | /* PHK ?? */ | |
5050 | } | |
5051 | } | |
5052 | ||
5053 | POST(sys_rtprio_thread) | |
5054 | { | |
227fa1d5 | 5055 | if (ARG1 == VKI_RTP_LOOKUP && RES == 0) { |
76d6b459 | 5056 | POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio)); |
227fa1d5 | 5057 | } |
e2e5d75f PF |
5058 | } |
5059 | ||
5060 | // SYS_sctp_peeloff 471 | |
5061 | // int sctp_peeloff(int s, sctp_assoc_t id); | |
5062 | // @todo | |
5063 | ||
76d6b459 | 5064 | |
e2e5d75f PF |
5065 | // SYS_sctp_generic_sendmsg 472 |
5066 | // int sctp_generic_sendmsg(int s, void *msg, int msglen, struct sockaddr *to, | |
76d6b459 | 5067 | // socklen_t len, struct sctp_sndrcvinfo *sinfo, int flags); |
5b524084 PF |
5068 | // |
5069 | // Not called directly from libc | |
5070 | PRE(sys_sctp_generic_sendmsg) | |
5071 | { | |
5072 | *flags |= SfMayBlock; | |
76d6b459 PF |
5073 | PRINT("sys_sctp_generic_sendmsg ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )",SARG1,ARG2,SARG3,ARG4,SARG5,ARG6,SARG7); |
5074 | PRE_REG_READ7(ssize_t, "sctp_generic_sendmsg", | |
5075 | int, s, void *, msg, int, msglen, | |
5076 | struct sockaddr *, to, socklen_t, len, | |
5077 | struct sctp_sndrcvinfo *, sinfo, int, flags); | |
5b524084 | 5078 | |
76d6b459 | 5079 | PRE_MEM_READ( "sctp_generic_sendmsg(msg)", ARG2, ARG3); |
e2e5d75f | 5080 | |
76d6b459 | 5081 | ML_(pre_mem_read_sockaddr) (tid, "sctp_generic_sendmsg(to)", (struct vki_sockaddr *)ARG4, ARG5); |
5b524084 | 5082 | |
227fa1d5 | 5083 | if (ARG6 != (Addr)NULL) { |
76d6b459 | 5084 | PRE_MEM_READ( "sctp_generic_sendmsg(sinfo)", ARG6, sizeof(struct vki_sctp_sndrcvinfo)); |
227fa1d5 | 5085 | } |
5b524084 | 5086 | } |
e2e5d75f PF |
5087 | |
5088 | // SYS_sctp_generic_sendmsg_iov 473 | |
5089 | // int sctp_generic_sendmsg_iov(int s, struct iovec *iov, int iovlen, | |
76d6b459 | 5090 | // struct sockaddr *to, struct sctp_sndrcvinfo *sinfo, int flags); |
e2e5d75f PF |
5091 | // @todo |
5092 | ||
5093 | // SYS_sctp_generic_recvmsg 474 | |
5094 | // int sctp_generic_recvmsg(int s, struct iovec *iov, int iovlen, | |
5095 | // struct sockaddr *from, socklen_t *fromlen, | |
5096 | // struct sctp_sndrcvinfo *sinfo, int *msgflags); | |
5b524084 PF |
5097 | // |
5098 | // Not called directly from libc | |
5099 | PRE(sys_sctp_generic_recvmsg) | |
5100 | { | |
5101 | *flags |= SfMayBlock; | |
76d6b459 PF |
5102 | PRINT("sys_sctp_generic_recvmsg ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,SARG3,ARG4,ARG5,ARG6,ARG7); |
5103 | PRE_REG_READ7(ssize_t, "sctp_generic_recvmsg", | |
5104 | int, s, struct iovec *, iov, int, iovlen, | |
5105 | struct sockaddr *, from, socklen_t *, fromlen, | |
5106 | struct sctp_sndrcvinfo *, sinfo, int *, msgflags); | |
5b524084 PF |
5107 | |
5108 | // in the sctp_recvmsg libc wrapper this is always 1 | |
5109 | if ((Int)ARG3 > 0) { | |
76d6b459 | 5110 | PRE_MEM_READ( "sctp_generic_recvmsg(iov)", ARG2, ARG3 * sizeof(struct vki_iovec) ); |
5b524084 PF |
5111 | } |
5112 | if (ML_(safe_to_deref)((const void*)ARG2, ARG3 * sizeof(struct vki_iovec))) { | |
5113 | struct vki_iovec* iovec = (struct vki_iovec*)ARG2; | |
76d6b459 | 5114 | PRE_MEM_WRITE("sctp_generic_recvmsg(iov.iov_base)", (Addr)iovec->iov_base, iovec->iov_len); |
5b524084 PF |
5115 | } |
5116 | ||
227fa1d5 | 5117 | if (ARG4 != (Addr)NULL) { |
76d6b459 | 5118 | ML_(buf_and_len_pre_check) (tid, ARG4, ARG5, |
e6ee535c | 5119 | "sctp_generic_recvmsg(from)", |
76d6b459 | 5120 | "sctp_generic_recvmsg(fromlen_in)"); |
227fa1d5 | 5121 | } |
5b524084 | 5122 | |
227fa1d5 | 5123 | if (ARG6 != (Addr)NULL) { |
76d6b459 | 5124 | PRE_MEM_WRITE("sctp_generic_recvmsg(sinfo)", ARG6, sizeof(struct vki_sctp_sndrcvinfo)); |
227fa1d5 | 5125 | } |
5b524084 | 5126 | |
227fa1d5 | 5127 | if (ARG7 != (Addr)NULL) { |
5b524084 | 5128 | PRE_MEM_WRITE("sctp_generic_recvmsg(msgflags)", ARG7, sizeof(int)); |
227fa1d5 | 5129 | } |
5b524084 PF |
5130 | } |
5131 | ||
5132 | POST(sys_sctp_generic_recvmsg) | |
5133 | { | |
5134 | vg_assert(SUCCESS); | |
5135 | struct vki_iovec* iovec = (struct vki_iovec*)ARG2; | |
5136 | POST_MEM_WRITE((Addr)iovec->iov_base, iovec->iov_len); | |
5137 | ||
76d6b459 | 5138 | POST_MEM_WRITE( ARG2, ARG3*sizeof(struct vki_iovec) ); |
5b524084 | 5139 | |
227fa1d5 | 5140 | if (ARG4 != (Addr)NULL) { |
76d6b459 PF |
5141 | ML_(buf_and_len_post_check) (tid, VG_(mk_SysRes_Success)(RES), ARG4, ARG5, |
5142 | "sctp_generic_recvmsg(fromlen_out)"); | |
227fa1d5 | 5143 | } |
5b524084 | 5144 | |
227fa1d5 | 5145 | if (ARG6 != (Addr)NULL) { |
5b524084 | 5146 | POST_MEM_WRITE(ARG6, sizeof(struct vki_sctp_sndrcvinfo)); |
227fa1d5 | 5147 | } |
5b524084 | 5148 | |
227fa1d5 | 5149 | if (ARG7 != (Addr)NULL) { |
5b524084 | 5150 | POST_MEM_WRITE(ARG7, sizeof(int)); |
227fa1d5 | 5151 | } |
5b524084 | 5152 | } |
e2e5d75f PF |
5153 | |
5154 | // SYS_pread 475 | |
5155 | // x86/amd64 | |
5156 | ||
5157 | // SYS_pwrite 476 | |
5158 | // x86/amd64 | |
5159 | ||
5160 | // SYS_mmap 477 | |
5161 | // x86/amd64 | |
5162 | ||
5163 | // SYS_lseek 478 | |
5164 | // x86/amd64 | |
5165 | ||
76d6b459 PF |
5166 | //SYS_truncate 479 |
5167 | // x86/amd64 | |
e2e5d75f PF |
5168 | |
5169 | // SYS_ftruncate 480 | |
5170 | // x86/amd64 | |
5171 | ||
5172 | // SYS_thr_kill2 481 | |
5173 | // int thr_kill2(pid_t pid, long id, int sig); | |
5174 | PRE(sys_thr_kill2) | |
5175 | { | |
76d6b459 | 5176 | PRINT("sys_thr_kill2 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); |
e2e5d75f PF |
5177 | PRE_REG_READ3(int, "thr_kill2", pid_t, pid, long, tid, int, sig); |
5178 | if (!ML_(client_signal_OK)(ARG3)) { | |
76d6b459 | 5179 | SET_STATUS_Failure( VKI_EINVAL ); |
e2e5d75f PF |
5180 | return; |
5181 | } | |
5182 | ||
5183 | /* Check to see if this kill gave us a pending signal */ | |
5184 | *flags |= SfPollAfter; | |
5185 | ||
227fa1d5 | 5186 | if (VG_(clo_trace_signals)) { |
76d6b459 PF |
5187 | VG_(message)(Vg_DebugMsg, "thr_kill2: sending signal %lu to pid %lu/%lu\n", |
5188 | ARG3, ARG1, ARG2); | |
227fa1d5 | 5189 | } |
e2e5d75f PF |
5190 | |
5191 | /* If we're sending SIGKILL, check to see if the target is one of | |
5192 | our threads and handle it specially. */ | |
5193 | if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) { | |
5194 | SET_STATUS_Success(0); | |
5195 | return; | |
5196 | } | |
5197 | ||
5198 | /* Ask to handle this syscall via the slow route, since that's the | |
5199 | only one that sets tst->status to VgTs_WaitSys. If the result | |
5200 | of doing the syscall is an immediate run of | |
5201 | async_signalhandler() in m_signals, then we need the thread to | |
5202 | be properly tidied away. I have the impression the previous | |
5203 | version of this wrapper worked on x86/amd64 only because the | |
5204 | kernel did not immediately deliver the async signal to this | |
5205 | thread (on ppc it did, which broke the assertion re tst->status | |
5206 | at the top of async_signalhandler()). */ | |
5207 | *flags |= SfMayBlock; | |
5208 | } | |
5209 | ||
5210 | POST(sys_thr_kill2) | |
5211 | { | |
227fa1d5 | 5212 | if (VG_(clo_trace_signals)) { |
e2e5d75f PF |
5213 | VG_(message)(Vg_DebugMsg, "thr_kill2: sent signal %lu to pid %lu/%lu\n", |
5214 | ARG3, ARG1, ARG2); | |
227fa1d5 | 5215 | } |
e2e5d75f PF |
5216 | } |
5217 | ||
5218 | // SYS_shm_open 482 | |
5219 | // int shm_open(const char *path, int flags, mode_t mode); | |
5220 | PRE(sys_shm_open) | |
5221 | { | |
76d6b459 PF |
5222 | PRE_REG_READ3(int, "shm_open", |
5223 | const char *, path, int, flags, vki_mode_t, mode); | |
e2e5d75f | 5224 | if (ARG1 == VKI_SHM_ANON) { |
76d6b459 | 5225 | PRINT("sys_shm_open(%#" FMT_REGWORD "x(SHM_ANON), %" FMT_REGWORD "u, %hu)", ARG1, ARG2, (vki_mode_t)ARG3); |
e2e5d75f | 5226 | } else { |
76d6b459 PF |
5227 | PRINT("sys_shm_open(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu)", ARG1, (HChar *)ARG1, ARG2, (vki_mode_t)ARG3); |
5228 | PRE_MEM_RASCIIZ( "shm_open(path)", ARG1 ); | |
e2e5d75f PF |
5229 | } |
5230 | *flags |= SfMayBlock; | |
5231 | } | |
5232 | ||
5233 | POST(sys_shm_open) | |
5234 | { | |
5235 | vg_assert(SUCCESS); | |
5236 | if (!ML_(fd_allowed)(RES, "shm_open", tid, True)) { | |
5237 | VG_(close)(RES); | |
76d6b459 | 5238 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f | 5239 | } else { |
227fa1d5 | 5240 | if (VG_(clo_track_fds)) { |
e2e5d75f | 5241 | ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); |
227fa1d5 | 5242 | } |
e2e5d75f PF |
5243 | } |
5244 | } | |
5245 | ||
5246 | // SYS_shm_unlink 483 | |
5247 | // int shm_unlink(const char *path); | |
5248 | PRE(sys_shm_unlink) | |
5249 | { | |
76d6b459 PF |
5250 | PRINT("sys_shm_unlink(%#" FMT_REGWORD "x(%s))", ARG1, (char *)ARG1); |
5251 | PRE_REG_READ1(int, "shm_unlink", | |
5252 | const char *, path); | |
e2e5d75f | 5253 | |
76d6b459 | 5254 | PRE_MEM_RASCIIZ( "shm_unlink(path)", ARG1 ); |
e2e5d75f PF |
5255 | |
5256 | *flags |= SfMayBlock; | |
5257 | } | |
5258 | ||
5259 | // SYS_cpuset 484 | |
5260 | // int cpuset(cpusetid_t *setid); | |
5261 | PRE(sys_cpuset) | |
5262 | { | |
5263 | PRINT("sys_cpuset ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 5264 | PRE_REG_READ1(int, "cpuset", vki_cpusetid_t *, setid); |
e2e5d75f PF |
5265 | PRE_MEM_WRITE("cpuset(setid)", ARG1, sizeof(vki_cpusetid_t)); |
5266 | } | |
5267 | ||
76d6b459 PF |
5268 | POST(sys_cpuset) |
5269 | { | |
5270 | POST_MEM_WRITE(ARG1, sizeof(vki_cpusetid_t)); | |
5271 | } | |
e2e5d75f PF |
5272 | |
5273 | // SYS_cpuset_setid 485 | |
5274 | // amd64 / x86 | |
5275 | ||
5276 | // SYS_cpuset_getid 486 | |
5277 | // amd64 / x86 | |
5278 | ||
5279 | // SYS_cpuset_getaffinity 487 | |
5280 | // amd64 / x86 | |
5281 | ||
5282 | // SYS_cpuset_setaffinity 488 | |
5283 | // amd64 / x86 | |
5284 | ||
5285 | // SYS_faccessat 489 | |
5286 | // int faccessat(int fd, const char *path, int mode, int flag); | |
5287 | PRE(sys_faccessat) | |
5288 | { | |
76d6b459 PF |
5289 | PRINT("sys_faccessat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); |
5290 | PRE_REG_READ3(int, "faccessat", | |
5291 | int, fd, const char *, path, int, flag); | |
5292 | PRE_MEM_RASCIIZ( "faccessat(path)", ARG2 ); | |
e2e5d75f PF |
5293 | } |
5294 | ||
5295 | // SYS_fchmodat 490 | |
5296 | // int fchmodat(int fd, const char *path, mode_t mode, int flag); | |
5297 | PRE(sys_fchmodat) | |
5298 | { | |
76d6b459 PF |
5299 | PRINT("sys_fchmodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); |
5300 | PRE_REG_READ4(int, "fchmodat", | |
5301 | int, fd, const char *, path, vki_mode_t, mode, int, flag); | |
5302 | PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 ); | |
e2e5d75f PF |
5303 | } |
5304 | ||
5305 | // SYS_fchownat 491 | |
5306 | // int fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag); | |
5307 | PRE(sys_fchownat) | |
5308 | { | |
76d6b459 PF |
5309 | PRINT("sys_fchownat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, %" FMT_REGWORD "d )", |
5310 | ARG1,ARG2,(char*)ARG2,ARG3,ARG4, SARG5); | |
5311 | PRE_REG_READ5(int, "fchownat", | |
5312 | int, fd, const char *, path, | |
5313 | vki_uid_t, owner, vki_gid_t, group, int, flag); | |
5314 | PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 ); | |
e2e5d75f PF |
5315 | } |
5316 | ||
5317 | // SYS_fexecve 492 | |
5318 | // int fexecve(int fd, char *const argv[], char *const envp[]); | |
5319 | PRE(sys_fexecve) | |
5320 | { | |
76d6b459 PF |
5321 | PRINT("sys_fexecve ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", |
5322 | SARG1,ARG2,ARG3); | |
5323 | PRE_REG_READ3(int, "fexecve", | |
5324 | int, fd, char * const *, argv, | |
5325 | char * const *, envp); | |
83dda2b7 PF |
5326 | |
5327 | if (!ML_(fd_allowed)(ARG1, "fexecve", tid, False)) { | |
5328 | SET_STATUS_Failure(VKI_EBADF); | |
5329 | return; | |
5330 | } | |
5331 | ||
76d6b459 | 5332 | const HChar *fname; |
83dda2b7 PF |
5333 | |
5334 | if (VG_(resolve_filename)(ARG1, &fname) == False) { | |
5335 | SET_STATUS_Failure(VKI_ENOENT); | |
5336 | return; | |
5337 | } | |
5338 | ||
5339 | struct vg_stat stats; | |
5340 | if (VG_(fstat)(ARG1, &stats) != 0) { | |
5341 | SET_STATUS_Failure(VKI_EACCES); | |
5342 | return; | |
5343 | } | |
5344 | ||
5345 | Int openFlags; | |
5346 | ||
5347 | if (VG_(resolve_filemode)(ARG1, &openFlags) == False) { | |
5348 | SET_STATUS_Failure(VKI_ENOENT); | |
5349 | return; | |
5350 | } | |
5351 | ||
5352 | /* | |
5353 | * openFlags is in kernel FFLAGS format | |
5354 | * (see /usr/include/sys/fcntl.h) | |
5355 | * which alllows us to tell if RDONLY is set | |
5356 | * | |
5357 | */ | |
5358 | ||
5359 | Bool isScript = False; | |
5360 | ||
5361 | SysRes res; | |
76d6b459 PF |
5362 | res = VG_(open)(fname, VKI_O_RDONLY, |
5363 | VKI_S_IRUSR|VKI_S_IRGRP|VKI_S_IROTH); | |
83dda2b7 PF |
5364 | if (sr_isError(res)) { |
5365 | SET_STATUS_Failure(VKI_ENOENT); | |
5366 | return; | |
227fa1d5 PF |
5367 | } |
5368 | ||
5369 | char buf[2]; | |
5370 | VG_(read)((Int)sr_Res(res), buf, 2); | |
5371 | VG_(close)((Int)sr_Res(res)); | |
5372 | if (buf[0] == '#' && buf[1] == '!') { | |
5373 | isScript = True; | |
83dda2b7 PF |
5374 | } |
5375 | ||
5376 | if (isScript) { | |
5377 | if (!(openFlags & VKI_FREAD)) { | |
5378 | SET_STATUS_Failure(VKI_EACCES); | |
5379 | return; | |
5380 | } | |
5381 | } else { | |
5382 | if (!((openFlags & VKI_O_EXEC) || | |
76d6b459 | 5383 | (stats.mode & (VKI_S_IXUSR|VKI_S_IXGRP|VKI_S_IXOTH)))) { |
83dda2b7 PF |
5384 | SET_STATUS_Failure(VKI_EACCES); |
5385 | return; | |
5386 | } | |
5387 | } | |
5388 | ||
5389 | Addr arg_2 = (Addr)ARG2; | |
5390 | Addr arg_3 = (Addr)ARG3; | |
5391 | ||
76d6b459 | 5392 | handle_pre_sys_execve(tid, status, (Addr)fname, arg_2, arg_3, FEXECVE, False); |
e2e5d75f PF |
5393 | } |
5394 | ||
5395 | // SYS_freebsd11_fstatat 493 | |
5396 | // int fstatat(int fd, const char *path, struct stat *sb, int flag); | |
5397 | #if (FREEBSD_VERS >= FREEBSD_12) | |
5398 | PRE(sys_freebsd11_fstatat) | |
5399 | { | |
76d6b459 PF |
5400 | PRINT("sys_freebsd11_fstatat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3); |
5401 | PRE_REG_READ4(int, "fstatat", | |
5402 | int, fd, const char *, path, struct freebsd11_stat *, buf, int, flag); | |
5403 | PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 ); | |
5404 | PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
5405 | } |
5406 | ||
5407 | POST(sys_freebsd11_fstatat) | |
5408 | { | |
76d6b459 | 5409 | POST_MEM_WRITE( ARG3, sizeof(struct vki_freebsd11_stat) ); |
e2e5d75f PF |
5410 | } |
5411 | #else | |
5412 | PRE(sys_fstatat) | |
5413 | { | |
76d6b459 PF |
5414 | PRINT("sys_fstatat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3); |
5415 | PRE_REG_READ4(int, "fstatat", | |
5416 | int, fd, const char *, path, struct stat *, buf, int, flag); | |
5417 | PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 ); | |
5418 | PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_freebsd11_stat) ); | |
e2e5d75f PF |
5419 | } |
5420 | ||
76d6b459 PF |
5421 | POST(sys_fstatat) |
5422 | { | |
5423 | POST_MEM_WRITE( ARG3, sizeof(struct vki_freebsd11_stat) ); | |
5424 | } | |
e2e5d75f PF |
5425 | #endif |
5426 | ||
5427 | // SYS_futimesat 494 | |
5428 | // int futimesat(int fd, const char *path, const struct timeval times[2]); | |
5429 | PRE(sys_futimesat) | |
5430 | { | |
76d6b459 PF |
5431 | PRINT("sys_futimesat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3); |
5432 | PRE_REG_READ3(int, "futimesat", | |
5433 | int, fd, const char *, path, struct timeval *, times); | |
227fa1d5 | 5434 | if (ARG2 != 0) { |
76d6b459 | 5435 | PRE_MEM_RASCIIZ( "futimesat(path)", ARG2 ); |
227fa1d5 PF |
5436 | } |
5437 | if (ARG3 != 0) { | |
76d6b459 | 5438 | PRE_MEM_READ( "futimesat(times)", ARG3, 2 * sizeof(struct vki_timeval) ); |
227fa1d5 | 5439 | } |
e2e5d75f PF |
5440 | } |
5441 | ||
5442 | // SYS_linkat 495 | |
5443 | // int linkat(int fd1, const char *name1, int fd2, const char *name2, int flag); | |
5444 | PRE(sys_linkat) | |
5445 | { | |
5446 | *flags |= SfMayBlock; | |
76d6b459 PF |
5447 | PRINT("sys_linkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4,ARG5); |
5448 | PRE_REG_READ5(int, "linkat", | |
5449 | int, fd1, const char *, name1, | |
5450 | int, fd2, const char *, name2, | |
5451 | int, flag); | |
5452 | PRE_MEM_RASCIIZ( "linkat(name1)", ARG2); | |
5453 | PRE_MEM_RASCIIZ( "linkat(name2)", ARG4); | |
e2e5d75f PF |
5454 | } |
5455 | ||
5456 | // SYS_mkdirat 496 | |
5457 | // int mkdirat(int fd, const char *path, mode_t mode); | |
5458 | PRE(sys_mkdirat) | |
5459 | { | |
5460 | *flags |= SfMayBlock; | |
76d6b459 PF |
5461 | PRINT("sys_mkdirat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); |
5462 | PRE_REG_READ3(int, "mkdirat", | |
26924849 | 5463 | int, fd, const char *, path, unsigned int, mode); |
76d6b459 | 5464 | PRE_MEM_RASCIIZ( "mkdirat(path)", ARG2 ); |
e2e5d75f PF |
5465 | } |
5466 | ||
5467 | // SYS_mkfifoat 497 | |
5468 | // int mkfifoat(int fd, const char *path, mode_t mode); | |
5469 | PRE(sys_mkfifoat) | |
5470 | { | |
76d6b459 PF |
5471 | PRINT("sys_mkfifoat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", |
5472 | SARG1,ARG2,(HChar*)ARG2,ARG3 ); | |
5473 | PRE_REG_READ3(int, "mkfifoat", | |
5474 | int, fd, const char *, path, vki_mode_t, mode); | |
5475 | PRE_MEM_RASCIIZ( "mkfifoat(path)", ARG2 ); | |
e2e5d75f PF |
5476 | } |
5477 | ||
5478 | // SYS_freebsd11_mknodat 498 | |
5479 | // int mknodat(int fd, const char *path, mode_t mode, dev_t dev); | |
5480 | #if (FREEBSD_VERS >= FREEBSD_12) | |
5481 | PRE(sys_freebsd11_mknodat) | |
5482 | { | |
76d6b459 PF |
5483 | PRINT("sys_freebsd11_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 ); |
5484 | PRE_REG_READ4(long, "mknodat", | |
5485 | int, dfd, const char *, pathname, int, mode, unsigned, dev); | |
5486 | PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 ); | |
e2e5d75f PF |
5487 | } |
5488 | #else | |
5489 | PRE(sys_mknodat) | |
5490 | { | |
76d6b459 PF |
5491 | PRINT("sys_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 ); |
5492 | PRE_REG_READ4(long, "mknodat", | |
5493 | int, dfd, const char *, pathname, int, mode, unsigned, dev); | |
5494 | PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 ); | |
e2e5d75f PF |
5495 | } |
5496 | #endif | |
5497 | ||
5498 | // SYS_openat 499 | |
5499 | // int openat(int fd, const char *path, int flags, ...); | |
5500 | PRE(sys_openat) | |
5501 | { | |
e2e5d75f PF |
5502 | if (ARG3 & VKI_O_CREAT) { |
5503 | // 4-arg version | |
76d6b459 PF |
5504 | PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4); |
5505 | PRE_REG_READ4(int, "openat", | |
5506 | int, fd, const char *, path, int, flags, vki_mode_t, mode); | |
e2e5d75f PF |
5507 | } else { |
5508 | // 3-arg version | |
76d6b459 PF |
5509 | PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3); |
5510 | PRE_REG_READ3(int, "openat", | |
5511 | int, fd, const char *, path, int, flags); | |
e2e5d75f PF |
5512 | } |
5513 | ||
76d6b459 PF |
5514 | if (ARG1 != (unsigned)VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat", tid, False)) { |
5515 | SET_STATUS_Failure( VKI_EBADF ); | |
227fa1d5 | 5516 | } else { |
76d6b459 | 5517 | PRE_MEM_RASCIIZ( "openat(path)", ARG2 ); |
227fa1d5 | 5518 | } |
e2e5d75f PF |
5519 | |
5520 | /* Otherwise handle normally */ | |
5521 | *flags |= SfMayBlock; | |
5522 | } | |
5523 | ||
5524 | POST(sys_openat) | |
5525 | { | |
5526 | vg_assert(SUCCESS); | |
5527 | if (!ML_(fd_allowed)(RES, "openat", tid, True)) { | |
5528 | VG_(close)(RES); | |
76d6b459 | 5529 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f | 5530 | } else { |
227fa1d5 | 5531 | if (VG_(clo_track_fds)) { |
e2e5d75f | 5532 | ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2); |
227fa1d5 | 5533 | } |
e2e5d75f PF |
5534 | } |
5535 | } | |
5536 | ||
5537 | // SYS_readlinkat 500 | |
5538 | // ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, | |
5539 | // size_t bufsize); | |
5540 | PRE(sys_readlinkat) | |
5541 | { | |
76d6b459 | 5542 | Word saved = SYSNO; |
b1aba911 | 5543 | Bool curproc_file = False; |
e2e5d75f | 5544 | |
76d6b459 PF |
5545 | PRINT("sys_readlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4); |
5546 | PRE_REG_READ4(ssize_t, "readlinkat", | |
5547 | int, fd, const char *, path, char *, buf, int, bufsize); | |
5548 | PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 ); | |
5549 | PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 ); | |
e2e5d75f | 5550 | |
b1aba911 | 5551 | if (VG_(have_slash_proc) == True && (Int)ARG1 == VKI_AT_FDCWD) { |
c15993dc PF |
5552 | /* |
5553 | * Handle the case where readlinkat is looking at /proc/curproc/file or | |
5554 | * /proc/<pid>/file. | |
5555 | */ | |
76d6b459 | 5556 | do_readlink((const HChar *)ARG2, (HChar *)ARG3, (SizeT)ARG4, status, &curproc_file); |
b1aba911 PF |
5557 | } |
5558 | ||
5559 | // @todo PJF there is still the case where fd refers to /proc or /proc/pid | |
5560 | // or /proc/curproc and path is relative pid/file, curptoc/file or just file | |
5561 | ||
5562 | if (!curproc_file) { | |
5563 | /* Normal case */ | |
76d6b459 | 5564 | SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4)); |
b1aba911 PF |
5565 | } |
5566 | if (SUCCESS && RES > 0) { | |
76d6b459 | 5567 | POST_MEM_WRITE( ARG3, RES ); |
e2e5d75f PF |
5568 | } |
5569 | } | |
5570 | ||
76d6b459 PF |
5571 | POST(sys_readlinkat) |
5572 | { | |
5573 | POST_MEM_WRITE( ARG3, RES ); | |
5574 | } | |
e2e5d75f PF |
5575 | |
5576 | // SYS_renameat 501 | |
5577 | // int renameat(int fromfd, const char *from, int tofd, const char *to); | |
5578 | PRE(sys_renameat) | |
5579 | { | |
76d6b459 PF |
5580 | PRINT("sys_renameat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s) )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4); |
5581 | PRE_REG_READ4(int, "renameat", | |
5582 | int, fromfd, const char *, from, | |
5583 | int, tofd, const char *, to); | |
5584 | PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 ); | |
5585 | PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 ); | |
e2e5d75f PF |
5586 | } |
5587 | ||
5588 | // SYS_symlinkat 502 | |
5589 | // int symlinkat(const char *name1, int fd, const char *name2); | |
5590 | PRE(sys_symlinkat) | |
5591 | { | |
5592 | *flags |= SfMayBlock; | |
76d6b459 PF |
5593 | PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s) )",ARG1,(char*)ARG1,ARG2,ARG3,(char*)ARG3); |
5594 | PRE_REG_READ3(int, "symlinkat", | |
5595 | const char *, name1, int, fd, const char *, name2); | |
5596 | PRE_MEM_RASCIIZ( "symlinkat(name1)", ARG1 ); | |
5597 | PRE_MEM_RASCIIZ( "symlinkat(name2)", ARG3 ); | |
e2e5d75f PF |
5598 | } |
5599 | ||
5600 | // SYS_unlinkat 503 | |
5601 | // int unlinkat(int fd, const char *path, int flag); | |
5602 | PRE(sys_unlinkat) | |
5603 | { | |
5604 | *flags |= SfMayBlock; | |
76d6b459 | 5605 | PRINT("sys_unlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u ", |
3ce76737 | 5606 | ARG1, ARG2, (char*)ARG2, ARG3); |
76d6b459 PF |
5607 | PRE_REG_READ3(int, "unlinkat", int, fd, const char *, path, int, flag); |
5608 | PRE_MEM_RASCIIZ( "unlinkat(path)", ARG2 ); | |
e2e5d75f PF |
5609 | } |
5610 | ||
5611 | // SYS_posix_openpt 504 | |
5612 | // int posix_openpt(int oflag); | |
5613 | PRE(sys_posix_openpt) | |
5614 | { | |
0fe27992 | 5615 | PRINT("sys_posix_openpt ( %" FMT_REGWORD "d )", SARG1); |
e2e5d75f | 5616 | PRE_REG_READ1(int, "posix_openpt", int, oflag); |
e2e5d75f PF |
5617 | } |
5618 | ||
5619 | // SYS_gssd_syscall 505 | |
5620 | // @todo | |
5621 | // see https://www.freebsd.org/cgi/man.cgi?format=html&query=gssapi(3) | |
5622 | // syscalls.master says ; 505 is initialised by the kgssapi code, if present. | |
5623 | ||
5624 | // SYS_jail_get 506 | |
5625 | // int jail_get(struct iovec *iov, u_int niov, int flags); | |
5626 | PRE(sys_jail_get) | |
5627 | { | |
76d6b459 PF |
5628 | PRINT("sys_jail_get ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); |
5629 | PRE_REG_READ3(int, "jail_get", struct vki_iovec *, iov, unsigned int, | |
5630 | niov, int, flags); | |
e2e5d75f PF |
5631 | PRE_MEM_READ("jail_get(iov)", ARG1, ARG2 * sizeof(struct vki_iovec)); |
5632 | } | |
5633 | ||
5634 | // SYS_jail_set 507 | |
5635 | // int jail_set(struct iovec *iov, u_int niov, int flags); | |
5636 | PRE(sys_jail_set) | |
5637 | { | |
76d6b459 PF |
5638 | PRINT("sys_jail_set ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); |
5639 | PRE_REG_READ3(int, "jail_set", struct vki_iovec *, iov, unsigned int, | |
5640 | niov, int, flags); | |
e2e5d75f PF |
5641 | PRE_MEM_READ("jail_set(iovs)", ARG1, ARG2 * sizeof(struct vki_iovec)); |
5642 | } | |
5643 | ||
5644 | // SYS_jail_remove 508 | |
5645 | // int jail_remove(int jid); | |
5646 | PRE(sys_jail_remove) | |
5647 | { | |
5648 | PRINT("sys_jail_remove ( %" FMT_REGWORD "d )", SARG1); | |
5649 | PRE_REG_READ1(int, "jail_remove", int, jid); | |
5650 | } | |
5651 | ||
5652 | // SYS_closefrom 509 | |
5653 | // void closefrom(int lowfd); | |
5654 | PRE(sys_closefrom) | |
5655 | { | |
5656 | PRINT("sys_closefrom ( %" FMT_REGWORD "dx )", SARG1); | |
5657 | PRE_REG_READ1(int, "closefrom", int, lowfd); | |
5658 | ||
5659 | /* | |
5660 | * Can't pass this on to the kernel otherwise it will close | |
5661 | * all of the host files like the log | |
5662 | */ | |
5663 | ||
196aafe6 PF |
5664 | for (int fd = ARG1; fd < VG_(fd_hard_limit); ++fd) { |
5665 | if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0) | |
5666 | && fd != VG_(log_output_sink).fd | |
5667 | && fd != VG_(xml_output_sink).fd) | |
5668 | VG_(close)(fd); | |
e2e5d75f PF |
5669 | } |
5670 | ||
5671 | SET_STATUS_Success(0); | |
5672 | } | |
5673 | ||
196aafe6 PF |
5674 | POST(sys_closefrom) |
5675 | { | |
5676 | unsigned int fd; | |
5677 | unsigned int last = VG_(fd_hard_limit); | |
5678 | ||
5679 | if (!VG_(clo_track_fds)) | |
5680 | return; | |
5681 | ||
5682 | for (fd = ARG1; fd <= last; fd++) | |
5683 | if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0) | |
5684 | && fd != VG_(log_output_sink).fd | |
5685 | && fd != VG_(xml_output_sink).fd) | |
5686 | ML_(record_fd_close)(tid, fd); | |
5687 | } | |
5688 | ||
e2e5d75f PF |
5689 | // SYS___semctl 510 |
5690 | // int semctl(int semid, int semnum, int cmd, ...); | |
5691 | // int __semctl(int semid, int semnum, int cmd, _Inout_ union semun *arg); | |
5692 | PRE(sys___semctl) | |
5693 | { | |
d6abe92a PF |
5694 | union vki_semun* semun; |
5695 | ||
e2e5d75f | 5696 | switch (ARG3) { |
e2e5d75f PF |
5697 | case VKI_IPC_STAT: |
5698 | case VKI_SEM_STAT: | |
5699 | case VKI_IPC_SET: | |
e2e5d75f PF |
5700 | case VKI_GETALL: |
5701 | case VKI_SETALL: | |
d6abe92a | 5702 | PRINT("sys___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); |
76d6b459 | 5703 | PRE_REG_READ4(long, "semctl", |
d6abe92a PF |
5704 | int, semid, int, semnum, int, cmd, union vki_semun *, arg); |
5705 | PRE_MEM_READ("sys___sysctl(arg)", ARG4, sizeof(union vki_semun)); | |
5706 | semun = (union vki_semun*)ARG4; | |
5707 | if (ML_(safe_to_deref)(semun, sizeof(*semun))) { | |
5708 | ARG4 = (RegWord)semun; | |
5709 | ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4); | |
5710 | } | |
e2e5d75f PF |
5711 | break; |
5712 | default: | |
76d6b459 PF |
5713 | PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
5714 | PRE_REG_READ3(long, "semctl", | |
5715 | int, semid, int, semnum, int, cmd); | |
e2e5d75f PF |
5716 | break; |
5717 | } | |
e2e5d75f PF |
5718 | } |
5719 | ||
5720 | POST(sys___semctl) | |
5721 | { | |
d6abe92a PF |
5722 | union vki_semun* semun = (union vki_semun*)ARG4; |
5723 | if (ML_(safe_to_deref)(semun, sizeof(*semun))) { | |
5724 | ARG4 = (RegWord)semun; | |
5725 | ML_(generic_POST_sys_semctl)(tid, RES, ARG1,ARG2,ARG3,ARG4); | |
5726 | } | |
e2e5d75f PF |
5727 | } |
5728 | ||
5729 | // SYS_msgctl 511 | |
5730 | // int msgctl(int msqid, int cmd, struct msqid_ds *buf); | |
5731 | PRE(sys_msgctl) | |
5732 | { | |
76d6b459 | 5733 | PRINT("sys_msgctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3 ); |
e2e5d75f | 5734 | |
76d6b459 | 5735 | PRE_REG_READ3(int, "msgctl", int, msqid, int, cmd, struct msqid_ds *, buf); |
e2e5d75f PF |
5736 | |
5737 | switch (ARG2 /* cmd */) { | |
5738 | case VKI_IPC_STAT: | |
76d6b459 PF |
5739 | PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", |
5740 | ARG3, sizeof(struct vki_msqid_ds) ); | |
e2e5d75f PF |
5741 | break; |
5742 | case VKI_IPC_SET: | |
76d6b459 PF |
5743 | PRE_MEM_READ( "msgctl(IPC_SET, buf)", |
5744 | ARG3, sizeof(struct vki_msqid_ds) ); | |
e2e5d75f PF |
5745 | break; |
5746 | } | |
5747 | } | |
5748 | ||
5749 | POST(sys_msgctl) | |
5750 | { | |
5751 | switch (ARG2 /* cmd */) { | |
5752 | case VKI_IPC_STAT: | |
76d6b459 | 5753 | POST_MEM_WRITE( ARG3, sizeof(struct vki_msqid_ds) ); |
e2e5d75f PF |
5754 | break; |
5755 | } | |
5756 | } | |
5757 | ||
76d6b459 | 5758 | |
e2e5d75f PF |
5759 | // SYS_shmctl 512 |
5760 | // int shmctl(int shmid, int cmd, struct shmid_ds *buf); | |
5761 | PRE(sys_shmctl) | |
5762 | { | |
76d6b459 PF |
5763 | PRINT("sys_shmctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,SARG2,ARG3); |
5764 | PRE_REG_READ3(int, "shmctl", | |
5765 | int, shmid, int, cmd, struct vki_shmid_ds *, buf); | |
e2e5d75f PF |
5766 | switch (ARG2 /* cmd */) { |
5767 | case VKI_IPC_STAT: | |
76d6b459 PF |
5768 | PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", |
5769 | ARG3, sizeof(struct vki_shmid_ds) ); | |
e2e5d75f PF |
5770 | break; |
5771 | case VKI_IPC_SET: | |
76d6b459 PF |
5772 | PRE_MEM_READ( "shmctl(IPC_SET, buf)", |
5773 | ARG3, sizeof(struct vki_shmid_ds) ); | |
e2e5d75f PF |
5774 | break; |
5775 | } | |
5776 | } | |
5777 | ||
5778 | POST(sys_shmctl) | |
5779 | { | |
5780 | if (ARG2 == VKI_IPC_STAT) { | |
76d6b459 | 5781 | POST_MEM_WRITE( ARG3, sizeof(struct vki_shmid_ds) ); |
e2e5d75f PF |
5782 | } |
5783 | } | |
5784 | ||
5785 | // SYS_lpathconf 513 | |
5786 | // long lpathconf(const char *path, int name); | |
5787 | PRE(sys_lpathconf) | |
5788 | { | |
5789 | PRINT("sys_lpathconf ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d)", ARG1, SARG2); | |
76d6b459 | 5790 | PRE_REG_READ2(long, "lpathconf", const char *, path, int, name); |
e2e5d75f PF |
5791 | PRE_MEM_RASCIIZ("lpathconf(path)", ARG1); |
5792 | } | |
5793 | ||
5794 | // SYS___cap_rights_get 515 | |
5795 | // note extra 1st argument for the internal function which is not present | |
5796 | // in the public interface | |
5797 | // int __cap_rights_get(int version, int fd, cap_rights_t *rights); | |
5798 | PRE(sys_cap_rights_get) | |
5799 | { | |
76d6b459 PF |
5800 | PRINT("sys_cap_rights_get ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3); |
5801 | PRE_REG_READ3(long, "cap_rights_get", int, version, int, fd, vki_cap_rights_t*, rights); | |
e2e5d75f PF |
5802 | PRE_MEM_WRITE("cap_rights_get(rights)", ARG3, sizeof(vki_cap_rights_t)); |
5803 | } | |
5804 | ||
76d6b459 PF |
5805 | POST(sys_cap_rights_get) |
5806 | { | |
5807 | POST_MEM_WRITE(ARG2, sizeof(vki_cap_rights_t)); | |
5808 | } | |
e2e5d75f PF |
5809 | |
5810 | // SYS_cap_enter 516 | |
5811 | // int cap_enter(void); | |
5812 | PRE(sys_cap_enter) | |
5813 | { | |
5814 | PRINT("%s", "sys_cap_enter ( )"); | |
5815 | PRE_REG_READ0(int, "cap_enter"); | |
5816 | static Bool warning_given = False; | |
5817 | if (!warning_given) { | |
5818 | warning_given = True; | |
5819 | capabiltyMode = True; | |
5820 | VG_(umsg)( | |
5821 | "WARNING: Valgrind may not operate correctly in capability mode.\n" | |
76d6b459 PF |
5822 | " Please consider disabling capability by using the RUNNING_ON_VALGRIND mechanism.\n" |
5823 | " See http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq\n"); | |
e2e5d75f | 5824 | } |
b9326bb1 PF |
5825 | /* now complete loading debuginfo since it is not allowed after entering cap mode */ |
5826 | VG_(load_all_debuginfo)(); | |
e2e5d75f PF |
5827 | } |
5828 | ||
5829 | // SYS_cap_getmode 517 | |
5830 | // int cap_getmode(u_int *modep); | |
5831 | PRE(sys_cap_getmode) | |
5832 | { | |
5833 | PRINT("sys_cap_getmode ( %#" FMT_REGWORD "x )", ARG1); | |
5834 | PRE_REG_READ1(int, "cap_getmode", u_int*, modep); | |
5835 | PRE_MEM_WRITE("cap_getmode(modep)", ARG1, sizeof(u_int)); | |
5836 | } | |
5837 | ||
76d6b459 PF |
5838 | POST(sys_cap_getmode) |
5839 | { | |
5840 | POST_MEM_WRITE(ARG1, sizeof(u_int)); | |
5841 | } | |
e2e5d75f PF |
5842 | |
5843 | static vki_sigset_t pdfork_saved_mask; | |
5844 | ||
5845 | // SYS_pdfork 518 | |
5846 | // pid_t pdfork(int *fdp, int flags); | |
5847 | PRE(sys_pdfork) | |
5848 | { | |
76d6b459 PF |
5849 | Bool is_child; |
5850 | Int child_pid; | |
e2e5d75f PF |
5851 | vki_sigset_t mask; |
5852 | ||
5853 | PRINT("sys_pdfork ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2); | |
5854 | PRE_REG_READ2(pid_t, "pdfork", int*, fdp, int, flags); | |
5855 | ||
5856 | /* Block all signals during fork, so that we can fix things up in | |
5857 | the child without being interrupted. */ | |
5858 | VG_(sigfillset)(&mask); | |
5859 | VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &pdfork_saved_mask); | |
5860 | ||
5861 | VG_(do_atfork_pre)(tid); | |
5862 | ||
76d6b459 | 5863 | SET_STATUS_from_SysRes( VG_(do_syscall2)(__NR_pdfork, ARG1, ARG2) ); |
e2e5d75f | 5864 | |
227fa1d5 PF |
5865 | if (!SUCCESS) { |
5866 | return; | |
5867 | } | |
e2e5d75f PF |
5868 | |
5869 | // RES is 0 for child, non-0 (the child's PID) for parent. | |
76d6b459 PF |
5870 | is_child = ( RES == 0 ? True : False ); |
5871 | child_pid = ( is_child ? -1 : (Int)RES ); | |
e2e5d75f PF |
5872 | |
5873 | if (is_child) { | |
5874 | VG_(do_atfork_child)(tid); | |
5875 | ||
5876 | /* restore signal mask */ | |
5877 | VG_(sigprocmask)(VKI_SIG_SETMASK, &pdfork_saved_mask, NULL); | |
5878 | } else { | |
5879 | VG_(do_atfork_parent)(tid); | |
5880 | ||
5881 | PRINT(" fork: process %d created child %d\n", VG_(getpid)(), child_pid); | |
5882 | ||
5883 | /* restore signal mask */ | |
5884 | VG_(sigprocmask)(VKI_SIG_SETMASK, &pdfork_saved_mask, NULL); | |
5885 | } | |
5886 | ||
5887 | if (ARG1) { | |
76d6b459 | 5888 | PRE_MEM_WRITE( "pdfork(fdp)", ARG1, sizeof(int) ); |
e2e5d75f PF |
5889 | } |
5890 | } | |
5891 | ||
5892 | POST(sys_pdfork) | |
5893 | { | |
5894 | if (ARG1) { | |
76d6b459 | 5895 | POST_MEM_WRITE( ARG1, sizeof(int) ); |
e2e5d75f PF |
5896 | } |
5897 | } | |
5898 | ||
5899 | // pdkill 519 | |
76d6b459 | 5900 | //int pdkill(int fd, int signum) |
e2e5d75f PF |
5901 | PRE(sys_pdkill) |
5902 | { | |
5903 | PRINT("sys_pdkill ( %" FMT_REGWORD "u, %" FMT_REGWORD "d )", ARG1, SARG2); | |
5904 | PRE_REG_READ2(int, "pdkill", int, fd, int, signum); | |
5905 | ||
5906 | if (!ML_(client_signal_OK)(ARG2)) { | |
76d6b459 | 5907 | SET_STATUS_Failure( VKI_EINVAL ); |
e2e5d75f PF |
5908 | return; |
5909 | } | |
5910 | ||
034e5d22 PF |
5911 | /* Ther was some code here to check if the kill is to this process |
5912 | * | |
5913 | * But it was totally wrong | |
5914 | * | |
5915 | * It was calling ML_(do_sigkill)(Int pid, Int tgid) | |
5916 | * | |
5917 | * With a file descriptor | |
5918 | * | |
5919 | * Fortunately this will never match a real process otherwise | |
5920 | * it might have accidentally killed us. | |
5921 | * | |
5922 | * For a start we need the pid, obtained with pdgetpid | |
5923 | * Next ML_(do_sigkill) doesn't map to FreeBSD. It takes a | |
5924 | * pid (lwpid) and a tgid (threadgroup) | |
5925 | * | |
5926 | * On FreeBSD lwpid is the tid and threadgroup is the pid | |
5927 | * The kill functions operate on pids, not tids. | |
5928 | * | |
5929 | * One last thing, I don't see how pdkill could do a self | |
5930 | * kill 9. It neads an fd which implied pdfork whichimplies | |
5931 | * that the fd/pid are for a child process | |
5932 | */ | |
5933 | ||
5934 | SET_STATUS_from_SysRes(VG_(do_syscall2)(SYSNO, ARG1, ARG2)); | |
e2e5d75f | 5935 | |
227fa1d5 | 5936 | if (VG_(clo_trace_signals)) { |
76d6b459 PF |
5937 | VG_(message)(Vg_DebugMsg, "pdkill: sent signal %ld to fd %ld\n", |
5938 | SARG2, SARG1); | |
227fa1d5 | 5939 | } |
e2e5d75f PF |
5940 | |
5941 | /* This kill might have given us a pending signal. Ask for a check once | |
5942 | the syscall is done. */ | |
5943 | *flags |= SfPollAfter; | |
76d6b459 | 5944 | |
e2e5d75f PF |
5945 | } |
5946 | ||
5947 | // SYS_pdgetpid 520 | |
5948 | // int pdgetpid(int fd, pid_t *pidp); | |
5949 | PRE(sys_pdgetpid) | |
5950 | { | |
5951 | PRINT("pdgetpid ( %" FMT_REGWORD "d, %#lx )", SARG1, ARG2); | |
76d6b459 PF |
5952 | PRE_REG_READ2(int, "pdgetpid", |
5953 | int, fd, pid_t*, pidp); | |
5954 | PRE_MEM_WRITE( "pdgetpid(pidp))", ARG2, sizeof(vki_pid_t) ); | |
e2e5d75f PF |
5955 | } |
5956 | ||
76d6b459 PF |
5957 | POST(sys_pdgetpid) |
5958 | { | |
5959 | POST_MEM_WRITE( ARG2, sizeof(vki_pid_t) ); | |
5960 | } | |
e2e5d75f PF |
5961 | |
5962 | // SYS_pselect 522 | |
5963 | ||
5964 | // int pselect(int nfds, fd_set * restrict readfds, fd_set * restrict writefds, | |
5965 | // fd_set * restrict exceptfds, | |
5966 | // const struct timespec * restrict timeout, | |
5967 | // const sigset_t * restrict newsigmask); | |
5968 | PRE(sys_pselect) | |
5969 | { | |
5970 | *flags |= SfMayBlock | SfPostOnFail; | |
76d6b459 PF |
5971 | PRINT("sys_pselect ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" |
5972 | FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", | |
e2e5d75f | 5973 | SARG1, ARG2, ARG3, ARG4, ARG5, ARG6); |
76d6b459 PF |
5974 | PRE_REG_READ6(int, "pselect", |
5975 | int, nfds, vki_fd_set *, readfds, vki_fd_set *, writefds, | |
5976 | vki_fd_set *, exceptfds, struct vki_timespec *, timeout, | |
5977 | const sigset_t *, newsigmask); | |
e2e5d75f | 5978 | // XXX: this possibly understates how much memory is read. |
227fa1d5 | 5979 | if (ARG2 != 0) { |
76d6b459 PF |
5980 | PRE_MEM_READ( "pselect(readfds)", |
5981 | ARG2, ARG1/8 /* __FD_SETSIZE/8 */ ); | |
227fa1d5 PF |
5982 | } |
5983 | if (ARG3 != 0) { | |
76d6b459 PF |
5984 | PRE_MEM_READ( "pselect(writefds)", |
5985 | ARG3, ARG1/8 /* __FD_SETSIZE/8 */ ); | |
227fa1d5 PF |
5986 | } |
5987 | if (ARG4 != 0) { | |
76d6b459 PF |
5988 | PRE_MEM_READ( "pselect(exceptfds)", |
5989 | ARG4, ARG1/8 /* __FD_SETSIZE/8 */ ); | |
227fa1d5 PF |
5990 | } |
5991 | if (ARG5 != 0) { | |
76d6b459 | 5992 | PRE_MEM_READ( "pselect(timeout)", ARG5, sizeof(struct vki_timeval) ); |
227fa1d5 | 5993 | } |
e2e5d75f PF |
5994 | |
5995 | if (ARG6 != 0) { | |
76d6b459 | 5996 | PRE_MEM_READ( "pselect(sig)", ARG6, sizeof(vki_sigset_t) ); |
e2e5d75f PF |
5997 | ARG6 = ML_(make_safe_mask)("syswrap.pselect.1", (Addr)ARG6); |
5998 | } | |
5999 | } | |
6000 | ||
76d6b459 PF |
6001 | POST(sys_pselect) |
6002 | { | |
6003 | ML_(free_safe_mask) ( (Addr)ARG6 ); | |
6004 | } | |
e2e5d75f PF |
6005 | |
6006 | // SYS_getloginclass 523 | |
6007 | // int getloginclass(char *name, size_t len); | |
6008 | PRE(sys_getloginclass) | |
6009 | { | |
76d6b459 PF |
6010 | PRINT("sys_getloginclass ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); |
6011 | PRE_REG_READ2(int, "getloginclass", char *, name, size_t, len); | |
e2e5d75f PF |
6012 | // The buffer should be at least MAXLOGNAME bytes in length. |
6013 | PRE_MEM_WRITE("getloginclass(name)", ARG1, ARG2); | |
6014 | } | |
6015 | ||
76d6b459 PF |
6016 | POST(sys_getloginclass) |
6017 | { | |
6018 | POST_MEM_WRITE(ARG1, ARG2); | |
6019 | } | |
e2e5d75f PF |
6020 | |
6021 | // SYS_setloginclass 524 | |
6022 | // int setloginclass(const char *name); | |
6023 | PRE(sys_setloginclass) | |
6024 | { | |
6025 | PRINT("sys_setloginclass ( %#" FMT_REGWORD "x(%s) )", ARG1, (HChar*)ARG1); | |
76d6b459 | 6026 | PRE_REG_READ1(int, "setloginclass", const char *, name); |
e2e5d75f PF |
6027 | PRE_MEM_RASCIIZ("rctl_setloginclass(name)", ARG1); |
6028 | } | |
6029 | ||
6030 | // SYS_rctl_get_racct 525 | |
6031 | // int rctl_get_racct(const char *inbufp, size_t inbuflen, char *outbufp, | |
6032 | // size_t outbuflen); | |
6033 | PRE(sys_rctl_get_racct) | |
6034 | { | |
76d6b459 PF |
6035 | PRINT("sys_rctl_get_racct ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); |
6036 | PRE_REG_READ4(int, "rctl_get_racct", const char *, inbufp, size_t, inbuflen, char *, outbufp, | |
6037 | size_t, outbuflen); | |
e2e5d75f PF |
6038 | PRE_MEM_READ("rctl_get_racct(inbufp)", ARG1, ARG2); |
6039 | PRE_MEM_WRITE("rctl_get_racct(outbufp)", ARG3, ARG4); | |
6040 | } | |
6041 | ||
76d6b459 PF |
6042 | POST(sys_rctl_get_racct) |
6043 | { | |
6044 | POST_MEM_WRITE(ARG3, ARG4); | |
6045 | } | |
e2e5d75f PF |
6046 | |
6047 | // SYS_rctl_get_rules 526 | |
6048 | // int rctl_get_rules(const char *inbufp, size_t inbuflen, char *outbufp, | |
6049 | // size_t outbuflen); | |
6050 | PRE(sys_rctl_get_rules) | |
6051 | { | |
76d6b459 PF |
6052 | PRINT("sys_rctl_get_rules ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); |
6053 | PRE_REG_READ4(int, "rctl_get_rules", const char *, inbufp, size_t, inbuflen, char *, outbufp, | |
6054 | size_t, outbuflen); | |
e2e5d75f PF |
6055 | PRE_MEM_READ("rctl_get_rules(inbufp)", ARG1, ARG2); |
6056 | PRE_MEM_WRITE("rctl_get_rules(outbufp)", ARG3, ARG4); | |
6057 | } | |
6058 | ||
76d6b459 PF |
6059 | POST(sys_rctl_get_rules) |
6060 | { | |
6061 | POST_MEM_WRITE(ARG3, ARG4); | |
6062 | } | |
e2e5d75f PF |
6063 | |
6064 | // SYS_rctl_get_limits 527 | |
6065 | // int rctl_get_limits(const char *inbufp, size_t inbuflen, char *outbufp, | |
6066 | // size_t outbuflen); | |
6067 | PRE(sys_rctl_get_limits) | |
6068 | { | |
76d6b459 PF |
6069 | PRINT("sys_rctl_get_limits ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); |
6070 | PRE_REG_READ4(int, "rctl_get_limits", const char *, inbufp, size_t, inbuflen, char *, outbufp, | |
6071 | size_t, outbuflen); | |
e2e5d75f PF |
6072 | PRE_MEM_READ("rctl_get_limits(inbufp)", ARG1, ARG2); |
6073 | PRE_MEM_WRITE("rctl_get_limits(outbufp)", ARG3, ARG4); | |
6074 | } | |
6075 | ||
76d6b459 PF |
6076 | POST(sys_rctl_get_limits) |
6077 | { | |
6078 | POST_MEM_WRITE(ARG3, ARG4); | |
6079 | } | |
e2e5d75f PF |
6080 | |
6081 | // SYS_rctl_add_rule 528 | |
6082 | // int rctl_add_rule(const char *inbufp, size_t inbuflen, char *outbufp, | |
6083 | // size_t outbuflen); | |
6084 | PRE(sys_rctl_add_rule) | |
6085 | { | |
76d6b459 PF |
6086 | PRINT("sys_rctl_add_rule ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); |
6087 | PRE_REG_READ2(int, "rctl_add_rule", const char *, inbufp, size_t, inbuflen); | |
e2e5d75f PF |
6088 | PRE_MEM_READ("rctl_add_rule(inbufp)", ARG1, ARG2); |
6089 | // man page says | |
6090 | // The outbufp and outbuflen arguments are unused | |
76d6b459 | 6091 | //PRE_MEM_WRITE("rctl_add_rule(outbufp)", ARG3, ARG4); |
e2e5d75f PF |
6092 | } |
6093 | ||
6094 | POST(sys_rctl_add_rule) | |
6095 | { | |
76d6b459 | 6096 | //POST_MEM_WRITE(ARG3, ARG4); |
e2e5d75f PF |
6097 | } |
6098 | ||
6099 | // SYS_rctl_remove_rule 529 | |
6100 | // int rctl_remove_rule(const char *inbufp, size_t inbuflen, char *outbufp, | |
6101 | // size_t outbuflen); | |
6102 | PRE(sys_rctl_remove_rule) | |
6103 | { | |
76d6b459 PF |
6104 | PRINT("sys_rctl_remove_rule ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4); |
6105 | PRE_REG_READ2(int, "rctl_remove_rule", const char *, inbufp, size_t, inbuflen); | |
e2e5d75f PF |
6106 | PRE_MEM_READ("rctl_remove_rule(inbufp)", ARG1, ARG2); |
6107 | // man page says | |
6108 | // The outbufp and outbuflen arguments are unused | |
76d6b459 | 6109 | //PRE_MEM_WRITE("rctl_remove_rule(outbufp)", ARG3, ARG4); |
e2e5d75f PF |
6110 | } |
6111 | ||
6112 | POST(sys_rctl_remove_rule) | |
6113 | { | |
76d6b459 | 6114 | //POST_MEM_WRITE(ARG3, ARG4); |
e2e5d75f PF |
6115 | } |
6116 | ||
6117 | // SYS_posix_fallocate 530 | |
6118 | // x86/amd64 | |
6119 | ||
6120 | // SYS_posix_fadvise 531 | |
6121 | // x86/amd64 | |
6122 | ||
6123 | // SYS_wait6 532 | |
6124 | // amd64 / x86 | |
6125 | ||
6126 | // SYS_cap_rights_limit 533 | |
76d6b459 | 6127 | //int cap_rights_limit(int fd, const cap_rights_t *rights); |
e2e5d75f PF |
6128 | PRE(sys_cap_rights_limit) |
6129 | { | |
76d6b459 PF |
6130 | PRINT("sys_cap_rights_limit ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); |
6131 | PRE_REG_READ2(int, "cap_rights_limit", | |
6132 | int, fd, const cap_rights_t *, rights); | |
6133 | PRE_MEM_READ( "cap_rights_limit(rights)", ARG2, sizeof(struct vki_cap_rights) ); | |
e2e5d75f PF |
6134 | } |
6135 | ||
6136 | // SYS_cap_ioctls_limit 534 | |
6137 | // int cap_ioctls_limit(int fd, const unsigned long *cmds, size_t ncmds); | |
6138 | PRE(sys_cap_ioctls_limit) | |
6139 | { | |
76d6b459 PF |
6140 | PRINT("cap_ioctls_limit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); |
6141 | PRE_REG_READ3(int, "cap_ioctls_limit", | |
6142 | int, fd, unsigned long*, rights, vki_size_t, ncmds); | |
e2e5d75f | 6143 | // "can be up to 256" taking that to not be inclusive |
76d6b459 PF |
6144 | if (ARG3 < 256 ) { |
6145 | PRE_MEM_READ( "cap_ioctls_limit(cmds))", ARG2, ARG3*sizeof(unsigned long) ); | |
e2e5d75f PF |
6146 | } |
6147 | // else fail? | |
6148 | } | |
6149 | ||
6150 | // SYS_cap_ioctls_get 535 | |
6151 | // int cap_ioctls_get(int fd, unsigned long *cmds, size_t maxcmds); | |
6152 | PRE(sys_cap_ioctls_get) | |
6153 | { | |
76d6b459 PF |
6154 | PRINT("sys_cap_ioctls_get ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, ARG2, ARG3); |
6155 | PRE_REG_READ3(int, "cap_ioctls_get", int, fd, unsigned long *, cmds, size_t, maxcmds); | |
e2e5d75f | 6156 | if (ARG3 < 256) { |
76d6b459 | 6157 | PRE_MEM_WRITE("cap_ioctls_get(cmds)", ARG2, ARG3*sizeof(unsigned long)); |
e2e5d75f PF |
6158 | } |
6159 | } | |
6160 | ||
6161 | POST(sys_cap_ioctls_get) | |
6162 | { | |
6163 | if (ARG3 < 256) { | |
76d6b459 | 6164 | POST_MEM_WRITE(ARG2, ARG3*sizeof(unsigned long)); |
e2e5d75f PF |
6165 | } |
6166 | } | |
6167 | ||
76d6b459 | 6168 | |
e2e5d75f | 6169 | // SYS_cap_fcntls_limit 536 |
76d6b459 | 6170 | //int cap_fcntls_limit(int fd, uint32_t fcntlrights); |
e2e5d75f PF |
6171 | PRE(sys_cap_fcntls_limit) |
6172 | { | |
76d6b459 PF |
6173 | PRINT("cap_fcntls_limit ( %" FMT_REGWORD "d, %" FMT_REGWORD "u )", SARG1, ARG2); |
6174 | PRE_REG_READ2(long, "cap_fcntls_limit", | |
6175 | int, fd, vki_uint32_t, fcntlrights); | |
e2e5d75f PF |
6176 | } |
6177 | ||
6178 | // SYS_cap_fcntls_get 537 | |
6179 | // int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); | |
6180 | PRE(sys_cap_fcntls_get) | |
6181 | { | |
76d6b459 PF |
6182 | PRINT("sys_cap_fcntls_get ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); |
6183 | PRE_REG_READ2(int, "cap_fcntls_get", int, fd, uint32_t *, fcntlrightsp); | |
e2e5d75f PF |
6184 | PRE_MEM_WRITE("cap_fcntls_get(fcntlrightsp)", ARG2, sizeof(uint32_t)); |
6185 | } | |
6186 | ||
76d6b459 PF |
6187 | POST(sys_cap_fcntls_get) |
6188 | { | |
6189 | POST_MEM_WRITE(ARG2, sizeof(uint32_t)); | |
6190 | } | |
e2e5d75f PF |
6191 | |
6192 | // SYS_bindat 538 | |
6193 | // int bindat(int fd, int s, const struct sockaddr *addr, socklen_t addrlen); | |
6194 | PRE(sys_bindat) | |
6195 | { | |
76d6b459 | 6196 | PRINT("sys_bindat ( %" FMT_REGWORD "d, %" FMT_REGWORD "dx, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", |
e2e5d75f | 6197 | SARG1, SARG2, ARG3, ARG4); |
76d6b459 | 6198 | PRE_REG_READ4(int, "bindat", int, fd, int, s, const struct vki_sockaddr *, name, vki_socklen_t, namelen); |
e2e5d75f PF |
6199 | PRE_MEM_READ("bindat(name)", ARG3, ARG4); |
6200 | } | |
6201 | ||
6202 | // SYS_connectat 539 | |
6203 | // int connectat(int fd, int s, const struct sockaddr *name, socklen_t namelen); | |
6204 | PRE(sys_connectat) | |
6205 | { | |
76d6b459 | 6206 | PRINT("sys_connectat ( %" FMT_REGWORD "d, %" FMT_REGWORD "dx, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", |
e2e5d75f | 6207 | SARG1, SARG2, ARG3, ARG4); |
76d6b459 | 6208 | PRE_REG_READ4(int, "connectat", int, fd, int, s, const struct vki_sockaddr *, name, vki_socklen_t, namelen); |
e2e5d75f PF |
6209 | PRE_MEM_READ("connectat(name)", ARG3, ARG4); |
6210 | } | |
6211 | ||
6212 | // SYS_chflagsat 540 | |
6213 | // int chflagsat(int fd, const char *path, unsigned long flags, int atflag); | |
6214 | PRE(sys_chflagsat) | |
6215 | { | |
76d6b459 | 6216 | PRINT("sys_chglagsat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d )", |
e2e5d75f | 6217 | SARG1, ARG2, ARG3, SARG4); |
76d6b459 | 6218 | PRE_REG_READ4(int, "chflagsat", int, fd, const char *, path, unsigned long, flags, int, atflag); |
e2e5d75f PF |
6219 | PRE_MEM_RASCIIZ("chflagsat(path)", ARG2); |
6220 | } | |
6221 | ||
6222 | // SYS_accept4 541 | |
6223 | // int accept4(int s, struct sockaddr * restrict addr, | |
6224 | // socklen_t * restrict addrlen, int flags); | |
6225 | PRE(sys_accept4) | |
6226 | { | |
6227 | *flags |= SfMayBlock; | |
76d6b459 PF |
6228 | PRINT("sys_accept4 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u)",ARG1,ARG2,ARG3,ARG4); |
6229 | PRE_REG_READ4(int, "accept4", | |
6230 | int, s, struct sockaddr *, addr, int, *addrlen, int, flags); | |
6231 | ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); | |
e2e5d75f PF |
6232 | } |
6233 | ||
6234 | POST(sys_accept4) | |
6235 | { | |
6236 | SysRes r; | |
6237 | vg_assert(SUCCESS); | |
76d6b459 PF |
6238 | r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), |
6239 | ARG1,ARG2,ARG3); | |
e2e5d75f PF |
6240 | SET_STATUS_from_SysRes(r); |
6241 | } | |
6242 | ||
6243 | // SYS_pipe2 542 | |
6244 | // int pipe2(int fildes[2], int flags); | |
6245 | PRE(sys_pipe2) | |
6246 | { | |
6247 | PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); | |
76d6b459 PF |
6248 | PRE_REG_READ2(int, "pipe2", |
6249 | int *, fildes, int, flags); | |
e2e5d75f | 6250 | PRE_MEM_WRITE("pipe2(fildes)", ARG1, 2 * sizeof(int)); |
76d6b459 | 6251 | |
e2e5d75f PF |
6252 | } |
6253 | ||
6254 | POST(sys_pipe2) | |
6255 | { | |
76d6b459 | 6256 | int *fildes; |
e2e5d75f | 6257 | |
227fa1d5 | 6258 | if (RES != 0) { |
e2e5d75f | 6259 | return; |
227fa1d5 | 6260 | } |
e2e5d75f PF |
6261 | |
6262 | POST_MEM_WRITE(ARG1, 2 * sizeof(int)); | |
76d6b459 | 6263 | fildes = (int *)ARG1; |
e2e5d75f PF |
6264 | |
6265 | if (!ML_(fd_allowed)(fildes[0], "pipe2", tid, True) || | |
76d6b459 | 6266 | !ML_(fd_allowed)(fildes[1], "pipe2", tid, True)) { |
e2e5d75f PF |
6267 | VG_(close)(fildes[0]); |
6268 | VG_(close)(fildes[1]); | |
76d6b459 | 6269 | SET_STATUS_Failure( VKI_EMFILE ); |
e2e5d75f PF |
6270 | } else if (VG_(clo_track_fds)) { |
6271 | ML_(record_fd_open_nameless)(tid, fildes[0]); | |
6272 | ML_(record_fd_open_nameless)(tid, fildes[1]); | |
6273 | } | |
6274 | } | |
6275 | ||
6276 | // SYS_aio_mlock 543 | |
6277 | // int aio_mlock(struct aiocb *iocb); | |
6278 | PRE(sys_aio_mlock) | |
6279 | { | |
6280 | PRINT("sys_aio_mlock ( %#" FMT_REGWORD "x )", ARG1); | |
76d6b459 | 6281 | PRE_REG_READ1(int, "aio_mlock", struct vki_aiocb *, iocb); |
e2e5d75f PF |
6282 | PRE_MEM_READ("aio_mlock(iocb", ARG1, sizeof(struct vki_aiocb)); |
6283 | // this locks memory into RAM, don't think that we need to do | |
6284 | // anything extra | |
6285 | } | |
6286 | ||
6287 | // SYS_procctl 544 | |
6288 | // amd64 / x86 | |
6289 | ||
6290 | // SYS_ppoll 545 | |
6291 | // int ppoll(struct pollfd fds[], nfds_t nfds, | |
6292 | // const struct timespec * restrict timeout, | |
6293 | // const sigset_t * restrict newsigmask); | |
6294 | PRE(sys_ppoll) | |
6295 | { | |
6296 | PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD | |
6297 | "x, %#" FMT_REGWORD "x )", | |
6298 | ARG1, ARG2, ARG3, ARG4); | |
76d6b459 PF |
6299 | UInt i; |
6300 | struct vki_pollfd* fds = (struct vki_pollfd *)(Addr)ARG1; | |
e2e5d75f | 6301 | *flags |= SfMayBlock | SfPostOnFail; |
76d6b459 PF |
6302 | PRE_REG_READ4(long, "ppoll", |
6303 | struct vki_pollfd *, fds, unsigned int, nfds, | |
6304 | struct vki_timespec *, timeout, vki_sigset_t *, newsigmask); | |
e2e5d75f | 6305 | |
6ce09798 PF |
6306 | for (i = 0; i < ARG2; i++) { |
6307 | PRE_MEM_READ( "ppoll(fds.fd)", | |
6308 | (Addr)(&fds[i].fd), sizeof(fds[i].fd) ); | |
6309 | if (ML_(safe_to_deref)(&fds[i].fd, sizeof(fds[i].fd)) && fds[i].fd >= 0) { | |
76d6b459 PF |
6310 | PRE_MEM_READ( "ppoll(fds.events)", |
6311 | (Addr)(&fds[i].events), sizeof(fds[i].events) ); | |
e2e5d75f | 6312 | } |
6ce09798 PF |
6313 | PRE_MEM_WRITE( "ppoll(fds.revents)", |
6314 | (Addr)(&fds[i].revents), sizeof(fds[i].revents) ); | |
e2e5d75f PF |
6315 | } |
6316 | ||
6317 | if (ARG3) { | |
76d6b459 PF |
6318 | PRE_MEM_READ( "ppoll(timeout)", ARG3, |
6319 | sizeof(struct vki_timespec) ); | |
e2e5d75f PF |
6320 | } |
6321 | if (ARG4) { | |
76d6b459 | 6322 | PRE_MEM_READ( "ppoll(newsigmask)", ARG4, sizeof(vki_sigset_t)); |
e2e5d75f PF |
6323 | ARG4 = ML_(make_safe_mask)("syswrap.ppoll.1", (Addr)ARG4); |
6324 | } | |
6325 | } | |
6326 | ||
6327 | POST(sys_ppoll) | |
6328 | { | |
6329 | if (SUCCESS && ((Word)RES != -1)) { | |
76d6b459 PF |
6330 | UInt i; |
6331 | struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1; | |
29cfa77b | 6332 | for (i = 0; i < ARG2; i++) { |
76d6b459 | 6333 | POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) ); |
29cfa77b | 6334 | } |
e2e5d75f | 6335 | } |
76d6b459 | 6336 | ML_(free_safe_mask) ( (Addr)ARG4 ); |
e2e5d75f PF |
6337 | } |
6338 | ||
6339 | // SYS_futimens 546 | |
6340 | // int futimens(int fd, const struct timespec times[2]); | |
6341 | PRE(sys_futimens) | |
6342 | { | |
6343 | PRINT("sys_futimens ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); | |
76d6b459 PF |
6344 | PRE_REG_READ2(int, "futimens", int, fd, const struct timespec *, times); |
6345 | PRE_MEM_READ("futimens(times)", ARG2, 2*sizeof(struct vki_timespec)); | |
e2e5d75f PF |
6346 | } |
6347 | ||
6348 | // SYS_utimensat 547 | |
6349 | // int utimensat(int fd, const char *path, const struct timespec times[2], | |
6350 | // int flag); | |
6351 | PRE(sys_utimensat) | |
6352 | { | |
76d6b459 | 6353 | PRINT("sys_utimensat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )", |
e2e5d75f | 6354 | SARG1, ARG2, ARG3, SARG4); |
76d6b459 PF |
6355 | PRE_REG_READ4(int, "utimensat", int, fd, const char *,path, const struct timespec *, times, |
6356 | int, flag); | |
e2e5d75f | 6357 | PRE_MEM_RASCIIZ("utimensat(path)", ARG2); |
76d6b459 | 6358 | PRE_MEM_READ("utimensat(times)", ARG3, 2*sizeof(struct vki_timespec)); |
e2e5d75f PF |
6359 | } |
6360 | ||
6361 | // SYS_fdatasync 550 | |
6362 | // int fdatasync(int fd); | |
6363 | PRE(sys_fdatasync) | |
6364 | { | |
76d6b459 | 6365 | PRINT("sys_fdatasync ( %" FMT_REGWORD "d )",SARG1); |
e2e5d75f PF |
6366 | PRE_REG_READ1(int, "fdatasync", int, fd); |
6367 | } | |
6368 | ||
6369 | #if (FREEBSD_VERS >= FREEBSD_12) | |
6370 | // SYS_fstat 551 | |
6371 | // int fstat(int fd, struct stat *sb); | |
6372 | PRE(sys_fstat) | |
6373 | { | |
76d6b459 PF |
6374 | PRINT("sys_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); |
6375 | PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); | |
6376 | PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_stat) ); | |
e2e5d75f PF |
6377 | } |
6378 | ||
76d6b459 PF |
6379 | POST(sys_fstat) |
6380 | { | |
6381 | POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); | |
6382 | } | |
e2e5d75f PF |
6383 | |
6384 | // SYS_fstatat 552 | |
6385 | // int fstatat(int fd, const char *path, struct stat *sb, int flag); | |
6386 | PRE(sys_fstatat) | |
6387 | { | |
76d6b459 PF |
6388 | PRINT("sys_fstatat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "d )", SARG1,ARG2,(char*)ARG2,ARG3,SARG4); |
6389 | PRE_REG_READ4(int, "fstatat", | |
6390 | int, fd, const char *, path, struct stat *, sb, int, flag); | |
6391 | PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 ); | |
6392 | PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_stat) ); | |
e2e5d75f PF |
6393 | } |
6394 | ||
76d6b459 PF |
6395 | POST(sys_fstatat) |
6396 | { | |
6397 | POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) ); | |
6398 | } | |
e2e5d75f PF |
6399 | // SYS_fhstat 553 |
6400 | // int fhstat(const fhandle_t *fhp, struct stat *sb); | |
6401 | PRE(sys_fhstat) | |
6402 | { | |
76d6b459 PF |
6403 | PRINT("sys_fhstat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
6404 | PRE_REG_READ2(long, "fhstat", const vki_fhandle_t *, fhp, struct stat *, sb); | |
6405 | PRE_MEM_READ( "fhstat(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
6406 | PRE_MEM_WRITE( "fhstat(sb)", ARG2, sizeof(struct vki_stat) ); | |
e2e5d75f PF |
6407 | } |
6408 | ||
76d6b459 PF |
6409 | POST(sys_fhstat) |
6410 | { | |
6411 | POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); | |
6412 | } | |
e2e5d75f PF |
6413 | |
6414 | // SYS_getdirentries 554 | |
6415 | // ssize_t getdirentries(int fd, char *buf, size_t nbytes, off_t *basep); | |
6416 | PRE(sys_getdirentries) | |
6417 | { | |
6418 | *flags |= SfMayBlock; | |
76d6b459 PF |
6419 | PRINT("sys_getdirentries ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4); |
6420 | PRE_REG_READ4(ssize_t, "getdirentries", | |
6421 | int, fd, char *, buf, | |
6422 | size_t, nbytes, | |
6423 | off_t *, basep); | |
6424 | PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); | |
227fa1d5 | 6425 | if (ARG4) { |
76d6b459 | 6426 | PRE_MEM_WRITE("getdirentries(basep)", ARG4, sizeof (vki_off_t)); |
227fa1d5 | 6427 | } |
e2e5d75f PF |
6428 | } |
6429 | ||
6430 | POST(sys_getdirentries) | |
6431 | { | |
6432 | vg_assert(SUCCESS); | |
6433 | if (RES > 0) { | |
76d6b459 PF |
6434 | POST_MEM_WRITE( ARG2, RES ); |
6435 | if ( ARG4 != 0 ) { | |
6436 | POST_MEM_WRITE( ARG4, sizeof (vki_off_t)); | |
227fa1d5 | 6437 | } |
e2e5d75f PF |
6438 | } |
6439 | } | |
6440 | ||
6441 | // SYS_statfs 555 | |
6442 | // int statfs(const char *path, struct statfs *buf); | |
6443 | PRE(sys_statfs) | |
6444 | { | |
76d6b459 PF |
6445 | PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); |
6446 | PRE_REG_READ2(int, "statfs", const char *, path, struct statfs *, buf); | |
6447 | PRE_MEM_RASCIIZ( "statfs(path)", ARG1 ); | |
6448 | PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) ); | |
e2e5d75f PF |
6449 | } |
6450 | ||
76d6b459 PF |
6451 | POST(sys_statfs) |
6452 | { | |
6453 | POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) ); | |
6454 | } | |
e2e5d75f PF |
6455 | |
6456 | // SYS_fstatfs 556 | |
6457 | // int fstatfs(int fd, struct statfs *buf); | |
6458 | PRE(sys_fstatfs) | |
6459 | { | |
76d6b459 PF |
6460 | PRINT("sys_fstatfs ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); |
6461 | PRE_REG_READ2(int, "fstatfs", | |
6462 | int, fd, struct vki_statfs *, buf); | |
6463 | PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) ); | |
e2e5d75f PF |
6464 | } |
6465 | ||
76d6b459 PF |
6466 | POST(sys_fstatfs) |
6467 | { | |
6468 | POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) ); | |
6469 | } | |
e2e5d75f PF |
6470 | |
6471 | // SYS_getfsstat 557 | |
6472 | // int getfsstat(struct statfs *buf, long bufsize, int mode); | |
6473 | PRE(sys_getfsstat) | |
6474 | { | |
76d6b459 PF |
6475 | PRINT("sys_getfsstat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); |
6476 | PRE_REG_READ3(long, "getfsstat", struct vki_statfs *, buf, long, len, int, flags); | |
6477 | PRE_MEM_WRITE( "getfsstat(buf)", ARG1, ARG2 ); | |
e2e5d75f PF |
6478 | } |
6479 | ||
6480 | POST(sys_getfsstat) | |
6481 | { | |
6482 | vg_assert(SUCCESS); | |
6483 | if ((Word)RES != -1) { | |
76d6b459 | 6484 | POST_MEM_WRITE( ARG1, RES * sizeof(struct vki_statfs) ); |
e2e5d75f PF |
6485 | } |
6486 | } | |
6487 | ||
6488 | // SYS_fhstatfs 558 | |
6489 | // int fhstatfs(const fhandle_t *fhp, struct statfs *buf); | |
6490 | PRE(sys_fhstatfs) | |
6491 | { | |
76d6b459 PF |
6492 | PRINT("sys_fhstatfs ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); |
6493 | PRE_REG_READ2(long, "fhstatfs", | |
6494 | struct fhandle *, fhp, struct statfs *, buf); | |
6495 | PRE_MEM_READ( "fhstatfs(fhp)", ARG1, sizeof(struct vki_fhandle) ); | |
6496 | PRE_MEM_WRITE( "fhstatfs(buf)", ARG2, sizeof(struct vki_statfs) ); | |
e2e5d75f PF |
6497 | } |
6498 | ||
76d6b459 PF |
6499 | POST(sys_fhstatfs) |
6500 | { | |
6501 | POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) ); | |
6502 | } | |
e2e5d75f PF |
6503 | |
6504 | // SYS_mknodat 559 | |
f6f7cae6 | 6505 | // x86 / amd64 |
e2e5d75f PF |
6506 | |
6507 | // SYS_kevent 560 | |
6508 | // int kevent(int kq, const struct kevent *changelist, int nchanges, | |
6509 | // struct kevent *eventlist, int nevents, | |
6510 | // const struct timespec *timeout); | |
6511 | PRE(sys_kevent) | |
6512 | { | |
76d6b459 PF |
6513 | PRINT("sys_kevent ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )\n", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); |
6514 | PRE_REG_READ6(int, "kevent", | |
6515 | int, kq, struct vki_kevent *, changelist, int, nchanges, | |
6516 | struct vki_kevent *, eventlist, int, nevents, | |
6517 | struct timespec *, timeout); | |
29cfa77b | 6518 | if (ARG2 != 0 && ARG3 != 0) { |
76d6b459 | 6519 | PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent)*ARG3 ); |
29cfa77b PF |
6520 | } |
6521 | if (ARG4 != 0 && ARG5 != 0) { | |
76d6b459 | 6522 | PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent)*ARG5); |
29cfa77b PF |
6523 | } |
6524 | if (ARG5 != 0) { | |
e2e5d75f | 6525 | *flags |= SfMayBlock; |
29cfa77b PF |
6526 | } |
6527 | if (ARG6 != 0) { | |
76d6b459 PF |
6528 | PRE_MEM_READ( "kevent(timeout)", |
6529 | ARG6, sizeof(struct vki_timespec)); | |
29cfa77b | 6530 | } |
e2e5d75f PF |
6531 | } |
6532 | ||
6533 | POST(sys_kevent) | |
6534 | { | |
6535 | vg_assert(SUCCESS); | |
6536 | if ((Word)RES != -1) { | |
29cfa77b | 6537 | if (ARG4 != 0) { |
76d6b459 | 6538 | POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent)*RES) ; |
29cfa77b | 6539 | } |
e2e5d75f PF |
6540 | } |
6541 | } | |
6542 | ||
6543 | // SYS_cpuset_getdomain 561 | |
6544 | // x86 / amd64 | |
6545 | ||
6546 | // SYS_cpuset_setdomain 562 | |
6547 | // x86 / amd64 | |
6548 | ||
6549 | // SYS_getrandom 563 | |
6550 | // ssize_t getrandom(void *buf, size_t buflen, unsigned int flags); | |
6551 | PRE(sys_getrandom) | |
6552 | { | |
76d6b459 PF |
6553 | PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); |
6554 | PRE_REG_READ3(ssize_t, "getrandom", | |
6555 | void *, buf, vki_size_t, buflen, unsigned int, flags); | |
6556 | PRE_MEM_WRITE( "getrandom(buf)", ARG1, ARG2 ); | |
e2e5d75f PF |
6557 | if ((ARG3 & VKI_GRND_NONBLOCK) == 0) { |
6558 | *flags |= SfMayBlock; | |
6559 | } | |
6560 | } | |
6561 | ||
76d6b459 PF |
6562 | POST(sys_getrandom) |
6563 | { | |
6564 | POST_MEM_WRITE( ARG1, ARG2 ); | |
6565 | } | |
e2e5d75f PF |
6566 | |
6567 | // SYS_getfhat 564 | |
6568 | // int getfhat(int fd, const char *path, fhandle_t *fhp, int flag); | |
6569 | PRE(sys_getfhat) | |
6570 | { | |
76d6b459 PF |
6571 | PRINT("sys_getfhat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "x, %" FMT_REGWORD "d ", SARG1, ARG2, ARG3, SARG4); |
6572 | PRE_REG_READ4(int, "getfhat", int, fd, const char*, path, vki_fhandle_t*, fhp, int, flag); | |
6573 | PRE_MEM_RASCIIZ( "getfhat(path)", ARG2 ); | |
e2e5d75f PF |
6574 | PRE_MEM_WRITE("getfhat(fhp)", ARG3, sizeof(vki_fhandle_t)); |
6575 | } | |
6576 | ||
76d6b459 PF |
6577 | POST(sys_getfhat) |
6578 | { | |
6579 | POST_MEM_WRITE(ARG3, sizeof(vki_fhandle_t)); | |
6580 | } | |
e2e5d75f PF |
6581 | |
6582 | // SYS_fhlink 565 | |
6583 | // int fhlink(fhandle_t *fhp, const char *to); | |
6584 | PRE(sys_fhlink) | |
6585 | { | |
6586 | PRINT("sys_fhlink ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2); | |
76d6b459 PF |
6587 | PRE_REG_READ2(int, "fhlink", vki_fhandle_t *, fhp, const char *, to); |
6588 | PRE_MEM_READ( "fhlink(fhp)", ARG1, sizeof(vki_fhandle_t)); | |
e2e5d75f PF |
6589 | PRE_MEM_RASCIIZ("fhlink(buf)", ARG2); |
6590 | } | |
6591 | ||
6592 | // SYS_fhlinkat 566 | |
6593 | // int fhlinkat(fhandle_t *fhp, int tofd, const char *to); | |
6594 | PRE(sys_fhlinkat) | |
6595 | { | |
76d6b459 PF |
6596 | PRINT("sys_fhlinkat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "xu ", ARG1, SARG2, ARG3); |
6597 | PRE_REG_READ3(int, "fhlinkat", vki_fhandle_t *, fhp, int, tofd, const char *, to); | |
6598 | PRE_MEM_READ( "fhlinkat(fhp)", ARG1, sizeof(vki_fhandle_t)); | |
e2e5d75f PF |
6599 | PRE_MEM_RASCIIZ("fhreadlink(to)", ARG3); |
6600 | } | |
6601 | ||
6602 | // SYS_fhreadlink 567 | |
6603 | // int fhreadlink(fhandle_t *fhp, char *buf, size_t bufsize); | |
6604 | PRE(sys_fhreadlink) | |
6605 | { | |
76d6b459 PF |
6606 | PRINT("sys_fhreadlink ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x, %" FMT_REGWORD "u ", ARG1, ARG2, ARG3); |
6607 | PRE_REG_READ3(int, "fhreadlink", vki_fhandle_t *, fhp, char *, buf, size_t, bufsize); | |
6608 | PRE_MEM_READ( "fhreadlink(fhp)", ARG1, sizeof(vki_fhandle_t)); | |
e2e5d75f PF |
6609 | PRE_MEM_WRITE("fhreadlink(buf)", ARG2, ARG3); |
6610 | } | |
6611 | ||
76d6b459 PF |
6612 | POST(sys_fhreadlink) |
6613 | { | |
6614 | POST_MEM_WRITE(ARG2, ARG3); | |
6615 | } | |
e2e5d75f PF |
6616 | |
6617 | #endif | |
6618 | ||
6619 | #if (FREEBSD_VERS >= FREEBSD_12_2) | |
6620 | ||
3ce76737 PF |
6621 | // SYS_unlinkat 568 |
6622 | // int funlinkat(int dfd, const char *path, int fd, int flag); | |
6623 | PRE(sys_funlinkat) | |
6624 | { | |
6625 | *flags |= SfMayBlock; | |
76d6b459 | 6626 | PRINT("sys_funlinkat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD"u )", |
3ce76737 | 6627 | SARG1, ARG2, (char*)ARG2, ARG4, ARG5); |
76d6b459 PF |
6628 | PRE_REG_READ4(int, "funlinkat", int, dfd, const char *, path, int, fd, int, flag); |
6629 | PRE_MEM_RASCIIZ( "funlinkat(path)", ARG2 ); | |
3ce76737 PF |
6630 | } |
6631 | ||
6632 | // SYS_copy_file_range 569 | |
6633 | // ssize_t copy_file_range(int infd, off_t *inoffp, int outfd, off_t *outoffp, | |
6634 | // size_t len, unsigned int flags); | |
6635 | PRE(sys_copy_file_range) | |
6636 | { | |
76d6b459 | 6637 | PRINT("sys_copy_file_range (%" FMT_REGWORD"d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "d, %" FMT_REGWORD "d)", |
227fa1d5 PF |
6638 | SARG1, ARG2, SARG3, ARG4, (char*)ARG4, SARG5, SARG6); |
6639 | ||
76d6b459 PF |
6640 | PRE_REG_READ6(vki_ssize_t, "copy_file_range", |
6641 | int, "infd", | |
6642 | vki_off_t *, "inoffp", | |
6643 | int, "outfd", | |
6644 | vki_off_t *, "outoffp", | |
6645 | vki_size_t, "len", | |
6646 | unsigned int, "flags"); | |
227fa1d5 PF |
6647 | |
6648 | /* File descriptors are "specially" tracked by valgrind. | |
6649 | valgrind itself uses some, so make sure someone didn't | |
6650 | put in one of our own... */ | |
6651 | if (!ML_(fd_allowed)(ARG1, "copy_file_range(infd)", tid, False) || | |
6652 | !ML_(fd_allowed)(ARG3, "copy_file_range(infd)", tid, False)) { | |
76d6b459 | 6653 | SET_STATUS_Failure( VKI_EBADF ); |
227fa1d5 PF |
6654 | } else { |
6655 | /* Now see if the offsets are defined. PRE_MEM_READ will | |
6656 | double check it can dereference them. */ | |
6657 | if (ARG2 != 0) { | |
76d6b459 | 6658 | PRE_MEM_READ( "copy_file_range(inoffp)", ARG2, sizeof(vki_off_t)); |
227fa1d5 PF |
6659 | } |
6660 | if (ARG4 != 0) { | |
76d6b459 | 6661 | PRE_MEM_READ( "copy_file_range(outoffp)", ARG4, sizeof(vki_off_t)); |
227fa1d5 PF |
6662 | } |
6663 | } | |
3ce76737 PF |
6664 | } |
6665 | ||
76d6b459 | 6666 | |
6db18bae | 6667 | // SYS___sysctlbyname 570 |
e2e5d75f PF |
6668 | // int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, |
6669 | // const void *newp, size_t newlen); | |
6670 | // syscalls.master: | |
6671 | // int __sysctlbyname(_In_reads_(namelen) const char *name, size_t namelen, | |
6672 | // _Out_writes_bytes_opt_(*oldlenp) void *old, | |
76d6b459 PF |
6673 | // _Inout_opt_ size_t *oldlenp, _In_reads_bytes_opt_(newlen) void *new, |
6674 | // size_t newlen ); | |
e2e5d75f PF |
6675 | PRE(sys___sysctlbyname) |
6676 | { | |
6677 | // this is very much like SYS___sysctl, instead of having an OID with length | |
6678 | // here threre is an ascii string with length | |
6679 | // @todo PJF factor out the common functionality of the two | |
76d6b459 PF |
6680 | PRINT("sys___sysctlbyname ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,(const char*)ARG1,ARG2,ARG3,ARG4,ARG5 ); |
6681 | PRE_REG_READ6(int, "__sysctlbyname", const char *, name, vki_size_t, namelen, | |
6682 | void *, oldp, vki_size_t *, oldlenp, | |
6683 | void *, newp, vki_size_t, newlen); | |
6684 | ||
9f27d8fb PF |
6685 | |
6686 | const char* name = (const char*)ARG1; | |
6687 | if (ML_(safe_to_deref)(name, sizeof("kern.ps_strings")) && | |
6688 | VG_(strcmp)(name, "kern.ps_strings") == 0) { | |
6689 | if (sysctl_kern_ps_strings((SizeT*)ARG3, (SizeT*)ARG4)) { | |
b29a1e1c | 6690 | SET_STATUS_Success(0); |
9f27d8fb PF |
6691 | } |
6692 | } | |
6693 | ||
b29a1e1c | 6694 | if (ML_(safe_to_deref)(name, sizeof("kern.usrstack")) && |
76d6b459 | 6695 | VG_(strcmp)(name, "kern.usrstack") == 0) { |
db0bfcc6 | 6696 | sysctl_kern_usrstack((SizeT*)ARG3, (SizeT*)ARG4); |
b29a1e1c PF |
6697 | SET_STATUS_Success(0); |
6698 | } | |
6699 | ||
5830ece5 PF |
6700 | // kern.proc.pathname doesn't seem to be handled |
6701 | // makes sense as the pid is variable and using | |
6702 | // a MIB is easier than generating a string | |
5d387642 | 6703 | |
ac7b5a20 PF |
6704 | // string length specified in ARG2 from mem pointed to by ARG1 |
6705 | PRE_MEM_READ("__sysctlbyname(name)", (Addr)ARG1, ARG2); | |
e2e5d75f PF |
6706 | |
6707 | // if 'newp' is not NULL can read namelen bytes from that addess | |
227fa1d5 | 6708 | if (ARG5 != (UWord)NULL) { |
e2e5d75f | 6709 | PRE_MEM_READ("__sysctlbyname(newp)", (Addr)ARG5, ARG6); |
227fa1d5 | 6710 | } |
e2e5d75f PF |
6711 | |
6712 | // there are two scenarios for oldlenp/oldp | |
6713 | // 1. oldval is NULL and oldlenp is non-NULL | |
6714 | // this is a query of oldlenp so oldlenp will be written | |
6715 | // 2. Both are non-NULL | |
6716 | // this is a query of oldp, oldlenp will be read and oldp will | |
6717 | // be written | |
6718 | ||
6719 | // is oldlenp is not NULL, can write | |
6720 | if (ARG4 != (UWord)NULL) { | |
6721 | if (ARG3 != (UWord)NULL) { | |
6722 | // case 2 above | |
76d6b459 | 6723 | PRE_MEM_READ("__sysctlbyname(oldlenp)", (Addr)ARG4, sizeof(vki_size_t)); |
e2e5d75f | 6724 | if (ML_(safe_to_deref)((void*)(Addr)ARG4, sizeof(vki_size_t))) { |
76d6b459 | 6725 | PRE_MEM_WRITE("__sysctlbyname(oldp)", (Addr)ARG3, *(vki_size_t *)ARG4); |
e2e5d75f | 6726 | } else { |
9f27d8fb | 6727 | VG_(dmsg)("Warning: Bad oldlenp address %p in sysctlbyname\n", |
76d6b459 PF |
6728 | (void *)(Addr)ARG4); |
6729 | SET_STATUS_Failure ( VKI_EFAULT ); | |
e2e5d75f PF |
6730 | } |
6731 | } else { | |
6732 | // case 1 above | |
76d6b459 | 6733 | PRE_MEM_WRITE("__sysctlbyname(oldlenp)", (Addr)ARG4, sizeof(vki_size_t)); |
e2e5d75f PF |
6734 | } |
6735 | } | |
6736 | } | |
6737 | ||
6738 | POST(sys___sysctlbyname) | |
6739 | { | |
6740 | if (ARG4 != (UWord)NULL) { | |
6741 | if (ARG3 != (UWord)NULL) { | |
76d6b459 PF |
6742 | //POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); |
6743 | POST_MEM_WRITE((Addr)ARG3, *(vki_size_t *)ARG4); | |
227fa1d5 | 6744 | } else { |
e2e5d75f | 6745 | POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t)); |
227fa1d5 | 6746 | } |
e2e5d75f PF |
6747 | } |
6748 | } | |
6749 | ||
6db18bae PF |
6750 | #endif // (FREEBSD_VERS >= FREEBSD_12_2) |
6751 | ||
bbc3bcab | 6752 | #if (FREEBSD_VERS >= FREEBSD_13_0) |
6db18bae | 6753 | |
3a883a6c PF |
6754 | // SYS_shm_open2 571 |
6755 | // from syscalls.master | |
6756 | // int shm_open2(_In_z_ const char *path, | |
6757 | // int flags, | |
6758 | // mode_t mode, | |
6759 | // int shmflags, | |
6760 | // _In_z_ const char *name); | |
6761 | PRE(sys_shm_open2) | |
6762 | { | |
76d6b459 PF |
6763 | PRE_REG_READ5(int, "shm_open2", |
6764 | const char *, path, int, flags, vki_mode_t, mode, int, shmflags, const char*, name); | |
3a883a6c | 6765 | if (ARG1 == VKI_SHM_ANON) { |
76d6b459 | 6766 | PRINT("sys_shm_open2(%#" FMT_REGWORD "x(SHM_ANON), %" FMT_REGWORD "u, %hu, %d, %#" FMT_REGWORD "x(%s))", |
3a883a6c PF |
6767 | ARG1, ARG2, (vki_mode_t)ARG3, (Int)ARG4, ARG5, (HChar*)ARG5); |
6768 | } else { | |
76d6b459 PF |
6769 | PRINT("sys_shm_open2(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu, %d, %#" FMT_REGWORD "x(%s))", |
6770 | ARG1, (HChar *)ARG1, ARG2, (vki_mode_t)ARG3, (Int)ARG4, ARG5, (HChar*)ARG5); | |
6771 | PRE_MEM_RASCIIZ( "shm_open2(path)", ARG1 ); | |
3a883a6c PF |
6772 | } |
6773 | ||
d99b369c | 6774 | if (ARG5) { |
76d6b459 | 6775 | PRE_MEM_RASCIIZ( "shm_open2(name)", ARG5 ); |
d99b369c | 6776 | } |
3a883a6c PF |
6777 | *flags |= SfMayBlock; |
6778 | } | |
6779 | ||
6780 | POST(sys_shm_open2) | |
6781 | { | |
6782 | vg_assert(SUCCESS); | |
6783 | if (!ML_(fd_allowed)(RES, "shm_open2", tid, True)) { | |
6784 | VG_(close)(RES); | |
76d6b459 | 6785 | SET_STATUS_Failure( VKI_EMFILE ); |
3a883a6c | 6786 | } else { |
227fa1d5 | 6787 | if (VG_(clo_track_fds)) { |
3a883a6c | 6788 | ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); |
227fa1d5 | 6789 | } |
3a883a6c PF |
6790 | } |
6791 | } | |
6792 | ||
d4c9a985 | 6793 | // SYS_sigfastblock 573 |
9f27d8fb PF |
6794 | // int sigfastblock(int cmd, void *ptr); |
6795 | PRE(sys_sigfastblock) | |
6796 | { | |
76d6b459 | 6797 | PRINT("sys_sigfastblock ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2); |
9f27d8fb PF |
6798 | PRE_REG_READ2(int, "sigfasblock", int, cmd, void*, ptr); |
6799 | } | |
6800 | ||
3a883a6c | 6801 | // SYS___realpathat 574 |
bb178889 PF |
6802 | // from syscalls.master |
6803 | // int __realpathat(int fd, | |
6804 | // _In_z_ const char *path, | |
6805 | // _Out_writes_z_(size) char *buf, | |
6806 | // size_t size, | |
6807 | // int flags) | |
6808 | PRE(sys___realpathat) | |
6809 | { | |
76d6b459 PF |
6810 | PRINT("sys___realpathat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "u %" FMT_REGWORD "d )", |
6811 | SARG1,ARG2,(const char*)ARG2,ARG3,ARG4,SARG5 ); | |
6812 | PRE_REG_READ5(int, "__realpathat", int, fd, const char *, path, | |
6813 | char *, buf, vki_size_t, size, int, flags); | |
bb178889 PF |
6814 | PRE_MEM_RASCIIZ("__realpathat(path)", (Addr)ARG2); |
6815 | PRE_MEM_WRITE("__realpathat(buf)", (Addr)ARG3, ARG4); | |
6816 | } | |
6817 | ||
ec86369d PF |
6818 | POST(sys___realpathat) |
6819 | { | |
6820 | POST_MEM_WRITE((Addr)ARG3, ARG4); | |
6821 | } | |
6822 | ||
6823 | #endif | |
6824 | ||
6825 | #if (FREEBSD_VERS >= FREEBSD_12_2) | |
6826 | ||
d4c9a985 PF |
6827 | // SYS_sys_close_range 575 |
6828 | // int close_range(close_range(u_int lowfd, u_int highfd, int flags); | |
6829 | PRE(sys_close_range) | |
6830 | { | |
6831 | SysRes res = VG_(mk_SysRes_Success)(0); | |
6832 | unsigned int lowfd = ARG1; | |
6833 | unsigned int fd_counter; // will count from lowfd to highfd | |
6834 | unsigned int highfd = ARG2; | |
6835 | ||
6836 | /* on linux the may lock if futexes are used | |
6837 | * there is a lock in the kernel but I assume it's just | |
6838 | * a spinlock */ | |
6839 | PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" | |
6840 | FMT_REGWORD "d )", ARG1, ARG2, SARG3); | |
6841 | PRE_REG_READ3(int, "close_range", | |
6842 | unsigned int, lowfd, unsigned int, highfd, | |
6843 | int, flags); | |
6844 | ||
6845 | if (lowfd > highfd) { | |
6846 | SET_STATUS_Failure( VKI_EINVAL ); | |
6847 | return; | |
6848 | } | |
6849 | ||
6850 | if (highfd >= VG_(fd_hard_limit)) | |
6851 | highfd = VG_(fd_hard_limit) - 1; | |
6852 | ||
6853 | if (lowfd > highfd) { | |
6854 | SET_STATUS_Success ( 0 ); | |
6855 | return; | |
6856 | } | |
6857 | ||
6858 | fd_counter = lowfd; | |
6859 | do { | |
6860 | if (fd_counter > highfd | |
6861 | || (fd_counter == 2U/*stderr*/ && VG_(debugLog_getLevel)() > 0) | |
6862 | || fd_counter == VG_(log_output_sink).fd | |
6863 | || fd_counter == VG_(xml_output_sink).fd) { | |
6864 | /* Split the range if it contains a file descriptor we're not | |
6865 | * supposed to close. */ | |
6866 | if (fd_counter - 1 >= lowfd) { | |
6867 | res = VG_(do_syscall3)(__NR_close_range, (UWord)lowfd, (UWord)fd_counter - 1, ARG3 ); | |
6868 | } | |
6869 | lowfd = fd_counter + 1; | |
6870 | } | |
6871 | } while (fd_counter++ <= highfd); | |
6872 | ||
6873 | /* If it failed along the way, it's presumably the flags being wrong. */ | |
6874 | SET_STATUS_from_SysRes (res); | |
6875 | } | |
6876 | ||
6877 | POST(sys_close_range) | |
6878 | { | |
6879 | unsigned int fd; | |
6880 | unsigned int last = ARG2; | |
6881 | ||
6882 | if (!VG_(clo_track_fds) | |
6883 | || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0) | |
6884 | return; | |
6885 | ||
6886 | if (last >= VG_(fd_hard_limit)) | |
6887 | last = VG_(fd_hard_limit) - 1; | |
6888 | ||
6889 | for (fd = ARG1; fd <= last; fd++) | |
6890 | if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0) | |
6891 | && fd != VG_(log_output_sink).fd | |
6892 | && fd != VG_(xml_output_sink).fd) | |
6a28e665 | 6893 | ML_(record_fd_close)(tid, fd); |
d4c9a985 | 6894 | } |
ec86369d | 6895 | #endif |
d4c9a985 | 6896 | |
ec86369d | 6897 | #if (FREEBSD_VERS >= FREEBSD_13_0) |
bb178889 | 6898 | |
6db18bae | 6899 | // SYS___specialfd 577 |
bb178889 PF |
6900 | // syscalls.master |
6901 | // int __specialfd(int type, | |
6902 | // _In_reads_bytes_(len) const void *req, | |
6903 | // size_t len); | |
6904 | PRE(sys___specialfd) | |
6905 | { | |
76d6b459 PF |
6906 | PRINT("sys___specialfd ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", |
6907 | SARG1,ARG2,(const char*)ARG2,ARG3 ); | |
6908 | PRE_REG_READ3(int, "__specialfd", int, type, const void *, req, vki_size_t, len); | |
bb178889 PF |
6909 | PRE_MEM_READ("__specialfd(req)", (Addr)ARG2, ARG3); |
6910 | } | |
6911 | ||
a15b387e PF |
6912 | // SYS_aio_writev 578 |
6913 | // int aio_writev(struct aiocb *iocb); | |
6914 | PRE(sys_aio_writev) | |
6915 | { | |
6916 | PRINT("sys_aio_writev ( %#" FMT_REGWORD "x )", ARG1); | |
6917 | PRE_REG_READ1(int, "aio_writev", struct vki_aiocb *, iocb); | |
6918 | PRE_MEM_READ("aio_writev(iocb)", ARG1, sizeof(struct vki_aiocb)); | |
6919 | if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) { | |
6920 | struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1; | |
6921 | if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_writev", tid, False)) { | |
6922 | SET_STATUS_Failure( VKI_EBADF ); | |
6923 | } else { | |
6924 | // aio_writev() gathers the data from the iocb->aio_iovcnt buffers specified | |
6925 | // by the members of the iocb->aio_iov array | |
6926 | // FreeBSD headers #define define this to aio_iovcnt | |
6927 | SizeT vec_count = (SizeT)iocb->aio_nbytes; | |
5d297459 PF |
6928 | #if defined(__clang__) |
6929 | #pragma clang diagnostic push | |
6930 | // yes, I know it is volatile | |
6931 | #pragma clang diagnostic ignored "-Wcast-qual" | |
6932 | #endif | |
a15b387e | 6933 | struct vki_iovec* p_iovec = (struct vki_iovec*)iocb->aio_buf; |
5d297459 PF |
6934 | #if defined(__clang__) |
6935 | #pragma clang diagnostic pop | |
6936 | #endif | |
a15b387e PF |
6937 | PRE_MEM_READ("aio_writev(iocb->aio_iov)", (Addr)p_iovec, vec_count*sizeof(struct vki_iovec)); |
6938 | // and this to aio_iov | |
6939 | ||
6940 | if (ML_(safe_to_deref)(p_iovec, vec_count*sizeof(struct vki_iovec))) { | |
6941 | for (SizeT i = 0U; i < vec_count; ++i) { | |
6942 | PRE_MEM_READ("aio_writev(iocb->iov[...])", | |
6943 | (Addr)p_iovec[i].iov_base, p_iovec[i].iov_len); | |
6944 | } | |
6945 | } | |
6946 | } | |
6947 | } else { | |
6948 | SET_STATUS_Failure(VKI_EINVAL); | |
6949 | } | |
6950 | } | |
6951 | ||
6952 | // SYS_aio_readv 579 | |
6953 | // int aio_readv(struct aiocb *iocb); | |
6954 | PRE(sys_aio_readv) | |
6955 | { | |
6956 | PRINT("sys_aio_readv ( %#" FMT_REGWORD "x )", ARG1); | |
6957 | PRE_REG_READ1(int, "aio_readv", struct vki_aiocb *, iocb); | |
6958 | PRE_MEM_READ("aio_readv(iocb)", ARG1, sizeof(struct vki_aiocb)); | |
6959 | if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) { | |
6960 | struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1; | |
6961 | if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_readv", tid, False)) { | |
6962 | SET_STATUS_Failure( VKI_EBADF ); | |
6963 | } else { | |
6964 | SizeT vec_count = (SizeT)iocb->aio_nbytes; | |
5d297459 PF |
6965 | #if defined(__clang__) |
6966 | #pragma clang diagnostic push | |
6967 | // yes, I know it is volatile | |
6968 | #pragma clang diagnostic ignored "-Wcast-qual" | |
6969 | #endif | |
a15b387e | 6970 | struct vki_iovec* p_iovec = (struct vki_iovec*)iocb->aio_buf; |
5d297459 PF |
6971 | #if defined(__clang__) |
6972 | #pragma clang diagnostic pop | |
6973 | #endif | |
a15b387e | 6974 | PRE_MEM_READ("aio_readv(iocb->aio_iov)", (Addr)p_iovec, vec_count*sizeof(struct vki_iovec)); |
b748cc9e | 6975 | if (ML_(safe_to_deref)(p_iovec, vec_count*sizeof(struct vki_iovec))) { |
a15b387e PF |
6976 | for (SizeT i = 0U; i < vec_count; ++i) { |
6977 | PRE_MEM_WRITE("aio_writev(iocb->aio_iov[...])", | |
6978 | (Addr)p_iovec[i].iov_base, p_iovec[i].iov_len); | |
6979 | } | |
6980 | } | |
6981 | } | |
6982 | } else { | |
6983 | SET_STATUS_Failure(VKI_EINVAL); | |
6984 | } | |
6985 | } | |
6986 | ||
6987 | POST(sys_aio_readv) | |
6988 | { | |
6989 | struct vki_aiocb* iocbv = (struct vki_aiocb*)ARG1; | |
6990 | if (iocbv->aio_buf) { | |
6991 | if (!aiov_init_done) { | |
6992 | aiov_init(); | |
6993 | } | |
6994 | ||
6995 | if (!VG_(OSetWord_Contains)(iocbv_table, (UWord)iocbv)) { | |
6996 | VG_(OSetWord_Insert)(iocbv_table, (UWord)iocbv); | |
6997 | } else { | |
60c8821f | 6998 | // @todo PJF this warns without callstack |
a15b387e PF |
6999 | VG_(dmsg)("Warning: Duplicate control block %p in aio_readv\n", |
7000 | (void *)(Addr)ARG1); | |
7001 | VG_(dmsg)("Warning: Ensure 'aio_return' is called when 'aio_readv' has completed\n"); | |
7002 | } | |
7003 | } | |
7004 | } | |
7005 | ||
f540c799 | 7006 | #endif // (FREEBSD_VERS >= FREEBSD_13_0) |
e2e5d75f | 7007 | |
6cb8e52c | 7008 | #if (FREEBSD_VERS >= FREEBSD_13_1) |
cdd98111 | 7009 | |
3cacde0c PF |
7010 | #if (FREEBSD_VERS >= FREEBSD_14) |
7011 | // SYS_fspacectl 580 | |
7012 | // int fspacectl(int fd, int cmd, const struct spacectl_range *rqsr, int flags, | |
7013 | // struct spacectl_range *rmsr); | |
7014 | PRE(sys_fspacectl) | |
7015 | { | |
7016 | PRINT("fspacectl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3, SARG4, ARG5); | |
7017 | PRE_REG_READ5(int, "fspacectl", int, fd, int, cmd, const struct spacectl_range *, rqsr, int, flags, struct spacectl_range *, rmsr); | |
7018 | PRE_MEM_READ("fspacectl(rqsr)", (Addr)ARG3, sizeof(struct vki_spacectl_range)); | |
7019 | if (ARG5) { | |
7020 | PRE_MEM_WRITE("fspacectl(rmsr)", (Addr)ARG5, sizeof(struct vki_spacectl_range)); | |
7021 | } | |
7022 | } | |
7023 | ||
7024 | POST(sys_fspacectl) | |
7025 | { | |
7026 | if (ARG5) { | |
7027 | POST_MEM_WRITE((Addr)ARG5, sizeof(struct vki_spacectl_range)); | |
7028 | } | |
7029 | } | |
7030 | #endif | |
7031 | ||
cdd98111 PF |
7032 | // SYS_swapoff 582 |
7033 | // int swapoff(const char *special, u_int flags); | |
7034 | PRE(sys_swapoff) | |
7035 | { | |
410adb9b | 7036 | PRINT("sys_swapoff(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u)", ARG1,(char *)ARG1, ARG2); |
76d6b459 PF |
7037 | PRE_REG_READ2(int, "swapoff", const char *, special, u_int, flags); |
7038 | PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 ); | |
cdd98111 PF |
7039 | } |
7040 | ||
7041 | #endif | |
7042 | ||
32ca31e9 | 7043 | #if (FREEBSD_VERS >= FREEBSD_15) || (FREEBSD_VERS >= FREEBSD_13_3) |
adf7cb52 | 7044 | |
410adb9b PF |
7045 | // SYS_kqueuex 583 |
7046 | // int kqueuex(u_int flags); | |
7047 | PRE(sys_kqueuex) | |
7048 | { | |
7049 | PRINT("sys_kqueuex(%#" FMT_REGWORD "x)", ARG1); | |
7050 | PRE_REG_READ1(int, "kqueuex", u_int, flags); | |
7051 | } | |
7052 | ||
7053 | POST(sys_kqueuex) | |
7054 | { | |
7055 | if (!ML_(fd_allowed)(RES, "kqueuex", tid, True)) { | |
7056 | VG_(close)(RES); | |
7057 | SET_STATUS_Failure(VKI_EMFILE); | |
7058 | } else { | |
7059 | if (VG_(clo_track_fds)) { | |
7060 | ML_(record_fd_open_nameless)(tid, RES); | |
7061 | } | |
7062 | } | |
7063 | } | |
adf7cb52 | 7064 | |
22069cd2 PF |
7065 | // SYS_membarrier 584 |
7066 | // syscalls.master | |
7067 | // int membarrier(int cmd, unsigned flags, int cpu_id); | |
7068 | PRE(sys_membarrier) | |
7069 | { | |
7070 | // cmd is signed int but the constants in the headers | |
7071 | // are hex so print in hex | |
7072 | PRINT("sys_membarrier(%#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "d)", | |
7073 | ARG1, ARG2, SARG3); | |
7074 | PRE_REG_READ3(int, "membarrier", int, cmd, unsigned, flags, int, cpu_id); | |
7075 | } | |
adf7cb52 | 7076 | |
32ca31e9 PF |
7077 | #endif |
7078 | ||
7079 | #if (FREEBSD_VERS >= FREEBSD_15) | |
7080 | ||
adf7cb52 PF |
7081 | // SYS_timerfd_create 585 |
7082 | // int timerfd_create(int clockid, int flags); | |
7083 | PRE(sys_timerfd_create) | |
7084 | { | |
7085 | PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2); | |
7086 | PRE_REG_READ2(int, "timerfd_create", int, clockid, int, flags); | |
7087 | } | |
7088 | ||
7089 | POST(sys_timerfd_create) | |
7090 | { | |
7091 | if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) { | |
7092 | VG_(close)(RES); | |
7093 | SET_STATUS_Failure( VKI_EMFILE ); | |
7094 | } else { | |
7095 | if (VG_(clo_track_fds)) | |
7096 | ML_(record_fd_open_nameless) (tid, RES); | |
7097 | } | |
7098 | } | |
7099 | ||
7100 | // SYS_timerfd_gettime 586 | |
7101 | // int timerfd_gettime(int fd, struct itimerspec *curr_value); | |
7102 | PRE(sys_timerfd_gettime) | |
7103 | { | |
7104 | PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2); | |
7105 | PRE_REG_READ2(int, "timerfd_gettime", | |
7106 | int, fd, | |
7107 | struct vki_itimerspec*, curr_value); | |
7108 | if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False)) | |
7109 | SET_STATUS_Failure(VKI_EBADF); | |
7110 | else | |
7111 | PRE_MEM_WRITE("timerfd_gettime(curr_value)", | |
7112 | ARG2, sizeof(struct vki_itimerspec)); | |
7113 | } | |
7114 | ||
7115 | POST(sys_timerfd_gettime) | |
7116 | { | |
7117 | if (RES == 0) | |
7118 | POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec)); | |
7119 | } | |
7120 | ||
7121 | // SYS_timerfd_gettime 587 | |
7122 | // int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, | |
7123 | // struct itimerspec *old_value); | |
7124 | PRE(sys_timerfd_settime) | |
7125 | { | |
7126 | PRINT("sys_timerfd_settime(%" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" | |
7127 | FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4); | |
7128 | PRE_REG_READ4(int, "timerfd_settime", | |
7129 | int, fd, | |
7130 | int, flags, | |
7131 | const struct vki_itimerspec*, new_value, | |
7132 | struct vki_itimerspec*, old_value); | |
7133 | if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False)) | |
7134 | SET_STATUS_Failure(VKI_EBADF); | |
7135 | else | |
7136 | { | |
7137 | PRE_MEM_READ("timerfd_settime(new_value)", | |
7138 | ARG3, sizeof(struct vki_itimerspec)); | |
7139 | if (ARG4) | |
7140 | { | |
7141 | PRE_MEM_WRITE("timerfd_settime(old_value)", | |
7142 | ARG4, sizeof(struct vki_itimerspec)); | |
7143 | } | |
7144 | } | |
7145 | } | |
7146 | ||
7147 | POST(sys_timerfd_settime) | |
7148 | { | |
7149 | if (RES == 0 && ARG4 != 0) { | |
7150 | POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec)); | |
7151 | } | |
7152 | } | |
49d5458a PF |
7153 | |
7154 | // SYS_kcmp 588 | |
7155 | // int kcmp(pid_t pid1, pid_t pid2, int type, uintptr_t idx1, uintptr_t idx2); | |
7156 | PRE(sys_kcmp) | |
7157 | { | |
7158 | PRINT("kcmp(%ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u)", | |
7159 | SARG1, SARG2, SARG3, ARG4, ARG5); | |
7160 | switch (ARG3) { | |
7161 | case VKI_KCMP_FILES: | |
7162 | case VKI_KCMP_VM: | |
7163 | case VKI_KCMP_SIGHAND: | |
7164 | /* Most of the comparison types don't look at |idx1| or |idx2|. */ | |
7165 | PRE_REG_READ3(int, "kcmp", | |
7166 | vki_pid_t, pid1, vki_pid_t, pid2, int, type); | |
7167 | break; | |
7168 | case VKI_KCMP_FILE: | |
7169 | case VKI_KCMP_FILEOBJ: | |
7170 | default: | |
7171 | PRE_REG_READ5(int, "kcmp", | |
7172 | vki_pid_t, pid1, vki_pid_t, pid2, int, type, | |
7173 | unsigned long, idx1, unsigned long, idx2); | |
7174 | break; | |
7175 | } | |
7176 | } | |
7177 | ||
7178 | ||
adf7cb52 PF |
7179 | #endif |
7180 | ||
e2e5d75f PF |
7181 | #undef PRE |
7182 | #undef POST | |
7183 | ||
7184 | const SyscallTableEntry ML_(syscall_table)[] = { | |
7185 | // syscall (handled specially) // 0 | |
76d6b459 PF |
7186 | BSDX_(__NR_exit, sys_exit), // 1 |
7187 | BSDX_(__NR_fork, sys_fork), // 2 | |
7188 | GENXY(__NR_read, sys_read), // 3 | |
e2e5d75f | 7189 | |
76d6b459 PF |
7190 | GENX_(__NR_write, sys_write), // 4 |
7191 | GENXY(__NR_open, sys_open), // 5 | |
6a28e665 | 7192 | GENX_(__NR_close, sys_close), // 6 |
76d6b459 | 7193 | GENXY(__NR_wait4, sys_wait4), // 7 |
e2e5d75f PF |
7194 | |
7195 | // 4.3 creat 8 | |
76d6b459 PF |
7196 | GENX_(__NR_link, sys_link), // 9 |
7197 | GENX_(__NR_unlink, sys_unlink), // 10 | |
e2e5d75f PF |
7198 | // obsol execv 11 |
7199 | ||
76d6b459 PF |
7200 | GENX_(__NR_chdir, sys_chdir), // 12 |
7201 | GENX_(__NR_fchdir, sys_fchdir), // 13 | |
7202 | GENX_(__NR_freebsd11_mknod, sys_mknod), // 14 | |
7203 | GENX_(__NR_chmod, sys_chmod), // 15 | |
e2e5d75f | 7204 | |
76d6b459 PF |
7205 | GENX_(__NR_chown, sys_chown), // 16 |
7206 | GENX_(__NR_break, sys_brk), // 17 | |
e2e5d75f PF |
7207 | // freebsd 4 getfsstat 18 |
7208 | // 4.3 lseek 19 | |
7209 | ||
76d6b459 PF |
7210 | GENX_(__NR_getpid, sys_getpid), // 20 |
7211 | BSDX_(__NR_mount, sys_mount), // 21 | |
7212 | BSDX_(__NR_unmount, sys_unmount), // 22 | |
7213 | GENX_(__NR_setuid, sys_setuid), // 23 | |
e2e5d75f | 7214 | |
76d6b459 PF |
7215 | GENX_(__NR_getuid, sys_getuid), // 24 |
7216 | GENX_(__NR_geteuid, sys_geteuid), // 25 | |
7217 | BSDXY(__NR_ptrace, sys_ptrace), // 26 | |
7218 | BSDXY(__NR_recvmsg, sys_recvmsg), // 27 | |
e2e5d75f | 7219 | |
76d6b459 PF |
7220 | BSDX_(__NR_sendmsg, sys_sendmsg), // 28 |
7221 | BSDXY(__NR_recvfrom, sys_recvfrom), // 29 | |
7222 | BSDXY(__NR_accept, sys_accept), // 30 | |
7223 | BSDXY(__NR_getpeername, sys_getpeername), // 31 | |
e2e5d75f | 7224 | |
76d6b459 PF |
7225 | BSDXY(__NR_getsockname, sys_getsockname), // 32 |
7226 | GENX_(__NR_access, sys_access), // 33 | |
7227 | BSDX_(__NR_chflags, sys_chflags), // 34 | |
7228 | BSDX_(__NR_fchflags, sys_fchflags), // 35 | |
e2e5d75f | 7229 | |
76d6b459 PF |
7230 | GENX_(__NR_sync, sys_sync), // 36 |
7231 | GENX_(__NR_kill, sys_kill), // 37 | |
e2e5d75f | 7232 | // 4.3 stat 38 |
76d6b459 | 7233 | GENX_(__NR_getppid, sys_getppid), // 39 |
e2e5d75f PF |
7234 | |
7235 | // 4.3 lstat 40 | |
76d6b459 | 7236 | GENXY(__NR_dup, sys_dup), // 41 |
e2e5d75f | 7237 | |
26924849 PF |
7238 | #if defined(VGP_arm64_freebsd) |
7239 | GENX_(__NR_freebsd10_pipe, sys_ni_syscall), // 42 | |
7240 | #else | |
76d6b459 | 7241 | BSDXY(__NR_freebsd10_pipe, sys_pipe), // 42 |
26924849 | 7242 | #endif |
76d6b459 | 7243 | GENX_(__NR_getegid, sys_getegid), // 43 |
e2e5d75f | 7244 | |
76d6b459 PF |
7245 | GENX_(__NR_profil, sys_ni_syscall), // 44 |
7246 | GENX_(__NR_ktrace, sys_ni_syscall), // 45 | |
e2e5d75f | 7247 | // 4.3 sigaction 46 |
76d6b459 | 7248 | GENX_(__NR_getgid, sys_getgid), // 47 |
e2e5d75f PF |
7249 | |
7250 | // 4.3 sigaction (int sigset) 48 | |
76d6b459 PF |
7251 | BSDXY(__NR_getlogin, sys_getlogin), // 49 |
7252 | BSDX_(__NR_setlogin, sys_setlogin), // 50 | |
7253 | GENX_(__NR_acct, sys_acct), // 51 | |
e2e5d75f PF |
7254 | |
7255 | // 4.3 sigpending 52 | |
76d6b459 PF |
7256 | GENXY(__NR_sigaltstack, sys_sigaltstack), // 53 |
7257 | BSDXY(__NR_ioctl, sys_ioctl), // 54 | |
7258 | BSDX_(__NR_reboot, sys_reboot), // 55 | |
e2e5d75f | 7259 | |
76d6b459 PF |
7260 | BSDX_(__NR_revoke, sys_revoke), // 56 |
7261 | GENX_(__NR_symlink, sys_symlink), // 57 | |
7262 | BSDX_(__NR_readlink, sys_readlink), // 58 | |
7263 | GENX_(__NR_execve, sys_execve), // 59 | |
e2e5d75f | 7264 | |
76d6b459 PF |
7265 | GENX_(__NR_umask, sys_umask), // 60 |
7266 | GENX_(__NR_chroot, sys_chroot), // 61 | |
e2e5d75f PF |
7267 | // 4.3 fstat 62 |
7268 | // 4.3 getgerninfo 63 | |
7269 | ||
7270 | // 4.3 getpagesize 64 | |
76d6b459 PF |
7271 | GENX_(__NR_msync, sys_msync), // 65 |
7272 | BSDX_(__NR_vfork, sys_vfork), // 66 | |
e2e5d75f PF |
7273 | // obsol vread 67 |
7274 | ||
7275 | // obsol vwrite 68 | |
76d6b459 | 7276 | BSDX_(__NR_sbrk, sys_sbrk), // 69 |
e2e5d75f PF |
7277 | // not implemented in OS sstk 70 |
7278 | // 4.3 mmap 71 | |
7279 | ||
7280 | // freebsd11 vadvise 72 | |
76d6b459 PF |
7281 | GENXY(__NR_munmap, sys_munmap), // 73 |
7282 | GENXY(__NR_mprotect, sys_mprotect), // 74 | |
7283 | GENX_(__NR_madvise, sys_madvise), // 75 | |
e2e5d75f PF |
7284 | |
7285 | // obsol vhangup 76 | |
7286 | // obsol vlimit 77 | |
76d6b459 PF |
7287 | GENXY(__NR_mincore, sys_mincore), // 78 |
7288 | GENXY(__NR_getgroups, sys_getgroups), // 79 | |
e2e5d75f | 7289 | |
76d6b459 PF |
7290 | GENX_(__NR_setgroups, sys_setgroups), // 80 |
7291 | GENX_(__NR_getpgrp, sys_getpgrp), // 81 | |
7292 | GENX_(__NR_setpgid, sys_setpgid), // 82 | |
7293 | GENXY(__NR_setitimer, sys_setitimer), // 83 | |
e2e5d75f PF |
7294 | |
7295 | // 4.3 wait 84 | |
76d6b459 PF |
7296 | BSDX_(__NR_swapon, sys_swapon), // 85 |
7297 | GENXY(__NR_getitimer, sys_getitimer), // 86 | |
e2e5d75f PF |
7298 | // 4.3 gethostname 87 |
7299 | ||
7300 | // 4.3 sethostname 88 | |
76d6b459 PF |
7301 | BSDX_(__NR_getdtablesize, sys_getdtablesize), // 89 |
7302 | GENXY(__NR_dup2, sys_dup2), // 90 | |
e2e5d75f | 7303 | |
76d6b459 PF |
7304 | BSDXY(__NR_fcntl, sys_fcntl), // 92 |
7305 | GENX_(__NR_select, sys_select), // 93 | |
7306 | GENX_(__NR_fsync, sys_fsync), // 95 | |
e2e5d75f | 7307 | |
76d6b459 PF |
7308 | GENX_(__NR_setpriority, sys_setpriority), // 96 |
7309 | BSDXY(__NR_socket, sys_socket), // 97 | |
7310 | BSDX_(__NR_connect, sys_connect), // 98 | |
e2e5d75f PF |
7311 | // 4.3 accept 99 |
7312 | ||
76d6b459 | 7313 | GENX_(__NR_getpriority, sys_getpriority), // 100 |
e2e5d75f PF |
7314 | // 4.3 send 101 |
7315 | // 4.3 recv 102 | |
7316 | // 4.3 sigreturn 103 | |
7317 | ||
76d6b459 PF |
7318 | BSDX_(__NR_bind, sys_bind), // 104 |
7319 | BSDX_(__NR_setsockopt, sys_setsockopt), // 105 | |
7320 | BSDX_(__NR_listen, sys_listen), // 106 | |
e2e5d75f PF |
7321 | // obsol vtimes 107 |
7322 | ||
7323 | // 4.3 sigvec 108 | |
7324 | // 4.3 sigblock 109 | |
7325 | // 4.3 sigsetmask 110 | |
7326 | // 4.3 sigsuspend 111 | |
7327 | ||
7328 | // 4.3 sigstack 112 | |
7329 | // 4.3 recvmsg 113 | |
7330 | // 4.3 sendmsg 114 | |
7331 | // 4.3 vtrace 115 | |
7332 | ||
76d6b459 PF |
7333 | GENXY(__NR_gettimeofday, sys_gettimeofday), // 116 |
7334 | GENXY(__NR_getrusage, sys_getrusage), // 117 | |
7335 | BSDXY(__NR_getsockopt, sys_getsockopt), // 118 | |
e2e5d75f | 7336 | |
76d6b459 PF |
7337 | GENXY(__NR_readv, sys_readv), // 120 |
7338 | GENX_(__NR_writev, sys_writev), // 121 | |
7339 | GENX_(__NR_settimeofday, sys_settimeofday), // 122 | |
7340 | GENX_(__NR_fchown, sys_fchown), // 123 | |
e2e5d75f | 7341 | |
76d6b459 | 7342 | GENX_(__NR_fchmod, sys_fchmod), // 124 |
e2e5d75f | 7343 | // 4.3 recvfrom 125 |
76d6b459 PF |
7344 | GENX_(__NR_setreuid, sys_setreuid), // 126 |
7345 | GENX_(__NR_setregid, sys_setregid), // 127 | |
e2e5d75f | 7346 | |
76d6b459 | 7347 | GENX_(__NR_rename, sys_rename), // 128 |
e2e5d75f PF |
7348 | // 4.3 truncate 129 |
7349 | // 4.3 ftruncate 130 | |
76d6b459 | 7350 | GENX_(__NR_flock, sys_flock), // 131 |
e2e5d75f | 7351 | |
76d6b459 PF |
7352 | BSDX_(__NR_mkfifo, sys_mkfifo), // 132 |
7353 | BSDX_(__NR_sendto, sys_sendto), // 133 | |
7354 | BSDX_(__NR_shutdown, sys_shutdown), // 134 | |
7355 | BSDXY(__NR_socketpair, sys_socketpair), // 135 | |
e2e5d75f | 7356 | |
76d6b459 PF |
7357 | GENX_(__NR_mkdir, sys_mkdir), // 136 |
7358 | GENX_(__NR_rmdir, sys_rmdir), // 137 | |
7359 | GENX_(__NR_utimes, sys_utimes), // 138 | |
e2e5d75f PF |
7360 | // 4.2 sigreturn 139 |
7361 | ||
76d6b459 | 7362 | BSDXY(__NR_adjtime, sys_adjtime), // 140 |
e2e5d75f PF |
7363 | // 4.3 getpeername 141 |
7364 | // 4.3 gethostid 142 | |
7365 | // 4.3 sethostid 143 | |
7366 | ||
7367 | // 4.3 getrlimit` 144 | |
7368 | // 4.3 setrlimit 145 | |
7369 | // 4.3 killpg 146 | |
76d6b459 | 7370 | GENX_(__NR_setsid, sys_setsid), // 147 |
e2e5d75f | 7371 | |
76d6b459 | 7372 | BSDX_(__NR_quotactl, sys_quotactl), // 148 |
e2e5d75f PF |
7373 | // 4.3 quota 149 |
7374 | // 4.3 getsockname 150 | |
7375 | // bsd/os sem_lock 151 | |
7376 | ||
7377 | // bsd/os sem_wakeup 152 | |
7378 | // bsd/os asyncdaemon 153 | |
7379 | ||
7380 | // no idea what the following syscall does | |
7381 | // unimp SYS_nlm_syscall 154 | |
7382 | ||
7383 | // a somewhat complicated NFS API | |
7384 | // takes a flag and a void* that can point to one of | |
7385 | // three different types of struct depending on the flag | |
7386 | // unimp SYS_nfssvc 155 | |
7387 | ||
7388 | // 4.3 getdirentries 156 | |
7389 | // freebsd 4 statfs 157 | |
7390 | // freebsd 4 fstatfs 158 | |
7391 | ||
76d6b459 PF |
7392 | BSDXY(__NR_lgetfh, sys_lgetfh), // 160 |
7393 | BSDXY(__NR_getfh, sys_getfh), // 161 | |
e2e5d75f PF |
7394 | #if (FREEBSD_VERS <= FREEBSD_10) |
7395 | BSDXY(__NR_freebsd4_getdomainname, sys_freebsd4_getdomainname), // 162 | |
7396 | BSDX_(__NR_freebsd4_setdomainname, sys_freebsd4_setdomainname), // 163 | |
76d6b459 | 7397 | BSDXY(__NR_freebsd4_uname, sys_freebsd4_uname), // 164 |
e2e5d75f | 7398 | #endif |
76d6b459 PF |
7399 | BSDXY(__NR_sysarch, sys_sysarch), // 165 |
7400 | BSDXY(__NR_rtprio, sys_rtprio), // 166 | |
e2e5d75f | 7401 | |
76d6b459 PF |
7402 | // the following 3 seem only to be defines in a header |
7403 | // semsys 169 | |
7404 | // msgsys 170 | |
7405 | // shmsys 171 | |
e2e5d75f PF |
7406 | |
7407 | #if (FREEBSD_VERS <= FREEBSD_10) | |
76d6b459 PF |
7408 | BSDXY(__NR_freebsd6_pread, sys_freebsd6_pread), // 173 |
7409 | BSDX_(__NR_freebsd6_pwrite, sys_freebsd6_pwrite), // 174 | |
e2e5d75f | 7410 | #endif |
76d6b459 | 7411 | BSDX_(__NR_setfib, sys_setfib), // 175 |
e2e5d75f PF |
7412 | |
7413 | // @todo PJF this exists on Darwin and Solaris as well | |
7414 | // and it isn't implememented on either | |
7415 | // looking at the manpage there is a rather fearsome | |
7416 | // timex struct with a mixture of ro and rw fields | |
7417 | // BSDXY(__NR_ntp_adjtime, sys_ntp_adjtime), // 176 | |
7418 | ||
7419 | // bsd/os sfork 177 | |
7420 | // bsd/os getdescriptor 178 | |
7421 | // bsd/os setdescriptor 179 | |
7422 | ||
76d6b459 PF |
7423 | GENX_(__NR_setgid, sys_setgid), // 181 |
7424 | BSDX_(__NR_setegid, sys_setegid), // 182 | |
7425 | BSDX_(__NR_seteuid, sys_seteuid), // 183 | |
e2e5d75f | 7426 | |
76d6b459 PF |
7427 | // obs lfs_bmapv 184 |
7428 | // obs lfs_markv 185 | |
7429 | // obs lfs_segclean 186 | |
7430 | // obs lfs_segwait 187 | |
e2e5d75f PF |
7431 | |
7432 | #if (FREEBSD_VERS >= FREEBSD_12) | |
76d6b459 PF |
7433 | BSDXY(__NR_freebsd11_stat, sys_freebsd11_stat), // 188 |
7434 | BSDXY(__NR_freebsd11_fstat, sys_freebsd11_fstat), // 189 | |
7435 | BSDXY(__NR_freebsd11_lstat, sys_freebsd11_lstat), // 190 | |
e2e5d75f | 7436 | #else |
76d6b459 PF |
7437 | BSDXY(__NR_stat, sys_stat), // 188 |
7438 | BSDXY(__NR_fstat, sys_fstat), // 189 | |
7439 | BSDXY(__NR_lstat, sys_lstat), // 190 | |
e2e5d75f | 7440 | #endif |
76d6b459 PF |
7441 | BSDX_(__NR_pathconf, sys_pathconf), // 191 |
7442 | BSDX_(__NR_fpathconf, sys_fpathconf), // 192 | |
7443 | GENXY(__NR_getrlimit, sys_getrlimit), // 194 | |
7444 | GENX_(__NR_setrlimit, sys_setrlimit), // 195 | |
e2e5d75f PF |
7445 | #if (FREEBSD_VERS >= FREEBSD_12) |
7446 | BSDXY(__NR_freebsd11_getdirentries, sys_freebsd11_getdirentries), // 196 | |
7447 | #else | |
76d6b459 | 7448 | BSDXY(__NR_getdirentries, sys_getdirentries), // 196 |
e2e5d75f PF |
7449 | #endif |
7450 | #if (FREEBSD_VERS <= FREEBSD_10) | |
76d6b459 | 7451 | BSDX_(__NR_freebsd6_mmap, sys_freebsd6_mmap), // 197 |
e2e5d75f | 7452 | #endif |
76d6b459 | 7453 | // __syscall (handled specially) // 198 |
e2e5d75f | 7454 | #if (FREEBSD_VERS <= FREEBSD_10) |
76d6b459 PF |
7455 | BSDX_(__NR_freebsd6_lseek, sys_freebsd6_lseek), // 199 |
7456 | BSDX_(__NR_freebsd6_truncate, sys_freebsd6_truncate), // 200 | |
e2e5d75f PF |
7457 | BSDX_(__NR_freebsd6_ftruncate, sys_freebsd6_ftruncate), // 201 |
7458 | #endif | |
76d6b459 PF |
7459 | BSDXY(__NR___sysctl, sys___sysctl), // 202 |
7460 | GENX_(__NR_mlock, sys_mlock), // 203 | |
e2e5d75f | 7461 | |
76d6b459 PF |
7462 | GENX_(__NR_munlock, sys_munlock), // 204 |
7463 | BSDX_(__NR_undelete, sys_undelete), // 205 | |
7464 | BSDX_(__NR_futimes, sys_futimes), // 206 | |
7465 | GENX_(__NR_getpgid, sys_getpgid), // 207 | |
e2e5d75f PF |
7466 | |
7467 | // netbsd newreboot 208 | |
76d6b459 | 7468 | GENXY(__NR_poll, sys_poll), // 209 |
e2e5d75f PF |
7469 | |
7470 | BSDXY(__NR_freebsd7___semctl, sys_freebsd7___semctl), // 220 | |
76d6b459 PF |
7471 | BSDX_(__NR_semget, sys_semget), // 221 |
7472 | BSDX_(__NR_semop, sys_semop), // 222 | |
e2e5d75f PF |
7473 | // obs semconfig 223 |
7474 | ||
76d6b459 PF |
7475 | BSDXY(__NR_freebsd7_msgctl, sys_freebsd7_msgctl), // 224 |
7476 | BSDX_(__NR_msgget, sys_msgget), // 225 | |
7477 | BSDX_(__NR_msgsnd, sys_msgsnd), // 226 | |
7478 | BSDXY(__NR_msgrcv, sys_msgrcv), // 227 | |
7479 | ||
7480 | BSDXY(__NR_shmat, sys_shmat), // 228 | |
7481 | BSDXY(__NR_freebsd7_shmctl, sys_freebsd7_shmctl), // 229 | |
7482 | BSDXY(__NR_shmdt, sys_shmdt), // 230 | |
7483 | BSDX_(__NR_shmget, sys_shmget), // 231 | |
7484 | ||
7485 | BSDXY(__NR_clock_gettime, sys_clock_gettime), // 232 | |
7486 | BSDX_(__NR_clock_settime, sys_clock_settime), // 233 | |
7487 | BSDXY(__NR_clock_getres, sys_clock_getres), // 234 | |
7488 | BSDXY(__NR_ktimer_create, sys_timer_create), // 235 | |
7489 | BSDX_(__NR_ktimer_delete, sys_timer_delete), // 236 | |
7490 | BSDXY(__NR_ktimer_settime, sys_timer_settime), // 237 | |
7491 | BSDXY(__NR_ktimer_gettime, sys_timer_gettime), // 238 | |
e2e5d75f PF |
7492 | BSDX_(__NR_ktimer_getoverrun, sys_timer_getoverrun), // 239 |
7493 | ||
76d6b459 | 7494 | GENXY(__NR_nanosleep, sys_nanosleep), // 240 |
e2e5d75f PF |
7495 | // unimpl SYS_ffclock_getcounter 241 |
7496 | // unimpl SYS_ffclock_setestimate 242 | |
7497 | // unimpl SYS_ffclock_getestimate 243 | |
7498 | ||
76d6b459 | 7499 | BSDXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 244 |
f13667b1 | 7500 | BSDXY(__NR_clock_getcpuclockid2, sys_clock_getcpuclockid2), // 247 |
e2e5d75f PF |
7501 | |
7502 | // unimpl SYS_ntp_gettime 248 | |
76d6b459 PF |
7503 | BSDXY(__NR_minherit, sys_minherit), // 250 |
7504 | BSDX_(__NR_rfork, sys_rfork), // 251 | |
e2e5d75f PF |
7505 | |
7506 | // openbsd_poll // 252 | |
76d6b459 PF |
7507 | BSDX_(__NR_issetugid, sys_issetugid), // 253 |
7508 | GENX_(__NR_lchown, sys_lchown), // 254 | |
7509 | BSDXY(__NR_aio_read, sys_aio_read), // 255 | |
a15b387e | 7510 | BSDX_(__NR_aio_write, sys_aio_write), // 256 |
76d6b459 PF |
7511 | BSDX_(__NR_lio_listio, sys_lio_listio), // 257 |
7512 | ||
7513 | GENXY(__NR_freebsd11_getdents, sys_getdents), // 272 | |
7514 | BSDX_(__NR_lchmod, sys_lchmod), // 274 | |
e2e5d75f PF |
7515 | // netbsd_lchown // 275 |
7516 | ||
76d6b459 | 7517 | BSDX_(__NR_lutimes, sys_lutimes), // 276 |
e2e5d75f PF |
7518 | // netbsd msync 277 |
7519 | // unimpl SYS_freebsd11_nstat 278 | |
7520 | // unimpl SYS_freebsd11_nfstat 279 | |
7521 | ||
7522 | // unimpl SYS_freebsd11_nlstat 280 | |
7523 | ||
76d6b459 PF |
7524 | BSDXY(__NR_preadv, sys_preadv), // 289 |
7525 | BSDX_(__NR_pwritev, sys_pwritev), // 290 | |
e2e5d75f PF |
7526 | |
7527 | // freebsd 4 fhstatfs 297 | |
76d6b459 | 7528 | BSDXY(__NR_fhopen, sys_fhopen), // 298 |
e2e5d75f | 7529 | #if (FREEBSD_VERS >= FREEBSD_12) |
76d6b459 | 7530 | BSDXY(__NR_freebsd11_fhstat, sys_freebsd11_fhstat), // 299 |
e2e5d75f | 7531 | #else |
76d6b459 | 7532 | BSDXY(__NR_fhstat, sys_fhstat), // 299 |
e2e5d75f PF |
7533 | #endif |
7534 | ||
76d6b459 PF |
7535 | BSDX_(__NR_modnext, sys_modnext), // 300 |
7536 | BSDXY(__NR_modstat, sys_modstat), // 301 | |
7537 | BSDX_(__NR_modfnext, sys_modfnext), // 302 | |
7538 | BSDX_(__NR_modfind, sys_modfind), // 303 | |
e2e5d75f | 7539 | |
76d6b459 PF |
7540 | BSDX_(__NR_kldload, sys_kldload), // 304 |
7541 | BSDX_(__NR_kldunload, sys_kldunload), // 305 | |
7542 | BSDX_(__NR_kldfind, sys_kldfind), // 306 | |
7543 | BSDX_(__NR_kldnext, sys_kldnext), // 307 | |
e2e5d75f | 7544 | |
76d6b459 PF |
7545 | BSDXY(__NR_kldstat, sys_kldstat), // 308 |
7546 | BSDX_(__NR_kldfirstmod, sys_kldfirstmod), // 309 | |
7547 | GENX_(__NR_getsid, sys_getsid), // 310 | |
7548 | BSDX_(__NR_setresuid, sys_setresuid), // 311 | |
e2e5d75f | 7549 | |
76d6b459 | 7550 | BSDX_(__NR_setresgid, sys_setresgid), // 312 |
e2e5d75f | 7551 | // obsol signanosleep 313 |
76d6b459 PF |
7552 | BSDX_(__NR_aio_return, sys_aio_return), // 314 |
7553 | BSDX_(__NR_aio_suspend, sys_aio_suspend), // 315 | |
e2e5d75f | 7554 | |
76d6b459 PF |
7555 | BSDX_(__NR_aio_cancel, sys_aio_cancel), // 316 |
7556 | BSDX_(__NR_aio_error, sys_aio_error), // 317 | |
e2e5d75f PF |
7557 | // freebsd 6 aio_read 318 |
7558 | // freebsd 6 aio_write 319 | |
7559 | // freebsd 6 lio_listio 320 | |
76d6b459 | 7560 | BSDX_(__NR_yield, sys_yield), // 321 |
e2e5d75f PF |
7561 | // obs thr_sleep 322 |
7562 | // obs thr_wakeup 323 | |
7563 | ||
76d6b459 PF |
7564 | GENX_(__NR_mlockall, sys_mlockall), // 324 |
7565 | BSDX_(__NR_munlockall, sys_munlockall), // 325 | |
7566 | BSDXY(__NR___getcwd, sys___getcwd), // 326 | |
7567 | BSDX_(__NR_sched_setparam, sys_sched_setparam), // 327 | |
7568 | BSDXY(__NR_sched_getparam, sys_sched_getparam), // 328 | |
e2e5d75f PF |
7569 | BSDX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 329 |
7570 | BSDX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 330 | |
76d6b459 | 7571 | BSDX_(__NR_sched_yield, sys_sched_yield), // 331 |
e2e5d75f PF |
7572 | |
7573 | BSDX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 332 | |
7574 | BSDX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 333 | |
76d6b459 PF |
7575 | BSDXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 334 |
7576 | BSDX_(__NR_utrace, sys_utrace), // 335 | |
e2e5d75f PF |
7577 | |
7578 | // freebsd 4 sendfile 336 | |
76d6b459 PF |
7579 | BSDXY(__NR_kldsym, sys_kldsym), // 337 |
7580 | BSDX_(__NR_jail, sys_jail), // 338 | |
e2e5d75f PF |
7581 | // unimpl SYS_nnpfs_syscall 339 |
7582 | ||
76d6b459 PF |
7583 | BSDXY(__NR_sigprocmask, sys_sigprocmask), // 340 |
7584 | BSDXY(__NR_sigsuspend, sys_sigsuspend), // 341 | |
e2e5d75f | 7585 | // freebsd 4 sigaction 342 |
76d6b459 | 7586 | BSDXY(__NR_sigpending, sys_sigpending), // 343 |
e2e5d75f PF |
7587 | |
7588 | // freebsd 4 sigreturn 344 | |
76d6b459 PF |
7589 | BSDXY(__NR_sigtimedwait, sys_sigtimedwait), // 345 |
7590 | BSDXY(__NR_sigwaitinfo, sys_sigwaitinfo), // 346 | |
7591 | BSDXY(__NR___acl_get_file, sys___acl_get_file), // 347 | |
e2e5d75f | 7592 | |
76d6b459 PF |
7593 | BSDX_(__NR___acl_set_file, sys___acl_set_file), // 348 |
7594 | BSDXY(__NR___acl_get_fd, sys___acl_get_fd), // 349 | |
7595 | BSDX_(__NR___acl_set_fd, sys___acl_set_fd), // 350 | |
e2e5d75f PF |
7596 | BSDX_(__NR___acl_delete_file, sys___acl_delete_file), // 351 |
7597 | ||
76d6b459 | 7598 | BSDX_(__NR___acl_delete_fd, sys___acl_delete_fd), // 352 |
e2e5d75f | 7599 | BSDX_(__NR___acl_aclcheck_file, sys___acl_aclcheck_file), // 353 |
76d6b459 PF |
7600 | BSDX_(__NR___acl_aclcheck_fd, sys___acl_aclcheck_fd), // 354 |
7601 | BSDX_(__NR_extattrctl, sys_extattrctl), // 355 | |
7602 | BSDX_(__NR_extattr_set_file, sys_extattr_set_file), // 356 | |
7603 | BSDXY(__NR_extattr_get_file, sys_extattr_get_file), // 357 | |
e2e5d75f | 7604 | BSDX_(__NR_extattr_delete_file, sys_extattr_delete_file), // 358 |
76d6b459 | 7605 | BSDXY(__NR_aio_waitcomplete, sys_aio_waitcomplete), // 359 |
e2e5d75f | 7606 | |
76d6b459 PF |
7607 | BSDXY(__NR_getresuid, sys_getresuid), // 360 |
7608 | BSDXY(__NR_getresgid, sys_getresgid), // 361 | |
7609 | BSDXY(__NR_kqueue, sys_kqueue), // 362 | |
e2e5d75f | 7610 | #if (FREEBSD_VERS >= FREEBSD_12) |
76d6b459 | 7611 | BSDXY(__NR_freebsd11_kevent, sys_freebsd11_kevent), // 363 |
e2e5d75f | 7612 | #else |
76d6b459 | 7613 | BSDXY(__NR_kevent, sys_kevent), // 363 |
e2e5d75f PF |
7614 | #endif |
7615 | // obs __cap_get_proc 364 | |
7616 | // obs __cap_set_proc 365 | |
7617 | // obs __cap_get_fd 366 | |
7618 | // obs __cap_get_file 367 | |
7619 | // obs __cap_set_fd 368 | |
7620 | // obs __cap_set_file 369 | |
7621 | ||
76d6b459 PF |
7622 | BSDX_(__NR_extattr_set_fd, sys_extattr_set_fd), // 371 |
7623 | BSDXY(__NR_extattr_get_fd, sys_extattr_get_fd), // 372 | |
e2e5d75f | 7624 | BSDX_(__NR_extattr_delete_fd, sys_extattr_delete_fd), // 373 |
76d6b459 | 7625 | BSDX_(__NR___setugid, sys___setugid), // 374 |
e2e5d75f PF |
7626 | // obs nfsclnt 375 |
7627 | ||
76d6b459 | 7628 | BSDX_(__NR_eaccess, sys_eaccess), // 376 |
e2e5d75f | 7629 | // unimpl afs3_syscall 377 |
76d6b459 | 7630 | BSDX_(__NR_nmount, sys_nmount), // 378 |
e2e5d75f PF |
7631 | // obs kse_exit 379 |
7632 | // obs kse_wakeup 380 | |
7633 | // obs kse_create 381 | |
7634 | // obs kse_thr_interrupt 382 | |
7635 | // obs kse_release 383 | |
7636 | ||
7637 | // unimpl __mac_get_proc 384 | |
7638 | // unimpl __mac_set_proc 385 | |
7639 | // unimpl __mac_get_fd 386 | |
7640 | // unimpl __mac_get_file 387 | |
7641 | // unimpl __mac_set_fd 388 | |
7642 | // unimpl __mac_set_file 389 | |
76d6b459 PF |
7643 | BSDXY(__NR_kenv, sys_kenv), // 390 |
7644 | BSDX_(__NR_lchflags, sys_lchflags), // 391 | |
e2e5d75f | 7645 | |
76d6b459 PF |
7646 | BSDXY(__NR_uuidgen, sys_uuidgen), // 392 |
7647 | BSDXY(__NR_sendfile, sys_sendfile), // 393 | |
7648 | // unimpl mac_syscall 394 | |
e2e5d75f PF |
7649 | |
7650 | #if (FREEBSD_VERS >= FREEBSD_12) | |
7651 | BSDXY(__NR_freebsd11_getfsstat, sys_freebsd11_getfsstat), // 395 | |
76d6b459 PF |
7652 | BSDXY(__NR_freebsd11_statfs, sys_statfs), // 396 |
7653 | BSDXY(__NR_freebsd11_fstatfs, sys_fstatfs), // 397 | |
7654 | BSDXY(__NR_freebsd11_fhstatfs, sys_fhstatfs), // 398 | |
e2e5d75f | 7655 | #else |
76d6b459 PF |
7656 | BSDXY(__NR_getfsstat, sys_getfsstat), // 395 |
7657 | BSDXY(__NR_statfs, sys_statfs), // 396 | |
7658 | BSDXY(__NR_fstatfs, sys_fstatfs), // 397 | |
7659 | BSDXY(__NR_fhstatfs, sys_fhstatfs), // 398 | |
e2e5d75f PF |
7660 | #endif |
7661 | ||
7662 | // unimpl ksem_close 400 | |
7663 | // unimpl ksem_post 401 | |
7664 | // unimpl ksem_wait 402 | |
7665 | // unimpl ksem_trywait 403 | |
7666 | ||
7667 | // unimpl ksem_init 404 | |
7668 | // unimpl ksem_open 405 | |
7669 | // unimpl ksem_unlink 406 | |
7670 | // unimpl ksem_getvalue 407 | |
7671 | ||
7672 | // unimpl ksem_destroy 408 | |
7673 | // unimpl __mac_get_pid 409 | |
7674 | // unimpl __mac_get_link 410 | |
7675 | // unimpl __mac_set_link 411 | |
7676 | ||
76d6b459 PF |
7677 | BSDX_(__NR_extattr_set_link, sys_extattr_set_link), // 412 |
7678 | BSDXY(__NR_extattr_get_link, sys_extattr_get_link), // 413 | |
e2e5d75f PF |
7679 | BSDX_(__NR_extattr_delete_link, sys_extattr_delete_link), // 414 |
7680 | // unimpl __mac_execve 415 | |
7681 | ||
76d6b459 PF |
7682 | BSDXY(__NR_sigaction, sys_sigaction), // 416 |
7683 | BSDX_(__NR_sigreturn, sys_sigreturn), // 417 | |
e2e5d75f | 7684 | |
76d6b459 PF |
7685 | BSDXY(__NR_getcontext, sys_getcontext), // 421 |
7686 | BSDX_(__NR_setcontext, sys_setcontext), // 422 | |
7687 | BSDXY(__NR_swapcontext, sys_swapcontext), // 423 | |
e2e5d75f | 7688 | |
6cb8e52c | 7689 | #if (FREEBSD_VERS >= FREEBSD_13_1) |
cdd98111 PF |
7690 | BSDX_(__NR_freebsd13_swapoff, sys_freebsd13_swapoff), // 424 |
7691 | #else | |
76d6b459 | 7692 | BSDX_(__NR_swapoff, sys_swapoff), // 424 |
cdd98111 | 7693 | #endif |
76d6b459 PF |
7694 | BSDXY(__NR___acl_get_link, sys___acl_get_link), // 425 |
7695 | BSDX_(__NR___acl_set_link, sys___acl_set_link), // 426 | |
e2e5d75f PF |
7696 | BSDX_(__NR___acl_delete_link, sys___acl_delete_link), // 427 |
7697 | ||
7698 | BSDX_(__NR___acl_aclcheck_link, sys___acl_aclcheck_link), // 428 | |
76d6b459 PF |
7699 | BSDXY(__NR_sigwait, sys_sigwait), // 429 |
7700 | BSDX_(__NR_thr_create, sys_thr_create), // 430 | |
7701 | BSDX_(__NR_thr_exit, sys_thr_exit), // 431 | |
e2e5d75f | 7702 | |
76d6b459 PF |
7703 | BSDXY(__NR_thr_self, sys_thr_self), // 432 |
7704 | BSDXY(__NR_thr_kill, sys_thr_kill), // 433 | |
e2e5d75f | 7705 | #if (FREEBSD_VERS <= FREEBSD_10) |
76d6b459 PF |
7706 | BSDXY(__NR__umtx_lock, sys__umtx_lock), // 434 |
7707 | BSDXY(__NR__umtx_unlock, sys__umtx_unlock), // 435 | |
e2e5d75f PF |
7708 | #endif |
7709 | ||
76d6b459 PF |
7710 | BSDX_(__NR_jail_attach, sys_jail_attach), // 436 |
7711 | BSDXY(__NR_extattr_list_fd, sys_extattr_list_fd), // 437 | |
e2e5d75f PF |
7712 | BSDXY(__NR_extattr_list_file, sys_extattr_list_file), // 438 |
7713 | BSDXY(__NR_extattr_list_link, sys_extattr_list_link), // 439 | |
7714 | ||
7715 | // obs kse_switchin 440 | |
7716 | // unimpl ksem_timedwait 441 | |
76d6b459 PF |
7717 | BSDX_(__NR_thr_suspend, sys_thr_suspend), // 442 |
7718 | BSDX_(__NR_thr_wake, sys_thr_wake), // 443 | |
7719 | BSDX_(__NR_kldunloadf, sys_kldunloadf), // 444 | |
e2e5d75f PF |
7720 | // unimpl audit 445 |
7721 | // unimpl auditon 446 | |
7722 | // unimpl getauid 447 | |
7723 | ||
7724 | // unimpl setauid 448 | |
7725 | // unimpl getaudit 449 | |
7726 | // unimpl setaudit 450 | |
7727 | // unimpl getaudit_addr 451 | |
7728 | // unimpl setaudit_addr 452 | |
7729 | // unimpl auditctl 453 | |
76d6b459 PF |
7730 | BSDXY(__NR__umtx_op, sys__umtx_op), // 454 |
7731 | BSDX_(__NR_thr_new, sys_thr_new), // 455 | |
e2e5d75f | 7732 | |
76d6b459 PF |
7733 | BSDX_(__NR_sigqueue, sys_sigqueue), // 456 |
7734 | BSDXY(__NR_kmq_open, sys_kmq_open), // 457 | |
7735 | BSDX_(__NR_kmq_setattr, sys_kmq_setattr), // 458 | |
7736 | BSDXY(__NR_kmq_timedreceive, sys_kmq_timedreceive), // 459 | |
e2e5d75f | 7737 | |
76d6b459 PF |
7738 | BSDX_(__NR_kmq_timedsend, sys_kmq_timedsend), // 460 |
7739 | BSDX_(__NR_kmq_notify, sys_kmq_notify), // 461 | |
7740 | BSDX_(__NR_kmq_unlink, sys_kmq_unlink), // 462 | |
7741 | BSDX_(__NR_abort2, sys_abort2), // 463 | |
e2e5d75f | 7742 | |
76d6b459 PF |
7743 | BSDX_(__NR_thr_set_name, sys_thr_set_name), // 464 |
7744 | BSDX_(__NR_aio_fsync, sys_aio_fsync), // 465 | |
7745 | BSDXY(__NR_rtprio_thread, sys_rtprio_thread), // 466 | |
e2e5d75f PF |
7746 | |
7747 | // unimpl sctp_peeloff 471 | |
5b524084 | 7748 | BSDX_(__NR_sctp_generic_sendmsg, sys_sctp_generic_sendmsg), // 472 |
e2e5d75f | 7749 | // unimpl sctp_generic_sendmsg_iov 473 |
5b524084 | 7750 | BSDXY(__NR_sctp_generic_recvmsg, sys_sctp_generic_recvmsg), // 474 |
76d6b459 | 7751 | BSDXY(__NR_pread, sys_pread), // 475 |
e2e5d75f | 7752 | |
76d6b459 PF |
7753 | BSDX_(__NR_pwrite, sys_pwrite), // 476 |
7754 | BSDX_(__NR_mmap, sys_mmap), // 477 | |
7755 | BSDX_(__NR_lseek, sys_lseek), // 478 | |
7756 | BSDX_(__NR_truncate, sys_truncate), // 479 | |
7757 | BSDX_(__NR_ftruncate, sys_ftruncate), // 480 | |
7758 | BSDXY(__NR_thr_kill2, sys_thr_kill2), // 481 | |
7759 | BSDXY(__NR_shm_open, sys_shm_open), // 482 | |
7760 | BSDX_(__NR_shm_unlink, sys_shm_unlink), // 483 | |
e2e5d75f | 7761 | |
76d6b459 PF |
7762 | BSDXY(__NR_cpuset, sys_cpuset), // 484 |
7763 | BSDX_(__NR_cpuset_setid, sys_cpuset_setid), // 485 | |
7764 | BSDXY(__NR_cpuset_getid, sys_cpuset_getid), // 486 | |
e2e5d75f PF |
7765 | |
7766 | BSDXY(__NR_cpuset_getaffinity, sys_cpuset_getaffinity), // 487 | |
7767 | BSDX_(__NR_cpuset_setaffinity, sys_cpuset_setaffinity), // 488 | |
76d6b459 PF |
7768 | BSDX_(__NR_faccessat, sys_faccessat), // 489 |
7769 | BSDX_(__NR_fchmodat, sys_fchmodat), // 490 | |
7770 | BSDX_(__NR_fchownat, sys_fchownat), // 491 | |
e2e5d75f | 7771 | |
76d6b459 | 7772 | BSDX_(__NR_fexecve, sys_fexecve), // 492 |
e2e5d75f PF |
7773 | #if (FREEBSD_VERS >= FREEBSD_12) |
7774 | BSDXY(__NR_freebsd11_fstatat, sys_freebsd11_fstatat), // 493 | |
7775 | #else | |
76d6b459 | 7776 | BSDXY(__NR_fstatat, sys_fstatat), // 493 |
e2e5d75f | 7777 | #endif |
76d6b459 PF |
7778 | BSDX_(__NR_futimesat, sys_futimesat), // 494 |
7779 | BSDX_(__NR_linkat, sys_linkat), // 495 | |
e2e5d75f | 7780 | |
76d6b459 PF |
7781 | BSDX_(__NR_mkdirat, sys_mkdirat), // 496 |
7782 | BSDX_(__NR_mkfifoat, sys_mkfifoat), // 497 | |
e2e5d75f PF |
7783 | |
7784 | #if (FREEBSD_VERS >= FREEBSD_12) | |
7785 | BSDX_(__NR_freebsd11_mknodat, sys_freebsd11_mknodat), // 498 | |
7786 | #else | |
76d6b459 | 7787 | BSDX_(__NR_mknodat, sys_mknodat), // 498 |
e2e5d75f PF |
7788 | #endif |
7789 | ||
76d6b459 | 7790 | BSDXY(__NR_openat, sys_openat), // 499 |
e2e5d75f | 7791 | |
76d6b459 PF |
7792 | BSDXY(__NR_readlinkat, sys_readlinkat), // 500 |
7793 | BSDX_(__NR_renameat, sys_renameat), // 501 | |
7794 | BSDX_(__NR_symlinkat, sys_symlinkat), // 502 | |
7795 | BSDX_(__NR_unlinkat, sys_unlinkat), // 503 | |
e2e5d75f | 7796 | |
76d6b459 | 7797 | BSDX_(__NR_posix_openpt, sys_posix_openpt), // 504 |
e2e5d75f | 7798 | // unimp gssd_syscall 505 |
76d6b459 PF |
7799 | BSDX_(__NR_jail_get, sys_jail_get), // 506 |
7800 | BSDX_(__NR_jail_set, sys_jail_set), // 507 | |
7801 | BSDX_(__NR_jail_remove, sys_jail_remove), // 508 | |
196aafe6 | 7802 | BSDXY(__NR_closefrom, sys_closefrom), // 509 |
76d6b459 PF |
7803 | BSDXY(__NR___semctl, sys___semctl), // 510 |
7804 | BSDXY(__NR_msgctl, sys_msgctl), // 511 | |
7805 | BSDXY(__NR_shmctl, sys_shmctl), // 512 | |
7806 | BSDX_(__NR_lpathconf, sys_lpathconf), // 513 | |
e2e5d75f | 7807 | /* 514 is obsolete cap_new */ |
76d6b459 PF |
7808 | BSDXY(__NR___cap_rights_get, sys_cap_rights_get), // 515 |
7809 | BSDX_(__NR_cap_enter, sys_cap_enter), // 516 | |
7810 | BSDXY(__NR_cap_getmode, sys_cap_getmode), // 517 | |
7811 | BSDXY(__NR_pdfork, sys_pdfork), // 518 | |
7812 | BSDX_(__NR_pdkill, sys_pdkill), // 519 | |
7813 | BSDXY(__NR_pdgetpid, sys_pdgetpid), // 520 | |
7814 | BSDXY(__NR_pselect, sys_pselect), // 522 | |
7815 | BSDXY(__NR_getloginclass, sys_getloginclass), // 523 | |
7816 | BSDX_(__NR_setloginclass, sys_setloginclass), // 524 | |
7817 | BSDXY(__NR_rctl_get_racct, sys_rctl_get_racct), // 525 | |
7818 | BSDXY(__NR_rctl_get_rules, sys_rctl_get_rules), // 526 | |
7819 | BSDXY(__NR_rctl_get_limits, sys_rctl_get_limits), // 527 | |
7820 | BSDXY(__NR_rctl_add_rule, sys_rctl_add_rule), // 528 | |
7821 | BSDXY(__NR_rctl_remove_rule, sys_rctl_remove_rule), // 529 | |
7822 | BSDX_(__NR_posix_fallocate, sys_posix_fallocate), // 530 | |
7823 | BSDX_(__NR_posix_fadvise, sys_posix_fadvise), // 531 | |
7824 | BSDXY(__NR_wait6, sys_wait6), // 532 | |
7825 | BSDX_(__NR_cap_rights_limit, sys_cap_rights_limit), // 533 | |
7826 | BSDX_(__NR_cap_ioctls_limit, sys_cap_ioctls_limit), // 534 | |
7827 | BSDXY(__NR_cap_ioctls_get, sys_cap_ioctls_get), // 535 | |
7828 | BSDX_(__NR_cap_fcntls_limit, sys_cap_fcntls_limit), // 536 | |
7829 | BSDXY(__NR_cap_fcntls_get, sys_cap_fcntls_get), // 537 | |
7830 | BSDX_(__NR_bindat, sys_bindat), // 538 | |
7831 | BSDX_(__NR_connectat, sys_connectat), // 539 | |
7832 | BSDX_(__NR_chflagsat, sys_chflagsat), // 540 | |
7833 | BSDXY(__NR_accept4, sys_accept4), // 541 | |
7834 | BSDXY(__NR_pipe2, sys_pipe2), // 542 | |
7835 | BSDX_(__NR_aio_mlock, sys_aio_mlock), // 543 | |
7836 | BSDXY(__NR_procctl, sys_procctl), // 544 | |
7837 | ||
7838 | // 544 is the highest syscall on FreeBSD 9 | |
e2e5d75f PF |
7839 | |
7840 | #if (FREEBSD_VERS >= FREEBSD_10) | |
7841 | ||
76d6b459 PF |
7842 | BSDXY(__NR_ppoll, sys_ppoll), // 545 |
7843 | BSDX_(__NR_futimens, sys_futimens), // 546 | |
7844 | BSDX_(__NR_utimensat, sys_utimensat), // 547 | |
e2e5d75f PF |
7845 | |
7846 | #endif // FREEBSD_VERS >= FREEBSD_10 | |
7847 | ||
7848 | #if (FREEBSD_VERS >= FREEBSD_11) | |
7849 | ||
7850 | /* 548 is obsolete numa_getaffinity */ | |
7851 | /* 549 is obsolete numa_setaffinity */ | |
76d6b459 | 7852 | BSDX_(__NR_fdatasync, sys_fdatasync), // 550 |
e2e5d75f PF |
7853 | |
7854 | #endif // FREEBSD_VERS >= FREEBSD_11 | |
7855 | ||
7856 | #if (FREEBSD_VERS >= FREEBSD_12) | |
76d6b459 PF |
7857 | BSDXY(__NR_fstat, sys_fstat), // 551 |
7858 | BSDXY(__NR_fstatat, sys_fstatat), // 552 | |
7859 | BSDXY(__NR_fhstat, sys_fhstat), // 553 | |
7860 | BSDXY(__NR_getdirentries, sys_getdirentries), // 554 | |
7861 | BSDXY(__NR_statfs, sys_statfs), // 555 | |
7862 | BSDXY(__NR_fstatfs, sys_fstatfs), // 556 | |
7863 | BSDXY(__NR_getfsstat, sys_getfsstat), // 557 | |
7864 | BSDXY(__NR_fhstatfs, sys_fhstatfs), // 558 | |
7865 | BSDX_(__NR_mknodat, sys_mknodat), // 559 | |
7866 | BSDXY(__NR_kevent, sys_kevent), // 560 | |
7867 | BSDXY(__NR_cpuset_getdomain, sys_cpuset_getdomain), // 561 | |
7868 | BSDX_(__NR_cpuset_setdomain, sys_cpuset_setdomain), // 562 | |
7869 | BSDXY(__NR_getrandom, sys_getrandom), // 563 | |
7870 | BSDXY(__NR_getfhat, sys_getfhat), // 564 | |
7871 | BSDX_(__NR_fhlink, sys_fhlink), // 565 | |
7872 | BSDX_(__NR_fhlinkat, sys_fhlinkat), // 566 | |
7873 | BSDXY(__NR_fhreadlink, sys_fhreadlink), // 567 | |
e2e5d75f PF |
7874 | #endif // FREEBSD_VERS >= FREEBSD_12 |
7875 | ||
7876 | #if (FREEBSD_VERS >= FREEBSD_12_2) | |
76d6b459 PF |
7877 | BSDX_(__NR_funlinkat, sys_funlinkat), // 568 |
7878 | BSDX_(__NR_copy_file_range, sys_copy_file_range), // 569 | |
7879 | BSDXY(__NR___sysctlbyname, sys___sysctlbyname), // 570 | |
6db18bae | 7880 | |
bbc3bcab | 7881 | #if (FREEBSD_VERS >= FREEBSD_13_0) |
76d6b459 | 7882 | BSDXY(__NR_shm_open2, sys_shm_open2), // 571 |
e2e5d75f | 7883 | // unimpl __NR_shm_rename 572 |
76d6b459 PF |
7884 | BSDX_(__NR_sigfastblock, sys_sigfastblock), // 573 |
7885 | BSDXY( __NR___realpathat, sys___realpathat), // 574 | |
6db18bae | 7886 | #endif |
d4c9a985 | 7887 | BSDXY(__NR_close_range, sys_close_range), // 575 |
e2e5d75f PF |
7888 | #endif |
7889 | ||
bbc3bcab | 7890 | #if (FREEBSD_VERS >= FREEBSD_13_0) |
e2e5d75f | 7891 | // unimpl __NR_rpctls_syscall 576 |
76d6b459 | 7892 | BSDX_(__NR___specialfd, sys___specialfd), // 577 |
a15b387e PF |
7893 | BSDX_(__NR_aio_writev, sys_aio_writev), // 578 |
7894 | BSDXY(__NR_aio_readv, sys_aio_readv), // 579 | |
e2e5d75f PF |
7895 | #endif |
7896 | ||
6cb8e52c | 7897 | #if (FREEBSD_VERS >= FREEBSD_13_1) |
3cacde0c PF |
7898 | |
7899 | #if (FREEBSD_VERS >= FREEBSD_14) | |
7900 | BSDXY(__NR_fspacectl, sys_fspacectl), // 580 | |
7901 | #endif | |
f540c799 | 7902 | // unimpl __NR_sched_getcpu 581 |
76d6b459 | 7903 | BSDX_(__NR_swapoff, sys_swapoff), // 582 |
f540c799 PF |
7904 | #endif |
7905 | ||
32ca31e9 | 7906 | #if (FREEBSD_VERS >= FREEBSD_15) || (FREEBSD_VERS >= FREEBSD_13_3) |
22069cd2 PF |
7907 | BSDXY(__NR_kqueuex, sys_kqueuex), // 583 |
7908 | BSDX_(__NR_membarrier, sys_membarrier), // 584 | |
32ca31e9 PF |
7909 | #endif |
7910 | #if (FREEBSD_VERS >= FREEBSD_15) | |
adf7cb52 PF |
7911 | BSDXY(__NR_timerfd_create, sys_timerfd_create), // 585 |
7912 | BSDXY(__NR_timerfd_settime, sys_timerfd_settime), // 586 | |
7913 | BSDXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 587 | |
49d5458a | 7914 | BSDX_(__NR_kcmp, sys_kcmp), // 588 |
adf7cb52 PF |
7915 | #endif |
7916 | ||
7917 | ||
76d6b459 | 7918 | BSDX_(__NR_fake_sigreturn, sys_fake_sigreturn), // 1000, fake sigreturn |
e2e5d75f PF |
7919 | |
7920 | }; | |
7921 | ||
76d6b459 | 7922 | const SyscallTableEntry* ML_(get_freebsd_syscall_entry) ( UInt sysno ) |
e2e5d75f | 7923 | { |
76d6b459 PF |
7924 | const UInt syscall_table_size |
7925 | = sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]); | |
e2e5d75f PF |
7926 | |
7927 | /* Is it in the contiguous initial section of the table? */ | |
7928 | if (sysno < syscall_table_size) { | |
7929 | const SyscallTableEntry* sys = &ML_(syscall_table)[sysno]; | |
29cfa77b | 7930 | if (sys->before == NULL) { |
e2e5d75f | 7931 | return NULL; /* no entry */ |
29cfa77b PF |
7932 | } |
7933 | return sys; | |
e2e5d75f PF |
7934 | } |
7935 | ||
7936 | /* Can't find a wrapper */ | |
7937 | return NULL; | |
7938 | } | |
7939 | ||
7940 | /*--------------------------------------------------------------------*/ | |
7941 | /*--- end ---*/ | |
7942 | /*--------------------------------------------------------------------*/ | |
7943 | ||
7944 | #endif // defined(VGO_freebsd) |