FreeBSD: add file descriptor tracking for _umtx_op
[valgrind.git] / coregrind / m_syswrap / syswrap-freebsd.c
blob071e6ab1523607ca5f1a33163eac91a6499e6130
1 /*--------------------------------------------------------------------*/
2 /*--- FreeBSD-specific syscalls, etc. syswrap-freebsd.c ---*/
3 /*--------------------------------------------------------------------*/
5 /*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
9 Copyright (C) 2000-2008 Nicholas Nethercote
10 njn@valgrind.org
11 Copyright (C) 2018-2021 Paul Floyd
12 pjfloyd@wanadoo.fr
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.
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.
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/>.
27 The GNU General Public License is contained in the file COPYING.
30 #if defined(VGO_freebsd)
32 #include "pub_core_basics.h"
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"
40 #include "pub_core_clientstate.h"
41 #include "pub_core_debuglog.h"
42 #include "pub_core_libcbase.h"
43 #include "pub_core_libcassert.h"
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"
50 #include "pub_core_tooliface.h"
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"
57 #include "pub_core_inner.h"
58 #include "pub_core_pathscan.h"
59 #include "pub_core_oset.h"
60 #if defined(ENABLE_INNER_CLIENT_REQUEST)
61 #include "pub_core_clreq.h"
62 #endif
64 #include "priv_types_n_macros.h"
65 #include "priv_syswrap-generic.h"
66 #include "priv_syswrap-main.h"
67 #include "priv_syswrap-freebsd.h"
69 static Bool capabiltyMode = False;
71 Bool VG_(get_capability_mode)(void)
73 return capabiltyMode;
77 // Run a thread from beginning to end and return the thread's
78 // scheduler-return-code.
79 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
81 VgSchedReturnCode ret;
82 ThreadId tid = (ThreadId)tidW;
83 Int lwpid = VG_(gettid)();
84 ThreadState* tst = VG_(get_ThreadState)(tid);
86 VG_(debugLog)(1, "syswrap-freebsd",
87 "thread_wrapper(tid=%u,lwpid=%d): entry\n",
88 tid, lwpid);
90 vg_assert(tst->status == VgTs_Init);
92 /* make sure we get the CPU lock before doing anything significant */
93 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
95 if (0) {
96 VG_(printf)("thread tid %u started: stack = %p\n",
97 tid, (void*)&tid);
100 /* Make sure error reporting is enabled in the new thread. */
101 tst->err_disablement_level = 0;
103 VG_TRACK(pre_thread_first_insn, tid);
105 tst->os_state.lwpid = lwpid;
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)();
110 /* Thread created with all signals blocked; scheduler will set the
111 appropriate mask */
113 ret = VG_(scheduler)(tid);
115 vg_assert(VG_(is_exiting)(tid));
117 vg_assert(tst->status == VgTs_Runnable);
118 vg_assert(VG_(is_running_thread)(tid));
120 VG_(debugLog)(1, "syswrap-freebsd",
121 "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n",
122 tid, lwpid, VG_(name_of_VgSchedReturnCode)(ret));
124 /* Return to caller, still holding the lock. */
125 return ret;
129 /* ---------------------------------------------------------------------
130 clone-related stuff
131 ------------------------------------------------------------------ */
133 /* Run a thread all the way to the end, then do appropriate exit actions
134 * (this is the last-one-out-turn-off-the-lights bit).
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.
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.
146 * If you really need a working base pointer modify Makefile.all.am
147 * and add -fno-omit-frame-pointer to AM_CFLAGS_BASE.
149 __attribute__((noreturn))
150 static void run_a_thread_NORETURN ( Word tidW )
152 ThreadId tid = (ThreadId)tidW;
153 VgSchedReturnCode src;
154 Int c;
155 ThreadState* tst;
156 #ifdef ENABLE_INNER_CLIENT_REQUEST
157 Int registered_vgstack_id;
158 #endif
160 VG_(debugLog)(1, "syswrap-freebsd",
161 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
162 tid);
164 tst = VG_(get_ThreadState)(tid);
165 vg_assert(tst);
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.
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));
180 /* Run the thread all the way through. */
181 src = thread_wrapper(tid);
183 VG_(debugLog)(1, "syswrap-freebsd",
184 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
185 tid);
187 c = VG_(count_living_threads)();
188 vg_assert(c >= 1); /* stay sane */
190 /* Deregister thread's stack. */
191 if (tst->os_state.stk_id != NULL_STK_ID) {
192 VG_(deregister_stack)(tst->os_state.stk_id);
195 // Tell the tool this thread is exiting
196 VG_TRACK( pre_thread_ll_exit, tid );
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) {
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"
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
217 tst->err_disablement_level = 0;
219 if (c == 1) {
221 VG_(debugLog)(1, "syswrap-freebsd",
222 "run_a_thread_NORETURN(tid=%u): "
223 "last one standing\n",
224 tid);
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. */
229 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
230 } else {
232 VG_(debugLog)(1, "syswrap-freebsd",
233 "run_a_thread_NORETURN(tid=%u): "
234 "not last one standing\n",
235 tid);
237 /* OK, thread is dead, but others still exist. Just exit. */
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));
245 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
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. */
255 #if defined(VGP_x86_freebsd) /* FreeBSD has args on the stack */
256 __asm__ volatile (
257 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
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"
269 #elif defined(VGP_amd64_freebsd)
270 __asm__ volatile (
271 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
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"
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"
291 #else
292 # error Unknown platform
293 #endif
295 VG_(core_panic)("Thread exit failed?\n");
298 /*NOTREACHED*/
299 vg_assert(0);
302 Word ML_(start_thread_NORETURN) ( void* arg )
304 ThreadState* tst = (ThreadState*)arg;
305 ThreadId tid = tst->tid;
307 run_a_thread_NORETURN ( (Word)tid );
308 /*NOTREACHED*/
309 vg_assert(0);
312 /* Allocate a stack for this thread, if it doesn't already have one.
313 They're allocated lazily, and never freed. Returns the initial stack
314 pointer value to use, or 0 if allocation failed. */
315 Addr ML_(allocstack)(ThreadId tid)
317 ThreadState* tst = VG_(get_ThreadState)(tid);
318 VgStack* stack;
319 Addr initial_SP;
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. */
325 if (tst->os_state.valgrind_stack_base == 0) {
326 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
329 if (tst->os_state.valgrind_stack_base != 0) {
330 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
333 /* If no stack is present, allocate one. */
335 if (tst->os_state.valgrind_stack_base == 0) {
336 stack = VG_(am_alloc_VgStack)( &initial_SP );
337 if (stack) {
338 tst->os_state.valgrind_stack_base = (Addr)stack;
339 tst->os_state.valgrind_stack_init_SP = initial_SP;
343 if (0) {
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 );
350 return tst->os_state.valgrind_stack_init_SP;
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.
358 __attribute__((noreturn))
359 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
361 Addr sp;
362 VG_(debugLog)(1, "syswrap-freebsd",
363 "entering VG_(main_thread_wrapper_NORETURN)\n");
365 sp = ML_(allocstack)(tid);
366 #if defined(ENABLE_INNER_CLIENT_REQUEST)
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);
372 INNER_REQUEST
373 ((void)
374 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
375 tst->os_state.valgrind_stack_init_SP));
377 #endif
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.");
383 /* shouldn't be any other threads around yet */
384 vg_assert( VG_(count_living_threads)() == 1 );
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 */
393 /*NOTREACHED*/
394 vg_assert(0);
398 /* Do a fork() */
399 SysRes ML_(do_fork) ( ThreadId tid )
401 vki_sigset_t fork_saved_mask;
402 vki_sigset_t mask;
403 SysRes res;
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);
410 VG_(do_atfork_pre)(tid);
412 res = VG_(do_syscall0)( __NR_fork );
414 if (!sr_isError(res)) {
415 if (sr_Res(res) == 0) {
416 /* child */
417 VG_(do_atfork_child)(tid);
419 /* restore signal mask */
420 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
422 } else {
423 /* parent */
424 VG_(do_atfork_parent)(tid);
426 if (VG_(clo_trace_syscalls)) {
427 VG_(printf)(" clone(fork): process %d created child %lu\n",
428 VG_(getpid)(), sr_Res(res));
431 /* restore signal mask */
432 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
436 return res;
439 static Addr ML_(make_safe_mask) ( const HChar* malloc_message, Addr mask_pointer )
441 vki_sigset_t* new_mask;
442 const vki_sigset_t* old_mask = (vki_sigset_t *)mask_pointer;
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 {
447 new_mask = VG_(malloc)(malloc_message, sizeof(vki_sigset_t));
448 *new_mask = *old_mask;
449 VG_(sanitize_client_sigmask)(new_mask);
452 return (Addr)new_mask;
455 static void ML_(free_safe_mask) ( Addr mask_pointer )
457 if (mask_pointer != 0 && mask_pointer != 1) {
458 VG_(free)((vki_sigset_t *) mask_pointer);
463 /* ---------------------------------------------------------------------
464 PRE/POST wrappers for arch-generic, FreeBSD-specific syscalls
465 ------------------------------------------------------------------ */
467 // Nb: See the comment above the generic PRE/POST wrappers in
468 // m_syswrap/syswrap-generic.c for notes about how they work.
470 #define PRE(name) DEFN_PRE_TEMPLATE(freebsd, name)
471 #define POST(name) DEFN_POST_TEMPLATE(freebsd, name)
473 /* On FreeBSD, if any thread calls exit(2), then they are all shut down, pretty
474 * much like linux's exit_group().
476 // SYS_exit 1
477 // void exit(int status);
478 PRE(sys_exit)
480 ThreadId t;
482 PRINT("exit( %" FMT_REGWORD "u )", ARG1);
483 PRE_REG_READ1(void, "exit", int, status);
485 /* Mark all threads (including this one) to exit. */
486 for (t = 1; t < VG_N_THREADS; t++) {
487 if ( /* not alive */ VG_(threads)[t].status == VgTs_Empty ) {
488 continue;
491 //VG_(threads)[t].exitreason = VgSrc_ExitThread;
492 VG_(threads)[t].os_state.exitcode = ARG1;
494 // if (t != tid)
495 // VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */
498 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
499 VG_(reap_threads)(tid);
500 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
502 /* We have to claim the syscall already succeeded. */
503 SET_STATUS_Success(0);
506 // SYS_fork 2
507 // pid_t fork(void);
508 PRE(sys_fork)
510 PRINT("%s", "sys_fork ()");
511 PRE_REG_READ0(pid_t, "fork");
513 SET_STATUS_from_SysRes( ML_(do_fork)(tid) );
514 if (SUCCESS) {
515 /* Thread creation was successful; let the child have the chance
516 to run */
517 *flags |= SfYieldAfter;
521 // SYS_read 3
522 // generic
524 // SYS_write 4
525 // generic
527 // SYS_open 5
528 // generic
530 // SYS_close 6
531 // generic
533 // SYS_wait4 7
534 // generic
536 // SYS_link 9
537 // generic
539 // SYS_unlink 10
540 // generic
542 // SYS_chdir 12
544 // SYS_fchdir 13
545 // generic
547 // SYS_freebsd11_mknod 14
548 // generic
550 // SYS_chmod 15
551 // generic
553 // SYS_chown 16
554 // generic
556 // SYS_break 17
557 // generic
559 // SYS_getpid 20
560 // generic
562 // SYS_mount 21
563 // int mount(const char *type, const char *dir, int flags, void *data);
564 PRE(sys_mount)
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;
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);
578 // SYS_unmount 22
579 // int unmount(const char *dir, int flags);
580 PRE(sys_unmount)
582 PRINT("sys_umount( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
583 PRE_REG_READ2(int, "unmount", const char *, dir, int, flags);
584 PRE_MEM_RASCIIZ( "unmount(path)", ARG1);
587 // SYS_setuid 23
588 // generic
590 // SYS_getuid 24
591 // generic
593 // SYS_geteuid 25
594 // generic
596 // SYS_ptrace 26
597 // int ptrace(int request, pid_t pid, caddr_t addr, int data);
598 PRE(sys_ptrace)
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);
603 PRE_REG_READ4(int, "ptrace", int, request, pid_t, pid, caddr_t, addr, int, data);
605 switch (ARG1) {
606 case VKI_PTRACE_TRACEME:
607 case VKI_PTRACE_READ_I:
608 case VKI_PTRACE_READ_D:
609 case VKI_PTRACE_WRITE_I:
610 case VKI_PTRACE_WRITE_D:
611 break;
613 case VKI_PTRACE_IO:
614 PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_ptrace_io_desc));
615 io_desc = (struct vki_ptrace_io_desc *)ARG3;
616 switch (io_desc->piod_op) {
617 case VKI_PIOD_READ_D:
618 case VKI_PIOD_READ_I:
619 PRE_MEM_WRITE( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len);
620 break;
621 case VKI_PIOD_WRITE_D:
622 case VKI_PIOD_WRITE_I:
623 PRE_MEM_READ( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len);
624 break;
626 break;
628 case VKI_PTRACE_CONTINUE:
629 case VKI_PTRACE_STEP:
630 case VKI_PTRACE_KILL:
631 case VKI_PTRACE_ATTACH:
632 case VKI_PTRACE_DETACH:
633 break;
635 case VKI_PTRACE_GETREGS:
636 PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_user_regs_struct));
637 break;
639 case VKI_PTRACE_SETREGS:
640 PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_user_regs_struct));
641 break;
643 case VKI_PTRACE_GETFPREGS:
644 PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_fpreg));
645 break;
647 case VKI_PTRACE_SETFPREGS:
648 PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_fpreg));
649 break;
651 case VKI_PTRACE_GETDBREGS:
652 PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_dbreg));
653 break;
655 case VKI_PTRACE_SETDBREGS:
656 PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_dbreg));
657 break;
659 case VKI_PTRACE_LWPINFO:
660 PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_ptrace_lwpinfo));
661 break;
663 case VKI_PTRACE_GETNUMLWPS:
664 break;
666 case VKI_PTRACE_GETLWPLIST:
667 PRE_MEM_WRITE( "ptrace", ARG3, sizeof(vki_lwpid_t) * ARG4);
668 break;
670 case VKI_PTRACE_SETSTEP:
671 case VKI_PTRACE_CLEARSTEP:
672 case VKI_PTRACE_SUSPEND:
673 case VKI_PTRACE_RESUME:
674 case VKI_PTRACE_TO_SCE:
675 case VKI_PTRACE_TO_SCX:
676 case VKI_PTRACE_SYSCALL:
677 case VKI_PTRACE_VM_TIMESTAMP:
678 break;
679 case VKI_PTRACE_VM_ENTRY:
680 PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_ptrace_vm_entry));
681 break;
685 POST(sys_ptrace)
687 struct vki_ptrace_io_desc *io_desc;
689 switch (ARG1) {
690 case VKI_PTRACE_TRACEME:
691 case VKI_PTRACE_READ_I:
692 case VKI_PTRACE_READ_D:
693 case VKI_PTRACE_WRITE_I:
694 case VKI_PTRACE_WRITE_D:
695 break;
697 case VKI_PTRACE_IO:
698 io_desc = (struct vki_ptrace_io_desc *)ARG3;
699 switch (io_desc->piod_op) {
700 case VKI_PIOD_READ_D:
701 case VKI_PIOD_READ_I:
702 if ((Word)RES != -1) {
703 POST_MEM_WRITE((UWord)io_desc->piod_addr, io_desc->piod_len);
705 break;
706 case VKI_PIOD_WRITE_D:
707 case VKI_PIOD_WRITE_I:
708 break;
710 break;
712 case VKI_PTRACE_CONTINUE:
713 case VKI_PTRACE_STEP:
714 case VKI_PTRACE_KILL:
715 case VKI_PTRACE_ATTACH:
716 case VKI_PTRACE_DETACH:
717 break;
719 case VKI_PTRACE_GETREGS:
720 if ((Word)RES != -1) {
721 POST_MEM_WRITE(ARG3, sizeof(struct vki_user_regs_struct));
723 break;
725 case VKI_PTRACE_SETREGS:
726 break;
728 case VKI_PTRACE_GETFPREGS:
729 if ((Word)RES != -1) {
730 POST_MEM_WRITE(ARG3, sizeof(struct vki_fpreg));
732 break;
734 case VKI_PTRACE_SETFPREGS:
735 break;
737 case VKI_PTRACE_GETDBREGS:
738 if ((Word)RES != -1) {
739 POST_MEM_WRITE(ARG3, sizeof(struct vki_dbreg));
741 break;
743 case VKI_PTRACE_SETDBREGS:
744 break;
746 case VKI_PTRACE_LWPINFO:
747 if ((Word)RES != -1) {
748 POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_lwpinfo));
750 break;
752 case VKI_PTRACE_GETNUMLWPS:
753 break;
755 case VKI_PTRACE_GETLWPLIST:
756 if ((Word)RES != -1) {
757 POST_MEM_WRITE(ARG3, sizeof(vki_lwpid_t) * RES);
759 break;
761 case VKI_PTRACE_SETSTEP:
762 case VKI_PTRACE_CLEARSTEP:
763 case VKI_PTRACE_SUSPEND:
764 case VKI_PTRACE_RESUME:
765 case VKI_PTRACE_TO_SCE:
766 case VKI_PTRACE_TO_SCX:
767 case VKI_PTRACE_SYSCALL:
768 case VKI_PTRACE_VM_TIMESTAMP:
769 break;
771 case VKI_PTRACE_VM_ENTRY:
772 if ((Word)RES != -1) {
773 POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_vm_entry));
775 break;
779 // SYS_recvmsg 27
780 // ssize_t recvmsg(int s, struct msghdr *msg, int flags);
781 PRE(sys_recvmsg)
783 *flags |= SfMayBlock;
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);
789 POST(sys_recvmsg)
792 ML_(generic_POST_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2, RES);
795 // SYS_sendmsg 28
796 // ssize_t sendmsg(int s, const struct msghdr *msg, int flags);
797 PRE(sys_sendmsg)
799 *flags |= SfMayBlock;
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);
806 // SYS_recvfrom 29
807 // ssize_t recvfrom(int s, void *buf, size_t len, int flags,
808 // struct sockaddr * restrict from, socklen_t * restrict fromlen);
809 PRE(sys_recvfrom)
811 *flags |= SfMayBlock;
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);
819 POST(sys_recvfrom)
821 vg_assert(SUCCESS);
822 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
823 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
826 // SYS_accept 30
827 // int accept(int s, struct sockaddr * restrict addr,
828 // socklen_t * restrict addrlen);
829 PRE(sys_accept)
831 *flags |= SfMayBlock;
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);
838 POST(sys_accept)
840 SysRes r;
841 vg_assert(SUCCESS);
842 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
843 ARG1,ARG2,ARG3);
844 SET_STATUS_from_SysRes(r);
847 // SYS_getpeername 31
848 // int getpeername(int s, struct sockaddr * restrict name,
849 // socklen_t * restrict namelen);
850 PRE(sys_getpeername)
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);
858 POST(sys_getpeername)
860 vg_assert(SUCCESS);
861 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
862 ARG1,ARG2,ARG3);
865 // SYS_getsockname 32
866 // int getsockname(int s, struct sockaddr * restrict name,
867 // socklen_t * restrict namelen);
868 PRE(sys_getsockname)
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);
876 POST(sys_getsockname)
878 vg_assert(SUCCESS);
879 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
880 ARG1,ARG2,ARG3);
883 // SYS_access 33
884 // generic
886 // SYS_chflags 34
887 // int chflags(const char *path, unsigned long flags)
888 PRE(sys_chflags)
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 );
896 // SYS_fchflags 35
897 // int fchflags(int fd, unsigned long flags);
898 PRE(sys_fchflags)
900 PRINT("sys_fchflags ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2);
901 PRE_REG_READ2(int, "fchflags", int, fd, unsigned long, flags);
904 // SYS_sync 36
905 // generic
907 // SYS_kill 37
908 // generic
910 // SYS_getppid 39
911 // generic
913 // SYS_dup 41
914 // generic
916 // Pipe on freebsd doesn't have args, and uses dual returns!
917 // SYS_freebsd10_pipe 42
918 // int pipe(void);
919 PRE(sys_pipe)
921 PRINT("%s", "sys_pipe ()");
924 POST(sys_pipe)
926 if (!ML_(fd_allowed)(RES, "pipe", tid, True) ||
927 !ML_(fd_allowed)(RESHI, "pipe", tid, True)) {
928 VG_(close)(RES);
929 VG_(close)(RESHI);
930 SET_STATUS_Failure( VKI_EMFILE );
931 } else {
932 if (VG_(clo_track_fds)) {
933 ML_(record_fd_open_nameless)(tid, RES);
934 ML_(record_fd_open_nameless)(tid, RESHI);
939 // SYS_getegid 43
940 // generic
942 // SYS_profil 44
943 // generic
945 // SYS_ktrace 45
946 // generic
948 // SYS_getgid 47
949 // generic
951 // SYS_getlogin 49
952 // syscall.master refers to namelen and namebuf for the argument names
953 // man getlogin has just getlogin(void) but also
954 // int getlogin_r(char *name, int len);
955 // so let's go with those names
956 PRE(sys_getlogin)
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 );
963 POST(sys_getlogin)
965 POST_MEM_WRITE(ARG1, ARG2 );
968 // SYS_setlogin 50
969 // int setlogin(const char *name);
970 PRE(sys_setlogin)
972 PRINT("sys_setlogin ( %#" FMT_REGWORD "x )",ARG1);
973 PRE_REG_READ1(long, "setlogin", char *, buf);
974 PRE_MEM_RASCIIZ( "setlogin(buf)", ARG1 );
977 // SYS_acct 51
978 // generic
980 // SYS_sigaltstack 53
981 // generic
983 // SYS_ioctl 54
984 // int ioctl(int fd, unsigned long request, ...);
985 PRE(sys_ioctl)
987 *flags |= SfMayBlock;
988 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3);
989 PRE_REG_READ3(int, "ioctl",
990 int, fd, unsigned long, request, unsigned long, arg);
992 switch (ARG2 /* request */) {
993 /* Handle specific ioctls which pass structures which may have pointers to other
994 buffers */
995 case VKI_BIOCSETF:
996 // #define BIOCSETF _IOW('B', 103, struct bpf_program)
997 // "usbconfig" to get a list of devices then
998 // test with "usbdump -i usbus0" (as root)
999 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_bpf_program))) {
1000 struct vki_bpf_program* fp = (struct vki_bpf_program*)ARG3;
1001 PRE_FIELD_READ("ioctl(BIOCSETF).bf_len", fp->bf_len);
1002 PRE_FIELD_READ("ioctl(BIOCSETF).bf_insns", fp->bf_insns);
1003 PRE_MEM_READ("ioctl(BIOCSETF).bf_insns",
1004 (Addr)(fp->bf_insns), fp->bf_len*sizeof(struct vki_bpf_insn));
1006 break;
1007 case VKI_CAMIOCOMMAND:
1008 // #define CAMIOCOMMAND _IOWR(CAM_VERSION, 2, union ccb)
1009 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(union vki_ccb))) {
1010 // test with "camcontrol devlist" (as root)
1011 // (many errors at present)
1012 union vki_ccb* ccb = (union vki_ccb*)ARG3;
1013 if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) {
1014 PRE_FIELD_READ("ioctl(CAMIOCOMMAND).cdm.match_buf_len", ccb->cdm.match_buf_len);
1015 PRE_FIELD_READ("ioctl(CAMIOCOMMAND).cdm.matches", ccb->cdm.matches);
1016 PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_DEV_MATCH).num_matches",
1017 (Addr)(&ccb->cdm.num_matches), sizeof(ccb->cdm.num_matches));
1018 PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_DEV_MATCH).matches",
1019 (Addr)(ccb->cdm.matches), ccb->cdm.match_buf_len);
1020 } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) {
1021 struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb;
1022 if (scsiio->dxfer_len) {
1023 if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) {
1024 PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr",
1025 (Addr)(scsiio->data_ptr), scsiio->dxfer_len);
1026 } else if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_OUT) {
1027 PRE_MEM_READ("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr",
1028 (Addr)(scsiio->data_ptr), scsiio->dxfer_len);
1031 } else if (ccb->ccb_h.func_code == VKI_XPT_GDEV_TYPE ||
1032 ccb->ccb_h.func_code == VKI_XPT_PATH_INQ ||
1033 ccb->ccb_h.func_code == VKI_XPT_GET_TRAN_SETTINGS) {
1034 // do nothing
1035 } else {
1036 VG_(message)(Vg_UserMsg,
1037 "Warning: unhandled ioctl CAMIOCOMMAND function 0x%x\n",
1038 ccb->ccb_h.func_code);
1041 break;
1042 case VKI_FIODGNAME:
1043 // #define FIODGNAME _IOW('f', 120, struct fiodgname_arg) /* get dev. name */
1044 // has a regression test
1045 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_fiodgname_arg))) {
1046 struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3;
1047 PRE_FIELD_READ("ioctl(FIODGNAME).len", data->len);
1048 PRE_FIELD_READ("ioctl(FIODGNAME).buf", data->buf);
1049 PRE_MEM_WRITE("ioctl(FIODGNAME).buf", (Addr)data->buf, data->len);
1051 break;
1052 case VKI_SIOCGIFCONF:
1053 // #define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */
1054 // test with "traceroute www.siemens.com" (as root)
1055 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifconf))) {
1056 struct vki_ifconf* ifc = (struct vki_ifconf*)ARG3;
1057 PRE_FIELD_READ("ioctl(SIOCGIFCONF).ifc_len", ifc->ifc_len);
1058 PRE_FIELD_READ("ioctl(SIOCGIFCONF).ifcu_req", ifc->ifc_ifcu.ifcu_req);
1059 PRE_MEM_WRITE("ioctl(SIOCGIFCONF).buf", (Addr)ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);
1061 break;
1062 case VKI_SIOCGIFMEDIA:
1063 // #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
1064 // test with "ifconfig -m"
1065 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifmediareq))) {
1066 struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3;
1067 if (imr->ifm_ulist) {
1068 PRE_MEM_WRITE("ioctl(SIOCGIFMEDIA).ifm_ulist",
1069 (Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int));
1072 break;
1073 case VKI_SIOCGIFSTATUS:
1074 // #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */
1075 // test with "ifconfig -a"
1076 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifstat))) {
1077 struct vki_ifstat* data = (struct vki_ifstat*)(Addr)ARG3;
1078 PRE_MEM_RASCIIZ("ioctl(SIOCGIFSTATUS).ifs_name", (Addr)data->ifs_name);
1079 PRE_MEM_WRITE("ioctl(SIOCGIFSTATUS).ascii", (Addr)data->ascii, sizeof(data->ascii));
1081 break;
1082 case VKI_PCIOCGETCONF:
1083 // #define PCIOCGETCONF _IOWR('p', 5, struct pci_conf_io)
1084 // test with "pciconf -l"
1085 if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_pci_conf_io))) {
1086 struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3;
1087 PRE_MEM_READ("ioctl(PCIOCGETCONF).patterns",
1088 (Addr)(pci->patterns), pci->pat_buf_len);
1089 PRE_MEM_WRITE("ioctl(PCIOCGETCONF).matches",
1090 (Addr)(pci->matches), pci->match_buf_len);
1092 break;
1093 default:
1094 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
1095 break;
1099 POST(sys_ioctl)
1101 switch (ARG2/* request */) {
1102 /* Handle specific ioctls which pass structures which may have pointers to other
1103 buffers */
1104 case VKI_CAMIOCOMMAND:
1105 if (ARG3) {
1106 union vki_ccb* ccb = (union vki_ccb*)ARG3;
1107 if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) {
1108 POST_MEM_WRITE((Addr)(&ccb->cdm.num_matches), sizeof(ccb->cdm.num_matches));
1109 POST_MEM_WRITE((Addr)(ccb->cdm.matches), ccb->cdm.num_matches*sizeof(struct vki_dev_match_result));
1110 } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) {
1111 struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb;
1112 if (scsiio->dxfer_len) {
1113 if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) {
1114 POST_MEM_WRITE((Addr)(scsiio->data_ptr), scsiio->dxfer_len);
1119 break;
1120 case VKI_FIODGNAME:
1121 if (ARG3) {
1122 struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3;
1123 POST_MEM_WRITE((Addr)data->buf, data->len);
1125 break;
1126 case VKI_SIOCGIFCONF:
1127 // #define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */
1128 if (ARG3) {
1129 struct vki_ifconf* ifc = (struct vki_ifconf*)ARG3;
1130 POST_MEM_WRITE((Addr)ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);
1132 break;
1133 case VKI_SIOCGIFMEDIA:
1134 if (ARG3) {
1135 struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3;
1136 if (imr->ifm_ulist) {
1137 POST_MEM_WRITE((Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int));
1140 break;
1141 case VKI_SIOCGIFSTATUS:
1142 // #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */
1143 if (ARG3) {
1144 struct vki_ifstat* data = (struct vki_ifstat*)(Addr)ARG3;
1145 POST_MEM_WRITE((Addr)data->ascii, sizeof(data->ascii));
1147 break;
1148 case VKI_PCIOCGETCONF:
1149 if (ARG3) {
1150 struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3;
1151 POST_MEM_WRITE((Addr)(pci->matches), pci->num_matches * sizeof(struct vki_pci_conf));
1153 break;
1156 default:
1157 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
1158 break;
1162 // SYS_reboot 55
1163 // int reboot(int howto);
1164 PRE(sys_reboot)
1166 PRINT("sys_reboot ( %" FMT_REGWORD "d )", SARG1);
1167 PRE_REG_READ1(int, "reboot", int, howto);
1170 // SYS_revoke 56
1171 // int revoke(const char *path);
1172 PRE(sys_revoke)
1174 PRINT("sys_revoke ( %#" FMT_REGWORD "x(%s) )", ARG1, (char*)ARG1);
1175 PRE_REG_READ1(long, "revoke", const char *, path);
1176 PRE_MEM_RASCIIZ( "revoke(path)", ARG1);
1179 // SYS_symlink 57
1180 // generic
1182 static void do_readlink(const HChar* path, HChar *buf, SizeT bufsize, SyscallStatus* status, Bool* curproc_file)
1184 HChar name[30];
1185 VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)());
1186 if (ML_(safe_to_deref)(path, 1)
1187 && (VG_(strcmp)(path, name) == 0
1188 || VG_(strcmp)(path, "/proc/curproc/file") == 0)) {
1189 vg_assert(VG_(resolved_exename));
1190 Int len = VG_(snprintf)(buf, bufsize, "%s", VG_(resolved_exename));
1191 SET_STATUS_Success(len);
1192 *curproc_file = True;
1196 // SYS_readlink 58
1197 // ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsiz);
1198 PRE(sys_readlink)
1200 FUSE_COMPATIBLE_MAY_BLOCK();
1201 Word saved = SYSNO;
1202 Bool curproc_file = False;
1204 PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )",
1205 ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3);
1206 PRE_REG_READ3(long, "readlink",
1207 const char *, path, char *, buf, int, bufsiz);
1208 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
1209 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
1211 if (VG_(have_slash_proc) == True)
1214 * Handle the case where readlink is looking at /proc/curproc/file or
1215 * /proc/<pid>/file
1217 do_readlink((const HChar *)ARG1, (HChar *)ARG2, (SizeT)ARG3, status, &curproc_file);
1220 if (!curproc_file) {
1221 /* Normal case */
1222 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
1224 if (SUCCESS && RES > 0) {
1225 POST_MEM_WRITE( ARG2, RES );
1229 // SYS_execve 59
1230 // generic
1232 // SYS_umask 60
1233 // generic
1235 // SYS_chroot 61
1236 // generic
1238 // SYS_msync 65
1239 // generic
1241 // SYS_vfork 66
1242 // pid_t vfork(void);
1243 PRE(sys_vfork)
1245 PRINT("%s", "sys_vfork ()");
1246 PRE_REG_READ0(pid_t, "vfork");
1248 /* Pretend vfork == fork. Not true, but will have to do. */
1249 SET_STATUS_from_SysRes( ML_(do_fork)(tid) );
1250 if (SUCCESS) {
1251 /* Thread creation was successful; let the child have the chance
1252 to run */
1253 *flags |= SfYieldAfter;
1257 // SYS_sbrk 69
1258 // int sbrk(int incr);
1259 PRE(sys_sbrk)
1261 PRINT("sys_sbrk ( %#" FMT_REGWORD "x )",ARG1);
1262 PRE_REG_READ1(int, "sbrk", int, incr);
1264 // removed in FreeBSD 15
1265 // prior to that it just returned EOPNOTSUPP
1266 // with a comment "Not yet implemented"
1268 // libc sbrk doesn't call this, it calls __sys_break
1269 // which maps to sys_brk
1272 // SYS_freebsd11_vadvise 72
1273 // @todo maybe
1275 // SYS_munmap 73
1276 // generic
1278 // SYS_mprotect 74
1279 // generic
1281 // SYS_madvise 75
1282 // generic
1284 // SYS_mincore 78
1285 // generic
1287 // SYS_getgroups 79
1288 // generic
1290 // SYS_setgroups 80
1291 // generic
1293 // SYS_getpgrp 81
1294 // generic
1296 // SYS_setpgid 82
1297 // generic
1299 // SYS_setitimer 83
1300 // generic
1302 // SYS_swapon 85
1303 // int swapon(const char *special);
1304 PRE(sys_swapon)
1306 PRINT("sys_swapon ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)ARG1);
1307 PRE_REG_READ1(int, "swapon", const char*, special );
1308 PRE_MEM_RASCIIZ( "swapon(special)", ARG1 );
1311 // SYS_getitimer 86
1312 // generic
1314 // SYS_getdtablesize 89
1315 // int getdtablesize(void);
1316 PRE(sys_getdtablesize)
1318 PRINT("%s", "sys_getdtablesize ( )");
1319 PRE_REG_READ0(long, "getdtablesize");
1322 // SYS_dup2 90
1323 // generic
1325 // SYS_fcntl 92
1326 // int fcntl(int fd, int cmd, ...);
1327 PRE(sys_fcntl)
1329 switch (ARG2) {
1330 // These ones ignore ARG3.
1331 case VKI_F_GETFD:
1332 case VKI_F_GETFL:
1333 case VKI_F_GETOWN:
1334 case VKI_F_GET_SEALS:
1335 case VKI_F_ISUNIONSTACK:
1336 PRINT("sys_fcntl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2);
1337 PRE_REG_READ2(int, "fcntl", int, fd, int, cmd);
1338 break;
1340 // These ones use ARG3 as "arg".
1341 case VKI_F_DUPFD:
1342 case VKI_F_DUPFD_CLOEXEC:
1343 case VKI_F_SETFD:
1344 case VKI_F_SETFL:
1345 case VKI_F_SETOWN:
1346 case VKI_F_READAHEAD:
1347 case VKI_F_RDAHEAD:
1348 case VKI_F_ADD_SEALS:
1349 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2,SARG3);
1350 PRE_REG_READ3(int, "fcntl",
1351 int, fd, int, cmd, int, arg);
1352 break;
1354 // These ones use ARG3 as "lock" - obsolete.
1355 case VKI_F_OSETLKW:
1356 *flags |= SfMayBlock;
1357 /* FALLTHROUGH */
1358 case VKI_F_OGETLK:
1359 case VKI_F_OSETLK:
1360 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1361 PRE_REG_READ3(int, "fcntl",
1362 int, fd, int, cmd,
1363 struct oflock *, lock);
1364 break;
1366 // This one uses ARG3 as "oldd" and ARG4 as "newd".
1367 case VKI_F_DUP2FD:
1368 case VKI_F_DUP2FD_CLOEXEC:
1369 PRINT("sys_fcntl[ARG3=='oldd', ARG4=='newd'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
1370 ARG1,ARG2,ARG3,ARG4);
1371 PRE_REG_READ4(int, "fcntl",
1372 int, fd, int, cmd,
1373 unsigned long, oldd, unsigned long, newd);
1374 break;
1376 // These ones use ARG3 as "lock".
1377 case VKI_F_SETLKW:
1378 *flags |= SfMayBlock;
1379 /* FALLTHROUGH */
1380 case VKI_F_GETLK:
1381 case VKI_F_SETLK:
1382 case VKI_F_SETLK_REMOTE:
1383 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1384 PRE_REG_READ3(int, "fcntl",
1385 int, fd, int, cmd,
1386 struct flock *, lock);
1387 break;
1388 case VKI_F_KINFO:
1389 PRINT("sys_fcntl[ARG3=='kinfo_file'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1390 PRE_REG_READ3(int, "fcntl",
1391 int, fd, int, cmd,
1392 struct vki_kinfo_file *, kinfo);
1393 if (ARG3) {
1394 struct vki_kinfo_file* p_kinfo_file = (struct vki_kinfo_file*)ARG3;
1395 PRE_MEM_WRITE("fcntl(ARG3=='kinfo_file)", ARG3, p_kinfo_file->vki_kf_structsize);
1397 break;
1399 default:
1400 PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1,ARG2,ARG3);
1401 I_die_here;
1405 POST(sys_fcntl)
1407 vg_assert(SUCCESS);
1408 if (ARG2 == VKI_F_DUPFD) {
1409 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
1410 VG_(close)(RES);
1411 SET_STATUS_Failure( VKI_EMFILE );
1412 } else {
1413 if (VG_(clo_track_fds)) {
1414 ML_(record_fd_open_named)(tid, RES);
1417 } else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
1418 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
1419 VG_(close)(RES);
1420 SET_STATUS_Failure( VKI_EMFILE );
1421 } else {
1422 if (VG_(clo_track_fds)) {
1423 ML_(record_fd_open_named)(tid, RES);
1429 // SYS_select 93
1430 // generic
1432 // SYS_fsync 95
1433 // generic
1435 // SYS_setpriority 9
1436 // generic
1438 // SYS_socket 97
1439 // int socket(int domain, int type, int protocol);
1440 PRE(sys_socket)
1442 PRINT("sys_socket ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2,SARG3);
1443 PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol);
1446 POST(sys_socket)
1448 SysRes r;
1449 vg_assert(SUCCESS);
1450 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
1451 SET_STATUS_from_SysRes(r);
1454 // SYS_connect 98
1455 // int connect(int s, const struct sockaddr *name, socklen_t namelen);
1456 PRE(sys_connect)
1458 *flags |= SfMayBlock;
1459 PRINT("sys_connect ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
1460 PRE_REG_READ3(int, "connect",
1461 int, s, const struct sockaddr *, name, int, namelen);
1462 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
1465 // SYS_getpriority 100
1466 // generic
1468 // SYS_bind 104
1469 // int bind(int s, const struct sockaddr *addr, socklen_t addrlen);
1470 PRE(sys_bind)
1472 PRINT("sys_bind ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
1473 PRE_REG_READ3(int, "bind",
1474 int, s, struct sockaddr *, addr, int, addrlen);
1475 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
1478 // SYS_setsockopt 105
1479 // int setsockopt(int s, int level, int optname, const void *optval,
1480 // socklen_t optlen);
1481 PRE(sys_setsockopt)
1483 PRINT("sys_setsockopt ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",SARG1,SARG2,SARG3,ARG4,ARG5);
1484 PRE_REG_READ5(int, "setsockopt",
1485 int, s, int, level, int, optname,
1486 const void *, optval, vki_socklen_t, optlen);
1487 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
1490 // SYS_listen 106
1491 // int listen(int s, int backlog);
1492 PRE(sys_listen)
1494 PRINT("sys_listen ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2);
1495 PRE_REG_READ2(int, "listen", int, s, int, backlog);
1498 //SYS_gettimeofday 116
1499 // generic
1501 // SYS_getrusage 117
1502 // generic
1504 // SYS_getsockopt 118
1505 // int getsockopt(int s, int level, int optname, void * restrict optval,
1506 // socklen_t * restrict optlen);
1507 PRE(sys_getsockopt)
1509 Addr optval_p = ARG4;
1510 Addr optlen_p = ARG5;
1511 PRINT("sys_getsockopt ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4,ARG5);
1512 PRE_REG_READ5(int, "getsockopt",
1513 int, s, int, level, int, optname,
1514 void *, optval, int, *optlen);
1515 if (optval_p != (Addr)NULL) {
1516 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
1517 "getsockopt(optval)",
1518 "getsockopt(optlen)" );
1522 POST(sys_getsockopt)
1524 Addr optval_p = ARG4;
1525 Addr optlen_p = ARG5;
1526 vg_assert(SUCCESS);
1527 if (optval_p != (Addr)NULL) {
1528 ML_(buf_and_len_post_check) ( tid, VG_(mk_SysRes_Success)(RES),
1529 optval_p, optlen_p,
1530 "getsockopt(optlen_out)" );
1534 // SYS_readv 120
1535 // generic
1537 // SYS_writev 121
1538 // generic
1540 // SYS_settimeofday 122
1541 // generic
1543 // SYS_fchown 123
1544 // generic
1546 // SYS_fchmod 124
1547 // generic
1549 // SYS_setreuid 126
1550 // generic
1552 // SYS_setregid 127
1553 // generic
1555 // SYS_rename 128
1556 // generic
1558 // SYS_flock 131
1559 // generic
1561 // SYS_mkfifo 132
1562 // int mkfifo(const char *path, mode_t mode);
1563 PRE(sys_mkfifo)
1565 PRINT("sys_mkfifo ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, (char *)ARG1, ARG2, ARG3 );
1566 PRE_REG_READ2(int, "mkfifo", const char *, path, int, mode);
1567 PRE_MEM_RASCIIZ( "mkfifo(path)", ARG1 );
1570 // SYS_sendto 133
1571 // ssize_t sendto(int s, const void *msg, size_t len, int flags,
1572 // const struct sockaddr *to, socklen_t tolen);
1573 PRE(sys_sendto)
1575 *flags |= SfMayBlock;
1576 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);
1577 PRE_REG_READ6(ssize_t, "sendto",
1578 int, s, const void *, msg, int, len,
1579 int, flags,
1580 const struct sockaddr *, to, socklen_t, tolen);
1581 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1584 // SYS_shutdown 134
1585 // int shutdown(int s, int how);
1586 PRE(sys_shutdown)
1588 *flags |= SfMayBlock;
1589 PRINT("sys_shutdown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2);
1590 PRE_REG_READ2(int, "shutdown", int, s, int, how);
1593 // SYS_socketpair 135
1594 // int socketpair(int domain, int type, int protocol, int *sv);
1595 PRE(sys_socketpair)
1597 PRINT("sys_socketpair ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
1598 PRE_REG_READ4(int, "socketpair",
1599 int, domain, int, type, int, protocol, int *, sv);
1600 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
1603 POST(sys_socketpair)
1605 vg_assert(SUCCESS);
1606 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
1607 ARG1,ARG2,ARG3,ARG4);
1610 // SYS_mkdir 136
1611 // generic
1613 // SYS_rmdir 137
1614 // generic
1616 // SYS_utimes 138
1617 // generic
1619 // SYS_adjtime 140
1620 // int adjtime(const struct timeval *delta, struct timeval *olddelta);
1621 PRE(sys_adjtime)
1623 PRINT("sys_adjtime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
1624 PRE_REG_READ2(int, "adjtime",
1625 const struct vki_timeval *, delta, struct vki_timeval *, olddelta);
1626 PRE_MEM_READ("adjtime(delta)", ARG1, sizeof(struct vki_timeval));
1627 if (ARG2) {
1628 PRE_MEM_WRITE("adjtime(olddelta)", ARG1, sizeof(struct vki_timeval));
1632 POST(sys_adjtime)
1634 if (ARG2) {
1635 POST_MEM_WRITE(ARG1, sizeof(struct vki_timeval));
1639 // SYS_setsid 147
1640 // generic
1642 // SYS_quotactl 148
1643 /* int quotactl(const char *path, int cmd, int id, void *addr); */
1644 PRE(sys_quotactl)
1646 PRINT("sys_quotactl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3, ARG4);
1647 switch (ARG2) {
1648 case VKI_Q_QUOTAON:
1649 case VKI_Q_SETQUOTA:
1650 case VKI_Q_SETUSE:
1652 case VKI_Q_GETQUOTASIZE:
1653 PRE_REG_READ4(int, "quotactl",
1654 const char *, path, int, cmd, int, id,
1655 void *, addr);
1656 PRE_MEM_RASCIIZ( "quotactl(path)", ARG1 );
1657 break;
1658 case VKI_Q_GETQUOTA:
1659 if (VG_(tdict).track_pre_reg_read) {
1661 PRRSN;
1662 PRA1("quotactl",const char*,path);
1663 PRA2("quotactl",int,cmd);
1664 PRA4("quotactl",void*,addr);
1666 break;
1667 case VKI_Q_QUOTAOFF:
1668 case VKI_Q_SYNC:
1669 PRE_REG_READ2(int, "quotactl",
1670 const char *, path, int, cmd);
1671 break;
1672 default:
1673 break;
1677 // SYS_nlm_syscall 154
1678 // syscall.master says ; 154 is initialised by the NLM code, if present.
1679 // @todo
1681 // SYS_nfssvc 155
1682 // int nfssvc(int flags, void *argstructp);
1683 // lengthy manpage, at least 3 types of struct that argstructp can point to
1684 // @todo
1686 // SYS_lgetfh 160
1687 // int lgetfh(const char *path, fhandle_t *fhp);
1688 PRE(sys_lgetfh)
1690 PRINT("sys_lgetfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2);
1691 PRE_REG_READ2(int, "lgetfh", const char*, path, vki_fhandle_t*, fhp);
1692 PRE_MEM_RASCIIZ( "lgetfh(path)", ARG1 );
1693 PRE_MEM_WRITE("lgetfh(fhp)", ARG2, sizeof(vki_fhandle_t));
1696 POST(sys_lgetfh)
1698 POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t));
1701 // SYS_getfh 161
1702 // int getfh(const char *path, fhandle_t *fhp);
1703 PRE(sys_getfh)
1705 PRINT("sys_getfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2);
1706 PRE_REG_READ2(int, "getfh", const char*, path, vki_fhandle_t*, fhp);
1707 PRE_MEM_RASCIIZ( "getfh(path)", ARG1 );
1708 PRE_MEM_WRITE("getfh(fhp)", ARG2, sizeof(vki_fhandle_t));
1711 POST(sys_getfh)
1713 POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t));
1716 #if (FREEBSD_VERS <= FREEBSD_10)
1717 // 162
1718 // int getdomainname(char *domainname, int len);
1719 PRE(sys_freebsd4_getdomainname)
1721 PRINT("sys_freebsd4_getdomainname ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2);
1722 PRE_REG_READ2(int, "getdomainname",
1723 char *, domainname, int, len);
1724 PRE_MEM_WRITE( "getdomainname(domainname)", ARG1, ARG2 );
1727 POST(sys_freebsd4_getdomainname)
1729 if (ARG1 != 0) {
1730 POST_MEM_WRITE( ARG1, ARG2 );
1734 // 163
1735 // int setdomainname(char *domainname, int len);
1736 PRE(sys_freebsd4_setdomainname)
1738 PRINT("sys_freebsd4_setdomainname ( %#" FMT_REGWORD "x )",ARG1);
1739 PRE_REG_READ2(int, "setdomainname", char *, domainname, int, len);
1740 PRE_MEM_RASCIIZ( "setdomainname(domainname)", ARG1 );
1743 // 164
1744 // int uname(struct utsname *name);
1745 PRE(sys_freebsd4_uname)
1747 PRINT("sys_freebsd4_uname ( %#" FMT_REGWORD "x )", ARG1);
1748 PRE_REG_READ1(int, "uname", struct utsname *, name);
1749 PRE_MEM_WRITE( "uname(name)", ARG1, sizeof(struct vki_utsname) );
1752 POST(sys_freebsd4_uname)
1754 if (ARG1 != 0) {
1755 POST_MEM_WRITE( ARG1, sizeof(struct vki_utsname) );
1758 #endif
1760 // SYS_sysarch 165
1761 // x86/amd64
1763 // SYS_rtprio 166
1764 PRE(sys_rtprio)
1766 PRINT( "sys_rtprio ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3 );
1767 PRE_REG_READ3(int, "rtprio",
1768 int, function, pid_t, pid, struct rtprio *, rtp);
1769 if (ARG1 == VKI_RTP_SET) {
1770 PRE_MEM_READ( "rtprio(rtp#set)", ARG3, sizeof(struct vki_rtprio));
1771 } else if (ARG1 == VKI_RTP_LOOKUP) {
1772 PRE_MEM_WRITE( "rtprio(rtp#lookup)", ARG3, sizeof(struct vki_rtprio));
1773 } else {
1774 /* PHK ?? */
1778 POST(sys_rtprio)
1780 if (ARG1 == VKI_RTP_LOOKUP && RES == 0) {
1781 POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio));
1785 // freebsd6_pread 173 FREEBSD_VERS <= 10
1786 // x86/amd64
1788 // freebsd6_pwrite 174 FREEBSD_VERS <= 10
1789 // x86/amd64
1791 // SYS_setfib 175
1792 // int setfib(int fib);
1793 PRE(sys_setfib)
1795 PRINT("sys_setfib ( %" FMT_REGWORD "d )", SARG1);
1796 PRE_REG_READ1(int, "setfib", int, fib);
1799 // SYS_ntp_adjtime 176
1800 // int ntp_adjtime(struct timex *);
1801 // @todo
1803 // SYS_setgid 181
1804 // generic
1806 // SYS_setegid 182
1807 // int setegid(gid_t egid);
1808 PRE(sys_setegid)
1810 PRINT("sys_setegid ( %" FMT_REGWORD "u )", ARG1);
1811 PRE_REG_READ1(int, "setegid", vki_gid_t, gid);
1814 // SYS_seteuid 183
1815 // int seteuid(uid_t euid);
1816 PRE(sys_seteuid)
1818 PRINT("sys_seteuid ( %" FMT_REGWORD "u )", ARG1);
1819 PRE_REG_READ1(long, "seteuid", vki_uid_t, uid);
1823 #if (FREEBSD_VERS >= FREEBSD_12)
1825 // SYS_freebsd11_stat 188
1826 // int stat(char *path, struct freebsd11_stat *sb);
1827 PRE(sys_freebsd11_stat)
1829 PRINT("sys_freebsd11_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
1830 PRE_REG_READ2(int, "stat", char *, path, struct freebsd11_stat *, sb);
1831 PRE_MEM_RASCIIZ( "stat(path)", ARG1 );
1832 PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
1835 POST(sys_freebsd11_stat)
1837 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1840 // SYS_freebsd11_fstat 189
1841 // int fstat(int fd, struct stat *sb);
1842 PRE(sys_freebsd11_fstat)
1844 PRINT("sys_freebsd11_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2);
1845 PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb);
1846 PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
1849 POST(sys_freebsd11_fstat)
1851 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1854 // SYS_freebsd11_lstat 190
1855 // int lstat(const char * restrict path, struct stat * restrict sb);
1856 PRE(sys_freebsd11_lstat)
1858 PRINT("sys_freebsd11_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
1859 PRE_REG_READ2(sb, "lstat", const char *, path, struct freebsd11_stat *, sb);
1860 PRE_MEM_RASCIIZ( "lstat(path)", ARG1 );
1861 PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
1864 POST(sys_freebsd11_lstat)
1866 vg_assert(SUCCESS);
1867 if (RES == 0) {
1868 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1872 #else
1874 PRE(sys_stat)
1876 PRINT("sys_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
1877 PRE_REG_READ2(int, "stat", char *, path, struct stat *, sb);
1878 PRE_MEM_RASCIIZ( "stat(path)", ARG1 );
1879 PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
1882 POST(sys_stat)
1884 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1888 PRE(sys_fstat)
1890 PRINT("sys_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2);
1891 PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb);
1892 PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
1895 POST(sys_fstat)
1897 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1900 PRE(sys_lstat)
1902 PRINT("sys_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
1903 PRE_REG_READ2(int, "lstat", const char *, path, struct stat *, sb);
1904 PRE_MEM_RASCIIZ( "lstat(path)", ARG1 );
1905 PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
1908 POST(sys_lstat)
1910 vg_assert(SUCCESS);
1911 if (RES == 0) {
1912 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
1916 #endif
1918 // SYS_pathconf 191
1919 // long pathconf(const char *path, int name);
1920 PRE(sys_pathconf)
1922 PRINT("sys_pathconf ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,(char *)ARG1,ARG2);
1923 PRE_REG_READ2(long, "pathconf", char *, path, int, name);
1924 PRE_MEM_RASCIIZ( "pathconf(path)", ARG1 );
1927 // SYS_fpathconf 192
1928 // long fpathconf(int fd, int name);
1929 PRE(sys_fpathconf)
1931 PRINT("sys_fpathconf ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2);
1932 PRE_REG_READ2(long, "fpathconf", int, fd, int, name);
1935 // SYS_getrlimit 194
1936 // generic
1938 // SYS_setrlimit 195
1939 // generic
1942 // SYS_freebsd11_getdirentries 196
1943 // int getdirentries(int fd, char *buf, int nbytes, long *basep);
1944 #if (FREEBSD_VERS >= FREEBSD_12)
1945 PRE(sys_freebsd11_getdirentries)
1947 *flags |= SfMayBlock;
1948 PRINT("sys_freebsd11_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3);
1949 PRE_REG_READ4(int, "getdirentries",
1950 int, fd, char *, buf,
1951 int, nbytes,
1952 long *, basep);
1953 PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 );
1954 if (ARG4) {
1955 PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) );
1959 POST(sys_freebsd11_getdirentries)
1961 vg_assert(SUCCESS);
1962 if (RES > 0) {
1963 POST_MEM_WRITE( ARG2, RES );
1964 if ( ARG4 != 0 ) {
1965 POST_MEM_WRITE( ARG4, sizeof (long));
1969 #else
1970 PRE(sys_getdirentries)
1972 *flags |= SfMayBlock;
1973 PRINT("sys_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3);
1974 PRE_REG_READ4(int, "getdirentries",
1975 int, fd, char *, buf,
1976 int, nbytes,
1977 long *, basep);
1978 PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 );
1979 if (ARG4)
1980 PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) );
1983 POST(sys_getdirentries)
1985 vg_assert(SUCCESS);
1986 if (RES > 0) {
1987 POST_MEM_WRITE( ARG2, RES );
1988 if ( ARG4 != 0 )
1989 POST_MEM_WRITE( ARG4, sizeof (long));
1992 #endif
1994 // SYS_freebsd6_mmap 197
1995 // amd64 / x86
1998 // SYS___syscall 198
1999 // special handling
2001 // freebsd6_lseek 199 FREEBSD_VERS <= 10
2002 // x86/amd64
2004 // freebsd6_truncate 200 FREEBSD_VERS <= 10
2005 // x86/amd64
2007 // freebsd6_ftruncate 201 FREEBSD_VERS <= 10
2008 // x86/amd64
2010 static Bool sysctl_kern_ps_strings(SizeT* out, SizeT* outlen)
2012 Word tmp = -1;
2013 const struct auxv *cauxv;
2015 for (cauxv = (struct auxv*)VG_(client_auxv); cauxv->a_type != VKI_AT_NULL; cauxv++) {
2016 if (cauxv->a_type == VKI_AT_PS_STRINGS) {
2017 tmp = (Word)cauxv->u.a_ptr;
2019 *out = tmp;
2020 *outlen = sizeof(size_t);
2021 return True;
2024 return False;
2027 static void sysctl_kern_usrstack(SizeT* out, SizeT* outlen)
2029 *out = VG_(get_usrstack)();
2030 *outlen = sizeof(ULong);
2033 static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len)
2035 const HChar *exe_name = VG_(resolved_exename);
2037 if (!len) {
2038 return False;
2041 if (!out) {
2042 HChar tmp[VKI_PATH_MAX];
2043 if (!VG_(realpath)(exe_name, tmp)) {
2044 return False;
2046 *len = VG_(strlen)(tmp)+1;
2047 return True;
2050 if (!VG_(realpath)(exe_name, out)) {
2051 return False;
2054 *len = VG_(strlen)(out)+1;
2055 return True;
2058 // SYS___sysctl 202
2059 /* int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); */
2060 /* ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 */
2061 PRE(sys___sysctl)
2063 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 );
2065 int* name = (int*)ARG1;
2066 if (ML_(safe_to_deref)(name, sizeof(int))) {
2067 PRINT("\nmib[0]: ");
2068 if (SARG2 >= 1) {
2069 switch (name[0]) {
2070 case 0: // CTL_UNSPEC
2071 PRINT("unspec");
2072 break;
2073 case 1: // CTL_KERN
2074 PRINT("kern");
2075 break;
2076 case 2: // CTL_VM
2077 PRINT("vm");
2078 break;
2079 case 3: // CTL_VFS
2080 PRINT("vfs");
2081 break;
2082 case 4: // CTL_NET
2083 PRINT("net");
2084 break;
2085 case 5: // CTL_DEBUG
2086 PRINT("debug");
2087 break;
2088 case 6: // CTL_HW
2089 PRINT("hw");
2090 break;
2091 case 7: // CTL_MACHDEP
2092 PRINT("machdep");
2093 break;
2094 case 8: // CTL _USER
2095 PRINT("user");
2096 break;
2097 case 9: //CTL_P1003_1B
2098 PRINT("p1003_b1b");
2099 break;
2100 default:
2101 PRINT("unrecognized (%d)", ((int*)ARG1)[0]);
2102 break;
2105 if (SARG2 >= 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) {
2106 PRINT(" mib[1]: %d\n", name[1]);
2111 * Special handling cases
2113 * 1. kern.usrstack
2114 * This sysctl returns the address of the bottom of the user stack
2115 * (that is the highest user stack address, since the stack grows
2116 * downwards). Without any special handling this would return the
2117 * address of the host userstack. We have created a stack for the
2118 * guest (in aspacemgr) and that is the one that we want the guest
2119 * to see. Aspacemgr is setup in m_main.c with the adresses and sizes
2120 * saved to file static variables in that file, so we call
2121 * VG_(get_usrstack)() to retrieve them from there.
2123 if (SARG2 == 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) {
2124 if (name[0] == 1 && name[1] == 33) {
2125 // kern.usrstack
2126 sysctl_kern_usrstack((SizeT*)ARG3, (SizeT*)ARG4);
2127 SET_STATUS_Success(0);
2132 * 2. kern.ps_strings
2134 if (SARG2 == 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) {
2135 if (name[0] == 1 && name[1] == 32) {
2136 if (sysctl_kern_ps_strings((SizeT*)ARG3, (SizeT*)ARG4)) {
2137 SET_STATUS_Success(0);
2143 * 3. kern.proc.pathname
2145 if (SARG2 == 4 && ML_(safe_to_deref)(name, 4*sizeof(int))) {
2146 if (name[0] == 1 && name[1] == 14 && name[2] == 12) {
2147 vki_pid_t pid = (vki_pid_t)name[3];
2148 if (pid == -1 || pid == VG_(getpid)()) {
2149 sysctl_kern_proc_pathname((HChar *)ARG3, (SizeT *)ARG4);
2150 SET_STATUS_Success(0);
2155 PRE_REG_READ6(int, "__sysctl", int *, name, vki_u_int32_t, namelen, void *, oldp,
2156 vki_size_t *, oldlenp, void *, newp, vki_size_t, newlen);
2158 // read number of ints specified in ARG2 from mem pointed to by ARG1
2159 PRE_MEM_READ("sysctl(name)", (Addr)ARG1, ARG2 * sizeof(int));
2161 // if 'newp' is not NULL can read namelen bytes from that address
2162 if (ARG5 != (UWord)NULL) {
2163 PRE_MEM_READ("sysctl(newp)", (Addr)ARG5, ARG6);
2166 // there are two scenarios for oldlenp/oldp
2167 // 1. oldval is NULL and oldlenp is non-NULL
2168 // this is a query of oldlenp so oldlenp will be written
2169 // 2. Both are non-NULL
2170 // this is a query of oldp, oldlenp will be read and oldp will
2171 // be written
2173 // More thoughts on this
2174 // if say oldp is a string buffer
2175 // oldlenp will point to the length of the buffer
2177 // but on return does oldlenp also get updated?
2179 // is oldlenp is not NULL, can write
2180 if (ARG4 != (UWord)NULL) {
2181 if (ARG3 != (UWord)NULL) {
2182 // case 2 above
2183 PRE_MEM_READ("sysctl(oldlenp)", (Addr)ARG4, sizeof(vki_size_t));
2184 PRE_MEM_WRITE("sysctl(oldlenp)", (Addr)ARG4, sizeof(vki_size_t));
2185 if (ML_(safe_to_deref)((void*)(Addr)ARG4, sizeof(vki_size_t))) {
2186 PRE_MEM_WRITE("sysctl(oldp)", (Addr)ARG3, *(vki_size_t *)ARG4);
2187 } else {
2188 VG_(dmsg)("Warning: Bad oldlenp address %p in sysctl\n",
2189 (void *)(Addr)ARG4);
2190 SET_STATUS_Failure ( VKI_EFAULT );
2192 } else {
2193 // case 1 above
2194 PRE_MEM_WRITE("sysctl(oldlenp)", (Addr)ARG4, sizeof(vki_size_t));
2199 POST(sys___sysctl)
2201 if (ARG4 != (UWord)NULL) {
2202 if (ARG3 != (UWord)NULL) {
2203 POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t));
2204 POST_MEM_WRITE((Addr)ARG3, *(vki_size_t *)ARG4);
2205 } else {
2206 POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t));
2211 // SYS_mlock 203
2212 // generic
2214 // SYS_munlock 204
2215 // generic
2217 // SYS_undelete 205
2218 // int undelete(const char *path);
2219 PRE(sys_undelete)
2221 *flags |= SfMayBlock;
2222 PRINT("sys_undelete ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1);
2223 PRE_REG_READ1(int, "undelete", const char *, path);
2224 PRE_MEM_RASCIIZ( "undelete(path)", ARG1 );
2227 // SYS_futimes 206
2228 // int futimes(int fd, const struct timeval *times);
2229 PRE(sys_futimes)
2231 PRINT("sys_lutimes ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2232 PRE_REG_READ2(long, "futimes", int, fd, struct timeval *, times);
2233 if (ARG2 != 0) {
2234 PRE_MEM_READ( "futimes(times)", ARG2, sizeof(struct vki_timeval) );
2238 // SYS_getpgid 207
2239 // generic
2241 // SYS_poll 209
2242 // generic
2244 // SYS_freebsd7___semctl 220
2245 // int semctl(int semid, int semnum, int cmd, ...);
2246 PRE(sys_freebsd7___semctl)
2248 union vki_semun* semun;
2249 switch (ARG3) {
2250 case VKI_IPC_STAT:
2251 case VKI_SEM_STAT:
2252 case VKI_IPC_SET:
2253 case VKI_GETALL:
2254 case VKI_SETALL:
2255 PRINT("sys_freebsd7___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
2256 PRE_REG_READ4(int, "semctl",
2257 int, semid, int, semnum, int, cmd, union vki_semun *, arg);
2258 PRE_MEM_READ("sys_freebsd7___semctl(arg)", ARG4, sizeof(union vki_semun));
2259 semun = (union vki_semun*)ARG4;
2260 if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
2261 ARG4 = (RegWord)semun;
2262 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
2264 break;
2265 default:
2266 PRINT("sys_freebsd7___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
2267 PRE_REG_READ3(long, "semctl",
2268 int, semid, int, semnum, int, cmd);
2269 break;
2273 POST(sys_freebsd7___semctl)
2275 union vki_semun* semun = (union vki_semun*)ARG4;
2276 if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
2277 ARG4 = (RegWord)semun;
2278 ML_(generic_POST_sys_semctl)(tid, RES, ARG1,ARG2,ARG3,ARG4);
2282 // SYS_semget 221
2283 // int semget(key_t key, int nsems, int flag);
2284 PRE(sys_semget)
2286 PRINT("sys_semget ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
2287 PRE_REG_READ3(int, "semget", vki_key_t, key, int, nsems, int, flag);
2290 // SYS_semop 222
2291 // int semop(int semid, struct sembuf *array, size_t nops);
2292 PRE(sys_semop)
2294 *flags |= SfMayBlock;
2295 PRINT("sys_semop ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
2296 PRE_REG_READ3(int, "semop",
2297 int, semid, struct sembuf *, array, unsigned, nops);
2298 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
2301 // SYS_freebsd7_msgctl 224
2302 // int msgctl(int msqid, int cmd, struct msqid_ds_old *buf);
2303 PRE(sys_freebsd7_msgctl)
2305 PRINT("sys_freebsd7_msgctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3 );
2307 PRE_REG_READ3(int, "msgctl", int, msqid, int, cmd, struct msqid_ds_old *, buf);
2309 switch (ARG2 /* cmd */) {
2310 case VKI_IPC_STAT:
2311 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
2312 ARG3, sizeof(struct vki_msqid_ds_old) );
2313 break;
2314 case VKI_IPC_SET:
2315 PRE_MEM_READ( "msgctl(IPC_SET, buf)",
2316 ARG3, sizeof(struct vki_msqid_ds_old) );
2317 break;
2321 POST(sys_freebsd7_msgctl)
2323 switch (ARG2 /* cmd */) {
2324 case VKI_IPC_STAT:
2325 POST_MEM_WRITE( ARG3, sizeof(struct vki_msqid_ds_old) );
2326 break;
2330 // SYS_msgget 225
2331 // int msgget(key_t key, int msgflg);
2332 PRE(sys_msgget)
2334 PRINT("sys_msgget ( %" FMT_REGWORD"d, %" FMT_REGWORD"d )",SARG1,SARG2);
2335 PRE_REG_READ2(int, "msgget", key_t, key, int, msgflg);
2338 // SYS_msgsnd 226
2339 // int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
2340 PRE(sys_msgsnd)
2342 PRINT("sys_msgsnd ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,ARG2,SARG3,SARG4 );
2343 PRE_REG_READ4(int, "msgsnd", int, msqid, struct msgbuf *, msgp, size_t, msgsz, int, msgflg);
2344 struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG2;
2345 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
2346 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, ARG3 );
2348 // SYS_msgrcv 227
2349 // ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);
2350 PRE(sys_msgrcv)
2352 *flags |= SfMayBlock;
2354 PRINT("sys_msgrcv ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,ARG2,ARG3,SARG4,SARG5 );
2355 PRE_REG_READ5(ssize_t, "msgrcv", int, msqid, struct msgbuf *, msgp, size_t, msgsz,
2356 long, msgtyp, int, msgflg);
2357 struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG2;
2358 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
2359 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, ARG3 );
2362 POST(sys_msgrcv)
2364 struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG2;
2365 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
2366 POST_MEM_WRITE( (Addr)&msgp->mtext, RES );
2369 // SYS_shmat 228
2370 // void * shmat(int shmid, const void *addr, int flag);
2371 PRE(sys_shmat)
2373 UWord arg2tmp;
2374 PRINT("sys_shmat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
2375 PRE_REG_READ3(void *, "shmat",
2376 int, shmid, const void *, addr, int, flag);
2377 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
2378 if (arg2tmp == 0) {
2379 SET_STATUS_Failure( VKI_EINVAL );
2380 } else {
2381 ARG2 = arg2tmp;
2385 POST(sys_shmat)
2387 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
2390 // SYS_freebsd7_shmctl 229
2391 // int shmctl(int shmid, int cmd, struct shmid_ds *buf);
2392 PRE(sys_freebsd7_shmctl)
2394 PRINT("sys_freebsd7_shmctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,SARG2,ARG3);
2395 PRE_REG_READ3(int, "shmctl",
2396 int, shmid, int, cmd, struct vki_shmid_ds_old *, buf);
2397 switch (ARG2 /* cmd */) {
2398 case VKI_IPC_STAT:
2399 PRE_MEM_WRITE( "shmctl7(IPC_STAT, buf)",
2400 ARG3, sizeof(struct vki_shmid_ds_old) );
2401 break;
2402 case VKI_IPC_SET:
2403 PRE_MEM_READ( "shmctl7(IPC_SET, buf)",
2404 ARG3, sizeof(struct vki_shmid_ds_old) );
2405 break;
2409 POST(sys_freebsd7_shmctl)
2411 if (ARG2 == VKI_IPC_STAT) {
2412 POST_MEM_WRITE( ARG3, sizeof(struct vki_shmid_ds_old) );
2416 // SYS_shmdt 230
2417 // int shmdt(const void *addr);
2418 PRE(sys_shmdt)
2420 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
2421 PRE_REG_READ1(int, "shmdt", const void *, addr);
2422 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1)) {
2423 SET_STATUS_Failure( VKI_EINVAL );
2427 POST(sys_shmdt)
2429 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
2432 // SYS_shmget 231
2433 // int shmget(key_t key, size_t size, int flag);
2434 PRE(sys_shmget)
2436 PRINT("sys_shmget ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
2437 PRE_REG_READ3(int, "shmget", vki_key_t, key, vki_size_t, size, int, flag);
2441 // SYS_clock_gettime 232
2442 // int clock_gettime(clockid_t clock_id, struct timespec *tp);
2443 PRE(sys_clock_gettime)
2445 PRINT("sys_clock_gettime( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2446 PRE_REG_READ2(int, "clock_gettime",
2447 vki_clockid_t, clk_id, struct timespec *, tp);
2448 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2451 POST(sys_clock_gettime)
2453 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2456 // SYS_clock_settime 233
2457 // int clock_settime(clockid_t clock_id, const struct timespec *tp);
2458 PRE(sys_clock_settime)
2460 PRINT("sys_clock_settime( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2461 PRE_REG_READ2(int, "clock_settime",
2462 vki_clockid_t, clk_id, const struct timespec *, tp);
2463 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2466 // SYS_clock_getres 234
2467 // int clock_getres(clockid_t clock_id, struct timespec *tp);
2468 PRE(sys_clock_getres)
2470 PRINT("sys_clock_getres( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2471 // Nb: we can't use "RES" as the param name because that's a macro
2472 // defined above!
2473 PRE_REG_READ2(int, "clock_getres",
2474 vki_clockid_t, clock_id, struct timespec *, tp);
2475 if (ARG2 != 0) {
2476 PRE_MEM_WRITE( "clock_getres(tp)", ARG2, sizeof(struct vki_timespec) );
2480 POST(sys_clock_getres)
2482 if (ARG2 != 0) {
2483 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2487 // SYS_ktimer_create 235
2488 // int timer_create(clockid_t clockid, struct sigevent *restrict evp,
2489 // timer_t *restrict timerid);
2490 PRE(sys_timer_create)
2492 PRINT("sys_timer_create( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,ARG2,ARG3);
2493 PRE_REG_READ3(int, "timer_create",
2494 vki_clockid_t, clockid, struct sigevent *, evp,
2495 vki_timer_t *, timerid);
2496 if (ARG2 != 0) {
2497 PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
2499 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2502 POST(sys_timer_create)
2504 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2507 // SYS_ktimer_delete 236
2508 // int timer_delete(timer_t timerid);
2509 PRE(sys_timer_delete)
2511 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
2512 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2515 // SYS_ktimer_settime 237
2516 // int timer_settime(timer_t timerid, int flags,
2517 // const struct itimerspec *restrict value,
2518 // struct itimerspec *restrict ovalue);
2519 PRE(sys_timer_settime)
2521 PRINT("sys_timer_settime( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3,ARG4);
2522 PRE_REG_READ4(int, "timer_settime",
2523 vki_timer_t, timerid, int, flags,
2524 const struct itimerspec *, value,
2525 struct itimerspec *, ovalue);
2526 PRE_MEM_READ( "timer_settime(value)", ARG3,
2527 sizeof(struct vki_itimerspec) );
2528 if (ARG4 != 0) {
2529 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2530 sizeof(struct vki_itimerspec) );
2534 POST(sys_timer_settime)
2536 if (ARG4 != 0) {
2537 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2541 // SYS_ktimer_gettime 238
2542 // int timer_gettime(timer_t timerid, struct itimerspec *value);
2543 PRE(sys_timer_gettime)
2545 PRINT("sys_timer_gettime( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
2546 PRE_REG_READ2(long, "timer_gettime",
2547 vki_timer_t, timerid, struct itimerspec *, value);
2548 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2549 sizeof(struct vki_itimerspec));
2552 POST(sys_timer_gettime)
2554 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2557 // SYS_ktimer_getoverrun 239
2558 // int timer_getoverrun(timer_t timerid);
2559 PRE(sys_timer_getoverrun)
2561 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
2562 PRE_REG_READ1(int, "timer_getoverrun", vki_timer_t, timerid);
2565 // SYS_nanosleep 240
2566 // generic
2568 // SYS_ffclock_getcounter 241
2569 // int ffclock_getcounter(ffcounter *ffcount);
2570 // @todo
2572 // SYS_ffclock_setestimate 242
2573 // int ffclock_setestimate(struct ffclock_estimate *cest);
2574 // @todo
2576 // SYS_ffclock_getestimate 243
2577 // int ffclock_getestimate(struct ffclock_estimate *cest);
2578 // @todo
2580 // SYS_clock_nanosleep 244
2581 // int clock_nanosleep(clockid_t clock_id, int flags,
2582 // const struct timespec *rqtp, struct timespec *rmtp);
2583 PRE(sys_clock_nanosleep)
2585 *flags |= SfMayBlock|SfPostOnFail;
2586 PRINT("sys_clock_nanosleep ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2587 SARG1, SARG2, ARG3, ARG4);
2588 PRE_REG_READ4(int, "clock_nanosleep", vki_clockid_t, clock_id, int, flags,
2589 const struct timespec *, rqtp, struct timespec *, rmtp);
2590 PRE_MEM_READ("clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec));
2591 if (ARG4 != 0) {
2592 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2596 POST(sys_clock_nanosleep)
2598 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR) {
2599 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2603 // SYS_clock_getcpuclockid2 247
2604 // x86/amd64
2606 POST(sys_clock_getcpuclockid2)
2608 POST_MEM_WRITE(ARG3, sizeof(vki_clockid_t));
2612 // SYS_ntp_gettime 248
2613 // int ntp_gettime(struct ntptimeval *);
2614 // @todo
2616 // SYS_minherit 250
2617 // int minherit(void *addr, size_t len, int inherit);
2618 PRE(sys_minherit)
2620 PRINT("sys_minherit( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3);
2621 PRE_REG_READ3(int, "minherit",
2622 void *, addr, vki_size_t, len, int, inherit);
2623 if (ARG2 != 0) {
2624 PRE_MEM_WRITE( "minherit(addr)", ARG1,ARG2 );
2628 POST(sys_minherit)
2630 if (ARG2 != 0) {
2631 POST_MEM_WRITE( ARG1, ARG2 );
2635 // SYS_rfork 251
2636 // x86/amd64 not functional
2638 // SYS_issetugid 253
2639 // int issetugid(void);
2640 PRE(sys_issetugid)
2642 PRINT("%s", "sys_issetugid ()");
2643 PRE_REG_READ0(long, "issetugid");
2646 // SYS_lchown 254
2647 // generic
2649 // We must record the iocb for each aio_read() in a table so that when
2650 // aio_return() is called we can mark the memory written asynchronously by
2651 // aio_read() as having been written. We don't have to do this for
2652 // aio_write(). See bug 197227 for more details.
2653 static OSet* iocb_table = NULL;
2654 static Bool aio_init_done = False;
2656 static void aio_init(void)
2658 iocb_table = VG_(OSetWord_Create)(VG_(malloc), "syswrap.aio", VG_(free));
2659 aio_init_done = True;
2662 // and the same thing for vector reads
2663 static OSet* iocbv_table = NULL;
2664 static Bool aiov_init_done = False;
2666 static void aiov_init(void)
2668 iocbv_table = VG_(OSetWord_Create)(VG_(malloc), "syswrap.aiov", VG_(free));
2669 aiov_init_done = True;
2673 // SYS_aio_read 255
2674 // int aio_read(struct aiocb *iocb);
2675 PRE(sys_aio_read)
2677 PRINT("sys_aio_read ( %#" FMT_REGWORD "x )", ARG1);
2678 PRE_REG_READ1(int, "aio_read", struct vki_aiocb *, iocb);
2679 PRE_MEM_READ("aio_read(iocb)", ARG1, sizeof(struct vki_aiocb));
2680 if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
2681 struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1;
2682 if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_read", tid, False)) {
2683 SET_STATUS_Failure(VKI_EBADF);
2684 } else {
2685 PRE_MEM_WRITE("aio_read(aiocbp->aio_buf)",
2686 (Addr)iocb->aio_buf, iocb->aio_nbytes);
2687 // @todo PJF there is a difference between FreeBSD and
2688 // Darwin here. On Darwin, if aio_buf is NULL the syscall
2689 // will fail, on FreeBSD it doesn't fail.
2691 } else {
2692 SET_STATUS_Failure(VKI_EINVAL);
2696 POST(sys_aio_read)
2698 struct vki_aiocb* iocb = (struct vki_aiocb*)ARG1;
2700 if (iocb->aio_buf) {
2701 if (!aio_init_done) {
2702 aio_init();
2704 // see also POST(sys_aio_readv)
2705 if (!VG_(OSetWord_Contains)(iocb_table, (UWord)iocb)) {
2706 VG_(OSetWord_Insert)(iocb_table, (UWord)iocb);
2707 } else {
2708 // @todo PJF this warns without callstack
2709 VG_(dmsg)("Warning: Duplicate control block %p in aio_read\n",
2710 (void *)(Addr)ARG1);
2711 VG_(dmsg)("Warning: Ensure 'aio_return' is called when 'aio_read' has completed\n");
2716 // SYS_aio_write 256
2717 // int aio_write(struct aiocb *iocb);
2718 PRE(sys_aio_write)
2720 PRINT("sys_aio_write ( %#" FMT_REGWORD "x )", ARG1);
2721 PRE_REG_READ1(int, "aio_write", struct vki_aiocb *, iocb);
2722 PRE_MEM_READ("aio_write(iocb)", ARG1, sizeof(struct vki_aiocb));
2723 if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
2724 struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1;
2725 if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_write", tid, False)) {
2726 SET_STATUS_Failure( VKI_EBADF );
2727 } else {
2728 PRE_MEM_READ("aio_write(iocb->aio_buf)",
2729 (Addr)iocb->aio_buf, iocb->aio_nbytes);
2730 // @todo PJF there is a difference between FreeBSD and
2731 // Darwin here. On Darwin, if aio_buf is NULL the syscall
2732 // will fail, on FreeBSD it doesn't fail.
2734 } else {
2735 SET_STATUS_Failure(VKI_EINVAL);
2739 // SYS_lio_listio 257
2740 // int lio_listio(int mode, struct aiocb * const list[], int nent,
2741 // struct sigevent *sig);
2742 PRE(sys_lio_listio)
2744 PRINT("sys_lio_listio ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",
2745 SARG1, ARG2, SARG3, ARG4);
2746 PRE_REG_READ4(int, "lio_listio", int, mode, struct aiocb * const *, list, int, nent,
2747 struct sigevent *,sig);
2748 PRE_MEM_READ("lio_listio(list)", ARG2, ARG3*sizeof(struct vki_aiocb *));
2749 // loop check elements
2750 if (ML_(safe_to_deref)((struct vki_aiocb **)ARG2, ARG3*sizeof(struct vki_aiocb *))) {
2751 struct vki_aiocb** list = (struct vki_aiocb **)ARG2;
2752 for (int i = 0; i < (int)ARG3; ++i) {
2753 if (list[i]) {
2754 PRE_MEM_READ("lio_listio(list[?])", (Addr)list[i], ARG3*sizeof(struct vki_aiocb));
2756 // @todo
2757 // figure out what gets read/written
2758 // when list[i]->aio_lio_opcode == VKI_LIO_READ and
2759 // when list[i]->aio_lio_opcode == VKI_LIO_WRITE
2760 //if (ML_(safe_to_deref)(list[i], ARG3*sizeof(struct vki_aiocb))) {
2765 if (ARG1 & VKI_LIO_WAIT) {
2766 *flags |= SfMayBlock;
2769 if (ARG4 && (ARG1 == VKI_LIO_NOWAIT)) {
2770 PRE_MEM_READ("lio_listio(sig)", ARG4, sizeof(struct vki_sigevent));
2774 // SYS_freebsd11_getdents 272
2775 // generic
2777 // SYS_lchmod 274
2778 // int lchmod(const char *path, mode_t mode);
2779 PRE(sys_lchmod)
2781 PRINT("sys_lchmod ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1,ARG2);
2782 PRE_REG_READ2(int, "lchmod", const char *, path, vki_mode_t, mode);
2783 PRE_MEM_RASCIIZ( "lchmod(path)", ARG1 );
2786 // SYS_lutimes 276
2787 // int lutimes(const char *path, const struct timeval *times);
2788 PRE(sys_lutimes)
2790 PRINT("sys_lutimes ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2);
2791 PRE_REG_READ2(int, "lutimes", char *, path, struct timeval *, times);
2792 PRE_MEM_RASCIIZ( "lutimes(path)", ARG1 );
2793 if (ARG2 != 0) {
2794 PRE_MEM_READ( "lutimes(times)", ARG2, sizeof(struct vki_timeval) );
2798 // SYS_freebsd11_nstat 278
2799 // @todo, maybe
2801 // SYS_freebsd11_nfstat 279
2802 // @todo, maybe
2804 // SYS_freebsd11_nlstat 280
2805 // @todo, maybe
2807 // SYS_preadv 289
2808 // amd64 / x86
2810 // SYS_pwritev 290
2811 // amd64 / x86
2813 // SYS_fhopen 298
2814 // int fhopen(const fhandle_t *fhp, int flags);
2815 PRE(sys_fhopen)
2817 PRINT("sys_open ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2);
2818 PRE_REG_READ2(int, "fhopen",
2819 struct fhandle_t *, fhp, int, flags);
2820 PRE_MEM_READ( "fhopen(fhp)", ARG1, sizeof(struct vki_fhandle) );
2822 /* Otherwise handle normally */
2823 *flags |= SfMayBlock;
2826 POST(sys_fhopen)
2828 vg_assert(SUCCESS);
2829 if (!ML_(fd_allowed)(RES, "fhopen", tid, True)) {
2830 VG_(close)(RES);
2831 SET_STATUS_Failure( VKI_EMFILE );
2832 } else {
2833 if (VG_(clo_track_fds)) {
2834 ML_(record_fd_open_nameless)(tid, RES);
2839 // SYS_freebsd11_fhstat 299
2840 // int fhstat(const fhandle_t *fhp, struct stat *sb);
2841 #if (FREEBSD_VERS >= FREEBSD_12)
2842 PRE(sys_freebsd11_fhstat)
2844 PRINT("sys_freebsd11_fhstat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
2845 PRE_REG_READ2(int, "fhstat", struct fhandle *, fhp, struct freebd11_stat *, sb);
2846 PRE_MEM_READ( "fhstat(fhp)", ARG1, sizeof(struct vki_fhandle) );
2847 PRE_MEM_WRITE( "fhstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
2850 POST(sys_freebsd11_fhstat)
2852 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
2854 #else
2855 PRE(sys_fhstat)
2857 PRINT("sys_fhstat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
2858 PRE_REG_READ2(int, "fhstat", struct fhandle *, fhp, struct stat *, sb);
2859 PRE_MEM_READ( "fhstat(fhp)", ARG1, sizeof(struct vki_fhandle) );
2860 PRE_MEM_WRITE( "fhstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) );
2863 POST(sys_fhstat)
2865 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) );
2868 #endif
2870 // SYS_modnext 300
2871 // int modnext(int modid);
2872 PRE(sys_modnext)
2874 PRINT("sys_modnext ( %" FMT_REGWORD "d )",SARG1);
2875 PRE_REG_READ1(int, "modnext", int, modid);
2878 // SYS_modstat 301
2879 // int modstat(int modid, struct module_stat *stat);
2880 PRE(sys_modstat)
2882 PRINT("sys_modstat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2);
2883 PRE_REG_READ2(int, "modstat", int, modid, struct module_stat *, buf);
2884 PRE_MEM_WRITE( "modstat(stat)", ARG2, sizeof(struct vki_module_stat) );
2887 POST(sys_modstat)
2889 POST_MEM_WRITE( ARG2, sizeof(struct vki_module_stat) );
2892 // SYS_modfnext 302
2893 // int modfnext(int modid);
2894 PRE(sys_modfnext)
2896 PRINT("sys_modfnext ( %" FMT_REGWORD "d )",SARG1);
2897 PRE_REG_READ1(int, "modfnext", int, modid);
2900 // SYS_modfind 303
2901 // int modfind(const char *modname);
2902 PRE(sys_modfind)
2904 PRINT("sys_modfind ( %#" FMT_REGWORD "x )",ARG1);
2905 PRE_REG_READ1(long, "modfind", char *, modname);
2906 PRE_MEM_RASCIIZ( "modfind(modname)", ARG1 );
2909 // SYS_kldload 304
2910 // int kldload(const char *file);
2911 PRE(sys_kldload)
2913 PRINT("sys_kldload ( %#" FMT_REGWORD "x(%s) )", ARG1, (char *)ARG1);
2914 PRE_REG_READ1(int, "kldload", const char *, "file");
2915 PRE_MEM_RASCIIZ( "kldload(file)", ARG1 );
2918 // SYS_kldunload 305
2919 // int kldunload(int fileid);
2920 PRE(sys_kldunload)
2922 PRINT("sys_kldunload ( %" FMT_REGWORD "u )", ARG1);
2923 PRE_REG_READ1(int, "kldunload", int, "fileid");
2926 // SYS_kldfind 306
2927 // int kldfind(const char *file);
2928 PRE(sys_kldfind)
2930 PRINT("sys_kldfind ( %#" FMT_REGWORD "x(%s) )", ARG1, (char *)ARG1);
2931 PRE_REG_READ1(int, "kldfind", const char *, file);
2932 PRE_MEM_RASCIIZ( "kldfind(file)", ARG1 );
2935 // SYS_kldnext 307
2936 // int kldnext(int fileid);
2937 PRE(sys_kldnext)
2939 PRINT("sys_kldnext ( %" FMT_REGWORD "u )", ARG1);
2940 PRE_REG_READ1(int, "kldnext", int, fileid);
2943 // SYS_kldstat 308
2944 // int kldstat(int fileid, struct kld_file_stat *stat);
2945 PRE(sys_kldstat)
2947 PRINT("sys_kldstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
2948 PRE_REG_READ2(int, "kldstat", int, fileid, struct kld_file_stat*, stat);
2949 PRE_MEM_WRITE("kldstat(stat)", ARG2, sizeof(struct vki_kld_file_stat));
2952 POST(sys_kldstat)
2954 POST_MEM_WRITE(ARG2, sizeof(struct vki_kld_file_stat));
2957 // SYS_kldfirstmod 309
2958 // int kldfirstmod(int fileid);
2959 PRE(sys_kldfirstmod)
2961 PRINT("sys_kldfirstmod ( %" FMT_REGWORD "u )", ARG1);
2962 PRE_REG_READ1(int, "kldfirstmod", int, fileid);
2965 // SYS_setresuid 311
2966 // int setresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
2967 PRE(sys_setresuid)
2969 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
2970 PRE_REG_READ3(int, "setresuid",
2971 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
2974 // SYS_setresgid 312
2975 // int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
2976 PRE(sys_setresgid)
2978 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
2979 PRE_REG_READ3(int, "setresgid",
2980 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
2983 // SYS_aio_return 314
2984 // ssize_t aio_return(struct aiocb *iocb);
2985 PRE(sys_aio_return)
2987 PRINT("sys_aio_return ( %#" FMT_REGWORD "x )", ARG1);
2988 PRE_REG_READ1(ssize_t, "aio_return", struct aiocb *, iocb);
2989 PRE_MEM_READ("aio_return(iocb)", ARG1, sizeof(struct vki_aiocb));
2990 // read or write?
2991 if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
2992 SET_STATUS_from_SysRes(VG_(do_syscall1)(SYSNO, ARG1));
2993 /*if (SUCCESS)*/ {
2994 struct vki_aiocb* iocb = (struct vki_aiocb*)ARG1;
2995 if (!aio_init_done) {
2996 aio_init();
2998 if (!aiov_init_done) {
2999 aiov_init();
3002 // for the happy path aio_return is supposed to be called
3003 // after the io has completed (as determined by aio_error,
3004 // aio_suspend or a signal).
3006 // but what if the aio_read failed or hasn't completed?
3007 // we want to remove the read from the iocb(v)_table
3008 // in the case of aio_read failing
3009 // if the read hasn't completed that's a user error
3010 // I don't know if it's possible to recover in that case
3011 // the iocb will have been removed from the table
3012 // so if the user does recover and call aio_return
3013 // 'correctly' we won't do the POST_MEM_WRITE
3014 // I don't think that we can tell apart a failing
3015 // read from a premature aio_return
3017 // check if it was a plain read
3018 if (VG_(OSetWord_Remove)(iocb_table, (UWord)iocb) && SUCCESS) {
3019 POST_MEM_WRITE((Addr)iocb->aio_buf, iocb->aio_nbytes);
3021 if (VG_(OSetWord_Remove)(iocbv_table, (UWord)iocb) && SUCCESS) {
3022 SizeT vec_count = (SizeT)iocb->aio_nbytes;
3023 // assume that id the read succeded p_iovec is accessible
3024 volatile struct vki_iovec* p_iovec = (volatile struct vki_iovec*)iocb->aio_buf;
3025 for (SizeT i = 0U; i < vec_count; ++i) {
3026 POST_MEM_WRITE((Addr)p_iovec[i].iov_base, p_iovec[i].iov_len);
3030 } else {
3031 SET_STATUS_Failure(VKI_EINVAL);
3035 // SYS_aio_suspend 315
3036 // int aio_suspend(const struct aiocb *const iocbs[], int niocb,
3037 // const struct timespec *timeout);
3038 PRE(sys_aio_suspend)
3040 PRINT("sys_aio_suspend ( %#" FMT_REGWORD "x )", ARG1);
3041 PRE_REG_READ3(int, "aio_suspend", const struct aiocb * const *, iocbs, int, nbiocb, const struct timespec*, timeout);
3042 if (ARG2 > 0) {
3043 PRE_MEM_READ("aio_suspend(iocbs)", ARG1, ARG2*sizeof(struct vki_aiocb*));
3045 if (ARG3) {
3046 PRE_MEM_READ("aio_suspend(timeout)", ARG3, sizeof(struct vki_timespec));
3050 // SYS_aio_cancel 316
3051 // int aio_cancel(int fildes, struct aiocb *iocb);
3052 PRE(sys_aio_cancel)
3054 PRINT("sys_aio_cancel ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
3055 PRE_REG_READ2(int, "aio_cancel", int, fildes, struct iocb *, iocb);
3056 if (ARG2) {
3057 PRE_MEM_READ("aio_cancel(iocb)", ARG2, sizeof(struct vki_aiocb));
3059 if (!ML_(fd_allowed)(ARG1, "aio_cancel", tid, False)) {
3060 SET_STATUS_Failure(VKI_EBADF);
3061 } else {
3062 if (ARG2) {
3063 if (ML_(safe_to_deref)((struct vki_aiocb *)ARG2, sizeof(struct vki_aiocb))) {
3064 // struct vki_aiocb *iocb = (struct vki_aiocb *)ARG2;
3065 // @todo PJF cancel only requests associated with
3066 // fildes and iocb
3067 // Do I need to remove pending reads from iocb(v)_table
3068 // or should the user always call aio_return even after
3069 // aio_cancel?
3070 } else {
3071 SET_STATUS_Failure(VKI_EINVAL);
3073 } else {
3074 // @todo PJF cancel all requests associated with fildes, see above
3079 // SYS_aio_error 317
3080 // int aio_error(const struct aiocb *iocb);
3081 PRE(sys_aio_error)
3083 PRINT("sys_aio_error ( %#" FMT_REGWORD "x )", ARG1);
3084 PRE_REG_READ1(ssize_t, "aio_error", struct aiocb *, iocb);
3085 PRE_MEM_READ("aio_error(iocb)", ARG1, sizeof(struct vki_aiocb));
3086 if (ARG1) {
3087 if (!ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
3088 SET_STATUS_Failure(VKI_EINVAL);
3093 // SYS_yield 321
3094 int yield(void);
3095 PRE(sys_yield)
3097 *flags |= SfMayBlock;
3098 PRINT("%s", "yield()");
3099 PRE_REG_READ0(long, "yield");
3102 // SYS_mlockall 324
3103 // generic
3105 // SYS_munlockall 325
3106 // int munlockall(void);
3107 PRE(sys_munlockall)
3109 *flags |= SfMayBlock;
3110 PRINT("%s", "sys_munlockall ( )");
3111 PRE_REG_READ0(int, "munlockall");
3114 // SYS___getcwd 326
3115 // int __getcwd(char *buf, size_t buflen);
3116 PRE(sys___getcwd)
3118 PRINT("sys___getcwd ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2);
3119 PRE_REG_READ2(long, "__getcwd", char *, buf, unsigned int, buflen);
3120 PRE_MEM_WRITE( "__getcwd(buf)", ARG1, ARG2 );
3123 POST(sys___getcwd)
3125 vg_assert(SUCCESS);
3126 if (RES == 0) {
3127 // QQQ it is unclear if this is legal or not, but the
3128 // QQQ kernel just wrote it there...
3129 // QQQ Why oh why didn't phk return the length from __getcwd()?
3130 UInt len = VG_(strlen) ( (char *)ARG1 ) + 1;
3131 POST_MEM_WRITE( ARG1, len );
3135 //SYS_sched_setparam 327
3136 // int sched_setparam(pid_t pid, const struct sched_param *param);
3137 PRE(sys_sched_setparam)
3139 PRINT("sched_setparam ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3140 PRE_REG_READ2(int, "sched_setparam",
3141 vki_pid_t, pid, struct sched_param *, param);
3142 PRE_MEM_READ( "sched_setparam(param)", ARG2, sizeof(struct vki_sched_param) );
3145 POST(sys_sched_setparam)
3147 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3150 // SYS_sched_getparam 328
3151 // int sched_getparam(pid_t pid, struct sched_param *param);
3152 PRE(sys_sched_getparam)
3154 PRINT("sched_getparam ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3155 PRE_REG_READ2(int, "sched_getparam",
3156 vki_pid_t, pid, struct sched_param *, param);
3157 PRE_MEM_WRITE( "sched_getparam(param)", ARG2, sizeof(struct vki_sched_param) );
3160 POST(sys_sched_getparam)
3162 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3165 // SYS_sched_setscheduler 329
3166 // int sched_setscheduler(pid_t pid, int policy,
3167 // const struct sched_param *param);
3168 PRE(sys_sched_setscheduler)
3170 PRINT("sys_sched_setscheduler ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3);
3171 PRE_REG_READ3(int, "sched_setscheduler",
3172 vki_pid_t, pid, int, policy, struct sched_param *, param);
3173 if (ARG3 != 0) {
3174 PRE_MEM_READ("sched_setscheduler(param)",
3175 ARG3, sizeof(struct vki_sched_param));
3179 // SYS_sched_getscheduler 330
3180 // int sched_getscheduler(pid_t pid);
3181 PRE(sys_sched_getscheduler)
3183 PRINT("sys_sched_getscheduler ( %" FMT_REGWORD "d )", SARG1);
3184 PRE_REG_READ1(int, "sched_getscheduler", vki_pid_t, pid);
3187 // SYS_sched_yield 331
3188 // int sched_yield(void);
3189 PRE(sys_sched_yield)
3191 *flags |= SfMayBlock;
3192 PRINT("sched_yield()");
3193 PRE_REG_READ0(int, "sched_yield");
3196 // SYS_sched_get_priority_max 332
3197 // int sched_get_priority_max(int policy);
3198 PRE(sys_sched_get_priority_max)
3200 PRINT("sched_get_priority_max ( %" FMT_REGWORD "u )", ARG1);
3201 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3204 // SYS_sched_get_priority_min 333
3205 // int sched_get_priority_min(int policy);
3206 PRE(sys_sched_get_priority_min)
3208 PRINT("sched_get_priority_min ( %" FMT_REGWORD "u )", ARG1);
3209 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3212 // SYS_sched_rr_get_interval 334
3213 // int sched_rr_get_interval(pid_t pid, struct timespec *interval);
3214 PRE(sys_sched_rr_get_interval)
3216 PRINT("sys_sched_rr_get_interval ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
3217 PRE_REG_READ2(int, "sched_rr_get_interval", vki_pid_t, pid, struct vki_timespec *,interval);
3218 PRE_MEM_WRITE("sys_sched_rr_get_interval(interval)", ARG2, sizeof(struct vki_timespec));
3221 POST(sys_sched_rr_get_interval)
3223 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3226 // SYS_utrace 335
3227 // int utrace(const void *addr, size_t len);
3228 PRE(sys_utrace)
3230 PRINT("sys_utrace ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
3231 PRE_REG_READ2(int, "utrace", const void *, addr, vki_size_t, len);
3232 PRE_MEM_READ( "utrace(addr)", ARG1, ARG2 );
3235 // SYS_kldsym 337
3236 // int kldsym(int fileid, int cmd, void *data);
3237 PRE(sys_kldsym)
3239 PRINT("sys_kldsym ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3 );
3240 PRE_REG_READ3(int, "kldsym", int, fileid, int, cmd, void*, data);
3241 PRE_MEM_READ( "kldsym(data)", ARG3, sizeof(struct vki_kld_sym_lookup) );
3242 struct vki_kld_sym_lookup *kslp = (struct vki_kld_sym_lookup *)ARG3;
3243 if (ML_(safe_to_deref)(kslp, sizeof(struct vki_kld_sym_lookup))) {
3244 PRE_MEM_RASCIIZ( "kldsym(data.symname)", (Addr)kslp->symname );
3248 POST(sys_kldsym)
3250 struct vki_kld_sym_lookup *kslp = (struct vki_kld_sym_lookup *)ARG3;
3251 POST_MEM_WRITE( (Addr)&kslp->symvalue, sizeof(kslp->symvalue) );
3252 POST_MEM_WRITE( (Addr)&kslp->symsize, sizeof(kslp->symsize) );
3255 // SYS_jail 338
3256 // int jail(struct jail *jail);
3257 PRE(sys_jail)
3259 PRINT("sys_jail ( %#" FMT_REGWORD "x )", ARG1);
3260 PRE_REG_READ1(int, "jail", struct jail *, jail);
3261 PRE_MEM_READ( "jail(jail)", ARG1, sizeof(struct vki_jail) );
3264 // SYS_nnpfs_syscall 338
3265 // @todo
3267 // SYS_sigprocmask 340
3268 // int sigprocmask(int how, const sigset_t * restrict set,
3269 // sigset_t * restrict oset);
3270 PRE(sys_sigprocmask)
3272 PRINT("sys_sigprocmask ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3);
3273 PRE_REG_READ3(int, "sigprocmask",
3274 int, how, vki_sigset_t *, set, vki_sigset_t *, oset);
3275 if (ARG2 != 0) {
3276 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3278 if (ARG3 != 0) {
3279 PRE_MEM_WRITE( "sigprocmask(oset)", ARG3, sizeof(vki_sigset_t));
3282 if (ARG2 != 0 &&
3283 !ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
3284 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
3285 (void *)(Addr)ARG2);
3286 SET_STATUS_Failure ( VKI_EFAULT );
3287 } else if (ARG3 != 0 &&
3288 !ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
3289 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
3290 (void *)(Addr)ARG3);
3291 SET_STATUS_Failure ( VKI_EFAULT );
3292 } else {
3293 SET_STATUS_from_SysRes(VG_(do_sys_sigprocmask)(tid, ARG1 /*how*/,
3294 (vki_sigset_t*)(Addr)ARG2,
3295 (vki_sigset_t*)(Addr)ARG3));
3298 if (SUCCESS) {
3299 *flags |= SfPollAfter;
3303 POST(sys_sigprocmask)
3305 vg_assert(SUCCESS);
3306 if (RES == 0 && ARG3 != 0) {
3307 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3311 // SYS_sigsuspend 341
3312 // int sigsuspend(const sigset_t *sigmask);
3313 PRE(sys_sigsuspend)
3315 *flags |= SfMayBlock;
3316 PRINT("sys_sigsuspend ( %#" FMT_REGWORD "x )", ARG1 );
3317 PRE_REG_READ1(int, "sigsuspend", const vki_sigset_t *, sigmask);
3318 PRE_MEM_READ( "sigsuspend(sigmask)", ARG1, sizeof(vki_sigset_t) );
3319 if (ARG1) {
3320 ARG1 = ML_(make_safe_mask)("syswrap.sigsuspend.1", (Addr)ARG1);
3324 POST(sys_sigsuspend)
3326 ML_(free_safe_mask) ( (Addr)ARG1 );
3329 // SYS_sigpending 343
3330 // int sigpending(sigset_t *set);
3331 PRE(sys_sigpending)
3333 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
3334 PRE_REG_READ1(int, "sigpending", vki_sigset_t *, set);
3335 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_sigset_t));
3338 POST(sys_sigpending)
3340 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3344 // SYS_sigtimedwait 345
3345 // int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info,
3346 // const struct timespec *restrict timeout);
3347 PRE(sys_sigtimedwait)
3349 *flags |= SfMayBlock;
3350 PRINT("sys_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3351 ARG1,ARG2,ARG3);
3352 PRE_REG_READ3(int, "sigtimedwait",
3353 const vki_sigset_t *, set, vki_siginfo_t *, info,
3354 const struct timespec *, timeout);
3355 if (ARG1 != 0) {
3356 PRE_MEM_READ( "sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
3358 if (ARG2 != 0) {
3359 PRE_MEM_WRITE( "sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
3361 if (ARG3 != 0) {
3362 PRE_MEM_READ( "sigtimedwait(timeout)",
3363 ARG3, sizeof(struct vki_timespec) );
3367 POST(sys_sigtimedwait)
3369 if (ARG2 != 0) {
3370 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3374 // SYS_sigwaitinfo 346
3375 // int sigwaitinfo(const sigset_t * restrict set, siginfo_t * restrict info);
3376 PRE(sys_sigwaitinfo)
3378 *flags |= SfMayBlock;
3379 PRINT("sys_sigwaitinfo ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3380 ARG1,ARG2);
3381 PRE_REG_READ2(int, "sigwaitinfo",
3382 const vki_sigset_t *, set, vki_siginfo_t *, info);
3383 if (ARG1 != 0) {
3384 PRE_MEM_READ( "sigwaitinfo(set)", ARG1, sizeof(vki_sigset_t));
3386 if (ARG2 != 0) {
3387 PRE_MEM_WRITE( "sigwaitinfo(info)", ARG2, sizeof(vki_siginfo_t) );
3391 POST(sys_sigwaitinfo)
3393 if (ARG2 != 0) {
3394 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3398 // SYS___acl_get_file 347
3399 // int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp);
3400 PRE(sys___acl_get_file)
3402 PRINT("sys___acl_get_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3);
3403 PRE_REG_READ3(int, "acl_get_file",
3404 const char *, path, int, type, struct vki_acl *, aclp);
3405 PRE_MEM_RASCIIZ("acl_get_file(path", ARG1);
3406 PRE_MEM_WRITE( "acl_get_file(aclp)", ARG3, sizeof(struct vki_acl) );
3409 POST(sys___acl_get_file)
3411 vg_assert(SUCCESS);
3412 if (RES == 0) {
3413 POST_MEM_WRITE( ARG3, sizeof(struct vki_acl) );
3417 // SYS___acl_set_file 348
3418 // int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp);
3419 PRE(sys___acl_set_file)
3421 PRINT("sys___acl_set_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3);
3422 PRE_REG_READ3(int, "acl_set_file",
3423 const char *, path, int, type, struct vki_acl *, aclp);
3424 PRE_MEM_RASCIIZ("acl_set_file(path", ARG1);
3425 PRE_MEM_READ("acl_set_file(aclp)", ARG3, sizeof(struct vki_acl) );
3428 // SYS___acl_get_fd 349
3429 // int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp);
3430 PRE(sys___acl_get_fd)
3432 PRINT("sys___acl_get_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
3433 PRE_REG_READ3(int, "acl_get_fd",
3434 int, fd, int, type, struct vki_acl *, aclp);
3435 PRE_MEM_WRITE( "acl_get_file(aclp)", ARG3, sizeof(struct vki_acl) );
3438 POST(sys___acl_get_fd)
3440 vg_assert(SUCCESS);
3441 if (RES == 0) {
3442 POST_MEM_WRITE( ARG3, sizeof(struct vki_acl) );
3446 // SYS___acl_set_fd 350
3447 // int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp);
3448 PRE(sys___acl_set_fd)
3450 PRINT("sys___acl_set_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
3451 PRE_REG_READ3(int, "acl_set_fd",
3452 int, filedes, int, type, struct vki_acl *, aclp);
3453 PRE_MEM_READ( "acl_get_file(aclp)", ARG3, sizeof(struct vki_acl) );
3456 // SYS___acl_delete_file 351
3457 // int __acl_delete_file(const char *path, acl_type_t type);
3458 PRE(sys___acl_delete_file)
3460 PRINT("sys___acl_delete_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1,ARG2);
3461 PRE_MEM_RASCIIZ("acl_set_file(path", ARG1);
3462 PRE_REG_READ2(int, "acl_delete_file",
3463 const char *, path, int, type);
3465 // SYS___acl_delete_fd 352
3466 // int __acl_delete_fd(int filedes, acl_type_t type);
3467 PRE(sys___acl_delete_fd)
3469 PRINT("sys___acl_delete_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2);
3470 PRE_REG_READ2(int, "acl_delete_fd",
3471 int, filedes, int, acltype);
3474 // SYS___acl_aclcheck_file 353
3475 // int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp);
3476 PRE(sys___acl_aclcheck_file)
3478 PRINT("sys___acl_aclcheck_file ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3);
3479 PRE_REG_READ3(int, "acl_aclcheck_file",
3480 const char *, path, int, type, struct vki_acl *, aclp);
3481 PRE_MEM_RASCIIZ("acl_set_file(path", ARG1);
3482 PRE_MEM_READ( "acl_aclcheck_file(aclp)", ARG3, sizeof(struct vki_acl) );
3485 // SYS___acl_aclcheck_fd 354
3486 // int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp);
3487 PRE(sys___acl_aclcheck_fd)
3489 PRINT("sys___acl_aclcheck_fd ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
3490 PRE_REG_READ3(int, "acl_aclcheck_fd",
3491 int, fd, int, type, struct vki_acl *, aclp);
3492 PRE_MEM_READ( "acl_aclcheck_fd(aclp)", ARG3, sizeof(struct vki_acl) );
3495 // SYS_extattrctl 355
3496 // no manpage?
3497 // syscalls.master: int extattrctl(_In_z_ const char *path, int cmd, _In_z_opt_ const char *filename, int attrnamespace, _In_z_ const char *attrname);
3498 PRE(sys_extattrctl)
3500 PRINT("sys_extattrctl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3,SARG4,ARG5);
3501 PRE_REG_READ5(ssize_t, "extattrctl",
3502 const char *, path, int, cmd, const char *, filename, int, attrnamespace, const char *, attrname);
3503 PRE_MEM_RASCIIZ("extattrctl(path)", ARG1);
3504 PRE_MEM_RASCIIZ("extattrctl(filename)", ARG3);
3505 PRE_MEM_RASCIIZ("extattrctl(attrname)", ARG5);
3508 // SYS_extattr_set_file 356
3509 // ssize_t extattr_set_file(const char *path, int attrnamespace,
3510 // const char *attrname, const void *data, size_t nbytes);
3511 PRE(sys_extattr_set_file)
3513 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);
3514 PRE_REG_READ5(ssize_t, "extattr_set_file",
3515 const char *, path, int, attrnamespace, const char *, attrname, const void *, data, size_t, nbytes);
3516 PRE_MEM_RASCIIZ("extattr_set_file(path)", ARG1);
3517 PRE_MEM_RASCIIZ("extattr_set_file(attrname)", ARG3);
3518 PRE_MEM_READ("extattr_set_file(data)", ARG4, ARG5);
3521 // SYS_extattr_get_file 357
3522 // ssize_t extattr_get_file(const char *path, int attrnamespace,
3523 // const char *attrname, void *data, size_t nbytes);
3524 PRE(sys_extattr_get_file)
3526 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);
3527 PRE_REG_READ5(ssize_t, "extattr_get_file",
3528 const char *, path, int, attrnamespace, const char *, attrname, void *, data, size_t, nbytes);
3529 PRE_MEM_RASCIIZ("extattr_get_file(path)", ARG1);
3530 PRE_MEM_RASCIIZ("extattr_get_file(attrname)", ARG3);
3531 if (ARG4) {
3532 PRE_MEM_WRITE("extattr_get_file(data)", ARG4, ARG5);
3536 POST(sys_extattr_get_file)
3538 if (ARG4) {
3539 POST_MEM_WRITE(ARG4, ARG5);
3543 // SYS_extattr_delete_file 358
3544 // int extattr_delete_file(const char *path, int attrnamespace,
3545 // const char *attrname);
3546 PRE(sys_extattr_delete_file)
3548 PRINT("sys_extattr_delete_file ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3);
3549 PRE_REG_READ3(ssize_t, "extattr_delete_file",
3550 const char *, path, int, attrnamespace, const char *, attrname);
3551 PRE_MEM_RASCIIZ("extattr_delete_file(path)", ARG1);
3552 PRE_MEM_RASCIIZ("extattr_delete_file(attrname)", ARG3);
3555 // SYS_aio_waitcomplete 359
3556 // ssize_t aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout);
3557 PRE(sys_aio_waitcomplete)
3559 *flags |= SfMayBlock;
3560 PRINT("sys_aio_waitcomplete ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
3561 PRE_REG_READ2(ssize_t, "aio_waitcomplete", struct aiocb **, iocbp, struct timespec *, timeout);
3562 if (ARG2) {
3563 PRE_MEM_READ("aio_waitcomplete(timeout", ARG2, sizeof(struct vki_timespec));
3565 PRE_MEM_WRITE( "aio_waitcomplete(iocbp)", ARG1, sizeof(struct aiocb *));
3568 POST(sys_aio_waitcomplete)
3570 POST_MEM_WRITE(ARG1, sizeof(struct aiocb *));
3573 // SYS_getresuid 360
3574 // int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
3575 PRE(sys_getresuid)
3577 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
3578 PRE_REG_READ3(long, "getresuid",
3579 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
3580 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
3581 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
3582 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
3585 POST(sys_getresuid)
3587 vg_assert(SUCCESS);
3588 if (RES == 0) {
3589 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
3590 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
3591 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
3595 // SYS_getresgid 361
3596 // int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
3597 PRE(sys_getresgid)
3599 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
3600 PRE_REG_READ3(long, "getresgid",
3601 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
3602 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
3603 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
3604 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
3607 POST(sys_getresgid)
3609 vg_assert(SUCCESS);
3610 if (RES == 0) {
3611 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
3612 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
3613 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
3617 // SYS_kqueue 362
3618 // int kqueue(void);
3619 PRE(sys_kqueue)
3621 PRINT("%s", "sys_kqueue(void)");
3622 PRE_REG_READ0(int, "kqueue");
3625 POST(sys_kqueue)
3627 if (!ML_(fd_allowed)(RES, "kqueue", tid, True)) {
3628 VG_(close)(RES);
3629 SET_STATUS_Failure( VKI_EMFILE );
3630 } else {
3631 if (VG_(clo_track_fds)) {
3632 ML_(record_fd_open_nameless)(tid, RES);
3637 // SYS_freebsd11_kevent 363
3638 // int kevent(int kq, const struct kevent *changelist, int nchanges,
3639 // struct kevent *eventlist, int nevents,
3640 // const struct timespec *timeout);
3641 #if (FREEBSD_VERS >= FREEBSD_12)
3642 PRE(sys_freebsd11_kevent)
3644 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);
3645 PRE_REG_READ6(int, "kevent",
3646 int, fd, const struct vki_kevent_freebsd11 *, changelist, int, nchanges,
3647 struct vki_kevent_freebsd11 *, eventlist, int, nevents,
3648 struct timespec *, timeout);
3649 if (ARG2 != 0 && ARG3 != 0) {
3650 PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent_freebsd11)*ARG3 );
3652 if (ARG4 != 0 && ARG5 != 0) {
3653 PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent_freebsd11)*ARG5);
3655 if (ARG5 != 0) {
3656 *flags |= SfMayBlock;
3658 if (ARG6 != 0) {
3659 PRE_MEM_READ( "kevent(timeout)",
3660 ARG6, sizeof(struct vki_timespec));
3664 POST(sys_freebsd11_kevent)
3666 vg_assert(SUCCESS);
3667 if ((Word)RES != -1) {
3668 if (ARG4 != 0) {
3669 POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent_freebsd11)*RES) ;
3673 #else
3674 PRE(sys_kevent)
3676 *flags |= SfMayBlock;
3677 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);
3678 PRE_REG_READ6(int, "kevent",
3679 int, fd, struct vki_kevent_freebsd11 *, changelist, int, nchanges,
3680 struct vki_kevent_freebsd11 *, eventlist, int, nevents,
3681 struct timespec *, timeout);
3682 if (ARG2 != 0 && ARG3 != 0)
3683 PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent_freebsd11)*ARG3 );
3684 if (ARG4 != 0 && ARG5 != 0)
3685 PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent_freebsd11)*ARG5);
3686 if (ARG6 != 0)
3687 PRE_MEM_READ( "kevent(timeout)",
3688 ARG6, sizeof(struct vki_timespec));
3691 POST(sys_kevent)
3693 vg_assert(SUCCESS);
3694 if ((Word)RES != -1) {
3695 if (ARG4 != 0)
3696 POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent_freebsd11)*RES) ;
3699 #endif
3701 // SYS_extattr_set_fd 371
3702 // ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname,
3703 // const void *data, size_t nbytes);
3704 PRE(sys_extattr_set_fd)
3706 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);
3707 PRE_REG_READ5(int, "extattr_set_fd", int, fd, int, attrnamespace, const char *,attrname, const void *,data, size_t, nbytes);
3708 PRE_MEM_RASCIIZ( "extattr_set_fd(attrname)", ARG3 );
3709 PRE_MEM_READ("extattr_set_fd(data)", ARG4, ARG5);
3712 // SYS_extattr_get_fd 372
3713 // ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname,
3714 // void *data, size_t nbytes);
3715 PRE(sys_extattr_get_fd)
3717 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);
3718 PRE_REG_READ5(int, "extattr_get_fd", int, fd, int, attrnamespace, const char *,attrname, const void *,data, size_t, nbytes);
3719 PRE_MEM_RASCIIZ( "extattr_get_fd(attrname)", ARG3 );
3720 PRE_MEM_WRITE("extattr_get_fd(data)", ARG4, ARG5);
3723 POST(sys_extattr_get_fd)
3725 POST_MEM_WRITE(ARG4, ARG5);
3728 // SYS_extattr_delete_fd 373
3729 // int extattr_delete_fd(int fd, int attrnamespace, const char *attrname);
3730 PRE(sys_extattr_delete_fd)
3732 PRINT("sys_extattr_delete_fd ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3);
3733 PRE_REG_READ3(int, "extattr_delete_fd", int, fd, int, attrnamespace, const char *,attrname);
3734 PRE_MEM_RASCIIZ( "extattr_delete_fd(attrname)", ARG3 );
3737 // SYS___setugid 374
3738 // no manpage?
3739 // syscalls.master: int __setugid(int flag);
3740 PRE(sys___setugid)
3742 PRINT("sys___setugid ( %" FMT_REGWORD "d )", SARG1);
3743 PRE_REG_READ1(int, "__setugid", int, flag);
3746 // SYS_eaccess 376
3747 // int eaccess(const char *path, int mode);
3748 PRE(sys_eaccess)
3750 PRINT("sys_eaccess ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char*)ARG1,ARG2);
3751 PRE_REG_READ2(int, "eaccess", const char *, path, int, mode);
3752 PRE_MEM_RASCIIZ( "eaccess(path)", ARG1 );
3755 // SYS_afs3_syscall 377
3756 // @todo
3758 // SYS_nmount 378
3759 // int nmount(struct iovec *iov, u_int niov, int flags);
3760 PRE(sys_nmount)
3762 PRINT("sys_nmount ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d )", ARG1, ARG2, SARG3);
3763 PRE_REG_READ3(int, "nmount", struct iovec *, iov, u_int, niov, int, flags);
3764 PRE_MEM_READ( "nmount(pathname)", ARG1, ARG2*sizeof(struct vki_iovec) );
3767 // SYS___mac_get_proc 384
3768 // @todo
3770 // SYS___mac_set_proc 385
3771 // @todo
3773 // SYS___mac_get_fd 386
3774 // @todo
3776 // SYS___mac_get_file 387
3777 // @todo
3779 // SYS___mac_set_fd 388
3780 // @todo
3782 // SYS___mac_set_file 389
3783 // @todo
3785 // SYS_kenv 390
3786 // int kenv(int action, const char *name, char *value, int len);
3787 PRE(sys_kenv)
3789 PRINT("sys_kenv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3,ARG4);
3790 PRE_REG_READ4(int, "kenv",
3791 int, action, const char *, name, char *, value, int, len);
3792 switch (ARG1) {
3793 case VKI_KENV_GET:
3794 case VKI_KENV_SET:
3795 case VKI_KENV_UNSET:
3796 PRE_MEM_RASCIIZ("kenv(name)", ARG2);
3797 /* FALLTHROUGH */
3798 case VKI_KENV_DUMP:
3799 break;
3800 default:
3801 VG_(dmsg)("Warning: Bad action %" FMT_REGWORD "u in kenv\n", ARG1);
3805 POST(sys_kenv)
3807 if (SUCCESS) {
3808 switch (ARG1) {
3809 case VKI_KENV_GET:
3810 POST_MEM_WRITE(ARG3, ARG4);
3811 break;
3812 case VKI_KENV_DUMP:
3813 if (ARG3 != (Addr)NULL) {
3814 POST_MEM_WRITE(ARG3, ARG4);
3816 break;
3821 // SYS_lchflags 391
3822 // int lchflags(const char *path, unsigned long flags);
3823 PRE(sys_lchflags)
3825 PRINT("sys_lchflags ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2);
3826 PRE_REG_READ2(int, "lchflags",
3827 const char *, path, unsigned long, flags);
3828 PRE_MEM_RASCIIZ( "lchflags(path)", ARG1 );
3831 // SYS_uuidgen 392
3832 // int uuidgen(struct uuid *store, int count);
3833 PRE(sys_uuidgen)
3835 PRINT("sys_uuidgen ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2);
3836 PRE_REG_READ2(int, "uuidgen",
3837 struct vki_uuid *, store, int, count);
3838 PRE_MEM_WRITE( "uuidgen(store)", ARG1, ARG2 * sizeof(struct vki_uuid));
3841 POST(sys_uuidgen)
3843 if (SUCCESS) {
3844 POST_MEM_WRITE( ARG1, ARG2 * sizeof(struct vki_uuid) );
3848 // SYS_sendfile 393
3849 // x86/amd64
3851 // SYS_mac_syscall 394
3852 // @todo
3854 #if (FREEBSD_VERS >= FREEBSD_12)
3856 // SYS_freebsd11_getfsstat 395
3857 // int getfsstat(struct freebsd11_statfs *buf, long bufsize, int mode);
3859 PRE(sys_freebsd11_getfsstat)
3861 PRINT("sys_freebsd11_getfsstat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
3862 PRE_REG_READ3(int, "getfsstat", struct vki_freebsd11_statfs *, buf, long, bufsize, int, mode);
3863 PRE_MEM_WRITE( "getfsstat(buf)", ARG1, ARG2 );
3866 POST(sys_freebsd11_getfsstat)
3868 vg_assert(SUCCESS);
3869 if ((Word)RES != -1) {
3870 POST_MEM_WRITE( ARG1, RES * sizeof(struct vki_freebsd11_statfs) );
3874 // SYS_freebsd11_statfs 396
3875 // int statfs(const char *path, struct statfs *buf);
3876 PRE(sys_freebsd11_statfs)
3878 PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
3879 PRE_REG_READ2(int, "statfs", const char *, path, struct statfs *, buf);
3880 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
3881 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) );
3884 POST(sys_freebsd11_statfs)
3886 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3889 // SYS_freebsd11_fstatfs 397
3890 // int fstatfs(int fd, struct statfs *buf);
3891 PRE(sys_freebsd11_fstatfs)
3893 PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2);
3894 PRE_REG_READ2(int, "fstatfs",
3895 unsigned int, fd, struct statfs *, buf);
3896 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) );
3899 POST(sys_freebsd11_fstatfs)
3901 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3904 // SYS_freebsd11_fhstatfs 398
3905 // int fhstatfs(const fhandle_t *fhp, struct statfs *buf);
3906 PRE(sys_freebsd11_fhstatfs)
3908 PRINT("sys_fhstatfs ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
3909 PRE_REG_READ2(int, "fhstatfs",
3910 struct fhandle *, fhp, struct statfs *, buf);
3911 PRE_MEM_READ( "fhstatfs(fhp)", ARG1, sizeof(struct vki_fhandle) );
3912 PRE_MEM_WRITE( "fhstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) );
3915 POST(sys_freebsd11_fhstatfs)
3917 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3921 #else
3923 PRE(sys_getfsstat)
3925 PRINT("sys_getfsstat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
3926 PRE_REG_READ3(int, "getfsstat", struct vki_freebsd11_statfs *, buf, long, bufsize, int, mode);
3927 PRE_MEM_WRITE( "getfsstat(buf)", ARG1, ARG2 );
3930 POST(sys_getfsstat)
3932 vg_assert(SUCCESS);
3933 if ((Word)RES != -1) {
3934 POST_MEM_WRITE( ARG1, RES * sizeof(struct vki_freebsd11_statfs) );
3938 PRE(sys_statfs)
3940 PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
3941 PRE_REG_READ2(int, "statfs", const char *, path, struct statfs *, buf);
3942 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
3943 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) );
3946 POST(sys_statfs)
3948 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3951 PRE(sys_fstatfs)
3953 PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2);
3954 PRE_REG_READ2(int, "fstatfs",
3955 unsigned int, fd, struct statfs *, buf);
3956 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) );
3959 POST(sys_fstatfs)
3961 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3964 PRE(sys_fhstatfs)
3966 PRINT("sys_fhstatfs ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
3967 PRE_REG_READ2(int, "fhstatfs",
3968 struct fhandle *, fhp, struct statfs *, buf);
3969 PRE_MEM_READ( "fhstatfs(fhp)", ARG1, sizeof(struct vki_fhandle) );
3970 PRE_MEM_WRITE( "fhstatfs(buf)", ARG2, sizeof(struct vki_freebsd11_statfs) );
3973 POST(sys_fhstatfs)
3975 POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_statfs) );
3979 #endif
3981 // SYS_ksem_close 400
3982 // @todo
3984 // SYS_ksem_post 401
3985 // @todo
3987 // SYS_ksem_wait 402
3988 // @todo
3990 // SYS_ksem_trywait 403
3991 // @todo
3993 // SYS_ksem_init 404
3994 // @todo
3996 // SYS_ksem_open 405
3997 // @todo
3999 // SYS_ksem_unlink 406
4000 // @todo
4002 // SYS_ksem_getvalue 407
4003 // @todo
4005 // SYS_ksem_destroy 408
4006 // @todo
4008 // SYS___mac_get_pid 409
4009 // @todo
4011 // SYS___mac_get_link 410
4012 // @todo
4014 // SYS___mac_set_link 411
4015 // @todo
4017 // SYS_extattr_set_link 412
4018 // ssize_t extattr_set_link(const char *path, int attrnamespace,
4019 // const char *attrname, const void *data, size_t nbytes);
4020 PRE(sys_extattr_set_link)
4022 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);
4023 PRE_REG_READ5(ssize_t, "extattr_set_link",
4024 const char *, path, int, attrnamespace, const char *, attrname, const void *, data, size_t, nbytes);
4025 PRE_MEM_RASCIIZ("extattr_set_link(path)", ARG1);
4026 PRE_MEM_RASCIIZ("extattr_set_link(attrname)", ARG3);
4027 PRE_MEM_READ("extattr_set_link(data)", ARG4, ARG5);
4030 // SYS_extattr_get_link 413
4031 // ssize_t extattr_get_link(const char *path, int attrnamespace,
4032 // const char *attrname, void *data, size_t nbytes);
4033 PRE(sys_extattr_get_link)
4035 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);
4036 PRE_REG_READ5(ssize_t, "extattr_get_link",
4037 const char *, path, int, attrnamespace, const char *, attrname, void *, data, size_t, nbytes);
4038 PRE_MEM_RASCIIZ("extattr_get_link(path)", ARG1);
4039 PRE_MEM_RASCIIZ("extattr_get_link(attrname)", ARG3);
4040 if (ARG4) {
4041 PRE_MEM_WRITE("extattr_get_link(data)", ARG4, ARG5);
4045 POST(sys_extattr_get_link)
4047 if (ARG4) {
4048 POST_MEM_WRITE(ARG4, ARG5);
4052 // SYS_extattr_delete_link 414
4053 // int extattr_delete_link(const char *path, int attrnamespace,
4054 // const char *attrname);
4055 PRE(sys_extattr_delete_link)
4057 PRINT("sys_extattr_delete_link ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1,SARG2,ARG3);
4058 PRE_REG_READ3(ssize_t, "extattr_delete_link",
4059 const char *, path, int, attrnamespace, const char *, attrname);
4060 PRE_MEM_RASCIIZ("extattr_delete_link(path)", ARG1);
4061 PRE_MEM_RASCIIZ("extattr_delete_link(attrname)", ARG3);
4064 // SYS___mac_execve 415
4065 // @todo
4067 // SYS_sigaction 416
4068 //int sigaction(int sig, const struct sigaction * restrict act,
4069 // struct sigaction * restrict oact);
4070 PRE(sys_sigaction)
4072 vki_sigaction_toK_t new;
4073 vki_sigaction_toK_t *newp;
4074 vki_sigaction_fromK_t old;
4075 vki_sigaction_fromK_t *oldp;
4077 PRINT("sys_sigaction ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4078 SARG1,ARG2,ARG3);
4079 PRE_REG_READ3(long, "sigaction",
4080 int, sign, const struct sigaction *, act,
4081 struct sigaction *, oact);
4083 newp = oldp = NULL;
4085 if (ARG2 != 0) {
4086 struct vki_sigaction *sa = (struct vki_sigaction *)ARG2;
4087 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4088 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4089 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4092 if (ARG3 != 0) {
4093 PRE_MEM_WRITE( "sigaction(oact)", ARG3, sizeof(struct vki_sigaction));
4094 oldp = &old;
4097 if (ARG2 != 0
4098 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4099 sizeof(struct vki_sigaction))) {
4100 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4101 (void *)(Addr)ARG2);
4102 SET_STATUS_Failure ( VKI_EFAULT );
4103 } else if ((ARG3 != 0
4104 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4105 sizeof(struct vki_sigaction)))) {
4106 VG_(umsg)("Warning: bad oact handler address %p in sigaction()\n",
4107 (void *)(Addr)ARG3);
4108 SET_STATUS_Failure ( VKI_EFAULT );
4109 } else {
4110 if (ARG2 != 0) {
4111 struct vki_sigaction *oldnew =
4112 (struct vki_sigaction *)(Addr)ARG2;
4114 new.ksa_handler = oldnew->ksa_handler;
4115 new.sa_flags = oldnew->sa_flags;
4116 new.sa_mask = oldnew->sa_mask;
4117 newp = &new;
4120 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4122 if (ARG3 != 0 && SUCCESS && RES == 0) {
4123 struct vki_sigaction *oldold =
4124 (struct vki_sigaction *)(Addr)ARG3;
4126 oldold->ksa_handler = oldp->ksa_handler;
4127 oldold->sa_flags = oldp->sa_flags;
4128 oldold->sa_mask = oldp->sa_mask;
4133 POST(sys_sigaction)
4135 vg_assert(SUCCESS);
4136 if (RES == 0 && ARG3 != 0) {
4137 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
4141 // SYS_sigreturn 417
4142 // x86/amd64
4144 // SYS_getcontext 421
4145 // SYS_setcontext 422
4146 // SYS_swapcontext 423
4147 // PRE in x86/amd64
4149 POST(sys_getcontext)
4151 POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) );
4154 POST(sys_swapcontext)
4156 if (SUCCESS) {
4157 POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) );
4161 #if (FREEBSD_VERS >= FREEBSD_13_1)
4162 // SYS_freebsd13_swapoff 424
4163 // int swapoff(const char *special);
4164 PRE(sys_freebsd13_swapoff)
4166 PRINT("sys_freebsd13_swapoff ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1);
4167 PRE_REG_READ1(int, "swapoff", const char *, special);
4168 PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 );
4170 #else
4171 // SYS_swapoff 424
4172 // int swapoff(const char *special);
4173 PRE(sys_swapoff)
4175 PRINT("sys_swapoff ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1);
4176 PRE_REG_READ1(int, "swapoff", const char *, special);
4177 PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 );
4179 #endif
4181 // SYS___acl_get_link 425
4182 // int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp);
4183 PRE(sys___acl_get_link)
4185 PRINT("sys___acl_get_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3);
4186 PRE_REG_READ3(int, "__acl_get_link",
4187 const char *, path, int, acltype, struct vki_acl *, aclp);
4188 PRE_MEM_RASCIIZ( "__acl_get_link(path)", ARG1 );
4189 PRE_MEM_WRITE( "__acl_get_link(aclp)", ARG3, sizeof(struct vki_acl) );
4192 POST(sys___acl_get_link)
4194 vg_assert(SUCCESS);
4195 if (RES == 0) {
4196 POST_MEM_WRITE( ARG3, sizeof(struct vki_acl) );
4200 // SYS___acl_set_link 426
4201 // int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp);
4202 PRE(sys___acl_set_link)
4204 PRINT("sys___acl_set_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3);
4205 PRE_REG_READ3(int, "__acl_set_link",
4206 const char *, path, int, acltype, struct vki_acl *, aclp);
4207 PRE_MEM_RASCIIZ( "__acl_set_link(path)", ARG1 );
4208 PRE_MEM_READ( "__acl_set_link(aclp)", ARG3, sizeof(struct vki_acl) );
4210 // SYS___acl_delete_link 427
4211 // int __acl_delete_link(const char *path, acl_type_t type);
4212 PRE(sys___acl_delete_link)
4214 PRINT("sys___acl_delete_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1,ARG2);
4215 PRE_MEM_RASCIIZ( "__acl_delete_link(path)", ARG1 );
4216 PRE_REG_READ2(int, "__acl_delete_link",
4217 const char *, path, int, acltype);
4220 // SYS___acl_aclcheck_link 428
4221 // int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp);
4222 PRE(sys___acl_aclcheck_link)
4224 PRINT("sys___acl_aclcheck_link ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2,ARG3);
4225 PRE_REG_READ3(long, "__acl_aclcheck_link",
4226 const char *, path, int, acltype, struct vki_acl *, aclp);
4227 PRE_MEM_RASCIIZ( "__acl_check_link(path)", ARG1 );
4228 PRE_MEM_READ( "__acl_aclcheck_link(aclp)", ARG3, sizeof(struct vki_acl) );
4231 // SYS_sigwait 429
4232 // int sigwait(const sigset_t * restrict set, int * restrict sig);
4233 PRE(sys_sigwait)
4235 *flags |= SfMayBlock;
4236 PRINT("sys_sigwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4237 ARG1,ARG2);
4238 PRE_REG_READ2(int, "sigwait",
4239 const vki_sigset_t *, set, int *, sig);
4240 if (ARG1 != 0) {
4241 PRE_MEM_READ( "sigwait(set)", ARG1, sizeof(vki_sigset_t));
4243 if (ARG2 != 0) {
4244 PRE_MEM_WRITE( "sigwait(sig)", ARG2, sizeof(int));
4248 POST(sys_sigwait)
4250 if (ARG2 != 0) {
4251 POST_MEM_WRITE( ARG2, sizeof(int));
4255 // SYS_thr_create 430
4256 // no manpage?
4257 // syscalls.master: int thr_create(_In_ ucontext_t *ctx, _Out_ long *id, int flags );
4258 PRE(sys_thr_create)
4260 PRINT( "sys_thr_create ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )", ARG1, ARG2, SARG3 );
4261 PRE_REG_READ3(int, "thr_create", /*ucontext_t*/void *, ctx, long *, id, int, flags );
4263 VG_(message)(Vg_UserMsg, "thr_create() not implemented");
4264 VG_(unimplemented)("Valgrind does not support thr_create().");
4266 SET_STATUS_Failure(VKI_ENOSYS);
4269 // SYS_thr_exit 431
4270 // void thr_exit(long *state);
4271 PRE(sys_thr_exit)
4273 ThreadState *tst;
4275 PRINT( "sys_thr_exit ( %#" FMT_REGWORD "x )", ARG1 );
4276 PRE_REG_READ1(void, "thr_exit", long *, state);
4278 if (ARG1) {
4279 PRE_MEM_WRITE( "thr_exit(state)", ARG1, sizeof(long) );
4282 tst = VG_(get_ThreadState)(tid);
4283 tst->exitreason = VgSrc_ExitThread;
4284 tst->os_state.exitcode = ARG1;
4285 SET_STATUS_Success(0);
4288 // SYS_thr_self 432
4289 // int thr_self(long *id);
4290 PRE(sys_thr_self)
4292 PRINT( "sys_thr_self ( %#" FMT_REGWORD "x )", ARG1 );
4293 PRE_REG_READ1(int, "thr_self", long *, id);
4294 PRE_MEM_WRITE( "thr_self()", ARG1, sizeof(long));
4297 POST(sys_thr_self)
4299 POST_MEM_WRITE( ARG1, sizeof(long));
4302 // SYS_thr_kill 433
4303 // int thr_kill(long id, int sig);
4304 PRE(sys_thr_kill)
4306 PRINT("sys_thr_kill ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2);
4307 PRE_REG_READ2(long, "thr_kill", long, id, int, sig);
4308 if (!ML_(client_signal_OK)(ARG2)) {
4309 SET_STATUS_Failure( VKI_EINVAL );
4310 return;
4313 /* Check to see if this kill gave us a pending signal */
4314 *flags |= SfPollAfter;
4316 if (VG_(clo_trace_signals)) {
4317 VG_(message)(Vg_DebugMsg, "thr_kill: sending signal %lu to tid %lu\n",
4318 ARG2, ARG1);
4321 /* If we're sending SIGKILL, check to see if the target is one of
4322 our threads and handle it specially. */
4323 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
4324 SET_STATUS_Success(0);
4325 return;
4328 /* Ask to handle this syscall via the slow route, since that's the
4329 only one that sets tst->status to VgTs_WaitSys. If the result
4330 of doing the syscall is an immediate run of
4331 async_signalhandler() in m_signals, then we need the thread to
4332 be properly tidied away. I have the impression the previous
4333 version of this wrapper worked on x86/amd64 only because the
4334 kernel did not immediately deliver the async signal to this
4335 thread (on ppc it did, which broke the assertion re tst->status
4336 at the top of async_signalhandler()). */
4337 *flags |= SfMayBlock;
4340 POST(sys_thr_kill)
4342 if (VG_(clo_trace_signals)) {
4343 VG_(message)(Vg_DebugMsg, "thr_kill: sent signal %lu to tid %lu\n",
4344 ARG2, ARG1);
4348 #if (FREEBSD_VERS <= FREEBSD_10)
4349 // SYS__umtx_lock 434
4350 PRE(sys__umtx_lock)
4352 PRINT( "sys__umtx_lock ( %#" FMT_REGWORD "x )", ARG1);
4353 PRE_REG_READ1(long, "_umtx_lock", struct vki_umtx *, umtx);
4354 PRE_MEM_READ( "_umtx_lock(mtx)", ARG1, sizeof(struct vki_umtx) );
4355 PRE_MEM_WRITE( "_umtx_lock(mtx)", ARG1, sizeof(struct vki_umtx) );
4358 POST(sys__umtx_lock)
4360 if (SUCCESS) {
4361 POST_MEM_WRITE(ARG1, sizeof(struct vki_umtx));
4365 // SYS__umtx_unlock 434
4366 PRE(sys__umtx_unlock)
4368 PRINT( "sys__umtx_unlock ( %#" FMT_REGWORD "x )", ARG1);
4369 PRE_REG_READ1(long, "_umtx_unlock", struct vki_umtx *, umtx);
4370 PRE_MEM_READ( "_umtx_unlock(mtx)", ARG1, sizeof(struct vki_umtx) );
4371 PRE_MEM_WRITE( "_umtx_unlock(mtx)", ARG1, sizeof(struct vki_umtx) );
4374 POST(sys__umtx_unlock)
4376 if (SUCCESS) {
4377 POST_MEM_WRITE(ARG1, sizeof(struct vki_umtx));
4380 #endif
4382 // SYS_jail_attach 436
4383 // int jail_attach(int jid);
4384 PRE(sys_jail_attach)
4386 PRINT("sys_jail_attach ( %" FMT_REGWORD "d )", SARG1);
4387 PRE_REG_READ1(int, "jail_attach", int, jid);
4390 // SYS_extattr_list_fd 437
4391 // ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes);
4392 PRE(sys_extattr_list_fd)
4394 PRINT("extattr_list_fd ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, SARG2, ARG3, ARG4);
4395 PRE_REG_READ4(ssize_t, "extattr_list_fd", int, id, int, attrnamespace, void *,data, size_t, nbytes);
4396 PRE_MEM_WRITE("extattr_list_fd(data)", ARG3, ARG4);
4399 POST(sys_extattr_list_fd)
4401 POST_MEM_WRITE(ARG3, ARG4);
4404 // SYS_extattr_list_file 438
4405 // ssize_t extattr_list_file(const char *path, int attrnamespace, void *data,
4406 // size_t nbytes);
4407 PRE(sys_extattr_list_file)
4409 PRINT("extattr_list_file ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, SARG2, ARG3, ARG4);
4410 PRE_REG_READ4(ssize_t, "extattr_list_file", const char *, path, int, attrnamespace, void *,data, size_t, nbytes);
4411 PRE_MEM_RASCIIZ("extattr_list_file(path)", ARG1);
4412 PRE_MEM_WRITE("extattr_list_file(data)", ARG3, ARG4);
4415 POST(sys_extattr_list_file)
4417 POST_MEM_WRITE(ARG3, ARG4);
4420 // SYS_extattr_list_link 439
4421 // ssize_t extattr_get_link(const char *path, int attrnamespace,
4422 // const char *attrname, void *data, size_t nbytes);
4423 PRE(sys_extattr_list_link)
4425 PRINT("extattr_list_link ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, SARG2, ARG3, ARG4);
4426 PRE_REG_READ4(ssize_t, "extattr_list_link", const char *, path, int, attrnamespace, void *,data, size_t, nbytes);
4427 PRE_MEM_RASCIIZ("extattr_list_link(path)", ARG1);
4428 PRE_MEM_WRITE("extattr_list_link(data)", ARG3, ARG4);
4431 POST(sys_extattr_list_link)
4433 POST_MEM_WRITE(ARG3, ARG4);
4436 // SYS_ksem_timedwait 441
4437 // @todo
4439 // SYS_thr_suspend 442
4440 // int thr_suspend(struct timespec *timeout);
4441 PRE(sys_thr_suspend)
4443 PRINT("sys_thr_suspend ( %#" FMT_REGWORD "x )", ARG1);
4444 PRE_REG_READ1(int, "thr_suspend", struct timespec *, timeout);
4445 PRE_MEM_READ("thr_suspend(timeout)", ARG1, sizeof(struct vki_timespec));
4447 VG_(message)(Vg_UserMsg, "thr_supend() not implemented");
4448 VG_(unimplemented)("Valgrind does not support thr_suspend().");
4450 SET_STATUS_Failure(VKI_ENOSYS);
4453 // SYS_thr_wake 443
4454 // int thr_wake(long id);
4455 PRE(sys_thr_wake)
4457 PRINT("sys_thr_wake ( %" FMT_REGWORD "d )", SARG1);
4458 PRE_REG_READ1(long, "thr_wake", long, id);
4460 if (VG_(is_valid_tid)(ARG1)) {
4461 VG_(threads)[ARG1].status = VgTs_Runnable;
4462 } else {
4463 SET_STATUS_Failure( VKI_ESRCH );
4468 // SYS_kldunloadf 444
4469 // int kldunloadf(int fileid, int flags);
4470 PRE(sys_kldunloadf)
4472 PRINT("sys_kldunloadf ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1, SARG2);
4473 PRE_REG_READ2(int, "kldunloadf", int, fileid, int, flags);
4476 // SYS_audit 445
4477 // int audit(const char *record, u_int length);
4478 // @todo
4480 // SYS_auditon 446
4481 // int auditon(int cmd, void *data, u_int length);
4482 // @todo
4484 // SYS_getauid 447
4485 // int getauid(au_id_t *auid);
4486 // @todo
4488 // SYS_setauid 448
4489 // int setauid(au_id_t *auid);
4490 // @todo
4492 // SYS_getaudit 449
4493 // int getaudit(auditinfo_t *auditinfo);
4494 // @todo
4496 // SYS_setaudit 450
4497 // int setaudit(auditinfo_t *auditinfo);
4498 // @todo
4500 // SYS_getaudit_addr 451
4501 // int getaudit_addr(auditinfo_addr_t *auditinfo_addr, u_int length);
4502 // @todo
4504 // SYS_setaudit_addr 452
4505 // int setaudit_addr(auditinfo_addr_t *auditinfo_addr, u_int length);
4506 // @todo
4508 // SYS_auditctl 453
4509 // @todo
4511 // SYS__umtx_op 454
4512 // int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2);
4513 PRE(sys__umtx_op)
4515 /* 5 args are always passed through. The last two can vary, but
4516 they're always pointers. They may not be used though. */
4517 switch(ARG2) {
4518 case VKI_UMTX_OP_LOCK:
4519 // marked as COMPAT10
4520 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, LOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4521 PRE_REG_READ5(long, "_umtx_op_lock",
4522 struct umtx *, obj, int, op, unsigned long, id,
4523 size_t, timeout_size, struct vki_timespec *, timeout);
4524 PRE_MEM_READ( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) );
4525 if (ARG5) {
4526 PRE_MEM_READ( "_umtx_op_lock(timespec)", ARG5, ARG4 );
4528 PRE_MEM_WRITE( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) );
4529 *flags |= SfMayBlock;
4530 break;
4531 case VKI_UMTX_OP_UNLOCK:
4532 // marked as COMPAT10
4533 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, UNLOCK, %" FMT_REGWORD "u)", ARG1, ARG3);
4534 PRE_REG_READ3(long, "_umtx_op_unlock",
4535 struct umtx *, obj, int, op, unsigned long, id);
4536 PRE_MEM_READ( "_umtx_op_unlock(mtx)", ARG1, sizeof(struct vki_umtx) );
4537 PRE_MEM_WRITE( "_umtx_op_unlock(mtx)", ARG1, sizeof(struct vki_umtx) );
4538 break;
4539 case VKI_UMTX_OP_WAIT:
4540 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4541 PRE_REG_READ5(long, "_umtx_op_wait",
4542 long *, obj, int, op, unsigned long, val,
4543 size_t, timeout_size, struct vki_timespec *, timeout);
4544 if (ARG1) {
4545 PRE_MEM_READ( "_umtx_op_wait(val)", ARG1, sizeof(long) );
4546 if (*(long*)ARG1 == (long)ARG3) {
4547 *flags |= SfMayBlock;
4551 if (ARG5) {
4552 PRE_MEM_READ( "_umtx_op_wait(timeout)", ARG5, ARG4 );
4555 break;
4556 case VKI_UMTX_OP_WAKE:
4557 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, WAKE, %" FMT_REGWORD "u)", ARG1, ARG3);
4558 PRE_REG_READ3(long, "_umtx_op_wake",
4559 vki_uintptr_t *, obj, int, op, int, val);
4560 // PJF I don't think that the value of obj gets read, the address is being used as a key
4561 //PRE_MEM_READ("_umtx_op_wake(obj)", ARG1, sizeof(vki_uintptr_t));
4562 break;
4563 case VKI_UMTX_OP_MUTEX_TRYLOCK:
4564 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_TRYLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4565 PRE_REG_READ2(long, "_umtx_op_mutex_trylock", struct umutex *, obj, int, op);
4566 PRE_MEM_READ( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) );
4567 PRE_MEM_WRITE( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) );
4568 /* not too sure about the restart here
4569 * it's hard to test as if the mutex is locked this returns EBUSY
4570 * so there is only a small window where the syscall could be interrupted */
4571 *flags |= SfMayBlock | SfKernelRestart;
4572 break;
4573 case VKI_UMTX_OP_MUTEX_LOCK:
4574 // called by pthread_mutex_lock
4575 // when the atribute UMUTEX_PRIO_PROTECT or UMUTEX_PRIO_INHERIT is set
4576 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_LOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4577 PRE_REG_READ5(long, "_umtx_op_mutex_lock",
4578 struct umutex *, obj, int, op, unsigned long, noid,
4579 size_t, timeout_size, struct vki_timespec *, timeout);
4580 PRE_MEM_READ( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) );
4581 if (ARG5) {
4582 PRE_MEM_READ( "_umtx_op_mutex_lock(timespec)", ARG5, ARG4 );
4583 } else {
4584 *flags |= SfKernelRestart;
4586 PRE_MEM_WRITE( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) );
4587 *flags |= SfMayBlock;
4588 break;
4589 case VKI_UMTX_OP_MUTEX_UNLOCK:
4590 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_UNLOCK)", ARG1);
4591 PRE_REG_READ2(long, "_umtx_op_mutex_unlock",
4592 struct umutex *, obj, int, op);
4593 PRE_MEM_READ( "_umtx_op_mutex_unlock(mutex)", ARG1, sizeof(struct vki_umutex) );
4594 PRE_MEM_WRITE( "_umtx_op_mutex_unlock(mutex)", ARG1, sizeof(struct vki_umutex) );
4595 break;
4596 case VKI_UMTX_OP_SET_CEILING:
4597 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SET_CEILING, %" FMT_REGWORD "u, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4);
4598 PRE_REG_READ4(long, "_umtx_op_set_ceiling",
4599 struct umutex *, obj, int, op, unsigned int, ceiling,
4600 unsigned int *, old_ceiling);
4601 PRE_MEM_READ( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) );
4602 PRE_MEM_WRITE( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) );
4603 if (ARG4) {
4604 PRE_MEM_WRITE( "_umtx_op_set_ceiling(old_ceiling)", ARG4, sizeof(vki_uint32_t) );
4606 break;
4607 case VKI_UMTX_OP_CV_WAIT:
4608 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4609 PRE_REG_READ5(long, "_umtx_op_cv_wait",
4610 struct ucond *, obj, int, op, unsigned long, wflags,
4611 struct umutex *, umtx, struct vki_timespec *, timeout);
4612 PRE_MEM_READ( "_umtx_op_cv_wait(cond)", ARG1, sizeof(struct vki_ucond) );
4613 PRE_MEM_WRITE( "_umtx_op_cv_wait(cond)", ARG1, sizeof(struct vki_ucond) );
4614 PRE_MEM_READ( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) );
4615 PRE_MEM_WRITE( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) );
4616 if (ARG5) {
4617 PRE_MEM_READ( "_umtx_op_cv_wait(timespec)", ARG5, sizeof(struct vki_timespec) );
4619 *flags |= SfMayBlock;
4620 break;
4621 case VKI_UMTX_OP_CV_SIGNAL:
4622 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_SIGNAL)", ARG1);
4623 PRE_REG_READ2(long, "_umtx_op_cv_signal",
4624 struct ucond *, obj, int, op);
4625 PRE_MEM_READ( "_umtx_op_cv_signal(cond)", ARG1, sizeof(struct vki_ucond) );
4626 PRE_MEM_WRITE( "_umtx_op_cv_signal(cond)", ARG1, sizeof(struct vki_ucond) );
4627 break;
4628 case VKI_UMTX_OP_CV_BROADCAST:
4629 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_BROADCAST, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4630 PRE_REG_READ2(long, "_umtx_op_cv_broadcast",
4631 struct ucond *, obj, int, op);
4632 PRE_MEM_READ( "_umtx_op_cv_broadcast(cond)", ARG1, sizeof(struct vki_ucond) );
4633 PRE_MEM_WRITE( "_umtx_op_cv_broadcast(cond)", ARG1, sizeof(struct vki_ucond) );
4634 break;
4635 case VKI_UMTX_OP_WAIT_UINT:
4636 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT_UINT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4637 PRE_REG_READ5(long, "_umtx_op_wait_uint",
4638 int *, obj, int, op, unsigned long, id,
4639 size_t, timeout_wait, struct vki_timespec *, timeout);
4640 PRE_MEM_READ( "_umtx_op_wait(uint)", ARG1, sizeof(int) );
4641 if (ARG5) {
4642 PRE_MEM_READ( "_umtx_op_wait(timespec)", ARG5, ARG4 );
4644 *flags |= SfMayBlock;
4645 break;
4646 case VKI_UMTX_OP_RW_RDLOCK:
4647 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, RW_RDLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4648 PRE_REG_READ5(long, "_umtx_op_rw_rdlock",
4649 struct urwlock *, obj, int, op, unsigned long, noid,
4650 void *, zero, struct vki_timespec *, timeout);
4651 PRE_MEM_READ( "_umtx_op_rw_rdlock(rw)", ARG1, sizeof(struct vki_urwlock) );
4652 PRE_MEM_WRITE( "_umtx_op_rw_rdlock(rw)", ARG1, sizeof(struct vki_urwlock) );
4653 *flags |= SfMayBlock;
4654 break;
4655 case VKI_UMTX_OP_RW_WRLOCK:
4656 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, RW_WRLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4657 PRE_REG_READ5(long, "_umtx_op_rw_wrlock",
4658 struct urwlock *, obj, int, op, unsigned long, noid,
4659 void *, zero, struct vki_timespec *, timeout);
4660 PRE_MEM_READ( "_umtx_op_rw_wrlock(rw)", ARG1, sizeof(struct vki_urwlock) );
4661 PRE_MEM_WRITE( "_umtx_op_rw_wrlock(rw)", ARG1, sizeof(struct vki_urwlock) );
4662 *flags |= SfMayBlock;
4663 break;
4664 case VKI_UMTX_OP_RW_UNLOCK:
4665 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, RW_UNLOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4666 PRE_REG_READ2(long, "_umtx_op_rw_unlock",
4667 struct urwlock *, obj, int, op);
4668 PRE_MEM_READ( "_umtx_op_rw_unlock(rw)", ARG1, sizeof(struct vki_urwlock) );
4669 PRE_MEM_WRITE( "_umtx_op_rw_unlock(rw)", ARG1, sizeof(struct vki_urwlock) );
4670 break;
4671 case VKI_UMTX_OP_WAIT_UINT_PRIVATE:
4672 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT_UINT_PRIVATE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4673 PRE_REG_READ5(long, "_umtx_op_wait_uint_private",
4674 int *, obj, int, op, unsigned long, id,
4675 size_t, timeout_size, struct vki_timespec *, timeout);
4676 PRE_MEM_READ( "_umtx_op_wait_private(uint)", ARG1, sizeof(int) );
4677 if (ARG5) {
4678 PRE_MEM_READ( "_umtx_op_wait_private(umtx_time)", ARG5, ARG4 );
4680 *flags |= SfMayBlock;
4681 break;
4682 case VKI_UMTX_OP_WAKE_PRIVATE:
4683 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAKE_PRIVATE, %" FMT_REGWORD "u)", ARG1, ARG3);
4684 PRE_REG_READ3(long, "_umtx_op_wake_private",
4685 vki_uintptr_t *, obj, int, op, int, val);
4686 // PJF like OP_WAKE contents of obj not read
4687 //PRE_MEM_READ("_umtx_op_wake_private(obj)", ARG1, sizeof(vki_uintptr_t));
4688 break;
4689 case VKI_UMTX_OP_MUTEX_WAIT:
4690 // pthread_mutex_lock without prio flags
4691 // does not need to be restarted
4692 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4693 PRE_REG_READ2(long, "_umtx_op_mutex_wait",
4694 struct umutex *, obj, int, op);
4695 PRE_MEM_READ( "_umtx_op_mutex_wait(mutex)", ARG1, sizeof(struct vki_umutex) );
4696 PRE_MEM_WRITE( "_umtx_op_mutex_wait(mutex)", ARG1, sizeof(struct vki_umutex) );
4697 *flags |= SfMayBlock;
4698 break;
4699 case VKI_UMTX_OP_MUTEX_WAKE:
4700 // marked as deprecated
4701 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_WAKE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4702 PRE_REG_READ2(long, "_umtx_op_mutex_wake",
4703 struct umutex *, obj, int, op);
4704 PRE_MEM_READ( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) );
4705 PRE_MEM_WRITE( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) );
4706 break;
4707 case VKI_UMTX_OP_SEM_WAIT:
4708 // marked as deprecated
4709 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4710 PRE_REG_READ5(long, "_umtx_op_sem_wait",
4711 struct usem *, obj, int, op, unsigned long, id,
4712 size_t, timeout_size, struct vki_timespec *, timeout);
4713 PRE_MEM_READ( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) );
4714 PRE_MEM_WRITE( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) );
4715 if (ARG5) {
4716 PRE_MEM_READ( "_umtx_op_sem_wait(umtx_time)", ARG5, ARG4 );
4718 *flags |= SfMayBlock;
4719 break;
4720 case VKI_UMTX_OP_SEM_WAKE:
4721 // marked as deprecated
4722 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM_WAKE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4723 PRE_REG_READ2(long, "_umtx_op_sem_wake",
4724 struct umutex *, obj, int, op);
4725 PRE_MEM_READ( "_umtx_op_sem_wake(mutex)", ARG1, sizeof(struct vki_usem) );
4726 PRE_MEM_WRITE( "_umtx_op_sem_wake(mutex)", ARG1, sizeof(struct vki_usem) );
4727 break;
4728 case VKI_UMTX_OP_NWAKE_PRIVATE:
4729 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, NWAKE_PRIVATE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4730 PRE_REG_READ3(long, "_umtx_op_nwake_private",
4731 struct umutex *, obj, int, op, int, count);
4732 PRE_MEM_READ( "_umtx_op_nwake_private(mtxs)", ARG1, ARG3 * sizeof(void *) );
4733 PRE_MEM_WRITE( "_umtx_op_mutex_wake(mtxs)", ARG1, sizeof(struct vki_umutex) );
4734 break;
4735 case VKI_UMTX_OP_MUTEX_WAKE2:
4736 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_WAKE2, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4737 PRE_REG_READ3(long, "_umtx_op_mutex_wake2",
4738 struct umutex *, obj, int, op, unsigned long, flags);
4739 PRE_MEM_READ( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) );
4740 PRE_MEM_WRITE( "_umtx_op_mutex_wake(mutex)", ARG1, sizeof(struct vki_umutex) );
4741 break;
4742 case VKI_UMTX_OP_SEM2_WAIT:
4743 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM2_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4744 PRE_REG_READ3(long, "_umtx_op_sem2_wake",
4745 struct _usem2 *, obj, int, op, unsigned long, flags);
4746 PRE_MEM_READ( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) );
4747 PRE_MEM_WRITE( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) );
4748 *flags |= SfMayBlock;
4749 break;
4750 case VKI_UMTX_OP_SEM2_WAKE:
4751 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SEM2_WAKE, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4752 PRE_REG_READ3(long, "_umtx_op_sem2_wake",
4753 struct _usem2 *, obj, int, op, unsigned long, flags);
4754 PRE_MEM_READ( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) );
4755 PRE_MEM_WRITE( "_umtx_op_sem2_wait(mutex)", ARG1, sizeof(struct vki_usem2) );
4756 break;
4757 case VKI_UMTX_OP_SHM:
4758 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, SHM, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4759 PRE_REG_READ4(long, "_umtx_op_shm",
4760 void *, obj, int, op, unsigned long, val, void*, uaddr);
4761 break;
4762 case VKI_UMTX_OP_ROBUST_LISTS:
4763 // strangely the obj pointer ARG1 isn't used, for instance lin libc
4764 // libthr/thread/thr_mutex.c: _umtx_op(NULL, UMTX_OP_ROBUST_LISTS, sizeof(rb), &rb, NULL);
4765 // val (ARG3) ought to be the same as sizeof(struct vki_umtx_robust_lists_params)
4766 // strangely the kernel returns EINVAL if size is larger than sizeof(struct vki_umtx_robust_lists_params)
4767 // (which seems relatively harmless)
4768 // but not if it is smaller (definitely dangerous, probably an overrun)
4769 if (ARG3 < sizeof(struct vki_umtx_robust_lists_params)) {
4770 VG_(umsg)("WARNING: _umtx_op_tobust_lists size is smaller than sizeof(struct umtx_robust_lists_params).\n");
4772 PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, ROBUST_LISTS, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
4773 PRE_REG_READ4(long, "_umtx_op_robust_lists",
4774 void*, obj, int, op, unsigned long, val, struct umtx_robust_lists*, uaddr);
4775 PRE_MEM_READ( "_umtx_op_robust_lists(robust_lists)", ARG4, ARG3 );
4776 break;
4777 #if (FREEBSD_VERS >= FREEBSD_13_3)
4778 case VKI_UMTX_OP_GET_MIN_TIMEOUT:
4779 PRINT( "sys__umtx_op ( GET_MIN_TIMEOUT, %#" FMT_REGWORD "x)", ARG4);
4780 // bit of a pain just reads args 2 and 4
4781 if (VG_(tdict).track_pre_reg_read) {
4782 PRRSN;
4783 PRA2("_umtx_op_get_min_timeout",int,op);
4784 PRA4("_umtx_op_get_min_timeout",long int*,timeout);
4786 PRE_MEM_WRITE( "_umtx_op_get_min_timout(uaddr)", ARG4, sizeof(long int) );
4787 break;
4788 case VKI_UMTX_OP_SET_MIN_TIMEOUT:
4789 PRINT( "sys__umtx_op ( SET_MIN_TIMEOUT, %" FMT_REGWORD "u)", ARG3);
4790 // bit of a pain just reads args 2 and 3
4791 if (VG_(tdict).track_pre_reg_read) {
4792 PRRSN;
4793 PRA2("_umtx_op_set_min_timeout",int,op);
4794 PRA3("_umtx_op_set_min_timeout",unsigned long,timeout);
4796 break;
4797 #endif
4798 default:
4799 VG_(umsg)("WARNING: _umtx_op unsupported value.\n");
4800 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);
4801 break;
4805 POST(sys__umtx_op)
4807 switch(ARG2) {
4808 case VKI_UMTX_OP_LOCK:
4809 case VKI_UMTX_OP_UNLOCK:
4810 if (SUCCESS) {
4811 POST_MEM_WRITE( ARG1, sizeof(struct vki_umtx) );
4813 break;
4814 case VKI_UMTX_OP_WAIT:
4815 case VKI_UMTX_OP_WAKE:
4816 case VKI_UMTX_OP_WAIT_UINT:
4817 case VKI_UMTX_OP_WAIT_UINT_PRIVATE:
4818 case VKI_UMTX_OP_WAKE_PRIVATE:
4819 break;
4820 case VKI_UMTX_OP_MUTEX_TRYLOCK:
4821 case VKI_UMTX_OP_MUTEX_LOCK:
4822 case VKI_UMTX_OP_MUTEX_UNLOCK:
4823 case VKI_UMTX_OP_MUTEX_WAIT: /* Sets/clears contested bits */
4824 case VKI_UMTX_OP_MUTEX_WAKE: /* Sets/clears contested bits */
4825 if (SUCCESS) {
4826 POST_MEM_WRITE( ARG1, sizeof(vki_uintptr_t) );
4828 break;
4829 case VKI_UMTX_OP_SET_CEILING:
4830 if (SUCCESS) {
4831 POST_MEM_WRITE( ARG1, sizeof(struct vki_umutex) );
4832 if (ARG4) {
4833 POST_MEM_WRITE( ARG4, sizeof(vki_uint32_t) );
4836 break;
4837 case VKI_UMTX_OP_CV_WAIT:
4838 if (SUCCESS) {
4839 POST_MEM_WRITE( ARG1, sizeof(struct vki_ucond) );
4840 POST_MEM_WRITE( ARG4, sizeof(struct vki_umutex) );
4842 break;
4843 case VKI_UMTX_OP_CV_SIGNAL:
4844 case VKI_UMTX_OP_CV_BROADCAST:
4845 if (SUCCESS) {
4846 POST_MEM_WRITE( ARG1, sizeof(struct vki_ucond) );
4848 break;
4849 case VKI_UMTX_OP_RW_RDLOCK:
4850 case VKI_UMTX_OP_RW_WRLOCK:
4851 case VKI_UMTX_OP_RW_UNLOCK:
4852 if (SUCCESS) {
4853 POST_MEM_WRITE( ARG1, sizeof(struct vki_urwlock) );
4855 break;
4856 case VKI_UMTX_OP_SEM2_WAIT:
4857 case VKI_UMTX_OP_SEM2_WAKE:
4858 if (SUCCESS) {
4859 POST_MEM_WRITE( ARG1, sizeof(struct vki_usem2) );
4861 break;
4862 case VKI_UMTX_OP_SHM:
4863 if (SUCCESS && ARG3 == VKI_UMTX_SHM_CREAT) {
4864 if (VG_(clo_track_fds))
4865 ML_(record_fd_open_nameless) (tid, RES);
4867 break;
4868 case VKI_UMTX_OP_ROBUST_LISTS:
4869 break;
4870 #if (FREEBSD_VERS >= FREEBSD_13_3)
4871 case VKI_UMTX_OP_GET_MIN_TIMEOUT:
4872 POST_MEM_WRITE( ARG4, sizeof(long int) );
4873 break;
4874 case VKI_UMTX_OP_SET_MIN_TIMEOUT:
4875 break;
4876 #endif
4877 default:
4878 break;
4882 // SYS_thr_new 455
4883 // x86/amd64
4885 // SYS_sigqueue 456
4886 // int sigqueue(pid_t pid, int signo, const union sigval value);
4887 PRE(sys_sigqueue)
4889 PRINT("sys_sigqueue ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",
4890 SARG1,SARG2,ARG3);
4891 PRE_REG_READ3(int, "sigqueue", vki_pid_t, pid, int, signo, const union vki_sigval, value);
4894 // SYS_kmq_open 457
4895 // mqd_t mq_open(const char *name, int oflag, ...);
4896 // int kmq_open(_In_z_ const char *path, int flags, mode_t mode, _In_opt_ const struct mq_attr *attr);
4897 PRE(sys_kmq_open)
4899 if (ARG2 & VKI_O_CREAT) {
4900 PRINT("sys_kmq_open( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu, %#" FMT_REGWORD "x )",
4901 ARG1,(char *)ARG1,ARG2,(vki_mode_t)ARG3,ARG4);
4902 PRE_REG_READ4(long, "mq_open",
4903 const char *, name, int, oflag, vki_mode_t, mode,
4904 struct mq_attr *, attr);
4905 } else {
4906 PRINT("sys_kmq_open( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu)",
4907 ARG1,(char *)ARG1,ARG2,(vki_mode_t)ARG3);
4908 PRE_REG_READ3(long, "mq_open",
4909 const char *, name, int, oflag, vki_mode_t, mode);
4911 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
4912 if (ARG2 & VKI_O_CREAT) {
4913 PRE_MEM_READ("mq_open(attr)", ARG4, sizeof(struct vki_mq_attr));
4914 if (ML_(safe_to_deref)((struct vki_mq_attr *)ARG4, sizeof(struct vki_mq_attr))) {
4915 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
4916 PRE_MEM_READ("mq_open(attr->mq_maxmsg)",
4917 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
4918 PRE_MEM_READ("mq_open(attr->mq_msgsize)",
4919 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
4924 POST(sys_kmq_open)
4926 vg_assert(SUCCESS);
4927 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
4928 VG_(close)(RES);
4929 SET_STATUS_Failure( VKI_EMFILE );
4930 } else {
4931 if (VG_(clo_track_fds)) {
4932 ML_(record_fd_open_with_given_name)(tid, RES, (const HChar*)ARG1);
4937 // SYS_kmq_setattr 458
4938 // int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat,
4939 // struct mq_attr *restrict omqstat);
4940 PRE(sys_kmq_setattr)
4942 PRINT("sys_kmq_getattr( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3 );
4943 PRE_REG_READ3(int, "mq_setattr",
4944 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
4945 struct mq_attr *, omqstat);
4946 if (!ML_(fd_allowed)(ARG1, "mq_getattr", tid, False)) {
4947 SET_STATUS_Failure( VKI_EBADF );
4948 } else {
4949 if (ML_(safe_to_deref)((struct vki_mq_attr *)ARG2, sizeof(struct vki_mq_attr))) {
4950 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
4951 PRE_MEM_READ( "mq_setattr(mqstat->mq_flags)",
4952 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
4954 PRE_MEM_WRITE( "mq_setattr(omqstat)", ARG3,
4955 sizeof(struct vki_mq_attr) );
4959 // SYS_kmq_timedreceive 459
4960 // ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
4961 // unsigned *msg_prio, const struct timespec *abs_timeout);
4962 PRE(sys_kmq_timedreceive)
4964 *flags |= SfMayBlock;
4965 PRINT("sys_kmq_timedreceive( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4966 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
4967 PRE_REG_READ5(ssize_t, "mq_timedreceive",
4968 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
4969 unsigned int *, msg_prio,
4970 const struct timespec *, abs_timeout);
4971 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
4972 SET_STATUS_Failure( VKI_EBADF );
4973 } else {
4974 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
4975 if (ARG4 != 0) {
4976 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
4977 ARG4, sizeof(unsigned int) );
4979 if (ARG5 != 0) {
4980 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
4981 ARG5, sizeof(struct vki_timespec) );
4986 POST(sys_kmq_timedreceive)
4988 POST_MEM_WRITE( ARG2, ARG3 );
4989 if (ARG4 != 0) {
4990 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
4994 // SYS_kmq_timedsend 460
4995 // int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
4996 // unsigned msg_prio, const struct timespec *abs_timeout);
4997 PRE(sys_kmq_timedsend)
4999 *flags |= SfMayBlock;
5000 PRINT("sys_kmq_timedsend ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %llu, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5001 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
5002 PRE_REG_READ5(int, "mq_timedsend",
5003 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5004 unsigned int, msg_prio, const struct timespec *, abs_timeout);
5005 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
5006 SET_STATUS_Failure( VKI_EBADF );
5007 } else {
5008 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
5009 if (ARG5 != 0) {
5010 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
5011 sizeof(struct vki_timespec) );
5016 // SYS_kmq_notify 461
5017 // int mq_notify(mqd_t mqdes, const struct sigevent *notification);
5018 PRE(sys_kmq_notify)
5020 PRINT("sys_kmq_notify( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2 );
5021 PRE_REG_READ2(int, "mq_notify",
5022 vki_mqd_t, mqdes, const struct sigevent *, notification);
5023 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False)) {
5024 SET_STATUS_Failure( VKI_EBADF );
5026 else if (ARG2 != 0) {
5027 PRE_MEM_READ( "mq_notify(notification)",
5028 ARG2, sizeof(struct vki_sigevent) );
5032 // SYS_kmq_unlink 462
5033 // int kmq_unlink(const char *path);
5034 PRE(sys_kmq_unlink)
5036 PRINT("sys_kmq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char *)ARG1);
5037 PRE_REG_READ1(int, "mq_unlink", const char *, name);
5038 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
5041 // SYS_abort2 463
5042 // void abort2(const char *why, int nargs, void **args);
5043 PRE(sys_abort2)
5045 PRINT( "sys_abort2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", ARG1, SARG2, ARG3 );
5046 PRE_REG_READ3(void, "abort2", const char *, why, int, nargs, void **, args);
5047 // max length of 'why' is 128
5048 PRE_MEM_RASCIIZ( "abort2(why)", ARG2);
5049 // max val for nargs is 16
5050 PRE_MEM_READ("abort2(args", ARG3, ARG2*sizeof(void*));
5053 // SYS_thr_set_name 464
5054 // int thr_set_name(long id, const char *name);
5055 PRE(sys_thr_set_name)
5057 PRINT( "sys_thr_set_name ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2 );
5058 PRE_REG_READ2(int, "thr_set_name", long, id, const char *, name);
5059 PRE_MEM_RASCIIZ( "thr_set_name(name)", ARG2);
5061 if (ML_(safe_to_deref)((void*)ARG2, 1)) {
5062 const HChar* new_name = (const HChar*) (Addr)ARG2;
5063 ThreadState* tst = VG_(get_ThreadState)(tid);
5064 SizeT new_len = VG_(strnlen)(new_name, VKI_MAXCOMLEN+1);
5065 tst->thread_name = VG_(realloc)("syswrap.thr_set_name", tst->thread_name, new_len + 1);
5066 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
5070 // SYS_aio_fsync 465
5071 // int aio_fsync(int op, struct aiocb *iocb);
5072 PRE(sys_aio_fsync)
5074 PRINT("aio_fsync ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,ARG2);
5075 PRE_REG_READ2(int, "aio_fsync", int, op, struct vki_aiocb *, iocb);
5076 PRE_MEM_READ( "aio_fsync(iocb)", ARG2, sizeof(struct vki_aiocb) );
5079 // SYS_rtprio_thread 466
5080 // int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp);
5081 PRE(sys_rtprio_thread)
5083 PRINT( "sys_rtprio_thread ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3 );
5084 PRE_REG_READ3(int, "rtprio_thread",
5085 int, function, __vki_lwpid_t, lwpid, struct vki_rtprio *, rtp);
5086 if (ARG1 == VKI_RTP_SET) {
5087 PRE_MEM_READ( "rtprio_thread(rtp#set)", ARG3, sizeof(struct vki_rtprio));
5088 } else if (ARG1 == VKI_RTP_LOOKUP) {
5089 PRE_MEM_WRITE( "rtprio_thread(rtp#lookup)", ARG3, sizeof(struct vki_rtprio));
5090 } else {
5091 /* PHK ?? */
5095 POST(sys_rtprio_thread)
5097 if (ARG1 == VKI_RTP_LOOKUP && RES == 0) {
5098 POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio));
5102 // SYS_sctp_peeloff 471
5103 // int sctp_peeloff(int s, sctp_assoc_t id);
5104 // @todo
5107 // SYS_sctp_generic_sendmsg 472
5108 // int sctp_generic_sendmsg(int s, void *msg, int msglen, struct sockaddr *to,
5109 // socklen_t len, struct sctp_sndrcvinfo *sinfo, int flags);
5111 // Not called directly from libc
5112 PRE(sys_sctp_generic_sendmsg)
5114 *flags |= SfMayBlock;
5115 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);
5116 PRE_REG_READ7(ssize_t, "sctp_generic_sendmsg",
5117 int, s, void *, msg, int, msglen,
5118 struct sockaddr *, to, socklen_t, len,
5119 struct sctp_sndrcvinfo *, sinfo, int, flags);
5121 PRE_MEM_READ( "sctp_generic_sendmsg(msg)", ARG2, ARG3);
5123 ML_(pre_mem_read_sockaddr) (tid, "sctp_generic_sendmsg(to)", (struct vki_sockaddr *)ARG4, ARG5);
5125 if (ARG6 != (Addr)NULL) {
5126 PRE_MEM_READ( "sctp_generic_sendmsg(sinfo)", ARG6, sizeof(struct vki_sctp_sndrcvinfo));
5130 // SYS_sctp_generic_sendmsg_iov 473
5131 // int sctp_generic_sendmsg_iov(int s, struct iovec *iov, int iovlen,
5132 // struct sockaddr *to, struct sctp_sndrcvinfo *sinfo, int flags);
5133 // @todo
5135 // SYS_sctp_generic_recvmsg 474
5136 // int sctp_generic_recvmsg(int s, struct iovec *iov, int iovlen,
5137 // struct sockaddr *from, socklen_t *fromlen,
5138 // struct sctp_sndrcvinfo *sinfo, int *msgflags);
5140 // Not called directly from libc
5141 PRE(sys_sctp_generic_recvmsg)
5143 *flags |= SfMayBlock;
5144 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);
5145 PRE_REG_READ7(ssize_t, "sctp_generic_recvmsg",
5146 int, s, struct iovec *, iov, int, iovlen,
5147 struct sockaddr *, from, socklen_t *, fromlen,
5148 struct sctp_sndrcvinfo *, sinfo, int *, msgflags);
5150 // in the sctp_recvmsg libc wrapper this is always 1
5151 if ((Int)ARG3 > 0) {
5152 PRE_MEM_READ( "sctp_generic_recvmsg(iov)", ARG2, ARG3 * sizeof(struct vki_iovec) );
5154 if (ML_(safe_to_deref)((const void*)ARG2, ARG3 * sizeof(struct vki_iovec))) {
5155 struct vki_iovec* iovec = (struct vki_iovec*)ARG2;
5156 PRE_MEM_WRITE("sctp_generic_recvmsg(iov.iov_base)", (Addr)iovec->iov_base, iovec->iov_len);
5159 if (ARG4 != (Addr)NULL) {
5160 ML_(buf_and_len_pre_check) (tid, ARG4, ARG5,
5161 "sctp_generic_recvmsg(from)",
5162 "sctp_generic_recvmsg(fromlen_in)");
5165 if (ARG6 != (Addr)NULL) {
5166 PRE_MEM_WRITE("sctp_generic_recvmsg(sinfo)", ARG6, sizeof(struct vki_sctp_sndrcvinfo));
5169 if (ARG7 != (Addr)NULL) {
5170 PRE_MEM_WRITE("sctp_generic_recvmsg(msgflags)", ARG7, sizeof(int));
5174 POST(sys_sctp_generic_recvmsg)
5176 vg_assert(SUCCESS);
5177 struct vki_iovec* iovec = (struct vki_iovec*)ARG2;
5178 POST_MEM_WRITE((Addr)iovec->iov_base, iovec->iov_len);
5180 POST_MEM_WRITE( ARG2, ARG3*sizeof(struct vki_iovec) );
5182 if (ARG4 != (Addr)NULL) {
5183 ML_(buf_and_len_post_check) (tid, VG_(mk_SysRes_Success)(RES), ARG4, ARG5,
5184 "sctp_generic_recvmsg(fromlen_out)");
5187 if (ARG6 != (Addr)NULL) {
5188 POST_MEM_WRITE(ARG6, sizeof(struct vki_sctp_sndrcvinfo));
5191 if (ARG7 != (Addr)NULL) {
5192 POST_MEM_WRITE(ARG7, sizeof(int));
5196 // SYS_pread 475
5197 // x86/amd64
5199 // SYS_pwrite 476
5200 // x86/amd64
5202 // SYS_mmap 477
5203 // x86/amd64
5205 // SYS_lseek 478
5206 // x86/amd64
5208 //SYS_truncate 479
5209 // x86/amd64
5211 // SYS_ftruncate 480
5212 // x86/amd64
5214 // SYS_thr_kill2 481
5215 // int thr_kill2(pid_t pid, long id, int sig);
5216 PRE(sys_thr_kill2)
5218 PRINT("sys_thr_kill2 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3);
5219 PRE_REG_READ3(int, "thr_kill2", pid_t, pid, long, tid, int, sig);
5220 if (!ML_(client_signal_OK)(ARG3)) {
5221 SET_STATUS_Failure( VKI_EINVAL );
5222 return;
5225 /* Check to see if this kill gave us a pending signal */
5226 *flags |= SfPollAfter;
5228 if (VG_(clo_trace_signals)) {
5229 VG_(message)(Vg_DebugMsg, "thr_kill2: sending signal %lu to pid %lu/%lu\n",
5230 ARG3, ARG1, ARG2);
5233 /* If we're sending SIGKILL, check to see if the target is one of
5234 our threads and handle it specially. */
5235 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
5236 SET_STATUS_Success(0);
5237 return;
5240 /* Ask to handle this syscall via the slow route, since that's the
5241 only one that sets tst->status to VgTs_WaitSys. If the result
5242 of doing the syscall is an immediate run of
5243 async_signalhandler() in m_signals, then we need the thread to
5244 be properly tidied away. I have the impression the previous
5245 version of this wrapper worked on x86/amd64 only because the
5246 kernel did not immediately deliver the async signal to this
5247 thread (on ppc it did, which broke the assertion re tst->status
5248 at the top of async_signalhandler()). */
5249 *flags |= SfMayBlock;
5252 POST(sys_thr_kill2)
5254 if (VG_(clo_trace_signals)) {
5255 VG_(message)(Vg_DebugMsg, "thr_kill2: sent signal %lu to pid %lu/%lu\n",
5256 ARG3, ARG1, ARG2);
5260 // SYS_shm_open 482
5261 // int shm_open(const char *path, int flags, mode_t mode);
5262 PRE(sys_shm_open)
5264 PRE_REG_READ3(int, "shm_open",
5265 const char *, path, int, flags, vki_mode_t, mode);
5266 if (ARG1 == VKI_SHM_ANON) {
5267 PRINT("sys_shm_open(%#" FMT_REGWORD "x(SHM_ANON), %" FMT_REGWORD "u, %hu)", ARG1, ARG2, (vki_mode_t)ARG3);
5268 } else {
5269 PRINT("sys_shm_open(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu)", ARG1, (HChar *)ARG1, ARG2, (vki_mode_t)ARG3);
5270 PRE_MEM_RASCIIZ( "shm_open(path)", ARG1 );
5272 *flags |= SfMayBlock;
5275 POST(sys_shm_open)
5277 vg_assert(SUCCESS);
5278 if (!ML_(fd_allowed)(RES, "shm_open", tid, True)) {
5279 VG_(close)(RES);
5280 SET_STATUS_Failure( VKI_EMFILE );
5281 } else {
5282 if (VG_(clo_track_fds)) {
5283 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1);
5288 // SYS_shm_unlink 483
5289 // int shm_unlink(const char *path);
5290 PRE(sys_shm_unlink)
5292 PRINT("sys_shm_unlink(%#" FMT_REGWORD "x(%s))", ARG1, (char *)ARG1);
5293 PRE_REG_READ1(int, "shm_unlink",
5294 const char *, path);
5296 PRE_MEM_RASCIIZ( "shm_unlink(path)", ARG1 );
5298 *flags |= SfMayBlock;
5301 // SYS_cpuset 484
5302 // int cpuset(cpusetid_t *setid);
5303 PRE(sys_cpuset)
5305 PRINT("sys_cpuset ( %#" FMT_REGWORD "x )", ARG1);
5306 PRE_REG_READ1(int, "cpuset", vki_cpusetid_t *, setid);
5307 PRE_MEM_WRITE("cpuset(setid)", ARG1, sizeof(vki_cpusetid_t));
5310 POST(sys_cpuset)
5312 POST_MEM_WRITE(ARG1, sizeof(vki_cpusetid_t));
5315 // SYS_cpuset_setid 485
5316 // amd64 / x86
5318 // SYS_cpuset_getid 486
5319 // amd64 / x86
5321 // SYS_cpuset_getaffinity 487
5322 // amd64 / x86
5324 // SYS_cpuset_setaffinity 488
5325 // amd64 / x86
5327 // SYS_faccessat 489
5328 // int faccessat(int fd, const char *path, int mode, int flag);
5329 PRE(sys_faccessat)
5331 PRINT("sys_faccessat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3);
5332 PRE_REG_READ3(int, "faccessat",
5333 int, fd, const char *, path, int, flag);
5334 PRE_MEM_RASCIIZ( "faccessat(path)", ARG2 );
5337 // SYS_fchmodat 490
5338 // int fchmodat(int fd, const char *path, mode_t mode, int flag);
5339 PRE(sys_fchmodat)
5341 PRINT("sys_fchmodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3);
5342 PRE_REG_READ4(int, "fchmodat",
5343 int, fd, const char *, path, vki_mode_t, mode, int, flag);
5344 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5347 // SYS_fchownat 491
5348 // int fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag);
5349 PRE(sys_fchownat)
5351 PRINT("sys_fchownat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, %" FMT_REGWORD "d )",
5352 ARG1,ARG2,(char*)ARG2,ARG3,ARG4, SARG5);
5353 PRE_REG_READ5(int, "fchownat",
5354 int, fd, const char *, path,
5355 vki_uid_t, owner, vki_gid_t, group, int, flag);
5356 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5359 // SYS_fexecve 492
5360 // int fexecve(int fd, char *const argv[], char *const envp[]);
5361 PRE(sys_fexecve)
5363 PRINT("sys_fexecve ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5364 SARG1,ARG2,ARG3);
5365 PRE_REG_READ3(int, "fexecve",
5366 int, fd, char * const *, argv,
5367 char * const *, envp);
5369 if (!ML_(fd_allowed)(ARG1, "fexecve", tid, False)) {
5370 SET_STATUS_Failure(VKI_EBADF);
5371 return;
5374 const HChar *fname;
5376 if (VG_(resolve_filename)(ARG1, &fname) == False) {
5377 SET_STATUS_Failure(VKI_ENOENT);
5378 return;
5381 struct vg_stat stats;
5382 if (VG_(fstat)(ARG1, &stats) != 0) {
5383 SET_STATUS_Failure(VKI_EACCES);
5384 return;
5387 Int openFlags;
5389 if (VG_(resolve_filemode)(ARG1, &openFlags) == False) {
5390 SET_STATUS_Failure(VKI_ENOENT);
5391 return;
5395 * openFlags is in kernel FFLAGS format
5396 * (see /usr/include/sys/fcntl.h)
5397 * which alllows us to tell if RDONLY is set
5401 Bool isScript = False;
5403 SysRes res;
5404 res = VG_(open)(fname, VKI_O_RDONLY,
5405 VKI_S_IRUSR|VKI_S_IRGRP|VKI_S_IROTH);
5406 if (sr_isError(res)) {
5407 SET_STATUS_Failure(VKI_ENOENT);
5408 return;
5411 char buf[2];
5412 VG_(read)((Int)sr_Res(res), buf, 2);
5413 VG_(close)((Int)sr_Res(res));
5414 if (buf[0] == '#' && buf[1] == '!') {
5415 isScript = True;
5418 if (isScript) {
5419 if (!(openFlags & VKI_FREAD)) {
5420 SET_STATUS_Failure(VKI_EACCES);
5421 return;
5423 } else {
5424 if (!((openFlags & VKI_O_EXEC) ||
5425 (stats.mode & (VKI_S_IXUSR|VKI_S_IXGRP|VKI_S_IXOTH)))) {
5426 SET_STATUS_Failure(VKI_EACCES);
5427 return;
5431 Addr arg_2 = (Addr)ARG2;
5432 Addr arg_3 = (Addr)ARG3;
5434 handle_pre_sys_execve(tid, status, (Addr)fname, arg_2, arg_3, FEXECVE, False);
5437 // SYS_freebsd11_fstatat 493
5438 // int fstatat(int fd, const char *path, struct stat *sb, int flag);
5439 #if (FREEBSD_VERS >= FREEBSD_12)
5440 PRE(sys_freebsd11_fstatat)
5442 PRINT("sys_freebsd11_fstatat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3);
5443 PRE_REG_READ4(int, "fstatat",
5444 int, fd, const char *, path, struct freebsd11_stat *, buf, int, flag);
5445 PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 );
5446 PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_freebsd11_stat) );
5449 POST(sys_freebsd11_fstatat)
5451 POST_MEM_WRITE( ARG3, sizeof(struct vki_freebsd11_stat) );
5453 #else
5454 PRE(sys_fstatat)
5456 PRINT("sys_fstatat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3);
5457 PRE_REG_READ4(int, "fstatat",
5458 int, fd, const char *, path, struct stat *, buf, int, flag);
5459 PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 );
5460 PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_freebsd11_stat) );
5463 POST(sys_fstatat)
5465 POST_MEM_WRITE( ARG3, sizeof(struct vki_freebsd11_stat) );
5467 #endif
5469 // SYS_futimesat 494
5470 // int futimesat(int fd, const char *path, const struct timeval times[2]);
5471 PRE(sys_futimesat)
5473 PRINT("sys_futimesat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3);
5474 PRE_REG_READ3(int, "futimesat",
5475 int, fd, const char *, path, struct timeval *, times);
5476 if (ARG2 != 0) {
5477 PRE_MEM_RASCIIZ( "futimesat(path)", ARG2 );
5479 if (ARG3 != 0) {
5480 PRE_MEM_READ( "futimesat(times)", ARG3, 2 * sizeof(struct vki_timeval) );
5484 // SYS_linkat 495
5485 // int linkat(int fd1, const char *name1, int fd2, const char *name2, int flag);
5486 PRE(sys_linkat)
5488 *flags |= SfMayBlock;
5489 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);
5490 PRE_REG_READ5(int, "linkat",
5491 int, fd1, const char *, name1,
5492 int, fd2, const char *, name2,
5493 int, flag);
5494 PRE_MEM_RASCIIZ( "linkat(name1)", ARG2);
5495 PRE_MEM_RASCIIZ( "linkat(name2)", ARG4);
5498 // SYS_mkdirat 496
5499 // int mkdirat(int fd, const char *path, mode_t mode);
5500 PRE(sys_mkdirat)
5502 *flags |= SfMayBlock;
5503 PRINT("sys_mkdirat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3);
5504 PRE_REG_READ3(int, "mkdirat",
5505 int, fd, const char *, path, unsigned int, mode);
5506 PRE_MEM_RASCIIZ( "mkdirat(path)", ARG2 );
5509 // SYS_mkfifoat 497
5510 // int mkfifoat(int fd, const char *path, mode_t mode);
5511 PRE(sys_mkfifoat)
5513 PRINT("sys_mkfifoat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )",
5514 SARG1,ARG2,(HChar*)ARG2,ARG3 );
5515 PRE_REG_READ3(int, "mkfifoat",
5516 int, fd, const char *, path, vki_mode_t, mode);
5517 PRE_MEM_RASCIIZ( "mkfifoat(path)", ARG2 );
5520 // SYS_freebsd11_mknodat 498
5521 // int mknodat(int fd, const char *path, mode_t mode, dev_t dev);
5522 #if (FREEBSD_VERS >= FREEBSD_12)
5523 PRE(sys_freebsd11_mknodat)
5525 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 );
5526 PRE_REG_READ4(long, "mknodat",
5527 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5528 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5530 #else
5531 PRE(sys_mknodat)
5533 PRINT("sys_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 );
5534 PRE_REG_READ4(long, "mknodat",
5535 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5536 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5538 #endif
5540 // SYS_openat 499
5541 // int openat(int fd, const char *path, int flags, ...);
5542 PRE(sys_openat)
5544 if (ARG3 & VKI_O_CREAT) {
5545 // 4-arg version
5546 PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
5547 PRE_REG_READ4(int, "openat",
5548 int, fd, const char *, path, int, flags, vki_mode_t, mode);
5549 } else {
5550 // 3-arg version
5551 PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3);
5552 PRE_REG_READ3(int, "openat",
5553 int, fd, const char *, path, int, flags);
5556 if (ARG1 != (unsigned)VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat", tid, False)) {
5557 SET_STATUS_Failure( VKI_EBADF );
5558 } else {
5559 PRE_MEM_RASCIIZ( "openat(path)", ARG2 );
5562 /* Otherwise handle normally */
5563 *flags |= SfMayBlock;
5566 POST(sys_openat)
5568 vg_assert(SUCCESS);
5569 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5570 VG_(close)(RES);
5571 SET_STATUS_Failure( VKI_EMFILE );
5572 } else {
5573 if (VG_(clo_track_fds)) {
5574 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
5579 // SYS_readlinkat 500
5580 // ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf,
5581 // size_t bufsize);
5582 PRE(sys_readlinkat)
5584 Word saved = SYSNO;
5585 Bool curproc_file = False;
5587 PRINT("sys_readlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4);
5588 PRE_REG_READ4(ssize_t, "readlinkat",
5589 int, fd, const char *, path, char *, buf, int, bufsize);
5590 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5591 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5593 if (VG_(have_slash_proc) == True && (Int)ARG1 == VKI_AT_FDCWD) {
5595 * Handle the case where readlinkat is looking at /proc/curproc/file or
5596 * /proc/<pid>/file.
5598 do_readlink((const HChar *)ARG2, (HChar *)ARG3, (SizeT)ARG4, status, &curproc_file);
5601 // @todo PJF there is still the case where fd refers to /proc or /proc/pid
5602 // or /proc/curproc and path is relative pid/file, curptoc/file or just file
5604 if (!curproc_file) {
5605 /* Normal case */
5606 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5608 if (SUCCESS && RES > 0) {
5609 POST_MEM_WRITE( ARG3, RES );
5613 POST(sys_readlinkat)
5615 POST_MEM_WRITE( ARG3, RES );
5618 // SYS_renameat 501
5619 // int renameat(int fromfd, const char *from, int tofd, const char *to);
5620 PRE(sys_renameat)
5622 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);
5623 PRE_REG_READ4(int, "renameat",
5624 int, fromfd, const char *, from,
5625 int, tofd, const char *, to);
5626 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5627 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5630 // SYS_symlinkat 502
5631 // int symlinkat(const char *name1, int fd, const char *name2);
5632 PRE(sys_symlinkat)
5634 *flags |= SfMayBlock;
5635 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s) )",ARG1,(char*)ARG1,ARG2,ARG3,(char*)ARG3);
5636 PRE_REG_READ3(int, "symlinkat",
5637 const char *, name1, int, fd, const char *, name2);
5638 PRE_MEM_RASCIIZ( "symlinkat(name1)", ARG1 );
5639 PRE_MEM_RASCIIZ( "symlinkat(name2)", ARG3 );
5642 // SYS_unlinkat 503
5643 // int unlinkat(int fd, const char *path, int flag);
5644 PRE(sys_unlinkat)
5646 *flags |= SfMayBlock;
5647 PRINT("sys_unlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u ",
5648 ARG1, ARG2, (char*)ARG2, ARG3);
5649 PRE_REG_READ3(int, "unlinkat", int, fd, const char *, path, int, flag);
5650 PRE_MEM_RASCIIZ( "unlinkat(path)", ARG2 );
5653 // SYS_posix_openpt 504
5654 // int posix_openpt(int oflag);
5655 PRE(sys_posix_openpt)
5657 PRINT("sys_posix_openpt ( %" FMT_REGWORD "d )", SARG1);
5658 PRE_REG_READ1(int, "posix_openpt", int, oflag);
5661 // SYS_gssd_syscall 505
5662 // @todo
5663 // see https://www.freebsd.org/cgi/man.cgi?format=html&query=gssapi(3)
5664 // syscalls.master says ; 505 is initialised by the kgssapi code, if present.
5666 // SYS_jail_get 506
5667 // int jail_get(struct iovec *iov, u_int niov, int flags);
5668 PRE(sys_jail_get)
5670 PRINT("sys_jail_get ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
5671 PRE_REG_READ3(int, "jail_get", struct vki_iovec *, iov, unsigned int,
5672 niov, int, flags);
5673 PRE_MEM_READ("jail_get(iov)", ARG1, ARG2 * sizeof(struct vki_iovec));
5676 // SYS_jail_set 507
5677 // int jail_set(struct iovec *iov, u_int niov, int flags);
5678 PRE(sys_jail_set)
5680 PRINT("sys_jail_set ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
5681 PRE_REG_READ3(int, "jail_set", struct vki_iovec *, iov, unsigned int,
5682 niov, int, flags);
5683 PRE_MEM_READ("jail_set(iovs)", ARG1, ARG2 * sizeof(struct vki_iovec));
5686 // SYS_jail_remove 508
5687 // int jail_remove(int jid);
5688 PRE(sys_jail_remove)
5690 PRINT("sys_jail_remove ( %" FMT_REGWORD "d )", SARG1);
5691 PRE_REG_READ1(int, "jail_remove", int, jid);
5694 // SYS_closefrom 509
5695 // void closefrom(int lowfd);
5696 PRE(sys_closefrom)
5698 PRINT("sys_closefrom ( %" FMT_REGWORD "dx )", SARG1);
5699 PRE_REG_READ1(int, "closefrom", int, lowfd);
5702 * Can't pass this on to the kernel otherwise it will close
5703 * all of the host files like the log
5706 for (int fd = ARG1; fd < VG_(fd_hard_limit); ++fd) {
5707 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
5708 && fd != VG_(log_output_sink).fd
5709 && fd != VG_(xml_output_sink).fd)
5710 VG_(close)(fd);
5713 SET_STATUS_Success(0);
5716 POST(sys_closefrom)
5718 unsigned int fd;
5719 unsigned int last = VG_(fd_hard_limit);
5721 if (!VG_(clo_track_fds))
5722 return;
5724 for (fd = ARG1; fd <= last; fd++)
5725 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
5726 && fd != VG_(log_output_sink).fd
5727 && fd != VG_(xml_output_sink).fd)
5728 ML_(record_fd_close)(tid, fd);
5731 // SYS___semctl 510
5732 // int semctl(int semid, int semnum, int cmd, ...);
5733 // int __semctl(int semid, int semnum, int cmd, _Inout_ union semun *arg);
5734 PRE(sys___semctl)
5736 union vki_semun* semun;
5738 switch (ARG3) {
5739 case VKI_IPC_STAT:
5740 case VKI_SEM_STAT:
5741 case VKI_IPC_SET:
5742 case VKI_GETALL:
5743 case VKI_SETALL:
5744 PRINT("sys___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
5745 PRE_REG_READ4(long, "semctl",
5746 int, semid, int, semnum, int, cmd, union vki_semun *, arg);
5747 PRE_MEM_READ("sys___sysctl(arg)", ARG4, sizeof(union vki_semun));
5748 semun = (union vki_semun*)ARG4;
5749 if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
5750 ARG4 = (RegWord)semun;
5751 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
5753 break;
5754 default:
5755 PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
5756 PRE_REG_READ3(long, "semctl",
5757 int, semid, int, semnum, int, cmd);
5758 break;
5762 POST(sys___semctl)
5764 union vki_semun* semun = (union vki_semun*)ARG4;
5765 if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
5766 ARG4 = (RegWord)semun;
5767 ML_(generic_POST_sys_semctl)(tid, RES, ARG1,ARG2,ARG3,ARG4);
5771 // SYS_msgctl 511
5772 // int msgctl(int msqid, int cmd, struct msqid_ds *buf);
5773 PRE(sys_msgctl)
5775 PRINT("sys_msgctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1,SARG2,ARG3 );
5777 PRE_REG_READ3(int, "msgctl", int, msqid, int, cmd, struct msqid_ds *, buf);
5779 switch (ARG2 /* cmd */) {
5780 case VKI_IPC_STAT:
5781 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
5782 ARG3, sizeof(struct vki_msqid_ds) );
5783 break;
5784 case VKI_IPC_SET:
5785 PRE_MEM_READ( "msgctl(IPC_SET, buf)",
5786 ARG3, sizeof(struct vki_msqid_ds) );
5787 break;
5791 POST(sys_msgctl)
5793 switch (ARG2 /* cmd */) {
5794 case VKI_IPC_STAT:
5795 POST_MEM_WRITE( ARG3, sizeof(struct vki_msqid_ds) );
5796 break;
5801 // SYS_shmctl 512
5802 // int shmctl(int shmid, int cmd, struct shmid_ds *buf);
5803 PRE(sys_shmctl)
5805 PRINT("sys_shmctl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,SARG2,ARG3);
5806 PRE_REG_READ3(int, "shmctl",
5807 int, shmid, int, cmd, struct vki_shmid_ds *, buf);
5808 switch (ARG2 /* cmd */) {
5809 case VKI_IPC_STAT:
5810 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
5811 ARG3, sizeof(struct vki_shmid_ds) );
5812 break;
5813 case VKI_IPC_SET:
5814 PRE_MEM_READ( "shmctl(IPC_SET, buf)",
5815 ARG3, sizeof(struct vki_shmid_ds) );
5816 break;
5820 POST(sys_shmctl)
5822 if (ARG2 == VKI_IPC_STAT) {
5823 POST_MEM_WRITE( ARG3, sizeof(struct vki_shmid_ds) );
5827 // SYS_lpathconf 513
5828 // long lpathconf(const char *path, int name);
5829 PRE(sys_lpathconf)
5831 PRINT("sys_lpathconf ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d)", ARG1, SARG2);
5832 PRE_REG_READ2(long, "lpathconf", const char *, path, int, name);
5833 PRE_MEM_RASCIIZ("lpathconf(path)", ARG1);
5836 // SYS___cap_rights_get 515
5837 // note extra 1st argument for the internal function which is not present
5838 // in the public interface
5839 // int __cap_rights_get(int version, int fd, cap_rights_t *rights);
5840 PRE(sys_cap_rights_get)
5842 PRINT("sys_cap_rights_get ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5843 PRE_REG_READ3(long, "cap_rights_get", int, version, int, fd, vki_cap_rights_t*, rights);
5844 PRE_MEM_WRITE("cap_rights_get(rights)", ARG3, sizeof(vki_cap_rights_t));
5847 POST(sys_cap_rights_get)
5849 POST_MEM_WRITE(ARG2, sizeof(vki_cap_rights_t));
5852 // SYS_cap_enter 516
5853 // int cap_enter(void);
5854 PRE(sys_cap_enter)
5856 PRINT("%s", "sys_cap_enter ( )");
5857 PRE_REG_READ0(int, "cap_enter");
5858 static Bool warning_given = False;
5859 if (!warning_given) {
5860 warning_given = True;
5861 capabiltyMode = True;
5862 VG_(umsg)(
5863 "WARNING: Valgrind may not operate correctly in capability mode.\n"
5864 " Please consider disabling capability by using the RUNNING_ON_VALGRIND mechanism.\n"
5865 " See http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq\n");
5867 /* now complete loading debuginfo since it is not allowed after entering cap mode */
5868 VG_(load_all_debuginfo)();
5871 // SYS_cap_getmode 517
5872 // int cap_getmode(u_int *modep);
5873 PRE(sys_cap_getmode)
5875 PRINT("sys_cap_getmode ( %#" FMT_REGWORD "x )", ARG1);
5876 PRE_REG_READ1(int, "cap_getmode", u_int*, modep);
5877 PRE_MEM_WRITE("cap_getmode(modep)", ARG1, sizeof(u_int));
5880 POST(sys_cap_getmode)
5882 POST_MEM_WRITE(ARG1, sizeof(u_int));
5885 static vki_sigset_t pdfork_saved_mask;
5887 // SYS_pdfork 518
5888 // pid_t pdfork(int *fdp, int flags);
5889 PRE(sys_pdfork)
5891 Bool is_child;
5892 Int child_pid;
5893 vki_sigset_t mask;
5895 PRINT("sys_pdfork ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
5896 PRE_REG_READ2(pid_t, "pdfork", int*, fdp, int, flags);
5898 /* Block all signals during fork, so that we can fix things up in
5899 the child without being interrupted. */
5900 VG_(sigfillset)(&mask);
5901 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &pdfork_saved_mask);
5903 VG_(do_atfork_pre)(tid);
5905 SET_STATUS_from_SysRes( VG_(do_syscall2)(__NR_pdfork, ARG1, ARG2) );
5907 if (!SUCCESS) {
5908 return;
5911 // RES is 0 for child, non-0 (the child's PID) for parent.
5912 is_child = ( RES == 0 ? True : False );
5913 child_pid = ( is_child ? -1 : (Int)RES );
5915 if (is_child) {
5916 VG_(do_atfork_child)(tid);
5918 /* restore signal mask */
5919 VG_(sigprocmask)(VKI_SIG_SETMASK, &pdfork_saved_mask, NULL);
5920 } else {
5921 VG_(do_atfork_parent)(tid);
5923 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), child_pid);
5925 /* restore signal mask */
5926 VG_(sigprocmask)(VKI_SIG_SETMASK, &pdfork_saved_mask, NULL);
5929 if (ARG1) {
5930 PRE_MEM_WRITE( "pdfork(fdp)", ARG1, sizeof(int) );
5934 POST(sys_pdfork)
5936 if (ARG1) {
5937 POST_MEM_WRITE( ARG1, sizeof(int) );
5941 // pdkill 519
5942 //int pdkill(int fd, int signum)
5943 PRE(sys_pdkill)
5945 PRINT("sys_pdkill ( %" FMT_REGWORD "u, %" FMT_REGWORD "d )", ARG1, SARG2);
5946 PRE_REG_READ2(int, "pdkill", int, fd, int, signum);
5948 if (!ML_(client_signal_OK)(ARG2)) {
5949 SET_STATUS_Failure( VKI_EINVAL );
5950 return;
5953 /* Ther was some code here to check if the kill is to this process
5955 * But it was totally wrong
5957 * It was calling ML_(do_sigkill)(Int pid, Int tgid)
5959 * With a file descriptor
5961 * Fortunately this will never match a real process otherwise
5962 * it might have accidentally killed us.
5964 * For a start we need the pid, obtained with pdgetpid
5965 * Next ML_(do_sigkill) doesn't map to FreeBSD. It takes a
5966 * pid (lwpid) and a tgid (threadgroup)
5968 * On FreeBSD lwpid is the tid and threadgroup is the pid
5969 * The kill functions operate on pids, not tids.
5971 * One last thing, I don't see how pdkill could do a self
5972 * kill 9. It neads an fd which implied pdfork whichimplies
5973 * that the fd/pid are for a child process
5976 SET_STATUS_from_SysRes(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
5978 if (VG_(clo_trace_signals)) {
5979 VG_(message)(Vg_DebugMsg, "pdkill: sent signal %ld to fd %ld\n",
5980 SARG2, SARG1);
5983 /* This kill might have given us a pending signal. Ask for a check once
5984 the syscall is done. */
5985 *flags |= SfPollAfter;
5989 // SYS_pdgetpid 520
5990 // int pdgetpid(int fd, pid_t *pidp);
5991 PRE(sys_pdgetpid)
5993 PRINT("pdgetpid ( %" FMT_REGWORD "d, %#lx )", SARG1, ARG2);
5994 PRE_REG_READ2(int, "pdgetpid",
5995 int, fd, pid_t*, pidp);
5996 PRE_MEM_WRITE( "pdgetpid(pidp))", ARG2, sizeof(vki_pid_t) );
5999 POST(sys_pdgetpid)
6001 POST_MEM_WRITE( ARG2, sizeof(vki_pid_t) );
6004 // SYS_pselect 522
6006 // int pselect(int nfds, fd_set * restrict readfds, fd_set * restrict writefds,
6007 // fd_set * restrict exceptfds,
6008 // const struct timespec * restrict timeout,
6009 // const sigset_t * restrict newsigmask);
6010 PRE(sys_pselect)
6012 *flags |= SfMayBlock | SfPostOnFail;
6013 PRINT("sys_pselect ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
6014 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
6015 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6016 PRE_REG_READ6(int, "pselect",
6017 int, nfds, vki_fd_set *, readfds, vki_fd_set *, writefds,
6018 vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
6019 const sigset_t *, newsigmask);
6020 // XXX: this possibly understates how much memory is read.
6021 if (ARG2 != 0) {
6022 PRE_MEM_READ( "pselect(readfds)",
6023 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
6025 if (ARG3 != 0) {
6026 PRE_MEM_READ( "pselect(writefds)",
6027 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
6029 if (ARG4 != 0) {
6030 PRE_MEM_READ( "pselect(exceptfds)",
6031 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
6033 if (ARG5 != 0) {
6034 PRE_MEM_READ( "pselect(timeout)", ARG5, sizeof(struct vki_timeval) );
6037 if (ARG6 != 0) {
6038 PRE_MEM_READ( "pselect(sig)", ARG6, sizeof(vki_sigset_t) );
6039 ARG6 = ML_(make_safe_mask)("syswrap.pselect.1", (Addr)ARG6);
6043 POST(sys_pselect)
6045 ML_(free_safe_mask) ( (Addr)ARG6 );
6048 // SYS_getloginclass 523
6049 // int getloginclass(char *name, size_t len);
6050 PRE(sys_getloginclass)
6052 PRINT("sys_getloginclass ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
6053 PRE_REG_READ2(int, "getloginclass", char *, name, size_t, len);
6054 // The buffer should be at least MAXLOGNAME bytes in length.
6055 PRE_MEM_WRITE("getloginclass(name)", ARG1, ARG2);
6058 POST(sys_getloginclass)
6060 POST_MEM_WRITE(ARG1, ARG2);
6063 // SYS_setloginclass 524
6064 // int setloginclass(const char *name);
6065 PRE(sys_setloginclass)
6067 PRINT("sys_setloginclass ( %#" FMT_REGWORD "x(%s) )", ARG1, (HChar*)ARG1);
6068 PRE_REG_READ1(int, "setloginclass", const char *, name);
6069 PRE_MEM_RASCIIZ("rctl_setloginclass(name)", ARG1);
6072 // SYS_rctl_get_racct 525
6073 // int rctl_get_racct(const char *inbufp, size_t inbuflen, char *outbufp,
6074 // size_t outbuflen);
6075 PRE(sys_rctl_get_racct)
6077 PRINT("sys_rctl_get_racct ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
6078 PRE_REG_READ4(int, "rctl_get_racct", const char *, inbufp, size_t, inbuflen, char *, outbufp,
6079 size_t, outbuflen);
6080 PRE_MEM_READ("rctl_get_racct(inbufp)", ARG1, ARG2);
6081 PRE_MEM_WRITE("rctl_get_racct(outbufp)", ARG3, ARG4);
6084 POST(sys_rctl_get_racct)
6086 POST_MEM_WRITE(ARG3, ARG4);
6089 // SYS_rctl_get_rules 526
6090 // int rctl_get_rules(const char *inbufp, size_t inbuflen, char *outbufp,
6091 // size_t outbuflen);
6092 PRE(sys_rctl_get_rules)
6094 PRINT("sys_rctl_get_rules ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
6095 PRE_REG_READ4(int, "rctl_get_rules", const char *, inbufp, size_t, inbuflen, char *, outbufp,
6096 size_t, outbuflen);
6097 PRE_MEM_READ("rctl_get_rules(inbufp)", ARG1, ARG2);
6098 PRE_MEM_WRITE("rctl_get_rules(outbufp)", ARG3, ARG4);
6101 POST(sys_rctl_get_rules)
6103 POST_MEM_WRITE(ARG3, ARG4);
6106 // SYS_rctl_get_limits 527
6107 // int rctl_get_limits(const char *inbufp, size_t inbuflen, char *outbufp,
6108 // size_t outbuflen);
6109 PRE(sys_rctl_get_limits)
6111 PRINT("sys_rctl_get_limits ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
6112 PRE_REG_READ4(int, "rctl_get_limits", const char *, inbufp, size_t, inbuflen, char *, outbufp,
6113 size_t, outbuflen);
6114 PRE_MEM_READ("rctl_get_limits(inbufp)", ARG1, ARG2);
6115 PRE_MEM_WRITE("rctl_get_limits(outbufp)", ARG3, ARG4);
6118 POST(sys_rctl_get_limits)
6120 POST_MEM_WRITE(ARG3, ARG4);
6123 // SYS_rctl_add_rule 528
6124 // int rctl_add_rule(const char *inbufp, size_t inbuflen, char *outbufp,
6125 // size_t outbuflen);
6126 PRE(sys_rctl_add_rule)
6128 PRINT("sys_rctl_add_rule ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
6129 PRE_REG_READ2(int, "rctl_add_rule", const char *, inbufp, size_t, inbuflen);
6130 PRE_MEM_READ("rctl_add_rule(inbufp)", ARG1, ARG2);
6131 // man page says
6132 // The outbufp and outbuflen arguments are unused
6133 //PRE_MEM_WRITE("rctl_add_rule(outbufp)", ARG3, ARG4);
6136 POST(sys_rctl_add_rule)
6138 //POST_MEM_WRITE(ARG3, ARG4);
6141 // SYS_rctl_remove_rule 529
6142 // int rctl_remove_rule(const char *inbufp, size_t inbuflen, char *outbufp,
6143 // size_t outbuflen);
6144 PRE(sys_rctl_remove_rule)
6146 PRINT("sys_rctl_remove_rule ( %#" FMT_REGWORD "xd, %" FMT_REGWORD "u, %#" FMT_REGWORD "xd, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
6147 PRE_REG_READ2(int, "rctl_remove_rule", const char *, inbufp, size_t, inbuflen);
6148 PRE_MEM_READ("rctl_remove_rule(inbufp)", ARG1, ARG2);
6149 // man page says
6150 // The outbufp and outbuflen arguments are unused
6151 //PRE_MEM_WRITE("rctl_remove_rule(outbufp)", ARG3, ARG4);
6154 POST(sys_rctl_remove_rule)
6156 //POST_MEM_WRITE(ARG3, ARG4);
6159 // SYS_posix_fallocate 530
6160 // x86/amd64
6162 // SYS_posix_fadvise 531
6163 // x86/amd64
6165 // SYS_wait6 532
6166 // amd64 / x86
6168 // SYS_cap_rights_limit 533
6169 //int cap_rights_limit(int fd, const cap_rights_t *rights);
6170 PRE(sys_cap_rights_limit)
6172 PRINT("sys_cap_rights_limit ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
6173 PRE_REG_READ2(int, "cap_rights_limit",
6174 int, fd, const cap_rights_t *, rights);
6175 PRE_MEM_READ( "cap_rights_limit(rights)", ARG2, sizeof(struct vki_cap_rights) );
6178 // SYS_cap_ioctls_limit 534
6179 // int cap_ioctls_limit(int fd, const unsigned long *cmds, size_t ncmds);
6180 PRE(sys_cap_ioctls_limit)
6182 PRINT("cap_ioctls_limit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6183 PRE_REG_READ3(int, "cap_ioctls_limit",
6184 int, fd, unsigned long*, rights, vki_size_t, ncmds);
6185 // "can be up to 256" taking that to not be inclusive
6186 if (ARG3 < 256 ) {
6187 PRE_MEM_READ( "cap_ioctls_limit(cmds))", ARG2, ARG3*sizeof(unsigned long) );
6189 // else fail?
6192 // SYS_cap_ioctls_get 535
6193 // int cap_ioctls_get(int fd, unsigned long *cmds, size_t maxcmds);
6194 PRE(sys_cap_ioctls_get)
6196 PRINT("sys_cap_ioctls_get ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, ARG2, ARG3);
6197 PRE_REG_READ3(int, "cap_ioctls_get", int, fd, unsigned long *, cmds, size_t, maxcmds);
6198 if (ARG3 < 256) {
6199 PRE_MEM_WRITE("cap_ioctls_get(cmds)", ARG2, ARG3*sizeof(unsigned long));
6203 POST(sys_cap_ioctls_get)
6205 if (ARG3 < 256) {
6206 POST_MEM_WRITE(ARG2, ARG3*sizeof(unsigned long));
6211 // SYS_cap_fcntls_limit 536
6212 //int cap_fcntls_limit(int fd, uint32_t fcntlrights);
6213 PRE(sys_cap_fcntls_limit)
6215 PRINT("cap_fcntls_limit ( %" FMT_REGWORD "d, %" FMT_REGWORD "u )", SARG1, ARG2);
6216 PRE_REG_READ2(long, "cap_fcntls_limit",
6217 int, fd, vki_uint32_t, fcntlrights);
6220 // SYS_cap_fcntls_get 537
6221 // int cap_fcntls_get(int fd, uint32_t *fcntlrightsp);
6222 PRE(sys_cap_fcntls_get)
6224 PRINT("sys_cap_fcntls_get ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
6225 PRE_REG_READ2(int, "cap_fcntls_get", int, fd, uint32_t *, fcntlrightsp);
6226 PRE_MEM_WRITE("cap_fcntls_get(fcntlrightsp)", ARG2, sizeof(uint32_t));
6229 POST(sys_cap_fcntls_get)
6231 POST_MEM_WRITE(ARG2, sizeof(uint32_t));
6234 // SYS_bindat 538
6235 // int bindat(int fd, int s, const struct sockaddr *addr, socklen_t addrlen);
6236 PRE(sys_bindat)
6238 PRINT("sys_bindat ( %" FMT_REGWORD "d, %" FMT_REGWORD "dx, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
6239 SARG1, SARG2, ARG3, ARG4);
6240 PRE_REG_READ4(int, "bindat", int, fd, int, s, const struct vki_sockaddr *, name, vki_socklen_t, namelen);
6241 PRE_MEM_READ("bindat(name)", ARG3, ARG4);
6244 // SYS_connectat 539
6245 // int connectat(int fd, int s, const struct sockaddr *name, socklen_t namelen);
6246 PRE(sys_connectat)
6248 PRINT("sys_connectat ( %" FMT_REGWORD "d, %" FMT_REGWORD "dx, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
6249 SARG1, SARG2, ARG3, ARG4);
6250 PRE_REG_READ4(int, "connectat", int, fd, int, s, const struct vki_sockaddr *, name, vki_socklen_t, namelen);
6251 PRE_MEM_READ("connectat(name)", ARG3, ARG4);
6254 // SYS_chflagsat 540
6255 // int chflagsat(int fd, const char *path, unsigned long flags, int atflag);
6256 PRE(sys_chflagsat)
6258 PRINT("sys_chglagsat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d )",
6259 SARG1, ARG2, ARG3, SARG4);
6260 PRE_REG_READ4(int, "chflagsat", int, fd, const char *, path, unsigned long, flags, int, atflag);
6261 PRE_MEM_RASCIIZ("chflagsat(path)", ARG2);
6264 // SYS_accept4 541
6265 // int accept4(int s, struct sockaddr * restrict addr,
6266 // socklen_t * restrict addrlen, int flags);
6267 PRE(sys_accept4)
6269 *flags |= SfMayBlock;
6270 PRINT("sys_accept4 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u)",ARG1,ARG2,ARG3,ARG4);
6271 PRE_REG_READ4(int, "accept4",
6272 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
6273 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
6276 POST(sys_accept4)
6278 SysRes r;
6279 vg_assert(SUCCESS);
6280 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
6281 ARG1,ARG2,ARG3);
6282 SET_STATUS_from_SysRes(r);
6285 // SYS_pipe2 542
6286 // int pipe2(int fildes[2], int flags);
6287 PRE(sys_pipe2)
6289 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
6290 PRE_REG_READ2(int, "pipe2",
6291 int *, fildes, int, flags);
6292 PRE_MEM_WRITE("pipe2(fildes)", ARG1, 2 * sizeof(int));
6296 POST(sys_pipe2)
6298 int *fildes;
6300 if (RES != 0) {
6301 return;
6304 POST_MEM_WRITE(ARG1, 2 * sizeof(int));
6305 fildes = (int *)ARG1;
6307 if (!ML_(fd_allowed)(fildes[0], "pipe2", tid, True) ||
6308 !ML_(fd_allowed)(fildes[1], "pipe2", tid, True)) {
6309 VG_(close)(fildes[0]);
6310 VG_(close)(fildes[1]);
6311 SET_STATUS_Failure( VKI_EMFILE );
6312 } else if (VG_(clo_track_fds)) {
6313 ML_(record_fd_open_nameless)(tid, fildes[0]);
6314 ML_(record_fd_open_nameless)(tid, fildes[1]);
6318 // SYS_aio_mlock 543
6319 // int aio_mlock(struct aiocb *iocb);
6320 PRE(sys_aio_mlock)
6322 PRINT("sys_aio_mlock ( %#" FMT_REGWORD "x )", ARG1);
6323 PRE_REG_READ1(int, "aio_mlock", struct vki_aiocb *, iocb);
6324 PRE_MEM_READ("aio_mlock(iocb", ARG1, sizeof(struct vki_aiocb));
6325 // this locks memory into RAM, don't think that we need to do
6326 // anything extra
6329 // SYS_procctl 544
6330 // amd64 / x86
6332 // SYS_ppoll 545
6333 // int ppoll(struct pollfd fds[], nfds_t nfds,
6334 // const struct timespec * restrict timeout,
6335 // const sigset_t * restrict newsigmask);
6336 PRE(sys_ppoll)
6338 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
6339 "x, %#" FMT_REGWORD "x )",
6340 ARG1, ARG2, ARG3, ARG4);
6341 UInt i;
6342 struct vki_pollfd* fds = (struct vki_pollfd *)(Addr)ARG1;
6343 *flags |= SfMayBlock | SfPostOnFail;
6344 PRE_REG_READ4(long, "ppoll",
6345 struct vki_pollfd *, fds, unsigned int, nfds,
6346 struct vki_timespec *, timeout, vki_sigset_t *, newsigmask);
6348 for (i = 0; i < ARG2; i++) {
6349 PRE_MEM_READ( "ppoll(fds.fd)",
6350 (Addr)(&fds[i].fd), sizeof(fds[i].fd) );
6351 if (ML_(safe_to_deref)(&fds[i].fd, sizeof(fds[i].fd)) && fds[i].fd >= 0) {
6352 PRE_MEM_READ( "ppoll(fds.events)",
6353 (Addr)(&fds[i].events), sizeof(fds[i].events) );
6355 PRE_MEM_WRITE( "ppoll(fds.revents)",
6356 (Addr)(&fds[i].revents), sizeof(fds[i].revents) );
6359 if (ARG3) {
6360 PRE_MEM_READ( "ppoll(timeout)", ARG3,
6361 sizeof(struct vki_timespec) );
6363 if (ARG4) {
6364 PRE_MEM_READ( "ppoll(newsigmask)", ARG4, sizeof(vki_sigset_t));
6365 ARG4 = ML_(make_safe_mask)("syswrap.ppoll.1", (Addr)ARG4);
6369 POST(sys_ppoll)
6371 if (SUCCESS && ((Word)RES != -1)) {
6372 UInt i;
6373 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
6374 for (i = 0; i < ARG2; i++) {
6375 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
6378 ML_(free_safe_mask) ( (Addr)ARG4 );
6381 // SYS_futimens 546
6382 // int futimens(int fd, const struct timespec times[2]);
6383 PRE(sys_futimens)
6385 PRINT("sys_futimens ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
6386 PRE_REG_READ2(int, "futimens", int, fd, const struct timespec *, times);
6387 PRE_MEM_READ("futimens(times)", ARG2, 2*sizeof(struct vki_timespec));
6390 // SYS_utimensat 547
6391 // int utimensat(int fd, const char *path, const struct timespec times[2],
6392 // int flag);
6393 PRE(sys_utimensat)
6395 PRINT("sys_utimensat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )",
6396 SARG1, ARG2, ARG3, SARG4);
6397 PRE_REG_READ4(int, "utimensat", int, fd, const char *,path, const struct timespec *, times,
6398 int, flag);
6399 PRE_MEM_RASCIIZ("utimensat(path)", ARG2);
6400 PRE_MEM_READ("utimensat(times)", ARG3, 2*sizeof(struct vki_timespec));
6403 // SYS_fdatasync 550
6404 // int fdatasync(int fd);
6405 PRE(sys_fdatasync)
6407 PRINT("sys_fdatasync ( %" FMT_REGWORD "d )",SARG1);
6408 PRE_REG_READ1(int, "fdatasync", int, fd);
6411 #if (FREEBSD_VERS >= FREEBSD_12)
6412 // SYS_fstat 551
6413 // int fstat(int fd, struct stat *sb);
6414 PRE(sys_fstat)
6416 PRINT("sys_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2);
6417 PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb);
6418 PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_stat) );
6421 POST(sys_fstat)
6423 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
6426 // SYS_fstatat 552
6427 // int fstatat(int fd, const char *path, struct stat *sb, int flag);
6428 PRE(sys_fstatat)
6430 PRINT("sys_fstatat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "d )", SARG1,ARG2,(char*)ARG2,ARG3,SARG4);
6431 PRE_REG_READ4(int, "fstatat",
6432 int, fd, const char *, path, struct stat *, sb, int, flag);
6433 PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 );
6434 PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_stat) );
6437 POST(sys_fstatat)
6439 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
6441 // SYS_fhstat 553
6442 // int fhstat(const fhandle_t *fhp, struct stat *sb);
6443 PRE(sys_fhstat)
6445 PRINT("sys_fhstat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
6446 PRE_REG_READ2(long, "fhstat", const vki_fhandle_t *, fhp, struct stat *, sb);
6447 PRE_MEM_READ( "fhstat(fhp)", ARG1, sizeof(struct vki_fhandle) );
6448 PRE_MEM_WRITE( "fhstat(sb)", ARG2, sizeof(struct vki_stat) );
6451 POST(sys_fhstat)
6453 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
6456 // SYS_getdirentries 554
6457 // ssize_t getdirentries(int fd, char *buf, size_t nbytes, off_t *basep);
6458 PRE(sys_getdirentries)
6460 *flags |= SfMayBlock;
6461 PRINT("sys_getdirentries ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
6462 PRE_REG_READ4(ssize_t, "getdirentries",
6463 int, fd, char *, buf,
6464 size_t, nbytes,
6465 off_t *, basep);
6466 PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 );
6467 if (ARG4) {
6468 PRE_MEM_WRITE("getdirentries(basep)", ARG4, sizeof (vki_off_t));
6472 POST(sys_getdirentries)
6474 vg_assert(SUCCESS);
6475 if (RES > 0) {
6476 POST_MEM_WRITE( ARG2, RES );
6477 if ( ARG4 != 0 ) {
6478 POST_MEM_WRITE( ARG4, sizeof (vki_off_t));
6483 // SYS_statfs 555
6484 // int statfs(const char *path, struct statfs *buf);
6485 PRE(sys_statfs)
6487 PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2);
6488 PRE_REG_READ2(int, "statfs", const char *, path, struct statfs *, buf);
6489 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
6490 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
6493 POST(sys_statfs)
6495 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
6498 // SYS_fstatfs 556
6499 // int fstatfs(int fd, struct statfs *buf);
6500 PRE(sys_fstatfs)
6502 PRINT("sys_fstatfs ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2);
6503 PRE_REG_READ2(int, "fstatfs",
6504 int, fd, struct vki_statfs *, buf);
6505 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
6508 POST(sys_fstatfs)
6510 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
6513 // SYS_getfsstat 557
6514 // int getfsstat(struct statfs *buf, long bufsize, int mode);
6515 PRE(sys_getfsstat)
6517 PRINT("sys_getfsstat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
6518 PRE_REG_READ3(long, "getfsstat", struct vki_statfs *, buf, long, len, int, flags);
6519 PRE_MEM_WRITE( "getfsstat(buf)", ARG1, ARG2 );
6522 POST(sys_getfsstat)
6524 vg_assert(SUCCESS);
6525 if ((Word)RES != -1) {
6526 POST_MEM_WRITE( ARG1, RES * sizeof(struct vki_statfs) );
6530 // SYS_fhstatfs 558
6531 // int fhstatfs(const fhandle_t *fhp, struct statfs *buf);
6532 PRE(sys_fhstatfs)
6534 PRINT("sys_fhstatfs ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
6535 PRE_REG_READ2(long, "fhstatfs",
6536 struct fhandle *, fhp, struct statfs *, buf);
6537 PRE_MEM_READ( "fhstatfs(fhp)", ARG1, sizeof(struct vki_fhandle) );
6538 PRE_MEM_WRITE( "fhstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
6541 POST(sys_fhstatfs)
6543 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
6546 // SYS_mknodat 559
6547 // x86 / amd64
6549 // SYS_kevent 560
6550 // int kevent(int kq, const struct kevent *changelist, int nchanges,
6551 // struct kevent *eventlist, int nevents,
6552 // const struct timespec *timeout);
6553 PRE(sys_kevent)
6555 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);
6556 PRE_REG_READ6(int, "kevent",
6557 int, kq, struct vki_kevent *, changelist, int, nchanges,
6558 struct vki_kevent *, eventlist, int, nevents,
6559 struct timespec *, timeout);
6560 if (ARG2 != 0 && ARG3 != 0) {
6561 PRE_MEM_READ( "kevent(changelist)", ARG2, sizeof(struct vki_kevent)*ARG3 );
6563 if (ARG4 != 0 && ARG5 != 0) {
6564 PRE_MEM_WRITE( "kevent(eventlist)", ARG4, sizeof(struct vki_kevent)*ARG5);
6566 if (ARG5 != 0) {
6567 *flags |= SfMayBlock;
6569 if (ARG6 != 0) {
6570 PRE_MEM_READ( "kevent(timeout)",
6571 ARG6, sizeof(struct vki_timespec));
6575 POST(sys_kevent)
6577 vg_assert(SUCCESS);
6578 if ((Word)RES != -1) {
6579 if (ARG4 != 0) {
6580 POST_MEM_WRITE( ARG4, sizeof(struct vki_kevent)*RES) ;
6585 // SYS_cpuset_getdomain 561
6586 // x86 / amd64
6588 // SYS_cpuset_setdomain 562
6589 // x86 / amd64
6591 // SYS_getrandom 563
6592 // ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
6593 PRE(sys_getrandom)
6595 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6596 PRE_REG_READ3(ssize_t, "getrandom",
6597 void *, buf, vki_size_t, buflen, unsigned int, flags);
6598 PRE_MEM_WRITE( "getrandom(buf)", ARG1, ARG2 );
6599 if ((ARG3 & VKI_GRND_NONBLOCK) == 0) {
6600 *flags |= SfMayBlock;
6604 POST(sys_getrandom)
6606 POST_MEM_WRITE( ARG1, ARG2 );
6609 // SYS_getfhat 564
6610 // int getfhat(int fd, const char *path, fhandle_t *fhp, int flag);
6611 PRE(sys_getfhat)
6613 PRINT("sys_getfhat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "x, %" FMT_REGWORD "d ", SARG1, ARG2, ARG3, SARG4);
6614 PRE_REG_READ4(int, "getfhat", int, fd, const char*, path, vki_fhandle_t*, fhp, int, flag);
6615 PRE_MEM_RASCIIZ( "getfhat(path)", ARG2 );
6616 PRE_MEM_WRITE("getfhat(fhp)", ARG3, sizeof(vki_fhandle_t));
6619 POST(sys_getfhat)
6621 POST_MEM_WRITE(ARG3, sizeof(vki_fhandle_t));
6624 // SYS_fhlink 565
6625 // int fhlink(fhandle_t *fhp, const char *to);
6626 PRE(sys_fhlink)
6628 PRINT("sys_fhlink ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
6629 PRE_REG_READ2(int, "fhlink", vki_fhandle_t *, fhp, const char *, to);
6630 PRE_MEM_READ( "fhlink(fhp)", ARG1, sizeof(vki_fhandle_t));
6631 PRE_MEM_RASCIIZ("fhlink(buf)", ARG2);
6634 // SYS_fhlinkat 566
6635 // int fhlinkat(fhandle_t *fhp, int tofd, const char *to);
6636 PRE(sys_fhlinkat)
6638 PRINT("sys_fhlinkat ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "xu ", ARG1, SARG2, ARG3);
6639 PRE_REG_READ3(int, "fhlinkat", vki_fhandle_t *, fhp, int, tofd, const char *, to);
6640 PRE_MEM_READ( "fhlinkat(fhp)", ARG1, sizeof(vki_fhandle_t));
6641 PRE_MEM_RASCIIZ("fhreadlink(to)", ARG3);
6644 // SYS_fhreadlink 567
6645 // int fhreadlink(fhandle_t *fhp, char *buf, size_t bufsize);
6646 PRE(sys_fhreadlink)
6648 PRINT("sys_fhreadlink ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x, %" FMT_REGWORD "u ", ARG1, ARG2, ARG3);
6649 PRE_REG_READ3(int, "fhreadlink", vki_fhandle_t *, fhp, char *, buf, size_t, bufsize);
6650 PRE_MEM_READ( "fhreadlink(fhp)", ARG1, sizeof(vki_fhandle_t));
6651 PRE_MEM_WRITE("fhreadlink(buf)", ARG2, ARG3);
6654 POST(sys_fhreadlink)
6656 POST_MEM_WRITE(ARG2, ARG3);
6659 #endif
6661 #if (FREEBSD_VERS >= FREEBSD_12_2)
6663 // SYS_unlinkat 568
6664 // int funlinkat(int dfd, const char *path, int fd, int flag);
6665 PRE(sys_funlinkat)
6667 *flags |= SfMayBlock;
6668 PRINT("sys_funlinkat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD"u )",
6669 SARG1, ARG2, (char*)ARG2, ARG4, ARG5);
6670 PRE_REG_READ4(int, "funlinkat", int, dfd, const char *, path, int, fd, int, flag);
6671 PRE_MEM_RASCIIZ( "funlinkat(path)", ARG2 );
6674 // SYS_copy_file_range 569
6675 // ssize_t copy_file_range(int infd, off_t *inoffp, int outfd, off_t *outoffp,
6676 // size_t len, unsigned int flags);
6677 PRE(sys_copy_file_range)
6679 PRINT("sys_copy_file_range (%" FMT_REGWORD"d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "d, %" FMT_REGWORD "d)",
6680 SARG1, ARG2, SARG3, ARG4, (char*)ARG4, SARG5, SARG6);
6682 PRE_REG_READ6(vki_ssize_t, "copy_file_range",
6683 int, "infd",
6684 vki_off_t *, "inoffp",
6685 int, "outfd",
6686 vki_off_t *, "outoffp",
6687 vki_size_t, "len",
6688 unsigned int, "flags");
6690 /* File descriptors are "specially" tracked by valgrind.
6691 valgrind itself uses some, so make sure someone didn't
6692 put in one of our own... */
6693 if (!ML_(fd_allowed)(ARG1, "copy_file_range(infd)", tid, False) ||
6694 !ML_(fd_allowed)(ARG3, "copy_file_range(infd)", tid, False)) {
6695 SET_STATUS_Failure( VKI_EBADF );
6696 } else {
6697 /* Now see if the offsets are defined. PRE_MEM_READ will
6698 double check it can dereference them. */
6699 if (ARG2 != 0) {
6700 PRE_MEM_READ( "copy_file_range(inoffp)", ARG2, sizeof(vki_off_t));
6702 if (ARG4 != 0) {
6703 PRE_MEM_READ( "copy_file_range(outoffp)", ARG4, sizeof(vki_off_t));
6709 // SYS___sysctlbyname 570
6710 // int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
6711 // const void *newp, size_t newlen);
6712 // syscalls.master:
6713 // int __sysctlbyname(_In_reads_(namelen) const char *name, size_t namelen,
6714 // _Out_writes_bytes_opt_(*oldlenp) void *old,
6715 // _Inout_opt_ size_t *oldlenp, _In_reads_bytes_opt_(newlen) void *new,
6716 // size_t newlen );
6717 PRE(sys___sysctlbyname)
6719 // this is very much like SYS___sysctl, instead of having an OID with length
6720 // here threre is an ascii string with length
6721 // @todo PJF factor out the common functionality of the two
6722 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 );
6723 PRE_REG_READ6(int, "__sysctlbyname", const char *, name, vki_size_t, namelen,
6724 void *, oldp, vki_size_t *, oldlenp,
6725 void *, newp, vki_size_t, newlen);
6728 const char* name = (const char*)ARG1;
6729 if (ML_(safe_to_deref)(name, sizeof("kern.ps_strings")) &&
6730 VG_(strcmp)(name, "kern.ps_strings") == 0) {
6731 if (sysctl_kern_ps_strings((SizeT*)ARG3, (SizeT*)ARG4)) {
6732 SET_STATUS_Success(0);
6736 if (ML_(safe_to_deref)(name, sizeof("kern.usrstack")) &&
6737 VG_(strcmp)(name, "kern.usrstack") == 0) {
6738 sysctl_kern_usrstack((SizeT*)ARG3, (SizeT*)ARG4);
6739 SET_STATUS_Success(0);
6742 // kern.proc.pathname doesn't seem to be handled
6743 // makes sense as the pid is variable and using
6744 // a MIB is easier than generating a string
6746 // string length specified in ARG2 from mem pointed to by ARG1
6747 PRE_MEM_READ("__sysctlbyname(name)", (Addr)ARG1, ARG2);
6749 // if 'newp' is not NULL can read namelen bytes from that addess
6750 if (ARG5 != (UWord)NULL) {
6751 PRE_MEM_READ("__sysctlbyname(newp)", (Addr)ARG5, ARG6);
6754 // there are two scenarios for oldlenp/oldp
6755 // 1. oldval is NULL and oldlenp is non-NULL
6756 // this is a query of oldlenp so oldlenp will be written
6757 // 2. Both are non-NULL
6758 // this is a query of oldp, oldlenp will be read and oldp will
6759 // be written
6761 // is oldlenp is not NULL, can write
6762 if (ARG4 != (UWord)NULL) {
6763 if (ARG3 != (UWord)NULL) {
6764 // case 2 above
6765 PRE_MEM_READ("__sysctlbyname(oldlenp)", (Addr)ARG4, sizeof(vki_size_t));
6766 if (ML_(safe_to_deref)((void*)(Addr)ARG4, sizeof(vki_size_t))) {
6767 PRE_MEM_WRITE("__sysctlbyname(oldp)", (Addr)ARG3, *(vki_size_t *)ARG4);
6768 } else {
6769 VG_(dmsg)("Warning: Bad oldlenp address %p in sysctlbyname\n",
6770 (void *)(Addr)ARG4);
6771 SET_STATUS_Failure ( VKI_EFAULT );
6773 } else {
6774 // case 1 above
6775 PRE_MEM_WRITE("__sysctlbyname(oldlenp)", (Addr)ARG4, sizeof(vki_size_t));
6780 POST(sys___sysctlbyname)
6782 if (ARG4 != (UWord)NULL) {
6783 if (ARG3 != (UWord)NULL) {
6784 //POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t));
6785 POST_MEM_WRITE((Addr)ARG3, *(vki_size_t *)ARG4);
6786 } else {
6787 POST_MEM_WRITE((Addr)ARG4, sizeof(vki_size_t));
6792 #endif // (FREEBSD_VERS >= FREEBSD_12_2)
6794 #if (FREEBSD_VERS >= FREEBSD_13_0)
6796 // SYS_shm_open2 571
6797 // from syscalls.master
6798 // int shm_open2(_In_z_ const char *path,
6799 // int flags,
6800 // mode_t mode,
6801 // int shmflags,
6802 // _In_z_ const char *name);
6803 PRE(sys_shm_open2)
6805 PRE_REG_READ5(int, "shm_open2",
6806 const char *, path, int, flags, vki_mode_t, mode, int, shmflags, const char*, name);
6807 if (ARG1 == VKI_SHM_ANON) {
6808 PRINT("sys_shm_open2(%#" FMT_REGWORD "x(SHM_ANON), %" FMT_REGWORD "u, %hu, %d, %#" FMT_REGWORD "x(%s))",
6809 ARG1, ARG2, (vki_mode_t)ARG3, (Int)ARG4, ARG5, (HChar*)ARG5);
6810 } else {
6811 PRINT("sys_shm_open2(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %hu, %d, %#" FMT_REGWORD "x(%s))",
6812 ARG1, (HChar *)ARG1, ARG2, (vki_mode_t)ARG3, (Int)ARG4, ARG5, (HChar*)ARG5);
6813 PRE_MEM_RASCIIZ( "shm_open2(path)", ARG1 );
6816 if (ARG5) {
6817 PRE_MEM_RASCIIZ( "shm_open2(name)", ARG5 );
6819 *flags |= SfMayBlock;
6822 POST(sys_shm_open2)
6824 vg_assert(SUCCESS);
6825 if (!ML_(fd_allowed)(RES, "shm_open2", tid, True)) {
6826 VG_(close)(RES);
6827 SET_STATUS_Failure( VKI_EMFILE );
6828 } else {
6829 if (VG_(clo_track_fds)) {
6830 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1);
6835 // SYS_sigfastblock 573
6836 // int sigfastblock(int cmd, void *ptr);
6837 PRE(sys_sigfastblock)
6839 PRINT("sys_sigfastblock ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, ARG2);
6840 PRE_REG_READ2(int, "sigfasblock", int, cmd, void*, ptr);
6843 // SYS___realpathat 574
6844 // from syscalls.master
6845 // int __realpathat(int fd,
6846 // _In_z_ const char *path,
6847 // _Out_writes_z_(size) char *buf,
6848 // size_t size,
6849 // int flags)
6850 PRE(sys___realpathat)
6852 PRINT("sys___realpathat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "u %" FMT_REGWORD "d )",
6853 SARG1,ARG2,(const char*)ARG2,ARG3,ARG4,SARG5 );
6854 PRE_REG_READ5(int, "__realpathat", int, fd, const char *, path,
6855 char *, buf, vki_size_t, size, int, flags);
6856 PRE_MEM_RASCIIZ("__realpathat(path)", (Addr)ARG2);
6857 PRE_MEM_WRITE("__realpathat(buf)", (Addr)ARG3, ARG4);
6860 POST(sys___realpathat)
6862 POST_MEM_WRITE((Addr)ARG3, ARG4);
6865 #endif
6867 #if (FREEBSD_VERS >= FREEBSD_12_2)
6869 // SYS_sys_close_range 575
6870 // int close_range(u_int lowfd, u_int highfd, int flags);
6871 PRE(sys_close_range)
6873 SysRes res = VG_(mk_SysRes_Success)(0);
6874 unsigned int lowfd = ARG1;
6875 unsigned int fd_counter; // will count from lowfd to highfd
6876 unsigned int highfd = ARG2;
6878 /* on linux the may lock if futexes are used
6879 * there is a lock in the kernel but I assume it's just
6880 * a spinlock */
6881 PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6882 FMT_REGWORD "d )", ARG1, ARG2, SARG3);
6883 PRE_REG_READ3(int, "close_range",
6884 unsigned int, lowfd, unsigned int, highfd,
6885 int, flags);
6887 if (lowfd > highfd) {
6888 SET_STATUS_Failure( VKI_EINVAL );
6889 return;
6892 if (highfd >= VG_(fd_hard_limit))
6893 highfd = VG_(fd_hard_limit) - 1;
6895 if (lowfd > highfd) {
6896 SET_STATUS_Success ( 0 );
6897 return;
6900 fd_counter = lowfd;
6901 do {
6902 if (fd_counter > highfd
6903 || (fd_counter == 2U/*stderr*/ && VG_(debugLog_getLevel)() > 0)
6904 || fd_counter == VG_(log_output_sink).fd
6905 || fd_counter == VG_(xml_output_sink).fd) {
6906 /* Split the range if it contains a file descriptor we're not
6907 * supposed to close. */
6908 if (fd_counter - 1 >= lowfd) {
6909 res = VG_(do_syscall3)(__NR_close_range, (UWord)lowfd, (UWord)fd_counter - 1, ARG3 );
6911 lowfd = fd_counter + 1;
6913 } while (fd_counter++ <= highfd);
6915 /* If it failed along the way, it's presumably the flags being wrong. */
6916 SET_STATUS_from_SysRes (res);
6919 POST(sys_close_range)
6921 unsigned int fd;
6922 unsigned int last = ARG2;
6924 if (!VG_(clo_track_fds)
6925 || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0)
6926 return;
6928 if (last >= VG_(fd_hard_limit))
6929 last = VG_(fd_hard_limit) - 1;
6931 /* If the close_range range is too wide, we don't want to loop
6932 through the whole range. */
6933 if (ARG2 == ~0U)
6934 ML_(record_fd_close_range)(tid, ARG1);
6935 else {
6936 for (fd = ARG1; fd <= last; fd++)
6937 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
6938 && fd != VG_(log_output_sink).fd
6939 && fd != VG_(xml_output_sink).fd)
6940 ML_(record_fd_close)(tid, fd);
6943 #endif
6945 #if (FREEBSD_VERS >= FREEBSD_13_0)
6947 // SYS___specialfd 577
6948 // syscalls.master
6949 // int __specialfd(int type,
6950 // _In_reads_bytes_(len) const void *req,
6951 // size_t len);
6952 PRE(sys___specialfd)
6954 PRINT("sys___specialfd ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
6955 SARG1,ARG2,(const char*)ARG2,ARG3 );
6956 PRE_REG_READ3(int, "__specialfd", int, type, const void *, req, vki_size_t, len);
6957 PRE_MEM_READ("__specialfd(req)", (Addr)ARG2, ARG3);
6960 // SYS_aio_writev 578
6961 // int aio_writev(struct aiocb *iocb);
6962 PRE(sys_aio_writev)
6964 PRINT("sys_aio_writev ( %#" FMT_REGWORD "x )", ARG1);
6965 PRE_REG_READ1(int, "aio_writev", struct vki_aiocb *, iocb);
6966 PRE_MEM_READ("aio_writev(iocb)", ARG1, sizeof(struct vki_aiocb));
6967 if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
6968 struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1;
6969 if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_writev", tid, False)) {
6970 SET_STATUS_Failure( VKI_EBADF );
6971 } else {
6972 // aio_writev() gathers the data from the iocb->aio_iovcnt buffers specified
6973 // by the members of the iocb->aio_iov array
6974 // FreeBSD headers #define define this to aio_iovcnt
6975 SizeT vec_count = (SizeT)iocb->aio_nbytes;
6976 #if defined(__clang__)
6977 #pragma clang diagnostic push
6978 // yes, I know it is volatile
6979 #pragma clang diagnostic ignored "-Wcast-qual"
6980 #endif
6981 struct vki_iovec* p_iovec = (struct vki_iovec*)iocb->aio_buf;
6982 #if defined(__clang__)
6983 #pragma clang diagnostic pop
6984 #endif
6985 PRE_MEM_READ("aio_writev(iocb->aio_iov)", (Addr)p_iovec, vec_count*sizeof(struct vki_iovec));
6986 // and this to aio_iov
6988 if (ML_(safe_to_deref)(p_iovec, vec_count*sizeof(struct vki_iovec))) {
6989 for (SizeT i = 0U; i < vec_count; ++i) {
6990 PRE_MEM_READ("aio_writev(iocb->iov[...])",
6991 (Addr)p_iovec[i].iov_base, p_iovec[i].iov_len);
6995 } else {
6996 SET_STATUS_Failure(VKI_EINVAL);
7000 // SYS_aio_readv 579
7001 // int aio_readv(struct aiocb *iocb);
7002 PRE(sys_aio_readv)
7004 PRINT("sys_aio_readv ( %#" FMT_REGWORD "x )", ARG1);
7005 PRE_REG_READ1(int, "aio_readv", struct vki_aiocb *, iocb);
7006 PRE_MEM_READ("aio_readv(iocb)", ARG1, sizeof(struct vki_aiocb));
7007 if (ML_(safe_to_deref)((struct vki_aiocb *)ARG1, sizeof(struct vki_aiocb))) {
7008 struct vki_aiocb *iocb = (struct vki_aiocb *)ARG1;
7009 if (!ML_(fd_allowed)(iocb->aio_fildes, "aio_readv", tid, False)) {
7010 SET_STATUS_Failure( VKI_EBADF );
7011 } else {
7012 SizeT vec_count = (SizeT)iocb->aio_nbytes;
7013 #if defined(__clang__)
7014 #pragma clang diagnostic push
7015 // yes, I know it is volatile
7016 #pragma clang diagnostic ignored "-Wcast-qual"
7017 #endif
7018 struct vki_iovec* p_iovec = (struct vki_iovec*)iocb->aio_buf;
7019 #if defined(__clang__)
7020 #pragma clang diagnostic pop
7021 #endif
7022 PRE_MEM_READ("aio_readv(iocb->aio_iov)", (Addr)p_iovec, vec_count*sizeof(struct vki_iovec));
7023 if (ML_(safe_to_deref)(p_iovec, vec_count*sizeof(struct vki_iovec))) {
7024 for (SizeT i = 0U; i < vec_count; ++i) {
7025 PRE_MEM_WRITE("aio_writev(iocb->aio_iov[...])",
7026 (Addr)p_iovec[i].iov_base, p_iovec[i].iov_len);
7030 } else {
7031 SET_STATUS_Failure(VKI_EINVAL);
7035 POST(sys_aio_readv)
7037 struct vki_aiocb* iocbv = (struct vki_aiocb*)ARG1;
7038 if (iocbv->aio_buf) {
7039 if (!aiov_init_done) {
7040 aiov_init();
7043 if (!VG_(OSetWord_Contains)(iocbv_table, (UWord)iocbv)) {
7044 VG_(OSetWord_Insert)(iocbv_table, (UWord)iocbv);
7045 } else {
7046 // @todo PJF this warns without callstack
7047 VG_(dmsg)("Warning: Duplicate control block %p in aio_readv\n",
7048 (void *)(Addr)ARG1);
7049 VG_(dmsg)("Warning: Ensure 'aio_return' is called when 'aio_readv' has completed\n");
7054 #endif // (FREEBSD_VERS >= FREEBSD_13_0)
7056 #if (FREEBSD_VERS >= FREEBSD_13_1)
7058 #if (FREEBSD_VERS >= FREEBSD_14_0)
7059 // SYS_fspacectl 580
7060 // int fspacectl(int fd, int cmd, const struct spacectl_range *rqsr, int flags,
7061 // struct spacectl_range *rmsr);
7062 PRE(sys_fspacectl)
7064 PRINT("fspacectl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3, SARG4, ARG5);
7065 PRE_REG_READ5(int, "fspacectl", int, fd, int, cmd, const struct spacectl_range *, rqsr, int, flags, struct spacectl_range *, rmsr);
7066 PRE_MEM_READ("fspacectl(rqsr)", (Addr)ARG3, sizeof(struct vki_spacectl_range));
7067 if (ARG5) {
7068 PRE_MEM_WRITE("fspacectl(rmsr)", (Addr)ARG5, sizeof(struct vki_spacectl_range));
7072 POST(sys_fspacectl)
7074 if (ARG5) {
7075 POST_MEM_WRITE((Addr)ARG5, sizeof(struct vki_spacectl_range));
7078 #endif
7080 // SYS_swapoff 582
7081 // int swapoff(const char *special, u_int flags);
7082 PRE(sys_swapoff)
7084 PRINT("sys_swapoff(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u)", ARG1,(char *)ARG1, ARG2);
7085 PRE_REG_READ2(int, "swapoff", const char *, special, u_int, flags);
7086 PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 );
7089 #endif
7091 #if (FREEBSD_VERS >= FREEBSD_15) || (FREEBSD_VERS >= FREEBSD_13_3)
7093 // SYS_kqueuex 583
7094 // int kqueuex(u_int flags);
7095 PRE(sys_kqueuex)
7097 PRINT("sys_kqueuex(%#" FMT_REGWORD "x)", ARG1);
7098 PRE_REG_READ1(int, "kqueuex", u_int, flags);
7101 POST(sys_kqueuex)
7103 if (!ML_(fd_allowed)(RES, "kqueuex", tid, True)) {
7104 VG_(close)(RES);
7105 SET_STATUS_Failure(VKI_EMFILE);
7106 } else {
7107 if (VG_(clo_track_fds)) {
7108 ML_(record_fd_open_nameless)(tid, RES);
7113 // SYS_membarrier 584
7114 // syscalls.master
7115 // int membarrier(int cmd, unsigned flags, int cpu_id);
7116 PRE(sys_membarrier)
7118 // cmd is signed int but the constants in the headers
7119 // are hex so print in hex
7120 PRINT("sys_membarrier(%#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "d)",
7121 ARG1, ARG2, SARG3);
7122 PRE_REG_READ3(int, "membarrier", int, cmd, unsigned, flags, int, cpu_id);
7125 #endif
7127 #if (FREEBSD_VERS >= FREEBSD_14_0) || (FREEBSD_VERS >= FREEBSD_13_4)
7129 // SYS_timerfd_create 585
7130 // int timerfd_create(int clockid, int flags);
7131 PRE(sys_timerfd_create)
7133 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
7134 PRE_REG_READ2(int, "timerfd_create", int, clockid, int, flags);
7137 POST(sys_timerfd_create)
7139 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
7140 VG_(close)(RES);
7141 SET_STATUS_Failure( VKI_EMFILE );
7142 } else {
7143 if (VG_(clo_track_fds))
7144 ML_(record_fd_open_nameless) (tid, RES);
7148 // SYS_timerfd_gettime 586
7149 // int timerfd_gettime(int fd, struct itimerspec *curr_value);
7150 PRE(sys_timerfd_gettime)
7152 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
7153 PRE_REG_READ2(int, "timerfd_gettime",
7154 int, fd,
7155 struct vki_itimerspec*, curr_value);
7156 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
7157 SET_STATUS_Failure(VKI_EBADF);
7158 else
7159 PRE_MEM_WRITE("timerfd_gettime(curr_value)",
7160 ARG2, sizeof(struct vki_itimerspec));
7163 POST(sys_timerfd_gettime)
7165 if (RES == 0)
7166 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
7169 // SYS_timerfd_gettime 587
7170 // int timerfd_settime(int fd, int flags, const struct itimerspec *new_value,
7171 // struct itimerspec *old_value);
7172 PRE(sys_timerfd_settime)
7174 PRINT("sys_timerfd_settime(%" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#"
7175 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
7176 PRE_REG_READ4(int, "timerfd_settime",
7177 int, fd,
7178 int, flags,
7179 const struct vki_itimerspec*, new_value,
7180 struct vki_itimerspec*, old_value);
7181 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
7182 SET_STATUS_Failure(VKI_EBADF);
7183 else
7185 PRE_MEM_READ("timerfd_settime(new_value)",
7186 ARG3, sizeof(struct vki_itimerspec));
7187 if (ARG4)
7189 PRE_MEM_WRITE("timerfd_settime(old_value)",
7190 ARG4, sizeof(struct vki_itimerspec));
7195 POST(sys_timerfd_settime)
7197 if (RES == 0 && ARG4 != 0) {
7198 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
7202 #endif // FREEBSD_14_0 or FREEDSD_13_4
7204 #if (FREEBSD_VERS >= FREEBSD_14_1) || (FREEBSD_VERS >= FREEBSD_13_4)
7206 // SYS_kcmp 588
7207 // int kcmp(pid_t pid1, pid_t pid2, int type, uintptr_t idx1, uintptr_t idx2);
7208 PRE(sys_kcmp)
7210 PRINT("kcmp(%ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u)",
7211 SARG1, SARG2, SARG3, ARG4, ARG5);
7212 switch (ARG3) {
7213 case VKI_KCMP_FILES:
7214 case VKI_KCMP_VM:
7215 case VKI_KCMP_SIGHAND:
7216 /* Most of the comparison types don't look at |idx1| or |idx2|. */
7217 PRE_REG_READ3(int, "kcmp",
7218 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
7219 break;
7220 case VKI_KCMP_FILE:
7221 case VKI_KCMP_FILEOBJ:
7222 default:
7223 PRE_REG_READ5(int, "kcmp",
7224 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
7225 unsigned long, idx1, unsigned long, idx2);
7226 break;
7230 #endif // FREEBSD_14_1 or FREEDSD_13_4
7232 #undef PRE
7233 #undef POST
7235 const SyscallTableEntry ML_(syscall_table)[] = {
7236 // syscall (handled specially) // 0
7237 BSDX_(__NR_exit, sys_exit), // 1
7238 BSDX_(__NR_fork, sys_fork), // 2
7239 GENXY(__NR_read, sys_read), // 3
7241 GENX_(__NR_write, sys_write), // 4
7242 GENXY(__NR_open, sys_open), // 5
7243 GENX_(__NR_close, sys_close), // 6
7244 GENXY(__NR_wait4, sys_wait4), // 7
7246 // 4.3 creat 8
7247 GENX_(__NR_link, sys_link), // 9
7248 GENX_(__NR_unlink, sys_unlink), // 10
7249 // obsol execv 11
7251 GENX_(__NR_chdir, sys_chdir), // 12
7252 GENX_(__NR_fchdir, sys_fchdir), // 13
7253 GENX_(__NR_freebsd11_mknod, sys_mknod), // 14
7254 GENX_(__NR_chmod, sys_chmod), // 15
7256 GENX_(__NR_chown, sys_chown), // 16
7257 #if defined(VGP_arm64_freebsd)
7258 BSDX_(__NR_break, sys_brk), // 17
7259 #else
7260 GENX_(__NR_break, sys_brk), // 17
7261 #endif
7262 // freebsd 4 getfsstat 18
7263 // 4.3 lseek 19
7265 GENX_(__NR_getpid, sys_getpid), // 20
7266 BSDX_(__NR_mount, sys_mount), // 21
7267 BSDX_(__NR_unmount, sys_unmount), // 22
7268 GENX_(__NR_setuid, sys_setuid), // 23
7270 GENX_(__NR_getuid, sys_getuid), // 24
7271 GENX_(__NR_geteuid, sys_geteuid), // 25
7272 BSDXY(__NR_ptrace, sys_ptrace), // 26
7273 BSDXY(__NR_recvmsg, sys_recvmsg), // 27
7275 BSDX_(__NR_sendmsg, sys_sendmsg), // 28
7276 BSDXY(__NR_recvfrom, sys_recvfrom), // 29
7277 BSDXY(__NR_accept, sys_accept), // 30
7278 BSDXY(__NR_getpeername, sys_getpeername), // 31
7280 BSDXY(__NR_getsockname, sys_getsockname), // 32
7281 GENX_(__NR_access, sys_access), // 33
7282 BSDX_(__NR_chflags, sys_chflags), // 34
7283 BSDX_(__NR_fchflags, sys_fchflags), // 35
7285 GENX_(__NR_sync, sys_sync), // 36
7286 GENX_(__NR_kill, sys_kill), // 37
7287 // 4.3 stat 38
7288 GENX_(__NR_getppid, sys_getppid), // 39
7290 // 4.3 lstat 40
7291 GENXY(__NR_dup, sys_dup), // 41
7293 #if defined(VGP_arm64_freebsd)
7294 GENX_(__NR_freebsd10_pipe, sys_ni_syscall), // 42
7295 #else
7296 BSDXY(__NR_freebsd10_pipe, sys_pipe), // 42
7297 #endif
7298 GENX_(__NR_getegid, sys_getegid), // 43
7300 GENX_(__NR_profil, sys_ni_syscall), // 44
7301 GENX_(__NR_ktrace, sys_ni_syscall), // 45
7302 // 4.3 sigaction 46
7303 GENX_(__NR_getgid, sys_getgid), // 47
7305 // 4.3 sigaction (int sigset) 48
7306 BSDXY(__NR_getlogin, sys_getlogin), // 49
7307 BSDX_(__NR_setlogin, sys_setlogin), // 50
7308 GENX_(__NR_acct, sys_acct), // 51
7310 // 4.3 sigpending 52
7311 GENXY(__NR_sigaltstack, sys_sigaltstack), // 53
7312 BSDXY(__NR_ioctl, sys_ioctl), // 54
7313 BSDX_(__NR_reboot, sys_reboot), // 55
7315 BSDX_(__NR_revoke, sys_revoke), // 56
7316 GENX_(__NR_symlink, sys_symlink), // 57
7317 BSDX_(__NR_readlink, sys_readlink), // 58
7318 GENX_(__NR_execve, sys_execve), // 59
7320 GENX_(__NR_umask, sys_umask), // 60
7321 GENX_(__NR_chroot, sys_chroot), // 61
7322 // 4.3 fstat 62
7323 // 4.3 getgerninfo 63
7325 // 4.3 getpagesize 64
7326 GENX_(__NR_msync, sys_msync), // 65
7327 BSDX_(__NR_vfork, sys_vfork), // 66
7328 // obsol vread 67
7330 // obsol vwrite 68
7331 BSDX_(__NR_sbrk, sys_sbrk), // 69
7332 // not implemented in OS sstk 70
7333 // 4.3 mmap 71
7335 // freebsd11 vadvise 72
7336 GENXY(__NR_munmap, sys_munmap), // 73
7337 GENXY(__NR_mprotect, sys_mprotect), // 74
7338 GENX_(__NR_madvise, sys_madvise), // 75
7340 // obsol vhangup 76
7341 // obsol vlimit 77
7342 GENXY(__NR_mincore, sys_mincore), // 78
7343 GENXY(__NR_getgroups, sys_getgroups), // 79
7345 GENX_(__NR_setgroups, sys_setgroups), // 80
7346 GENX_(__NR_getpgrp, sys_getpgrp), // 81
7347 GENX_(__NR_setpgid, sys_setpgid), // 82
7348 GENXY(__NR_setitimer, sys_setitimer), // 83
7350 // 4.3 wait 84
7351 BSDX_(__NR_swapon, sys_swapon), // 85
7352 GENXY(__NR_getitimer, sys_getitimer), // 86
7353 // 4.3 gethostname 87
7355 // 4.3 sethostname 88
7356 BSDX_(__NR_getdtablesize, sys_getdtablesize), // 89
7357 GENXY(__NR_dup2, sys_dup2), // 90
7359 BSDXY(__NR_fcntl, sys_fcntl), // 92
7360 GENX_(__NR_select, sys_select), // 93
7361 GENX_(__NR_fsync, sys_fsync), // 95
7363 GENX_(__NR_setpriority, sys_setpriority), // 96
7364 BSDXY(__NR_socket, sys_socket), // 97
7365 BSDX_(__NR_connect, sys_connect), // 98
7366 // 4.3 accept 99
7368 GENX_(__NR_getpriority, sys_getpriority), // 100
7369 // 4.3 send 101
7370 // 4.3 recv 102
7371 // 4.3 sigreturn 103
7373 BSDX_(__NR_bind, sys_bind), // 104
7374 BSDX_(__NR_setsockopt, sys_setsockopt), // 105
7375 BSDX_(__NR_listen, sys_listen), // 106
7376 // obsol vtimes 107
7378 // 4.3 sigvec 108
7379 // 4.3 sigblock 109
7380 // 4.3 sigsetmask 110
7381 // 4.3 sigsuspend 111
7383 // 4.3 sigstack 112
7384 // 4.3 recvmsg 113
7385 // 4.3 sendmsg 114
7386 // 4.3 vtrace 115
7388 GENXY(__NR_gettimeofday, sys_gettimeofday), // 116
7389 GENXY(__NR_getrusage, sys_getrusage), // 117
7390 BSDXY(__NR_getsockopt, sys_getsockopt), // 118
7392 GENXY(__NR_readv, sys_readv), // 120
7393 GENX_(__NR_writev, sys_writev), // 121
7394 GENX_(__NR_settimeofday, sys_settimeofday), // 122
7395 GENX_(__NR_fchown, sys_fchown), // 123
7397 GENX_(__NR_fchmod, sys_fchmod), // 124
7398 // 4.3 recvfrom 125
7399 GENX_(__NR_setreuid, sys_setreuid), // 126
7400 GENX_(__NR_setregid, sys_setregid), // 127
7402 GENX_(__NR_rename, sys_rename), // 128
7403 // 4.3 truncate 129
7404 // 4.3 ftruncate 130
7405 GENX_(__NR_flock, sys_flock), // 131
7407 BSDX_(__NR_mkfifo, sys_mkfifo), // 132
7408 BSDX_(__NR_sendto, sys_sendto), // 133
7409 BSDX_(__NR_shutdown, sys_shutdown), // 134
7410 BSDXY(__NR_socketpair, sys_socketpair), // 135
7412 GENX_(__NR_mkdir, sys_mkdir), // 136
7413 GENX_(__NR_rmdir, sys_rmdir), // 137
7414 GENX_(__NR_utimes, sys_utimes), // 138
7415 // 4.2 sigreturn 139
7417 BSDXY(__NR_adjtime, sys_adjtime), // 140
7418 // 4.3 getpeername 141
7419 // 4.3 gethostid 142
7420 // 4.3 sethostid 143
7422 // 4.3 getrlimit` 144
7423 // 4.3 setrlimit 145
7424 // 4.3 killpg 146
7425 GENX_(__NR_setsid, sys_setsid), // 147
7427 BSDX_(__NR_quotactl, sys_quotactl), // 148
7428 // 4.3 quota 149
7429 // 4.3 getsockname 150
7430 // bsd/os sem_lock 151
7432 // bsd/os sem_wakeup 152
7433 // bsd/os asyncdaemon 153
7435 // no idea what the following syscall does
7436 // unimp SYS_nlm_syscall 154
7438 // a somewhat complicated NFS API
7439 // takes a flag and a void* that can point to one of
7440 // three different types of struct depending on the flag
7441 // unimp SYS_nfssvc 155
7443 // 4.3 getdirentries 156
7444 // freebsd 4 statfs 157
7445 // freebsd 4 fstatfs 158
7447 BSDXY(__NR_lgetfh, sys_lgetfh), // 160
7448 BSDXY(__NR_getfh, sys_getfh), // 161
7449 #if (FREEBSD_VERS <= FREEBSD_10)
7450 BSDXY(__NR_freebsd4_getdomainname, sys_freebsd4_getdomainname), // 162
7451 BSDX_(__NR_freebsd4_setdomainname, sys_freebsd4_setdomainname), // 163
7452 BSDXY(__NR_freebsd4_uname, sys_freebsd4_uname), // 164
7453 #endif
7454 BSDXY(__NR_sysarch, sys_sysarch), // 165
7455 BSDXY(__NR_rtprio, sys_rtprio), // 166
7457 // the following 3 seem only to be defines in a header
7458 // semsys 169
7459 // msgsys 170
7460 // shmsys 171
7462 #if (FREEBSD_VERS <= FREEBSD_10)
7463 BSDXY(__NR_freebsd6_pread, sys_freebsd6_pread), // 173
7464 BSDX_(__NR_freebsd6_pwrite, sys_freebsd6_pwrite), // 174
7465 #endif
7466 BSDX_(__NR_setfib, sys_setfib), // 175
7468 // @todo PJF this exists on Darwin and Solaris as well
7469 // and it isn't implememented on either
7470 // looking at the manpage there is a rather fearsome
7471 // timex struct with a mixture of ro and rw fields
7472 // BSDXY(__NR_ntp_adjtime, sys_ntp_adjtime), // 176
7474 // bsd/os sfork 177
7475 // bsd/os getdescriptor 178
7476 // bsd/os setdescriptor 179
7478 GENX_(__NR_setgid, sys_setgid), // 181
7479 BSDX_(__NR_setegid, sys_setegid), // 182
7480 BSDX_(__NR_seteuid, sys_seteuid), // 183
7482 // obs lfs_bmapv 184
7483 // obs lfs_markv 185
7484 // obs lfs_segclean 186
7485 // obs lfs_segwait 187
7487 #if (FREEBSD_VERS >= FREEBSD_12)
7488 BSDXY(__NR_freebsd11_stat, sys_freebsd11_stat), // 188
7489 BSDXY(__NR_freebsd11_fstat, sys_freebsd11_fstat), // 189
7490 BSDXY(__NR_freebsd11_lstat, sys_freebsd11_lstat), // 190
7491 #else
7492 BSDXY(__NR_stat, sys_stat), // 188
7493 BSDXY(__NR_fstat, sys_fstat), // 189
7494 BSDXY(__NR_lstat, sys_lstat), // 190
7495 #endif
7496 BSDX_(__NR_pathconf, sys_pathconf), // 191
7497 BSDX_(__NR_fpathconf, sys_fpathconf), // 192
7498 GENXY(__NR_getrlimit, sys_getrlimit), // 194
7499 GENX_(__NR_setrlimit, sys_setrlimit), // 195
7500 #if (FREEBSD_VERS >= FREEBSD_12)
7501 BSDXY(__NR_freebsd11_getdirentries, sys_freebsd11_getdirentries), // 196
7502 #else
7503 BSDXY(__NR_getdirentries, sys_getdirentries), // 196
7504 #endif
7505 #if (FREEBSD_VERS <= FREEBSD_10)
7506 BSDX_(__NR_freebsd6_mmap, sys_freebsd6_mmap), // 197
7507 #endif
7508 // __syscall (handled specially) // 198
7509 #if (FREEBSD_VERS <= FREEBSD_10)
7510 BSDX_(__NR_freebsd6_lseek, sys_freebsd6_lseek), // 199
7511 BSDX_(__NR_freebsd6_truncate, sys_freebsd6_truncate), // 200
7512 BSDX_(__NR_freebsd6_ftruncate, sys_freebsd6_ftruncate), // 201
7513 #endif
7514 BSDXY(__NR___sysctl, sys___sysctl), // 202
7515 GENX_(__NR_mlock, sys_mlock), // 203
7517 GENX_(__NR_munlock, sys_munlock), // 204
7518 BSDX_(__NR_undelete, sys_undelete), // 205
7519 BSDX_(__NR_futimes, sys_futimes), // 206
7520 GENX_(__NR_getpgid, sys_getpgid), // 207
7522 // netbsd newreboot 208
7523 GENXY(__NR_poll, sys_poll), // 209
7525 BSDXY(__NR_freebsd7___semctl, sys_freebsd7___semctl), // 220
7526 BSDX_(__NR_semget, sys_semget), // 221
7527 BSDX_(__NR_semop, sys_semop), // 222
7528 // obs semconfig 223
7530 BSDXY(__NR_freebsd7_msgctl, sys_freebsd7_msgctl), // 224
7531 BSDX_(__NR_msgget, sys_msgget), // 225
7532 BSDX_(__NR_msgsnd, sys_msgsnd), // 226
7533 BSDXY(__NR_msgrcv, sys_msgrcv), // 227
7535 BSDXY(__NR_shmat, sys_shmat), // 228
7536 BSDXY(__NR_freebsd7_shmctl, sys_freebsd7_shmctl), // 229
7537 BSDXY(__NR_shmdt, sys_shmdt), // 230
7538 BSDX_(__NR_shmget, sys_shmget), // 231
7540 BSDXY(__NR_clock_gettime, sys_clock_gettime), // 232
7541 BSDX_(__NR_clock_settime, sys_clock_settime), // 233
7542 BSDXY(__NR_clock_getres, sys_clock_getres), // 234
7543 BSDXY(__NR_ktimer_create, sys_timer_create), // 235
7544 BSDX_(__NR_ktimer_delete, sys_timer_delete), // 236
7545 BSDXY(__NR_ktimer_settime, sys_timer_settime), // 237
7546 BSDXY(__NR_ktimer_gettime, sys_timer_gettime), // 238
7547 BSDX_(__NR_ktimer_getoverrun, sys_timer_getoverrun), // 239
7549 GENXY(__NR_nanosleep, sys_nanosleep), // 240
7550 // unimpl SYS_ffclock_getcounter 241
7551 // unimpl SYS_ffclock_setestimate 242
7552 // unimpl SYS_ffclock_getestimate 243
7554 BSDXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 244
7555 BSDXY(__NR_clock_getcpuclockid2, sys_clock_getcpuclockid2), // 247
7557 // unimpl SYS_ntp_gettime 248
7558 BSDXY(__NR_minherit, sys_minherit), // 250
7559 BSDX_(__NR_rfork, sys_rfork), // 251
7561 // openbsd_poll // 252
7562 BSDX_(__NR_issetugid, sys_issetugid), // 253
7563 GENX_(__NR_lchown, sys_lchown), // 254
7564 BSDXY(__NR_aio_read, sys_aio_read), // 255
7565 BSDX_(__NR_aio_write, sys_aio_write), // 256
7566 BSDX_(__NR_lio_listio, sys_lio_listio), // 257
7568 GENXY(__NR_freebsd11_getdents, sys_getdents), // 272
7569 BSDX_(__NR_lchmod, sys_lchmod), // 274
7570 // netbsd_lchown // 275
7572 BSDX_(__NR_lutimes, sys_lutimes), // 276
7573 // netbsd msync 277
7574 // unimpl SYS_freebsd11_nstat 278
7575 // unimpl SYS_freebsd11_nfstat 279
7577 // unimpl SYS_freebsd11_nlstat 280
7579 BSDXY(__NR_preadv, sys_preadv), // 289
7580 BSDX_(__NR_pwritev, sys_pwritev), // 290
7582 // freebsd 4 fhstatfs 297
7583 BSDXY(__NR_fhopen, sys_fhopen), // 298
7584 #if (FREEBSD_VERS >= FREEBSD_12)
7585 BSDXY(__NR_freebsd11_fhstat, sys_freebsd11_fhstat), // 299
7586 #else
7587 BSDXY(__NR_fhstat, sys_fhstat), // 299
7588 #endif
7590 BSDX_(__NR_modnext, sys_modnext), // 300
7591 BSDXY(__NR_modstat, sys_modstat), // 301
7592 BSDX_(__NR_modfnext, sys_modfnext), // 302
7593 BSDX_(__NR_modfind, sys_modfind), // 303
7595 BSDX_(__NR_kldload, sys_kldload), // 304
7596 BSDX_(__NR_kldunload, sys_kldunload), // 305
7597 BSDX_(__NR_kldfind, sys_kldfind), // 306
7598 BSDX_(__NR_kldnext, sys_kldnext), // 307
7600 BSDXY(__NR_kldstat, sys_kldstat), // 308
7601 BSDX_(__NR_kldfirstmod, sys_kldfirstmod), // 309
7602 GENX_(__NR_getsid, sys_getsid), // 310
7603 BSDX_(__NR_setresuid, sys_setresuid), // 311
7605 BSDX_(__NR_setresgid, sys_setresgid), // 312
7606 // obsol signanosleep 313
7607 BSDX_(__NR_aio_return, sys_aio_return), // 314
7608 BSDX_(__NR_aio_suspend, sys_aio_suspend), // 315
7610 BSDX_(__NR_aio_cancel, sys_aio_cancel), // 316
7611 BSDX_(__NR_aio_error, sys_aio_error), // 317
7612 // freebsd 6 aio_read 318
7613 // freebsd 6 aio_write 319
7614 // freebsd 6 lio_listio 320
7615 BSDX_(__NR_yield, sys_yield), // 321
7616 // obs thr_sleep 322
7617 // obs thr_wakeup 323
7619 GENX_(__NR_mlockall, sys_mlockall), // 324
7620 BSDX_(__NR_munlockall, sys_munlockall), // 325
7621 BSDXY(__NR___getcwd, sys___getcwd), // 326
7622 BSDX_(__NR_sched_setparam, sys_sched_setparam), // 327
7623 BSDXY(__NR_sched_getparam, sys_sched_getparam), // 328
7624 BSDX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 329
7625 BSDX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 330
7626 BSDX_(__NR_sched_yield, sys_sched_yield), // 331
7628 BSDX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 332
7629 BSDX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 333
7630 BSDXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 334
7631 BSDX_(__NR_utrace, sys_utrace), // 335
7633 // freebsd 4 sendfile 336
7634 BSDXY(__NR_kldsym, sys_kldsym), // 337
7635 BSDX_(__NR_jail, sys_jail), // 338
7636 // unimpl SYS_nnpfs_syscall 339
7638 BSDXY(__NR_sigprocmask, sys_sigprocmask), // 340
7639 BSDXY(__NR_sigsuspend, sys_sigsuspend), // 341
7640 // freebsd 4 sigaction 342
7641 BSDXY(__NR_sigpending, sys_sigpending), // 343
7643 // freebsd 4 sigreturn 344
7644 BSDXY(__NR_sigtimedwait, sys_sigtimedwait), // 345
7645 BSDXY(__NR_sigwaitinfo, sys_sigwaitinfo), // 346
7646 BSDXY(__NR___acl_get_file, sys___acl_get_file), // 347
7648 BSDX_(__NR___acl_set_file, sys___acl_set_file), // 348
7649 BSDXY(__NR___acl_get_fd, sys___acl_get_fd), // 349
7650 BSDX_(__NR___acl_set_fd, sys___acl_set_fd), // 350
7651 BSDX_(__NR___acl_delete_file, sys___acl_delete_file), // 351
7653 BSDX_(__NR___acl_delete_fd, sys___acl_delete_fd), // 352
7654 BSDX_(__NR___acl_aclcheck_file, sys___acl_aclcheck_file), // 353
7655 BSDX_(__NR___acl_aclcheck_fd, sys___acl_aclcheck_fd), // 354
7656 BSDX_(__NR_extattrctl, sys_extattrctl), // 355
7657 BSDX_(__NR_extattr_set_file, sys_extattr_set_file), // 356
7658 BSDXY(__NR_extattr_get_file, sys_extattr_get_file), // 357
7659 BSDX_(__NR_extattr_delete_file, sys_extattr_delete_file), // 358
7660 BSDXY(__NR_aio_waitcomplete, sys_aio_waitcomplete), // 359
7662 BSDXY(__NR_getresuid, sys_getresuid), // 360
7663 BSDXY(__NR_getresgid, sys_getresgid), // 361
7664 BSDXY(__NR_kqueue, sys_kqueue), // 362
7665 #if (FREEBSD_VERS >= FREEBSD_12)
7666 BSDXY(__NR_freebsd11_kevent, sys_freebsd11_kevent), // 363
7667 #else
7668 BSDXY(__NR_kevent, sys_kevent), // 363
7669 #endif
7670 // obs __cap_get_proc 364
7671 // obs __cap_set_proc 365
7672 // obs __cap_get_fd 366
7673 // obs __cap_get_file 367
7674 // obs __cap_set_fd 368
7675 // obs __cap_set_file 369
7677 BSDX_(__NR_extattr_set_fd, sys_extattr_set_fd), // 371
7678 BSDXY(__NR_extattr_get_fd, sys_extattr_get_fd), // 372
7679 BSDX_(__NR_extattr_delete_fd, sys_extattr_delete_fd), // 373
7680 BSDX_(__NR___setugid, sys___setugid), // 374
7681 // obs nfsclnt 375
7683 BSDX_(__NR_eaccess, sys_eaccess), // 376
7684 // unimpl afs3_syscall 377
7685 BSDX_(__NR_nmount, sys_nmount), // 378
7686 // obs kse_exit 379
7687 // obs kse_wakeup 380
7688 // obs kse_create 381
7689 // obs kse_thr_interrupt 382
7690 // obs kse_release 383
7692 // unimpl __mac_get_proc 384
7693 // unimpl __mac_set_proc 385
7694 // unimpl __mac_get_fd 386
7695 // unimpl __mac_get_file 387
7696 // unimpl __mac_set_fd 388
7697 // unimpl __mac_set_file 389
7698 BSDXY(__NR_kenv, sys_kenv), // 390
7699 BSDX_(__NR_lchflags, sys_lchflags), // 391
7701 BSDXY(__NR_uuidgen, sys_uuidgen), // 392
7702 BSDXY(__NR_sendfile, sys_sendfile), // 393
7703 // unimpl mac_syscall 394
7705 #if (FREEBSD_VERS >= FREEBSD_12)
7706 BSDXY(__NR_freebsd11_getfsstat, sys_freebsd11_getfsstat), // 395
7707 BSDXY(__NR_freebsd11_statfs, sys_statfs), // 396
7708 BSDXY(__NR_freebsd11_fstatfs, sys_fstatfs), // 397
7709 BSDXY(__NR_freebsd11_fhstatfs, sys_fhstatfs), // 398
7710 #else
7711 BSDXY(__NR_getfsstat, sys_getfsstat), // 395
7712 BSDXY(__NR_statfs, sys_statfs), // 396
7713 BSDXY(__NR_fstatfs, sys_fstatfs), // 397
7714 BSDXY(__NR_fhstatfs, sys_fhstatfs), // 398
7715 #endif
7717 // unimpl ksem_close 400
7718 // unimpl ksem_post 401
7719 // unimpl ksem_wait 402
7720 // unimpl ksem_trywait 403
7722 // unimpl ksem_init 404
7723 // unimpl ksem_open 405
7724 // unimpl ksem_unlink 406
7725 // unimpl ksem_getvalue 407
7727 // unimpl ksem_destroy 408
7728 // unimpl __mac_get_pid 409
7729 // unimpl __mac_get_link 410
7730 // unimpl __mac_set_link 411
7732 BSDX_(__NR_extattr_set_link, sys_extattr_set_link), // 412
7733 BSDXY(__NR_extattr_get_link, sys_extattr_get_link), // 413
7734 BSDX_(__NR_extattr_delete_link, sys_extattr_delete_link), // 414
7735 // unimpl __mac_execve 415
7737 BSDXY(__NR_sigaction, sys_sigaction), // 416
7738 BSDX_(__NR_sigreturn, sys_sigreturn), // 417
7740 BSDXY(__NR_getcontext, sys_getcontext), // 421
7741 BSDX_(__NR_setcontext, sys_setcontext), // 422
7742 BSDXY(__NR_swapcontext, sys_swapcontext), // 423
7744 #if (FREEBSD_VERS >= FREEBSD_13_1)
7745 BSDX_(__NR_freebsd13_swapoff, sys_freebsd13_swapoff), // 424
7746 #else
7747 BSDX_(__NR_swapoff, sys_swapoff), // 424
7748 #endif
7749 BSDXY(__NR___acl_get_link, sys___acl_get_link), // 425
7750 BSDX_(__NR___acl_set_link, sys___acl_set_link), // 426
7751 BSDX_(__NR___acl_delete_link, sys___acl_delete_link), // 427
7753 BSDX_(__NR___acl_aclcheck_link, sys___acl_aclcheck_link), // 428
7754 BSDXY(__NR_sigwait, sys_sigwait), // 429
7755 BSDX_(__NR_thr_create, sys_thr_create), // 430
7756 BSDX_(__NR_thr_exit, sys_thr_exit), // 431
7758 BSDXY(__NR_thr_self, sys_thr_self), // 432
7759 BSDXY(__NR_thr_kill, sys_thr_kill), // 433
7760 #if (FREEBSD_VERS <= FREEBSD_10)
7761 BSDXY(__NR__umtx_lock, sys__umtx_lock), // 434
7762 BSDXY(__NR__umtx_unlock, sys__umtx_unlock), // 435
7763 #endif
7765 BSDX_(__NR_jail_attach, sys_jail_attach), // 436
7766 BSDXY(__NR_extattr_list_fd, sys_extattr_list_fd), // 437
7767 BSDXY(__NR_extattr_list_file, sys_extattr_list_file), // 438
7768 BSDXY(__NR_extattr_list_link, sys_extattr_list_link), // 439
7770 // obs kse_switchin 440
7771 // unimpl ksem_timedwait 441
7772 BSDX_(__NR_thr_suspend, sys_thr_suspend), // 442
7773 BSDX_(__NR_thr_wake, sys_thr_wake), // 443
7774 BSDX_(__NR_kldunloadf, sys_kldunloadf), // 444
7775 // unimpl audit 445
7776 // unimpl auditon 446
7777 // unimpl getauid 447
7779 // unimpl setauid 448
7780 // unimpl getaudit 449
7781 // unimpl setaudit 450
7782 // unimpl getaudit_addr 451
7783 // unimpl setaudit_addr 452
7784 // unimpl auditctl 453
7785 BSDXY(__NR__umtx_op, sys__umtx_op), // 454
7786 BSDX_(__NR_thr_new, sys_thr_new), // 455
7788 BSDX_(__NR_sigqueue, sys_sigqueue), // 456
7789 BSDXY(__NR_kmq_open, sys_kmq_open), // 457
7790 BSDX_(__NR_kmq_setattr, sys_kmq_setattr), // 458
7791 BSDXY(__NR_kmq_timedreceive, sys_kmq_timedreceive), // 459
7793 BSDX_(__NR_kmq_timedsend, sys_kmq_timedsend), // 460
7794 BSDX_(__NR_kmq_notify, sys_kmq_notify), // 461
7795 BSDX_(__NR_kmq_unlink, sys_kmq_unlink), // 462
7796 BSDX_(__NR_abort2, sys_abort2), // 463
7798 BSDX_(__NR_thr_set_name, sys_thr_set_name), // 464
7799 BSDX_(__NR_aio_fsync, sys_aio_fsync), // 465
7800 BSDXY(__NR_rtprio_thread, sys_rtprio_thread), // 466
7802 // unimpl sctp_peeloff 471
7803 BSDX_(__NR_sctp_generic_sendmsg, sys_sctp_generic_sendmsg), // 472
7804 // unimpl sctp_generic_sendmsg_iov 473
7805 BSDXY(__NR_sctp_generic_recvmsg, sys_sctp_generic_recvmsg), // 474
7806 BSDXY(__NR_pread, sys_pread), // 475
7808 BSDX_(__NR_pwrite, sys_pwrite), // 476
7809 BSDX_(__NR_mmap, sys_mmap), // 477
7810 BSDX_(__NR_lseek, sys_lseek), // 478
7811 BSDX_(__NR_truncate, sys_truncate), // 479
7812 BSDX_(__NR_ftruncate, sys_ftruncate), // 480
7813 BSDXY(__NR_thr_kill2, sys_thr_kill2), // 481
7814 BSDXY(__NR_shm_open, sys_shm_open), // 482
7815 BSDX_(__NR_shm_unlink, sys_shm_unlink), // 483
7817 BSDXY(__NR_cpuset, sys_cpuset), // 484
7818 BSDX_(__NR_cpuset_setid, sys_cpuset_setid), // 485
7819 BSDXY(__NR_cpuset_getid, sys_cpuset_getid), // 486
7821 BSDXY(__NR_cpuset_getaffinity, sys_cpuset_getaffinity), // 487
7822 BSDX_(__NR_cpuset_setaffinity, sys_cpuset_setaffinity), // 488
7823 BSDX_(__NR_faccessat, sys_faccessat), // 489
7824 BSDX_(__NR_fchmodat, sys_fchmodat), // 490
7825 BSDX_(__NR_fchownat, sys_fchownat), // 491
7827 BSDX_(__NR_fexecve, sys_fexecve), // 492
7828 #if (FREEBSD_VERS >= FREEBSD_12)
7829 BSDXY(__NR_freebsd11_fstatat, sys_freebsd11_fstatat), // 493
7830 #else
7831 BSDXY(__NR_fstatat, sys_fstatat), // 493
7832 #endif
7833 BSDX_(__NR_futimesat, sys_futimesat), // 494
7834 BSDX_(__NR_linkat, sys_linkat), // 495
7836 BSDX_(__NR_mkdirat, sys_mkdirat), // 496
7837 BSDX_(__NR_mkfifoat, sys_mkfifoat), // 497
7839 #if (FREEBSD_VERS >= FREEBSD_12)
7840 BSDX_(__NR_freebsd11_mknodat, sys_freebsd11_mknodat), // 498
7841 #else
7842 BSDX_(__NR_mknodat, sys_mknodat), // 498
7843 #endif
7845 BSDXY(__NR_openat, sys_openat), // 499
7847 BSDXY(__NR_readlinkat, sys_readlinkat), // 500
7848 BSDX_(__NR_renameat, sys_renameat), // 501
7849 BSDX_(__NR_symlinkat, sys_symlinkat), // 502
7850 BSDX_(__NR_unlinkat, sys_unlinkat), // 503
7852 BSDX_(__NR_posix_openpt, sys_posix_openpt), // 504
7853 // unimp gssd_syscall 505
7854 BSDX_(__NR_jail_get, sys_jail_get), // 506
7855 BSDX_(__NR_jail_set, sys_jail_set), // 507
7856 BSDX_(__NR_jail_remove, sys_jail_remove), // 508
7857 BSDXY(__NR_closefrom, sys_closefrom), // 509
7858 BSDXY(__NR___semctl, sys___semctl), // 510
7859 BSDXY(__NR_msgctl, sys_msgctl), // 511
7860 BSDXY(__NR_shmctl, sys_shmctl), // 512
7861 BSDX_(__NR_lpathconf, sys_lpathconf), // 513
7862 /* 514 is obsolete cap_new */
7863 BSDXY(__NR___cap_rights_get, sys_cap_rights_get), // 515
7864 BSDX_(__NR_cap_enter, sys_cap_enter), // 516
7865 BSDXY(__NR_cap_getmode, sys_cap_getmode), // 517
7866 BSDXY(__NR_pdfork, sys_pdfork), // 518
7867 BSDX_(__NR_pdkill, sys_pdkill), // 519
7868 BSDXY(__NR_pdgetpid, sys_pdgetpid), // 520
7869 BSDXY(__NR_pselect, sys_pselect), // 522
7870 BSDXY(__NR_getloginclass, sys_getloginclass), // 523
7871 BSDX_(__NR_setloginclass, sys_setloginclass), // 524
7872 BSDXY(__NR_rctl_get_racct, sys_rctl_get_racct), // 525
7873 BSDXY(__NR_rctl_get_rules, sys_rctl_get_rules), // 526
7874 BSDXY(__NR_rctl_get_limits, sys_rctl_get_limits), // 527
7875 BSDXY(__NR_rctl_add_rule, sys_rctl_add_rule), // 528
7876 BSDXY(__NR_rctl_remove_rule, sys_rctl_remove_rule), // 529
7877 BSDX_(__NR_posix_fallocate, sys_posix_fallocate), // 530
7878 BSDX_(__NR_posix_fadvise, sys_posix_fadvise), // 531
7879 BSDXY(__NR_wait6, sys_wait6), // 532
7880 BSDX_(__NR_cap_rights_limit, sys_cap_rights_limit), // 533
7881 BSDX_(__NR_cap_ioctls_limit, sys_cap_ioctls_limit), // 534
7882 BSDXY(__NR_cap_ioctls_get, sys_cap_ioctls_get), // 535
7883 BSDX_(__NR_cap_fcntls_limit, sys_cap_fcntls_limit), // 536
7884 BSDXY(__NR_cap_fcntls_get, sys_cap_fcntls_get), // 537
7885 BSDX_(__NR_bindat, sys_bindat), // 538
7886 BSDX_(__NR_connectat, sys_connectat), // 539
7887 BSDX_(__NR_chflagsat, sys_chflagsat), // 540
7888 BSDXY(__NR_accept4, sys_accept4), // 541
7889 BSDXY(__NR_pipe2, sys_pipe2), // 542
7890 BSDX_(__NR_aio_mlock, sys_aio_mlock), // 543
7891 BSDXY(__NR_procctl, sys_procctl), // 544
7893 // 544 is the highest syscall on FreeBSD 9
7895 #if (FREEBSD_VERS >= FREEBSD_10)
7897 BSDXY(__NR_ppoll, sys_ppoll), // 545
7898 BSDX_(__NR_futimens, sys_futimens), // 546
7899 BSDX_(__NR_utimensat, sys_utimensat), // 547
7901 #endif // FREEBSD_VERS >= FREEBSD_10
7903 #if (FREEBSD_VERS >= FREEBSD_11)
7905 /* 548 is obsolete numa_getaffinity */
7906 /* 549 is obsolete numa_setaffinity */
7907 BSDX_(__NR_fdatasync, sys_fdatasync), // 550
7909 #endif // FREEBSD_VERS >= FREEBSD_11
7911 #if (FREEBSD_VERS >= FREEBSD_12)
7912 BSDXY(__NR_fstat, sys_fstat), // 551
7913 BSDXY(__NR_fstatat, sys_fstatat), // 552
7914 BSDXY(__NR_fhstat, sys_fhstat), // 553
7915 BSDXY(__NR_getdirentries, sys_getdirentries), // 554
7916 BSDXY(__NR_statfs, sys_statfs), // 555
7917 BSDXY(__NR_fstatfs, sys_fstatfs), // 556
7918 BSDXY(__NR_getfsstat, sys_getfsstat), // 557
7919 BSDXY(__NR_fhstatfs, sys_fhstatfs), // 558
7920 BSDX_(__NR_mknodat, sys_mknodat), // 559
7921 BSDXY(__NR_kevent, sys_kevent), // 560
7922 BSDXY(__NR_cpuset_getdomain, sys_cpuset_getdomain), // 561
7923 BSDX_(__NR_cpuset_setdomain, sys_cpuset_setdomain), // 562
7924 BSDXY(__NR_getrandom, sys_getrandom), // 563
7925 BSDXY(__NR_getfhat, sys_getfhat), // 564
7926 BSDX_(__NR_fhlink, sys_fhlink), // 565
7927 BSDX_(__NR_fhlinkat, sys_fhlinkat), // 566
7928 BSDXY(__NR_fhreadlink, sys_fhreadlink), // 567
7929 #endif // FREEBSD_VERS >= FREEBSD_12
7931 #if (FREEBSD_VERS >= FREEBSD_12_2)
7932 BSDX_(__NR_funlinkat, sys_funlinkat), // 568
7933 BSDX_(__NR_copy_file_range, sys_copy_file_range), // 569
7934 BSDXY(__NR___sysctlbyname, sys___sysctlbyname), // 570
7936 #if (FREEBSD_VERS >= FREEBSD_13_0)
7937 BSDXY(__NR_shm_open2, sys_shm_open2), // 571
7938 // unimpl __NR_shm_rename 572
7939 BSDX_(__NR_sigfastblock, sys_sigfastblock), // 573
7940 BSDXY( __NR___realpathat, sys___realpathat), // 574
7941 #endif
7942 BSDXY(__NR_close_range, sys_close_range), // 575
7943 #endif
7945 #if (FREEBSD_VERS >= FREEBSD_13_0)
7946 // unimpl __NR_rpctls_syscall 576
7947 BSDX_(__NR___specialfd, sys___specialfd), // 577
7948 BSDX_(__NR_aio_writev, sys_aio_writev), // 578
7949 BSDXY(__NR_aio_readv, sys_aio_readv), // 579
7950 #endif
7952 #if (FREEBSD_VERS >= FREEBSD_13_1)
7954 #if (FREEBSD_VERS >= FREEBSD_14_0)
7955 BSDXY(__NR_fspacectl, sys_fspacectl), // 580
7956 #endif
7957 // unimpl __NR_sched_getcpu 581
7958 BSDX_(__NR_swapoff, sys_swapoff), // 582
7959 #endif
7961 #if (FREEBSD_VERS >= FREEBSD_15) || (FREEBSD_VERS >= FREEBSD_13_3)
7962 BSDXY(__NR_kqueuex, sys_kqueuex), // 583
7963 BSDX_(__NR_membarrier, sys_membarrier), // 584
7964 #endif
7965 #if (FREEBSD_VERS >= FREEBSD_14_0) || (FREEBSD_VERS >= FREEBSD_13_4)
7966 BSDXY(__NR_timerfd_create, sys_timerfd_create), // 585
7967 BSDXY(__NR_timerfd_settime, sys_timerfd_settime), // 586
7968 BSDXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 587
7969 #endif
7970 #if (FREEBSD_VERS >= FREEBSD_14_1) || (FREEBSD_VERS >= FREEBSD_13_4)
7971 BSDX_(__NR_kcmp, sys_kcmp), // 588
7972 #endif
7976 BSDX_(__NR_fake_sigreturn, sys_fake_sigreturn), // 1000, fake sigreturn
7980 const SyscallTableEntry* ML_(get_freebsd_syscall_entry) ( UInt sysno )
7982 const UInt syscall_table_size
7983 = sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
7985 /* Is it in the contiguous initial section of the table? */
7986 if (sysno < syscall_table_size) {
7987 const SyscallTableEntry* sys = &ML_(syscall_table)[sysno];
7988 if (sys->before == NULL) {
7989 return NULL; /* no entry */
7991 return sys;
7994 /* Can't find a wrapper */
7995 return NULL;
7998 /*--------------------------------------------------------------------*/
7999 /*--- end ---*/
8000 /*--------------------------------------------------------------------*/
8002 #endif // defined(VGO_freebsd)