]> git.ipfire.org Git - thirdparty/valgrind.git/blame - coregrind/m_syswrap/syswrap-freebsd.c
FreeBSD ioctl: enable SIOCGIFMEDIA PCIOCGETCONF CAMIOCOMMAND ioctls and add SIOCGIFSTATUS
[thirdparty/valgrind.git] / coregrind / m_syswrap / syswrap-freebsd.c
CommitLineData
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
69static Bool capabiltyMode = False;
70
76d6b459
PF
71Bool 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.
79static 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))
150static 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 302Word 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. */
315Addr 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))
359void 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 399SysRes 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 439static 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 455static 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);
478PRE(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);
508PRE(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);
564PRE(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);
580PRE(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);
598PRE(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
685POST(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);
781PRE(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
789POST(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);
797PRE(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
809PRE(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
819POST(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);
829PRE(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
838POST(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);
850PRE(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
858POST(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);
868PRE(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
876POST(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
888PRE(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);
898PRE(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
919PRE(sys_pipe)
920{
921 PRINT("%s", "sys_pipe ()");
922}
e2e5d75f
PF
923
924POST(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
956PRE(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
963POST(sys_getlogin)
964{
965 POST_MEM_WRITE(ARG1, ARG2 );
966}
e2e5d75f
PF
967
968// SYS_setlogin 50
969// int setlogin(const char *name);
970PRE(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, ...);
985PRE(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
1079POST(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);
1134PRE(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);
1142PRE(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 1152static 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
1168PRE(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);
1213PRE(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);
1229PRE(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);
1267PRE(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);
1279PRE(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, ...);
1290PRE(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
1368POST(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);
1403PRE(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
1409POST(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);
1419PRE(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);
1433PRE(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);
1444PRE(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);
1455PRE(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);
1470PRE(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
1485POST(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);
1526PRE(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);
1536PRE(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);
1549PRE(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);
1558PRE(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
1566POST(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);
1584PRE(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
1595POST(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); */
1607PRE(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);
1651PRE(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
1659POST(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);
1666PRE(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
1674POST(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);
1682PRE(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
1690POST(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);
1699PRE(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);
1708PRE(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
1715POST(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
1727PRE(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
1741POST(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);
1756PRE(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);
1771PRE(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);
1779PRE(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);
1790PRE(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
1798POST(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);
1805PRE(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
1812POST(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);
1819PRE(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
1827POST(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
1837PRE(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
1845POST(sys_stat)
1846{
1847 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
e2e5d75f
PF
1848}
1849
1850
1851PRE(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
1858POST(sys_fstat)
1859{
1860 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1861}
e2e5d75f
PF
1862
1863PRE(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
1871POST(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);
1883PRE(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);
1892PRE(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)
1908PRE(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
1922POST(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
1933PRE(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
1946POST(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
1973static 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
1990static void sysctl_kern_usrstack(SizeT* out, SizeT* outlen)
1991{
76d6b459 1992 *out = VG_(get_usrstack)();
b29a1e1c
PF
1993 *outlen = sizeof(ULong);
1994}
1995
76d6b459 1996static 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
2024PRE(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
2162POST(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);
2182PRE(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);
2192PRE(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, ...);
2209PRE(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
2236POST(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);
2247PRE(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);
2255PRE(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);
2266PRE(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
2284POST(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);
2295PRE(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);
2303PRE(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
2313PRE(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
2325POST(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);
2334PRE(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
2348POST(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);
2355PRE(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
2372POST(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);
2381PRE(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
2390POST(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);
2397PRE(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);
2406PRE(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
2414POST(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);
2421PRE(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);
2431PRE(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
2443POST(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);
2453PRE(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
2465POST(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);
2472PRE(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);
2482PRE(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
2497POST(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);
2506PRE(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
2515POST(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);
2522PRE(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);
2546PRE(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
2559POST(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
2569POST(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);
2581PRE(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
2591POST(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);
2603PRE(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.
2616static OSet* iocb_table = NULL;
2617static Bool aio_init_done = False;
2618
2619static 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
2626static OSet* iocbv_table = NULL;
2627static Bool aiov_init_done = False;
2628
2629static 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);
2638PRE(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
2659POST(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);
2681PRE(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);
2705PRE(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);
2742PRE(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);
2751PRE(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);
2778PRE(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
2789POST(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)
2805PRE(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
2813POST(sys_freebsd11_fhstat)
2814{
76d6b459 2815 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
e2e5d75f
PF
2816}
2817#else
2818PRE(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
2826POST(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);
2835PRE(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);
2843PRE(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
2850POST(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);
2857PRE(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);
2865PRE(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);
2874PRE(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);
2883PRE(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);
2891PRE(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);
2900PRE(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);
2908PRE(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
2915POST(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);
2922PRE(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);
2930PRE(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);
2939PRE(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);
2948PRE(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);
3001PRE(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);
3015PRE(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);
3044PRE(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
3057int yield(void);
3058PRE(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);
3070PRE(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);
3079PRE(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
3086POST(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
3100PRE(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
3108POST(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);
3115PRE(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
3123POST(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);
3131PRE(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);
3144PRE(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);
3152PRE(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);
3161PRE(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);
3169PRE(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);
3177PRE(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
3184POST(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);
3191PRE(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);
3200PRE(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
3211POST(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);
3220PRE(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);
3233PRE(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
3266POST(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);
3276PRE(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
3287POST(sys_sigsuspend)
3288{
3289 ML_(free_safe_mask) ( (Addr)ARG1 );
3290}
e2e5d75f
PF
3291
3292// SYS_sigpending 343
3293// int sigpending(sigset_t *set);
3294PRE(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
3301POST(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);
3310PRE(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
3330POST(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);
3339PRE(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
3354POST(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);
3363PRE(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
3372POST(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);
3382PRE(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);
3393PRE(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
3401POST(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);
3411PRE(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);
3421PRE(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);
3430PRE(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);
3439PRE(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);
3450PRE(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
3461PRE(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
3474PRE(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);
3487PRE(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
3499POST(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);
3509PRE(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);
3520PRE(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
3531POST(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);
3538PRE(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
3548POST(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);
3560PRE(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
3570POST(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);
3582PRE(sys_kqueue)
3583{
410adb9b
PF
3584 PRINT("%s", "sys_kqueue(void)");
3585 PRE_REG_READ0(int, "kqueue");
e2e5d75f
PF
3586}
3587
3588POST(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)
3605PRE(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
3627POST(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
3637PRE(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
3654POST(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);
3667PRE(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);
3678PRE(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
3686POST(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);
3693PRE(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);
3703PRE(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);
3711PRE(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);
3723PRE(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);
3750PRE(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
3768POST(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);
3786PRE(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);
3796PRE(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
3804POST(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
3822PRE(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
3829POST(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);
3839PRE(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
3847POST(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);
3854PRE(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
3862POST(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);
3869PRE(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
3878POST(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
3886PRE(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
3893POST(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
3901PRE(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
3909POST(sys_statfs)
3910{
3911 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3912}
e2e5d75f
PF
3913
3914PRE(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
3922POST(sys_fstatfs)
3923{
3924 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3925}
e2e5d75f
PF
3926
3927PRE(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
3936POST(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
3983PRE(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);
3996PRE(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
4008POST(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);
4018PRE(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);
4033PRE(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
4096POST(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
4112POST(sys_getcontext)
4113{
4114 POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) );
4115}
e2e5d75f
PF
4116
4117POST(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);
4127PRE(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);
4136PRE(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);
4146PRE(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
4155POST(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);
4165PRE(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);
4175PRE(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);
4185PRE(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);
4196PRE(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
4211POST(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
4221PRE(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);
4234PRE(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);
4253PRE(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
4260POST(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);
4267PRE(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
4303POST(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
4313PRE(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
4321POST(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
4329PRE(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
4337POST(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);
4347PRE(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
4355PRE(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
4362POST(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);
4370PRE(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
4378POST(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);
4386PRE(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
4394POST(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);
4404PRE(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);
4418PRE(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);
4433PRE(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);
4476PRE(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
4768POST(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);
4845PRE(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
4855PRE(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
4882POST(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);
4898PRE(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
4920PRE(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
4944POST(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);
4955PRE(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);
4976PRE(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);
4992PRE(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);
5001PRE(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);
5013PRE(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);
5030PRE(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);
5039PRE(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
5053POST(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
5070PRE(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
5099PRE(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
5132POST(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);
5174PRE(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
5210POST(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);
5220PRE(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
5233POST(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);
5248PRE(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);
5261PRE(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
5268POST(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);
5287PRE(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);
5297PRE(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);
5307PRE(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[]);
5319PRE(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)
5398PRE(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
5407POST(sys_freebsd11_fstatat)
5408{
76d6b459 5409 POST_MEM_WRITE( ARG3, sizeof(struct vki_freebsd11_stat) );
e2e5d75f
PF
5410}
5411#else
5412PRE(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
5421POST(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]);
5429PRE(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);
5444PRE(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);
5458PRE(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);
5469PRE(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)
5481PRE(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
5489PRE(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, ...);
5500PRE(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
5524POST(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);
5540PRE(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
5571POST(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);
5578PRE(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);
5590PRE(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);
5602PRE(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);
5613PRE(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);
5626PRE(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);
5636PRE(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);
5646PRE(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);
5654PRE(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
5674POST(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);
5692PRE(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
5720POST(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);
5731PRE(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
5749POST(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);
5761PRE(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
5778POST(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);
5787PRE(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);
5798PRE(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
5805POST(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);
5812PRE(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);
5831PRE(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
5838POST(sys_cap_getmode)
5839{
5840 POST_MEM_WRITE(ARG1, sizeof(u_int));
5841}
e2e5d75f
PF
5842
5843static vki_sigset_t pdfork_saved_mask;
5844
5845// SYS_pdfork 518
5846// pid_t pdfork(int *fdp, int flags);
5847PRE(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
5892POST(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
5901PRE(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);
5949PRE(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
5957POST(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);
5968PRE(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
6001POST(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);
6008PRE(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
6016POST(sys_getloginclass)
6017{
6018 POST_MEM_WRITE(ARG1, ARG2);
6019}
e2e5d75f
PF
6020
6021// SYS_setloginclass 524
6022// int setloginclass(const char *name);
6023PRE(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);
6033PRE(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
6042POST(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);
6050PRE(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
6059POST(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);
6067PRE(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
6076POST(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);
6084PRE(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
6094POST(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);
6102PRE(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
6112POST(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
6128PRE(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);
6138PRE(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);
6152PRE(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
6161POST(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
6171PRE(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);
6180PRE(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
6187POST(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);
6194PRE(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);
6204PRE(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);
6214PRE(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);
6225PRE(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
6234POST(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);
6245PRE(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
6254POST(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);
6278PRE(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);
6294PRE(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
6327POST(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]);
6341PRE(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);
6351PRE(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);
6363PRE(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);
6372PRE(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
6379POST(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);
6386PRE(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
6395POST(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);
6401PRE(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
6409POST(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);
6416PRE(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
6430POST(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);
6443PRE(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
6451POST(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);
6458PRE(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
6466POST(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);
6473PRE(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
6480POST(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);
6490PRE(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
6499POST(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);
6511PRE(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
6533POST(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);
6551PRE(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
6562POST(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);
6569PRE(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
6577POST(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);
6584PRE(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);
6594PRE(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);
6604PRE(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
6612POST(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);
6623PRE(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);
6635PRE(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
6675PRE(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
6738POST(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);
6761PRE(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
6780POST(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);
6795PRE(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)
6808PRE(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
6818POST(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);
6829PRE(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
6877POST(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);
6904PRE(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);
6914PRE(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);
6954PRE(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
6987POST(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);
7014PRE(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
7024POST(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);
7034PRE(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);
7047PRE(sys_kqueuex)
7048{
7049 PRINT("sys_kqueuex(%#" FMT_REGWORD "x)", ARG1);
7050 PRE_REG_READ1(int, "kqueuex", u_int, flags);
7051}
7052
7053POST(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);
7068PRE(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);
7083PRE(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
7089POST(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);
7102PRE(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
7115POST(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);
7124PRE(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
7147POST(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);
7156PRE(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
7184const 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 7922const 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)