Command line help - demangling isn't just for C++
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob60e05a46c42237094409e199fa8b1608e7369413
2 /*--------------------------------------------------------------------*/
3 /*--- Linux-specific syscalls, etc. syswrap-linux.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Nicholas Nethercote
11 njn@valgrind.org
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGO_linux)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
37 #include "pub_core_transtab.h" // VG_(discard_translations)
38 #include "pub_core_xarray.h"
39 #include "pub_core_clientstate.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcfile.h"
44 #include "pub_core_libcprint.h"
45 #include "pub_core_libcproc.h"
46 #include "pub_core_libcsignal.h"
47 #include "pub_core_machine.h" // VG_(get_SP)
48 #include "pub_core_mallocfree.h"
49 #include "pub_core_tooliface.h"
50 #include "pub_core_options.h"
51 #include "pub_core_scheduler.h"
52 #include "pub_core_signals.h"
53 #include "pub_core_stacks.h"
54 #include "pub_core_syscall.h"
55 #include "pub_core_syswrap.h"
56 #include "pub_core_inner.h"
57 #if defined(ENABLE_INNER_CLIENT_REQUEST)
58 #include "pub_core_clreq.h"
59 #endif
61 #include "priv_types_n_macros.h"
62 #include "priv_syswrap-generic.h"
63 #include "priv_syswrap-linux.h"
64 #include "priv_syswrap-main.h"
65 #include "priv_syswrap-xen.h"
67 // Run a thread from beginning to end and return the thread's
68 // scheduler-return-code.
69 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
71 VgSchedReturnCode ret;
72 ThreadId tid = (ThreadId)tidW;
73 Int lwpid = VG_(gettid)();
74 ThreadState* tst = VG_(get_ThreadState)(tid);
76 VG_(debugLog)(1, "syswrap-linux",
77 "thread_wrapper(tid=%u,lwpid=%d): entry\n",
78 tid, lwpid);
80 vg_assert(tst->status == VgTs_Init);
82 /* make sure we get the CPU lock before doing anything significant */
83 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
85 if (0)
86 VG_(printf)("thread tid %u started: stack = %p\n",
87 tid, (void *)&tid);
89 /* Make sure error reporting is enabled in the new thread. */
90 tst->err_disablement_level = 0;
92 VG_TRACK(pre_thread_first_insn, tid);
94 tst->os_state.lwpid = lwpid;
95 /* Set the threadgroup for real. This overwrites the provisional value set
96 in do_clone(). See comments in do_clone for background, also #226116. */
97 tst->os_state.threadgroup = VG_(getpid)();
99 /* Thread created with all signals blocked; scheduler will set the
100 appropriate mask */
102 ret = VG_(scheduler)(tid);
104 vg_assert(VG_(is_exiting)(tid));
106 vg_assert(tst->status == VgTs_Runnable);
107 vg_assert(VG_(is_running_thread)(tid));
109 VG_(debugLog)(1, "syswrap-linux",
110 "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n",
111 tid, lwpid, VG_(name_of_VgSchedReturnCode)(ret));
113 /* Return to caller, still holding the lock. */
114 return ret;
118 /* ---------------------------------------------------------------------
119 clone-related stuff
120 ------------------------------------------------------------------ */
122 /* Run a thread all the way to the end, then do appropriate exit actions
123 (this is the last-one-out-turn-off-the-lights bit). */
124 static void run_a_thread_NORETURN ( Word tidW )
126 ThreadId tid = (ThreadId)tidW;
127 VgSchedReturnCode src;
128 Int c;
129 ThreadState* tst;
130 #ifdef ENABLE_INNER_CLIENT_REQUEST
131 Int registered_vgstack_id;
132 #endif
134 VG_(debugLog)(1, "syswrap-linux",
135 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
136 tid);
138 tst = VG_(get_ThreadState)(tid);
139 vg_assert(tst);
141 /* An thread has two stacks:
142 * the simulated stack (used by the synthetic cpu. Guest process
143 is using this stack).
144 * the valgrind stack (used by the real cpu. Valgrind code is running
145 on this stack).
146 When Valgrind runs as an inner, it must signals that its (real) stack
147 is the stack to use by the outer to e.g. do stacktraces.
149 INNER_REQUEST
150 (registered_vgstack_id
151 = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
152 tst->os_state.valgrind_stack_init_SP));
154 /* Run the thread all the way through. */
155 src = thread_wrapper(tid);
157 VG_(debugLog)(1, "syswrap-linux",
158 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
159 tid);
161 c = VG_(count_living_threads)();
162 vg_assert(c >= 1); /* stay sane */
164 /* Deregister thread's stack. */
165 if (tst->os_state.stk_id != NULL_STK_ID)
166 VG_(deregister_stack)(tst->os_state.stk_id);
168 // Tell the tool this thread is exiting
169 VG_TRACK( pre_thread_ll_exit, tid );
171 /* If the thread is exiting with errors disabled, complain loudly;
172 doing so is bad (does the user know this has happened?) Also,
173 in all cases, be paranoid and clear the flag anyway so that the
174 thread slot is safe in this respect if later reallocated. This
175 should be unnecessary since the flag should be cleared when the
176 slot is reallocated, in thread_wrapper(). */
177 if (tst->err_disablement_level > 0) {
178 VG_(umsg)(
179 "WARNING: exiting thread has error reporting disabled.\n"
180 "WARNING: possibly as a result of some mistake in the use\n"
181 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
183 VG_(debugLog)(
184 1, "syswrap-linux",
185 "run_a_thread_NORETURN(tid=%u): "
186 "WARNING: exiting thread has err_disablement_level = %u\n",
187 tid, tst->err_disablement_level
190 tst->err_disablement_level = 0;
192 if (c == 1) {
194 VG_(debugLog)(1, "syswrap-linux",
195 "run_a_thread_NORETURN(tid=%u): "
196 "last one standing\n",
197 tid);
199 /* We are the last one standing. Keep hold of the lock and
200 carry on to show final tool results, then exit the entire system.
201 Use the continuation pointer set at startup in m_main. */
202 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
203 } else {
205 VG_(debugLog)(1, "syswrap-linux",
206 "run_a_thread_NORETURN(tid=%u): "
207 "not last one standing\n",
208 tid);
210 /* OK, thread is dead, but others still exist. Just exit. */
212 /* This releases the run lock */
213 VG_(exit_thread)(tid);
214 vg_assert(tst->status == VgTs_Zombie);
215 vg_assert(sizeof(tst->status) == 4);
216 vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
218 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
220 /* We have to use this sequence to terminate the thread to
221 prevent a subtle race. If VG_(exit_thread)() had left the
222 ThreadState as Empty, then it could have been reallocated,
223 reusing the stack while we're doing these last cleanups.
224 Instead, VG_(exit_thread) leaves it as Zombie to prevent
225 reallocation. We need to make sure we don't touch the stack
226 between marking it Empty and exiting. Hence the
227 assembler. */
228 #if defined(VGP_x86_linux)
229 asm volatile (
230 "pushl %%ebx\n"
231 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
232 "movl %2, %%eax\n" /* set %eax = __NR_exit */
233 "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
234 "int $0x80\n" /* exit(tst->os_state.exitcode) */
235 "popl %%ebx\n"
236 : "=m" (tst->status)
237 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
238 : "eax"
240 #elif defined(VGP_amd64_linux)
241 asm volatile (
242 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
243 "movq %2, %%rax\n" /* set %rax = __NR_exit */
244 "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
245 "syscall\n" /* exit(tst->os_state.exitcode) */
246 : "=m" (tst->status)
247 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
248 : "rax", "rdi"
250 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
251 || defined(VGP_ppc64le_linux)
252 { UInt vgts_empty = (UInt)VgTs_Empty;
253 asm volatile (
254 "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
255 "li 0,%2\n\t" /* set r0 = __NR_exit */
256 "lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
257 "sc\n\t" /* exit(tst->os_state.exitcode) */
258 : "=m" (tst->status)
259 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
260 : "r0", "r3"
263 #elif defined(VGP_arm_linux)
264 asm volatile (
265 "str %1, %0\n" /* set tst->status = VgTs_Empty */
266 "mov r7, %2\n" /* set %r7 = __NR_exit */
267 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
268 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
269 : "=m" (tst->status)
270 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
271 : "r0", "r7"
273 #elif defined(VGP_arm64_linux)
274 asm volatile (
275 "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */
276 "mov x8, %2\n" /* set %x8 = __NR_exit */
277 "ldr x0, %3\n" /* set %x0 = tst->os_state.exitcode */
278 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
279 : "=m" (tst->status)
280 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
281 : "x0", "x8"
283 #elif defined(VGP_s390x_linux)
284 asm volatile (
285 "st %1, %0\n" /* set tst->status = VgTs_Empty */
286 "lg 2, %3\n" /* set r2 = tst->os_state.exitcode */
287 "svc %2\n" /* exit(tst->os_state.exitcode) */
288 : "=m" (tst->status)
289 : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
290 : "2"
292 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
293 asm volatile (
294 "sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
295 "li $2, %2\n\t" /* set v0 = __NR_exit */
296 "lw $4, %3\n\t" /* set a0 = tst->os_state.exitcode */
297 "syscall\n\t" /* exit(tst->os_state.exitcode) */
298 "nop"
299 : "=m" (tst->status)
300 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
301 : "cc", "memory" , "v0", "a0"
303 #elif defined(VGP_nanomips_linux)
304 asm volatile (
305 "sw %1, %0 \n\t" /* set tst->status = VgTs_Empty */
306 "li $t4, %2 \n\t" /* set t4 = __NR_exit */
307 "lw $a0, %3 \n\t" /* set a0 = tst->os_state.exitcode */
308 "syscall[32] \n\t" /* exit(tst->os_state.exitcode) */
309 : "=m" (tst->status)
310 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
311 : "memory" , "$t4", "$a0"
313 #else
314 # error Unknown platform
315 #endif
317 VG_(core_panic)("Thread exit failed?\n");
320 /*NOTREACHED*/
321 vg_assert(0);
324 Word ML_(start_thread_NORETURN) ( void* arg )
326 ThreadState* tst = (ThreadState*)arg;
327 ThreadId tid = tst->tid;
329 run_a_thread_NORETURN ( (Word)tid );
330 /*NOTREACHED*/
331 vg_assert(0);
334 /* Allocate a stack for this thread, if it doesn't already have one.
335 They're allocated lazily, and never freed. Returns the initial stack
336 pointer value to use, or 0 if allocation failed. */
337 Addr ML_(allocstack)(ThreadId tid)
339 ThreadState* tst = VG_(get_ThreadState)(tid);
340 VgStack* stack;
341 Addr initial_SP;
343 /* Either the stack_base and stack_init_SP are both zero (in which
344 case a stack hasn't been allocated) or they are both non-zero,
345 in which case it has. */
347 if (tst->os_state.valgrind_stack_base == 0)
348 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
350 if (tst->os_state.valgrind_stack_base != 0)
351 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
353 /* If no stack is present, allocate one. */
355 if (tst->os_state.valgrind_stack_base == 0) {
356 stack = VG_(am_alloc_VgStack)( &initial_SP );
357 if (stack) {
358 tst->os_state.valgrind_stack_base = (Addr)stack;
359 tst->os_state.valgrind_stack_init_SP = initial_SP;
363 if (0)
364 VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
365 tid,
366 (void*)tst->os_state.valgrind_stack_base,
367 (void*)tst->os_state.valgrind_stack_init_SP );
369 return tst->os_state.valgrind_stack_init_SP;
372 /* Allocate a stack for the main thread, and run it all the way to the
373 end. Although we already have a working VgStack
374 (VG_(interim_stack)) it's better to allocate a new one, so that
375 overflow detection works uniformly for all threads.
377 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
379 Addr sp;
380 VG_(debugLog)(1, "syswrap-linux",
381 "entering VG_(main_thread_wrapper_NORETURN)\n");
383 sp = ML_(allocstack)(tid);
384 #if defined(ENABLE_INNER_CLIENT_REQUEST)
386 // we must register the main thread stack before the call
387 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
388 // reports 'write error' on the non registered stack.
389 ThreadState* tst = VG_(get_ThreadState)(tid);
390 INNER_REQUEST
391 ((void)
392 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
393 tst->os_state.valgrind_stack_init_SP));
395 #endif
397 #if defined(VGP_ppc32_linux)
398 /* make a stack frame */
399 sp -= 16;
400 sp &= ~0xF;
401 *(UWord *)sp = 0;
402 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
403 /* make a stack frame */
404 sp -= 112;
405 sp &= ~((Addr)0xF);
406 *(UWord *)sp = 0;
407 #elif defined(VGP_s390x_linux)
408 /* make a stack frame */
409 sp -= 160;
410 sp &= ~((Addr)0xF);
411 *(UWord *)sp = 0;
412 #endif
414 /* If we can't even allocate the first thread's stack, we're hosed.
415 Give up. */
416 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
418 /* shouldn't be any other threads around yet */
419 vg_assert( VG_(count_living_threads)() == 1 );
421 ML_(call_on_new_stack_0_1)(
422 (Addr)sp, /* stack */
423 0, /* bogus return address */
424 run_a_thread_NORETURN, /* fn to call */
425 (Word)tid /* arg to give it */
428 /*NOTREACHED*/
429 vg_assert(0);
432 /* Clone a new thread. Note that in the clone syscalls, we hard-code
433 tlsaddr argument as NULL : the guest TLS is emulated via guest
434 registers, and Valgrind itself has no thread local storage. */
435 static SysRes clone_new_thread ( Word (*fn)(void *),
436 void* stack,
437 Word flags,
438 ThreadState* ctst,
439 Int* child_tidptr,
440 Int* parent_tidptr)
442 SysRes res;
443 /* Note that in all the below, we make sys_clone appear to have returned
444 Success(0) in the child, by assigning the relevant child guest
445 register(s) just before the clone syscall. */
446 #if defined(VGP_x86_linux)
447 Int eax;
448 ctst->arch.vex.guest_EAX = 0;
449 eax = do_syscall_clone_x86_linux
450 (ML_(start_thread_NORETURN), stack, flags, ctst,
451 child_tidptr, parent_tidptr, NULL);
452 res = VG_(mk_SysRes_x86_linux)( eax );
453 #elif defined(VGP_amd64_linux)
454 Long rax;
455 ctst->arch.vex.guest_RAX = 0;
456 rax = do_syscall_clone_amd64_linux
457 (ML_(start_thread_NORETURN), stack, flags, ctst,
458 child_tidptr, parent_tidptr, NULL);
459 res = VG_(mk_SysRes_amd64_linux)( rax );
460 #elif defined(VGP_ppc32_linux)
461 ULong word64;
462 UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
463 /* %r3 = 0 */
464 ctst->arch.vex.guest_GPR3 = 0;
465 /* %cr0.so = 0 */
466 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
467 word64 = do_syscall_clone_ppc32_linux
468 (ML_(start_thread_NORETURN), stack, flags, ctst,
469 child_tidptr, parent_tidptr, NULL);
470 /* High half word64 is syscall return value. Low half is
471 the entire CR, from which we need to extract CR0.SO. */
472 /* VG_(printf)("word64 = 0x%llx\n", word64); */
473 res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
474 /*errflag*/ (((UInt)word64) >> 28) & 1);
475 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
476 ULong word64;
477 UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
478 UInt flag = ctst->arch.vex.guest_syscall_flag;
479 /* %r3 = 0 */
480 ctst->arch.vex.guest_GPR3 = 0;
481 /* %cr0.so = 0 */
482 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
483 word64 = do_syscall_clone_ppc64_linux
484 (ML_(start_thread_NORETURN), stack, flags, ctst,
485 child_tidptr, parent_tidptr, NULL);
486 /* Low half word64 is syscall return value. Hi half is
487 the entire CR, from which we need to extract CR0.SO. */
488 /* VG_(printf)("word64 = 0x%llx\n", word64); */
489 res = VG_(mk_SysRes_ppc64_linux)
490 (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
491 /*errflag*/ (UInt)((word64 >> (32+28)) & 1), flag);
492 #elif defined(VGP_s390x_linux)
493 ULong r2;
494 ctst->arch.vex.guest_r2 = 0;
495 r2 = do_syscall_clone_s390x_linux
496 (stack, flags, parent_tidptr, child_tidptr, NULL,
497 ML_(start_thread_NORETURN), ctst);
498 res = VG_(mk_SysRes_s390x_linux)( r2 );
499 #elif defined(VGP_arm64_linux)
500 ULong x0;
501 ctst->arch.vex.guest_X0 = 0;
502 x0 = do_syscall_clone_arm64_linux
503 (ML_(start_thread_NORETURN), stack, flags, ctst,
504 child_tidptr, parent_tidptr, NULL);
505 res = VG_(mk_SysRes_arm64_linux)( x0 );
506 #elif defined(VGP_arm_linux)
507 UInt r0;
508 ctst->arch.vex.guest_R0 = 0;
509 r0 = do_syscall_clone_arm_linux
510 (ML_(start_thread_NORETURN), stack, flags, ctst,
511 child_tidptr, parent_tidptr, NULL);
512 res = VG_(mk_SysRes_arm_linux)( r0 );
513 #elif defined(VGP_mips64_linux)
514 UInt ret = 0;
515 ctst->arch.vex.guest_r2 = 0;
516 ctst->arch.vex.guest_r7 = 0;
517 ret = do_syscall_clone_mips64_linux
518 (ML_(start_thread_NORETURN), stack, flags, ctst,
519 parent_tidptr, NULL, child_tidptr);
520 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
521 #elif defined(VGP_mips32_linux)
522 UInt ret = 0;
523 ctst->arch.vex.guest_r2 = 0;
524 ctst->arch.vex.guest_r7 = 0;
525 ret = do_syscall_clone_mips_linux
526 (ML_(start_thread_NORETURN), stack, flags, ctst,
527 child_tidptr, parent_tidptr, NULL);
528 /* High half word64 is syscall return value. Low half is
529 the entire CR, from which we need to extract CR0.SO. */
530 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
531 #elif defined(VGP_nanomips_linux)
532 UInt ret = 0;
533 ctst->arch.vex.guest_r4 = 0;
534 ret = do_syscall_clone_nanomips_linux
535 (ML_(start_thread_NORETURN), stack, flags, ctst,
536 child_tidptr, parent_tidptr, NULL);
537 res = VG_ (mk_SysRes_nanomips_linux) (ret);
538 #else
539 # error Unknown platform
540 #endif
541 return res;
544 static void setup_child ( /*OUT*/ ThreadArchState *child,
545 /*IN*/ ThreadArchState *parent )
547 /* We inherit our parent's guest state. */
548 child->vex = parent->vex;
549 child->vex_shadow1 = parent->vex_shadow1;
550 child->vex_shadow2 = parent->vex_shadow2;
552 #if defined(VGP_x86_linux)
553 extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
554 /*IN*/ ThreadArchState *parent );
555 ML_(x86_setup_LDT_GDT)(child, parent);
556 #endif
559 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
561 static const Bool debug = False;
562 ThreadState* ctst = VG_(get_ThreadState)(ctid);
563 // res is successful by default, overriden if a real syscall is needed/done.
564 SysRes res = VG_(mk_SysRes_Success)(0);
566 if (debug)
567 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
569 #if defined(VGP_x86_linux)
570 vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
571 if (debug)
572 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
573 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
574 tlsinfo, tlsinfo->entry_number,
575 tlsinfo->base_addr, tlsinfo->limit,
576 ctst->arch.vex.guest_ESP,
577 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
578 res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
579 #elif defined(VGP_amd64_linux)
580 ctst->arch.vex.guest_FS_CONST = tlsaddr;
581 #elif defined(VGP_ppc32_linux)
582 ctst->arch.vex.guest_GPR2 = tlsaddr;
583 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
584 ctst->arch.vex.guest_GPR13 = tlsaddr;
585 #elif defined(VGP_s390x_linux)
586 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
587 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
588 #elif defined(VGP_arm64_linux)
589 /* Just assign the tls pointer in the guest TPIDR_EL0. */
590 ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
591 #elif defined(VGP_arm_linux)
592 /* Just assign the tls pointer in the guest TPIDRURO. */
593 ctst->arch.vex.guest_TPIDRURO = tlsaddr;
594 #elif defined(VGP_mips64_linux)
595 ctst->arch.vex.guest_ULR = tlsaddr;
596 ctst->arch.vex.guest_r27 = tlsaddr;
597 #elif defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
598 ctst->arch.vex.guest_ULR = tlsaddr;
599 ctst->arch.vex.guest_r27 = tlsaddr;
600 #else
601 # error Unknown platform
602 #endif
603 return res;
607 When a client clones, we need to keep track of the new thread. This means:
608 1. allocate a ThreadId+ThreadState+stack for the thread
610 2. initialize the thread's new VCPU state
612 3. create the thread using the same args as the client requested,
613 but using the scheduler entrypoint for EIP, and a separate stack
614 for ESP.
616 static SysRes do_clone ( ThreadId ptid,
617 UWord flags, Addr sp,
618 Int* parent_tidptr,
619 Int* child_tidptr,
620 Addr tlsaddr)
622 ThreadId ctid = VG_(alloc_ThreadState)();
623 ThreadState* ptst = VG_(get_ThreadState)(ptid);
624 ThreadState* ctst = VG_(get_ThreadState)(ctid);
625 UWord* stack;
626 SysRes res;
627 vki_sigset_t blockall, savedmask;
629 VG_(sigfillset)(&blockall);
631 vg_assert(VG_(is_running_thread)(ptid));
632 vg_assert(VG_(is_valid_tid)(ctid));
634 stack = (UWord*)ML_(allocstack)(ctid);
635 if (stack == NULL) {
636 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
637 goto out;
640 /* Copy register state
642 Both parent and child return to the same place, and the code
643 following the clone syscall works out which is which, so we
644 don't need to worry about it.
646 The parent gets the child's new tid returned from clone, but the
647 child gets 0.
649 If the clone call specifies a NULL sp for the new thread, then
650 it actually gets a copy of the parent's sp.
652 setup_child( &ctst->arch, &ptst->arch );
654 if (sp != 0)
655 VG_(set_SP)(ctid, sp);
657 ctst->os_state.parent = ptid;
659 /* inherit signal mask */
660 ctst->sig_mask = ptst->sig_mask;
661 ctst->tmp_sig_mask = ptst->sig_mask;
663 /* Start the child with its threadgroup being the same as the
664 parent's. This is so that any exit_group calls that happen
665 after the child is created but before it sets its
666 os_state.threadgroup field for real (in thread_wrapper in
667 syswrap-linux.c), really kill the new thread. a.k.a this avoids
668 a race condition in which the thread is unkillable (via
669 exit_group) because its threadgroup is not set. The race window
670 is probably only a few hundred or a few thousand cycles long.
671 See #226116. */
672 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
674 ML_(guess_and_register_stack) (sp, ctst);
676 /* Assume the clone will succeed, and tell any tool that wants to
677 know that this thread has come into existence. We cannot defer
678 it beyond this point because setup_tls, just below,
679 causes checks to assert by making references to the new ThreadId
680 if we don't state the new thread exists prior to that point.
681 If the clone fails, we'll send out a ll_exit notification for it
682 at the out: label below, to clean up. */
683 vg_assert(VG_(owns_BigLock_LL)(ptid));
684 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
686 if (flags & VKI_CLONE_SETTLS) {
687 res = setup_child_tls(ctid, tlsaddr);
688 if (sr_isError(res))
689 goto out;
691 flags &= ~VKI_CLONE_SETTLS;
693 /* start the thread with everything blocked */
694 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
696 /* Create the new thread */
697 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
698 child_tidptr, parent_tidptr);
700 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
702 out:
703 if (sr_isError(res)) {
704 /* clone failed */
705 VG_(cleanup_thread)(&ctst->arch);
706 ctst->status = VgTs_Empty;
707 /* oops. Better tell the tool the thread exited in a hurry :-) */
708 VG_TRACK( pre_thread_ll_exit, ctid );
711 return res;
714 /* Do a clone which is really a fork().
715 ML_(do_fork_clone) uses the clone syscall to fork a child process.
716 Note that this should not be called for a thread creation.
717 Also, some flags combinations are not supported, and such combinations
718 are handled either by masking the non supported flags or by asserting.
720 The CLONE_VFORK flag is accepted, as this just tells that the parent is
721 suspended till the child exits or calls execve. We better keep this flag,
722 just in case the guests parent/client code depends on this synchronisation.
724 We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
725 instructions in the child process, that will mess up the parent host
726 memory. So, we hope for the best and assumes that the guest application does
727 not (really) depends on sharing the memory between parent and child in the
728 interval between clone and exits/execve.
730 If child_sp != 0, the child (guest) sp will be set to child_sp just after the
731 clone syscall, before child guest instructions are executed. */
732 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
733 Int* parent_tidptr, Int* child_tidptr,
734 Addr child_sp)
736 vki_sigset_t fork_saved_mask;
737 vki_sigset_t mask;
738 SysRes res;
740 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
741 | VKI_CLONE_FILES))
742 return VG_(mk_SysRes_Error)( VKI_EINVAL );
744 /* Block all signals during fork, so that we can fix things up in
745 the child without being interrupted. */
746 VG_(sigfillset)(&mask);
747 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
749 VG_(do_atfork_pre)(tid);
751 /* Since this is the fork() form of clone, we don't need all that
752 VG_(clone) stuff */
753 #if defined(VGP_x86_linux) \
754 || defined(VGP_ppc32_linux) \
755 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
756 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
757 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
758 || defined(VGP_nanomips_linux)
759 res = VG_(do_syscall5)( __NR_clone, flags,
760 (UWord)NULL, (UWord)parent_tidptr,
761 (UWord)NULL, (UWord)child_tidptr );
762 #elif defined(VGP_amd64_linux)
763 /* note that the last two arguments are the opposite way round to x86 and
764 ppc32 as the amd64 kernel expects the arguments in a different order */
765 res = VG_(do_syscall5)( __NR_clone, flags,
766 (UWord)NULL, (UWord)parent_tidptr,
767 (UWord)child_tidptr, (UWord)NULL );
768 #elif defined(VGP_s390x_linux)
769 /* Note that s390 has the stack first and then the flags */
770 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
771 (UWord)parent_tidptr, (UWord)child_tidptr);
772 #else
773 # error Unknown platform
774 #endif
776 if (!sr_isError(res) && sr_Res(res) == 0) {
777 /* child */
778 if (child_sp != 0)
779 VG_(set_SP)(tid, child_sp);
780 VG_(do_atfork_child)(tid);
782 /* restore signal mask */
783 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
785 else
786 if (!sr_isError(res) && sr_Res(res) > 0) {
787 /* parent */
788 VG_(do_atfork_parent)(tid);
790 if (VG_(clo_trace_syscalls))
791 VG_(printf)(" clone(fork): process %d created child %" FMT_REGWORD "u\n",
792 VG_(getpid)(), (RegWord)sr_Res(res));
794 /* restore signal mask */
795 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
798 return res;
801 /* ---------------------------------------------------------------------
802 PRE/POST wrappers for arch-generic, Linux-specific syscalls
803 ------------------------------------------------------------------ */
805 // Nb: See the comment above the generic PRE/POST wrappers in
806 // m_syswrap/syswrap-generic.c for notes about how they work.
808 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
809 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
811 PRE(sys_clone)
813 UInt cloneflags;
814 Bool badarg = False;
816 PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
817 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
818 ARG4, ARG5);
820 // Order of arguments differs between platforms.
821 #if defined(VGP_x86_linux) \
822 || defined(VGP_ppc32_linux) \
823 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
824 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
825 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
826 || defined(VGP_nanomips_linux)
827 #define ARG_CHILD_TIDPTR ARG5
828 #define PRA_CHILD_TIDPTR PRA5
829 #define ARG_TLS ARG4
830 #define PRA_TLS PRA4
831 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
832 #define ARG_CHILD_TIDPTR ARG4
833 #define PRA_CHILD_TIDPTR PRA4
834 #define ARG_TLS ARG5
835 #define PRA_TLS PRA5
836 #else
837 # error Unknown platform
838 #endif
839 // And s390x is even more special, and inverts flags and child stack args
840 #if defined(VGP_s390x_linux)
841 #define ARG_FLAGS ARG2
842 #define PRA_FLAGS PRA2
843 #define ARG_CHILD_STACK ARG1
844 #define PRA_CHILD_STACK PRA1
845 #else
846 #define ARG_FLAGS ARG1
847 #define PRA_FLAGS PRA1
848 #define ARG_CHILD_STACK ARG2
849 #define PRA_CHILD_STACK PRA2
850 #endif
852 if (VG_(tdict).track_pre_reg_read) {
853 PRA_FLAGS("clone", unsigned long, flags);
854 PRA_CHILD_STACK("clone", void *, child_stack);
857 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD)) {
858 if (VG_(tdict).track_pre_reg_read) {
859 PRA3("clone", int *, parent_tidptr);
861 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
862 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
863 VKI_PROT_WRITE)) {
864 badarg = True;
867 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
868 if (VG_(tdict).track_pre_reg_read) {
869 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
871 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
872 dummy type (that we define as a char). We only dereference/check the
873 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
874 if (sizeof(vki_modify_ldt_t) > 1) {
875 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
876 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
877 VKI_PROT_READ)) {
878 badarg = True;
882 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
883 if (VG_(tdict).track_pre_reg_read) {
884 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
886 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
887 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
888 VKI_PROT_WRITE)) {
889 badarg = True;
893 if (badarg) {
894 SET_STATUS_Failure( VKI_EFAULT );
895 return;
898 cloneflags = ARG_FLAGS;
900 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
901 SET_STATUS_Failure( VKI_EINVAL );
902 return;
905 /* Only look at the flags we really care about */
906 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
907 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
908 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
909 /* thread creation */
910 SET_STATUS_from_SysRes(
911 do_clone(tid,
912 ARG_FLAGS, /* flags */
913 (Addr)ARG_CHILD_STACK, /* child ESP */
914 (Int*)(Addr)ARG3, /* parent_tidptr */
915 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
916 (Addr)ARG_TLS)); /* set_tls */
917 break;
919 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
920 case VKI_CLONE_VFORK: /* vfork without memory sharing */
921 cloneflags &= ~VKI_CLONE_VM;
922 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
924 case 0: /* plain fork */
925 SET_STATUS_from_SysRes(
926 ML_(do_fork_clone)(tid,
927 cloneflags, /* flags */
928 (Int*)(Addr)ARG3, /* parent_tidptr */
929 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
930 (Addr)ARG_CHILD_STACK));
931 break;
933 default:
934 /* should we just ENOSYS? */
935 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
936 "x\n", ARG_FLAGS);
937 VG_(message)(Vg_UserMsg, "\n");
938 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
939 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
940 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
941 VG_(unimplemented)
942 ("Valgrind does not support general clone().");
945 if (SUCCESS && RES != 0) {
946 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD))
947 POST_MEM_WRITE(ARG3, sizeof(Int));
948 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
949 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
950 if (ARG_FLAGS & VKI_CLONE_PIDFD) {
951 Int fd = *(Int*)(Addr)ARG3;
952 if (!ML_(fd_allowed)(fd, "clone", tid, True)) {
953 VG_(close)(fd);
954 SET_STATUS_Failure( VKI_EMFILE );
955 } else {
956 if (VG_(clo_track_fds))
957 ML_(record_fd_open_nameless) (tid, fd);
961 /* Thread creation was successful; let the child have the chance
962 to run */
963 *flags |= SfYieldAfter;
966 #undef ARG_CHILD_TIDPTR
967 #undef PRA_CHILD_TIDPTR
968 #undef ARG_TLS
969 #undef PRA_TLS
970 #undef ARG_FLAGS
971 #undef PRA_FLAGS
972 #undef ARG_CHILD_STACK
973 #undef PRA_CHILD_STACK
976 /* ---------------------------------------------------------------------
977 *mount wrappers
978 ------------------------------------------------------------------ */
980 PRE(sys_mount)
982 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
983 // We are conservative and check everything, except the memory pointed to
984 // by 'data'.
985 *flags |= SfMayBlock;
986 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
987 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
988 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
989 (HChar*)(Addr)ARG3, ARG4, ARG5);
990 PRE_REG_READ5(long, "mount",
991 char *, source, char *, target, char *, type,
992 unsigned long, flags, void *, data);
993 if (ARG1)
994 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
995 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
996 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
999 PRE(sys_oldumount)
1001 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
1002 PRE_REG_READ1(long, "umount", char *, path);
1003 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
1006 PRE(sys_umount)
1008 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
1009 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
1010 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
1013 /* Not actually wrapped by GLibc but does things with the system
1014 * mounts so it is put here.
1016 PRE(sys_pivot_root)
1018 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
1019 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
1020 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
1021 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
1025 /* ---------------------------------------------------------------------
1026 16- and 32-bit uid/gid wrappers
1027 ------------------------------------------------------------------ */
1029 PRE(sys_setfsuid16)
1031 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1032 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1035 PRE(sys_setfsuid)
1037 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1038 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1041 PRE(sys_setfsgid16)
1043 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1044 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1047 PRE(sys_setfsgid)
1049 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1050 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1053 PRE(sys_setresuid16)
1055 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1056 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1057 PRE_REG_READ3(long, "setresuid16",
1058 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1061 PRE(sys_setresuid)
1063 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1064 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1065 PRE_REG_READ3(long, "setresuid",
1066 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1069 PRE(sys_getresuid16)
1071 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1072 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1073 PRE_REG_READ3(long, "getresuid16",
1074 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1075 vki_old_uid_t *, suid);
1076 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1077 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1078 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1080 POST(sys_getresuid16)
1082 vg_assert(SUCCESS);
1083 if (RES == 0) {
1084 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1085 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1086 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1090 PRE(sys_getresuid)
1092 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1093 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1094 PRE_REG_READ3(long, "getresuid",
1095 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1096 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1097 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1098 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1100 POST(sys_getresuid)
1102 vg_assert(SUCCESS);
1103 if (RES == 0) {
1104 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1105 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1106 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1110 PRE(sys_setresgid16)
1112 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1113 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1114 PRE_REG_READ3(long, "setresgid16",
1115 vki_old_gid_t, rgid,
1116 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1119 PRE(sys_setresgid)
1121 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1122 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1123 PRE_REG_READ3(long, "setresgid",
1124 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1127 PRE(sys_getresgid16)
1129 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1130 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1131 PRE_REG_READ3(long, "getresgid16",
1132 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1133 vki_old_gid_t *, sgid);
1134 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1135 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1136 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1138 POST(sys_getresgid16)
1140 vg_assert(SUCCESS);
1141 if (RES == 0) {
1142 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1143 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1144 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1148 PRE(sys_getresgid)
1150 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1151 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1152 PRE_REG_READ3(long, "getresgid",
1153 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1154 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1155 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1156 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1158 POST(sys_getresgid)
1160 vg_assert(SUCCESS);
1161 if (RES == 0) {
1162 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1163 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1164 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1168 /* ---------------------------------------------------------------------
1169 miscellaneous wrappers
1170 ------------------------------------------------------------------ */
1172 PRE(sys_exit_group)
1174 ThreadId t;
1175 ThreadState* tst;
1177 PRINT("exit_group( %ld )", SARG1);
1178 PRE_REG_READ1(void, "exit_group", int, status);
1180 tst = VG_(get_ThreadState)(tid);
1181 /* A little complex; find all the threads with the same threadgroup
1182 as this one (including this one), and mark them to exit */
1183 /* It is unclear how one can get a threadgroup in this process which
1184 is not the threadgroup of the calling thread:
1185 The assignments to threadgroups are:
1186 = 0; /// scheduler.c os_state_clear
1187 = getpid(); /// scheduler.c in child after fork
1188 = getpid(); /// this file, in thread_wrapper
1189 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1190 copying the thread group of the thread doing clone
1191 So, the only case where the threadgroup might be different to the getpid
1192 value is in the child, just after fork. But then the fork syscall is
1193 still going on, the forked thread has had no chance yet to make this
1194 syscall. */
1195 for (t = 1; t < VG_N_THREADS; t++) {
1196 if ( /* not alive */
1197 VG_(threads)[t].status == VgTs_Empty
1199 /* not our group */
1200 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1202 continue;
1203 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1204 the exitreason. */
1205 VG_(threads)[t].os_state.exitcode = ARG1;
1208 /* Indicate in all other threads that the process is exiting.
1209 Then wait using VG_(reap_threads) for these threads to disappear.
1211 Can this give a deadlock if another thread is calling exit in parallel
1212 and would then wait for this thread to disappear ?
1213 The answer is no:
1214 Other threads are either blocked in a syscall or have yielded the CPU.
1216 A thread that has yielded the CPU is trying to get the big lock in
1217 VG_(scheduler). This thread will get the CPU thanks to the call
1218 to VG_(reap_threads). The scheduler will then check for signals,
1219 kill the process if this is a fatal signal, and otherwise prepare
1220 the thread for handling this signal. After this preparation, if
1221 the thread status is VG_(is_exiting), the scheduler exits the thread.
1222 So, a thread that has yielded the CPU does not have a chance to
1223 call exit => no deadlock for this thread.
1225 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1226 to all threads blocked in a syscall.
1227 The syscall will be interrupted, and the control will go to the
1228 scheduler. The scheduler will then return, as the thread is in
1229 exiting state. */
1231 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1232 VG_(reap_threads)(tid);
1233 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1234 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1235 is the thread calling exit_group and so its registers must be considered
1236 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1238 /* We have to claim the syscall already succeeded. */
1239 SET_STATUS_Success(0);
1242 PRE(sys_llseek)
1244 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1245 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1246 ARG1, ARG2, ARG3, ARG4, ARG5);
1247 PRE_REG_READ5(long, "llseek",
1248 unsigned int, fd, unsigned long, offset_high,
1249 unsigned long, offset_low, vki_loff_t *, result,
1250 unsigned int, whence);
1251 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1252 SET_STATUS_Failure( VKI_EBADF );
1253 else
1254 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1256 POST(sys_llseek)
1258 vg_assert(SUCCESS);
1259 if (RES == 0)
1260 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1263 PRE(sys_adjtimex)
1265 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1266 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1267 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1269 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1270 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1272 #define ADJX(bits,field) \
1273 if (tx->modes & (bits)) \
1274 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1275 (Addr)&tx->field, sizeof(tx->field))
1277 if (tx->modes & VKI_ADJ_ADJTIME) {
1278 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1279 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1280 } else {
1281 ADJX(VKI_ADJ_OFFSET, offset);
1282 ADJX(VKI_ADJ_FREQUENCY, freq);
1283 ADJX(VKI_ADJ_MAXERROR, maxerror);
1284 ADJX(VKI_ADJ_ESTERROR, esterror);
1285 ADJX(VKI_ADJ_STATUS, status);
1286 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1287 ADJX(VKI_ADJ_TICK, tick);
1289 #undef ADJX
1292 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1295 POST(sys_adjtimex)
1297 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1300 PRE(sys_clock_adjtime)
1302 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1303 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1304 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1305 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1307 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1308 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1310 #define ADJX(bits,field) \
1311 if (tx->modes & (bits)) \
1312 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1313 (Addr)&tx->field, sizeof(tx->field))
1315 if (tx->modes & VKI_ADJ_ADJTIME) {
1316 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1317 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1318 } else {
1319 ADJX(VKI_ADJ_OFFSET, offset);
1320 ADJX(VKI_ADJ_FREQUENCY, freq);
1321 ADJX(VKI_ADJ_MAXERROR, maxerror);
1322 ADJX(VKI_ADJ_ESTERROR, esterror);
1323 ADJX(VKI_ADJ_STATUS, status);
1324 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1325 ADJX(VKI_ADJ_TICK, tick);
1327 #undef ADJX
1330 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1333 POST(sys_clock_adjtime)
1335 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1338 PRE(sys_ioperm)
1340 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1341 ARG1, ARG2, SARG3 );
1342 PRE_REG_READ3(long, "ioperm",
1343 unsigned long, from, unsigned long, num, int, turn_on);
1346 PRE(sys_syslog)
1348 *flags |= SfMayBlock;
1349 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1350 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1351 switch (ARG1) {
1352 // The kernel uses magic numbers here, rather than named constants,
1353 // therefore so do we.
1354 case 2: case 3: case 4:
1355 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1356 break;
1357 default:
1358 break;
1361 POST(sys_syslog)
1363 switch (ARG1) {
1364 case 2: case 3: case 4:
1365 POST_MEM_WRITE( ARG2, ARG3 );
1366 break;
1367 default:
1368 break;
1372 PRE(sys_vhangup)
1374 PRINT("sys_vhangup ( )");
1375 PRE_REG_READ0(long, "vhangup");
1378 PRE(sys_sysinfo)
1380 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1381 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1382 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1384 POST(sys_sysinfo)
1386 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1389 PRE(sys_personality)
1391 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1392 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1395 PRE(sys_sysctl)
1397 struct __vki_sysctl_args *args;
1398 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1399 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1400 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1401 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1402 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1403 VKI_PROT_READ)) {
1404 SET_STATUS_Failure( VKI_EFAULT );
1405 return;
1408 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1409 if (args->newval != NULL)
1410 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1411 if (args->oldlenp != NULL) {
1412 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1413 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1416 POST(sys_sysctl)
1418 struct __vki_sysctl_args *args;
1419 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1420 if (args->oldlenp != NULL) {
1421 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1422 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1426 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1427 const char *attr_name)
1429 const HChar *step_str = (const HChar *)str;
1430 SizeT len;
1431 UInt i;
1434 * The name can be up to maxlen bytes long, including the terminating null
1435 * byte. So do not check more than maxlen bytes.
1437 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1438 len = VG_(strnlen)((const HChar *)str, maxlen);
1439 if (len < maxlen)
1440 PRE_MEM_RASCIIZ(attr_name, str);
1441 else
1442 PRE_MEM_READ(attr_name, str, maxlen);
1443 } else {
1445 * Do it the slow way, one byte at a time, while checking for terminating
1446 * '\0'.
1448 for (i = 0; i < maxlen; i++) {
1449 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1450 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1451 break;
1456 PRE(sys_prctl)
1458 *flags |= SfMayBlock;
1459 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1460 switch (ARG1) {
1461 case VKI_PR_SET_PDEATHSIG:
1462 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1463 break;
1464 case VKI_PR_GET_PDEATHSIG:
1465 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1466 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1467 break;
1468 case VKI_PR_GET_DUMPABLE:
1469 PRE_REG_READ1(int, "prctl", int, option);
1470 break;
1471 case VKI_PR_SET_DUMPABLE:
1472 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1473 break;
1474 case VKI_PR_GET_UNALIGN:
1475 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1476 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1477 break;
1478 case VKI_PR_SET_UNALIGN:
1479 PRE_REG_READ2(int, "prctl", int, option, int, value);
1480 break;
1481 case VKI_PR_GET_KEEPCAPS:
1482 PRE_REG_READ1(int, "prctl", int, option);
1483 break;
1484 case VKI_PR_SET_KEEPCAPS:
1485 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1486 break;
1487 case VKI_PR_GET_FPEMU:
1488 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1489 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1490 break;
1491 case VKI_PR_SET_FPEMU:
1492 PRE_REG_READ2(int, "prctl", int, option, int, value);
1493 break;
1494 case VKI_PR_GET_FPEXC:
1495 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1496 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1497 break;
1498 case VKI_PR_SET_FPEXC:
1499 PRE_REG_READ2(int, "prctl", int, option, int, value);
1500 break;
1501 case VKI_PR_GET_TIMING:
1502 PRE_REG_READ1(int, "prctl", int, option);
1503 break;
1504 case VKI_PR_SET_TIMING:
1505 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1506 break;
1507 case VKI_PR_SET_NAME:
1508 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1509 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1510 break;
1511 case VKI_PR_GET_NAME:
1512 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1513 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1514 break;
1515 case VKI_PR_GET_ENDIAN:
1516 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1517 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1518 break;
1519 case VKI_PR_SET_ENDIAN:
1520 PRE_REG_READ2(int, "prctl", int, option, int, value);
1521 break;
1522 case VKI_PR_SET_PTRACER:
1523 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1524 break;
1525 case VKI_PR_SET_SECCOMP:
1526 /* This is a bit feeble in that it uses |option| before checking
1527 it, but at least both sides of the conditional check it. */
1528 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1529 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1530 if (ARG3) {
1531 /* Should check that ARG3 points at a valid struct sock_fprog.
1532 Sounds complex; hence be lame. */
1533 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1534 ARG3, 1 );
1536 } else {
1537 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1539 break;
1540 case VKI_PR_CAPBSET_READ:
1541 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1542 break;
1543 case VKI_PR_CAPBSET_DROP:
1544 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1545 break;
1546 default:
1547 PRE_REG_READ5(long, "prctl",
1548 int, option, unsigned long, arg2, unsigned long, arg3,
1549 unsigned long, arg4, unsigned long, arg5);
1550 break;
1553 POST(sys_prctl)
1555 switch (ARG1) {
1556 case VKI_PR_GET_PDEATHSIG:
1557 POST_MEM_WRITE(ARG2, sizeof(Int));
1558 break;
1559 case VKI_PR_GET_UNALIGN:
1560 POST_MEM_WRITE(ARG2, sizeof(Int));
1561 break;
1562 case VKI_PR_GET_FPEMU:
1563 POST_MEM_WRITE(ARG2, sizeof(Int));
1564 break;
1565 case VKI_PR_GET_FPEXC:
1566 POST_MEM_WRITE(ARG2, sizeof(Int));
1567 break;
1568 case VKI_PR_GET_NAME:
1569 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1570 break;
1571 case VKI_PR_GET_ENDIAN:
1572 POST_MEM_WRITE(ARG2, sizeof(Int));
1573 break;
1574 case VKI_PR_SET_NAME:
1576 const HChar* new_name = (const HChar*) (Addr)ARG2;
1577 if (new_name) { // Paranoia
1578 ThreadState* tst = VG_(get_ThreadState)(tid);
1579 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1581 /* Don't bother reusing the memory. This is a rare event. */
1582 tst->thread_name =
1583 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1584 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1587 break;
1591 PRE(sys_sendfile)
1593 *flags |= SfMayBlock;
1594 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1595 SARG1, SARG2, ARG3, ARG4);
1596 PRE_REG_READ4(ssize_t, "sendfile",
1597 int, out_fd, int, in_fd, vki_off_t *, offset,
1598 vki_size_t, count);
1599 if (ARG3 != 0)
1600 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1602 POST(sys_sendfile)
1604 if (ARG3 != 0 ) {
1605 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1609 PRE(sys_sendfile64)
1611 *flags |= SfMayBlock;
1612 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1613 SARG1, SARG2, ARG3, ARG4);
1614 PRE_REG_READ4(ssize_t, "sendfile64",
1615 int, out_fd, int, in_fd, vki_loff_t *, offset,
1616 vki_size_t, count);
1617 if (ARG3 != 0)
1618 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1620 POST(sys_sendfile64)
1622 if (ARG3 != 0 ) {
1623 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1627 static void pre_read_timespec64 (ThreadId tid, const char *msg, UWord arg)
1629 struct vki_timespec64 *ts64 = (void *)(Addr)arg;
1630 PRE_MEM_READ (msg, (Addr) &ts64->tv_sec, sizeof(vki_time64_t));
1631 PRE_MEM_READ (msg, (Addr) &ts64->tv_nsec, sizeof(vki_int32_t));
1634 static void pre_read_itimerspec64 (ThreadId tid, const char *msg, UWord arg)
1636 struct vki_itimerspec64 *its64 = (void *)(Addr)arg;
1637 pre_read_timespec64 (tid, msg, (UWord) &its64->it_interval);
1638 pre_read_timespec64 (tid, msg, (UWord) &its64->it_value);
1641 static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1642 SyscallArgs* arrghs, SyscallStatus* status,
1643 UWord* flags, Bool is_time64 )
1646 arg param used by ops
1648 ARG1 - u32 *futex all
1649 ARG2 - int op
1650 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1651 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1652 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1653 ARG6 - int val3 CMP_REQUEUE
1656 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1657 case VKI_FUTEX_CMP_REQUEUE:
1658 case VKI_FUTEX_WAKE_OP:
1659 case VKI_FUTEX_CMP_REQUEUE_PI:
1660 if (is_time64) {
1661 PRE_REG_READ6(long, "futex_time64",
1662 vki_u32 *, futex, int, op, int, val,
1663 struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3);
1664 } else {
1665 PRE_REG_READ6(long, "futex",
1666 vki_u32 *, futex, int, op, int, val,
1667 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1669 break;
1670 case VKI_FUTEX_REQUEUE:
1671 case VKI_FUTEX_WAIT_REQUEUE_PI:
1672 if (is_time64) {
1673 PRE_REG_READ5(long, "futex_time64",
1674 vki_u32 *, futex, int, op, int, val,
1675 struct timespec64 *, utime, vki_u32 *, uaddr2);
1676 } else {
1677 PRE_REG_READ5(long, "futex",
1678 vki_u32 *, futex, int, op, int, val,
1679 struct timespec *, utime, vki_u32 *, uaddr2);
1681 break;
1682 case VKI_FUTEX_WAIT_BITSET:
1683 /* Check that the address at least begins in client-accessible area. */
1684 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1685 SET_STATUS_Failure( VKI_EFAULT );
1686 return;
1688 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1689 if (is_time64) {
1690 PRE_REG_READ4(long, "futex_time64",
1691 vki_u32 *, futex, int, op, int, val,
1692 struct timespec64 *, utime);
1693 } else {
1694 PRE_REG_READ4(long, "futex",
1695 vki_u32 *, futex, int, op, int, val,
1696 struct timespec64 *, utime);
1698 } else {
1699 /* Note argument 5 is unused, but argument 6 is used.
1700 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1701 if (is_time64) {
1702 PRE_REG_READ4(long, "futex_time64",
1703 vki_u32 *, futex, int, op, int, val,
1704 struct timespec64 *, utime);
1705 } else {
1706 PRE_REG_READ4(long, "futex",
1707 vki_u32 *, futex, int, op, int, val,
1708 struct timespec *, utime);
1710 if (VG_(tdict).track_pre_reg_read)
1711 PRA6("futex",int,val3);
1713 break;
1714 case VKI_FUTEX_WAKE_BITSET:
1715 PRE_REG_READ3(long, "futex",
1716 vki_u32 *, futex, int, op, int, val);
1717 if (VG_(tdict).track_pre_reg_read) {
1718 PRA6("futex", int, val3);
1720 break;
1721 case VKI_FUTEX_WAIT:
1722 case VKI_FUTEX_LOCK_PI:
1723 if (is_time64) {
1724 PRE_REG_READ4(long, "futex_time64",
1725 vki_u32 *, futex, int, op, int, val,
1726 struct timespec64 *, utime);
1727 } else {
1728 PRE_REG_READ4(long, "futex",
1729 vki_u32 *, futex, int, op, int, val,
1730 struct timespec *, utime);
1732 break;
1733 case VKI_FUTEX_WAKE:
1734 case VKI_FUTEX_FD:
1735 PRE_REG_READ3(long, "futex",
1736 vki_u32 *, futex, int, op, int, val);
1737 break;
1738 case VKI_FUTEX_TRYLOCK_PI:
1739 case VKI_FUTEX_UNLOCK_PI:
1740 default:
1741 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1742 break;
1745 *flags |= SfMayBlock;
1746 if ((ARG2 & (VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_LOCK_PI)) == (VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_LOCK_PI)) {
1747 *flags |= SfKernelRestart;
1750 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1751 case VKI_FUTEX_WAIT:
1752 case VKI_FUTEX_LOCK_PI:
1753 case VKI_FUTEX_WAIT_BITSET:
1754 case VKI_FUTEX_WAIT_REQUEUE_PI:
1755 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1756 if (ARG4 != 0) {
1757 if (is_time64) {
1758 pre_read_timespec64 (tid, "futex_time64(timeout)", ARG4);
1759 } else {
1760 PRE_MEM_READ( "futex(timeout)", ARG4,
1761 sizeof(struct vki_timespec) );
1764 break;
1766 case VKI_FUTEX_REQUEUE:
1767 case VKI_FUTEX_CMP_REQUEUE:
1768 case VKI_FUTEX_CMP_REQUEUE_PI:
1769 case VKI_FUTEX_WAKE_OP:
1770 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1771 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1772 break;
1774 case VKI_FUTEX_FD:
1775 case VKI_FUTEX_TRYLOCK_PI:
1776 case VKI_FUTEX_UNLOCK_PI:
1777 case VKI_FUTEX_WAKE:
1778 case VKI_FUTEX_WAKE_BITSET:
1779 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1780 break;
1782 default:
1783 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1784 break;
1788 static void futex_post_helper ( ThreadId tid, SyscallArgs* arrghs,
1789 SyscallStatus* status )
1791 vg_assert(SUCCESS);
1792 POST_MEM_WRITE( ARG1, sizeof(int) );
1793 if (ARG2 == VKI_FUTEX_FD) {
1794 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1795 VG_(close)(RES);
1796 SET_STATUS_Failure( VKI_EMFILE );
1797 } else {
1798 if (VG_(clo_track_fds))
1799 ML_(record_fd_open_nameless)(tid, RES);
1804 PRE(sys_futex)
1806 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1807 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1808 futex_pre_helper (tid, layout, arrghs, status, flags, False);
1811 POST(sys_futex)
1813 futex_post_helper (tid, arrghs, status);
1816 PRE(sys_futex_time64)
1818 PRINT("sys_futex_time64 ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1819 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1820 futex_pre_helper (tid, layout, arrghs, status, flags, True);
1823 POST(sys_futex_time64)
1825 futex_post_helper (tid, arrghs, status);
1828 PRE(sys_set_robust_list)
1830 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1831 FMT_REGWORD "u )", ARG1, ARG2);
1832 PRE_REG_READ2(long, "set_robust_list",
1833 struct vki_robust_list_head *, head, vki_size_t, len);
1835 /* Just check the robust_list_head structure is readable - don't
1836 try and chase the list as the kernel will only read it when
1837 the thread exits so the current contents is irrelevant. */
1838 if (ARG1 != 0)
1839 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1842 PRE(sys_get_robust_list)
1844 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1845 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1846 PRE_REG_READ3(long, "get_robust_list",
1847 int, pid,
1848 struct vki_robust_list_head **, head_ptr,
1849 vki_size_t *, len_ptr);
1850 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1851 ARG2, sizeof(struct vki_robust_list_head *));
1852 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1853 ARG3, sizeof(struct vki_size_t *));
1855 POST(sys_get_robust_list)
1857 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1858 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1861 struct pselect_sized_sigset {
1862 const vki_sigset_t *ss;
1863 vki_size_t ss_len;
1865 struct pselect_adjusted_sigset {
1866 struct pselect_sized_sigset ss; /* The actual syscall arg */
1867 vki_sigset_t adjusted_ss;
1870 static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1871 SyscallArgs* arrghs, SyscallStatus* status,
1872 UWord* flags, Bool is_time64 )
1874 *flags |= SfMayBlock | SfPostOnFail;
1875 if (is_time64) {
1876 PRE_REG_READ6(long, "pselect6_time64",
1877 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1878 vki_fd_set *, exceptfds, struct vki_timespec64 *, timeout,
1879 void *, sig);
1880 } else {
1881 PRE_REG_READ6(long, "pselect6",
1882 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1883 vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
1884 void *, sig);
1886 // XXX: this possibly understates how much memory is read.
1887 if (ARG2 != 0)
1888 PRE_MEM_READ( "pselect6(readfds)",
1889 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1890 if (ARG3 != 0)
1891 PRE_MEM_READ( "pselect6(writefds)",
1892 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1893 if (ARG4 != 0)
1894 PRE_MEM_READ( "pselect6(exceptfds)",
1895 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1896 if (ARG5 != 0) {
1897 if (is_time64) {
1898 pre_read_timespec64(tid, "pselect6_time64(timeout)", ARG5);
1899 } else {
1900 PRE_MEM_READ( "pselect6(timeout)", ARG5,
1901 sizeof(struct vki_timespec) );
1904 if (ARG6 != 0) {
1905 const struct pselect_sized_sigset *pss =
1906 (struct pselect_sized_sigset *)(Addr)ARG6;
1907 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1908 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1909 ARG6 = 1; /* Something recognisable to POST() hook. */
1910 } else {
1911 struct pselect_adjusted_sigset *pas;
1912 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1913 ARG6 = (Addr)pas;
1914 pas->ss.ss = (void *)1;
1915 pas->ss.ss_len = pss->ss_len;
1916 if (pss->ss_len == sizeof(*pss->ss)) {
1917 if (pss->ss == NULL) {
1918 pas->ss.ss = NULL;
1919 } else {
1920 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1921 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1922 pas->adjusted_ss = *pss->ss;
1923 pas->ss.ss = &pas->adjusted_ss;
1924 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1932 PRE(sys_pselect6)
1934 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1935 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1936 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1937 pselect6_pre_helper (tid, layout, arrghs, status, flags, False);
1940 POST(sys_pselect6)
1942 if (ARG6 != 0 && ARG6 != 1) {
1943 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1947 PRE(sys_pselect6_time64)
1949 PRINT("sys_pselect6_time64 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1950 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1951 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1952 pselect6_pre_helper (tid, layout, arrghs, status, flags, True);
1955 POST(sys_pselect6_time64)
1957 if (ARG6 != 0 && ARG6 != 1) {
1958 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1962 static void blocking_syscall_sigmask_pre ( ThreadId tid,
1963 Addr *sig_p, vki_size_t sigsz,
1964 const HChar *sig_mem_name,
1965 const HChar *malloc_str )
1967 if (*sig_p != 0 && sigsz == sizeof(vki_sigset_t)) {
1968 const vki_sigset_t *guest_sigmask = (vki_sigset_t *) *sig_p;
1969 PRE_MEM_READ(sig_mem_name, *sig_p, sigsz);
1970 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1971 *sig_p = 1; /* Something recognizable to PST() hook. */
1972 } else {
1973 vki_sigset_t *vg_sigmask =
1974 VG_(malloc)(malloc_str, sizeof(*vg_sigmask));
1975 *sig_p = (Addr)vg_sigmask;
1976 *vg_sigmask = *guest_sigmask;
1977 VG_(sanitize_client_sigmask)(vg_sigmask);
1982 static void blocking_syscall_sigmask_post ( Addr sig, vki_size_t sigsz )
1984 if (sig != 0 && sigsz == sizeof(vki_sigset_t) && sig != 1) {
1985 VG_(free)((vki_sigset_t *)sig);
1989 static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1990 SyscallArgs* arrghs, SyscallStatus* status,
1991 UWord* flags, Bool is_time64 )
1993 UInt i;
1994 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1995 *flags |= SfMayBlock | SfPostOnFail;
1996 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1997 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1998 ARG1, ARG2, ARG3, ARG4, ARG5);
1999 if (is_time64) {
2000 PRE_REG_READ5(long, "ppoll_time64",
2001 struct vki_pollfd *, ufds, unsigned int, nfds,
2002 struct vki_timespec64 *, tsp, vki_sigset_t *, sigmask,
2003 vki_size_t, sigsetsize);
2004 } else {
2005 PRE_REG_READ5(long, "ppoll",
2006 struct vki_pollfd *, ufds, unsigned int, nfds,
2007 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
2008 vki_size_t, sigsetsize);
2011 for (i = 0; i < ARG2; i++) {
2012 PRE_MEM_READ( "ppoll(ufds.fd)",
2013 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
2014 if (ufds[i].fd >= 0) {
2015 PRE_MEM_READ( "ppoll(ufds.events)",
2016 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
2018 PRE_MEM_WRITE( "ppoll(ufds.revents)",
2019 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2022 if (ARG3) {
2023 if (is_time64) {
2024 pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
2025 } else {
2026 PRE_MEM_READ( "ppoll(tsp)", ARG3,
2027 sizeof(struct vki_timespec) );
2030 blocking_syscall_sigmask_pre(tid, (Addr *)&ARG4, ARG5,
2031 "ppoll(sigmask)",
2032 "syswrap.ppoll.1");
2035 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2036 SyscallStatus* status )
2038 vg_assert(SUCCESS || FAILURE);
2039 if (SUCCESS && (RES >= 0)) {
2040 UInt i;
2041 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
2042 for (i = 0; i < ARG2; i++)
2043 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2045 blocking_syscall_sigmask_post((Addr)ARG4, ARG5);
2048 PRE(sys_ppoll)
2050 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
2051 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2052 ARG1, ARG2, ARG3, ARG4, ARG5);
2053 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2056 POST(sys_ppoll)
2058 ppoll_post_helper (tid, arrghs, status);
2061 PRE(sys_ppoll_time64)
2063 PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
2064 "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2065 ARG1, ARG2, ARG3, ARG4, ARG5);
2066 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2069 POST(sys_ppoll_time64)
2071 ppoll_post_helper (tid, arrghs, status);
2075 /* ---------------------------------------------------------------------
2076 epoll_* wrappers
2077 ------------------------------------------------------------------ */
2079 PRE(sys_epoll_create)
2081 PRINT("sys_epoll_create ( %ld )", SARG1);
2082 PRE_REG_READ1(long, "epoll_create", int, size);
2084 POST(sys_epoll_create)
2086 vg_assert(SUCCESS);
2087 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
2088 VG_(close)(RES);
2089 SET_STATUS_Failure( VKI_EMFILE );
2090 } else {
2091 if (VG_(clo_track_fds))
2092 ML_(record_fd_open_nameless) (tid, RES);
2096 PRE(sys_epoll_create1)
2098 PRINT("sys_epoll_create1 ( %ld )", SARG1);
2099 PRE_REG_READ1(long, "epoll_create1", int, flags);
2101 POST(sys_epoll_create1)
2103 vg_assert(SUCCESS);
2104 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
2105 VG_(close)(RES);
2106 SET_STATUS_Failure( VKI_EMFILE );
2107 } else {
2108 if (VG_(clo_track_fds))
2109 ML_(record_fd_open_nameless) (tid, RES);
2113 PRE(sys_epoll_ctl)
2115 static const HChar* epoll_ctl_s[3] = {
2116 "EPOLL_CTL_ADD",
2117 "EPOLL_CTL_DEL",
2118 "EPOLL_CTL_MOD"
2120 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
2121 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
2122 PRE_REG_READ4(long, "epoll_ctl",
2123 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
2124 if (ARG2 != VKI_EPOLL_CTL_DEL) {
2125 /* Just check the events field, the data field is for user space and
2126 unused by the kernel. */
2127 struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
2128 PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
2129 sizeof(__vki_u32) );
2133 /* RES event records have been written (exclude padding). */
2134 static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2135 SyscallStatus* status )
2137 vg_assert(SUCCESS);
2138 if (RES > 0) {
2139 Int i;
2140 struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
2141 for (i = 0; i < RES; i++) {
2142 /* Assume both events and data are set (data is user space only). */
2143 POST_FIELD_WRITE(events[i].events);
2144 POST_FIELD_WRITE(events[i].data);
2149 PRE(sys_epoll_wait)
2151 *flags |= SfMayBlock;
2152 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2153 SARG1, ARG2, SARG3, SARG4);
2154 PRE_REG_READ4(long, "epoll_wait",
2155 int, epfd, struct vki_epoll_event *, events,
2156 int, maxevents, int, timeout);
2157 /* Assume all (maxevents) events records should be (fully) writable. */
2158 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2160 POST(sys_epoll_wait)
2162 epoll_post_helper (tid, arrghs, status);
2165 PRE(sys_epoll_pwait)
2167 *flags |= SfMayBlock | SfPostOnFail;
2168 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2169 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2170 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2171 PRE_REG_READ6(long, "epoll_pwait",
2172 int, epfd, struct vki_epoll_event *, events,
2173 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2174 vki_size_t, sigsetsize);
2175 /* Assume all (maxevents) events records should be (fully) writable. */
2176 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2177 blocking_syscall_sigmask_pre(tid, (Addr *)&ARG5, ARG6,
2178 "epoll_pwait(sigmask)",
2179 "syswrap.epoll_pwait.1");
2181 POST(sys_epoll_pwait)
2183 if (SUCCESS)
2184 epoll_post_helper (tid, arrghs, status);
2185 blocking_syscall_sigmask_post((Addr) ARG5, ARG6);
2188 PRE(sys_epoll_pwait2)
2190 *flags |= SfMayBlock;
2191 PRINT("sys_epoll_pwait2 ( %ld, %#" FMT_REGWORD "x, %ld, %#"
2192 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2193 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
2194 PRE_REG_READ6(long, "epoll_pwait2",
2195 int, epfd, struct vki_epoll_event *, events,
2196 int, maxevents, const struct timespec64 *, timeout,
2197 vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
2198 /* Assume all (maxevents) events records should be (fully) writable. */
2199 PRE_MEM_WRITE( "epoll_pwait2(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2200 /* epoll_pwait2 only supports 64bit timespec. */
2201 if (ARG4)
2202 pre_read_timespec64(tid, "epoll_pwait2(timeout)", ARG4);
2203 if (ARG5)
2204 PRE_MEM_READ( "epoll_pwait2(sigmask)", ARG5, sizeof(vki_sigset_t) );
2206 POST(sys_epoll_pwait2)
2208 epoll_post_helper (tid, arrghs, status);
2211 PRE(sys_eventfd)
2213 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2214 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2216 POST(sys_eventfd)
2218 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2219 VG_(close)(RES);
2220 SET_STATUS_Failure( VKI_EMFILE );
2221 } else {
2222 if (VG_(clo_track_fds))
2223 ML_(record_fd_open_nameless) (tid, RES);
2227 PRE(sys_eventfd2)
2229 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2230 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2232 POST(sys_eventfd2)
2234 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2235 VG_(close)(RES);
2236 SET_STATUS_Failure( VKI_EMFILE );
2237 } else {
2238 if (VG_(clo_track_fds))
2239 ML_(record_fd_open_nameless) (tid, RES);
2243 PRE(sys_fallocate)
2245 *flags |= SfMayBlock;
2246 #if VG_WORDSIZE == 4
2247 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2248 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2249 PRE_REG_READ6(long, "fallocate",
2250 int, fd, int, mode,
2251 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2252 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2253 #elif VG_WORDSIZE == 8
2254 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2255 SARG1, SARG2, SARG3, SARG4);
2256 PRE_REG_READ4(long, "fallocate",
2257 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2258 #else
2259 # error Unexpected word size
2260 #endif
2261 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2262 SET_STATUS_Failure( VKI_EBADF );
2265 PRE(sys_prlimit64)
2267 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2268 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2269 PRE_REG_READ4(long, "prlimit64",
2270 vki_pid_t, pid, unsigned int, resource,
2271 const struct rlimit64 *, new_rlim,
2272 struct rlimit64 *, old_rlim);
2273 if (ARG3)
2274 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2275 if (ARG4)
2276 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2278 if (ARG3 &&
2279 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2280 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2281 SET_STATUS_Failure( VKI_EINVAL );
2283 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2284 switch (ARG2) {
2285 case VKI_RLIMIT_NOFILE:
2286 SET_STATUS_Success( 0 );
2287 if (ARG4) {
2288 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2289 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2291 if (ARG3) {
2292 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2293 > VG_(fd_hard_limit) ||
2294 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2295 != VG_(fd_hard_limit)) {
2296 SET_STATUS_Failure( VKI_EPERM );
2298 else {
2299 VG_(fd_soft_limit) =
2300 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2303 break;
2305 case VKI_RLIMIT_DATA:
2306 SET_STATUS_Success( 0 );
2307 if (ARG4) {
2308 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2309 VG_(client_rlimit_data).rlim_cur;
2310 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2311 VG_(client_rlimit_data).rlim_max;
2313 if (ARG3) {
2314 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2315 > VG_(client_rlimit_data).rlim_max ||
2316 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2317 > VG_(client_rlimit_data).rlim_max) {
2318 SET_STATUS_Failure( VKI_EPERM );
2320 else {
2321 VG_(client_rlimit_data).rlim_cur =
2322 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2323 VG_(client_rlimit_data).rlim_max =
2324 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2327 break;
2329 case VKI_RLIMIT_STACK:
2330 SET_STATUS_Success( 0 );
2331 if (ARG4) {
2332 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2333 VG_(client_rlimit_stack).rlim_cur;
2334 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2335 VG_(client_rlimit_stack).rlim_max;
2337 if (ARG3) {
2338 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2339 > VG_(client_rlimit_stack).rlim_max ||
2340 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2341 > VG_(client_rlimit_stack).rlim_max) {
2342 SET_STATUS_Failure( VKI_EPERM );
2344 else {
2345 VG_(threads)[tid].client_stack_szB =
2346 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2347 VG_(client_rlimit_stack).rlim_cur =
2348 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2349 VG_(client_rlimit_stack).rlim_max =
2350 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2353 break;
2358 POST(sys_prlimit64)
2360 if (ARG4)
2361 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2364 /* ---------------------------------------------------------------------
2365 tid-related wrappers
2366 ------------------------------------------------------------------ */
2368 PRE(sys_gettid)
2370 PRINT("sys_gettid ()");
2371 PRE_REG_READ0(long, "gettid");
2374 PRE(sys_set_tid_address)
2376 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2377 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2380 PRE(sys_tkill)
2382 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2383 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2384 if (!ML_(client_signal_OK)(ARG2)) {
2385 SET_STATUS_Failure( VKI_EINVAL );
2386 return;
2389 /* Check to see if this kill gave us a pending signal */
2390 *flags |= SfPollAfter;
2392 if (VG_(clo_trace_signals))
2393 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2394 SARG2, SARG1);
2396 /* If we're sending SIGKILL, check to see if the target is one of
2397 our threads and handle it specially. */
2398 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2399 SET_STATUS_Success(0);
2400 return;
2403 /* Ask to handle this syscall via the slow route, since that's the
2404 only one that sets tst->status to VgTs_WaitSys. If the result
2405 of doing the syscall is an immediate run of
2406 async_signalhandler() in m_signals, then we need the thread to
2407 be properly tidied away. I have the impression the previous
2408 version of this wrapper worked on x86/amd64 only because the
2409 kernel did not immediately deliver the async signal to this
2410 thread (on ppc it did, which broke the assertion re tst->status
2411 at the top of async_signalhandler()). */
2412 *flags |= SfMayBlock;
2414 POST(sys_tkill)
2416 if (VG_(clo_trace_signals))
2417 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2418 SARG2, SARG1);
2421 PRE(sys_tgkill)
2423 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2424 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2425 if (!ML_(client_signal_OK)(ARG3)) {
2426 SET_STATUS_Failure( VKI_EINVAL );
2427 return;
2430 /* Check to see if this kill gave us a pending signal */
2431 *flags |= SfPollAfter;
2433 if (VG_(clo_trace_signals))
2434 VG_(message)(Vg_DebugMsg,
2435 "tgkill: sending signal %ld to pid %ld/%ld\n",
2436 SARG3, SARG1, SARG2);
2438 /* If we're sending SIGKILL, check to see if the target is one of
2439 our threads and handle it specially. */
2440 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2441 SET_STATUS_Success(0);
2442 return;
2445 /* Ask to handle this syscall via the slow route, since that's the
2446 only one that sets tst->status to VgTs_WaitSys. If the result
2447 of doing the syscall is an immediate run of
2448 async_signalhandler() in m_signals, then we need the thread to
2449 be properly tidied away. I have the impression the previous
2450 version of this wrapper worked on x86/amd64 only because the
2451 kernel did not immediately deliver the async signal to this
2452 thread (on ppc it did, which broke the assertion re tst->status
2453 at the top of async_signalhandler()). */
2454 *flags |= SfMayBlock;
2456 POST(sys_tgkill)
2458 if (VG_(clo_trace_signals))
2459 VG_(message)(Vg_DebugMsg,
2460 "tgkill: sent signal %ld to pid %ld/%ld\n",
2461 SARG3, SARG1, SARG2);
2464 /* ---------------------------------------------------------------------
2465 fadvise64* wrappers
2466 ------------------------------------------------------------------ */
2468 PRE(sys_fadvise64)
2470 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2471 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2472 PRE_REG_READ5(long, "fadvise64",
2473 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2474 vki_size_t, len, int, advice);
2477 PRE(sys_fadvise64_64)
2479 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2480 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2481 PRE_REG_READ6(long, "fadvise64_64",
2482 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2483 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2486 /* ---------------------------------------------------------------------
2487 io_* wrappers
2488 ------------------------------------------------------------------ */
2490 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2491 // and this allows us to control exactly the code that gets run while
2492 // the padding is in place.
2494 PRE(sys_io_setup)
2496 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2497 PRE_REG_READ2(long, "io_setup",
2498 unsigned, nr_events, vki_aio_context_t *, ctxp);
2499 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2502 POST(sys_io_setup)
2504 SizeT size;
2505 struct vki_aio_ring *r;
2507 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2508 ARG1*sizeof(struct vki_io_event));
2509 r = *(struct vki_aio_ring **)(Addr)ARG2;
2510 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2512 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2513 VKI_PROT_READ | VKI_PROT_WRITE,
2514 VKI_MAP_ANONYMOUS, -1, 0 );
2516 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2519 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2520 // after the syscall. We must get 'size' from the aio_ring structure,
2521 // before the syscall, while the aio_ring structure still exists. (And we
2522 // know that we must look at the aio_ring structure because Tom inspected the
2523 // kernel and glibc sources to see what they do, yuk.)
2525 // XXX This segment can be implicitly unmapped when aio
2526 // file-descriptors are closed...
2527 PRE(sys_io_destroy)
2529 SizeT size = 0;
2531 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2532 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2534 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2535 // possible...
2536 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2537 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2538 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2539 r->nr*sizeof(struct vki_io_event));
2542 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2544 if (SUCCESS && RES == 0) {
2545 Bool d = VG_(am_notify_munmap)( ARG1, size );
2546 VG_TRACK( die_mem_munmap, ARG1, size );
2547 if (d)
2548 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2549 "PRE(sys_io_destroy)" );
2553 PRE(sys_io_getevents)
2555 *flags |= SfMayBlock;
2556 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2557 FMT_REGWORD "x )",
2558 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2559 PRE_REG_READ5(long, "io_getevents",
2560 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2561 struct io_event *, events,
2562 struct timespec *, timeout);
2563 if (ARG3 > 0)
2564 PRE_MEM_WRITE( "io_getevents(events)",
2565 ARG4, sizeof(struct vki_io_event)*ARG3 );
2566 if (ARG5 != 0)
2567 PRE_MEM_READ( "io_getevents(timeout)",
2568 ARG5, sizeof(struct vki_timespec));
2570 POST(sys_io_getevents)
2572 Int i;
2573 vg_assert(SUCCESS);
2574 if (RES > 0) {
2575 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2576 for (i = 0; i < RES; i++) {
2577 const struct vki_io_event *vev =
2578 ((struct vki_io_event *)(Addr)ARG4) + i;
2579 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2581 switch (cb->aio_lio_opcode) {
2582 case VKI_IOCB_CMD_PREAD:
2583 if (vev->result > 0)
2584 POST_MEM_WRITE( cb->aio_buf, vev->result );
2585 break;
2587 case VKI_IOCB_CMD_PWRITE:
2588 break;
2590 case VKI_IOCB_CMD_FSYNC:
2591 break;
2593 case VKI_IOCB_CMD_FDSYNC:
2594 break;
2596 case VKI_IOCB_CMD_PREADV:
2597 if (vev->result > 0) {
2598 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2599 Int remains = vev->result;
2600 Int j;
2602 for (j = 0; j < cb->aio_nbytes; j++) {
2603 Int nReadThisBuf = vec[j].iov_len;
2604 if (nReadThisBuf > remains) nReadThisBuf = remains;
2605 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2606 remains -= nReadThisBuf;
2607 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2610 break;
2612 case VKI_IOCB_CMD_PWRITEV:
2613 break;
2615 default:
2616 VG_(message)(Vg_DebugMsg,
2617 "Warning: unhandled io_getevents opcode: %u\n",
2618 cb->aio_lio_opcode);
2619 break;
2625 PRE(sys_io_submit)
2627 Int i, j;
2629 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2630 ARG1, SARG2, ARG3);
2631 PRE_REG_READ3(long, "io_submit",
2632 vki_aio_context_t, ctx_id, long, nr,
2633 struct iocb **, iocbpp);
2634 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2635 if (ARG3 != 0) {
2636 for (i = 0; i < ARG2; i++) {
2637 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2638 struct vki_iovec *iov;
2640 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2641 switch (cb->aio_lio_opcode) {
2642 case VKI_IOCB_CMD_PREAD:
2643 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2644 break;
2646 case VKI_IOCB_CMD_PWRITE:
2647 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2648 break;
2650 case VKI_IOCB_CMD_FSYNC:
2651 break;
2653 case VKI_IOCB_CMD_FDSYNC:
2654 break;
2656 case VKI_IOCB_CMD_PREADV:
2657 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2658 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2659 for (j = 0; j < cb->aio_nbytes; j++)
2660 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2661 break;
2663 case VKI_IOCB_CMD_PWRITEV:
2664 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2665 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2666 for (j = 0; j < cb->aio_nbytes; j++)
2667 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2668 break;
2670 default:
2671 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2672 cb->aio_lio_opcode);
2673 break;
2679 PRE(sys_io_cancel)
2681 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2682 (ULong)ARG1, ARG2, ARG3);
2683 PRE_REG_READ3(long, "io_cancel",
2684 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2685 struct io_event *, result);
2686 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2687 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2689 POST(sys_io_cancel)
2691 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2694 /* ---------------------------------------------------------------------
2695 *_mempolicy wrappers
2696 ------------------------------------------------------------------ */
2698 PRE(sys_mbind)
2700 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2701 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2702 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2703 PRE_REG_READ6(long, "mbind",
2704 unsigned long, start, unsigned long, len,
2705 unsigned long, policy, unsigned long *, nodemask,
2706 unsigned long, maxnode, unsigned, flags);
2707 if (ARG1 != 0)
2708 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2709 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2712 PRE(sys_set_mempolicy)
2714 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2715 SARG1, ARG2, ARG3);
2716 PRE_REG_READ3(long, "set_mempolicy",
2717 int, policy, unsigned long *, nodemask,
2718 unsigned long, maxnode);
2719 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2720 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2723 PRE(sys_get_mempolicy)
2725 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2726 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2727 ARG1, ARG2, ARG3, ARG4, ARG5);
2728 PRE_REG_READ5(long, "get_mempolicy",
2729 int *, policy, unsigned long *, nodemask,
2730 unsigned long, maxnode, unsigned long, addr,
2731 unsigned long, flags);
2732 if (ARG1 != 0)
2733 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2734 if (ARG2 != 0)
2735 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2736 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2738 POST(sys_get_mempolicy)
2740 if (ARG1 != 0)
2741 POST_MEM_WRITE( ARG1, sizeof(Int) );
2742 if (ARG2 != 0)
2743 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2746 /* ---------------------------------------------------------------------
2747 fanotify_* wrappers
2748 ------------------------------------------------------------------ */
2750 PRE(sys_fanotify_init)
2752 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2753 ARG1, ARG2);
2754 PRE_REG_READ2(long, "fanotify_init",
2755 unsigned int, flags, unsigned int, event_f_flags);
2758 POST(sys_fanotify_init)
2760 vg_assert(SUCCESS);
2761 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2762 VG_(close)(RES);
2763 SET_STATUS_Failure( VKI_EMFILE );
2764 } else {
2765 if (VG_(clo_track_fds))
2766 ML_(record_fd_open_nameless) (tid, RES);
2770 PRE(sys_fanotify_mark)
2772 #if VG_WORDSIZE == 4
2773 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2774 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2775 (HChar *)(Addr)ARG6);
2776 PRE_REG_READ6(long, "sys_fanotify_mark",
2777 int, fanotify_fd, unsigned int, flags,
2778 __vki_u32, mask0, __vki_u32, mask1,
2779 int, dfd, const char *, pathname);
2780 if (ARG6)
2781 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2782 #elif VG_WORDSIZE == 8
2783 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2784 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2785 PRE_REG_READ5(long, "sys_fanotify_mark",
2786 int, fanotify_fd, unsigned int, flags,
2787 __vki_u64, mask,
2788 int, dfd, const char *, pathname);
2789 if (ARG5)
2790 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2791 #else
2792 # error Unexpected word size
2793 #endif
2796 /* ---------------------------------------------------------------------
2797 inotify_* wrappers
2798 ------------------------------------------------------------------ */
2800 PRE(sys_inotify_init)
2802 PRINT("sys_inotify_init ( )");
2803 PRE_REG_READ0(long, "inotify_init");
2805 POST(sys_inotify_init)
2807 vg_assert(SUCCESS);
2808 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2809 VG_(close)(RES);
2810 SET_STATUS_Failure( VKI_EMFILE );
2811 } else {
2812 if (VG_(clo_track_fds))
2813 ML_(record_fd_open_nameless) (tid, RES);
2817 PRE(sys_inotify_init1)
2819 PRINT("sys_inotify_init ( %ld )", SARG1);
2820 PRE_REG_READ1(long, "inotify_init", int, flag);
2823 POST(sys_inotify_init1)
2825 vg_assert(SUCCESS);
2826 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2827 VG_(close)(RES);
2828 SET_STATUS_Failure( VKI_EMFILE );
2829 } else {
2830 if (VG_(clo_track_fds))
2831 ML_(record_fd_open_nameless) (tid, RES);
2835 PRE(sys_inotify_add_watch)
2837 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2838 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2839 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2840 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2843 PRE(sys_inotify_rm_watch)
2845 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2846 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2849 /* ---------------------------------------------------------------------
2850 mq_* wrappers
2851 ------------------------------------------------------------------ */
2853 PRE(sys_mq_open)
2855 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2856 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2857 PRE_REG_READ4(long, "mq_open",
2858 const char *, name, int, oflag, vki_mode_t, mode,
2859 struct mq_attr *, attr);
2860 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2861 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2862 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2863 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2864 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2865 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2866 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2869 POST(sys_mq_open)
2871 vg_assert(SUCCESS);
2872 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2873 VG_(close)(RES);
2874 SET_STATUS_Failure( VKI_EMFILE );
2875 } else {
2876 if (VG_(clo_track_fds))
2877 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2881 PRE(sys_mq_unlink)
2883 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2884 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2885 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2888 PRE(sys_mq_timedsend)
2890 *flags |= SfMayBlock;
2891 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2892 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2893 SARG1,ARG2,ARG3,ARG4,ARG5);
2894 PRE_REG_READ5(long, "mq_timedsend",
2895 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2896 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2897 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2898 SET_STATUS_Failure( VKI_EBADF );
2899 } else {
2900 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2901 if (ARG5 != 0)
2902 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2903 sizeof(struct vki_timespec) );
2907 PRE(sys_mq_timedsend_time64)
2909 *flags |= SfMayBlock;
2910 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2911 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2912 SARG1,ARG2,ARG3,ARG4,ARG5);
2913 PRE_REG_READ5(long, "mq_timedsend_time64",
2914 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2915 unsigned int, msg_prio,
2916 const struct vki_timespec64 *, abs_timeout);
2917 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2918 SET_STATUS_Failure( VKI_EBADF );
2919 } else {
2920 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2921 if (ARG5 != 0)
2922 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2926 PRE(sys_mq_timedreceive)
2928 *flags |= SfMayBlock;
2929 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2930 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2931 SARG1,ARG2,ARG3,ARG4,ARG5);
2932 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2933 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2934 unsigned int *, msg_prio,
2935 const struct timespec *, abs_timeout);
2936 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2937 SET_STATUS_Failure( VKI_EBADF );
2938 } else {
2939 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2940 if (ARG4 != 0)
2941 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2942 ARG4, sizeof(unsigned int) );
2943 if (ARG5 != 0)
2944 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2945 ARG5, sizeof(struct vki_timespec) );
2948 POST(sys_mq_timedreceive)
2950 POST_MEM_WRITE( ARG2, RES );
2951 if (ARG4 != 0)
2952 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2955 PRE(sys_mq_timedreceive_time64)
2957 *flags |= SfMayBlock;
2958 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2959 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2960 SARG1,ARG2,ARG3,ARG4,ARG5);
2961 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2962 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2963 unsigned int *, msg_prio,
2964 const struct vki_timespec64 *, abs_timeout);
2965 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2966 SET_STATUS_Failure( VKI_EBADF );
2967 } else {
2968 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2969 if (ARG4 != 0)
2970 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2971 ARG4, sizeof(unsigned int) );
2972 if (ARG5 != 0)
2973 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2977 POST(sys_mq_timedreceive_time64)
2979 POST_MEM_WRITE( ARG2, RES );
2980 if (ARG4 != 0)
2981 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2984 PRE(sys_mq_notify)
2986 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2987 PRE_REG_READ2(long, "mq_notify",
2988 vki_mqd_t, mqdes, const struct sigevent *, notification);
2989 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2990 SET_STATUS_Failure( VKI_EBADF );
2991 else if (ARG2 != 0)
2992 PRE_MEM_READ( "mq_notify(notification)",
2993 ARG2, sizeof(struct vki_sigevent) );
2996 PRE(sys_mq_getsetattr)
2998 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2999 SARG1, ARG2, ARG3 );
3000 PRE_REG_READ3(long, "mq_getsetattr",
3001 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
3002 struct mq_attr *, omqstat);
3003 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
3004 SET_STATUS_Failure( VKI_EBADF );
3005 } else {
3006 if (ARG2 != 0) {
3007 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
3008 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
3009 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
3011 if (ARG3 != 0)
3012 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
3013 sizeof(struct vki_mq_attr) );
3016 POST(sys_mq_getsetattr)
3018 if (ARG3 != 0)
3019 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
3022 /* ---------------------------------------------------------------------
3023 clock_* wrappers
3024 ------------------------------------------------------------------ */
3026 PRE(sys_clock_settime)
3028 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3029 PRE_REG_READ2(long, "clock_settime",
3030 vki_clockid_t, clk_id, const struct timespec *, tp);
3031 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
3034 PRE(sys_clock_settime64)
3036 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3037 PRE_REG_READ2(long, "clock_settime64",
3038 vki_clockid_t, clk_id, const struct timespec64 *, tp);
3039 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
3042 PRE(sys_clock_gettime)
3044 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3045 PRE_REG_READ2(long, "clock_gettime",
3046 vki_clockid_t, clk_id, struct timespec *, tp);
3047 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
3049 POST(sys_clock_gettime)
3051 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3054 PRE(sys_clock_gettime64)
3056 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3057 PRE_REG_READ2(long, "clock_gettime64",
3058 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
3059 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
3060 sizeof(struct vki_timespec64) );
3062 POST(sys_clock_gettime64)
3064 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3067 PRE(sys_clock_getres)
3069 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3070 // Nb: we can't use "RES" as the param name because that's a macro
3071 // defined above!
3072 PRE_REG_READ2(long, "clock_getres",
3073 vki_clockid_t, clk_id, struct timespec *, res);
3074 if (ARG2 != 0)
3075 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3077 POST(sys_clock_getres)
3079 if (ARG2 != 0)
3080 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3083 PRE(sys_clock_getres_time64)
3085 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3086 // Nb: we can't use "RES" as the param name because that's a macro
3087 // defined above!
3088 PRE_REG_READ2(long, "clock_getres_time64",
3089 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3090 if (ARG2 != 0)
3091 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3092 sizeof(struct vki_timespec64) );
3094 POST(sys_clock_getres_time64)
3096 if (ARG2 != 0)
3097 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3100 PRE(sys_clock_nanosleep)
3102 *flags |= SfMayBlock|SfPostOnFail;
3103 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3104 FMT_REGWORD "x )",
3105 SARG1, SARG2, ARG3, ARG4);
3106 PRE_REG_READ4(int32_t, "clock_nanosleep",
3107 vki_clockid_t, clkid, int, flags,
3108 const struct timespec *, rqtp, struct timespec *, rmtp);
3109 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3110 if (ARG4 != 0)
3111 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3113 POST(sys_clock_nanosleep)
3115 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3116 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3119 PRE(sys_clock_nanosleep_time64)
3121 *flags |= SfMayBlock|SfPostOnFail;
3122 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3123 FMT_REGWORD "x )",
3124 SARG1, SARG2, ARG3, ARG4);
3125 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3126 vki_clockid_t, clkid, int, flags,
3127 const struct vki_timespec64 *, rqtp,
3128 struct vki_timespec64 *, rmtp);
3129 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3130 if (ARG4 != 0)
3131 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3132 sizeof(struct vki_timespec64) );
3134 POST(sys_clock_nanosleep_time64)
3136 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3137 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3140 /* ---------------------------------------------------------------------
3141 timer_* wrappers
3142 ------------------------------------------------------------------ */
3144 PRE(sys_timer_create)
3146 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3147 SARG1, ARG2, ARG3);
3148 PRE_REG_READ3(long, "timer_create",
3149 vki_clockid_t, clockid, struct sigevent *, evp,
3150 vki_timer_t *, timerid);
3151 if (ARG2 != 0) {
3152 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3153 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3154 sizeof(vki_sigval_t) );
3155 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3156 sizeof(int) );
3157 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3158 sizeof(int) );
3159 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3160 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3161 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3162 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3164 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3166 POST(sys_timer_create)
3168 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3171 PRE(sys_timer_settime)
3173 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3174 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3175 PRE_REG_READ4(long, "timer_settime",
3176 vki_timer_t, timerid, int, flags,
3177 const struct itimerspec *, value,
3178 struct itimerspec *, ovalue);
3179 PRE_MEM_READ( "timer_settime(value)", ARG3,
3180 sizeof(struct vki_itimerspec) );
3181 if (ARG4 != 0)
3182 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3183 sizeof(struct vki_itimerspec) );
3185 POST(sys_timer_settime)
3187 if (ARG4 != 0)
3188 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3191 PRE(sys_timer_settime64)
3193 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3194 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3195 PRE_REG_READ4(long, "timer_settime64",
3196 vki_timer_t, timerid, int, flags,
3197 const struct vki_itimerspec64 *, value,
3198 struct vki_itimerspec64 *, ovalue);
3199 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3200 sizeof(struct vki_itimerspec64) );
3201 if (ARG4 != 0)
3202 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3203 sizeof(struct vki_itimerspec64) );
3205 POST(sys_timer_settime64)
3207 if (ARG4 != 0)
3208 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3211 PRE(sys_timer_gettime)
3213 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3214 PRE_REG_READ2(long, "timer_gettime",
3215 vki_timer_t, timerid, struct itimerspec *, value);
3216 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3217 sizeof(struct vki_itimerspec));
3219 POST(sys_timer_gettime)
3221 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3224 PRE(sys_timer_gettime64)
3226 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3227 PRE_REG_READ2(long, "timer_gettime64",
3228 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3229 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3230 sizeof(struct vki_itimerspec64));
3232 POST(sys_timer_gettime64)
3234 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3237 PRE(sys_timer_getoverrun)
3239 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3240 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3243 PRE(sys_timer_delete)
3245 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3246 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3249 /* ---------------------------------------------------------------------
3250 timerfd* wrappers
3251 See also http://lwn.net/Articles/260172/ for an overview.
3252 See also /usr/src/linux/fs/timerfd.c for the implementation.
3253 ------------------------------------------------------------------ */
3255 /* Returns True if running on 2.6.22, else False (or False if
3256 cannot be determined). */
3257 static Bool linux_kernel_2_6_22(void)
3259 static Int result = -1;
3260 Int fd, read;
3261 HChar release[64]; // large enough
3262 SysRes res;
3264 if (result == -1) {
3265 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3266 if (sr_isError(res))
3267 return False;
3268 fd = sr_Res(res);
3269 read = VG_(read)(fd, release, sizeof(release) - 1);
3270 if (read < 0)
3271 return False;
3272 release[read] = 0;
3273 VG_(close)(fd);
3274 //VG_(printf)("kernel release = %s\n", release);
3275 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3276 && ! VG_(isdigit)(release[6]);
3278 vg_assert(result == 0 || result == 1);
3279 return result == 1;
3282 PRE(sys_timerfd_create)
3284 if (linux_kernel_2_6_22()) {
3285 /* 2.6.22 kernel: timerfd system call. */
3286 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3287 PRE_REG_READ3(long, "sys_timerfd",
3288 int, fd, int, clockid, const struct itimerspec *, tmr);
3289 PRE_MEM_READ("timerfd(tmr)", ARG3,
3290 sizeof(struct vki_itimerspec) );
3291 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3292 SET_STATUS_Failure( VKI_EBADF );
3293 } else {
3294 /* 2.6.24 and later kernels: timerfd_create system call. */
3295 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3296 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3299 POST(sys_timerfd_create)
3301 if (linux_kernel_2_6_22())
3303 /* 2.6.22 kernel: timerfd system call. */
3304 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3305 VG_(close)(RES);
3306 SET_STATUS_Failure( VKI_EMFILE );
3307 } else {
3308 if (VG_(clo_track_fds))
3309 ML_(record_fd_open_nameless) (tid, RES);
3312 else
3314 /* 2.6.24 and later kernels: timerfd_create system call. */
3315 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3316 VG_(close)(RES);
3317 SET_STATUS_Failure( VKI_EMFILE );
3318 } else {
3319 if (VG_(clo_track_fds))
3320 ML_(record_fd_open_nameless) (tid, RES);
3325 PRE(sys_timerfd_gettime)
3327 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3328 PRE_REG_READ2(long, "timerfd_gettime",
3329 int, fd,
3330 struct vki_itimerspec*, curr_value);
3331 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3332 SET_STATUS_Failure(VKI_EBADF);
3333 else
3334 PRE_MEM_WRITE("timerfd_gettime(curr_value)",
3335 ARG2, sizeof(struct vki_itimerspec));
3337 POST(sys_timerfd_gettime)
3339 if (RES == 0)
3340 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3343 PRE(sys_timerfd_gettime64)
3345 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3346 PRE_REG_READ2(long, "timerfd_gettime64",
3347 int, ufd,
3348 struct vki_itimerspec64*, otmr);
3349 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3350 SET_STATUS_Failure(VKI_EBADF);
3351 else
3352 PRE_MEM_WRITE("timerfd_gettime64(result)",
3353 ARG2, sizeof(struct vki_itimerspec64));
3355 POST(sys_timerfd_gettime64)
3357 if (RES == 0)
3358 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3361 PRE(sys_timerfd_settime)
3363 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3364 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3365 PRE_REG_READ4(long, "timerfd_settime",
3366 int, fd,
3367 int, flags,
3368 const struct vki_itimerspec*, new_value,
3369 struct vki_itimerspec*, old_value);
3370 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3371 SET_STATUS_Failure(VKI_EBADF);
3372 else
3374 PRE_MEM_READ("timerfd_settime(new_value)",
3375 ARG3, sizeof(struct vki_itimerspec));
3376 if (ARG4)
3378 PRE_MEM_WRITE("timerfd_settime(old_value)",
3379 ARG4, sizeof(struct vki_itimerspec));
3383 POST(sys_timerfd_settime)
3385 if (RES == 0 && ARG4 != 0)
3386 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3389 PRE(sys_timerfd_settime64)
3391 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3392 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3393 PRE_REG_READ4(long, "timerfd_settime64",
3394 int, ufd,
3395 int, flags,
3396 const struct vki_itimerspec64*, utmr,
3397 struct vki_itimerspec64*, otmr);
3398 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3399 SET_STATUS_Failure(VKI_EBADF);
3400 else
3402 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3403 if (ARG4)
3405 PRE_MEM_WRITE("timerfd_settime64(result)",
3406 ARG4, sizeof(struct vki_itimerspec64));
3410 POST(sys_timerfd_settime64)
3412 if (RES == 0 && ARG4 != 0)
3413 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3416 /* ---------------------------------------------------------------------
3417 capabilities wrappers
3418 ------------------------------------------------------------------ */
3420 PRE(sys_capget)
3422 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3423 PRE_REG_READ2(long, "capget",
3424 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3425 PRE_MEM_READ( "capget(header)", ARG1,
3426 sizeof(struct __vki_user_cap_header_struct) );
3427 if (ARG2 != (Addr)NULL)
3428 PRE_MEM_WRITE( "capget(data)", ARG2,
3429 sizeof(struct __vki_user_cap_data_struct) );
3431 POST(sys_capget)
3433 if (ARG2 != (Addr)NULL)
3434 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3437 PRE(sys_capset)
3439 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3440 PRE_REG_READ2(long, "capset",
3441 vki_cap_user_header_t, header,
3442 const vki_cap_user_data_t, data);
3443 PRE_MEM_READ( "capset(header)",
3444 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3445 PRE_MEM_READ( "capset(data)",
3446 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3449 /* ---------------------------------------------------------------------
3450 16-bit uid/gid/groups wrappers
3451 ------------------------------------------------------------------ */
3453 PRE(sys_getuid16)
3455 PRINT("sys_getuid16 ( )");
3456 PRE_REG_READ0(long, "getuid16");
3459 PRE(sys_setuid16)
3461 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3462 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3465 PRE(sys_getgid16)
3467 PRINT("sys_getgid16 ( )");
3468 PRE_REG_READ0(long, "getgid16");
3471 PRE(sys_setgid16)
3473 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3474 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3477 PRE(sys_geteuid16)
3479 PRINT("sys_geteuid16 ( )");
3480 PRE_REG_READ0(long, "geteuid16");
3483 PRE(sys_getegid16)
3485 PRINT("sys_getegid16 ( )");
3486 PRE_REG_READ0(long, "getegid16");
3489 PRE(sys_setreuid16)
3491 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3492 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3495 PRE(sys_setregid16)
3497 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3498 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3501 PRE(sys_getgroups16)
3503 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3504 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3505 if (ARG1 > 0)
3506 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3508 POST(sys_getgroups16)
3510 vg_assert(SUCCESS);
3511 if (ARG1 > 0 && RES > 0)
3512 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3515 PRE(sys_setgroups16)
3517 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3518 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3519 if (ARG1 > 0)
3520 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3523 /* ---------------------------------------------------------------------
3524 *chown16 wrappers
3525 ------------------------------------------------------------------ */
3527 PRE(sys_chown16)
3529 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3530 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3531 PRE_REG_READ3(long, "chown16",
3532 const char *, path,
3533 vki_old_uid_t, owner, vki_old_gid_t, group);
3534 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3537 PRE(sys_fchown16)
3539 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3540 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3541 PRE_REG_READ3(long, "fchown16",
3542 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3545 /* ---------------------------------------------------------------------
3546 *xattr wrappers
3547 ------------------------------------------------------------------ */
3549 PRE(sys_setxattr)
3551 *flags |= SfMayBlock;
3552 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3553 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3554 ARG4, SARG5);
3555 PRE_REG_READ5(long, "setxattr",
3556 char *, path, char *, name,
3557 void *, value, vki_size_t, size, int, flags);
3558 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3559 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3560 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3563 PRE(sys_lsetxattr)
3565 *flags |= SfMayBlock;
3566 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3567 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3568 ARG1, ARG2, ARG3, ARG4, SARG5);
3569 PRE_REG_READ5(long, "lsetxattr",
3570 char *, path, char *, name,
3571 void *, value, vki_size_t, size, int, flags);
3572 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3573 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3574 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3577 PRE(sys_fsetxattr)
3579 *flags |= SfMayBlock;
3580 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3581 FMT_REGWORD "u, %ld )",
3582 SARG1, ARG2, ARG3, ARG4, SARG5);
3583 PRE_REG_READ5(long, "fsetxattr",
3584 int, fd, char *, name, void *, value,
3585 vki_size_t, size, int, flags);
3586 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3587 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3590 PRE(sys_getxattr)
3592 *flags |= SfMayBlock;
3593 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3594 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3595 PRE_REG_READ4(ssize_t, "getxattr",
3596 char *, path, char *, name, void *, value, vki_size_t, size);
3597 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3598 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3599 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3601 POST(sys_getxattr)
3603 vg_assert(SUCCESS);
3604 if (RES > 0 && ARG3 != (Addr)NULL) {
3605 POST_MEM_WRITE( ARG3, RES );
3609 PRE(sys_lgetxattr)
3611 *flags |= SfMayBlock;
3612 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3613 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3614 PRE_REG_READ4(ssize_t, "lgetxattr",
3615 char *, path, char *, name, void *, value, vki_size_t, size);
3616 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3617 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3618 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3620 POST(sys_lgetxattr)
3622 vg_assert(SUCCESS);
3623 if (RES > 0 && ARG3 != (Addr)NULL) {
3624 POST_MEM_WRITE( ARG3, RES );
3628 PRE(sys_fgetxattr)
3630 *flags |= SfMayBlock;
3631 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3632 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3633 PRE_REG_READ4(ssize_t, "fgetxattr",
3634 int, fd, char *, name, void *, value, vki_size_t, size);
3635 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3636 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3638 POST(sys_fgetxattr)
3640 if (RES > 0 && ARG3 != (Addr)NULL)
3641 POST_MEM_WRITE( ARG3, RES );
3644 PRE(sys_listxattr)
3646 *flags |= SfMayBlock;
3647 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3648 ARG1, ARG2, (ULong)ARG3);
3649 PRE_REG_READ3(ssize_t, "listxattr",
3650 char *, path, char *, list, vki_size_t, size);
3651 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3652 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3654 POST(sys_listxattr)
3656 if (RES > 0 && ARG2 != (Addr)NULL)
3657 POST_MEM_WRITE( ARG2, RES );
3660 PRE(sys_llistxattr)
3662 *flags |= SfMayBlock;
3663 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3664 ARG1, ARG2, (ULong)ARG3);
3665 PRE_REG_READ3(ssize_t, "llistxattr",
3666 char *, path, char *, list, vki_size_t, size);
3667 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3668 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3670 POST(sys_llistxattr)
3672 if (RES > 0 && ARG2 != (Addr)NULL)
3673 POST_MEM_WRITE( ARG2, RES );
3676 PRE(sys_flistxattr)
3678 *flags |= SfMayBlock;
3679 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3680 SARG1, ARG2, ARG3);
3681 PRE_REG_READ3(ssize_t, "flistxattr",
3682 int, fd, char *, list, vki_size_t, size);
3683 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3685 POST(sys_flistxattr)
3687 if (RES > 0 && ARG2 != (Addr)NULL)
3688 POST_MEM_WRITE( ARG2, RES );
3691 PRE(sys_removexattr)
3693 *flags |= SfMayBlock;
3694 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3695 ARG1, ARG2);
3696 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3697 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3698 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3701 PRE(sys_lremovexattr)
3703 *flags |= SfMayBlock;
3704 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3705 ARG1, ARG2);
3706 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3707 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3708 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3711 PRE(sys_fremovexattr)
3713 *flags |= SfMayBlock;
3714 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3715 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3716 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3719 /* ---------------------------------------------------------------------
3720 sched_* wrappers
3721 ------------------------------------------------------------------ */
3723 PRE(sys_sched_setparam)
3725 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3726 PRE_REG_READ2(long, "sched_setparam",
3727 vki_pid_t, pid, struct sched_param *, p);
3728 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3730 POST(sys_sched_setparam)
3732 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3735 PRE(sys_sched_getparam)
3737 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3738 PRE_REG_READ2(long, "sched_getparam",
3739 vki_pid_t, pid, struct sched_param *, p);
3740 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3742 POST(sys_sched_getparam)
3744 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3747 PRE(sys_sched_setattr)
3749 struct vki_sched_attr *attr;
3750 PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
3751 FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
3752 PRE_REG_READ3(long, "sched_setattr",
3753 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
3754 /* We need to be able to read at least the size field. */
3755 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3756 attr = (struct vki_sched_attr *)(Addr)ARG2;
3757 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3758 PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
3761 PRE(sys_sched_getattr)
3763 struct vki_sched_attr *attr;
3764 PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3765 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
3766 PRE_REG_READ4(long, "sched_getattr",
3767 vki_pid_t, pid, struct sched_attr *, p,
3768 unsigned int, size, unsigned int, flags);
3769 /* We need to be able to read at least the size field. */
3770 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3771 /* And the kernel needs to be able to write to the whole struct size. */
3772 attr = (struct vki_sched_attr *)(Addr)ARG2;
3773 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3774 PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
3776 POST(sys_sched_getattr)
3778 struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
3779 POST_MEM_WRITE( (Addr)attr, attr->size );
3782 PRE(sys_sched_getscheduler)
3784 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3785 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3788 PRE(sys_sched_setscheduler)
3790 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3791 SARG1, SARG2, ARG3);
3792 PRE_REG_READ3(long, "sched_setscheduler",
3793 vki_pid_t, pid, int, policy, struct sched_param *, p);
3794 if (ARG3 != 0)
3795 PRE_MEM_READ( "sched_setscheduler(p)",
3796 ARG3, sizeof(struct vki_sched_param));
3799 PRE(sys_sched_yield)
3801 *flags |= SfMayBlock;
3802 PRINT("sched_yield()");
3803 PRE_REG_READ0(long, "sys_sched_yield");
3806 PRE(sys_sched_get_priority_max)
3808 PRINT("sched_get_priority_max ( %ld )", SARG1);
3809 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3812 PRE(sys_sched_get_priority_min)
3814 PRINT("sched_get_priority_min ( %ld )", SARG1);
3815 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3818 PRE(sys_sched_rr_get_interval)
3820 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3821 PRE_REG_READ2(int, "sched_rr_get_interval",
3822 vki_pid_t, pid,
3823 struct vki_timespec *, tp);
3824 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3825 ARG2, sizeof(struct vki_timespec));
3828 POST(sys_sched_rr_get_interval)
3830 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3833 PRE(sys_sched_rr_get_interval_time64)
3835 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3836 SARG1, ARG2);
3837 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3838 vki_pid_t, pid,
3839 struct vki_timespec *, tp);
3840 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3841 ARG2, sizeof(struct vki_timespec64));
3844 POST(sys_sched_rr_get_interval_time64)
3846 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3849 PRE(sys_sched_setaffinity)
3851 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3852 SARG1, ARG2, ARG3);
3853 PRE_REG_READ3(long, "sched_setaffinity",
3854 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3855 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3858 PRE(sys_sched_getaffinity)
3860 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3861 SARG1, ARG2, ARG3);
3862 PRE_REG_READ3(long, "sched_getaffinity",
3863 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3864 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3866 POST(sys_sched_getaffinity)
3868 POST_MEM_WRITE(ARG3, ARG2);
3871 PRE(sys_unshare)
3873 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3874 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3877 PRE(sys_setns)
3879 PRINT("sys_setns ( %ld, %ld )", SARG1, SARG2);
3880 PRE_REG_READ2(int, "setns",
3881 int, fd,
3882 int, nstype);
3883 if (!ML_(fd_allowed)(ARG1, "setns", tid, False))
3884 SET_STATUS_Failure( VKI_EBADF );
3888 /* ---------------------------------------------------------------------
3889 miscellaneous wrappers
3890 ------------------------------------------------------------------ */
3892 PRE(sys_munlockall)
3894 *flags |= SfMayBlock;
3895 PRINT("sys_munlockall ( )");
3896 PRE_REG_READ0(long, "munlockall");
3899 // This has different signatures for different platforms.
3901 // x86: int sys_pipe(unsigned long __user *fildes);
3902 // AMD64: long sys_pipe(int *fildes);
3903 // ppc32: int sys_pipe(int __user *fildes);
3904 // ppc64: int sys_pipe(int __user *fildes);
3906 // The type of the argument is most important, and it is an array of 32 bit
3907 // values in all cases. (The return type differs across platforms, but it
3908 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3909 // was caused by using an array of 'unsigned long's, which didn't work on
3910 // AMD64.
3911 PRE(sys_pipe)
3913 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3914 PRE_REG_READ1(int, "pipe", int *, filedes);
3915 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3917 POST(sys_pipe)
3919 Int *p = (Int *)(Addr)ARG1;
3920 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3921 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3922 VG_(close)(p[0]);
3923 VG_(close)(p[1]);
3924 SET_STATUS_Failure( VKI_EMFILE );
3925 } else {
3926 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3927 if (VG_(clo_track_fds)) {
3928 ML_(record_fd_open_nameless)(tid, p[0]);
3929 ML_(record_fd_open_nameless)(tid, p[1]);
3934 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3935 there's a second arg containing flags to be applied to the new file
3936 descriptors. It hardly seems worth the effort to factor out the
3937 duplicated code, hence: */
3938 PRE(sys_pipe2)
3940 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3941 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3942 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3944 POST(sys_pipe2)
3946 Int *p = (Int *)(Addr)ARG1;
3947 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3948 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3949 VG_(close)(p[0]);
3950 VG_(close)(p[1]);
3951 SET_STATUS_Failure( VKI_EMFILE );
3952 } else {
3953 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3954 if (VG_(clo_track_fds)) {
3955 ML_(record_fd_open_nameless)(tid, p[0]);
3956 ML_(record_fd_open_nameless)(tid, p[1]);
3961 PRE(sys_dup3)
3963 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3964 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3965 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3966 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3967 SET_STATUS_Failure( VKI_EBADF );
3970 POST(sys_dup3)
3972 vg_assert(SUCCESS);
3973 if (VG_(clo_track_fds))
3974 ML_(record_fd_open_named)(tid, RES);
3977 PRE(sys_quotactl)
3979 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3980 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3981 PRE_REG_READ4(long, "quotactl",
3982 unsigned int, cmd, const char *, special, vki_qid_t, id,
3983 void *, addr);
3984 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3987 PRE(sys_waitid)
3989 *flags |= SfMayBlock;
3990 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3991 SARG1, SARG2, ARG3, SARG4, ARG5);
3992 PRE_REG_READ5(int32_t, "sys_waitid",
3993 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3994 int, options, struct vki_rusage *, ru);
3995 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3996 if (ARG5 != 0)
3997 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3999 POST(sys_waitid)
4001 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
4002 if (ARG5 != 0)
4003 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
4006 PRE(sys_sync_file_range)
4008 *flags |= SfMayBlock;
4009 #if VG_WORDSIZE == 4
4010 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
4011 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
4012 PRE_REG_READ6(long, "sync_file_range",
4013 int, fd,
4014 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
4015 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
4016 unsigned int, flags);
4017 #elif VG_WORDSIZE == 8
4018 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
4019 SARG1, SARG2, SARG3, ARG4);
4020 PRE_REG_READ4(long, "sync_file_range",
4021 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
4022 unsigned int, flags);
4023 #else
4024 # error Unexpected word size
4025 #endif
4026 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
4027 SET_STATUS_Failure( VKI_EBADF );
4030 PRE(sys_sync_file_range2)
4032 *flags |= SfMayBlock;
4033 #if VG_WORDSIZE == 4
4034 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
4035 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
4036 PRE_REG_READ6(long, "sync_file_range2",
4037 int, fd, unsigned int, flags,
4038 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
4039 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
4040 #elif VG_WORDSIZE == 8
4041 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
4042 SARG1, ARG2, SARG3, SARG4);
4043 PRE_REG_READ4(long, "sync_file_range2",
4044 int, fd, unsigned int, flags,
4045 vki_loff_t, offset, vki_loff_t, nbytes);
4046 #else
4047 # error Unexpected word size
4048 #endif
4049 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
4050 SET_STATUS_Failure( VKI_EBADF );
4053 PRE(sys_stime)
4055 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
4056 PRE_REG_READ1(int, "stime", vki_time_t*, t);
4057 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
4060 PRE(sys_perf_event_open)
4062 struct vki_perf_event_attr *attr;
4063 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
4064 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
4065 PRE_REG_READ5(long, "perf_event_open",
4066 struct vki_perf_event_attr *, attr,
4067 vki_pid_t, pid, int, cpu, int, group_fd,
4068 unsigned long, flags);
4069 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
4070 PRE_MEM_READ( "perf_event_open(attr->size)",
4071 (Addr)&attr->size, sizeof(attr->size) );
4072 PRE_MEM_READ( "perf_event_open(attr)",
4073 (Addr)attr, attr->size );
4076 POST(sys_perf_event_open)
4078 vg_assert(SUCCESS);
4079 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
4080 VG_(close)(RES);
4081 SET_STATUS_Failure( VKI_EMFILE );
4082 } else {
4083 if (VG_(clo_track_fds))
4084 ML_(record_fd_open_nameless)(tid, RES);
4088 PRE(sys_getcpu)
4090 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4091 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
4092 PRE_REG_READ3(int, "getcpu",
4093 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
4094 if (ARG1 != 0)
4095 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
4096 if (ARG2 != 0)
4097 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
4098 if (ARG3 != 0)
4099 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
4102 POST(sys_getcpu)
4104 if (ARG1 != 0)
4105 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
4106 if (ARG2 != 0)
4107 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
4108 if (ARG3 != 0)
4109 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
4112 PRE(sys_move_pages)
4114 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4115 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4116 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4117 PRE_REG_READ6(int, "move_pages",
4118 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4119 const int *, nodes, int *, status, int, flags);
4120 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4121 if (ARG4)
4122 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4123 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4126 POST(sys_move_pages)
4128 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4131 PRE(sys_getrandom)
4133 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4134 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4135 PRE_REG_READ3(int, "getrandom",
4136 char *, buf, vki_size_t, count, unsigned int, flags);
4137 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4140 POST(sys_getrandom)
4142 POST_MEM_WRITE( ARG1, ARG2 );
4145 PRE(sys_memfd_create)
4147 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4148 ARG1, ARG2);
4149 PRE_REG_READ2(int, "memfd_create",
4150 char *, uname, unsigned int, flags);
4151 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4154 POST(sys_memfd_create)
4156 vg_assert(SUCCESS);
4157 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4158 VG_(close)(RES);
4159 SET_STATUS_Failure( VKI_EMFILE );
4160 } else {
4161 if (VG_(clo_track_fds))
4162 ML_(record_fd_open_nameless)(tid, RES);
4166 PRE(sys_landlock_create_ruleset)
4168 PRINT("sys_landlock_create_ruleset ( %#" FMT_REGWORD "x, %lu, %lu )",
4169 ARG1, ARG2, ARG3);
4170 PRE_REG_READ3(long, "landlock_create_ruleset",
4171 const struct vki_landlock_ruleset_attr*, attr,
4172 vki_size_t, size, vki_uint32_t, flags);
4173 PRE_MEM_READ( "landlock_create_ruleset(value)", ARG1, ARG2 );
4175 /* XXX Alternatively we could always fail with EOPNOTSUPP
4176 since the rules might interfere with valgrind itself. */
4179 POST(sys_landlock_create_ruleset)
4181 /* Returns either the abi version or a file descriptor. */
4182 if (ARG3 != VKI_LANDLOCK_CREATE_RULESET_VERSION) {
4183 if (!ML_(fd_allowed)(RES, "landlock_create_ruleset", tid, True)) {
4184 VG_(close)(RES);
4185 SET_STATUS_Failure( VKI_EMFILE );
4186 } else {
4187 if (VG_(clo_track_fds))
4188 ML_(record_fd_open_nameless)(tid, RES);
4193 PRE(sys_landlock_add_rule)
4195 PRINT("sys_landlock_add_rule ( %ld, %lu, %#" FMT_REGWORD "x, %lu )",
4196 SARG1, ARG2, ARG3, ARG4);
4197 PRE_REG_READ4(long, "landlock_add_rule",
4198 int, ruleset_fd, enum vki_landlock_rule_type, rule_type,
4199 const void*, rule_attr, vki_uint32_t, flags);
4200 if (!ML_(fd_allowed)(ARG1, "landlock_add_rule", tid, False))
4201 SET_STATUS_Failure(VKI_EBADF);
4202 /* XXX Depending on rule_type we should also check the given rule_attr. */
4205 PRE(sys_landlock_restrict_self)
4207 PRINT("sys_landlock_restrict_self ( %ld, %lu )", SARG1, ARG2);
4208 PRE_REG_READ2(long, "landlock_create_ruleset",
4209 int, ruleset_fd, vki_uint32_t, flags);
4210 if (!ML_(fd_allowed)(ARG1, "landlock_restrict_self", tid, False))
4211 SET_STATUS_Failure(VKI_EBADF);
4214 PRE(sys_memfd_secret)
4216 PRINT("sys_memfd_secret ( %#" FMT_REGWORD "x )", ARG1);
4217 PRE_REG_READ1(int, "memfd_secret", unsigned int, flags);
4220 POST(sys_memfd_secret)
4222 vg_assert(SUCCESS);
4223 if (!ML_(fd_allowed)(RES, "memfd_secret", tid, True)) {
4224 VG_(close)(RES);
4225 SET_STATUS_Failure( VKI_EMFILE );
4226 } else {
4227 if (VG_(clo_track_fds))
4228 ML_(record_fd_open_nameless)(tid, RES);
4232 PRE(sys_membarrier)
4234 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4235 PRE_REG_READ1(int, "membarrier", int, flags);
4238 PRE(sys_syncfs)
4240 *flags |= SfMayBlock;
4241 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4242 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4245 PRE(sys_statx)
4247 FUSE_COMPATIBLE_MAY_BLOCK();
4248 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4249 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4250 PRE_REG_READ5(long, "statx",
4251 int, dirfd, char *, filename, int, flags,
4252 unsigned int, mask, struct statx *, buf);
4253 // Work around Rust's dubious use of statx, as described here:
4254 // https://github.com/rust-lang/rust/blob/
4255 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4256 // src/libstd/sys/unix/fs.rs#L128-L142
4257 // in which it passes NULL for both filename and buf, and then looks at the
4258 // return value, so as to determine whether or not this syscall is supported.
4259 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4260 Bool statx_null_path = (ARG2 == 0) && (ARG3 & VKI_AT_EMPTY_PATH);
4261 if (!both_filename_and_buf_are_null) {
4262 // Since Linux 6.11, the kernel allows passing a NULL filename when
4263 // the AT_EMPTY_PATH flag is set.
4264 if (!statx_null_path)
4265 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4266 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4269 POST(sys_statx)
4271 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4274 /* ---------------------------------------------------------------------
4275 utime wrapper
4276 ------------------------------------------------------------------ */
4278 PRE(sys_utime)
4280 *flags |= SfMayBlock;
4281 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4282 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4283 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4284 if (ARG2 != 0)
4285 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4288 /* ---------------------------------------------------------------------
4289 lseek wrapper
4290 ------------------------------------------------------------------ */
4292 PRE(sys_lseek)
4294 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4295 ARG1, SARG2, ARG3);
4296 PRE_REG_READ3(vki_off_t, "lseek",
4297 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4300 /* ---------------------------------------------------------------------
4301 readahead wrapper
4302 ------------------------------------------------------------------ */
4304 PRE(sys_readahead)
4306 *flags |= SfMayBlock;
4307 #if VG_WORDSIZE == 4
4308 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4309 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4310 PRE_REG_READ4(vki_off_t, "readahead",
4311 int, fd, unsigned, MERGE64_FIRST(offset),
4312 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4313 #elif VG_WORDSIZE == 8
4314 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4315 PRE_REG_READ3(vki_off_t, "readahead",
4316 int, fd, vki_loff_t, offset, vki_size_t, count);
4317 #else
4318 # error Unexpected word size
4319 #endif
4320 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4321 SET_STATUS_Failure( VKI_EBADF );
4324 /* ---------------------------------------------------------------------
4325 sig* wrappers
4326 ------------------------------------------------------------------ */
4328 PRE(sys_sigpending)
4330 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4331 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4332 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4334 POST(sys_sigpending)
4336 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4339 // This syscall is not used on amd64/Linux -- it only provides
4340 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4341 // This wrapper is only suitable for 32-bit architectures.
4342 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4343 // conditional compilation like this?)
4344 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4345 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4346 || defined(VGP_nanomips_linux)
4347 PRE(sys_sigprocmask)
4349 vki_old_sigset_t* set;
4350 vki_old_sigset_t* oldset;
4351 vki_sigset_t bigger_set;
4352 vki_sigset_t bigger_oldset;
4354 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4355 PRE_REG_READ3(long, "sigprocmask",
4356 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4357 if (ARG2 != 0)
4358 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4359 if (ARG3 != 0)
4360 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4362 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4363 // vki_sigset_t params.
4364 set = (vki_old_sigset_t*)(Addr)ARG2;
4365 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4367 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4368 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4369 if (set)
4370 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4372 SET_STATUS_from_SysRes(
4373 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4374 set ? &bigger_set : NULL,
4375 oldset ? &bigger_oldset : NULL)
4378 if (oldset)
4379 *oldset = bigger_oldset.sig[0];
4381 if (SUCCESS)
4382 *flags |= SfPollAfter;
4384 POST(sys_sigprocmask)
4386 vg_assert(SUCCESS);
4387 if (RES == 0 && ARG3 != 0)
4388 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4391 /* Convert from non-RT to RT sigset_t's */
4392 static
4393 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4395 VG_(sigemptyset)(set);
4396 set->sig[0] = *oldset;
4398 PRE(sys_sigaction)
4400 vki_sigaction_toK_t new, *newp;
4401 vki_sigaction_fromK_t old, *oldp;
4403 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4404 PRE_REG_READ3(int, "sigaction",
4405 int, signum, const struct old_sigaction *, act,
4406 struct old_sigaction *, oldact);
4408 newp = oldp = NULL;
4410 if (ARG2 != 0) {
4411 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4412 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4413 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4414 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4415 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4416 && (sa->sa_flags & VKI_SA_RESTORER))
4417 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4420 if (ARG3 != 0) {
4421 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4422 oldp = &old;
4425 /* If the new or old sigaction is not NULL, but the structs
4426 aren't accessible then sigaction returns EFAULT and we cannot
4427 use either struct for our own bookkeeping. Just fail early. */
4428 if (ARG2 != 0
4429 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4430 sizeof(struct vki_old_sigaction))) {
4431 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4432 (void *)(Addr)ARG2);
4433 SET_STATUS_Failure ( VKI_EFAULT );
4434 } else if ((ARG3 != 0
4435 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4436 sizeof(struct vki_old_sigaction)))) {
4437 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4438 (void *)(Addr)ARG3);
4439 SET_STATUS_Failure ( VKI_EFAULT );
4440 } else {
4441 if (ARG2 != 0) {
4442 struct vki_old_sigaction *oldnew =
4443 (struct vki_old_sigaction *)(Addr)ARG2;
4445 new.ksa_handler = oldnew->ksa_handler;
4446 new.sa_flags = oldnew->sa_flags;
4447 new.sa_restorer = oldnew->sa_restorer;
4448 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4449 newp = &new;
4452 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4454 if (ARG3 != 0 && SUCCESS && RES == 0) {
4455 struct vki_old_sigaction *oldold =
4456 (struct vki_old_sigaction *)(Addr)ARG3;
4458 oldold->ksa_handler = oldp->ksa_handler;
4459 oldold->sa_flags = oldp->sa_flags;
4460 oldold->sa_restorer = oldp->sa_restorer;
4461 oldold->sa_mask = oldp->sa_mask.sig[0];
4465 POST(sys_sigaction)
4467 vg_assert(SUCCESS);
4468 if (RES == 0 && ARG3 != 0)
4469 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4471 #endif
4473 PRE(sys_signalfd)
4475 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4476 (ULong)ARG3);
4477 PRE_REG_READ3(long, "sys_signalfd",
4478 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4479 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4480 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4481 SET_STATUS_Failure( VKI_EBADF );
4483 POST(sys_signalfd)
4485 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4486 VG_(close)(RES);
4487 SET_STATUS_Failure( VKI_EMFILE );
4488 } else {
4489 if (VG_(clo_track_fds))
4490 ML_(record_fd_open_nameless) (tid, RES);
4494 PRE(sys_signalfd4)
4496 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4497 SARG1, ARG2, ARG3, SARG4);
4498 PRE_REG_READ4(long, "sys_signalfd4",
4499 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4500 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4501 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4502 SET_STATUS_Failure( VKI_EBADF );
4504 POST(sys_signalfd4)
4506 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4507 VG_(close)(RES);
4508 SET_STATUS_Failure( VKI_EMFILE );
4509 } else {
4510 if (VG_(clo_track_fds))
4511 ML_(record_fd_open_nameless) (tid, RES);
4516 /* ---------------------------------------------------------------------
4517 rt_sig* wrappers
4518 ------------------------------------------------------------------ */
4520 PRE(sys_rt_sigaction)
4522 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4523 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4524 PRE_REG_READ4(long, "rt_sigaction",
4525 int, signum, const struct sigaction *, act,
4526 struct sigaction *, oldact, vki_size_t, sigsetsize);
4528 if (ARG2 != 0) {
4529 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4530 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4531 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4532 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4533 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4534 && (sa->sa_flags & VKI_SA_RESTORER))
4535 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4537 if (ARG3 != 0)
4538 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4540 /* If the new or old sigaction is not NULL, but the structs
4541 aren't accessible then sigaction returns EFAULT and we cannot
4542 use either struct for our own bookkeeping. Just fail early. */
4543 if (ARG2 != 0
4544 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4545 sizeof(vki_sigaction_toK_t))) {
4546 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4547 (void *)(Addr)ARG2);
4548 SET_STATUS_Failure ( VKI_EFAULT );
4549 } else if ((ARG3 != 0
4550 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4551 sizeof(vki_sigaction_fromK_t)))) {
4552 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4553 (void *)(Addr)ARG3);
4554 SET_STATUS_Failure ( VKI_EFAULT );
4555 } else {
4557 // XXX: doesn't seem right to be calling do_sys_sigaction for
4558 // sys_rt_sigaction... perhaps this function should be renamed
4559 // VG_(do_sys_rt_sigaction)() --njn
4561 SET_STATUS_from_SysRes(
4562 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4563 (vki_sigaction_fromK_t *)(Addr)ARG3)
4567 POST(sys_rt_sigaction)
4569 vg_assert(SUCCESS);
4570 if (RES == 0 && ARG3 != 0)
4571 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4574 PRE(sys_rt_sigprocmask)
4576 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4577 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4578 PRE_REG_READ4(long, "rt_sigprocmask",
4579 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4580 vki_size_t, sigsetsize);
4581 if (ARG2 != 0)
4582 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4583 if (ARG3 != 0)
4584 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4586 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4587 // Since we want to use the set and oldset for bookkeeping we also want
4588 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4589 if (sizeof(vki_sigset_t) != ARG4)
4590 SET_STATUS_Failure( VKI_EINVAL );
4591 else if (ARG2 != 0
4592 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4593 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4594 (void *)(Addr)ARG2);
4595 SET_STATUS_Failure ( VKI_EFAULT );
4597 else if (ARG3 != 0
4598 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4599 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4600 (void *)(Addr)ARG3);
4601 SET_STATUS_Failure ( VKI_EFAULT );
4604 else {
4605 SET_STATUS_from_SysRes(
4606 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4607 (vki_sigset_t*) (Addr)ARG2,
4608 (vki_sigset_t*) (Addr)ARG3 )
4612 if (SUCCESS)
4613 *flags |= SfPollAfter;
4615 POST(sys_rt_sigprocmask)
4617 vg_assert(SUCCESS);
4618 if (RES == 0 && ARG3 != 0)
4619 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4622 PRE(sys_rt_sigpending)
4624 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4625 PRE_REG_READ2(long, "rt_sigpending",
4626 vki_sigset_t *, set, vki_size_t, sigsetsize);
4627 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4629 POST(sys_rt_sigpending)
4631 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4634 PRE(sys_rt_sigtimedwait)
4636 *flags |= SfMayBlock;
4637 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4638 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4639 ARG1, ARG2, ARG3, ARG4);
4640 PRE_REG_READ4(long, "rt_sigtimedwait",
4641 const vki_sigset_t *, set, vki_siginfo_t *, info,
4642 const struct timespec *, timeout, vki_size_t, sigsetsize);
4643 if (ARG1 != 0)
4644 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4645 if (ARG2 != 0)
4646 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4647 if (ARG3 != 0)
4648 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4649 ARG3, sizeof(struct vki_timespec) );
4651 POST(sys_rt_sigtimedwait)
4653 if (ARG2 != 0)
4654 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4657 PRE(sys_rt_sigtimedwait_time64)
4659 *flags |= SfMayBlock;
4660 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4661 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4662 ARG1, ARG2, ARG3, ARG4);
4663 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4664 const vki_sigset_t *, set, vki_siginfo_t *, info,
4665 const struct vki_timespec64 *, timeout,
4666 vki_size_t, sigsetsize);
4667 if (ARG1 != 0)
4668 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4669 if (ARG2 != 0)
4670 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4671 sizeof(vki_siginfo_t) );
4672 if (ARG3 != 0)
4673 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4675 POST(sys_rt_sigtimedwait_time64)
4677 if (ARG2 != 0)
4678 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4681 PRE(sys_rt_sigqueueinfo)
4683 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4684 SARG1, SARG2, ARG3);
4685 PRE_REG_READ3(long, "rt_sigqueueinfo",
4686 int, pid, int, sig, vki_siginfo_t *, uinfo);
4687 if (ARG2 != 0)
4688 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4690 POST(sys_rt_sigqueueinfo)
4692 if (!ML_(client_signal_OK)(ARG2))
4693 SET_STATUS_Failure( VKI_EINVAL );
4696 PRE(sys_rt_tgsigqueueinfo)
4698 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4699 SARG1, SARG2, SARG3, ARG4);
4700 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4701 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4702 if (ARG3 != 0)
4703 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4706 POST(sys_rt_tgsigqueueinfo)
4708 if (!ML_(client_signal_OK)(ARG3))
4709 SET_STATUS_Failure( VKI_EINVAL );
4712 // XXX: x86-specific? The kernel prototypes for the different archs are
4713 // hard to decipher.
4714 PRE(sys_rt_sigsuspend)
4716 /* The C library interface to sigsuspend just takes a pointer to
4717 a signal mask but this system call has two arguments - a pointer
4718 to the mask and the number of bytes used by it. The kernel insists
4719 on the size being equal to sizeof(sigset_t) however and will just
4720 return EINVAL if it isn't.
4722 *flags |= SfMayBlock;
4723 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4724 ARG1, ARG2 );
4725 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4726 if (ARG1 != (Addr)NULL) {
4727 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4728 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4729 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4730 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4731 be killable by VG_(nuke_all_threads_except).
4732 We thus silently ignore the user request to mask this signal.
4733 Note that this is similar to what is done for e.g.
4734 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4735 } else {
4736 SET_STATUS_Failure(VKI_EFAULT);
4741 /* ---------------------------------------------------------------------
4742 linux msg* wrapper helpers
4743 ------------------------------------------------------------------ */
4745 void
4746 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4747 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4749 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4750 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4751 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4752 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4755 void
4756 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4757 UWord arg0, UWord arg1, UWord arg2,
4758 UWord arg3, UWord arg4 )
4760 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4761 long msgtyp, int msgflg); */
4762 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4763 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4764 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4766 void
4767 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4768 UWord res,
4769 UWord arg0, UWord arg1, UWord arg2,
4770 UWord arg3, UWord arg4 )
4772 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4773 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4774 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4777 void
4778 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4779 UWord arg0, UWord arg1, UWord arg2 )
4781 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4782 switch (arg1 /* cmd */) {
4783 case VKI_IPC_INFO:
4784 case VKI_MSG_INFO:
4785 case VKI_IPC_INFO|VKI_IPC_64:
4786 case VKI_MSG_INFO|VKI_IPC_64:
4787 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4788 arg2, sizeof(struct vki_msginfo) );
4789 break;
4790 case VKI_IPC_STAT:
4791 case VKI_MSG_STAT:
4792 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4793 arg2, sizeof(struct vki_msqid_ds) );
4794 break;
4795 case VKI_IPC_STAT|VKI_IPC_64:
4796 case VKI_MSG_STAT|VKI_IPC_64:
4797 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4798 arg2, sizeof(struct vki_msqid64_ds) );
4799 break;
4800 case VKI_IPC_SET:
4801 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4802 arg2, sizeof(struct vki_msqid_ds) );
4803 break;
4804 case VKI_IPC_SET|VKI_IPC_64:
4805 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4806 arg2, sizeof(struct vki_msqid64_ds) );
4807 break;
4810 void
4811 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4812 UWord res,
4813 UWord arg0, UWord arg1, UWord arg2 )
4815 switch (arg1 /* cmd */) {
4816 case VKI_IPC_INFO:
4817 case VKI_MSG_INFO:
4818 case VKI_IPC_INFO|VKI_IPC_64:
4819 case VKI_MSG_INFO|VKI_IPC_64:
4820 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4821 break;
4822 case VKI_IPC_STAT:
4823 case VKI_MSG_STAT:
4824 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4825 break;
4826 case VKI_IPC_STAT|VKI_IPC_64:
4827 case VKI_MSG_STAT|VKI_IPC_64:
4828 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4829 break;
4833 /* ---------------------------------------------------------------------
4834 Generic handler for sys_ipc
4835 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4836 are either direct system calls, or are all implemented via sys_ipc.
4837 ------------------------------------------------------------------ */
4838 #ifdef __NR_ipc
4839 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4841 Addr* a_p = (Addr*)a;
4842 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4843 return *a_p;
4846 static Bool semctl_cmd_has_4args (UWord cmd)
4848 switch (cmd & ~VKI_IPC_64)
4850 case VKI_IPC_INFO:
4851 case VKI_SEM_INFO:
4852 case VKI_IPC_STAT:
4853 case VKI_SEM_STAT:
4854 case VKI_IPC_SET:
4855 case VKI_GETALL:
4856 case VKI_SETALL:
4857 return True;
4858 default:
4859 return False;
4863 PRE(sys_ipc)
4865 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4866 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4868 switch (ARG1 /* call */) {
4869 case VKI_SEMOP:
4870 PRE_REG_READ5(int, "ipc",
4871 vki_uint, call, int, first, int, second, int, third,
4872 void *, ptr);
4873 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4874 *flags |= SfMayBlock;
4875 break;
4876 case VKI_SEMGET:
4877 PRE_REG_READ4(int, "ipc",
4878 vki_uint, call, int, first, int, second, int, third);
4879 break;
4880 case VKI_SEMCTL:
4882 PRE_REG_READ5(int, "ipc",
4883 vki_uint, call, int, first, int, second, int, third,
4884 void *, ptr);
4885 UWord arg;
4886 if (semctl_cmd_has_4args(ARG4))
4887 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4888 else
4889 arg = 0;
4890 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4891 break;
4893 case VKI_SEMTIMEDOP:
4894 #ifdef VGP_s390x_linux
4895 /* On s390x Linux platforms the sys_ipc semtimedop call has four instead
4896 of five parameters, where the timeout is passed in the third instead of
4897 the fifth. */
4898 PRE_REG_READ5(int, "ipc",
4899 vki_uint, call, int, first, int, second, long, third,
4900 void *, ptr);
4901 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG4 );
4902 #else
4903 PRE_REG_READ6(int, "ipc",
4904 vki_uint, call, int, first, int, second, int, third,
4905 void *, ptr, long, fifth);
4906 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4907 #endif
4908 *flags |= SfMayBlock;
4909 break;
4910 case VKI_MSGSND:
4911 PRE_REG_READ5(int, "ipc",
4912 vki_uint, call, int, first, int, second, int, third,
4913 void *, ptr);
4914 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4915 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4916 *flags |= SfMayBlock;
4917 break;
4918 case VKI_MSGRCV:
4920 PRE_REG_READ5(int, "ipc",
4921 vki_uint, call, int, first, int, second, int, third,
4922 void *, ptr);
4923 Addr msgp;
4924 Word msgtyp;
4926 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4927 "msgrcv(msgp)" );
4928 msgtyp = deref_Addr( tid,
4929 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4930 "msgrcv(msgp)" );
4932 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4934 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4935 *flags |= SfMayBlock;
4936 break;
4938 case VKI_MSGGET:
4939 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4940 break;
4941 case VKI_MSGCTL:
4942 PRE_REG_READ5(int, "ipc",
4943 vki_uint, call, int, first, int, second, int, third,
4944 void *, ptr);
4945 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4946 break;
4947 case VKI_SHMAT:
4949 PRE_REG_READ5(int, "ipc",
4950 vki_uint, call, int, first, int, second, int, third,
4951 void *, ptr);
4952 UWord w;
4953 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4954 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4955 if (w == 0)
4956 SET_STATUS_Failure( VKI_EINVAL );
4957 else
4958 ARG5 = w;
4959 break;
4961 case VKI_SHMDT:
4962 PRE_REG_READ5(int, "ipc",
4963 vki_uint, call, int, first, int, second, int, third,
4964 void *, ptr);
4965 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4966 SET_STATUS_Failure( VKI_EINVAL );
4967 break;
4968 case VKI_SHMGET:
4969 PRE_REG_READ4(int, "ipc",
4970 vki_uint, call, int, first, int, second, int, third);
4971 if (ARG4 & VKI_SHM_HUGETLB) {
4972 static Bool warning_given = False;
4973 ARG4 &= ~VKI_SHM_HUGETLB;
4974 if (!warning_given) {
4975 warning_given = True;
4976 VG_(umsg)(
4977 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4980 break;
4981 case VKI_SHMCTL: /* IPCOP_shmctl */
4982 PRE_REG_READ5(int, "ipc",
4983 vki_uint, call, int, first, int, second, int, third,
4984 void *, ptr);
4985 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4986 break;
4987 default:
4988 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4989 VG_(core_panic)("... bye!\n");
4990 break; /*NOTREACHED*/
4994 POST(sys_ipc)
4996 vg_assert(SUCCESS);
4997 switch (ARG1 /* call */) {
4998 case VKI_SEMOP:
4999 case VKI_SEMGET:
5000 break;
5001 case VKI_SEMCTL:
5003 UWord arg;
5004 if (semctl_cmd_has_4args(ARG4))
5005 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
5006 else
5007 arg = 0;
5008 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
5009 break;
5011 case VKI_SEMTIMEDOP:
5012 case VKI_MSGSND:
5013 break;
5014 case VKI_MSGRCV:
5016 Addr msgp;
5017 Word msgtyp;
5019 msgp = deref_Addr( tid,
5020 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
5021 "msgrcv(msgp)" );
5022 msgtyp = deref_Addr( tid,
5023 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
5024 "msgrcv(msgp)" );
5026 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
5027 break;
5029 case VKI_MSGGET:
5030 break;
5031 case VKI_MSGCTL:
5032 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
5033 break;
5034 case VKI_SHMAT:
5036 Addr addr;
5038 /* force readability. before the syscall it is
5039 * indeed uninitialized, as can be seen in
5040 * glibc/sysdeps/unix/sysv/linux/shmat.c */
5041 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
5043 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
5044 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
5045 break;
5047 case VKI_SHMDT:
5048 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
5049 break;
5050 case VKI_SHMGET:
5051 break;
5052 case VKI_SHMCTL:
5053 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
5054 break;
5055 default:
5056 VG_(message)(Vg_DebugMsg,
5057 "FATAL: unhandled syscall(ipc) %lu\n",
5058 ARG1 );
5059 VG_(core_panic)("... bye!\n");
5060 break; /*NOTREACHED*/
5063 #endif
5065 PRE(sys_semget)
5067 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5068 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
5071 PRE(sys_semop)
5073 *flags |= SfMayBlock;
5074 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5075 SARG1, ARG2, ARG3);
5076 PRE_REG_READ3(long, "semop",
5077 int, semid, struct sembuf *, sops, unsigned, nsoops);
5078 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
5081 PRE(sys_semctl)
5083 switch (ARG3 & ~VKI_IPC_64) {
5084 case VKI_IPC_INFO:
5085 case VKI_SEM_INFO:
5086 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5087 SARG3, ARG4);
5088 PRE_REG_READ4(long, "semctl",
5089 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
5090 break;
5091 case VKI_IPC_STAT:
5092 case VKI_SEM_STAT:
5093 case VKI_IPC_SET:
5094 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5095 SARG3, ARG4);
5096 PRE_REG_READ4(long, "semctl",
5097 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
5098 break;
5099 case VKI_GETALL:
5100 case VKI_SETALL:
5101 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5102 SARG3, ARG4);
5103 PRE_REG_READ4(long, "semctl",
5104 int, semid, int, semnum, int, cmd, unsigned short *, arg);
5105 break;
5106 default:
5107 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5108 PRE_REG_READ3(long, "semctl",
5109 int, semid, int, semnum, int, cmd);
5110 break;
5112 #ifdef VGP_amd64_linux
5113 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5114 #else
5115 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
5116 #endif
5119 POST(sys_semctl)
5121 #ifdef VGP_amd64_linux
5122 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5123 #else
5124 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
5125 #endif
5128 PRE(sys_semtimedop)
5130 *flags |= SfMayBlock;
5131 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5132 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5133 PRE_REG_READ4(long, "semtimedop",
5134 int, semid, struct sembuf *, sops, unsigned, nsoops,
5135 struct timespec *, timeout);
5136 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
5139 PRE(sys_semtimedop_time64)
5141 *flags |= SfMayBlock;
5142 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
5143 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5144 PRE_REG_READ4(long, "semtimedop_time64",
5145 int, semid, struct sembuf *, sops, unsigned, nsoops,
5146 struct vki_timespec64 *, timeout);
5147 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
5148 ARG2 * sizeof(struct vki_sembuf) );
5149 if (ARG3 != 0)
5150 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
5153 PRE(sys_msgget)
5155 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
5156 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
5159 PRE(sys_msgsnd)
5161 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
5162 SARG1, ARG2, ARG3, SARG4);
5163 PRE_REG_READ4(long, "msgsnd",
5164 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
5165 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
5166 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
5167 *flags |= SfMayBlock;
5170 PRE(sys_msgrcv)
5172 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
5173 SARG1, ARG2, ARG3, SARG4, SARG5);
5174 PRE_REG_READ5(long, "msgrcv",
5175 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
5176 long, msgytp, int, msgflg);
5177 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5178 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
5179 *flags |= SfMayBlock;
5181 POST(sys_msgrcv)
5183 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
5186 PRE(sys_msgctl)
5188 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5189 PRE_REG_READ3(long, "msgctl",
5190 int, msqid, int, cmd, struct msqid_ds *, buf);
5191 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5194 POST(sys_msgctl)
5196 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5199 PRE(sys_shmget)
5201 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5202 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5203 if (ARG3 & VKI_SHM_HUGETLB) {
5204 static Bool warning_given = False;
5205 ARG3 &= ~VKI_SHM_HUGETLB;
5206 if (!warning_given) {
5207 warning_given = True;
5208 VG_(umsg)(
5209 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5214 PRE(sys_shmat)
5216 UWord arg2tmp;
5217 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5218 PRE_REG_READ3(long, "shmat",
5219 int, shmid, const void *, shmaddr, int, shmflg);
5220 #if defined(VGP_arm_linux)
5221 /* Round the attach address down to an VKI_SHMLBA boundary if the
5222 client requested rounding. See #222545. This is necessary only
5223 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5224 other linux targets it is the same as the page size. */
5225 if (ARG3 & VKI_SHM_RND)
5226 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5227 #endif
5228 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5229 if (arg2tmp == 0)
5230 SET_STATUS_Failure( VKI_EINVAL );
5231 else
5232 ARG2 = arg2tmp; // used in POST
5235 POST(sys_shmat)
5237 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5240 PRE(sys_shmdt)
5242 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5243 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5244 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5245 SET_STATUS_Failure( VKI_EINVAL );
5248 POST(sys_shmdt)
5250 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5253 PRE(sys_shmctl)
5255 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5256 PRE_REG_READ3(long, "shmctl",
5257 int, shmid, int, cmd, struct shmid_ds *, buf);
5258 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5259 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5260 #else
5261 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5262 #endif
5265 POST(sys_shmctl)
5267 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5268 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5269 #else
5270 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5271 #endif
5275 /* ---------------------------------------------------------------------
5276 Generic handler for sys_socketcall
5277 Depending on the platform, some socket related syscalls (e.g. socketpair,
5278 socket, bind, ...)
5279 are either direct system calls, or are all implemented via sys_socketcall.
5280 ------------------------------------------------------------------ */
5281 #ifdef __NR_socketcall
5282 PRE(sys_socketcall)
5284 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5285 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5286 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5287 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5288 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5289 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5291 // call PRE_MEM_READ and check for EFAULT result.
5292 #define PRE_MEM_READ_ef(msg, arg, size) \
5294 PRE_MEM_READ( msg, arg, size); \
5295 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5296 SET_STATUS_Failure( VKI_EFAULT ); \
5297 break; \
5301 *flags |= SfMayBlock;
5302 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5303 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5305 switch (ARG1 /* request */) {
5307 case VKI_SYS_SOCKETPAIR:
5308 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5309 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5310 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5311 break;
5313 case VKI_SYS_SOCKET:
5314 /* int socket(int domain, int type, int protocol); */
5315 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5316 break;
5318 case VKI_SYS_BIND:
5319 /* int bind(int sockfd, struct sockaddr *my_addr,
5320 int addrlen); */
5321 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5322 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5323 break;
5325 case VKI_SYS_LISTEN:
5326 /* int listen(int s, int backlog); */
5327 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5328 break;
5330 case VKI_SYS_ACCEPT:
5331 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5332 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5333 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5334 break;
5336 case VKI_SYS_ACCEPT4:
5337 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5338 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5339 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5340 break;
5342 case VKI_SYS_SENDTO:
5343 /* int sendto(int s, const void *msg, int len,
5344 unsigned int flags,
5345 const struct sockaddr *to, int tolen); */
5346 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5347 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5348 ARG2_3, ARG2_4, ARG2_5 );
5349 break;
5351 case VKI_SYS_SEND:
5352 /* int send(int s, const void *msg, size_t len, int flags); */
5353 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5354 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5355 break;
5357 case VKI_SYS_RECVFROM:
5358 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5359 struct sockaddr *from, int *fromlen); */
5360 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5361 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5362 ARG2_3, ARG2_4, ARG2_5 );
5363 break;
5365 case VKI_SYS_RECV:
5366 /* int recv(int s, void *buf, int len, unsigned int flags); */
5367 /* man 2 recv says:
5368 The recv call is normally used only on a connected socket
5369 (see connect(2)) and is identical to recvfrom with a NULL
5370 from parameter.
5372 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5373 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5374 break;
5376 case VKI_SYS_CONNECT:
5377 /* int connect(int sockfd,
5378 struct sockaddr *serv_addr, int addrlen ); */
5379 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5380 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5381 break;
5383 case VKI_SYS_SETSOCKOPT:
5384 /* int setsockopt(int s, int level, int optname,
5385 const void *optval, int optlen); */
5386 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5387 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5388 ARG2_3, ARG2_4 );
5389 break;
5391 case VKI_SYS_GETSOCKOPT:
5392 /* int getsockopt(int s, int level, int optname,
5393 void *optval, socklen_t *optlen); */
5394 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5395 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5396 ARG2_3, ARG2_4 );
5397 break;
5399 case VKI_SYS_GETSOCKNAME:
5400 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5401 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5402 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5403 break;
5405 case VKI_SYS_GETPEERNAME:
5406 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5407 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5408 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5409 break;
5411 case VKI_SYS_SHUTDOWN:
5412 /* int shutdown(int s, int how); */
5413 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5414 break;
5416 case VKI_SYS_SENDMSG:
5417 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5418 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5419 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5420 (struct vki_msghdr *)(Addr)ARG2_1 );
5421 break;
5423 case VKI_SYS_RECVMSG:
5424 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5425 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5426 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5427 (struct vki_msghdr *)(Addr)ARG2_1 );
5428 break;
5430 case VKI_SYS_RECVMMSG:
5431 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5432 struct timespec *timeout); */
5433 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5434 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5435 ARG2_4 );
5436 break;
5438 case VKI_SYS_SENDMMSG:
5439 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5440 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5441 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5442 break;
5444 default:
5445 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5446 SET_STATUS_Failure( VKI_EINVAL );
5447 break;
5449 # undef ARG2_0
5450 # undef ARG2_1
5451 # undef ARG2_2
5452 # undef ARG2_3
5453 # undef ARG2_4
5454 # undef ARG2_5
5457 POST(sys_socketcall)
5459 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5460 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5461 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5462 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5463 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5464 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5466 SysRes r;
5467 vg_assert(SUCCESS);
5468 switch (ARG1 /* request */) {
5470 case VKI_SYS_SOCKETPAIR:
5471 r = ML_(generic_POST_sys_socketpair)(
5472 tid, VG_(mk_SysRes_Success)(RES),
5473 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5475 SET_STATUS_from_SysRes(r);
5476 break;
5478 case VKI_SYS_SOCKET:
5479 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5480 SET_STATUS_from_SysRes(r);
5481 break;
5483 case VKI_SYS_BIND:
5484 /* int bind(int sockfd, struct sockaddr *my_addr,
5485 int addrlen); */
5486 break;
5488 case VKI_SYS_LISTEN:
5489 /* int listen(int s, int backlog); */
5490 break;
5492 case VKI_SYS_ACCEPT:
5493 case VKI_SYS_ACCEPT4:
5494 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5495 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5496 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5497 ARG2_0, ARG2_1, ARG2_2 );
5498 SET_STATUS_from_SysRes(r);
5499 break;
5501 case VKI_SYS_SENDTO:
5502 break;
5504 case VKI_SYS_SEND:
5505 break;
5507 case VKI_SYS_RECVFROM:
5508 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5509 ARG2_0, ARG2_1, ARG2_2,
5510 ARG2_3, ARG2_4, ARG2_5 );
5511 break;
5513 case VKI_SYS_RECV:
5514 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5515 break;
5517 case VKI_SYS_CONNECT:
5518 break;
5520 case VKI_SYS_SETSOCKOPT:
5521 break;
5523 case VKI_SYS_GETSOCKOPT:
5524 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5525 ARG2_0, ARG2_1,
5526 ARG2_2, ARG2_3, ARG2_4 );
5527 break;
5529 case VKI_SYS_GETSOCKNAME:
5530 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5531 ARG2_0, ARG2_1, ARG2_2 );
5532 break;
5534 case VKI_SYS_GETPEERNAME:
5535 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5536 ARG2_0, ARG2_1, ARG2_2 );
5537 break;
5539 case VKI_SYS_SHUTDOWN:
5540 break;
5542 case VKI_SYS_SENDMSG:
5543 break;
5545 case VKI_SYS_RECVMSG:
5546 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5547 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5548 break;
5550 case VKI_SYS_RECVMMSG:
5551 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5552 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5553 break;
5555 case VKI_SYS_SENDMMSG:
5556 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5557 break;
5559 default:
5560 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5561 VG_(core_panic)("... bye!\n");
5562 break; /*NOTREACHED*/
5564 # undef ARG2_0
5565 # undef ARG2_1
5566 # undef ARG2_2
5567 # undef ARG2_3
5568 # undef ARG2_4
5569 # undef ARG2_5
5571 #endif
5573 PRE(sys_socket)
5575 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5576 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5578 POST(sys_socket)
5580 SysRes r;
5581 vg_assert(SUCCESS);
5582 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5583 SET_STATUS_from_SysRes(r);
5586 PRE(sys_setsockopt)
5588 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5589 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5590 PRE_REG_READ5(long, "setsockopt",
5591 int, s, int, level, int, optname,
5592 const void *, optval, unsigned, optlen); // socklen_t
5593 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5596 PRE(sys_getsockopt)
5598 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5599 SARG1, SARG2, SARG3, ARG4, SARG5);
5600 PRE_REG_READ5(long, "getsockopt",
5601 int, s, int, level, int, optname,
5602 void *, optval, int, *optlen);
5603 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5605 POST(sys_getsockopt)
5607 vg_assert(SUCCESS);
5608 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5609 ARG1,ARG2,ARG3,ARG4,ARG5);
5612 PRE(sys_connect)
5614 *flags |= SfMayBlock;
5615 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5616 PRE_REG_READ3(long, "connect",
5617 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5618 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5621 PRE(sys_accept)
5623 *flags |= SfMayBlock;
5624 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5625 SARG1, ARG2, ARG3);
5626 PRE_REG_READ3(long, "accept",
5627 int, s, struct sockaddr *, addr, int *, addrlen);
5628 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5630 POST(sys_accept)
5632 SysRes r;
5633 vg_assert(SUCCESS);
5634 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5635 ARG1,ARG2,ARG3);
5636 SET_STATUS_from_SysRes(r);
5639 PRE(sys_accept4)
5641 *flags |= SfMayBlock;
5642 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5643 SARG1, ARG2, ARG3, SARG4);
5644 PRE_REG_READ4(long, "accept4",
5645 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5646 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5648 POST(sys_accept4)
5650 SysRes r;
5651 vg_assert(SUCCESS);
5652 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5653 ARG1,ARG2,ARG3);
5654 SET_STATUS_from_SysRes(r);
5657 PRE(sys_send)
5659 *flags |= SfMayBlock;
5660 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5661 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5662 PRE_REG_READ4(long, "send",
5663 int, s, const void *, msg, vki_size_t, len,
5664 int, flags);
5666 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5669 PRE(sys_sendto)
5671 *flags |= SfMayBlock;
5672 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5673 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5674 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5675 PRE_REG_READ6(long, "sendto",
5676 int, s, const void *, msg, vki_size_t, len,
5677 unsigned int, flags,
5678 const struct sockaddr *, to, int, tolen);
5679 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5682 PRE (sys_recv)
5684 *flags |= SfMayBlock;
5685 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5686 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5687 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5688 unsigned int, flags);
5689 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5692 POST (sys_recv)
5694 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5697 PRE(sys_recvfrom)
5699 *flags |= SfMayBlock;
5700 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5701 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5702 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5703 PRE_REG_READ6(long, "recvfrom",
5704 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5705 struct sockaddr *, from, int *, fromlen);
5706 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5708 POST(sys_recvfrom)
5710 vg_assert(SUCCESS);
5711 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5712 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5715 PRE(sys_sendmsg)
5717 *flags |= SfMayBlock;
5718 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5719 SARG1, ARG2, ARG3);
5720 PRE_REG_READ3(long, "sendmsg",
5721 int, s, const struct msghdr *, msg, unsigned int, flags);
5722 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5725 PRE(sys_recvmsg)
5727 *flags |= SfMayBlock;
5728 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5729 SARG1, ARG2, ARG3);
5730 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5731 unsigned int, flags);
5732 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5734 POST(sys_recvmsg)
5736 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5737 RES);
5740 PRE(sys_shutdown)
5742 *flags |= SfMayBlock;
5743 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5744 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5747 PRE(sys_bind)
5749 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5750 PRE_REG_READ3(long, "bind",
5751 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5752 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5755 PRE(sys_listen)
5757 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5758 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5761 PRE(sys_getsockname)
5763 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5764 SARG1, ARG2, ARG3);
5765 PRE_REG_READ3(long, "getsockname",
5766 int, s, struct sockaddr *, name, int *, namelen);
5767 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5769 POST(sys_getsockname)
5771 vg_assert(SUCCESS);
5772 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5773 ARG1,ARG2,ARG3);
5776 PRE(sys_getpeername)
5778 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5779 SARG1, ARG2, ARG3);
5780 PRE_REG_READ3(long, "getpeername",
5781 int, s, struct sockaddr *, name, int *, namelen);
5782 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5784 POST(sys_getpeername)
5786 vg_assert(SUCCESS);
5787 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5788 ARG1,ARG2,ARG3);
5791 PRE(sys_socketpair)
5793 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5794 SARG3, ARG4);
5795 PRE_REG_READ4(long, "socketpair",
5796 int, d, int, type, int, protocol, int*, sv);
5797 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5799 POST(sys_socketpair)
5801 vg_assert(SUCCESS);
5802 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5803 ARG1,ARG2,ARG3,ARG4);
5807 /* ---------------------------------------------------------------------
5808 *at wrappers
5809 ------------------------------------------------------------------ */
5811 PRE(sys_openat)
5813 HChar name[30]; // large enough
5814 SysRes sres;
5816 if (ARG3 & VKI_O_CREAT) {
5817 // 4-arg version
5818 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5819 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5820 PRE_REG_READ4(long, "openat",
5821 int, dfd, const char *, filename, int, flags, int, mode);
5822 } else {
5823 // 3-arg version
5824 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5825 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5826 PRE_REG_READ3(long, "openat",
5827 int, dfd, const char *, filename, int, flags);
5830 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5832 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5833 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5834 be sure only to compare the bottom 32 bits. */
5835 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5836 && *(Char *)(Addr)ARG2 != '/'
5837 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5838 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5839 SET_STATUS_Failure( VKI_EBADF );
5841 /* Handle the case where the open is of /proc/self/cmdline or
5842 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5843 fake file we cooked up at startup (in m_main). Also, seek the
5844 cloned fd back to the start. */
5846 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5847 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5848 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5849 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5850 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5851 SET_STATUS_from_SysRes( sres );
5852 if (!sr_isError(sres)) {
5853 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5854 if (off < 0)
5855 SET_STATUS_Failure( VKI_EMFILE );
5857 return;
5860 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5862 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5863 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5864 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5865 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5866 sres = VG_(dup)( VG_(cl_auxv_fd) );
5867 SET_STATUS_from_SysRes( sres );
5868 if (!sr_isError(sres)) {
5869 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5870 if (off < 0)
5871 SET_STATUS_Failure( VKI_EMFILE );
5873 return;
5876 /* And for /proc/self/exe or /proc/<pid>/exe case. */
5878 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5879 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5880 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5881 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5882 sres = VG_(dup)( VG_(cl_exec_fd) );
5883 SET_STATUS_from_SysRes( sres );
5884 if (!sr_isError(sres)) {
5885 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5886 if (off < 0)
5887 SET_STATUS_Failure( VKI_EMFILE );
5889 return;
5892 /* Otherwise handle normally */
5893 *flags |= SfMayBlock;
5896 POST(sys_openat)
5898 vg_assert(SUCCESS);
5899 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5900 VG_(close)(RES);
5901 SET_STATUS_Failure( VKI_EMFILE );
5902 } else {
5903 if (VG_(clo_track_fds))
5904 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5908 PRE(sys_mkdirat)
5910 *flags |= SfMayBlock;
5911 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5912 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5913 PRE_REG_READ3(long, "mkdirat",
5914 int, dfd, const char *, pathname, int, mode);
5915 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5918 PRE(sys_mknodat)
5920 FUSE_COMPATIBLE_MAY_BLOCK();
5921 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5922 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5923 PRE_REG_READ4(long, "mknodat",
5924 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5925 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5928 PRE(sys_fchownat)
5930 FUSE_COMPATIBLE_MAY_BLOCK();
5931 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5932 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5933 PRE_REG_READ4(long, "fchownat",
5934 int, dfd, const char *, path,
5935 vki_uid_t, owner, vki_gid_t, group);
5936 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5939 PRE(sys_futimesat)
5941 FUSE_COMPATIBLE_MAY_BLOCK();
5942 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5943 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5944 PRE_REG_READ3(long, "futimesat",
5945 int, dfd, char *, filename, struct timeval *, tvp);
5946 if (ARG2 != 0)
5947 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5948 if (ARG3 != 0)
5949 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5952 PRE(sys_utimensat)
5954 FUSE_COMPATIBLE_MAY_BLOCK();
5955 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5956 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5957 PRE_REG_READ4(long, "utimensat",
5958 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5959 if (ARG2 != 0)
5960 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5961 if (ARG3 != 0) {
5962 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5963 then the tv_sec field is ignored. */
5964 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5965 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5966 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5967 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5968 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5969 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5970 if (times[0].tv_nsec != VKI_UTIME_NOW
5971 && times[0].tv_nsec != VKI_UTIME_OMIT)
5972 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5973 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5974 if (times[1].tv_nsec != VKI_UTIME_NOW
5975 && times[1].tv_nsec != VKI_UTIME_OMIT)
5976 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5977 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5982 PRE(sys_utimensat_time64)
5984 FUSE_COMPATIBLE_MAY_BLOCK();
5985 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5986 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5987 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5988 PRE_REG_READ4(long, "utimensat_time64",
5989 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5990 if (ARG2 != 0)
5991 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5992 if (ARG3 != 0) {
5993 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5994 then the tv_sec field is ignored. */
5995 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5996 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5997 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5998 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5999 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
6000 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
6001 if (times[0].tv_nsec != VKI_UTIME_NOW
6002 && times[0].tv_nsec != VKI_UTIME_OMIT)
6003 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
6004 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
6005 if (times[1].tv_nsec != VKI_UTIME_NOW
6006 && times[1].tv_nsec != VKI_UTIME_OMIT)
6007 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
6008 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
6013 #if !defined(VGP_nanomips_linux)
6014 PRE(sys_newfstatat)
6016 FUSE_COMPATIBLE_MAY_BLOCK();
6017 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
6018 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6019 PRE_REG_READ3(long, "fstatat",
6020 int, dfd, char *, file_name, struct stat *, buf);
6021 // See the comment about Rust in PRE(sys_statx). When glibc does support
6022 // statx rust uses that instead of the system call, but glibc's statx is
6023 // implemented in terms of fstatat, so the filename being NULL is
6024 // transferred here.
6025 if (ARG2 != 0) {
6026 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
6027 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
6031 POST(sys_newfstatat)
6033 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
6035 #endif
6037 PRE(sys_unlinkat)
6039 *flags |= SfMayBlock;
6040 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
6041 (HChar*)(Addr)ARG2);
6042 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
6043 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
6046 PRE(sys_renameat)
6048 FUSE_COMPATIBLE_MAY_BLOCK();
6049 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
6050 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
6051 ARG4, (HChar*)(Addr)ARG4);
6052 PRE_REG_READ4(long, "renameat",
6053 int, olddfd, const char *, oldpath,
6054 int, newdfd, const char *, newpath);
6055 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
6056 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
6059 PRE(sys_renameat2)
6061 FUSE_COMPATIBLE_MAY_BLOCK();
6062 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
6063 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
6064 ARG4, (HChar*)(Addr)ARG4, ARG5);
6065 PRE_REG_READ5(long, "renameat2",
6066 int, olddfd, const char *, oldpath,
6067 int, newdfd, const char *, newpath,
6068 unsigned int, flags);
6069 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
6070 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
6073 PRE(sys_linkat)
6075 *flags |= SfMayBlock;
6076 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
6077 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
6078 (HChar*)(Addr)ARG4, SARG5);
6079 PRE_REG_READ5(long, "linkat",
6080 int, olddfd, const char *, oldpath,
6081 int, newdfd, const char *, newpath,
6082 int, flags);
6083 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
6084 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
6087 PRE(sys_symlinkat)
6089 *flags |= SfMayBlock;
6090 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
6091 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
6092 PRE_REG_READ3(long, "symlinkat",
6093 const char *, oldpath, int, newdfd, const char *, newpath);
6094 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
6095 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
6098 PRE(sys_readlinkat)
6100 FUSE_COMPATIBLE_MAY_BLOCK();
6101 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
6102 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
6103 PRE_REG_READ4(long, "readlinkat",
6104 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
6105 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
6106 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
6109 POST(sys_readlinkat)
6111 HChar name[30]; // large enough
6112 Word saved = SYSNO;
6115 * Handle the case where readlinkat is looking at /proc/self/exe or
6116 * /proc/<pid>/exe.
6118 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
6119 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
6120 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
6121 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
6122 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
6123 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
6124 ARG3, ARG4));
6127 if (SUCCESS && RES > 0)
6128 POST_MEM_WRITE( ARG3, RES );
6131 PRE(sys_fchmodat)
6133 FUSE_COMPATIBLE_MAY_BLOCK();
6134 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
6135 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6136 PRE_REG_READ3(long, "fchmodat",
6137 int, dfd, const char *, path, vki_mode_t, mode);
6138 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
6141 PRE(sys_fchmodat2)
6143 FUSE_COMPATIBLE_MAY_BLOCK();
6144 PRINT("sys_fchmodat2 ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %"
6145 FMT_REGWORD "u )",
6146 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
6147 PRE_REG_READ4(long, "fchmodat2",
6148 int, dfd, const char *, path, vki_mode_t, mode,
6149 unsigned int, flags);
6150 PRE_MEM_RASCIIZ( "fchmodat2(pathname)", ARG2 );
6153 PRE(sys_faccessat)
6155 FUSE_COMPATIBLE_MAY_BLOCK();
6156 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
6157 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
6158 PRE_REG_READ3(long, "faccessat",
6159 int, dfd, const char *, pathname, int, mode);
6160 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
6163 PRE(sys_faccessat2)
6165 FUSE_COMPATIBLE_MAY_BLOCK();
6166 PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
6167 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
6168 PRE_REG_READ4(long, "faccessat2",
6169 int, dfd, const char *, pathname, int, mode, int, flags);
6170 PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 );
6173 PRE(sys_name_to_handle_at)
6175 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
6176 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
6177 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6178 PRE_REG_READ5(int, "name_to_handle_at",
6179 int, dfd, const char *, name,
6180 struct vki_file_handle *, handle,
6181 int *, mnt_id, int, flag);
6182 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
6183 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
6184 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6185 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
6186 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
6188 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
6191 POST(sys_name_to_handle_at)
6193 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6194 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
6195 POST_MEM_WRITE( ARG4, sizeof(int) );
6198 PRE(sys_open_by_handle_at)
6200 *flags |= SfMayBlock;
6201 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
6202 ARG2, SARG3);
6203 PRE_REG_READ3(int, "open_by_handle_at",
6204 int, mountdirfd,
6205 struct vki_file_handle *, handle,
6206 int, flags);
6207 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
6208 sizeof(struct vki_file_handle) +
6209 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
6212 POST(sys_open_by_handle_at)
6214 vg_assert(SUCCESS);
6215 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
6216 VG_(close)(RES);
6217 SET_STATUS_Failure( VKI_EMFILE );
6218 } else {
6219 if (VG_(clo_track_fds))
6220 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
6224 /* ---------------------------------------------------------------------
6225 p{read,write}v wrappers
6226 ------------------------------------------------------------------ */
6227 /* This handles the common part of the PRE macro for preadv and preadv2. */
6228 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
6229 Int fd, Addr vector, Int count, const char *str)
6231 struct vki_iovec * vec;
6232 Int i;
6233 /* safe size for the "preadv/preadv2(vector[i])" string */
6234 char tmp[30];
6236 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6237 SET_STATUS_Failure( VKI_EBADF );
6238 } else if (count > 0) {
6239 VG_(strcpy) (tmp, str);
6240 VG_(strcat) (tmp, "(vector)");
6241 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6243 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6244 count * sizeof(struct vki_iovec))) {
6245 vec = (struct vki_iovec *)(Addr)vector;
6246 for (i = 0; i < count; i++) {
6247 /* Note: building such a dynamic error string is *not*
6248 a pattern to follow. See bug 417075. */
6249 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6250 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6256 /* This handles the common part of the POST macro for preadv and preadv2. */
6257 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6259 vg_assert(SUCCESS);
6260 if (RES > 0) {
6261 Int i;
6262 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6263 Int remains = RES;
6265 /* RES holds the number of bytes read. */
6266 for (i = 0; i < count; i++) {
6267 Int nReadThisBuf = vec[i].iov_len;
6268 if (nReadThisBuf > remains) nReadThisBuf = remains;
6269 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6270 remains -= nReadThisBuf;
6271 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6276 PRE(sys_preadv)
6278 *flags |= SfMayBlock;
6279 const char *str = "preadv";
6280 #if VG_WORDSIZE == 4
6281 /* Note that the offset argument here is in lo+hi order on both
6282 big and little endian platforms... */
6283 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6284 "u, %lld )",
6285 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6286 PRE_REG_READ5(ssize_t, "preadv",
6287 unsigned long, fd, const struct iovec *, vector,
6288 unsigned long, count, vki_u32, offset_low,
6289 vki_u32, offset_high);
6290 #elif VG_WORDSIZE == 8
6291 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6292 PRE_REG_READ4(ssize_t, "preadv",
6293 unsigned long, fd, const struct iovec *, vector,
6294 unsigned long, count, Word, offset);
6295 #else
6296 # error Unexpected word size
6297 #endif
6298 Int fd = ARG1;
6299 Addr vector = ARG2;
6300 Int count = ARG3;
6302 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6306 POST(sys_preadv)
6308 Addr vector = ARG2;
6309 Int count = ARG3;
6311 handle_post_sys_preadv(tid, status, vector, count);
6314 PRE(sys_preadv2)
6316 *flags |= SfMayBlock;
6317 const char *str = "preadv2";
6318 #if VG_WORDSIZE == 4
6319 /* Note that the offset argument here is in lo+hi order on both
6320 big and little endian platforms... */
6321 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6322 "u, %lld, %" FMT_REGWORD "u )",
6323 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6324 PRE_REG_READ6(ssize_t, "preadv2",
6325 unsigned long, fd, const struct iovec *, vector,
6326 unsigned long, count, vki_u32, offset_low,
6327 vki_u32, offset_high, unsigned long, flags);
6328 #elif VG_WORDSIZE == 8
6329 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6330 PRE_REG_READ5(ssize_t, "preadv2",
6331 unsigned long, fd, const struct iovec *, vector,
6332 unsigned long, count, Word, offset, unsigned long, flags);
6333 #else
6334 # error Unexpected word size
6335 #endif
6336 Int fd = ARG1;
6337 Addr vector = ARG2;
6338 Int count = ARG3;
6340 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6343 POST(sys_preadv2)
6345 Addr vector = ARG2;
6346 Int count = ARG3;
6348 handle_post_sys_preadv(tid, status, vector, count);
6351 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6352 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6353 Int fd, Addr vector, Int count, const char *str)
6355 Int i;
6356 struct vki_iovec * vec;
6357 /* safe size for the "preadv/preadv2(vector[i])" string */
6358 char tmp[30];
6360 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6361 SET_STATUS_Failure( VKI_EBADF );
6362 } else if (count > 0) {
6363 VG_(strcpy) (tmp, str);
6364 VG_(strcat) (tmp, "(vector)");
6365 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6366 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6367 count * sizeof(struct vki_iovec))) {
6368 vec = (struct vki_iovec *)(Addr)vector;
6369 for (i = 0; i < count; i++) {
6370 /* Note: building such a dynamic error string is *not*
6371 a pattern to follow. See bug 417075. */
6372 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6373 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6379 PRE(sys_pwritev)
6381 *flags |= SfMayBlock;
6382 const char *str = "pwritev";
6383 #if VG_WORDSIZE == 4
6384 /* Note that the offset argument here is in lo+hi order on both
6385 big and little endian platforms... */
6386 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6387 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6388 PRE_REG_READ5(ssize_t, "pwritev",
6389 unsigned long, fd, const struct iovec *, vector,
6390 unsigned long, count, vki_u32, offset_low,
6391 vki_u32, offset_high);
6392 #elif VG_WORDSIZE == 8
6393 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6394 PRE_REG_READ4(ssize_t, "pwritev",
6395 unsigned long, fd, const struct iovec *, vector,
6396 unsigned long, count, Word, offset);
6397 #else
6398 # error Unexpected word size
6399 #endif
6400 Int fd = ARG1;
6401 Addr vector = ARG2;
6402 Int count = ARG3;
6404 handle_sys_pwritev(tid, status, fd, vector, count, str);
6407 PRE(sys_pwritev2)
6409 *flags |= SfMayBlock;
6410 const char *str = "pwritev2";
6411 #if VG_WORDSIZE == 4
6412 /* Note that the offset argument here is in lo+hi order on both
6413 big and little endian platforms... */
6414 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6415 "u, %lld, %" FMT_REGWORD "u )",
6416 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6417 PRE_REG_READ6(ssize_t, "pwritev2",
6418 unsigned long, fd, const struct iovec *, vector,
6419 unsigned long, count, vki_u32, offset_low,
6420 vki_u32, offset_high, unsigned long, flags);
6421 #elif VG_WORDSIZE == 8
6422 /* Note offset_high isn't actually used? */
6423 PRE_REG_READ6(ssize_t, "pwritev2",
6424 unsigned long, fd, const struct iovec *, vector,
6425 unsigned long, count, Word, offset,
6426 Word, offset_high, unsigned long, flags);
6427 #else
6428 # error Unexpected word size
6429 #endif
6430 Int fd = ARG1;
6431 Addr vector = ARG2;
6432 Int count = ARG3;
6434 handle_sys_pwritev(tid, status, fd, vector, count, str);
6437 /* ---------------------------------------------------------------------
6438 process_vm_{read,write}v wrappers
6439 ------------------------------------------------------------------ */
6441 PRE(sys_process_vm_readv)
6443 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6444 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6445 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6446 PRE_REG_READ6(ssize_t, "process_vm_readv",
6447 vki_pid_t, pid,
6448 const struct iovec *, lvec,
6449 unsigned long, liovcnt,
6450 const struct iovec *, rvec,
6451 unsigned long, riovcnt,
6452 unsigned long, flags);
6453 PRE_MEM_READ( "process_vm_readv(lvec)",
6454 ARG2, ARG3 * sizeof(struct vki_iovec) );
6455 PRE_MEM_READ( "process_vm_readv(rvec)",
6456 ARG4, ARG5 * sizeof(struct vki_iovec) );
6457 if (ARG2 != 0
6458 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6459 sizeof(struct vki_iovec) * ARG3)) {
6460 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6461 UInt i;
6462 for (i = 0; i < ARG3; i++)
6463 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6464 (Addr)vec[i].iov_base, vec[i].iov_len );
6468 POST(sys_process_vm_readv)
6470 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6471 UInt remains = RES;
6472 UInt i;
6473 for (i = 0; i < ARG3; i++) {
6474 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6475 vec[i].iov_len : remains;
6476 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6477 remains -= nReadThisBuf;
6481 PRE(sys_process_vm_writev)
6483 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6484 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6485 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6486 PRE_REG_READ6(ssize_t, "process_vm_writev",
6487 vki_pid_t, pid,
6488 const struct iovec *, lvec,
6489 unsigned long, liovcnt,
6490 const struct iovec *, rvec,
6491 unsigned long, riovcnt,
6492 unsigned long, flags);
6493 PRE_MEM_READ( "process_vm_writev(lvec)",
6494 ARG2, ARG3 * sizeof(struct vki_iovec) );
6495 PRE_MEM_READ( "process_vm_writev(rvec)",
6496 ARG4, ARG5 * sizeof(struct vki_iovec) );
6497 if (ARG2 != 0
6498 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6499 sizeof(struct vki_iovec) * ARG3)) {
6500 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6501 UInt i;
6502 for (i = 0; i < ARG3; i++)
6503 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6504 (Addr)vec[i].iov_base, vec[i].iov_len );
6508 /* ---------------------------------------------------------------------
6509 {send,recv}mmsg wrappers
6510 ------------------------------------------------------------------ */
6512 PRE(sys_sendmmsg)
6514 *flags |= SfMayBlock;
6515 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6516 SARG3, SARG4);
6517 PRE_REG_READ4(long, "sendmmsg",
6518 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6519 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6522 POST(sys_sendmmsg)
6524 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6527 PRE(sys_recvmmsg)
6529 *flags |= SfMayBlock;
6530 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6531 FMT_REGWORD "x )",
6532 SARG1, ARG2, SARG3, SARG4, ARG5);
6533 PRE_REG_READ5(long, "recvmmsg",
6534 int, s, struct mmsghdr *, mmsg, int, vlen,
6535 int, flags, struct timespec *, timeout);
6536 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6539 POST(sys_recvmmsg)
6541 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6544 PRE(sys_recvmmsg_time64)
6546 *flags |= SfMayBlock;
6547 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6548 FMT_REGWORD "x )",
6549 SARG1, ARG2, SARG3, SARG4, ARG5);
6550 PRE_REG_READ5(long, "recvmmsg_time64",
6551 int, s, struct mmsghdr *, mmsg, int, vlen,
6552 int, flags, struct vki_timespec64 *, timeout);
6553 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6554 HChar name[40]; // large enough
6555 UInt i;
6556 for (i = 0; i < ARG3; i++) {
6557 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6558 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6559 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6560 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6562 if (ARG5)
6563 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6566 POST(sys_recvmmsg_time64)
6568 /* ARG5 isn't actually used, so just use the generic POST. */
6569 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6572 /* ---------------------------------------------------------------------
6573 key retention service wrappers
6574 ------------------------------------------------------------------ */
6576 PRE(sys_request_key)
6578 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6579 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6580 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6581 PRE_REG_READ4(long, "request_key",
6582 const char *, type, const char *, description,
6583 const char *, callout_info, vki_key_serial_t, keyring);
6584 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6585 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6586 if (ARG3 != (UWord)NULL)
6587 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6590 PRE(sys_add_key)
6592 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6593 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6594 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6595 PRE_REG_READ5(long, "add_key",
6596 const char *, type, const char *, description,
6597 const void *, payload, vki_size_t, plen,
6598 vki_key_serial_t, keyring);
6599 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6600 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6601 if (ARG3 != (UWord)NULL)
6602 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6605 PRE(sys_keyctl)
6607 switch (ARG1 /* option */) {
6608 case VKI_KEYCTL_GET_KEYRING_ID:
6609 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6610 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6611 int, option, vki_key_serial_t, id, int, create);
6612 break;
6613 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6614 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6615 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6616 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6617 int, option, const char *, name);
6618 if (ARG2 != (UWord)NULL)
6619 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6620 break;
6621 case VKI_KEYCTL_UPDATE:
6622 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6623 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6624 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6625 int, option, vki_key_serial_t, key,
6626 const void *, payload, vki_size_t, plen);
6627 if (ARG3 != (UWord)NULL)
6628 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6629 break;
6630 case VKI_KEYCTL_REVOKE:
6631 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6632 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6633 int, option, vki_key_serial_t, id);
6634 break;
6635 case VKI_KEYCTL_CHOWN:
6636 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6637 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6638 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6639 int, option, vki_key_serial_t, id,
6640 vki_uid_t, uid, vki_gid_t, gid);
6641 break;
6642 case VKI_KEYCTL_SETPERM:
6643 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6644 SARG2, ARG3);
6645 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6646 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6647 break;
6648 case VKI_KEYCTL_DESCRIBE:
6649 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6650 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6651 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6652 int, option, vki_key_serial_t, id,
6653 char *, buffer, vki_size_t, buflen);
6654 if (ARG3 != (UWord)NULL)
6655 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6656 break;
6657 case VKI_KEYCTL_CLEAR:
6658 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6659 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6660 int, option, vki_key_serial_t, keyring);
6661 break;
6662 case VKI_KEYCTL_LINK:
6663 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6664 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6665 vki_key_serial_t, keyring, vki_key_serial_t, key);
6666 break;
6667 case VKI_KEYCTL_UNLINK:
6668 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6669 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6670 vki_key_serial_t, keyring, vki_key_serial_t, key);
6671 break;
6672 case VKI_KEYCTL_SEARCH:
6673 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6674 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6675 ARG4, (HChar*)(Addr)ARG4, SARG5);
6676 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6677 int, option, vki_key_serial_t, keyring,
6678 const char *, type, const char *, description,
6679 vki_key_serial_t, destring);
6680 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6681 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6682 break;
6683 case VKI_KEYCTL_READ:
6684 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6685 "u )", SARG2, ARG3, ARG4);
6686 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6687 int, option, vki_key_serial_t, keyring,
6688 char *, buffer, vki_size_t, buflen);
6689 if (ARG3 != (UWord)NULL)
6690 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6691 break;
6692 case VKI_KEYCTL_INSTANTIATE:
6693 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6694 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6695 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6696 int, option, vki_key_serial_t, key,
6697 char *, payload, vki_size_t, plen,
6698 vki_key_serial_t, keyring);
6699 if (ARG3 != (UWord)NULL)
6700 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6701 break;
6702 case VKI_KEYCTL_NEGATE:
6703 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6704 SARG2, ARG3, SARG4);
6705 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6706 int, option, vki_key_serial_t, key,
6707 unsigned, timeout, vki_key_serial_t, keyring);
6708 break;
6709 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6710 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6711 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6712 int, option, int, reqkey_defl);
6713 break;
6714 case VKI_KEYCTL_SET_TIMEOUT:
6715 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6716 SARG2, ARG3);
6717 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6718 int, option, vki_key_serial_t, key, unsigned, timeout);
6719 break;
6720 case VKI_KEYCTL_ASSUME_AUTHORITY:
6721 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6722 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6723 int, option, vki_key_serial_t, key);
6724 break;
6725 default:
6726 PRINT("sys_keyctl ( %ld ) ", SARG1);
6727 PRE_REG_READ1(long, "keyctl", int, option);
6728 break;
6732 POST(sys_keyctl)
6734 vg_assert(SUCCESS);
6735 switch (ARG1 /* option */) {
6736 case VKI_KEYCTL_DESCRIBE:
6737 case VKI_KEYCTL_READ:
6738 if (RES > ARG4)
6739 POST_MEM_WRITE(ARG3, ARG4);
6740 else
6741 POST_MEM_WRITE(ARG3, RES);
6742 break;
6743 default:
6744 break;
6748 /* ---------------------------------------------------------------------
6749 ioprio_ wrappers
6750 ------------------------------------------------------------------ */
6752 PRE(sys_ioprio_set)
6754 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6755 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6758 PRE(sys_ioprio_get)
6760 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6761 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6764 /* ---------------------------------------------------------------------
6765 _module wrappers
6766 ------------------------------------------------------------------ */
6768 PRE(sys_init_module)
6770 *flags |= SfMayBlock;
6771 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6772 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6773 PRE_REG_READ3(long, "init_module",
6774 void *, umod, unsigned long, len, const char *, uargs);
6775 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6776 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6779 PRE(sys_finit_module)
6781 *flags |= SfMayBlock;
6783 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6784 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6785 PRE_REG_READ3(long, "finit_module",
6786 int, fd, const char *, params, int, flags);
6787 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6790 PRE(sys_delete_module)
6792 *flags |= SfMayBlock;
6793 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6794 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6795 PRE_REG_READ2(long, "delete_module",
6796 const char *, name_user, unsigned int, flags);
6797 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6800 /* ---------------------------------------------------------------------
6801 splice wrappers
6802 ------------------------------------------------------------------ */
6804 PRE(sys_splice)
6806 *flags |= SfMayBlock;
6807 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6808 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6809 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6810 PRE_REG_READ6(vki_ssize_t, "splice",
6811 int, fd_in, vki_loff_t *, off_in,
6812 int, fd_out, vki_loff_t *, off_out,
6813 vki_size_t, len, unsigned int, flags);
6814 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6815 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6816 SET_STATUS_Failure( VKI_EBADF );
6817 } else {
6818 if (ARG2 != 0)
6819 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6820 if (ARG4 != 0)
6821 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6825 PRE(sys_tee)
6827 *flags |= SfMayBlock;
6828 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6829 SARG1, SARG2, ARG3, ARG4);
6830 PRE_REG_READ4(vki_ssize_t, "tee",
6831 int, fd_in, int, fd_out,
6832 vki_size_t, len, unsigned int, flags);
6833 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6834 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6835 SET_STATUS_Failure( VKI_EBADF );
6839 PRE(sys_vmsplice)
6841 Int fdfl;
6842 *flags |= SfMayBlock;
6843 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6844 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6845 PRE_REG_READ4(vki_ssize_t, "splice",
6846 int, fd, struct vki_iovec *, iov,
6847 unsigned long, nr_segs, unsigned int, flags);
6848 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6849 SET_STATUS_Failure( VKI_EBADF );
6850 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6851 SET_STATUS_Failure( VKI_EBADF );
6852 } else {
6853 const struct vki_iovec *iov;
6854 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6855 for (iov = (struct vki_iovec *)(Addr)ARG2;
6856 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6858 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6859 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6860 PRE_MEM_WRITE( "vmsplice(iov[...])",
6861 (Addr)iov->iov_base, iov->iov_len );
6862 else
6863 PRE_MEM_READ( "vmsplice(iov[...])",
6864 (Addr)iov->iov_base, iov->iov_len );
6870 POST(sys_vmsplice)
6872 vg_assert(SUCCESS);
6873 if (RES > 0) {
6874 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6875 vg_assert(fdfl >= 0);
6876 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6878 const struct vki_iovec *iov;
6879 for (iov = (struct vki_iovec *)(Addr)ARG2;
6880 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6882 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6888 /* ---------------------------------------------------------------------
6889 oprofile-related wrappers
6890 ------------------------------------------------------------------ */
6892 #if defined(VGP_x86_linux)
6893 PRE(sys_lookup_dcookie)
6895 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6896 MERGE64(ARG1,ARG2), ARG3, ARG4);
6897 PRE_REG_READ4(long, "lookup_dcookie",
6898 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6899 char *, buf, vki_size_t, len);
6900 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6902 POST(sys_lookup_dcookie)
6904 vg_assert(SUCCESS);
6905 if (ARG3 != (Addr)NULL)
6906 POST_MEM_WRITE( ARG3, RES);
6908 #endif
6910 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6911 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6912 PRE(sys_lookup_dcookie)
6914 *flags |= SfMayBlock;
6915 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6916 PRE_REG_READ3(int, "lookup_dcookie",
6917 unsigned long long, cookie, char *, buf, vki_size_t, len);
6919 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6922 POST(sys_lookup_dcookie)
6924 vg_assert(SUCCESS);
6925 if (ARG2 != (Addr)NULL)
6926 POST_MEM_WRITE( ARG2, RES );
6928 #endif
6930 /* ---------------------------------------------------------------------
6931 fcntl wrappers
6932 ------------------------------------------------------------------ */
6934 PRE(sys_fcntl)
6936 switch (ARG2) {
6937 // These ones ignore ARG3.
6938 case VKI_F_GETFD:
6939 case VKI_F_GETFL:
6940 case VKI_F_GETOWN:
6941 case VKI_F_GETSIG:
6942 case VKI_F_GETLEASE:
6943 case VKI_F_GETPIPE_SZ:
6944 case VKI_F_GET_SEALS:
6945 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6946 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6947 break;
6949 // These ones use ARG3 as "arg".
6950 case VKI_F_DUPFD:
6951 case VKI_F_DUPFD_CLOEXEC:
6952 case VKI_F_SETFD:
6953 case VKI_F_SETFL:
6954 case VKI_F_SETLEASE:
6955 case VKI_F_NOTIFY:
6956 case VKI_F_SETOWN:
6957 case VKI_F_SETSIG:
6958 case VKI_F_SETPIPE_SZ:
6959 case VKI_F_ADD_SEALS:
6960 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6961 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6962 PRE_REG_READ3(long, "fcntl",
6963 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6964 break;
6966 // These ones use ARG3 as "lock".
6967 case VKI_F_GETLK:
6968 case VKI_F_SETLK:
6969 case VKI_F_SETLKW:
6970 case VKI_F_OFD_GETLK:
6971 case VKI_F_OFD_SETLK:
6972 case VKI_F_OFD_SETLKW:
6973 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6974 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6975 PRE_REG_READ3(long, "fcntl",
6976 unsigned int, fd, unsigned int, cmd,
6977 struct vki_flock *, lock);
6979 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6980 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6981 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6982 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6983 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6984 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6985 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6988 break;
6990 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6991 case VKI_F_GETLK64:
6992 case VKI_F_SETLK64:
6993 case VKI_F_SETLKW64:
6994 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6995 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6996 PRE_REG_READ3(long, "fcntl",
6997 unsigned int, fd, unsigned int, cmd,
6998 struct flock64 *, lock);
7000 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
7001 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
7002 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
7003 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
7004 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
7005 if (ARG2 == VKI_F_GETLK64) {
7006 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
7009 break;
7010 # endif
7012 case VKI_F_SETOWN_EX:
7013 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7014 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7015 PRE_REG_READ3(long, "fcntl",
7016 unsigned int, fd, unsigned int, cmd,
7017 struct vki_f_owner_ex *, arg);
7018 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7019 break;
7021 case VKI_F_GETOWN_EX:
7022 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7023 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7024 PRE_REG_READ3(long, "fcntl",
7025 unsigned int, fd, unsigned int, cmd,
7026 struct vki_f_owner_ex *, arg);
7027 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7028 break;
7030 default:
7031 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
7032 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7033 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
7034 ARG2);
7035 SET_STATUS_Failure( VKI_EINVAL );
7036 break;
7039 # if defined(VGP_x86_linux)
7040 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
7041 # else
7042 if (ARG2 == VKI_F_SETLKW)
7043 # endif
7044 *flags |= SfMayBlock;
7046 if (!ML_(fd_allowed)(ARG1, "fcntl", tid, False)) {
7047 SET_STATUS_Failure (VKI_EBADF);
7051 POST(sys_fcntl)
7053 vg_assert(SUCCESS);
7054 if (ARG2 == VKI_F_DUPFD) {
7055 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
7056 VG_(close)(RES);
7057 SET_STATUS_Failure( VKI_EMFILE );
7058 } else {
7059 if (VG_(clo_track_fds))
7060 ML_(record_fd_open_named)(tid, RES);
7063 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
7064 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
7065 VG_(close)(RES);
7066 SET_STATUS_Failure( VKI_EMFILE );
7067 } else {
7068 if (VG_(clo_track_fds))
7069 ML_(record_fd_open_named)(tid, RES);
7071 } else if (ARG2 == VKI_F_GETOWN_EX) {
7072 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7073 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
7074 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
7075 POST_FIELD_WRITE(lock->l_pid);
7076 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
7077 } else if (ARG2 == VKI_F_GETLK64) {
7078 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
7079 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
7080 # endif
7084 // XXX: wrapper only suitable for 32-bit systems
7085 PRE(sys_fcntl64)
7087 switch (ARG2) {
7088 // These ones ignore ARG3.
7089 case VKI_F_GETFD:
7090 case VKI_F_GETFL:
7091 case VKI_F_GETOWN:
7092 case VKI_F_SETOWN:
7093 case VKI_F_GETSIG:
7094 case VKI_F_SETSIG:
7095 case VKI_F_GETLEASE:
7096 case VKI_F_GET_SEALS:
7097 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
7098 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
7099 break;
7101 // These ones use ARG3 as "arg".
7102 case VKI_F_DUPFD:
7103 case VKI_F_DUPFD_CLOEXEC:
7104 case VKI_F_SETFD:
7105 case VKI_F_SETFL:
7106 case VKI_F_SETLEASE:
7107 case VKI_F_NOTIFY:
7108 case VKI_F_ADD_SEALS:
7109 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7110 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7111 PRE_REG_READ3(long, "fcntl64",
7112 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
7113 break;
7115 // These ones use ARG3 as "lock".
7116 case VKI_F_GETLK:
7117 case VKI_F_SETLK:
7118 case VKI_F_SETLKW:
7119 # if defined(VGP_x86_linux)
7120 case VKI_F_GETLK64:
7121 case VKI_F_SETLK64:
7122 case VKI_F_SETLKW64:
7123 # endif
7124 case VKI_F_OFD_GETLK:
7125 case VKI_F_OFD_SETLK:
7126 case VKI_F_OFD_SETLKW:
7127 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7128 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7129 PRE_REG_READ3(long, "fcntl64",
7130 unsigned int, fd, unsigned int, cmd,
7131 struct flock64 *, lock);
7132 break;
7134 case VKI_F_SETOWN_EX:
7135 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7136 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7137 PRE_REG_READ3(long, "fcntl",
7138 unsigned int, fd, unsigned int, cmd,
7139 struct vki_f_owner_ex *, arg);
7140 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7141 break;
7143 case VKI_F_GETOWN_EX:
7144 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7145 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7146 PRE_REG_READ3(long, "fcntl",
7147 unsigned int, fd, unsigned int, cmd,
7148 struct vki_f_owner_ex *, arg);
7149 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7150 break;
7153 # if defined(VGP_x86_linux)
7154 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
7155 # else
7156 if (ARG2 == VKI_F_SETLKW)
7157 # endif
7158 *flags |= SfMayBlock;
7160 if (!ML_(fd_allowed)(ARG1, "fcntl64", tid, False)) {
7161 SET_STATUS_Failure (VKI_EBADF);
7165 POST(sys_fcntl64)
7167 vg_assert(SUCCESS);
7168 if (ARG2 == VKI_F_DUPFD) {
7169 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
7170 VG_(close)(RES);
7171 SET_STATUS_Failure( VKI_EMFILE );
7172 } else {
7173 if (VG_(clo_track_fds))
7174 ML_(record_fd_open_named)(tid, RES);
7177 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
7178 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
7179 VG_(close)(RES);
7180 SET_STATUS_Failure( VKI_EMFILE );
7181 } else {
7182 if (VG_(clo_track_fds))
7183 ML_(record_fd_open_named)(tid, RES);
7185 } else if (ARG2 == VKI_F_GETOWN_EX) {
7186 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7190 /* ---------------------------------------------------------------------
7191 ioctl wrappers
7192 ------------------------------------------------------------------ */
7194 struct vg_drm_version_info {
7195 struct vki_drm_version data;
7196 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
7199 PRE(sys_ioctl)
7201 *flags |= SfMayBlock;
7203 ARG2 = (UInt)ARG2;
7205 // We first handle the ones that don't use ARG3 (even as a
7206 // scalar/non-pointer argument).
7207 switch (ARG2 /* request */) {
7209 /* asm-generic/ioctls.h */
7210 case VKI_FIOCLEX:
7211 case VKI_FIONCLEX:
7212 case VKI_TIOCNOTTY:
7214 /* linux perf_event ioctls */
7215 case VKI_PERF_EVENT_IOC_ENABLE:
7216 case VKI_PERF_EVENT_IOC_DISABLE:
7218 /* linux/soundcard interface (ALSA) */
7219 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7220 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7221 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7222 case VKI_SNDRV_PCM_IOCTL_RESET:
7223 case VKI_SNDRV_PCM_IOCTL_START:
7224 case VKI_SNDRV_PCM_IOCTL_DROP:
7225 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7226 case VKI_SNDRV_PCM_IOCTL_RESUME:
7227 case VKI_SNDRV_PCM_IOCTL_XRUN:
7228 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7229 case VKI_SNDRV_TIMER_IOCTL_START:
7230 case VKI_SNDRV_TIMER_IOCTL_STOP:
7231 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7232 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
7234 /* SCSI no operand */
7235 case VKI_SCSI_IOCTL_DOORLOCK:
7236 case VKI_SCSI_IOCTL_DOORUNLOCK:
7238 /* CDROM stuff. */
7239 case VKI_CDROM_DISC_STATUS:
7240 case VKI_CDROMSTOP:
7242 /* DVD stuff */
7243 case VKI_DVD_READ_STRUCT:
7245 /* KVM ioctls that don't check for a numeric value as parameter */
7246 case VKI_KVM_S390_ENABLE_SIE:
7247 case VKI_KVM_CREATE_IRQCHIP:
7248 case VKI_KVM_S390_INITIAL_RESET:
7249 case VKI_KVM_KVMCLOCK_CTRL:
7251 /* vhost without parameter */
7252 case VKI_VHOST_SET_OWNER:
7253 case VKI_VHOST_RESET_OWNER:
7255 /* User input device creation */
7256 case VKI_UI_DEV_CREATE:
7257 case VKI_UI_DEV_DESTROY:
7259 /* InfiniBand */
7260 case VKI_IB_USER_MAD_ENABLE_PKEY:
7262 /* Lustre */
7263 case VKI_LL_IOC_GROUP_LOCK:
7264 case VKI_LL_IOC_GROUP_UNLOCK:
7266 /* V4L2 */
7267 case VKI_V4L2_LOG_STATUS:
7269 /* Mesa */
7270 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7272 /* DVB */
7273 case VKI_DMX_STOP:
7274 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7275 PRE_REG_READ2(long, "ioctl",
7276 unsigned int, fd, unsigned int, request);
7277 return;
7279 default:
7280 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7281 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7282 PRE_REG_READ3(long, "ioctl",
7283 unsigned int, fd, unsigned int, request, unsigned long, arg);
7284 break;
7287 // We now handle those that do look at ARG3 (and unknown ones fall into
7288 // this category). Nb: some of these may well belong in the
7289 // doesn't-use-ARG3 switch above.
7290 switch (ARG2 /* request */) {
7292 case VKI_ION_IOC_ALLOC: {
7293 struct vki_ion_allocation_data* data
7294 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7295 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7296 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7297 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7298 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7299 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7300 break;
7302 case VKI_ION_IOC_MAP: {
7303 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7304 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7305 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7306 break;
7308 case VKI_ION_IOC_IMPORT: {
7309 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7310 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7311 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7312 break;
7315 case VKI_SYNC_IOC_MERGE: {
7316 struct vki_sync_merge_data* data =
7317 (struct vki_sync_merge_data*)(Addr)ARG3;
7318 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7319 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7320 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7321 PRE_FIELD_READ("ioctl(SYNC_IOC_MERGE).flags", data->flags);
7322 break;
7325 case VKI_SYNC_IOC_FILE_INFO: {
7326 struct vki_sync_file_info* data =
7327 (struct vki_sync_file_info*)(Addr)ARG3;
7328 PRE_FIELD_READ ("ioctl(SYNC_IOC_FILE_INFO).flags", data->flags);
7329 PRE_FIELD_READ ("ioctl(SYNC_IOC_FILE_INFO).num_fences", data->num_fences);
7330 PRE_FIELD_WRITE("ioctl(SYNC_IOC_FILE_INFO).status", data->status);
7331 if (data->num_fences)
7332 PRE_MEM_WRITE("ioctl(SYNC_IOC_FILE_INFO).sync_fence_info",
7333 (Addr)data->sync_fence_info,
7334 (data->num_fences
7335 * sizeof(sizeof(struct vki_sync_fence_info))));
7336 break;
7339 case VKI_SYNC_IOC_SET_DEADLINE: {
7340 struct vki_sync_set_deadline* data =
7341 (struct vki_sync_set_deadline*)(Addr)ARG3;
7342 PRE_FIELD_READ ("ioctl(SYNC_IOC_SET_DEADLINE).deadline_ns",
7343 data->deadline_ns);
7344 break;
7347 case VKI_TCSETS:
7348 case VKI_TCSETSW:
7349 case VKI_TCSETSF:
7350 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7351 break;
7352 case VKI_TCGETS:
7353 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7354 break;
7355 case VKI_TCSETA:
7356 case VKI_TCSETAW:
7357 case VKI_TCSETAF:
7358 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7359 break;
7360 case VKI_TCGETA:
7361 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7362 break;
7363 case VKI_TCSBRK:
7364 case VKI_TCXONC:
7365 case VKI_TCSBRKP:
7366 case VKI_TCFLSH:
7367 case VKI_TIOCSIG:
7368 /* These just take an int by value */
7369 break;
7370 case VKI_TIOCGWINSZ:
7371 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7372 break;
7373 case VKI_TIOCSWINSZ:
7374 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7375 break;
7376 case VKI_TIOCMBIS:
7377 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7378 break;
7379 case VKI_TIOCMBIC:
7380 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7381 break;
7382 case VKI_TIOCMSET:
7383 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7384 break;
7385 case VKI_TIOCMGET:
7386 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7387 break;
7388 case VKI_TIOCLINUX:
7389 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7390 if (*(char *)(Addr)ARG3 == 11) {
7391 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7393 break;
7394 case VKI_TIOCGPGRP:
7395 /* Get process group ID for foreground processing group. */
7396 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7397 break;
7398 case VKI_TIOCSPGRP:
7399 /* Set a process group ID? */
7400 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7401 break;
7402 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7403 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7404 break;
7405 case VKI_TIOCSCTTY:
7406 /* Just takes an int value. */
7407 break;
7408 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7409 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7410 break;
7411 case VKI_FIONBIO:
7412 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7413 break;
7414 case VKI_FIOASYNC:
7415 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7416 break;
7417 case VKI_FIONREAD: /* identical to SIOCINQ */
7418 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7419 break;
7420 case VKI_FIOQSIZE:
7421 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7422 break;
7424 case VKI_TIOCSERGETLSR:
7425 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7426 break;
7427 case VKI_TIOCGICOUNT:
7428 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7429 sizeof(struct vki_serial_icounter_struct) );
7430 break;
7432 case VKI_SG_SET_COMMAND_Q:
7433 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7434 break;
7435 case VKI_SG_IO:
7436 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7438 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7439 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7440 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7441 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7442 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7445 break;
7446 case VKI_SG_GET_SCSI_ID:
7447 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7448 break;
7449 case VKI_SG_SET_RESERVED_SIZE:
7450 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7451 break;
7452 case VKI_SG_SET_TIMEOUT:
7453 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7454 break;
7455 case VKI_SG_GET_RESERVED_SIZE:
7456 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7457 break;
7458 case VKI_SG_GET_TIMEOUT:
7459 break;
7460 case VKI_SG_GET_VERSION_NUM:
7461 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7462 break;
7463 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7464 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7465 break;
7466 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7467 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7468 break;
7470 case VKI_IIOCGETCPS:
7471 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7472 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7473 break;
7474 case VKI_IIOCNETGPN:
7475 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7476 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7477 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7478 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7479 sizeof(vki_isdn_net_ioctl_phone) );
7480 break;
7482 /* These all use struct ifreq AFAIK */
7483 case VKI_SIOCGIFINDEX: /* get iface index */
7484 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7485 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7486 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7487 break;
7488 case VKI_SIOCGIFFLAGS: /* get flags */
7489 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7490 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7491 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7492 break;
7493 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7494 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7495 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7496 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7497 break;
7498 case VKI_SIOCGIFMTU: /* get MTU size */
7499 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7500 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7501 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7502 break;
7503 case VKI_SIOCGIFADDR: /* get PA address */
7504 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7505 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7506 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7507 break;
7508 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7509 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7510 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7511 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7512 break;
7513 case VKI_SIOCGIFMETRIC: /* get metric */
7514 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7515 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7516 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7517 break;
7518 case VKI_SIOCGIFMAP: /* Get device parameters */
7519 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7520 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7521 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7522 break;
7523 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7524 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7525 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7526 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7527 break;
7528 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7529 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7530 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7531 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7532 break;
7533 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7534 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7535 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7536 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7537 break;
7538 case VKI_SIOCGIFNAME: /* get iface name */
7539 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7540 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7541 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7542 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7543 break;
7545 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7546 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7547 // The kernel will have to look at ifr_data to determine which operation
7548 // to perform.
7549 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7550 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7552 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7554 // Is this correct? Is ifr_name *always* looked at?
7555 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7556 (Addr)ir->vki_ifr_name );
7558 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7559 // the whole structure is defined. So in this case, just check it's
7560 // accessible.
7561 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7562 case VKI_ETHTOOL_GSET:
7563 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7564 (Addr)ir, sizeof(struct vki_ifreq) );
7565 break;
7566 default:
7567 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7568 (Addr)ir, sizeof(struct vki_ifreq) );
7569 break;
7572 // Now perform the relevant pre-action for the operation.
7573 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7574 case VKI_ETHTOOL_GSET:
7575 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7576 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7577 break;
7578 case VKI_ETHTOOL_SSET:
7579 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7580 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7581 break;
7582 case VKI_ETHTOOL_GDRVINFO:
7583 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7584 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7585 break;
7586 case VKI_ETHTOOL_GREGS:
7587 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7588 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7589 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7590 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7591 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7592 break;
7593 case VKI_ETHTOOL_GWOL:
7594 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7595 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7596 break;
7597 case VKI_ETHTOOL_SWOL:
7598 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7599 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7600 break;
7601 case VKI_ETHTOOL_GMSGLVL:
7602 case VKI_ETHTOOL_GLINK:
7603 case VKI_ETHTOOL_GRXCSUM:
7604 case VKI_ETHTOOL_GSG:
7605 case VKI_ETHTOOL_GTSO:
7606 case VKI_ETHTOOL_GUFO:
7607 case VKI_ETHTOOL_GGSO:
7608 case VKI_ETHTOOL_GFLAGS:
7609 case VKI_ETHTOOL_GGRO:
7610 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7611 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7612 break;
7613 case VKI_ETHTOOL_SMSGLVL:
7614 case VKI_ETHTOOL_SRXCSUM:
7615 case VKI_ETHTOOL_SSG:
7616 case VKI_ETHTOOL_STSO:
7617 case VKI_ETHTOOL_SUFO:
7618 case VKI_ETHTOOL_SGSO:
7619 case VKI_ETHTOOL_SFLAGS:
7620 case VKI_ETHTOOL_SGRO:
7621 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7622 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7623 break;
7624 case VKI_ETHTOOL_NWAY_RST:
7625 break;
7626 case VKI_ETHTOOL_GRINGPARAM:
7627 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7628 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7629 break;
7630 case VKI_ETHTOOL_SRINGPARAM:
7631 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7632 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7633 break;
7634 case VKI_ETHTOOL_TEST:
7635 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7636 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7637 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7638 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7639 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7640 break;
7641 case VKI_ETHTOOL_PHYS_ID:
7642 break;
7643 case VKI_ETHTOOL_GPERMADDR:
7644 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7645 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7646 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7647 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7648 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7649 break;
7650 case VKI_ETHTOOL_RESET:
7651 break;
7652 case VKI_ETHTOOL_GSSET_INFO:
7653 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7654 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7655 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7656 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7657 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7658 break;
7659 case VKI_ETHTOOL_GFEATURES:
7660 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7661 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7662 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7663 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7664 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7665 break;
7666 case VKI_ETHTOOL_SFEATURES:
7667 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7668 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7669 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7670 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7671 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7672 break;
7673 case VKI_ETHTOOL_GCHANNELS:
7674 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7675 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7676 break;
7677 case VKI_ETHTOOL_SCHANNELS:
7678 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7679 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7680 break;
7681 case VKI_ETHTOOL_GET_TS_INFO:
7682 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7683 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7684 break;
7686 break;
7687 } /* case VKI_SIOCETHTOOL */
7689 case VKI_SIOCGMIIPHY: /* get hardware entry */
7690 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7691 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7692 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7693 break;
7694 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7695 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7696 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7697 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7698 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7699 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7700 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7701 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7702 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7703 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7704 sizeof(struct vki_ifreq));
7705 break;
7706 case VKI_SIOCGIFCONF: /* get iface list */
7707 /* WAS:
7708 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7709 KERNEL_DO_SYSCALL(tid,RES);
7710 if (!VG_(is_kerror)(RES) && RES == 0)
7711 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7713 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7714 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7715 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7716 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7717 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7718 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7719 if ( ARG3 ) {
7720 // TODO len must be readable and writable
7721 // buf pointer only needs to be readable
7722 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7723 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7724 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7726 break;
7727 case VKI_SIOCGSTAMP:
7728 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7729 break;
7730 case VKI_SIOCGSTAMPNS:
7731 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7732 break;
7733 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7734 the number of bytes currently in that socket's send buffer.
7735 It writes this value as an int to the memory location
7736 indicated by the third argument of ioctl(2). */
7737 case VKI_SIOCOUTQ:
7738 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7739 break;
7740 case VKI_SIOCGRARP: /* get RARP table entry */
7741 case VKI_SIOCGARP: /* get ARP table entry */
7742 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7743 break;
7745 case VKI_SIOCSIFFLAGS: /* set flags */
7746 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7747 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7748 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7749 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7750 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7751 break;
7752 case VKI_SIOCSIFMAP: /* Set device parameters */
7753 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7754 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7755 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7756 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7757 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7758 break;
7759 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7760 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7761 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7762 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7763 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7764 sizeof(struct vki_hwtstamp_config) );
7765 break;
7766 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7767 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7768 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7769 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7770 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7771 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7772 break;
7773 case VKI_SIOCSIFADDR: /* set PA address */
7774 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7775 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7776 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7777 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7778 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7779 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7780 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7781 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7782 break;
7783 case VKI_SIOCSIFMETRIC: /* set metric */
7784 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7785 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7786 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7787 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7788 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7789 break;
7790 case VKI_SIOCSIFMTU: /* set MTU size */
7791 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7792 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7793 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7794 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7795 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7796 break;
7797 case VKI_SIOCSIFHWADDR: /* set hardware address */
7798 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7799 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7800 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7801 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7802 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7803 break;
7804 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7805 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7806 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7807 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7808 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7809 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7810 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7811 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7812 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7813 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7814 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7815 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7816 break;
7817 /* Routing table calls. */
7818 case VKI_SIOCADDRT: /* add routing table entry */
7819 case VKI_SIOCDELRT: /* delete routing table entry */
7820 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7821 sizeof(struct vki_rtentry));
7822 break;
7824 /* tun/tap related ioctls */
7825 case VKI_TUNSETNOCSUM:
7826 case VKI_TUNSETDEBUG:
7827 break;
7828 case VKI_TUNSETIFF:
7829 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7830 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7831 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7832 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7833 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7834 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7835 break;
7836 case VKI_TUNSETPERSIST:
7837 case VKI_TUNSETOWNER:
7838 case VKI_TUNSETLINK:
7839 case VKI_TUNSETGROUP:
7840 break;
7841 case VKI_TUNGETFEATURES:
7842 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7843 break;
7844 case VKI_TUNSETOFFLOAD:
7845 break;
7846 case VKI_TUNGETIFF:
7847 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7848 break;
7849 case VKI_TUNGETSNDBUF:
7850 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7851 break;
7852 case VKI_TUNSETSNDBUF:
7853 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7854 break;
7855 case VKI_TUNGETVNETHDRSZ:
7856 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7857 break;
7858 case VKI_TUNSETVNETHDRSZ:
7859 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7860 break;
7861 case VKI_TUNSETQUEUE:
7862 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7863 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7864 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7865 break;
7866 case VKI_TUNSETIFINDEX:
7867 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7868 break;
7870 /* RARP cache control calls. */
7871 case VKI_SIOCDRARP: /* delete RARP table entry */
7872 case VKI_SIOCSRARP: /* set RARP table entry */
7873 /* ARP cache control calls. */
7874 case VKI_SIOCSARP: /* set ARP table entry */
7875 case VKI_SIOCDARP: /* delete ARP table entry */
7876 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7877 break;
7879 case VKI_SIOCGPGRP:
7880 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7881 break;
7882 case VKI_SIOCSPGRP:
7883 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7884 //tst->sys_flags &= ~SfMayBlock;
7885 break;
7887 case VKI_SIOCATMARK:
7888 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7889 break;
7891 /* linux/soundcard interface (OSS) */
7892 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7893 case VKI_SNDCTL_SEQ_GETINCOUNT:
7894 case VKI_SNDCTL_SEQ_PERCMODE:
7895 case VKI_SNDCTL_SEQ_TESTMIDI:
7896 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7897 case VKI_SNDCTL_SEQ_NRSYNTHS:
7898 case VKI_SNDCTL_SEQ_NRMIDIS:
7899 case VKI_SNDCTL_SEQ_GETTIME:
7900 case VKI_SNDCTL_DSP_GETBLKSIZE:
7901 case VKI_SNDCTL_DSP_GETFMTS:
7902 case VKI_SNDCTL_DSP_GETTRIGGER:
7903 case VKI_SNDCTL_DSP_GETODELAY:
7904 case VKI_SNDCTL_DSP_GETSPDIF:
7905 case VKI_SNDCTL_DSP_GETCAPS:
7906 case VKI_SOUND_PCM_READ_RATE:
7907 case VKI_SOUND_PCM_READ_CHANNELS:
7908 case VKI_SOUND_PCM_READ_BITS:
7909 case VKI_SOUND_PCM_READ_FILTER:
7910 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7911 ARG3, sizeof(int));
7912 break;
7913 case VKI_SNDCTL_SEQ_CTRLRATE:
7914 case VKI_SNDCTL_DSP_SPEED:
7915 case VKI_SNDCTL_DSP_STEREO:
7916 case VKI_SNDCTL_DSP_CHANNELS:
7917 case VKI_SOUND_PCM_WRITE_FILTER:
7918 case VKI_SNDCTL_DSP_SUBDIVIDE:
7919 case VKI_SNDCTL_DSP_SETFRAGMENT:
7920 case VKI_SNDCTL_DSP_SETFMT:
7921 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7922 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7923 case VKI_SNDCTL_TMR_TIMEBASE:
7924 case VKI_SNDCTL_TMR_TEMPO:
7925 case VKI_SNDCTL_TMR_SOURCE:
7926 case VKI_SNDCTL_MIDI_PRETIME:
7927 case VKI_SNDCTL_MIDI_MPUMODE:
7928 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7929 ARG3, sizeof(int));
7930 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7931 ARG3, sizeof(int));
7932 break;
7933 case VKI_SNDCTL_DSP_GETOSPACE:
7934 case VKI_SNDCTL_DSP_GETISPACE:
7935 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7936 ARG3, sizeof(vki_audio_buf_info));
7937 break;
7938 case VKI_SNDCTL_DSP_NONBLOCK:
7939 break;
7940 case VKI_SNDCTL_DSP_SETTRIGGER:
7941 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7942 ARG3, sizeof(int));
7943 break;
7945 case VKI_SNDCTL_DSP_POST:
7946 case VKI_SNDCTL_DSP_RESET:
7947 case VKI_SNDCTL_DSP_SYNC:
7948 case VKI_SNDCTL_DSP_SETSYNCRO:
7949 case VKI_SNDCTL_DSP_SETDUPLEX:
7950 break;
7952 /* linux/soundcard interface (ALSA) */
7953 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7954 case VKI_SNDRV_PCM_IOCTL_LINK:
7955 /* these just take an int by value */
7956 break;
7957 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7958 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7959 break;
7960 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7961 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7962 break;
7963 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7964 struct vki_snd_ctl_elem_list *data =
7965 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7966 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7967 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7968 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7969 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7970 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7971 if (data->pids) {
7972 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7974 break;
7976 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7977 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7978 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7979 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7980 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7981 break;
7983 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7984 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7985 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7986 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7987 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7988 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7989 break;
7992 /* Real Time Clock (/dev/rtc) ioctls */
7993 case VKI_RTC_UIE_ON:
7994 case VKI_RTC_UIE_OFF:
7995 case VKI_RTC_AIE_ON:
7996 case VKI_RTC_AIE_OFF:
7997 case VKI_RTC_PIE_ON:
7998 case VKI_RTC_PIE_OFF:
7999 case VKI_RTC_IRQP_SET:
8000 break;
8001 case VKI_RTC_RD_TIME:
8002 case VKI_RTC_ALM_READ:
8003 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
8004 ARG3, sizeof(struct vki_rtc_time));
8005 break;
8006 case VKI_RTC_ALM_SET:
8007 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
8008 break;
8009 case VKI_RTC_IRQP_READ:
8010 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
8011 break;
8013 /* Loopback control */
8014 case VKI_LOOP_CTL_ADD:
8015 case VKI_LOOP_CTL_REMOVE:
8016 case VKI_LOOP_CTL_GET_FREE:
8017 break;
8018 /* Loopback device */
8019 case VKI_LOOP_SET_FD:
8020 case VKI_LOOP_CLR_FD:
8021 case VKI_LOOP_CHANGE_FD:
8022 case VKI_LOOP_SET_CAPACITY:
8023 case VKI_LOOP_SET_DIRECT_IO:
8024 case VKI_LOOP_SET_BLOCK_SIZE:
8025 break;
8026 case VKI_LOOP_SET_STATUS:
8027 PRE_MEM_READ("ioctl(LOOP_SET_STATUS)", ARG3, sizeof(struct vki_loop_info));
8028 break;
8029 case VKI_LOOP_GET_STATUS:
8030 PRE_MEM_WRITE("ioctl(LOOP_GET_STATUS)", ARG3, sizeof(struct vki_loop_info));
8031 break;
8032 case VKI_LOOP_SET_STATUS64:
8033 PRE_MEM_READ("ioctl(LOOP_SET_STATUS64)", ARG3, sizeof(struct vki_loop_info64));
8034 break;
8035 case VKI_LOOP_GET_STATUS64:
8036 PRE_MEM_WRITE("ioctl(LOOP_GET_STATUS64)", ARG3, sizeof(struct vki_loop_info64));
8037 break;
8039 /* Block devices */
8040 case VKI_BLKROSET:
8041 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
8042 break;
8043 case VKI_BLKROGET:
8044 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
8045 break;
8046 case VKI_BLKGETSIZE:
8047 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
8048 break;
8049 case VKI_BLKFLSBUF:
8050 break;
8051 case VKI_BLKRASET:
8052 break;
8053 case VKI_BLKRAGET:
8054 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
8055 break;
8056 case VKI_BLKFRASET:
8057 break;
8058 case VKI_BLKFRAGET:
8059 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
8060 break;
8061 case VKI_BLKSECTGET:
8062 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
8063 break;
8064 case VKI_BLKSSZGET:
8065 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
8066 break;
8067 case VKI_BLKBSZGET:
8068 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
8069 break;
8070 case VKI_BLKBSZSET:
8071 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
8072 break;
8073 case VKI_BLKGETSIZE64:
8074 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
8075 break;
8076 case VKI_BLKPBSZGET:
8077 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
8078 break;
8079 case VKI_BLKIOMIN:
8080 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
8081 break;
8082 case VKI_BLKIOOPT:
8083 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
8084 break;
8085 case VKI_BLKALIGNOFF:
8086 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
8087 break;
8088 case VKI_BLKDISCARDZEROES:
8089 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
8090 break;
8091 case VKI_BLKREPORTZONE:
8092 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
8093 sizeof(struct vki_blk_zone_report));
8094 break;
8095 case VKI_BLKRESETZONE:
8096 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
8097 sizeof(struct vki_blk_zone_range));
8098 break;
8100 /* Hard disks */
8101 case VKI_HDIO_GETGEO: /* 0x0301 */
8102 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
8103 break;
8104 case VKI_HDIO_GET_DMA: /* 0x030b */
8105 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
8106 break;
8107 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
8108 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
8109 VKI_SIZEOF_STRUCT_HD_DRIVEID );
8110 break;
8112 /* SCSI */
8113 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
8114 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
8115 break;
8116 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
8117 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
8118 break;
8120 /* CD ROM stuff (??) */
8121 case VKI_CDROM_GET_MCN:
8122 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
8123 sizeof(struct vki_cdrom_mcn) );
8124 break;
8125 case VKI_CDROM_SEND_PACKET:
8126 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
8127 sizeof(struct vki_cdrom_generic_command));
8128 break;
8129 case VKI_CDROMSUBCHNL:
8130 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
8131 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
8132 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
8133 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
8134 sizeof(struct vki_cdrom_subchnl));
8135 break;
8136 case VKI_CDROMREADMODE1: /*0x530d*/
8137 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
8138 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
8139 break;
8140 case VKI_CDROMREADMODE2: /*0x530c*/
8141 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
8142 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
8143 break;
8144 case VKI_CDROMREADTOCHDR:
8145 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
8146 sizeof(struct vki_cdrom_tochdr));
8147 break;
8148 case VKI_CDROMREADTOCENTRY:
8149 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
8150 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
8151 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
8152 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
8153 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
8154 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
8155 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
8156 sizeof(struct vki_cdrom_tocentry));
8157 break;
8158 case VKI_CDROMMULTISESSION: /* 0x5310 */
8159 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
8160 sizeof(struct vki_cdrom_multisession));
8161 break;
8162 case VKI_CDROMVOLREAD: /* 0x5313 */
8163 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
8164 sizeof(struct vki_cdrom_volctrl));
8165 break;
8166 case VKI_CDROMREADRAW: /* 0x5314 */
8167 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
8168 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
8169 break;
8170 case VKI_CDROMREADAUDIO: /* 0x530e */
8171 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
8172 sizeof (struct vki_cdrom_read_audio));
8173 if ( ARG3 ) {
8174 /* ToDo: don't do any of the following if the structure is invalid */
8175 struct vki_cdrom_read_audio *cra =
8176 (struct vki_cdrom_read_audio *) (Addr)ARG3;
8177 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
8178 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
8180 break;
8181 case VKI_CDROMPLAYMSF:
8182 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
8183 break;
8184 /* The following two are probably bogus (should check args
8185 for readability). JRS 20021117 */
8186 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
8187 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
8188 break;
8189 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
8190 break;
8192 case VKI_FIGETBSZ:
8193 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
8194 break;
8195 case VKI_FIBMAP:
8196 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
8197 break;
8198 case VKI_FICLONE:
8199 /* The direction of FICLONE (W) is incorrectly specified
8200 * as it expects a file descriptor and not a pointer to
8201 * user data */
8202 break;
8204 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
8205 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
8206 sizeof(struct vki_fb_var_screeninfo));
8207 break;
8208 case VKI_FBIOPUT_VSCREENINFO:
8209 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
8210 sizeof(struct vki_fb_var_screeninfo));
8211 break;
8212 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
8213 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
8214 sizeof(struct vki_fb_fix_screeninfo));
8215 break;
8216 case VKI_FBIOPAN_DISPLAY:
8217 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
8218 sizeof(struct vki_fb_var_screeninfo));
8220 break;
8221 case VKI_PPCLAIM:
8222 case VKI_PPEXCL:
8223 case VKI_PPYIELD:
8224 case VKI_PPRELEASE:
8225 break;
8226 case VKI_PPSETMODE:
8227 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
8228 break;
8229 case VKI_PPGETMODE:
8230 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
8231 break;
8232 case VKI_PPSETPHASE:
8233 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
8234 break;
8235 case VKI_PPGETPHASE:
8236 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
8237 break;
8238 case VKI_PPGETMODES:
8239 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
8240 break;
8241 case VKI_PPSETFLAGS:
8242 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
8243 break;
8244 case VKI_PPGETFLAGS:
8245 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
8246 break;
8247 case VKI_PPRSTATUS:
8248 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
8249 break;
8250 case VKI_PPRDATA:
8251 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
8252 break;
8253 case VKI_PPRCONTROL:
8254 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
8255 break;
8256 case VKI_PPWDATA:
8257 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
8258 break;
8259 case VKI_PPWCONTROL:
8260 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
8261 break;
8262 case VKI_PPFCONTROL:
8263 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
8264 break;
8265 case VKI_PPDATADIR:
8266 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
8267 break;
8268 case VKI_PPNEGOT:
8269 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
8270 break;
8271 case VKI_PPWCTLONIRQ:
8272 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
8273 break;
8274 case VKI_PPCLRIRQ:
8275 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
8276 break;
8277 case VKI_PPSETTIME:
8278 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
8279 break;
8280 case VKI_PPGETTIME:
8281 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
8282 break;
8284 case VKI_GIO_FONT:
8285 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
8286 break;
8287 case VKI_PIO_FONT:
8288 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
8289 break;
8291 case VKI_GIO_FONTX:
8292 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8293 if ( ARG3 ) {
8294 /* ToDo: don't do any of the following if the structure is invalid */
8295 struct vki_consolefontdesc *cfd =
8296 (struct vki_consolefontdesc *)(Addr)ARG3;
8297 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
8298 32 * cfd->charcount );
8300 break;
8301 case VKI_PIO_FONTX:
8302 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8303 if ( ARG3 ) {
8304 /* ToDo: don't do any of the following if the structure is invalid */
8305 struct vki_consolefontdesc *cfd =
8306 (struct vki_consolefontdesc *)(Addr)ARG3;
8307 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
8308 32 * cfd->charcount );
8310 break;
8312 case VKI_PIO_FONTRESET:
8313 break;
8315 case VKI_GIO_CMAP:
8316 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8317 break;
8318 case VKI_PIO_CMAP:
8319 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8320 break;
8322 case VKI_KIOCSOUND:
8323 case VKI_KDMKTONE:
8324 break;
8326 case VKI_KDGETLED:
8327 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8328 break;
8329 case VKI_KDSETLED:
8330 break;
8332 case VKI_KDGKBTYPE:
8333 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8334 break;
8336 case VKI_KDADDIO:
8337 case VKI_KDDELIO:
8338 case VKI_KDENABIO:
8339 case VKI_KDDISABIO:
8340 break;
8342 case VKI_KDSETMODE:
8343 break;
8344 case VKI_KDGETMODE:
8345 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8346 break;
8348 case VKI_KDMAPDISP:
8349 case VKI_KDUNMAPDISP:
8350 break;
8352 case VKI_GIO_SCRNMAP:
8353 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8354 break;
8355 case VKI_PIO_SCRNMAP:
8356 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8357 break;
8358 case VKI_GIO_UNISCRNMAP:
8359 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8360 VKI_E_TABSZ * sizeof(unsigned short) );
8361 break;
8362 case VKI_PIO_UNISCRNMAP:
8363 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8364 VKI_E_TABSZ * sizeof(unsigned short) );
8365 break;
8367 case VKI_GIO_UNIMAP:
8368 if ( ARG3 ) {
8369 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8370 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8371 sizeof(unsigned short));
8372 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8373 sizeof(struct vki_unipair *));
8374 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8375 desc->entry_ct * sizeof(struct vki_unipair));
8377 break;
8378 case VKI_PIO_UNIMAP:
8379 if ( ARG3 ) {
8380 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8381 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8382 sizeof(unsigned short) );
8383 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8384 sizeof(struct vki_unipair *) );
8385 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8386 desc->entry_ct * sizeof(struct vki_unipair) );
8388 break;
8389 case VKI_PIO_UNIMAPCLR:
8390 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8391 break;
8393 case VKI_KDGKBMODE:
8394 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8395 break;
8396 case VKI_KDSKBMODE:
8397 break;
8399 case VKI_KDGKBMETA:
8400 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8401 break;
8402 case VKI_KDSKBMETA:
8403 break;
8405 case VKI_KDGKBLED:
8406 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8407 break;
8408 case VKI_KDSKBLED:
8409 break;
8411 case VKI_KDGKBENT:
8412 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8413 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8414 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8415 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8416 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8417 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8418 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8419 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8420 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8421 break;
8422 case VKI_KDSKBENT:
8423 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
8424 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8425 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8426 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
8427 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8428 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8429 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8430 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8431 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8432 break;
8434 case VKI_KDGKBSENT:
8435 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8436 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8437 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8438 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8439 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8440 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8441 break;
8442 case VKI_KDSKBSENT:
8443 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8444 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8445 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8446 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8447 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8448 break;
8450 case VKI_KDGKBDIACR:
8451 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8452 break;
8453 case VKI_KDSKBDIACR:
8454 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8455 break;
8457 case VKI_KDGETKEYCODE:
8458 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8459 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8460 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8461 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8462 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8463 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8464 break;
8465 case VKI_KDSETKEYCODE:
8466 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8467 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8468 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8469 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8470 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8471 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8472 break;
8474 case VKI_KDSIGACCEPT:
8475 break;
8477 case VKI_KDKBDREP:
8478 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8479 break;
8481 case VKI_KDFONTOP:
8482 if ( ARG3 ) {
8483 struct vki_console_font_op *op =
8484 (struct vki_console_font_op *) (Addr)ARG3;
8485 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8486 sizeof(struct vki_console_font_op) );
8487 switch ( op->op ) {
8488 case VKI_KD_FONT_OP_SET:
8489 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8490 (Addr)op->data,
8491 (op->width + 7) / 8 * 32 * op->charcount );
8492 break;
8493 case VKI_KD_FONT_OP_GET:
8494 if ( op->data )
8495 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8496 (Addr)op->data,
8497 (op->width + 7) / 8 * 32 * op->charcount );
8498 break;
8499 case VKI_KD_FONT_OP_SET_DEFAULT:
8500 if ( op->data )
8501 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8502 (Addr)op->data );
8503 break;
8504 case VKI_KD_FONT_OP_COPY:
8505 break;
8508 break;
8510 case VKI_VT_OPENQRY:
8511 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8512 break;
8513 case VKI_VT_GETMODE:
8514 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8515 break;
8516 case VKI_VT_SETMODE:
8517 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8518 break;
8519 case VKI_VT_GETSTATE:
8520 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8521 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8522 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8523 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8524 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8525 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8526 break;
8527 case VKI_VT_RELDISP:
8528 case VKI_VT_ACTIVATE:
8529 case VKI_VT_WAITACTIVE:
8530 case VKI_VT_DISALLOCATE:
8531 break;
8532 case VKI_VT_RESIZE:
8533 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8534 break;
8535 case VKI_VT_RESIZEX:
8536 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8537 break;
8538 case VKI_VT_LOCKSWITCH:
8539 case VKI_VT_UNLOCKSWITCH:
8540 break;
8542 case VKI_USBDEVFS_CONTROL:
8543 if ( ARG3 ) {
8544 struct vki_usbdevfs_ctrltransfer *vkuc =
8545 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8546 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8547 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8548 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8549 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8550 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8551 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8552 if (vkuc->bRequestType & 0x80)
8553 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8554 else
8555 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8557 break;
8558 case VKI_USBDEVFS_BULK:
8559 if ( ARG3 ) {
8560 struct vki_usbdevfs_bulktransfer *vkub =
8561 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8562 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8563 if (vkub->ep & 0x80)
8564 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8565 else
8566 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8568 break;
8569 case VKI_USBDEVFS_GETDRIVER:
8570 if ( ARG3 ) {
8571 struct vki_usbdevfs_getdriver *vkugd =
8572 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8573 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8575 break;
8576 case VKI_USBDEVFS_SUBMITURB:
8577 if ( ARG3 ) {
8578 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8580 /* Not the whole struct needs to be initialized */
8581 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8582 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8583 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8584 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8585 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8586 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8587 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8588 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8589 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8590 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8591 if (vkusp->bRequestType & 0x80)
8592 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8593 else
8594 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8595 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8596 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8597 int total_length = 0;
8598 int i;
8599 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8600 for(i=0; i<vkuu->number_of_packets; i++) {
8601 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8602 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].actual_length", (Addr)&vkuu->iso_frame_desc[i].actual_length, sizeof(vkuu->iso_frame_desc[i].actual_length));
8603 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8604 total_length += vkuu->iso_frame_desc[i].length;
8606 if (vkuu->endpoint & 0x80)
8607 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8608 else
8609 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8610 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8611 } else {
8612 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8613 if (vkuu->endpoint & 0x80)
8614 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8615 else
8616 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8617 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8620 break;
8621 case VKI_USBDEVFS_DISCARDURB:
8622 break;
8623 case VKI_USBDEVFS_REAPURB:
8624 if ( ARG3 ) {
8625 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8627 break;
8628 case VKI_USBDEVFS_REAPURBNDELAY:
8629 if ( ARG3 ) {
8630 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8632 break;
8633 case VKI_USBDEVFS_CONNECTINFO:
8634 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8635 break;
8636 case VKI_USBDEVFS_IOCTL:
8637 if ( ARG3 ) {
8638 struct vki_usbdevfs_ioctl *vkui =
8639 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8640 UInt dir2, size2;
8641 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8642 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8643 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8644 if (size2 > 0) {
8645 if (dir2 & _VKI_IOC_WRITE)
8646 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8647 else if (dir2 & _VKI_IOC_READ)
8648 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8651 break;
8652 case VKI_USBDEVFS_RESET:
8653 break;
8655 /* I2C (/dev/i2c-*) ioctls */
8656 case VKI_I2C_SLAVE:
8657 case VKI_I2C_SLAVE_FORCE:
8658 case VKI_I2C_TENBIT:
8659 case VKI_I2C_PEC:
8660 break;
8661 case VKI_I2C_FUNCS:
8662 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8663 break;
8664 case VKI_I2C_RDWR:
8665 if ( ARG3 ) {
8666 struct vki_i2c_rdwr_ioctl_data *vkui =
8667 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8668 UInt i;
8669 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8670 for (i=0; i < vkui->nmsgs; i++) {
8671 struct vki_i2c_msg *msg = vkui->msgs + i;
8672 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8673 if (msg->flags & VKI_I2C_M_RD)
8674 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8675 else
8676 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8679 break;
8680 case VKI_I2C_SMBUS:
8681 if ( ARG3 ) {
8682 struct vki_i2c_smbus_ioctl_data *vkis
8683 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8684 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8685 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8686 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8687 (Addr)&vkis->size, sizeof(vkis->size));
8688 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8689 (Addr)&vkis->command, sizeof(vkis->command));
8690 /* i2c_smbus_write_quick hides its value in read_write, so
8691 this variable can have a different meaning */
8692 /* to make matters worse i2c_smbus_write_byte stores its
8693 value in command */
8694 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8695 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8696 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8697 /* the rest uses the byte array to store the data,
8698 some the first byte for size */
8699 UInt size;
8700 switch(vkis->size) {
8701 case VKI_I2C_SMBUS_BYTE_DATA:
8702 size = 1;
8703 break;
8704 case VKI_I2C_SMBUS_WORD_DATA:
8705 case VKI_I2C_SMBUS_PROC_CALL:
8706 size = 2;
8707 break;
8708 case VKI_I2C_SMBUS_BLOCK_DATA:
8709 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8710 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8711 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8712 size = 1 + vkis->data->block[0];
8713 break;
8714 default:
8715 size = 0;
8718 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8719 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8720 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8721 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8722 ".i2c_smbus_ioctl_data.data",
8723 (Addr)&vkis->data->block[0], size);
8724 else
8725 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8726 "i2c_smbus_ioctl_data.data",
8727 (Addr)&vkis->data->block[0], size);
8730 break;
8732 /* Wireless extensions ioctls */
8733 case VKI_SIOCSIWCOMMIT:
8734 case VKI_SIOCSIWNWID:
8735 case VKI_SIOCSIWFREQ:
8736 case VKI_SIOCSIWMODE:
8737 case VKI_SIOCSIWSENS:
8738 case VKI_SIOCSIWRANGE:
8739 case VKI_SIOCSIWPRIV:
8740 case VKI_SIOCSIWSTATS:
8741 case VKI_SIOCSIWSPY:
8742 case VKI_SIOCSIWTHRSPY:
8743 case VKI_SIOCSIWAP:
8744 case VKI_SIOCSIWSCAN:
8745 case VKI_SIOCSIWESSID:
8746 case VKI_SIOCSIWRATE:
8747 case VKI_SIOCSIWNICKN:
8748 case VKI_SIOCSIWRTS:
8749 case VKI_SIOCSIWFRAG:
8750 case VKI_SIOCSIWTXPOW:
8751 case VKI_SIOCSIWRETRY:
8752 case VKI_SIOCSIWENCODE:
8753 case VKI_SIOCSIWPOWER:
8754 case VKI_SIOCSIWGENIE:
8755 case VKI_SIOCSIWMLME:
8756 case VKI_SIOCSIWAUTH:
8757 case VKI_SIOCSIWENCODEEXT:
8758 case VKI_SIOCSIWPMKSA:
8759 break;
8760 case VKI_SIOCGIWNAME:
8761 if (ARG3) {
8762 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8763 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8764 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8766 break;
8767 case VKI_SIOCGIWNWID:
8768 case VKI_SIOCGIWSENS:
8769 case VKI_SIOCGIWRATE:
8770 case VKI_SIOCGIWRTS:
8771 case VKI_SIOCGIWFRAG:
8772 case VKI_SIOCGIWTXPOW:
8773 case VKI_SIOCGIWRETRY:
8774 case VKI_SIOCGIWPOWER:
8775 case VKI_SIOCGIWAUTH:
8776 if (ARG3) {
8777 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8778 "RETRY|PARAM|AUTH])",
8779 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8780 sizeof(struct vki_iw_param));
8782 break;
8783 case VKI_SIOCGIWFREQ:
8784 if (ARG3) {
8785 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8786 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8787 sizeof(struct vki_iw_freq));
8789 break;
8790 case VKI_SIOCGIWMODE:
8791 if (ARG3) {
8792 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8793 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8794 sizeof(__vki_u32));
8796 break;
8797 case VKI_SIOCGIWRANGE:
8798 case VKI_SIOCGIWPRIV:
8799 case VKI_SIOCGIWSTATS:
8800 case VKI_SIOCGIWSPY:
8801 case VKI_SIOCGIWTHRSPY:
8802 case VKI_SIOCGIWAPLIST:
8803 case VKI_SIOCGIWSCAN:
8804 case VKI_SIOCGIWESSID:
8805 case VKI_SIOCGIWNICKN:
8806 case VKI_SIOCGIWENCODE:
8807 case VKI_SIOCGIWGENIE:
8808 case VKI_SIOCGIWENCODEEXT:
8809 if (ARG3) {
8810 struct vki_iw_point* point;
8811 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8812 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8813 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8814 (Addr)point->pointer, point->length);
8816 break;
8817 case VKI_SIOCGIWAP:
8818 if (ARG3) {
8819 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8820 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8821 sizeof(struct vki_sockaddr));
8823 break;
8825 /* User input device creation */
8826 case VKI_UI_SET_EVBIT:
8827 case VKI_UI_SET_KEYBIT:
8828 case VKI_UI_SET_RELBIT:
8829 case VKI_UI_SET_ABSBIT:
8830 case VKI_UI_SET_MSCBIT:
8831 case VKI_UI_SET_LEDBIT:
8832 case VKI_UI_SET_SNDBIT:
8833 case VKI_UI_SET_FFBIT:
8834 case VKI_UI_SET_SWBIT:
8835 case VKI_UI_SET_PROPBIT:
8836 /* These just take an int by value */
8837 break;
8839 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8840 || defined(VGPV_mips32_linux_android) \
8841 || defined(VGPV_arm64_linux_android)
8842 /* ashmem */
8843 case VKI_ASHMEM_GET_SIZE:
8844 case VKI_ASHMEM_SET_SIZE:
8845 case VKI_ASHMEM_GET_PROT_MASK:
8846 case VKI_ASHMEM_SET_PROT_MASK:
8847 case VKI_ASHMEM_GET_PIN_STATUS:
8848 case VKI_ASHMEM_PURGE_ALL_CACHES:
8849 break;
8850 case VKI_ASHMEM_GET_NAME:
8851 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8852 break;
8853 case VKI_ASHMEM_SET_NAME:
8854 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8855 break;
8856 case VKI_ASHMEM_PIN:
8857 case VKI_ASHMEM_UNPIN:
8858 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8859 ARG3, sizeof(struct vki_ashmem_pin) );
8860 break;
8862 /* binder */
8863 case VKI_BINDER_WRITE_READ:
8864 if (ARG3) {
8865 struct vki_binder_write_read* bwr
8866 = (struct vki_binder_write_read*)(Addr)ARG3;
8868 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8869 bwr->write_buffer);
8870 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8871 bwr->write_size);
8872 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8873 bwr->write_consumed);
8874 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8875 bwr->read_buffer);
8876 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8877 bwr->read_size);
8878 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8879 bwr->read_consumed);
8881 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8882 bwr->write_consumed);
8883 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8884 bwr->read_consumed);
8886 if (bwr->read_size)
8887 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8888 (Addr)bwr->read_buffer, bwr->read_size);
8889 if (bwr->write_size)
8890 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8891 (Addr)bwr->write_buffer, bwr->write_size);
8893 break;
8895 case VKI_BINDER_SET_IDLE_TIMEOUT:
8896 case VKI_BINDER_SET_MAX_THREADS:
8897 case VKI_BINDER_SET_IDLE_PRIORITY:
8898 case VKI_BINDER_SET_CONTEXT_MGR:
8899 case VKI_BINDER_THREAD_EXIT:
8900 break;
8901 case VKI_BINDER_VERSION:
8902 if (ARG3) {
8903 struct vki_binder_version* bv =
8904 (struct vki_binder_version*)(Addr)ARG3;
8905 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8907 break;
8908 # endif /* defined(VGPV_*_linux_android) */
8910 case VKI_HCIGETDEVLIST:
8911 if (ARG3) {
8912 struct vki_hci_dev_list_req* dlr =
8913 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8914 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8915 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8916 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8917 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8918 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8920 break;
8922 case VKI_HCIINQUIRY:
8923 if (ARG3) {
8924 struct vki_hci_inquiry_req* ir =
8925 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8926 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8927 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8928 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8929 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8930 ir->num_rsp * sizeof(struct vki_inquiry_info));
8932 break;
8934 case VKI_DRM_IOCTL_VERSION:
8935 if (ARG3) {
8936 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8937 struct vg_drm_version_info* info;
8938 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8939 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8940 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8941 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8942 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8943 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8944 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8945 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8946 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8947 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8948 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8949 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8950 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8951 // To ensure we VG_(free) info even when syscall fails:
8952 *flags |= SfPostOnFail;
8953 info->data = *data;
8954 info->orig = data;
8955 ARG3 = (Addr)&info->data;
8957 break;
8958 case VKI_DRM_IOCTL_GET_UNIQUE:
8959 if (ARG3) {
8960 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8961 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8962 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8963 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8965 break;
8966 case VKI_DRM_IOCTL_GET_MAGIC:
8967 if (ARG3) {
8968 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8969 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8971 break;
8972 case VKI_DRM_IOCTL_WAIT_VBLANK:
8973 if (ARG3) {
8974 union vki_drm_wait_vblank *data =
8975 (union vki_drm_wait_vblank *)(Addr)ARG3;
8976 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8977 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8978 /* XXX: It seems request.signal isn't used */
8979 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8981 break;
8982 case VKI_DRM_IOCTL_GEM_CLOSE:
8983 if (ARG3) {
8984 struct vki_drm_gem_close *data =
8985 (struct vki_drm_gem_close *)(Addr)ARG3;
8986 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8988 break;
8989 case VKI_DRM_IOCTL_GEM_FLINK:
8990 if (ARG3) {
8991 struct vki_drm_gem_flink *data =
8992 (struct vki_drm_gem_flink *)(Addr)ARG3;
8993 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8994 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8996 break;
8997 case VKI_DRM_IOCTL_GEM_OPEN:
8998 if (ARG3) {
8999 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
9000 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
9001 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
9002 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
9004 break;
9005 case VKI_DRM_IOCTL_I915_GETPARAM:
9006 if (ARG3) {
9007 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
9008 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
9009 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
9011 break;
9012 case VKI_DRM_IOCTL_I915_GEM_BUSY:
9013 if (ARG3) {
9014 struct vki_drm_i915_gem_busy *data =
9015 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
9016 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
9017 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
9019 break;
9020 case VKI_DRM_IOCTL_I915_GEM_CREATE:
9021 if (ARG3) {
9022 struct vki_drm_i915_gem_create *data =
9023 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
9024 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
9025 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
9027 break;
9028 case VKI_DRM_IOCTL_I915_GEM_PREAD:
9029 if (ARG3) {
9030 struct vki_drm_i915_gem_pread *data =
9031 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
9032 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
9033 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
9034 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
9035 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
9036 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
9038 break;
9039 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
9040 if (ARG3) {
9041 struct vki_drm_i915_gem_pwrite *data =
9042 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
9043 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
9044 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
9045 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
9046 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
9047 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
9048 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
9049 * interleaved vertex attributes may have a wide stride with uninitialized data between
9050 * consecutive vertices) */
9052 break;
9053 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
9054 if (ARG3) {
9055 struct vki_drm_i915_gem_mmap_v1 *data =
9056 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
9057 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
9058 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
9059 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
9060 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
9062 break;
9063 case VKI_DRM_IOCTL_I915_GEM_MMAP:
9064 if (ARG3) {
9065 struct vki_drm_i915_gem_mmap *data =
9066 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
9067 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
9068 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
9069 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
9070 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
9071 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
9073 break;
9074 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
9075 if (ARG3) {
9076 struct vki_drm_i915_gem_mmap_gtt *data =
9077 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
9078 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
9079 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
9081 break;
9082 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
9083 if (ARG3) {
9084 struct vki_drm_i915_gem_set_domain *data =
9085 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
9086 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
9087 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
9088 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
9090 break;
9091 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
9092 if (ARG3) {
9093 struct vki_drm_i915_gem_set_tiling *data =
9094 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
9095 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
9096 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
9097 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
9098 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
9100 break;
9101 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
9102 if (ARG3) {
9103 struct vki_drm_i915_gem_get_tiling *data =
9104 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
9105 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
9106 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
9107 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
9109 break;
9110 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
9111 if (ARG3) {
9112 struct vki_drm_i915_gem_get_aperture *data =
9113 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
9114 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
9115 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
9117 break;
9119 /* KVM ioctls that check for a numeric value as parameter */
9120 case VKI_KVM_GET_API_VERSION:
9121 case VKI_KVM_CREATE_VM:
9122 case VKI_KVM_GET_VCPU_MMAP_SIZE:
9123 case VKI_KVM_CHECK_EXTENSION:
9124 case VKI_KVM_SET_TSS_ADDR:
9125 case VKI_KVM_CREATE_VCPU:
9126 case VKI_KVM_RUN:
9127 break;
9129 case VKI_KVM_S390_MEM_OP: {
9130 struct vki_kvm_s390_mem_op *args =
9131 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
9132 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
9133 sizeof(struct vki_kvm_s390_mem_op));
9134 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
9135 break;
9136 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
9137 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
9138 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
9139 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
9141 break;
9144 #ifdef ENABLE_XEN
9145 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
9146 SyscallArgs harrghs;
9147 struct vki_xen_privcmd_hypercall *args =
9148 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
9150 if (!args)
9151 break;
9153 VG_(memset)(&harrghs, 0, sizeof(harrghs));
9154 harrghs.sysno = args->op;
9155 harrghs.arg1 = args->arg[0];
9156 harrghs.arg2 = args->arg[1];
9157 harrghs.arg3 = args->arg[2];
9158 harrghs.arg4 = args->arg[3];
9159 harrghs.arg5 = args->arg[4];
9160 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
9162 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
9164 /* HACK. arg8 is used to return the number of hypercall
9165 * arguments actually consumed! */
9166 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
9167 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
9169 break;
9172 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
9173 struct vki_xen_privcmd_mmap *args =
9174 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
9175 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
9176 (Addr)&args->num, sizeof(args->num));
9177 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
9178 (Addr)&args->dom, sizeof(args->dom));
9179 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
9180 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
9181 break;
9183 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
9184 struct vki_xen_privcmd_mmapbatch *args =
9185 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
9186 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
9187 (Addr)&args->num, sizeof(args->num));
9188 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
9189 (Addr)&args->dom, sizeof(args->dom));
9190 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
9191 (Addr)&args->addr, sizeof(args->addr));
9192 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
9193 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9194 break;
9196 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
9197 struct vki_xen_privcmd_mmapbatch_v2 *args =
9198 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
9199 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
9200 (Addr)&args->num, sizeof(args->num));
9201 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
9202 (Addr)&args->dom, sizeof(args->dom));
9203 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
9204 (Addr)&args->addr, sizeof(args->addr));
9205 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
9206 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9207 break;
9210 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
9211 struct vki_xen_ioctl_evtchn_bind_virq *args =
9212 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
9213 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
9214 (Addr)&args->virq, sizeof(args->virq));
9216 break;
9217 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
9218 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
9219 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
9220 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
9221 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9222 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
9223 (Addr)&args->remote_port, sizeof(args->remote_port));
9225 break;
9226 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
9227 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
9228 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
9229 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
9230 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9232 break;
9233 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
9234 struct vki_xen_ioctl_evtchn_unbind *args =
9235 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
9236 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
9237 (Addr)&args->port, sizeof(args->port));
9239 break;
9240 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
9241 struct vki_xen_ioctl_evtchn_notify *args =
9242 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
9243 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
9244 (Addr)&args->port, sizeof(args->port));
9246 break;
9247 case VKI_XEN_IOCTL_EVTCHN_RESET:
9248 /* No input*/
9249 break;
9250 #endif
9252 /* Lustre */
9253 case VKI_OBD_IOC_FID2PATH: {
9254 struct vki_getinfo_fid2path *gf =
9255 (struct vki_getinfo_fid2path *)(Addr)ARG3;
9256 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
9257 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
9258 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
9259 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
9260 break;
9263 case VKI_LL_IOC_PATH2FID:
9264 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
9265 break;
9267 case VKI_LL_IOC_GETPARENT: {
9268 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
9269 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
9270 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
9271 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
9272 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
9273 break;
9276 /* V4L2 */
9277 case VKI_V4L2_QUERYCAP: {
9278 struct vki_v4l2_capability *data =
9279 (struct vki_v4l2_capability *)(Addr)ARG3;
9280 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
9281 break;
9283 case VKI_V4L2_ENUM_FMT: {
9284 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
9285 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
9286 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
9287 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
9288 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
9289 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
9290 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
9291 break;
9293 case VKI_V4L2_G_FMT: {
9294 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9295 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
9296 switch (data->type) {
9297 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9298 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9299 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
9300 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
9301 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
9302 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
9303 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
9304 break;
9305 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9306 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9307 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
9308 break;
9309 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9310 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9311 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
9312 break;
9313 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9314 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9315 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
9316 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9317 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9318 if (data->fmt.win.clipcount && data->fmt.win.clips)
9319 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9320 (Addr)data->fmt.win.clips,
9321 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9322 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9323 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9324 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9325 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9326 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9327 break;
9328 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9329 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9330 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9331 break;
9332 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9333 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9334 break;
9336 break;
9338 case VKI_V4L2_S_FMT: {
9339 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9340 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9341 switch (data->type) {
9342 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9343 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9344 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9345 (Addr)&data->type + sizeof(data->type),
9346 sizeof(*data) - sizeof(data->type));
9347 break;
9348 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9349 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9350 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9351 break;
9352 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9353 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9354 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9355 break;
9356 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9357 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9358 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9359 if (data->fmt.win.clipcount && data->fmt.win.clips)
9360 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9361 (Addr)data->fmt.win.clips,
9362 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9363 if (data->fmt.win.bitmap)
9364 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9365 (Addr)data->fmt.win.bitmap,
9366 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9367 break;
9368 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9369 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9370 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9371 break;
9372 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9373 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9374 break;
9376 break;
9378 case VKI_V4L2_TRY_FMT: {
9379 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9380 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9381 switch (data->type) {
9382 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9383 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9384 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9385 (Addr)&data->type + sizeof(data->type),
9386 sizeof(*data) - sizeof(data->type));
9387 break;
9388 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9389 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9390 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9391 break;
9392 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9393 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9394 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9395 break;
9396 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9397 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9398 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9399 if (data->fmt.win.clipcount && data->fmt.win.clips)
9400 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9401 (Addr)data->fmt.win.clips,
9402 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9403 if (data->fmt.win.bitmap)
9404 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9405 (Addr)data->fmt.win.bitmap,
9406 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9407 break;
9408 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9409 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9410 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9411 break;
9412 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9413 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9414 break;
9416 break;
9418 case VKI_V4L2_REQBUFS: {
9419 struct vki_v4l2_requestbuffers *data =
9420 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9421 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9422 break;
9424 case VKI_V4L2_QUERYBUF: {
9425 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9426 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9427 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9428 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9429 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9430 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9431 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9432 unsigned i;
9434 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9435 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9436 for (i = 0; i < data->length; i++) {
9437 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9438 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9439 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9440 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9441 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9443 } else {
9444 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9445 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9447 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9448 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9449 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9450 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9451 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9452 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9453 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9454 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9455 break;
9457 case VKI_V4L2_G_FBUF: {
9458 struct vki_v4l2_framebuffer *data =
9459 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9460 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9461 break;
9463 case VKI_V4L2_S_FBUF: {
9464 struct vki_v4l2_framebuffer *data =
9465 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9466 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9467 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9468 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9469 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9470 break;
9472 case VKI_V4L2_OVERLAY: {
9473 int *data = (int *)(Addr)ARG3;
9474 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9475 break;
9477 case VKI_V4L2_QBUF: {
9478 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9479 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9480 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9481 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9482 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9484 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9485 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9486 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9487 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9488 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9489 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9490 if (is_output) {
9491 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9492 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9494 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9495 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9496 unsigned i;
9498 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9499 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9500 for (i = 0; i < data->length; i++) {
9501 if (is_output) {
9502 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9503 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9505 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9506 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9507 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9508 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9509 else
9510 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9511 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9513 } else {
9514 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9515 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9516 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9517 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9518 else
9519 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9520 if (is_output) {
9521 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9522 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9525 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9526 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9527 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9529 break;
9531 case VKI_V4L2_EXPBUF: {
9532 struct vki_v4l2_exportbuffer *data =
9533 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9534 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9535 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9536 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9537 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9538 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9539 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9540 break;
9542 case VKI_V4L2_DQBUF: {
9543 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9544 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9545 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9546 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9547 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9548 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9549 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9550 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9551 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9552 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9553 unsigned i;
9555 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9556 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9557 for (i = 0; i < data->length; i++) {
9558 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9559 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9560 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9561 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9562 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9564 } else {
9565 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9566 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9567 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9568 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9570 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9571 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9572 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9573 break;
9575 case VKI_V4L2_STREAMON: {
9576 int *data = (int *)(Addr)ARG3;
9577 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9578 break;
9580 case VKI_V4L2_STREAMOFF: {
9581 int *data = (int *)(Addr)ARG3;
9582 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9583 break;
9585 case VKI_V4L2_G_PARM: {
9586 struct vki_v4l2_streamparm *data =
9587 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9588 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9589 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9590 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9591 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9593 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9594 if (is_output) {
9595 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9596 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9597 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9598 } else {
9599 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9600 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9601 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9603 break;
9605 case VKI_V4L2_S_PARM: {
9606 struct vki_v4l2_streamparm *data =
9607 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9608 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9609 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9610 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9611 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9613 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9614 if (is_output)
9615 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9616 else
9617 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9618 break;
9620 case VKI_V4L2_G_STD: {
9621 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9622 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9623 break;
9625 case VKI_V4L2_S_STD: {
9626 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9627 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9628 break;
9630 case VKI_V4L2_ENUMSTD: {
9631 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9632 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9633 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9634 break;
9636 case VKI_V4L2_ENUMINPUT: {
9637 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9638 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9639 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9640 break;
9642 case VKI_V4L2_G_CTRL: {
9643 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9644 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9645 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9646 break;
9648 case VKI_V4L2_S_CTRL: {
9649 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9650 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9651 break;
9653 case VKI_V4L2_G_TUNER: {
9654 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9655 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9656 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9657 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9658 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9659 break;
9661 case VKI_V4L2_S_TUNER: {
9662 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9663 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9664 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9665 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9666 break;
9668 case VKI_V4L2_G_AUDIO: {
9669 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9670 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9671 sizeof(*data) - sizeof(data->reserved));
9672 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9673 break;
9675 case VKI_V4L2_S_AUDIO: {
9676 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9677 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9678 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9679 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9680 break;
9682 case VKI_V4L2_QUERYCTRL: {
9683 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9684 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9685 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9686 sizeof(*data) - sizeof(data->id));
9687 break;
9689 case VKI_V4L2_QUERYMENU: {
9690 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9691 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9692 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9693 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9694 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9695 break;
9697 case VKI_V4L2_G_INPUT: {
9698 int *data = (int *)(Addr)ARG3;
9699 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9700 break;
9702 case VKI_V4L2_S_INPUT: {
9703 int *data = (int *)(Addr)ARG3;
9704 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9705 break;
9707 case VKI_V4L2_G_EDID: {
9708 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9709 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9710 if (data->blocks && data->edid)
9711 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9712 break;
9714 case VKI_V4L2_S_EDID: {
9715 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9716 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9717 if (data->blocks && data->edid)
9718 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9719 break;
9721 case VKI_V4L2_G_OUTPUT: {
9722 int *data = (int *)(Addr)ARG3;
9723 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9724 break;
9726 case VKI_V4L2_S_OUTPUT: {
9727 int *data = (int *)(Addr)ARG3;
9728 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9729 break;
9731 case VKI_V4L2_ENUMOUTPUT: {
9732 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9733 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9734 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9735 break;
9737 case VKI_V4L2_G_AUDOUT: {
9738 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9739 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9740 sizeof(*data) - sizeof(data->reserved));
9741 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9742 break;
9744 case VKI_V4L2_S_AUDOUT: {
9745 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9746 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9747 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9748 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9749 break;
9751 case VKI_V4L2_G_MODULATOR: {
9752 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9753 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9754 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9755 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9756 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9757 break;
9759 case VKI_V4L2_S_MODULATOR: {
9760 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9761 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9762 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9763 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9764 break;
9766 case VKI_V4L2_G_FREQUENCY: {
9767 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9768 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9769 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9770 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9771 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9772 break;
9774 case VKI_V4L2_S_FREQUENCY: {
9775 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9776 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9777 break;
9779 case VKI_V4L2_CROPCAP: {
9780 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9781 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9782 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9783 break;
9785 case VKI_V4L2_G_CROP: {
9786 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9787 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9788 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9789 break;
9791 case VKI_V4L2_S_CROP: {
9792 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9793 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9794 break;
9796 case VKI_V4L2_G_JPEGCOMP: {
9797 struct vki_v4l2_jpegcompression *data =
9798 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9799 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9800 break;
9802 case VKI_V4L2_S_JPEGCOMP: {
9803 struct vki_v4l2_jpegcompression *data =
9804 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9805 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9806 break;
9808 case VKI_V4L2_QUERYSTD: {
9809 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9810 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9811 break;
9813 case VKI_V4L2_ENUMAUDIO: {
9814 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9815 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9816 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9817 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9818 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9819 break;
9821 case VKI_V4L2_ENUMAUDOUT: {
9822 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9823 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9824 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9825 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9826 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9827 break;
9829 case VKI_V4L2_G_PRIORITY: {
9830 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9831 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9832 break;
9834 case VKI_V4L2_S_PRIORITY: {
9835 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9836 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9837 break;
9839 case VKI_V4L2_G_SLICED_VBI_CAP: {
9840 struct vki_v4l2_sliced_vbi_cap *data =
9841 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9842 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9843 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9844 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9845 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9846 break;
9848 case VKI_V4L2_G_EXT_CTRLS: {
9849 struct vki_v4l2_ext_controls *data =
9850 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9851 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9852 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9853 if (data->count) {
9854 unsigned i;
9856 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9857 for (i = 0; i < data->count; i++) {
9858 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9859 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9860 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9861 if (data->controls[i].size) {
9862 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9863 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9864 (Addr)data->controls[i].ptr, data->controls[i].size);
9865 } else {
9866 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9867 data->controls[i].value64);
9871 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9872 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9873 break;
9875 case VKI_V4L2_S_EXT_CTRLS: {
9876 struct vki_v4l2_ext_controls *data =
9877 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9878 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9879 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9880 if (data->count) {
9881 unsigned i;
9883 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9884 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9885 data->count * sizeof(data->controls[0]));
9886 for (i = 0; i < data->count; i++) {
9887 if (data->controls[i].size) {
9888 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9889 (Addr)data->controls[i].ptr, data->controls[i].size);
9893 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9894 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9895 break;
9897 case VKI_V4L2_TRY_EXT_CTRLS: {
9898 struct vki_v4l2_ext_controls *data =
9899 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9900 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9901 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9902 if (data->count) {
9903 unsigned i;
9905 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9906 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9907 data->count * sizeof(data->controls[0]));
9908 for (i = 0; i < data->count; i++) {
9909 if (data->controls[i].size) {
9910 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9911 (Addr)data->controls[i].ptr, data->controls[i].size);
9915 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9916 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9917 break;
9919 case VKI_V4L2_ENUM_FRAMESIZES: {
9920 struct vki_v4l2_frmsizeenum *data =
9921 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9922 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9923 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9924 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9925 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9926 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9927 break;
9929 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9930 struct vki_v4l2_frmivalenum *data =
9931 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9932 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9933 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9934 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9935 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9936 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9937 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9938 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9939 break;
9941 case VKI_V4L2_G_ENC_INDEX: {
9942 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9943 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9944 break;
9946 case VKI_V4L2_ENCODER_CMD: {
9947 struct vki_v4l2_encoder_cmd *data =
9948 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9949 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9950 break;
9952 case VKI_V4L2_TRY_ENCODER_CMD: {
9953 struct vki_v4l2_encoder_cmd *data =
9954 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9955 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9956 break;
9958 case VKI_V4L2_DBG_S_REGISTER: {
9959 struct vki_v4l2_dbg_register *data =
9960 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9961 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9962 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9963 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9964 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9965 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9966 break;
9968 case VKI_V4L2_DBG_G_REGISTER: {
9969 struct vki_v4l2_dbg_register *data =
9970 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9971 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9972 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9973 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9974 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9975 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9976 break;
9978 case VKI_V4L2_S_HW_FREQ_SEEK: {
9979 struct vki_v4l2_hw_freq_seek *data =
9980 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9981 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9982 break;
9984 case VKI_V4L2_S_DV_TIMINGS: {
9985 struct vki_v4l2_dv_timings *data =
9986 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9987 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9988 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9989 break;
9991 case VKI_V4L2_G_DV_TIMINGS: {
9992 struct vki_v4l2_dv_timings *data =
9993 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9994 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9995 break;
9997 case VKI_V4L2_DQEVENT: {
9998 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9999 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
10000 break;
10002 case VKI_V4L2_SUBSCRIBE_EVENT: {
10003 struct vki_v4l2_event_subscription *data =
10004 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
10005 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
10006 break;
10008 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
10009 struct vki_v4l2_event_subscription *data =
10010 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
10011 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
10012 break;
10014 case VKI_V4L2_CREATE_BUFS: {
10015 struct vki_v4l2_create_buffers *data =
10016 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
10017 struct vki_v4l2_format *fmt = &data->format;
10018 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
10019 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
10020 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
10021 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
10022 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
10023 switch (fmt->type) {
10024 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
10025 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
10026 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
10027 break;
10028 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
10029 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
10030 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
10031 break;
10032 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
10033 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
10034 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
10035 break;
10036 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
10037 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
10038 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
10039 break;
10040 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
10041 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
10042 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
10043 break;
10044 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
10045 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
10046 break;
10048 break;
10050 case VKI_V4L2_PREPARE_BUF: {
10051 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10052 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
10053 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
10054 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
10055 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
10056 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
10057 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10058 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10059 unsigned i;
10061 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
10062 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
10063 for (i = 0; i < data->length; i++) {
10064 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
10067 break;
10069 case VKI_V4L2_G_SELECTION: {
10070 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
10071 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
10072 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
10073 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
10074 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
10075 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
10076 break;
10078 case VKI_V4L2_S_SELECTION: {
10079 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
10080 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
10081 break;
10083 case VKI_V4L2_DECODER_CMD: {
10084 struct vki_v4l2_decoder_cmd *data =
10085 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
10086 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
10087 break;
10089 case VKI_V4L2_TRY_DECODER_CMD: {
10090 struct vki_v4l2_decoder_cmd *data =
10091 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
10092 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
10093 break;
10095 case VKI_V4L2_ENUM_DV_TIMINGS: {
10096 struct vki_v4l2_enum_dv_timings *data =
10097 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
10098 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
10099 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
10100 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
10101 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
10102 break;
10104 case VKI_V4L2_QUERY_DV_TIMINGS: {
10105 struct vki_v4l2_dv_timings *data =
10106 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
10107 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
10108 break;
10110 case VKI_V4L2_DV_TIMINGS_CAP: {
10111 struct vki_v4l2_dv_timings_cap *data =
10112 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
10113 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
10114 break;
10116 case VKI_V4L2_ENUM_FREQ_BANDS: {
10117 struct vki_v4l2_frequency_band *data =
10118 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
10119 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
10120 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
10121 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
10122 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
10123 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
10124 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
10125 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
10126 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
10127 break;
10129 case VKI_V4L2_DBG_G_CHIP_INFO: {
10130 struct vki_v4l2_dbg_chip_info *data =
10131 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
10132 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
10133 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
10134 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
10135 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
10136 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
10137 break;
10139 case VKI_V4L2_QUERY_EXT_CTRL: {
10140 struct vki_v4l2_query_ext_ctrl *data =
10141 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
10142 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
10143 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
10144 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
10145 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
10146 break;
10148 case VKI_V4L2_SUBDEV_G_FMT: {
10149 struct vki_v4l2_subdev_format *data =
10150 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
10151 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
10152 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
10153 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
10154 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
10155 break;
10157 case VKI_V4L2_SUBDEV_S_FMT: {
10158 struct vki_v4l2_subdev_format *data =
10159 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
10160 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
10161 break;
10163 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
10164 struct vki_v4l2_subdev_frame_interval *data =
10165 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
10166 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
10167 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
10168 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
10169 break;
10171 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
10172 struct vki_v4l2_subdev_frame_interval *data =
10173 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
10174 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
10175 break;
10177 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
10178 struct vki_v4l2_subdev_mbus_code_enum *data =
10179 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
10180 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
10181 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
10182 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
10183 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
10184 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
10185 break;
10187 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
10188 struct vki_v4l2_subdev_frame_size_enum *data =
10189 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
10190 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
10191 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
10192 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
10193 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
10194 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
10195 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
10196 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
10197 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
10198 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
10199 break;
10201 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10202 struct vki_v4l2_subdev_frame_interval_enum *data =
10203 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
10204 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
10205 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
10206 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
10207 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
10208 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
10209 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
10210 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
10211 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
10212 break;
10214 case VKI_V4L2_SUBDEV_G_CROP: {
10215 struct vki_v4l2_subdev_crop *data =
10216 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10217 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
10218 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
10219 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
10220 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
10221 break;
10223 case VKI_V4L2_SUBDEV_S_CROP: {
10224 struct vki_v4l2_subdev_crop *data =
10225 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10226 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
10227 break;
10229 case VKI_V4L2_SUBDEV_G_SELECTION: {
10230 struct vki_v4l2_subdev_selection *data =
10231 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10232 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
10233 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
10234 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
10235 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
10236 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
10237 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
10238 break;
10240 case VKI_V4L2_SUBDEV_S_SELECTION: {
10241 struct vki_v4l2_subdev_selection *data =
10242 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10243 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
10244 break;
10246 case VKI_MEDIA_IOC_DEVICE_INFO: {
10247 struct vki_media_device_info *data =
10248 (struct vki_media_device_info *)(Addr)ARG3;
10249 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
10250 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
10251 (Addr)data, sizeof(*data) - sizeof(data->reserved));
10252 break;
10254 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10255 struct vki_media_entity_desc *data =
10256 (struct vki_media_entity_desc *)(Addr)ARG3;
10257 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
10258 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
10259 (Addr)data->name, sizeof(*data) - sizeof(data->id));
10260 break;
10262 case VKI_MEDIA_IOC_ENUM_LINKS: {
10263 struct vki_media_links_enum *data =
10264 (struct vki_media_links_enum *)(Addr)ARG3;
10265 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
10266 break;
10268 case VKI_MEDIA_IOC_SETUP_LINK: {
10269 struct vki_media_link_desc *data =
10270 (struct vki_media_link_desc *)(Addr)ARG3;
10271 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
10272 break;
10275 /* Serial */
10276 case VKI_TIOCGSERIAL: {
10277 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10278 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
10279 break;
10281 case VKI_TIOCSSERIAL: {
10282 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10283 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
10284 break;
10287 case VKI_PERF_EVENT_IOC_RESET:
10288 case VKI_PERF_EVENT_IOC_REFRESH:
10289 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10290 case VKI_PERF_EVENT_IOC_SET_BPF:
10291 /* These take scalar arguments, so already handled above */
10292 break;
10294 case VKI_PERF_EVENT_IOC_PERIOD:
10295 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
10296 break;
10298 case VKI_PERF_EVENT_IOC_SET_FILTER:
10299 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
10300 break;
10302 case VKI_PERF_EVENT_IOC_ID:
10303 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
10304 break;
10306 /* Pulse Per Second (PPS) */
10307 case VKI_PPS_GETPARAMS: {
10308 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10309 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
10310 break;
10312 case VKI_PPS_SETPARAMS: {
10313 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10314 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
10315 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
10316 data->assert_off_tu.sec);
10317 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10318 data->assert_off_tu.nsec);
10319 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10320 data->clear_off_tu.sec);
10321 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10322 data->clear_off_tu.nsec);
10323 break;
10325 case VKI_PPS_GETCAP:
10326 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10327 break;
10328 case VKI_PPS_FETCH: {
10329 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10330 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10331 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10332 break;
10334 case VKI_PPS_KC_BIND: {
10335 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10336 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10337 break;
10340 /* PTP Hardware Clock */
10341 case VKI_PTP_CLOCK_GETCAPS: {
10342 struct vki_ptp_clock_caps *data =
10343 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10344 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10345 break;
10347 case VKI_PTP_EXTTS_REQUEST: {
10348 struct vki_ptp_extts_request *data =
10349 (struct vki_ptp_extts_request *)(Addr)ARG3;
10350 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10351 break;
10353 case VKI_PTP_PEROUT_REQUEST: {
10354 struct vki_ptp_perout_request *data =
10355 (struct vki_ptp_perout_request *)(Addr)ARG3;
10356 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10357 break;
10359 case VKI_PTP_ENABLE_PPS:
10360 break;
10361 case VKI_PTP_SYS_OFFSET: {
10362 struct vki_ptp_sys_offset *data =
10363 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10364 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10365 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10366 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10367 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10368 break;
10370 case VKI_PTP_PIN_GETFUNC: {
10371 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10372 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10373 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10374 break;
10376 case VKI_PTP_PIN_SETFUNC: {
10377 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10378 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10379 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10380 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10381 break;
10383 case VKI_PTP_SYS_OFFSET_PRECISE: {
10384 struct vki_ptp_sys_offset_precise *data =
10385 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10386 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10387 break;
10389 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10390 struct vki_ptp_sys_offset_extended *data =
10391 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10392 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10393 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10394 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10395 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10396 3 * data->n_samples * sizeof(data->ts[0][0]));
10397 break;
10400 default:
10401 /* EVIOC* are variable length and return size written on success */
10402 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10403 case VKI_EVIOCGNAME(0):
10404 case VKI_EVIOCGPHYS(0):
10405 case VKI_EVIOCGUNIQ(0):
10406 case VKI_EVIOCGKEY(0):
10407 case VKI_EVIOCGLED(0):
10408 case VKI_EVIOCGSND(0):
10409 case VKI_EVIOCGSW(0):
10410 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10411 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10412 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10413 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10414 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10415 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10416 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10417 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10418 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10419 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10420 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10421 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10422 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10423 break;
10424 default:
10425 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10426 break;
10428 break;
10432 POST(sys_ioctl)
10434 ARG2 = (UInt)ARG2;
10436 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10438 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10440 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10441 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10442 VG_(clo_kernel_variant))) {
10444 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10445 /* What's going on here: there appear to be a bunch of ioctls
10446 of the form 0xC01C67xx which are undocumented, and if
10447 unhandled give rise to a vast number of false positives in
10448 Memcheck.
10450 The "normal" interpretation of an ioctl of this form would
10451 be that the 3rd arg is a pointer to an area of size 0x1C
10452 (28 bytes) which is filled in by the kernel. Hence you
10453 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10454 But it doesn't.
10456 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10457 One interpretation of this is that ARG3 really does point
10458 to a 28 byte struct, but inside that are pointers to other
10459 areas also filled in by the kernel. If these happen to be
10460 allocated just back up the stack then the 256 byte paint
10461 might cover them too, somewhat indiscriminately.
10463 By printing out ARG3 and also the 28 bytes that it points
10464 at, it's possible to guess that the 7 word structure has
10465 this form
10467 0 1 2 3 4 5 6
10468 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10470 Unfortunately that doesn't seem to work for some reason,
10471 so stay with the blunt-instrument approach for the time
10472 being.
10474 if (1) {
10475 /* blunt-instrument approach */
10476 POST_MEM_WRITE(ARG3, 256);
10477 } else {
10478 /* be a bit more sophisticated */
10479 POST_MEM_WRITE(ARG3, 28);
10480 UInt* word = (UInt*)(Addr)ARG3;
10481 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10482 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10483 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10484 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10486 goto post_sys_ioctl__out;
10489 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10491 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10492 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10493 VG_(clo_kernel_variant))) {
10494 if (ARG2 == 0xC00C0902) {
10495 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10496 goto post_sys_ioctl__out;
10499 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10501 /* --- END special IOCTL handlers for specific Android hardware --- */
10503 /* --- normal handling --- */
10504 switch (ARG2 /* request */) {
10506 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10507 this is pretty poor given that there's no pre-handling to check
10508 that writable areas are addressable. */
10509 case VKI_ION_IOC_ALLOC: {
10510 struct vki_ion_allocation_data* data
10511 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10512 POST_FIELD_WRITE(data->handle);
10513 break;
10515 case VKI_ION_IOC_MAP: {
10516 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10517 POST_FIELD_WRITE(data->fd);
10518 break;
10520 case VKI_ION_IOC_FREE: // is this necessary?
10521 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10522 break;
10523 case VKI_ION_IOC_SHARE:
10524 break;
10525 case VKI_ION_IOC_IMPORT: {
10526 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10527 POST_FIELD_WRITE(data->handle);
10528 break;
10530 case VKI_ION_IOC_SYNC:
10531 break;
10532 case VKI_ION_IOC_CUSTOM: // is this necessary?
10533 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10534 break;
10536 case VKI_SYNC_IOC_MERGE: {
10537 struct vki_sync_merge_data* data =
10538 (struct vki_sync_merge_data*)(Addr)ARG3;
10539 POST_FIELD_WRITE(data->fence);
10540 if (VG_(clo_track_fds))
10541 ML_(record_fd_open_nameless) (tid, data->fence);
10542 break;
10545 case VKI_SYNC_IOC_FILE_INFO: {
10546 struct vki_sync_file_info* data =
10547 (struct vki_sync_file_info*)(Addr)ARG3;
10548 POST_FIELD_WRITE(data->status);
10549 if (data->num_fences > 0 && (Addr)data->sync_fence_info != (Addr)NULL)
10550 POST_MEM_WRITE(data->sync_fence_info,
10551 data->num_fences * sizeof(struct vki_sync_fence_info));
10552 break;
10555 case VKI_TCSETS:
10556 case VKI_TCSETSW:
10557 case VKI_TCSETSF:
10558 case VKI_IB_USER_MAD_ENABLE_PKEY:
10559 break;
10560 case VKI_TCGETS:
10561 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10562 break;
10563 case VKI_TCSETA:
10564 case VKI_TCSETAW:
10565 case VKI_TCSETAF:
10566 break;
10567 case VKI_TCGETA:
10568 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10569 break;
10570 case VKI_TCSBRK:
10571 case VKI_TCXONC:
10572 case VKI_TCSBRKP:
10573 case VKI_TCFLSH:
10574 case VKI_TIOCSIG:
10575 break;
10576 case VKI_TIOCGWINSZ:
10577 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10578 break;
10579 case VKI_TIOCSWINSZ:
10580 case VKI_TIOCMBIS:
10581 case VKI_TIOCMBIC:
10582 case VKI_TIOCMSET:
10583 break;
10584 case VKI_TIOCMGET:
10585 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10586 break;
10587 case VKI_TIOCLINUX:
10588 POST_MEM_WRITE( ARG3, sizeof(char *) );
10589 break;
10590 case VKI_TIOCGPGRP:
10591 /* Get process group ID for foreground processing group. */
10592 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10593 break;
10594 case VKI_TIOCSPGRP:
10595 /* Set a process group ID? */
10596 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10597 break;
10598 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10599 POST_MEM_WRITE( ARG3, sizeof(int));
10600 break;
10601 case VKI_TIOCSCTTY:
10602 break;
10603 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10604 break;
10605 case VKI_FIONBIO:
10606 break;
10607 case VKI_FIONCLEX:
10608 break;
10609 case VKI_FIOCLEX:
10610 break;
10611 case VKI_TIOCNOTTY:
10612 break;
10613 case VKI_FIOASYNC:
10614 break;
10615 case VKI_FIONREAD: /* identical to SIOCINQ */
10616 POST_MEM_WRITE( ARG3, sizeof(int) );
10617 break;
10618 case VKI_FIOQSIZE:
10619 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10620 break;
10622 case VKI_TIOCSERGETLSR:
10623 POST_MEM_WRITE( ARG3, sizeof(int) );
10624 break;
10625 case VKI_TIOCGICOUNT:
10626 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10627 break;
10629 case VKI_SG_SET_COMMAND_Q:
10630 break;
10631 case VKI_SG_IO:
10633 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10634 if ( sgio->sbp ) {
10635 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10637 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10638 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10639 int transferred = sgio->dxfer_len - sgio->resid;
10640 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10643 break;
10644 case VKI_SG_GET_SCSI_ID:
10645 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10646 break;
10647 case VKI_SG_SET_RESERVED_SIZE:
10648 break;
10649 case VKI_SG_SET_TIMEOUT:
10650 break;
10651 case VKI_SG_GET_RESERVED_SIZE:
10652 POST_MEM_WRITE(ARG3, sizeof(int));
10653 break;
10654 case VKI_SG_GET_TIMEOUT:
10655 break;
10656 case VKI_SG_GET_VERSION_NUM:
10657 POST_MEM_WRITE(ARG3, sizeof(int));
10658 break;
10659 case VKI_SG_EMULATED_HOST:
10660 POST_MEM_WRITE(ARG3, sizeof(int));
10661 break;
10662 case VKI_SG_GET_SG_TABLESIZE:
10663 POST_MEM_WRITE(ARG3, sizeof(int));
10664 break;
10666 case VKI_IIOCGETCPS:
10667 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10668 break;
10669 case VKI_IIOCNETGPN:
10670 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10671 break;
10673 /* These all use struct ifreq AFAIK */
10674 case VKI_SIOCGIFINDEX: /* get iface index */
10675 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10676 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10677 break;
10678 case VKI_SIOCGIFFLAGS: /* get flags */
10679 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10680 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10681 break;
10682 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10683 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10684 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10685 break;
10686 case VKI_SIOCGIFMTU: /* get MTU size */
10687 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10688 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10689 break;
10690 case VKI_SIOCGIFADDR: /* get PA address */
10691 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10692 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10693 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10694 POST_MEM_WRITE(
10695 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10696 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10697 break;
10698 case VKI_SIOCGIFMETRIC: /* get metric */
10699 POST_MEM_WRITE(
10700 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10701 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10702 break;
10703 case VKI_SIOCGIFMAP: /* Get device parameters */
10704 POST_MEM_WRITE(
10705 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10706 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10707 break;
10708 break;
10709 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10710 POST_MEM_WRITE(
10711 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10712 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10713 break;
10714 case VKI_SIOCGIFNAME: /* get iface name */
10715 POST_MEM_WRITE(
10716 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10717 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10718 break;
10719 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10720 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10721 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10722 case VKI_ETHTOOL_GSET:
10723 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10724 break;
10725 case VKI_ETHTOOL_SSET:
10726 break;
10727 case VKI_ETHTOOL_GDRVINFO:
10728 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10729 break;
10730 case VKI_ETHTOOL_GREGS:
10731 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10732 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10733 break;
10734 case VKI_ETHTOOL_GWOL:
10735 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10736 break;
10737 case VKI_ETHTOOL_SWOL:
10738 break;
10739 case VKI_ETHTOOL_GMSGLVL:
10740 case VKI_ETHTOOL_GLINK:
10741 case VKI_ETHTOOL_GRXCSUM:
10742 case VKI_ETHTOOL_GSG:
10743 case VKI_ETHTOOL_GTSO:
10744 case VKI_ETHTOOL_GUFO:
10745 case VKI_ETHTOOL_GGSO:
10746 case VKI_ETHTOOL_GFLAGS:
10747 case VKI_ETHTOOL_GGRO:
10748 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10749 break;
10750 case VKI_ETHTOOL_SMSGLVL:
10751 case VKI_ETHTOOL_SRXCSUM:
10752 case VKI_ETHTOOL_SSG:
10753 case VKI_ETHTOOL_STSO:
10754 case VKI_ETHTOOL_SUFO:
10755 case VKI_ETHTOOL_SGSO:
10756 case VKI_ETHTOOL_SFLAGS:
10757 case VKI_ETHTOOL_SGRO:
10758 break;
10759 case VKI_ETHTOOL_NWAY_RST:
10760 break;
10761 case VKI_ETHTOOL_GRINGPARAM:
10762 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10763 break;
10764 case VKI_ETHTOOL_SRINGPARAM:
10765 break;
10766 case VKI_ETHTOOL_TEST:
10767 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10768 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10769 break;
10770 case VKI_ETHTOOL_PHYS_ID:
10771 break;
10772 case VKI_ETHTOOL_GPERMADDR:
10773 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10774 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10775 break;
10776 case VKI_ETHTOOL_RESET:
10777 break;
10778 case VKI_ETHTOOL_GSSET_INFO:
10779 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10780 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10781 break;
10782 case VKI_ETHTOOL_GFEATURES:
10783 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10784 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10785 break;
10786 case VKI_ETHTOOL_SFEATURES:
10787 break;
10788 case VKI_ETHTOOL_GCHANNELS:
10789 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10790 break;
10791 case VKI_ETHTOOL_SCHANNELS:
10792 break;
10793 case VKI_ETHTOOL_GET_TS_INFO:
10794 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10795 break;
10797 break;
10799 case VKI_SIOCGMIIPHY: /* get hardware entry */
10800 POST_MEM_WRITE(
10801 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10802 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10803 break;
10804 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10805 POST_MEM_WRITE(
10806 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10807 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10808 break;
10810 /* tun/tap related ioctls */
10811 case VKI_TUNSETIFF:
10812 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10813 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10814 break;
10815 case VKI_TUNGETFEATURES:
10816 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10817 break;
10818 case VKI_TUNGETIFF:
10819 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10820 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10821 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10822 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10823 break;
10824 case VKI_TUNGETSNDBUF:
10825 POST_MEM_WRITE( ARG3, sizeof(int) );
10826 break;
10827 case VKI_TUNGETVNETHDRSZ:
10828 POST_MEM_WRITE( ARG3, sizeof(int) );
10829 break;
10831 case VKI_SIOCGIFCONF: /* get iface list */
10832 /* WAS:
10833 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10834 KERNEL_DO_SYSCALL(tid,RES);
10835 if (!VG_(is_kerror)(RES) && RES == 0)
10836 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10838 if (RES == 0 && ARG3 ) {
10839 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10840 if (ifc->vki_ifc_buf != NULL)
10841 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10843 break;
10844 case VKI_SIOCGSTAMP:
10845 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10846 break;
10847 case VKI_SIOCGSTAMPNS:
10848 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10849 break;
10850 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10851 the number of bytes currently in that socket's send buffer.
10852 It writes this value as an int to the memory location
10853 indicated by the third argument of ioctl(2). */
10854 case VKI_SIOCOUTQ:
10855 POST_MEM_WRITE(ARG3, sizeof(int));
10856 break;
10857 case VKI_SIOCGRARP: /* get RARP table entry */
10858 case VKI_SIOCGARP: /* get ARP table entry */
10859 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10860 break;
10862 case VKI_SIOCSIFFLAGS: /* set flags */
10863 case VKI_SIOCSIFMAP: /* Set device parameters */
10864 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10865 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10866 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10867 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10868 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10869 case VKI_SIOCSIFMETRIC: /* set metric */
10870 case VKI_SIOCSIFADDR: /* set PA address */
10871 case VKI_SIOCSIFMTU: /* set MTU size */
10872 case VKI_SIOCSIFHWADDR: /* set hardware address */
10873 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10874 break;
10875 /* Routing table calls. */
10876 case VKI_SIOCADDRT: /* add routing table entry */
10877 case VKI_SIOCDELRT: /* delete routing table entry */
10878 break;
10880 /* RARP cache control calls. */
10881 case VKI_SIOCDRARP: /* delete RARP table entry */
10882 case VKI_SIOCSRARP: /* set RARP table entry */
10883 /* ARP cache control calls. */
10884 case VKI_SIOCSARP: /* set ARP table entry */
10885 case VKI_SIOCDARP: /* delete ARP table entry */
10886 break;
10888 case VKI_SIOCGPGRP:
10889 POST_MEM_WRITE(ARG3, sizeof(int));
10890 break;
10891 case VKI_SIOCSPGRP:
10892 break;
10894 case VKI_SIOCATMARK:
10895 POST_MEM_WRITE(ARG3, sizeof(int));
10896 break;
10898 /* linux/soundcard interface (OSS) */
10899 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10900 case VKI_SNDCTL_SEQ_GETINCOUNT:
10901 case VKI_SNDCTL_SEQ_PERCMODE:
10902 case VKI_SNDCTL_SEQ_TESTMIDI:
10903 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10904 case VKI_SNDCTL_SEQ_NRSYNTHS:
10905 case VKI_SNDCTL_SEQ_NRMIDIS:
10906 case VKI_SNDCTL_SEQ_GETTIME:
10907 case VKI_SNDCTL_DSP_GETBLKSIZE:
10908 case VKI_SNDCTL_DSP_GETFMTS:
10909 case VKI_SNDCTL_DSP_SETFMT:
10910 case VKI_SNDCTL_DSP_GETTRIGGER:
10911 case VKI_SNDCTL_DSP_GETODELAY:
10912 case VKI_SNDCTL_DSP_GETSPDIF:
10913 case VKI_SNDCTL_DSP_GETCAPS:
10914 case VKI_SOUND_PCM_READ_RATE:
10915 case VKI_SOUND_PCM_READ_CHANNELS:
10916 case VKI_SOUND_PCM_READ_BITS:
10917 case VKI_SOUND_PCM_READ_FILTER:
10918 POST_MEM_WRITE(ARG3, sizeof(int));
10919 break;
10920 case VKI_SNDCTL_SEQ_CTRLRATE:
10921 case VKI_SNDCTL_DSP_SPEED:
10922 case VKI_SNDCTL_DSP_STEREO:
10923 case VKI_SNDCTL_DSP_CHANNELS:
10924 case VKI_SOUND_PCM_WRITE_FILTER:
10925 case VKI_SNDCTL_DSP_SUBDIVIDE:
10926 case VKI_SNDCTL_DSP_SETFRAGMENT:
10927 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10928 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10929 case VKI_SNDCTL_TMR_TIMEBASE:
10930 case VKI_SNDCTL_TMR_TEMPO:
10931 case VKI_SNDCTL_TMR_SOURCE:
10932 case VKI_SNDCTL_MIDI_PRETIME:
10933 case VKI_SNDCTL_MIDI_MPUMODE:
10934 break;
10935 case VKI_SNDCTL_DSP_GETOSPACE:
10936 case VKI_SNDCTL_DSP_GETISPACE:
10937 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10938 break;
10939 case VKI_SNDCTL_DSP_NONBLOCK:
10940 break;
10941 case VKI_SNDCTL_DSP_SETTRIGGER:
10942 break;
10944 case VKI_SNDCTL_DSP_POST:
10945 case VKI_SNDCTL_DSP_RESET:
10946 case VKI_SNDCTL_DSP_SYNC:
10947 case VKI_SNDCTL_DSP_SETSYNCRO:
10948 case VKI_SNDCTL_DSP_SETDUPLEX:
10949 break;
10951 /* linux/soundcard interface (ALSA) */
10952 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10953 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10954 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10955 case VKI_SNDRV_PCM_IOCTL_RESET:
10956 case VKI_SNDRV_PCM_IOCTL_START:
10957 case VKI_SNDRV_PCM_IOCTL_DROP:
10958 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10959 case VKI_SNDRV_PCM_IOCTL_RESUME:
10960 case VKI_SNDRV_PCM_IOCTL_XRUN:
10961 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10962 case VKI_SNDRV_TIMER_IOCTL_START:
10963 case VKI_SNDRV_TIMER_IOCTL_STOP:
10964 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10965 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10966 break;
10968 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10969 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10970 break;
10972 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10973 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10974 break;
10975 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10976 struct vki_snd_ctl_elem_list *data =
10977 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10978 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10979 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10980 if (data->pids) {
10981 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10983 break;
10985 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10986 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10987 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10988 break;
10990 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10991 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10992 break;
10994 /* SCSI no operand */
10995 case VKI_SCSI_IOCTL_DOORLOCK:
10996 case VKI_SCSI_IOCTL_DOORUNLOCK:
10997 break;
10999 /* Real Time Clock (/dev/rtc) ioctls */
11000 case VKI_RTC_UIE_ON:
11001 case VKI_RTC_UIE_OFF:
11002 case VKI_RTC_AIE_ON:
11003 case VKI_RTC_AIE_OFF:
11004 case VKI_RTC_PIE_ON:
11005 case VKI_RTC_PIE_OFF:
11006 case VKI_RTC_IRQP_SET:
11007 break;
11008 case VKI_RTC_RD_TIME:
11009 case VKI_RTC_ALM_READ:
11010 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
11011 break;
11012 case VKI_RTC_ALM_SET:
11013 break;
11014 case VKI_RTC_IRQP_READ:
11015 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
11016 break;
11018 /* Loopback devices */
11019 case VKI_LOOP_CTL_ADD:
11020 case VKI_LOOP_CTL_REMOVE:
11021 case VKI_LOOP_CTL_GET_FREE:
11022 break;
11023 /* Loopback device */
11024 case VKI_LOOP_SET_FD:
11025 case VKI_LOOP_CLR_FD:
11026 case VKI_LOOP_CHANGE_FD:
11027 case VKI_LOOP_SET_CAPACITY:
11028 case VKI_LOOP_SET_DIRECT_IO:
11029 case VKI_LOOP_SET_BLOCK_SIZE:
11030 break;
11031 case VKI_LOOP_SET_STATUS:
11032 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info));
11033 break;
11034 case VKI_LOOP_GET_STATUS:
11035 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info));
11036 break;
11037 case VKI_LOOP_SET_STATUS64:
11038 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info64));
11039 break;
11040 case VKI_LOOP_GET_STATUS64:
11041 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info64));
11042 break;
11045 /* Block devices */
11046 case VKI_BLKROSET:
11047 break;
11048 case VKI_BLKROGET:
11049 POST_MEM_WRITE(ARG3, sizeof(int));
11050 break;
11051 case VKI_BLKGETSIZE:
11052 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
11053 break;
11054 case VKI_BLKFLSBUF:
11055 break;
11056 case VKI_BLKRASET:
11057 break;
11058 case VKI_BLKRAGET:
11059 POST_MEM_WRITE(ARG3, sizeof(long));
11060 break;
11061 case VKI_BLKFRASET:
11062 break;
11063 case VKI_BLKFRAGET:
11064 POST_MEM_WRITE(ARG3, sizeof(long));
11065 break;
11066 case VKI_BLKSECTGET:
11067 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
11068 break;
11069 case VKI_BLKSSZGET:
11070 POST_MEM_WRITE(ARG3, sizeof(int));
11071 break;
11072 case VKI_BLKBSZGET:
11073 POST_MEM_WRITE(ARG3, sizeof(int));
11074 break;
11075 case VKI_BLKBSZSET:
11076 break;
11077 case VKI_BLKGETSIZE64:
11078 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
11079 break;
11080 case VKI_BLKPBSZGET:
11081 POST_MEM_WRITE(ARG3, sizeof(int));
11082 break;
11083 case VKI_BLKIOMIN:
11084 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
11085 break;
11086 case VKI_BLKIOOPT:
11087 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
11088 break;
11089 case VKI_BLKALIGNOFF:
11090 POST_MEM_WRITE(ARG3, sizeof(int));
11091 break;
11092 case VKI_BLKDISCARDZEROES:
11093 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
11094 break;
11095 case VKI_BLKREPORTZONE: {
11096 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
11098 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
11099 break;
11101 case VKI_BLKRESETZONE:
11102 break;
11104 /* Hard disks */
11105 case VKI_HDIO_GETGEO: /* 0x0301 */
11106 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
11107 break;
11108 case VKI_HDIO_GET_DMA: /* 0x030b */
11109 POST_MEM_WRITE(ARG3, sizeof(long));
11110 break;
11111 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
11112 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
11113 break;
11115 /* SCSI */
11116 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
11117 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
11118 break;
11119 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
11120 POST_MEM_WRITE(ARG3, sizeof(int));
11121 break;
11123 /* CD ROM stuff (??) */
11124 case VKI_CDROM_DISC_STATUS:
11125 case VKI_CDROMSTOP:
11126 break;
11127 case VKI_CDROMSUBCHNL:
11128 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
11129 break;
11130 case VKI_CDROMREADTOCHDR:
11131 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
11132 break;
11133 case VKI_CDROMREADTOCENTRY:
11134 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
11135 break;
11136 case VKI_CDROMMULTISESSION:
11137 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
11138 break;
11139 case VKI_CDROMVOLREAD:
11140 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
11141 break;
11142 case VKI_CDROMREADMODE1:
11143 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
11144 break;
11145 case VKI_CDROMREADMODE2:
11146 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
11147 break;
11148 case VKI_CDROMREADRAW:
11149 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
11150 break;
11151 case VKI_CDROMREADAUDIO:
11153 struct vki_cdrom_read_audio *cra =
11154 (struct vki_cdrom_read_audio *) (Addr)ARG3;
11155 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
11156 break;
11159 case VKI_CDROMPLAYMSF:
11160 break;
11161 /* The following two are probably bogus (should check args
11162 for readability). JRS 20021117 */
11163 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
11164 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
11165 break;
11166 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
11167 break;
11169 /* DVD stuff */
11170 case VKI_DVD_READ_STRUCT:
11171 break;
11173 case VKI_FIGETBSZ:
11174 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
11175 break;
11176 case VKI_FIBMAP:
11177 POST_MEM_WRITE(ARG3, sizeof(int));
11178 break;
11179 case VKI_FICLONE:
11180 break;
11182 case VKI_FBIOGET_VSCREENINFO: //0x4600
11183 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
11184 break;
11185 case VKI_FBIOGET_FSCREENINFO: //0x4602
11186 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
11187 break;
11189 case VKI_PPCLAIM:
11190 case VKI_PPEXCL:
11191 case VKI_PPYIELD:
11192 case VKI_PPRELEASE:
11193 case VKI_PPSETMODE:
11194 case VKI_PPSETPHASE:
11195 case VKI_PPSETFLAGS:
11196 case VKI_PPWDATA:
11197 case VKI_PPWCONTROL:
11198 case VKI_PPFCONTROL:
11199 case VKI_PPDATADIR:
11200 case VKI_PPNEGOT:
11201 case VKI_PPWCTLONIRQ:
11202 case VKI_PPSETTIME:
11203 break;
11204 case VKI_PPGETMODE:
11205 POST_MEM_WRITE( ARG3, sizeof(int) );
11206 break;
11207 case VKI_PPGETPHASE:
11208 POST_MEM_WRITE( ARG3, sizeof(int) );
11209 break;
11210 case VKI_PPGETMODES:
11211 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
11212 break;
11213 case VKI_PPGETFLAGS:
11214 POST_MEM_WRITE( ARG3, sizeof(int) );
11215 break;
11216 case VKI_PPRSTATUS:
11217 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11218 break;
11219 case VKI_PPRDATA:
11220 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11221 break;
11222 case VKI_PPRCONTROL:
11223 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11224 break;
11225 case VKI_PPCLRIRQ:
11226 POST_MEM_WRITE( ARG3, sizeof(int) );
11227 break;
11228 case VKI_PPGETTIME:
11229 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
11230 break;
11232 case VKI_GIO_FONT:
11233 POST_MEM_WRITE( ARG3, 32 * 256 );
11234 break;
11235 case VKI_PIO_FONT:
11236 break;
11238 case VKI_GIO_FONTX:
11239 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
11240 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
11241 break;
11242 case VKI_PIO_FONTX:
11243 break;
11245 case VKI_PIO_FONTRESET:
11246 break;
11248 case VKI_GIO_CMAP:
11249 POST_MEM_WRITE( ARG3, 16 * 3 );
11250 break;
11251 case VKI_PIO_CMAP:
11252 break;
11254 case VKI_KIOCSOUND:
11255 case VKI_KDMKTONE:
11256 break;
11258 case VKI_KDGETLED:
11259 POST_MEM_WRITE( ARG3, sizeof(char) );
11260 break;
11261 case VKI_KDSETLED:
11262 break;
11264 case VKI_KDGKBTYPE:
11265 POST_MEM_WRITE( ARG3, sizeof(char) );
11266 break;
11268 case VKI_KDADDIO:
11269 case VKI_KDDELIO:
11270 case VKI_KDENABIO:
11271 case VKI_KDDISABIO:
11272 break;
11274 case VKI_KDSETMODE:
11275 break;
11276 case VKI_KDGETMODE:
11277 POST_MEM_WRITE( ARG3, sizeof(int) );
11278 break;
11280 case VKI_KDMAPDISP:
11281 case VKI_KDUNMAPDISP:
11282 break;
11284 case VKI_GIO_SCRNMAP:
11285 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
11286 break;
11287 case VKI_PIO_SCRNMAP:
11288 break;
11289 case VKI_GIO_UNISCRNMAP:
11290 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
11291 break;
11292 case VKI_PIO_UNISCRNMAP:
11293 break;
11295 case VKI_GIO_UNIMAP:
11296 if ( ARG3 ) {
11297 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
11298 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
11299 POST_MEM_WRITE( (Addr)desc->entries,
11300 desc->entry_ct * sizeof(struct vki_unipair) );
11302 break;
11303 case VKI_PIO_UNIMAP:
11304 break;
11305 case VKI_PIO_UNIMAPCLR:
11306 break;
11308 case VKI_KDGKBMODE:
11309 POST_MEM_WRITE( ARG3, sizeof(int) );
11310 break;
11311 case VKI_KDSKBMODE:
11312 break;
11314 case VKI_KDGKBMETA:
11315 POST_MEM_WRITE( ARG3, sizeof(int) );
11316 break;
11317 case VKI_KDSKBMETA:
11318 break;
11320 case VKI_KDGKBLED:
11321 POST_MEM_WRITE( ARG3, sizeof(char) );
11322 break;
11323 case VKI_KDSKBLED:
11324 break;
11326 case VKI_KDGKBENT:
11327 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
11328 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
11329 break;
11330 case VKI_KDSKBENT:
11331 break;
11333 case VKI_KDGKBSENT:
11334 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
11335 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
11336 break;
11337 case VKI_KDSKBSENT:
11338 break;
11340 case VKI_KDGKBDIACR:
11341 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
11342 break;
11343 case VKI_KDSKBDIACR:
11344 break;
11346 case VKI_KDGETKEYCODE:
11347 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
11348 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
11349 break;
11350 case VKI_KDSETKEYCODE:
11351 break;
11353 case VKI_KDSIGACCEPT:
11354 break;
11356 case VKI_KDKBDREP:
11357 break;
11359 case VKI_KDFONTOP:
11360 if ( ARG3 ) {
11361 struct vki_console_font_op *op =
11362 (struct vki_console_font_op *) (Addr)ARG3;
11363 switch ( op->op ) {
11364 case VKI_KD_FONT_OP_SET:
11365 break;
11366 case VKI_KD_FONT_OP_GET:
11367 if ( op->data )
11368 POST_MEM_WRITE( (Addr) op->data,
11369 (op->width + 7) / 8 * 32 * op->charcount );
11370 break;
11371 case VKI_KD_FONT_OP_SET_DEFAULT:
11372 break;
11373 case VKI_KD_FONT_OP_COPY:
11374 break;
11376 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11378 break;
11380 case VKI_VT_OPENQRY:
11381 POST_MEM_WRITE( ARG3, sizeof(int) );
11382 break;
11383 case VKI_VT_GETMODE:
11384 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11385 break;
11386 case VKI_VT_SETMODE:
11387 break;
11388 case VKI_VT_GETSTATE:
11389 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11390 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11391 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11392 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11393 break;
11394 case VKI_VT_RELDISP:
11395 case VKI_VT_ACTIVATE:
11396 case VKI_VT_WAITACTIVE:
11397 case VKI_VT_DISALLOCATE:
11398 break;
11399 case VKI_VT_RESIZE:
11400 break;
11401 case VKI_VT_RESIZEX:
11402 break;
11403 case VKI_VT_LOCKSWITCH:
11404 case VKI_VT_UNLOCKSWITCH:
11405 break;
11407 case VKI_USBDEVFS_CONTROL:
11408 if ( ARG3 ) {
11409 struct vki_usbdevfs_ctrltransfer *vkuc =
11410 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11411 if (vkuc->bRequestType & 0x80)
11412 POST_MEM_WRITE((Addr)vkuc->data, RES);
11414 break;
11415 case VKI_USBDEVFS_BULK:
11416 if ( ARG3 ) {
11417 struct vki_usbdevfs_bulktransfer *vkub =
11418 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11419 if (vkub->ep & 0x80)
11420 POST_MEM_WRITE((Addr)vkub->data, RES);
11422 break;
11423 case VKI_USBDEVFS_GETDRIVER:
11424 if ( ARG3 ) {
11425 struct vki_usbdevfs_getdriver *vkugd =
11426 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11427 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11429 break;
11430 case VKI_USBDEVFS_REAPURB:
11431 case VKI_USBDEVFS_REAPURBNDELAY:
11432 if ( ARG3 ) {
11433 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11434 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11435 if (!*vkuu)
11436 break;
11437 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11438 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11439 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11440 if (vkusp->bRequestType & 0x80)
11441 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11442 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11443 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11444 char *bp = (*vkuu)->buffer;
11445 int i;
11446 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11447 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11448 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11449 if ((*vkuu)->endpoint & 0x80)
11450 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11451 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11453 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11454 } else {
11455 if ((*vkuu)->endpoint & 0x80)
11456 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11457 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11460 break;
11461 case VKI_USBDEVFS_CONNECTINFO:
11462 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11463 break;
11464 case VKI_USBDEVFS_IOCTL:
11465 if ( ARG3 ) {
11466 struct vki_usbdevfs_ioctl *vkui =
11467 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11468 UInt dir2, size2;
11469 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11470 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11471 if (size2 > 0) {
11472 if (dir2 & _VKI_IOC_READ)
11473 POST_MEM_WRITE((Addr)vkui->data, size2);
11476 break;
11478 /* I2C (/dev/i2c-*) ioctls */
11479 case VKI_I2C_SLAVE:
11480 case VKI_I2C_SLAVE_FORCE:
11481 case VKI_I2C_TENBIT:
11482 case VKI_I2C_PEC:
11483 break;
11484 case VKI_I2C_FUNCS:
11485 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11486 break;
11487 case VKI_I2C_RDWR:
11488 if ( ARG3 ) {
11489 struct vki_i2c_rdwr_ioctl_data *vkui =
11490 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11491 UInt i;
11492 for (i=0; i < vkui->nmsgs; i++) {
11493 struct vki_i2c_msg *msg = vkui->msgs + i;
11494 if (msg->flags & VKI_I2C_M_RD)
11495 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11498 break;
11499 case VKI_I2C_SMBUS:
11500 if ( ARG3 ) {
11501 struct vki_i2c_smbus_ioctl_data *vkis
11502 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11503 /* i2c_smbus_write_quick hides its value in read_write, so
11504 this variable can have a different meaning */
11505 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11506 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11507 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11508 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11509 UInt size;
11510 switch(vkis->size) {
11511 case VKI_I2C_SMBUS_BYTE:
11512 case VKI_I2C_SMBUS_BYTE_DATA:
11513 size = 1;
11514 break;
11515 case VKI_I2C_SMBUS_WORD_DATA:
11516 case VKI_I2C_SMBUS_PROC_CALL:
11517 size = 2;
11518 break;
11519 case VKI_I2C_SMBUS_BLOCK_DATA:
11520 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11521 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11522 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11523 size = 1 + vkis->data->block[0];
11524 break;
11525 default:
11526 size = 0;
11528 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11532 break;
11534 /* Wireless extensions ioctls */
11535 case VKI_SIOCSIWCOMMIT:
11536 case VKI_SIOCSIWNWID:
11537 case VKI_SIOCSIWFREQ:
11538 case VKI_SIOCSIWMODE:
11539 case VKI_SIOCSIWSENS:
11540 case VKI_SIOCSIWRANGE:
11541 case VKI_SIOCSIWPRIV:
11542 case VKI_SIOCSIWSTATS:
11543 case VKI_SIOCSIWSPY:
11544 case VKI_SIOCSIWTHRSPY:
11545 case VKI_SIOCSIWAP:
11546 case VKI_SIOCSIWSCAN:
11547 case VKI_SIOCSIWESSID:
11548 case VKI_SIOCSIWRATE:
11549 case VKI_SIOCSIWNICKN:
11550 case VKI_SIOCSIWRTS:
11551 case VKI_SIOCSIWFRAG:
11552 case VKI_SIOCSIWTXPOW:
11553 case VKI_SIOCSIWRETRY:
11554 case VKI_SIOCSIWENCODE:
11555 case VKI_SIOCSIWPOWER:
11556 case VKI_SIOCSIWGENIE:
11557 case VKI_SIOCSIWMLME:
11558 case VKI_SIOCSIWAUTH:
11559 case VKI_SIOCSIWENCODEEXT:
11560 case VKI_SIOCSIWPMKSA:
11561 break;
11562 case VKI_SIOCGIWNAME:
11563 if (ARG3) {
11564 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11565 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11567 break;
11568 case VKI_SIOCGIWNWID:
11569 case VKI_SIOCGIWSENS:
11570 case VKI_SIOCGIWRATE:
11571 case VKI_SIOCGIWRTS:
11572 case VKI_SIOCGIWFRAG:
11573 case VKI_SIOCGIWTXPOW:
11574 case VKI_SIOCGIWRETRY:
11575 case VKI_SIOCGIWPOWER:
11576 case VKI_SIOCGIWAUTH:
11577 if (ARG3) {
11578 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11579 sizeof(struct vki_iw_param));
11581 break;
11582 case VKI_SIOCGIWFREQ:
11583 if (ARG3) {
11584 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11585 sizeof(struct vki_iw_freq));
11587 break;
11588 case VKI_SIOCGIWMODE:
11589 if (ARG3) {
11590 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11591 sizeof(__vki_u32));
11593 break;
11594 case VKI_SIOCGIWRANGE:
11595 case VKI_SIOCGIWPRIV:
11596 case VKI_SIOCGIWSTATS:
11597 case VKI_SIOCGIWSPY:
11598 case VKI_SIOCGIWTHRSPY:
11599 case VKI_SIOCGIWAPLIST:
11600 case VKI_SIOCGIWSCAN:
11601 case VKI_SIOCGIWESSID:
11602 case VKI_SIOCGIWNICKN:
11603 case VKI_SIOCGIWENCODE:
11604 case VKI_SIOCGIWGENIE:
11605 case VKI_SIOCGIWENCODEEXT:
11606 if (ARG3) {
11607 struct vki_iw_point* point;
11608 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11609 POST_MEM_WRITE((Addr)point->pointer, point->length);
11611 break;
11612 case VKI_SIOCGIWAP:
11613 if (ARG3) {
11614 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11615 sizeof(struct vki_sockaddr));
11617 break;
11619 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11620 || defined(VGPV_mips32_linux_android) \
11621 || defined(VGPV_arm64_linux_android)
11622 /* ashmem */
11623 case VKI_ASHMEM_GET_SIZE:
11624 case VKI_ASHMEM_SET_SIZE:
11625 case VKI_ASHMEM_GET_PROT_MASK:
11626 case VKI_ASHMEM_SET_PROT_MASK:
11627 case VKI_ASHMEM_GET_PIN_STATUS:
11628 case VKI_ASHMEM_PURGE_ALL_CACHES:
11629 case VKI_ASHMEM_SET_NAME:
11630 case VKI_ASHMEM_PIN:
11631 case VKI_ASHMEM_UNPIN:
11632 break;
11633 case VKI_ASHMEM_GET_NAME:
11634 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11635 break;
11637 /* binder */
11638 case VKI_BINDER_WRITE_READ:
11639 if (ARG3) {
11640 struct vki_binder_write_read* bwr
11641 = (struct vki_binder_write_read*)(Addr)ARG3;
11642 POST_FIELD_WRITE(bwr->write_consumed);
11643 POST_FIELD_WRITE(bwr->read_consumed);
11645 if (bwr->read_size)
11646 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11648 break;
11650 case VKI_BINDER_SET_IDLE_TIMEOUT:
11651 case VKI_BINDER_SET_MAX_THREADS:
11652 case VKI_BINDER_SET_IDLE_PRIORITY:
11653 case VKI_BINDER_SET_CONTEXT_MGR:
11654 case VKI_BINDER_THREAD_EXIT:
11655 break;
11656 case VKI_BINDER_VERSION:
11657 if (ARG3) {
11658 struct vki_binder_version* bv =
11659 (struct vki_binder_version*)(Addr)ARG3;
11660 POST_FIELD_WRITE(bv->protocol_version);
11662 break;
11663 # endif /* defined(VGPV_*_linux_android) */
11665 case VKI_HCIGETDEVLIST:
11666 if (ARG3) {
11667 struct vki_hci_dev_list_req* dlr =
11668 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11669 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11670 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11672 break;
11674 case VKI_HCIINQUIRY:
11675 if (ARG3) {
11676 struct vki_hci_inquiry_req* ir =
11677 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11678 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11679 ir->num_rsp * sizeof(struct vki_inquiry_info));
11681 break;
11683 case VKI_DRM_IOCTL_VERSION:
11684 if (ARG3) {
11685 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11686 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11687 const vki_size_t orig_name_len = info->orig->name_len;
11688 const vki_size_t orig_date_len = info->orig->date_len;
11689 const vki_size_t orig_desc_len = info->orig->desc_len;
11690 *info->orig = info->data;
11691 ARG3 = (Addr)info->orig;
11692 data = info->orig;
11693 VG_(free)(info);
11694 if (SUCCESS) {
11695 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11696 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11697 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11698 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11699 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11700 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11701 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11702 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11703 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11706 break;
11707 case VKI_DRM_IOCTL_GET_UNIQUE:
11708 if (ARG3) {
11709 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11710 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11712 break;
11713 case VKI_DRM_IOCTL_GET_MAGIC:
11714 if (ARG3) {
11715 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11716 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11718 break;
11719 case VKI_DRM_IOCTL_WAIT_VBLANK:
11720 if (ARG3) {
11721 union vki_drm_wait_vblank *data =
11722 (union vki_drm_wait_vblank *)(Addr)ARG3;
11723 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11725 break;
11726 case VKI_DRM_IOCTL_GEM_FLINK:
11727 if (ARG3) {
11728 struct vki_drm_gem_flink *data =
11729 (struct vki_drm_gem_flink *)(Addr)ARG3;
11730 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11732 break;
11733 case VKI_DRM_IOCTL_GEM_OPEN:
11734 if (ARG3) {
11735 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11736 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11737 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11739 break;
11740 case VKI_DRM_IOCTL_I915_GETPARAM:
11741 if (ARG3) {
11742 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11743 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11745 break;
11746 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11747 if (ARG3) {
11748 struct vki_drm_i915_gem_busy *data =
11749 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11750 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11752 break;
11753 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11754 if (ARG3) {
11755 struct vki_drm_i915_gem_create *data =
11756 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11757 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11759 break;
11760 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11761 if (ARG3) {
11762 struct vki_drm_i915_gem_pread *data =
11763 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11764 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11766 break;
11767 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11768 if (ARG3) {
11769 struct vki_drm_i915_gem_mmap_v1 *data =
11770 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11771 Addr addr = data->addr_ptr;
11772 SizeT size = data->size;
11773 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11774 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11775 ML_(notify_core_and_tool_of_mmap)(addr, size,
11776 VKI_PROT_READ | VKI_PROT_WRITE,
11777 VKI_MAP_ANONYMOUS, -1, 0 );
11778 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11780 break;
11781 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11782 if (ARG3) {
11783 struct vki_drm_i915_gem_mmap *data =
11784 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11785 Addr addr = data->addr_ptr;
11786 SizeT size = data->size;
11787 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11788 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11789 ML_(notify_core_and_tool_of_mmap)(addr, size,
11790 VKI_PROT_READ | VKI_PROT_WRITE,
11791 VKI_MAP_ANONYMOUS, -1, 0 );
11792 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11794 break;
11795 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11796 if (ARG3) {
11797 struct vki_drm_i915_gem_mmap_gtt *data =
11798 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11799 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11801 break;
11802 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11803 if (ARG3) {
11804 struct vki_drm_i915_gem_set_tiling *data =
11805 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11806 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11807 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11808 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11810 break;
11811 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11812 if (ARG3) {
11813 struct vki_drm_i915_gem_get_tiling *data =
11814 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11815 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11816 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11818 break;
11819 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11820 if (ARG3) {
11821 struct vki_drm_i915_gem_get_aperture *data =
11822 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11823 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11824 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11826 break;
11828 case VKI_DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD:
11829 if (ARG3) {
11830 struct vki_drm_syncobj_handle *data =
11831 (struct vki_drm_syncobj_handle *)(Addr)ARG3;
11832 if (VG_(clo_track_fds))
11833 ML_(record_fd_open_nameless) (tid, data->fd);
11835 break;
11837 case VKI_DRM_IOCTL_PRIME_HANDLE_TO_FD:
11838 if (ARG3) {
11839 struct vki_drm_prime_handle *data =
11840 (struct vki_drm_prime_handle *)(Addr)ARG3;
11841 if (VG_(clo_track_fds))
11842 ML_(record_fd_open_nameless) (tid, data->fd);
11844 break;
11846 case VKI_DRM_IOCTL_MODE_CREATE_LEASE:
11847 if (ARG3) {
11848 struct vki_drm_mode_create_lease *data =
11849 (struct vki_drm_mode_create_lease*)(Addr)ARG3;
11850 if (VG_(clo_track_fds))
11851 ML_(record_fd_open_nameless) (tid, data->fd);
11853 break;
11855 /* KVM ioctls that only write the system call return value */
11856 case VKI_KVM_GET_API_VERSION:
11857 case VKI_KVM_CREATE_VM:
11858 case VKI_KVM_CHECK_EXTENSION:
11859 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11860 case VKI_KVM_S390_ENABLE_SIE:
11861 case VKI_KVM_CREATE_VCPU:
11862 case VKI_KVM_SET_TSS_ADDR:
11863 case VKI_KVM_CREATE_IRQCHIP:
11864 case VKI_KVM_RUN:
11865 case VKI_KVM_S390_INITIAL_RESET:
11866 case VKI_KVM_KVMCLOCK_CTRL:
11867 break;
11869 case VKI_KVM_S390_MEM_OP: {
11870 struct vki_kvm_s390_mem_op *args =
11871 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11872 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11873 break;
11874 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11875 POST_MEM_WRITE((Addr)args->buf, args->size);
11877 break;
11879 #ifdef ENABLE_XEN
11880 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11881 SyscallArgs harrghs;
11882 struct vki_xen_privcmd_hypercall *args =
11883 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11885 if (!args)
11886 break;
11888 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11889 harrghs.sysno = args->op;
11890 harrghs.arg1 = args->arg[0];
11891 harrghs.arg2 = args->arg[1];
11892 harrghs.arg3 = args->arg[2];
11893 harrghs.arg4 = args->arg[3];
11894 harrghs.arg5 = args->arg[4];
11895 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11897 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11899 break;
11901 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11902 break;
11903 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11904 struct vki_xen_privcmd_mmapbatch *args =
11905 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11906 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11908 break;
11909 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11910 struct vki_xen_privcmd_mmapbatch_v2 *args =
11911 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11912 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11914 break;
11916 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11917 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11918 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11919 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11920 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11921 case VKI_XEN_IOCTL_EVTCHN_RESET:
11922 /* No output */
11923 break;
11924 #endif
11926 /* Lustre */
11927 case VKI_OBD_IOC_FID2PATH: {
11928 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11929 POST_FIELD_WRITE(args->gf_recno);
11930 POST_FIELD_WRITE(args->gf_linkno);
11931 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11932 break;
11935 case VKI_LL_IOC_PATH2FID:
11936 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11937 break;
11939 case VKI_LL_IOC_GETPARENT: {
11940 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11941 POST_FIELD_WRITE(gp->gp_fid);
11942 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11943 break;
11946 /* V4L2 */
11947 case VKI_V4L2_S_FMT:
11948 case VKI_V4L2_TRY_FMT:
11949 case VKI_V4L2_REQBUFS:
11950 case VKI_V4L2_OVERLAY:
11951 case VKI_V4L2_STREAMON:
11952 case VKI_V4L2_STREAMOFF:
11953 case VKI_V4L2_S_PARM:
11954 case VKI_V4L2_S_STD:
11955 case VKI_V4L2_S_FREQUENCY:
11956 case VKI_V4L2_S_CTRL:
11957 case VKI_V4L2_S_TUNER:
11958 case VKI_V4L2_S_AUDIO:
11959 case VKI_V4L2_S_INPUT:
11960 case VKI_V4L2_S_EDID:
11961 case VKI_V4L2_S_OUTPUT:
11962 case VKI_V4L2_S_AUDOUT:
11963 case VKI_V4L2_S_MODULATOR:
11964 case VKI_V4L2_S_JPEGCOMP:
11965 case VKI_V4L2_S_CROP:
11966 case VKI_V4L2_S_PRIORITY:
11967 case VKI_V4L2_S_HW_FREQ_SEEK:
11968 case VKI_V4L2_S_DV_TIMINGS:
11969 case VKI_V4L2_SUBSCRIBE_EVENT:
11970 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11971 case VKI_V4L2_PREPARE_BUF:
11972 break;
11973 case VKI_V4L2_QUERYCAP: {
11974 struct vki_v4l2_capability *data =
11975 (struct vki_v4l2_capability *)(Addr)ARG3;
11976 POST_MEM_WRITE((Addr)data, sizeof(*data));
11977 break;
11979 case VKI_V4L2_ENUM_FMT: {
11980 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11981 POST_FIELD_WRITE(data->flags);
11982 POST_FIELD_WRITE(data->description);
11983 POST_FIELD_WRITE(data->pixelformat);
11984 POST_FIELD_WRITE(data->reserved);
11985 break;
11987 case VKI_V4L2_G_FMT: {
11988 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11989 switch (data->type) {
11990 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11991 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11992 POST_FIELD_WRITE(data->fmt.pix);
11993 break;
11994 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11995 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11996 POST_FIELD_WRITE(data->fmt.vbi);
11997 break;
11998 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11999 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
12000 POST_FIELD_WRITE(data->fmt.sliced);
12001 break;
12002 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
12003 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
12004 POST_FIELD_WRITE(data->fmt.win);
12005 break;
12006 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
12007 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
12008 POST_FIELD_WRITE(data->fmt.pix_mp);
12009 break;
12010 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
12011 POST_FIELD_WRITE(data->fmt.sdr);
12012 break;
12014 break;
12016 case VKI_V4L2_QUERYBUF: {
12017 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
12018 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
12019 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
12020 unsigned i;
12022 for (i = 0; i < data->length; i++) {
12023 POST_FIELD_WRITE(data->m.planes[i].bytesused);
12024 POST_FIELD_WRITE(data->m.planes[i].length);
12025 POST_FIELD_WRITE(data->m.planes[i].m);
12026 POST_FIELD_WRITE(data->m.planes[i].data_offset);
12027 POST_FIELD_WRITE(data->m.planes[i].reserved);
12029 } else {
12030 POST_FIELD_WRITE(data->m);
12031 POST_FIELD_WRITE(data->length);
12033 POST_FIELD_WRITE(data->bytesused);
12034 POST_FIELD_WRITE(data->flags);
12035 POST_FIELD_WRITE(data->field);
12036 POST_FIELD_WRITE(data->timestamp);
12037 POST_FIELD_WRITE(data->timecode);
12038 POST_FIELD_WRITE(data->sequence);
12039 POST_FIELD_WRITE(data->memory);
12040 POST_FIELD_WRITE(data->sequence);
12041 break;
12043 case VKI_V4L2_G_FBUF: {
12044 struct vki_v4l2_framebuffer *data =
12045 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
12046 POST_MEM_WRITE((Addr)data, sizeof(*data));
12047 break;
12049 case VKI_V4L2_S_FBUF: {
12050 struct vki_v4l2_framebuffer *data =
12051 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
12052 POST_FIELD_WRITE(data->capability);
12053 POST_FIELD_WRITE(data->flags);
12054 POST_FIELD_WRITE(data->fmt);
12055 break;
12057 case VKI_V4L2_QBUF: {
12058 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
12060 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
12061 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
12062 unsigned i;
12064 for (i = 0; i < data->length; i++) {
12065 POST_FIELD_WRITE(data->m.planes[i].length);
12066 if (data->memory == VKI_V4L2_MEMORY_MMAP)
12067 POST_FIELD_WRITE(data->m.planes[i].m);
12069 } else {
12070 if (data->memory == VKI_V4L2_MEMORY_MMAP)
12071 POST_FIELD_WRITE(data->m);
12072 POST_FIELD_WRITE(data->length);
12074 break;
12076 case VKI_V4L2_EXPBUF: {
12077 struct vki_v4l2_exportbuffer *data =
12078 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
12079 POST_FIELD_WRITE(data->fd);
12080 break;
12082 case VKI_V4L2_DQBUF: {
12083 struct vki_v4l2_buffer *data =
12084 (struct vki_v4l2_buffer *)(Addr)ARG3;
12085 POST_FIELD_WRITE(data->index);
12086 POST_FIELD_WRITE(data->bytesused);
12087 POST_FIELD_WRITE(data->field);
12088 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
12089 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
12090 unsigned i;
12092 for (i = 0; i < data->length; i++) {
12093 POST_FIELD_WRITE(data->m.planes[i].bytesused);
12094 POST_FIELD_WRITE(data->m.planes[i].data_offset);
12095 POST_FIELD_WRITE(data->m.planes[i].length);
12096 POST_FIELD_WRITE(data->m.planes[i].m);
12098 } else {
12099 POST_FIELD_WRITE(data->m);
12100 POST_FIELD_WRITE(data->length);
12101 POST_FIELD_WRITE(data->bytesused);
12102 POST_FIELD_WRITE(data->field);
12104 POST_FIELD_WRITE(data->timestamp);
12105 POST_FIELD_WRITE(data->timecode);
12106 POST_FIELD_WRITE(data->sequence);
12107 break;
12109 case VKI_V4L2_G_PARM: {
12110 struct vki_v4l2_streamparm *data =
12111 (struct vki_v4l2_streamparm *)(Addr)ARG3;
12112 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
12113 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
12114 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
12115 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
12117 if (is_output)
12118 POST_MEM_WRITE((Addr)&data->parm.output,
12119 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
12120 else
12121 POST_MEM_WRITE((Addr)&data->parm.capture,
12122 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
12123 break;
12125 case VKI_V4L2_G_STD: {
12126 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
12127 POST_MEM_WRITE((Addr)data, sizeof(*data));
12128 break;
12130 case VKI_V4L2_ENUMSTD: {
12131 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
12132 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
12133 break;
12135 case VKI_V4L2_ENUMINPUT: {
12136 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
12137 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
12138 break;
12140 case VKI_V4L2_G_CTRL: {
12141 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
12142 POST_FIELD_WRITE(data->value);
12143 break;
12145 case VKI_V4L2_G_TUNER: {
12146 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
12147 POST_MEM_WRITE((Addr)data->name,
12148 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12149 break;
12151 case VKI_V4L2_G_AUDIO: {
12152 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
12153 POST_MEM_WRITE((Addr)data,
12154 sizeof(*data) - sizeof(data->reserved));
12155 break;
12157 case VKI_V4L2_QUERYCTRL: {
12158 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
12159 POST_MEM_WRITE((Addr)&data->type,
12160 sizeof(*data) - sizeof(data->id));
12161 break;
12163 case VKI_V4L2_QUERYMENU: {
12164 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
12165 POST_MEM_WRITE((Addr)data->name,
12166 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
12167 break;
12169 case VKI_V4L2_G_INPUT: {
12170 int *data = (int *)(Addr)ARG3;
12171 POST_MEM_WRITE((Addr)data, sizeof(*data));
12172 break;
12174 case VKI_V4L2_G_EDID: {
12175 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
12176 if (data->blocks && data->edid)
12177 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
12178 break;
12180 case VKI_V4L2_G_OUTPUT: {
12181 int *data = (int *)(Addr)ARG3;
12182 POST_MEM_WRITE((Addr)data, sizeof(*data));
12183 break;
12185 case VKI_V4L2_ENUMOUTPUT: {
12186 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
12187 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
12188 break;
12190 case VKI_V4L2_G_AUDOUT: {
12191 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
12192 POST_MEM_WRITE((Addr)data,
12193 sizeof(*data) - sizeof(data->reserved));
12194 break;
12196 case VKI_V4L2_G_MODULATOR: {
12197 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
12198 POST_MEM_WRITE((Addr)data->name,
12199 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12200 break;
12202 case VKI_V4L2_G_FREQUENCY: {
12203 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
12204 POST_FIELD_WRITE(data->type);
12205 POST_FIELD_WRITE(data->frequency);
12206 break;
12208 case VKI_V4L2_CROPCAP: {
12209 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
12210 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
12211 break;
12213 case VKI_V4L2_G_CROP: {
12214 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
12215 POST_FIELD_WRITE(data->c);
12216 break;
12218 case VKI_V4L2_G_JPEGCOMP: {
12219 struct vki_v4l2_jpegcompression *data =
12220 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
12221 POST_MEM_WRITE((Addr)data, sizeof(*data));
12222 break;
12224 case VKI_V4L2_QUERYSTD: {
12225 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
12226 POST_MEM_WRITE((Addr)data, sizeof(*data));
12227 break;
12229 case VKI_V4L2_ENUMAUDIO: {
12230 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
12231 POST_MEM_WRITE((Addr)data->name,
12232 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12233 break;
12235 case VKI_V4L2_ENUMAUDOUT: {
12236 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
12237 POST_MEM_WRITE((Addr)data->name,
12238 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12239 break;
12241 case VKI_V4L2_G_PRIORITY: {
12242 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
12243 POST_MEM_WRITE((Addr)data, sizeof(*data));
12244 break;
12246 case VKI_V4L2_G_SLICED_VBI_CAP: {
12247 struct vki_v4l2_sliced_vbi_cap *data =
12248 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
12249 POST_MEM_WRITE((Addr)data,
12250 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
12251 break;
12253 case VKI_V4L2_G_EXT_CTRLS: {
12254 struct vki_v4l2_ext_controls *data =
12255 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12256 if (data->count) {
12257 unsigned i;
12259 for (i = 0; i < data->count; i++) {
12260 if (data->controls[i].size)
12261 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
12262 else
12263 POST_FIELD_WRITE(data->controls[i].value64);
12266 POST_FIELD_WRITE(data->error_idx);
12267 break;
12269 case VKI_V4L2_S_EXT_CTRLS: {
12270 struct vki_v4l2_ext_controls *data =
12271 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12272 POST_FIELD_WRITE(data->error_idx);
12273 break;
12275 case VKI_V4L2_TRY_EXT_CTRLS: {
12276 struct vki_v4l2_ext_controls *data =
12277 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12278 POST_FIELD_WRITE(data->error_idx);
12279 break;
12281 case VKI_V4L2_ENUM_FRAMESIZES: {
12282 struct vki_v4l2_frmsizeenum *data =
12283 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
12284 POST_FIELD_WRITE(data->type);
12285 POST_FIELD_WRITE(data->stepwise);
12286 break;
12288 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
12289 struct vki_v4l2_frmivalenum *data =
12290 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
12291 POST_FIELD_WRITE(data->type);
12292 POST_FIELD_WRITE(data->stepwise);
12293 break;
12295 case VKI_V4L2_G_ENC_INDEX: {
12296 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
12297 POST_MEM_WRITE((Addr)data, sizeof(*data));
12298 break;
12300 case VKI_V4L2_ENCODER_CMD: {
12301 struct vki_v4l2_encoder_cmd *data =
12302 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12303 POST_FIELD_WRITE(data->flags);
12304 break;
12306 case VKI_V4L2_TRY_ENCODER_CMD: {
12307 struct vki_v4l2_encoder_cmd *data =
12308 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12309 POST_FIELD_WRITE(data->flags);
12310 break;
12312 case VKI_V4L2_DBG_S_REGISTER: {
12313 struct vki_v4l2_dbg_register *data =
12314 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12315 POST_FIELD_WRITE(data->size);
12316 break;
12318 case VKI_V4L2_DBG_G_REGISTER: {
12319 struct vki_v4l2_dbg_register *data =
12320 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12321 POST_FIELD_WRITE(data->val);
12322 POST_FIELD_WRITE(data->size);
12323 break;
12325 case VKI_V4L2_G_DV_TIMINGS: {
12326 struct vki_v4l2_dv_timings *data =
12327 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12328 POST_MEM_WRITE((Addr)data, sizeof(*data));
12329 break;
12331 case VKI_V4L2_DQEVENT: {
12332 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
12333 POST_MEM_WRITE((Addr)data, sizeof(*data));
12334 break;
12336 case VKI_V4L2_CREATE_BUFS: {
12337 struct vki_v4l2_create_buffers *data =
12338 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
12339 POST_FIELD_WRITE(data->index);
12340 break;
12342 case VKI_V4L2_G_SELECTION: {
12343 struct vki_v4l2_selection *data =
12344 (struct vki_v4l2_selection *)(Addr)ARG3;
12345 POST_FIELD_WRITE(data->r);
12346 break;
12348 case VKI_V4L2_S_SELECTION: {
12349 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
12350 POST_FIELD_WRITE(data->r);
12351 break;
12353 case VKI_V4L2_DECODER_CMD: {
12354 struct vki_v4l2_decoder_cmd *data =
12355 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12356 POST_FIELD_WRITE(data->flags);
12357 break;
12359 case VKI_V4L2_TRY_DECODER_CMD: {
12360 struct vki_v4l2_decoder_cmd *data =
12361 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12362 POST_FIELD_WRITE(data->flags);
12363 break;
12365 case VKI_V4L2_ENUM_DV_TIMINGS: {
12366 struct vki_v4l2_enum_dv_timings *data =
12367 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
12368 POST_FIELD_WRITE(data->timings);
12369 break;
12371 case VKI_V4L2_QUERY_DV_TIMINGS: {
12372 struct vki_v4l2_dv_timings *data =
12373 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12374 POST_MEM_WRITE((Addr)data, sizeof(*data));
12375 break;
12377 case VKI_V4L2_DV_TIMINGS_CAP: {
12378 struct vki_v4l2_dv_timings_cap *data =
12379 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
12380 POST_MEM_WRITE((Addr)data, sizeof(*data));
12381 break;
12383 case VKI_V4L2_ENUM_FREQ_BANDS: {
12384 struct vki_v4l2_frequency_band *data =
12385 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12386 POST_FIELD_WRITE(data->capability);
12387 POST_FIELD_WRITE(data->rangelow);
12388 POST_FIELD_WRITE(data->rangehigh);
12389 POST_FIELD_WRITE(data->modulation);
12390 break;
12392 case VKI_V4L2_DBG_G_CHIP_INFO: {
12393 struct vki_v4l2_dbg_chip_info *data =
12394 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12395 POST_FIELD_WRITE(data->name);
12396 POST_FIELD_WRITE(data->flags);
12397 break;
12399 case VKI_V4L2_QUERY_EXT_CTRL: {
12400 struct vki_v4l2_query_ext_ctrl *data =
12401 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12402 POST_MEM_WRITE((Addr)&data->type,
12403 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12404 break;
12407 case VKI_V4L2_SUBDEV_S_FMT:
12408 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12409 case VKI_V4L2_SUBDEV_S_CROP:
12410 case VKI_V4L2_SUBDEV_S_SELECTION:
12411 break;
12413 case VKI_V4L2_SUBDEV_G_FMT: {
12414 struct vki_v4l2_subdev_format *data =
12415 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12416 POST_FIELD_WRITE(data->format);
12417 break;
12419 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12420 struct vki_v4l2_subdev_frame_interval *data =
12421 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12422 POST_FIELD_WRITE(data->interval);
12423 break;
12425 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12426 struct vki_v4l2_subdev_mbus_code_enum *data =
12427 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12428 POST_FIELD_WRITE(data->code);
12429 break;
12431 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12432 struct vki_v4l2_subdev_frame_size_enum *data =
12433 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12434 POST_FIELD_WRITE(data->min_width);
12435 POST_FIELD_WRITE(data->min_height);
12436 POST_FIELD_WRITE(data->max_width);
12437 POST_FIELD_WRITE(data->max_height);
12438 break;
12440 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12441 struct vki_v4l2_subdev_frame_interval_enum *data =
12442 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12443 POST_FIELD_WRITE(data->interval);
12444 break;
12446 case VKI_V4L2_SUBDEV_G_CROP: {
12447 struct vki_v4l2_subdev_crop *data =
12448 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12449 POST_FIELD_WRITE(data->rect);
12450 break;
12452 case VKI_V4L2_SUBDEV_G_SELECTION: {
12453 struct vki_v4l2_subdev_selection *data =
12454 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12455 POST_FIELD_WRITE(data->r);
12456 break;
12458 case VKI_MEDIA_IOC_DEVICE_INFO: {
12459 struct vki_media_device_info *data =
12460 (struct vki_media_device_info *)(Addr)ARG3;
12461 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12462 break;
12464 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12465 struct vki_media_entity_desc *data =
12466 (struct vki_media_entity_desc *)(Addr)ARG3;
12467 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12468 break;
12470 case VKI_MEDIA_IOC_ENUM_LINKS:
12472 * This ioctl does write to the provided pointers, but it's not
12473 * possible to deduce the size of the array those pointers point to.
12475 break;
12476 case VKI_MEDIA_IOC_SETUP_LINK:
12477 break;
12479 /* Serial */
12480 case VKI_TIOCGSERIAL: {
12481 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12482 POST_MEM_WRITE((Addr)data, sizeof(*data));
12483 break;
12485 case VKI_TIOCSSERIAL:
12486 break;
12488 case VKI_PERF_EVENT_IOC_ENABLE:
12489 case VKI_PERF_EVENT_IOC_DISABLE:
12490 case VKI_PERF_EVENT_IOC_REFRESH:
12491 case VKI_PERF_EVENT_IOC_RESET:
12492 case VKI_PERF_EVENT_IOC_PERIOD:
12493 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12494 case VKI_PERF_EVENT_IOC_SET_FILTER:
12495 case VKI_PERF_EVENT_IOC_SET_BPF:
12496 break;
12498 case VKI_PERF_EVENT_IOC_ID:
12499 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12500 break;
12502 /* Pulse Per Second (PPS) */
12503 case VKI_PPS_GETPARAMS: {
12504 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12505 POST_MEM_WRITE((Addr)data, sizeof(*data));
12506 break;
12508 case VKI_PPS_GETCAP:
12509 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12510 break;
12511 case VKI_PPS_FETCH: {
12512 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12513 POST_FIELD_WRITE(data->info);
12514 break;
12516 case VKI_PPS_SETPARAMS:
12517 case VKI_PPS_KC_BIND:
12518 break;
12520 /* PTP Hardware Clock */
12521 case VKI_PTP_CLOCK_GETCAPS: {
12522 struct vki_ptp_clock_caps *data =
12523 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12524 POST_MEM_WRITE((Addr)data, sizeof(*data));
12525 break;
12527 case VKI_PTP_SYS_OFFSET: {
12528 struct vki_ptp_sys_offset *data =
12529 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12530 POST_MEM_WRITE((Addr)data->ts,
12531 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12532 break;
12534 case VKI_PTP_PIN_GETFUNC: {
12535 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12536 POST_MEM_WRITE((Addr)data, sizeof(*data));
12537 break;
12539 case VKI_PTP_SYS_OFFSET_PRECISE: {
12540 struct vki_ptp_sys_offset_precise *data =
12541 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12542 POST_MEM_WRITE((Addr)data, sizeof(*data));
12543 break;
12545 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12546 struct vki_ptp_sys_offset_extended *data =
12547 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12548 POST_MEM_WRITE((Addr)data->ts,
12549 3 * data->n_samples * sizeof(data->ts[0][0]));
12550 break;
12552 case VKI_PTP_EXTTS_REQUEST:
12553 case VKI_PTP_PEROUT_REQUEST:
12554 case VKI_PTP_ENABLE_PPS:
12555 case VKI_PTP_PIN_SETFUNC:
12556 break;
12558 default:
12559 /* EVIOC* are variable length and return size written on success */
12560 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12561 case VKI_EVIOCGNAME(0):
12562 case VKI_EVIOCGPHYS(0):
12563 case VKI_EVIOCGUNIQ(0):
12564 case VKI_EVIOCGKEY(0):
12565 case VKI_EVIOCGLED(0):
12566 case VKI_EVIOCGSND(0):
12567 case VKI_EVIOCGSW(0):
12568 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12569 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12570 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12571 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12572 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12573 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12574 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12575 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12576 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12577 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12578 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12579 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12580 if (RES > 0)
12581 POST_MEM_WRITE(ARG3, RES);
12582 break;
12583 default:
12584 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12585 break;
12587 break;
12590 post_sys_ioctl__out:
12591 {} /* keep C compilers happy */
12594 /* ---------------------------------------------------------------------
12595 socketcall wrapper helpers
12596 ------------------------------------------------------------------ */
12598 void
12599 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12600 UWord arg0, UWord arg1, UWord arg2,
12601 UWord arg3, UWord arg4 )
12603 /* int getsockopt(int s, int level, int optname,
12604 void *optval, socklen_t *optlen); */
12605 Addr optval_p = arg3;
12606 Addr optlen_p = arg4;
12607 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12608 if (optval_p != (Addr)NULL) {
12609 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12610 "socketcall.getsockopt(optval)",
12611 "socketcall.getsockopt(optlen)" );
12612 if (arg1 == VKI_SOL_SCTP &&
12613 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12614 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12616 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12617 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12618 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12619 (Addr)ga->addrs, address_bytes );
12624 void
12625 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12626 SysRes res,
12627 UWord arg0, UWord arg1, UWord arg2,
12628 UWord arg3, UWord arg4 )
12630 Addr optval_p = arg3;
12631 Addr optlen_p = arg4;
12632 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12633 if (optval_p != (Addr)NULL) {
12634 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12635 "socketcall.getsockopt(optlen_out)" );
12636 if (arg1 == VKI_SOL_SCTP &&
12637 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12638 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12640 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12641 struct vki_sockaddr *a = ga->addrs;
12642 int i;
12643 for (i = 0; i < ga->addr_num; i++) {
12644 int sl = 0;
12645 if (a->sa_family == VKI_AF_INET)
12646 sl = sizeof(struct vki_sockaddr_in);
12647 else if (a->sa_family == VKI_AF_INET6)
12648 sl = sizeof(struct vki_sockaddr_in6);
12649 else {
12650 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12651 "address type %d\n", a->sa_family);
12653 a = (struct vki_sockaddr*)((char*)a + sl);
12655 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12660 void
12661 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12662 UWord arg0, UWord arg1, UWord arg2,
12663 UWord arg3, UWord arg4 )
12665 /* int setsockopt(int s, int level, int optname,
12666 const void *optval, socklen_t optlen); */
12667 Addr optval_p = arg3;
12668 if (optval_p != (Addr)NULL) {
12670 * OK, let's handle at least some setsockopt levels and options
12671 * ourselves, so we don't get false claims of references to
12672 * uninitialized memory (such as padding in structures) and *do*
12673 * check what pointers in the argument point to.
12675 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12677 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12680 * struct sock_fprog has a 16-bit count of instructions,
12681 * followed by a pointer to an array of those instructions.
12682 * There's padding between those two elements.
12684 * So that we don't bogusly complain about the padding bytes,
12685 * we just report that we read len and and filter.
12687 * We then make sure that what filter points to is valid.
12689 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12690 (Addr)&fp->len, sizeof(fp->len) );
12691 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12692 (Addr)&fp->filter, sizeof(fp->filter) );
12694 /* len * sizeof (*filter) */
12695 if (fp->filter != NULL)
12697 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12698 (Addr)(fp->filter),
12699 fp->len * sizeof(*fp->filter) );
12702 else
12704 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12705 arg3, /* optval */
12706 arg4 /* optlen */ );
12711 void
12712 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12713 UWord arg1, UWord arg2, UWord arg3,
12714 UWord arg4, UWord arg5 )
12716 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12717 HChar name[40]; // large enough
12718 UInt i;
12719 for (i = 0; i < arg3; i++) {
12720 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12721 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12722 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12723 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12725 if (arg5)
12726 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12729 void
12730 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12731 UWord arg1, UWord arg2, UWord arg3,
12732 UWord arg4, UWord arg5 )
12734 if (res > 0) {
12735 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12736 HChar name[32]; // large enough
12737 UInt i;
12738 for (i = 0; i < res; i++) {
12739 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12740 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12741 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12746 void
12747 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12748 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12750 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12751 HChar name[40]; // large enough
12752 UInt i;
12753 for (i = 0; i < arg3; i++) {
12754 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12755 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12756 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12757 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12761 void
12762 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12763 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12765 if (res > 0) {
12766 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12767 UInt i;
12768 for (i = 0; i < res; i++) {
12769 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12774 /* ---------------------------------------------------------------------
12775 ptrace wrapper helpers
12776 ------------------------------------------------------------------ */
12778 void
12779 ML_(linux_POST_traceme) ( ThreadId tid )
12781 ThreadState *tst = VG_(get_ThreadState)(tid);
12782 tst->ptrace = VKI_PT_PTRACED;
12785 void
12786 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12788 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12790 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12791 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12792 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12793 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12794 (Addr) iov->iov_base, iov->iov_len);
12798 void
12799 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12801 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12803 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12804 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12805 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12806 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12807 (Addr) iov->iov_base, iov->iov_len);
12811 void
12812 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12814 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12816 /* XXX: The actual amount of data written by the kernel might be
12817 less than iov_len, depending on the regset (arg3). */
12818 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12821 PRE(sys_kcmp)
12823 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12824 SARG1, SARG2, SARG3, ARG4, ARG5);
12825 switch (ARG3) {
12826 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12827 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12828 /* Most of the comparison types don't look at |idx1| or
12829 |idx2|. */
12830 PRE_REG_READ3(long, "kcmp",
12831 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12832 break;
12833 case VKI_KCMP_FILE:
12834 default:
12835 PRE_REG_READ5(long, "kcmp",
12836 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12837 unsigned long, idx1, unsigned long, idx2);
12838 break;
12842 /* ---------------------------------------------------------------------
12843 bpf wrappers
12844 ------------------------------------------------------------------ */
12846 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12848 HChar path[32], buf[1024]; /* large enough */
12849 SysRes sres;
12850 HChar *comp;
12851 Int proc_fd;
12853 *key_size = 0;
12854 *value_size = 0;
12856 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12857 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12858 if (sr_isError(sres))
12859 return False;
12860 proc_fd = sr_Res(sres);
12862 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12863 return False;
12864 VG_(close)(proc_fd);
12866 comp = VG_(strstr)(buf, "key_size:");
12867 if (comp)
12868 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12870 comp = VG_(strstr)(buf, "value_size:");
12871 if (comp)
12872 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12874 return (*key_size && *value_size);
12878 * From a file descriptor for an eBPF object, try to determine the size of the
12879 * struct that will be written, i.e. determine if object is a map or a program.
12880 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12881 * search for strings "prog_type" or "map_type".
12883 static UInt bpf_obj_get_info_size(Int fd)
12885 HChar path[32], buf[1024]; /* large enough */
12886 SysRes sres;
12887 Int proc_fd;
12889 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12890 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12891 if (sr_isError(sres))
12892 return 0;
12893 proc_fd = sr_Res(sres);
12895 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12896 return 0;
12897 VG_(close)(proc_fd);
12899 if (VG_(strstr)(buf, "prog_type:"))
12900 return sizeof(struct vki_bpf_prog_info);
12902 if (VG_(strstr)(buf, "map_type:"))
12903 return sizeof(struct vki_bpf_map_info);
12905 return 0;
12908 PRE(sys_bpf)
12910 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12911 UInt res, key_size, value_size;
12913 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12914 (Word)ARG1, ARG2, ARG3);
12915 PRE_REG_READ3(long, "bpf",
12916 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12917 switch (ARG1) {
12918 case VKI_BPF_PROG_GET_NEXT_ID:
12919 case VKI_BPF_MAP_GET_NEXT_ID:
12920 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12921 break;
12922 case VKI_BPF_PROG_GET_FD_BY_ID:
12923 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12924 break;
12925 case VKI_BPF_MAP_GET_FD_BY_ID:
12926 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12927 break;
12928 case VKI_BPF_BTF_GET_FD_BY_ID:
12929 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12930 break;
12931 case VKI_BPF_MAP_CREATE:
12932 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12933 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12934 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12935 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12936 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12937 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12938 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12939 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12940 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12941 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12942 switch (attr->map_type) {
12943 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12944 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12945 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12946 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12947 SET_STATUS_Failure(VKI_EBADF);
12948 break;
12949 case VKI_BPF_MAP_TYPE_ARRAY:
12950 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12951 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12952 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12953 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12954 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12955 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12956 SET_STATUS_Failure(VKI_EBADF);
12957 break;
12961 break;
12962 case VKI_BPF_MAP_TYPE_UNSPEC:
12963 case VKI_BPF_MAP_TYPE_HASH:
12964 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12965 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12966 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12967 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12968 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12969 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12970 case VKI_BPF_MAP_TYPE_LRU_HASH:
12971 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12972 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12973 case VKI_BPF_MAP_TYPE_DEVMAP:
12974 case VKI_BPF_MAP_TYPE_SOCKMAP:
12975 case VKI_BPF_MAP_TYPE_CPUMAP:
12976 case VKI_BPF_MAP_TYPE_XSKMAP:
12977 case VKI_BPF_MAP_TYPE_SOCKHASH:
12978 default:
12979 break;
12981 break;
12982 case VKI_BPF_MAP_LOOKUP_ELEM:
12983 /* Perform a lookup on an eBPF map. Read key, write value. */
12984 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12985 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12986 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12987 if (ML_(safe_to_deref)(attr, ARG3)) {
12988 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12989 SET_STATUS_Failure(VKI_EBADF);
12990 break;
12992 /* Get size of key and value for this map. */
12993 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12994 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12995 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12998 break;
12999 case VKI_BPF_MAP_UPDATE_ELEM:
13000 /* Add or update a map element in kernel. Read key, read value. */
13001 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
13002 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
13003 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13004 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
13005 if (ML_(safe_to_deref)(attr, ARG3)) {
13006 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
13007 SET_STATUS_Failure(VKI_EBADF);
13008 break;
13010 /* Get size of key and value for this map. */
13011 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
13012 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
13013 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
13016 break;
13017 case VKI_BPF_MAP_DELETE_ELEM:
13018 /* Delete a map element in kernel. Read key from user space. */
13019 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
13020 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13021 if (ML_(safe_to_deref)(attr, ARG3)) {
13022 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
13023 SET_STATUS_Failure(VKI_EBADF);
13024 break;
13026 /* Get size of key for this map. */
13027 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13028 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
13030 break;
13031 case VKI_BPF_MAP_GET_NEXT_KEY:
13032 /* From a key, get next key for the map. Read key, write next key. */
13033 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
13034 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
13035 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13036 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
13037 if (ML_(safe_to_deref)(attr, ARG3)) {
13038 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
13039 SET_STATUS_Failure(VKI_EBADF);
13040 break;
13042 /* Get size of key for this map. */
13043 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
13044 /* see https://bugs.kde.org/show_bug.cgi?id=496571 */
13045 /* Key is null when getting first entry in map. */
13046 if (attr->key) {
13047 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
13049 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
13052 break;
13053 case VKI_BPF_PROG_LOAD:
13054 /* Load a program into the kernel from an array of instructions. */
13055 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
13056 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
13057 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
13058 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
13059 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
13060 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
13061 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
13062 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
13063 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
13064 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
13065 if (ML_(safe_to_deref)(attr, ARG3)) {
13066 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
13067 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
13068 /* Read instructions, license, program name. */
13069 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
13070 attr->insn_cnt * sizeof(struct vki_bpf_insn));
13071 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
13072 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
13073 /* Possibly write up to log_len into user space log buffer. */
13074 if (attr->log_level || attr->log_size || attr->log_buf)
13075 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
13077 break;
13078 case VKI_BPF_OBJ_PIN:
13079 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
13080 /* fall through */
13081 case VKI_BPF_OBJ_GET:
13082 /* Get pinned eBPF program or map. Read path name. */
13083 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
13084 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
13085 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
13086 if (ML_(safe_to_deref)(attr, ARG3)) {
13087 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
13088 SET_STATUS_Failure(VKI_EBADF);
13089 break;
13091 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
13093 break;
13094 case VKI_BPF_PROG_ATTACH:
13095 case VKI_BPF_PROG_DETACH:
13096 /* Detach eBPF program from kernel attach point. */
13097 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
13098 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
13099 if (ML_(safe_to_deref)(attr, ARG3)) {
13100 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
13101 SET_STATUS_Failure(VKI_EBADF);
13102 if (ARG1 == VKI_BPF_PROG_ATTACH ||
13103 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
13104 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
13105 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
13106 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
13107 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
13108 SET_STATUS_Failure(VKI_EBADF);
13111 break;
13112 case VKI_BPF_PROG_TEST_RUN:
13113 /* Test prog. Read data_in, write up to data_size_out to data_out. */
13114 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
13115 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
13116 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
13117 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
13118 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
13119 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
13120 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
13121 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
13122 if (ML_(safe_to_deref)(attr, ARG3)) {
13123 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
13124 SET_STATUS_Failure(VKI_EBADF);
13125 break;
13127 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
13128 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
13129 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
13131 break;
13132 case VKI_BPF_OBJ_GET_INFO_BY_FD:
13133 /* Get info for eBPF map or program. Write info. */
13134 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
13135 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
13136 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
13137 if (ML_(safe_to_deref)(attr, ARG3)) {
13138 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
13139 SET_STATUS_Failure(VKI_EBADF);
13140 break;
13142 /* Get size of struct to write: is object a program or a map? */
13143 res = bpf_obj_get_info_size(attr->info.bpf_fd);
13144 if (res)
13145 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
13146 VG_MIN(attr->info.info_len, res));
13147 else
13148 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
13149 VG_MIN(attr->info.info_len,
13150 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
13151 sizeof(struct vki_bpf_map_info)),
13152 sizeof(struct vki_bpf_btf_info))));
13154 break;
13155 case VKI_BPF_PROG_QUERY:
13157 * Query list of eBPF program attached to cgroup.
13158 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
13160 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
13161 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
13162 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
13163 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13164 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
13165 if (ML_(safe_to_deref)(attr, ARG3)) {
13166 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
13167 SET_STATUS_Failure(VKI_EBADF);
13168 break;
13170 if (attr->query.prog_cnt > 0) {
13171 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
13172 if (attr->query.prog_ids) {
13173 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
13174 attr->query.prog_cnt * sizeof(__vki_u32));
13178 break;
13179 case VKI_BPF_RAW_TRACEPOINT_OPEN:
13180 /* Open raw tracepoint. Read tracepoint name. */
13181 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
13182 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
13183 if (ML_(safe_to_deref)(attr, ARG3)) {
13184 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
13185 "bpf", tid, False)) {
13186 SET_STATUS_Failure(VKI_EBADF);
13187 break;
13189 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
13190 if (attr->raw_tracepoint.name != 0)
13191 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
13192 "bpf(attr->raw_tracepoint.name)");
13194 break;
13195 case VKI_BPF_BTF_LOAD:
13196 /* Load BTF information about a program into the kernel. */
13197 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
13198 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
13199 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
13200 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
13201 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
13202 if (ML_(safe_to_deref)(attr, ARG3)) {
13203 /* Read BTF data. */
13204 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
13205 /* Possibly write up to btf_log_len into user space log buffer. */
13206 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
13207 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
13208 attr->btf_log_buf, attr->btf_log_size);
13210 break;
13211 case VKI_BPF_TASK_FD_QUERY:
13212 /* Get info about the task. Write collected info. */
13213 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
13214 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
13215 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
13216 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
13217 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
13218 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13219 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13220 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13221 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13222 if (ML_(safe_to_deref)(attr, ARG3)) {
13223 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
13224 SET_STATUS_Failure(VKI_EBADF);
13225 break;
13227 if (attr->task_fd_query.buf_len > 0) {
13228 /* Write task or perf event name. */
13229 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
13230 attr->task_fd_query.buf,
13231 attr->task_fd_query.buf_len);
13234 break;
13235 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13236 /* Perform a lookup on an eBPF map. Read key, write value (delete key) */
13237 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
13238 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
13239 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13240 if (ML_(safe_to_deref)(attr, ARG3)) {
13241 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
13242 SET_STATUS_Failure(VKI_EBADF);
13243 break;
13245 /* Get size of key and value for this map. */
13246 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
13247 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
13248 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
13251 break;
13252 case VKI_BPF_MAP_FREEZE:
13253 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13254 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13255 break;
13256 default:
13257 VG_(message)(Vg_DebugMsg,
13258 "WARNING: unhandled eBPF command %lu\n", ARG1);
13259 break;
13263 POST(sys_bpf)
13265 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
13266 UInt key_size, value_size;
13268 vg_assert(SUCCESS);
13270 switch (ARG1) {
13271 case VKI_BPF_PROG_GET_NEXT_ID:
13272 case VKI_BPF_MAP_GET_NEXT_ID:
13273 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
13274 break;
13275 case VKI_BPF_MAP_UPDATE_ELEM:
13276 case VKI_BPF_MAP_DELETE_ELEM:
13277 case VKI_BPF_OBJ_PIN:
13278 case VKI_BPF_PROG_ATTACH:
13279 case VKI_BPF_PROG_DETACH:
13280 break;
13281 /* Following commands have bpf() return a file descriptor. */
13282 case VKI_BPF_MAP_CREATE:
13283 case VKI_BPF_OBJ_GET:
13284 case VKI_BPF_PROG_GET_FD_BY_ID:
13285 case VKI_BPF_MAP_GET_FD_BY_ID:
13286 case VKI_BPF_BTF_GET_FD_BY_ID:
13287 case VKI_BPF_RAW_TRACEPOINT_OPEN:
13288 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13289 VG_(close)(RES);
13290 SET_STATUS_Failure(VKI_EMFILE);
13291 } else {
13292 if (VG_(clo_track_fds))
13293 ML_(record_fd_open_nameless)(tid, RES);
13295 break;
13297 * TODO: Is there a way to pass information between PRE and POST hooks?
13298 * To avoid querying again for the size of keys and values.
13300 case VKI_BPF_MAP_LOOKUP_ELEM:
13301 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13302 POST_MEM_WRITE(attr->value, value_size);
13303 break;
13304 case VKI_BPF_MAP_GET_NEXT_KEY:
13305 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13306 POST_MEM_WRITE(attr->next_key, key_size);
13307 break;
13308 case VKI_BPF_PROG_LOAD:
13309 /* Return a file descriptor for loaded program, write into log_buf. */
13310 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13311 VG_(close)(RES);
13312 SET_STATUS_Failure(VKI_EMFILE);
13313 } else {
13314 if (VG_(clo_track_fds))
13315 ML_(record_fd_open_nameless)(tid, RES);
13317 if (attr->log_level || attr->log_size || attr->log_buf)
13318 POST_MEM_WRITE(attr->log_buf, attr->log_size);
13319 break;
13320 case VKI_BPF_PROG_TEST_RUN:
13321 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
13322 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
13323 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
13324 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
13325 break;
13326 case VKI_BPF_OBJ_GET_INFO_BY_FD:
13327 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
13328 break;
13329 case VKI_BPF_PROG_QUERY:
13330 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
13331 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13332 if (attr->query.prog_ids)
13333 POST_MEM_WRITE(attr->query.prog_ids,
13334 attr->query.prog_cnt * sizeof(__vki_u32));
13335 break;
13336 case VKI_BPF_BTF_LOAD:
13337 /* Return a file descriptor for BTF data, write into btf_log_buf. */
13338 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13339 VG_(close)(RES);
13340 SET_STATUS_Failure(VKI_EMFILE);
13341 } else {
13342 if (VG_(clo_track_fds))
13343 ML_(record_fd_open_nameless)(tid, RES);
13345 if (attr->btf_log_level)
13346 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
13347 break;
13348 case VKI_BPF_TASK_FD_QUERY:
13349 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
13350 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13351 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13352 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13353 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13354 break;
13355 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13356 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13357 POST_MEM_WRITE(attr->value, value_size);
13358 break;
13359 case VKI_BPF_MAP_FREEZE:
13360 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13361 break;
13362 default:
13363 VG_(message)(Vg_DebugMsg,
13364 "WARNING: unhandled eBPF command %lu\n", ARG1);
13365 break;
13369 PRE(sys_copy_file_range)
13371 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
13372 ARG4, ARG5, ARG6);
13374 PRE_REG_READ6(vki_size_t, "copy_file_range",
13375 int, "fd_in",
13376 vki_loff_t *, "off_in",
13377 int, "fd_out",
13378 vki_loff_t *, "off_out",
13379 vki_size_t, "len",
13380 unsigned int, "flags");
13382 /* File descriptors are "specially" tracked by valgrind.
13383 valgrind itself uses some, so make sure someone didn't
13384 put in one of our own... */
13385 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
13386 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
13387 SET_STATUS_Failure( VKI_EBADF );
13388 } else {
13389 /* Now see if the offsets are defined. PRE_MEM_READ will
13390 double check it can dereference them. */
13391 if (ARG2 != 0)
13392 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
13393 if (ARG4 != 0)
13394 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
13398 PRE(sys_pkey_alloc)
13400 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
13402 PRE_REG_READ2(long, "pkey_alloc",
13403 unsigned long, "flags",
13404 unsigned long, "access_rights");
13406 /* The kernel says: pkey_alloc() is always safe to call regardless of
13407 whether or not the operating system supports protection keys. It can be
13408 used in lieu of any other mechanism for detecting pkey support and will
13409 simply fail with the error ENOSPC if the operating system has no pkey
13410 support.
13412 So we simply always return ENOSPC to signal memory protection keys are
13413 not supported under valgrind, unless there are unknown flags, then we
13414 return EINVAL. */
13415 unsigned long pkey_flags = ARG1;
13416 if (pkey_flags != 0)
13417 SET_STATUS_Failure( VKI_EINVAL );
13418 else
13419 SET_STATUS_Failure( VKI_ENOSPC );
13422 PRE(sys_pkey_free)
13424 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13426 PRE_REG_READ1(long, "pkey_free",
13427 unsigned long, "pkey");
13429 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13430 always an error. */
13431 SET_STATUS_Failure( VKI_EINVAL );
13434 PRE(sys_pkey_mprotect)
13436 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13437 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13438 PRE_REG_READ4(long, "pkey_mprotect",
13439 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13440 unsigned long, pkey);
13442 Addr addr = ARG1;
13443 SizeT len = ARG2;
13444 Int prot = ARG3;
13445 Int pkey = ARG4;
13447 /* Since pkey_alloc () can never succeed, see above, any pkey is
13448 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13449 if (pkey != -1)
13450 SET_STATUS_Failure( VKI_EINVAL );
13451 else
13452 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13454 ARG1 = addr;
13455 ARG2 = len;
13456 ARG3 = prot;
13459 POST(sys_pkey_mprotect)
13461 Addr addr = ARG1;
13462 SizeT len = ARG2;
13463 Int prot = ARG3;
13465 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13468 PRE(sys_io_uring_setup)
13470 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13471 ARG1, ARG2);
13472 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13473 struct vki_io_uring_params *, p);
13474 if (ARG2)
13475 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13476 offsetof(struct vki_io_uring_params, sq_off));
13479 POST(sys_io_uring_setup)
13481 vg_assert(SUCCESS);
13482 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13483 VG_(close)(RES);
13484 SET_STATUS_Failure( VKI_EMFILE );
13485 } else {
13486 if (VG_(clo_track_fds))
13487 ML_(record_fd_open_nameless)(tid, RES);
13488 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13489 sizeof(struct vki_io_sqring_offsets) +
13490 sizeof(struct vki_io_cqring_offsets));
13494 PRE(sys_io_uring_enter)
13496 *flags |= SfMayBlock | SfPostOnFail;
13497 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13498 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13499 FMT_REGWORD "u )",
13500 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13501 PRE_REG_READ6(long, "io_uring_enter",
13502 unsigned int, fd, unsigned int, to_submit,
13503 unsigned int, min_complete, unsigned int, flags,
13504 const void *, sig, unsigned long, sigsz);
13505 blocking_syscall_sigmask_pre(tid, (Addr *)&ARG5, ARG6,
13506 "io_uring_enter(sig)",
13507 "syswrap.io_uring_enter.1");
13510 POST(sys_io_uring_enter)
13512 blocking_syscall_sigmask_post((Addr)ARG5, ARG6);
13515 PRE(sys_io_uring_register)
13517 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13518 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13519 PRE_REG_READ4(long, "io_uring_register",
13520 unsigned int, fd, unsigned int, opcode,
13521 void *, arg, unsigned int, nr_args);
13522 switch (ARG2) {
13523 case VKI_IORING_REGISTER_BUFFERS:
13524 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13525 break;
13526 case VKI_IORING_UNREGISTER_BUFFERS:
13527 break;
13528 case VKI_IORING_REGISTER_FILES:
13529 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13530 break;
13531 case VKI_IORING_UNREGISTER_FILES:
13532 break;
13533 case VKI_IORING_REGISTER_EVENTFD:
13534 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13535 break;
13536 case VKI_IORING_UNREGISTER_EVENTFD:
13537 break;
13541 POST(sys_io_uring_register)
13545 PRE(sys_execveat)
13547 PRINT("sys_execveat ( %lu, %#lx(%s), %#lx, %#lx, %lu", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
13548 PRE_REG_READ5(vki_off_t, "execveat",
13549 int, fd, char *, filename, char **, argv, char **, envp, int, flags);
13550 PRE_MEM_RASCIIZ( "execveat(filename)", ARG2);
13552 #if !defined(__NR_execveat)
13553 SET_STATUS_Failure(VKI_ENOSYS);
13554 return;
13555 #endif
13557 const HChar *path = (const HChar*) ARG2;
13558 Addr arg_2 = ARG3;
13559 Addr arg_3 = ARG4;
13560 const HChar *buf;
13561 HChar *abs_path = NULL;
13562 Bool check_at_symlink = False;
13563 Bool check_pathptr = True;
13565 if (ML_(safe_to_deref) (path, 1)) {
13566 /* If pathname is absolute, we'll ignore dirfd
13567 * and just pass the pathname, try to determine
13568 * the absolute path otherwise. */
13569 if (path[0] != '/') {
13570 /* Check dirfd is a valid fd. */
13571 if (!ML_(fd_allowed)(ARG1, "execveat", tid, False)) {
13572 SET_STATUS_Failure( VKI_EBADF );
13573 return;
13575 /* If pathname is empty and AT_EMPTY_PATH is
13576 set then dirfd describes the whole path. */
13577 if (path[0] == '\0') {
13578 if (ARG5 & VKI_AT_EMPTY_PATH) {
13579 if (VG_(resolve_filename)(ARG1, &buf)) {
13580 path = buf;
13581 check_pathptr = False;
13585 else if (ARG1 == VKI_AT_FDCWD) {
13586 check_at_symlink = True;
13587 } else
13588 if (ARG5 & VKI_AT_SYMLINK_NOFOLLOW)
13589 check_at_symlink = True;
13590 else if (VG_(resolve_filename)(ARG1, &buf)) {
13591 abs_path = VG_(malloc)("execveat",
13592 (VG_(strlen)(buf) + 1
13593 + VG_(strlen)(path) + 1));
13594 VG_(sprintf)(abs_path, "%s/%s", buf, path);
13595 path = abs_path;
13596 check_pathptr = False;
13598 else
13599 path = NULL;
13600 if (check_at_symlink) {
13601 struct vg_stat statbuf;
13602 SysRes statres;
13604 statres = VG_(stat)(path, &statbuf);
13605 if (sr_isError(statres) || VKI_S_ISLNK(statbuf.mode)) {
13606 SET_STATUS_Failure( VKI_ELOOP );
13607 return;
13611 } else {
13612 SET_STATUS_Failure(VKI_EFAULT);
13613 return;
13616 handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, EXECVEAT,
13617 check_pathptr);
13619 /* The exec failed, we keep running... cleanup. */
13620 VG_(free)(abs_path);
13625 PRE(sys_close_range)
13627 SysRes res = VG_(mk_SysRes_Success)(0);
13628 Int beg, end;
13629 Int first = ARG1;
13630 Int last = ARG2;
13632 FUSE_COMPATIBLE_MAY_BLOCK();
13633 PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
13634 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
13635 PRE_REG_READ3(long, "close_range",
13636 unsigned int, first, unsigned int, last,
13637 unsigned int, flags);
13639 if (first > last) {
13640 SET_STATUS_Failure( VKI_EINVAL );
13641 return;
13644 if (last >= VG_(fd_hard_limit))
13645 last = VG_(fd_hard_limit) - 1;
13647 if (first > last) {
13648 SET_STATUS_Success ( 0 );
13649 return;
13652 beg = end = first;
13653 do {
13654 if (end > last
13655 || (end == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
13656 || end == VG_(log_output_sink).fd
13657 || end == VG_(xml_output_sink).fd) {
13658 /* Split the range if it contains a file descriptor we're not
13659 * supposed to close. */
13660 if (end - 1 >= beg)
13661 res = VG_(do_syscall3)(__NR_close_range, (UWord)beg, (UWord)end - 1, ARG3 );
13662 beg = end + 1;
13664 } while (end++ <= last);
13666 /* If it failed along the way, it's presumably the flags being wrong. */
13667 SET_STATUS_from_SysRes (res);
13670 POST(sys_close_range)
13672 Int fd;
13673 Int first = ARG1;
13674 Int last = ARG2;
13676 if (!VG_(clo_track_fds)
13677 || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0)
13678 return;
13680 if (last >= VG_(fd_hard_limit))
13681 last = VG_(fd_hard_limit) - 1;
13683 /* If the close_range range is too wide, we don't want to loop
13684 through the whole range. */
13685 if (last == ~0U)
13686 ML_(record_fd_close_range)(tid, first);
13687 else {
13688 for (fd = first; fd <= last; fd++)
13689 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
13690 && fd != VG_(log_output_sink).fd
13691 && fd != VG_(xml_output_sink).fd)
13692 ML_(record_fd_close)(tid, fd);
13697 #define VKI_O_DIRECTORY 00200000
13698 #define VKI___O_TMPFILE 020000000
13699 #define VKI_O_TMPFILE (VKI___O_TMPFILE | VKI_O_DIRECTORY)
13701 // long syscall(SYS_openat2, int dirfd, const char *pathname,
13702 // struct open_how *how, size_t size);
13703 PRE(sys_openat2)
13705 HChar name[30]; // large enough
13706 SysRes sres;
13707 struct vki_open_how * how;
13709 PRINT("sys_openat2 ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %ld )",
13710 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, SARG4);
13711 PRE_REG_READ4(long, "openat2",
13712 int, dfd, const char *, filename, struct vki_open_how *, how, vki_size_t, size);
13714 PRE_MEM_RASCIIZ( "openat2(filename)", ARG2 );
13715 PRE_MEM_READ( "openat2(how)", ARG3, sizeof(struct vki_open_how));
13717 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
13718 filename is relative to cwd. When comparing dfd against AT_FDCWD,
13719 be sure only to compare the bottom 32 bits. */
13720 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13721 && *(Char *)(Addr)ARG2 != '/'
13722 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
13723 && !ML_(fd_allowed)(ARG1, "openat2", tid, False))
13724 SET_STATUS_Failure( VKI_EBADF );
13726 how = (struct vki_open_how *)ARG3;
13728 if (how && ML_(safe_to_deref) (how, sizeof(struct vki_open_how))) {
13729 if (how->vki_mode) {
13730 if (!(how->vki_flags & ((vki_uint64_t)VKI_O_CREAT | VKI_O_TMPFILE))) {
13731 SET_STATUS_Failure( VKI_EINVAL );
13734 if (how->vki_resolve & ~((vki_uint64_t)VKI_RESOLVE_NO_XDEV |
13735 VKI_RESOLVE_NO_MAGICLINKS |
13736 VKI_RESOLVE_NO_SYMLINKS |
13737 VKI_RESOLVE_BENEATH |
13738 VKI_RESOLVE_IN_ROOT |
13739 VKI_RESOLVE_CACHED)) {
13740 SET_STATUS_Failure( VKI_EINVAL );
13744 /* Handle the case where the open is of /proc/self/cmdline or
13745 /proc/<pid>/cmdline, and just give it a copy of the fd for the
13746 fake file we cooked up at startup (in m_main). Also, seek the
13747 cloned fd back to the start. */
13749 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
13750 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13751 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13752 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
13753 sres = VG_(dup)( VG_(cl_cmdline_fd) );
13754 SET_STATUS_from_SysRes( sres );
13755 if (!sr_isError(sres)) {
13756 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13757 if (off < 0)
13758 SET_STATUS_Failure( VKI_EMFILE );
13760 return;
13763 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
13765 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
13766 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13767 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13768 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
13769 sres = VG_(dup)( VG_(cl_auxv_fd) );
13770 SET_STATUS_from_SysRes( sres );
13771 if (!sr_isError(sres)) {
13772 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13773 if (off < 0)
13774 SET_STATUS_Failure( VKI_EMFILE );
13776 return;
13779 /* And for /proc/self/exe or /proc/<pid>/exe case. */
13781 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
13782 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13783 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13784 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
13785 sres = VG_(dup)( VG_(cl_exec_fd) );
13786 SET_STATUS_from_SysRes( sres );
13787 if (!sr_isError(sres)) {
13788 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13789 if (off < 0)
13790 SET_STATUS_Failure( VKI_EMFILE );
13792 return;
13795 /* Otherwise handle normally */
13796 *flags |= SfMayBlock;
13799 POST(sys_openat2)
13801 vg_assert(SUCCESS);
13802 if (!ML_(fd_allowed)(RES, "openat2", tid, True)) {
13803 VG_(close)(RES);
13804 SET_STATUS_Failure( VKI_EMFILE );
13805 } else {
13806 if (VG_(clo_track_fds))
13807 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
13811 PRE(sys_pidfd_open)
13813 PRINT("sys_pidfd_open ( %ld, %lu )", SARG1, ARG2);
13816 POST(sys_pidfd_open)
13818 if (!ML_(fd_allowed)(RES, "pidfd", tid, True)) {
13819 VG_(close)(RES);
13820 SET_STATUS_Failure( VKI_EMFILE );
13821 } else {
13822 if (VG_(clo_track_fds))
13823 ML_(record_fd_open_nameless) (tid, RES);
13827 PRE(sys_pidfd_getfd)
13829 PRINT("sys_pidfd_getfd ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
13830 PRE_REG_READ3(long, "pidfd_getfd", int, pidfd, int, targetfd, unsigned int, flags);
13833 POST(sys_pidfd_getfd)
13835 vg_assert(SUCCESS);
13836 if (!ML_(fd_allowed)(RES, "pidfd_getfd", tid, True)) {
13837 VG_(close)(RES);
13838 SET_STATUS_Failure( VKI_EMFILE );
13839 } else {
13840 if (VG_(clo_track_fds))
13841 ML_(record_fd_open_nameless) (tid, RES);
13845 /* int open_tree (int dfd, const char *filename, unsigned int flags) */
13846 PRE(sys_open_tree)
13848 PRINT("sys_open_tree ( %ld, %#" FMT_REGWORD "x(%s), %ld",
13849 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
13850 PRE_REG_READ3(long, "open_tree",
13851 int, dfd, const char *, filename, int, flags);
13852 PRE_MEM_RASCIIZ( "open_tree(filename)", ARG2);
13853 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
13854 filename is relative to cwd. When comparing dfd against AT_FDCWD,
13855 be sure only to compare the bottom 32 bits. */
13856 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13857 && *(Char *)(Addr)ARG2 != '/'
13858 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
13859 && !ML_(fd_allowed)(ARG1, "open_tree", tid, False))
13860 SET_STATUS_Failure( VKI_EBADF );
13863 POST(sys_open_tree)
13865 if (!ML_(fd_allowed)(RES, "open_tree", tid, True)) {
13866 VG_(close)(RES);
13867 SET_STATUS_Failure( VKI_EMFILE );
13868 } else {
13869 if (VG_(clo_track_fds))
13870 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
13874 /* int move_mount (int from_dfd, const char *from_pathname,
13875 int to_dfd, const char *to_pathname,
13876 unsigned int flags) */
13877 PRE(sys_move_mount)
13879 PRINT("sys_move_mount ( %ld, %#" FMT_REGWORD "x(%s), "
13880 "%ld, %#" FMT_REGWORD "x(%s), %ld",
13881 SARG1, ARG2, (HChar*)(Addr)ARG2,
13882 SARG3, ARG4, (HChar*)(Addr)ARG4, SARG5);
13883 PRE_REG_READ5(long, "mount_move",
13884 int, from_dfd, const char *, from_pathname,
13885 int, to_dfd, const char*, to_pathname, int, flags);
13886 PRE_MEM_RASCIIZ( "mount_move(from_pathname)", ARG2);
13887 /* For absolute filenames, from_dfd is ignored. If from_dfd is AT_FDCWD,
13888 from_pathname is relative to cwd. When comparing from_dfd against
13889 AT_FDCWD, be sure only to compare the bottom 32 bits. */
13890 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13891 && *(Char *)(Addr)ARG2 != '/'
13892 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
13893 && !ML_(fd_allowed)(ARG1, "mount_move", tid, False))
13894 SET_STATUS_Failure( VKI_EBADF );
13895 PRE_MEM_RASCIIZ( "mount_move(from_pathname)", ARG4);
13896 /* For absolute filenames, to_dfd is ignored. If to_dfd is AT_FDCWD,
13897 to_pathname is relative to cwd. When comparing to_dfd against
13898 AT_FDCWD, be sure only to compare the bottom 32 bits. */
13899 if (ML_(safe_to_deref)( (void*)(Addr)ARG4, 1 )
13900 && *(Char *)(Addr)ARG4 != '/'
13901 && ((Int)ARG4) != ((Int)VKI_AT_FDCWD)
13902 && !ML_(fd_allowed)(ARG3, "mount_move", tid, False))
13903 SET_STATUS_Failure( VKI_EBADF );
13906 /* int fsopen (const char *fs_name, unsigned int flags) */
13907 PRE(sys_fsopen)
13909 PRINT("sys_fsopen ( %#" FMT_REGWORD "x(%s), %ld",
13910 ARG1, (HChar*)(Addr)ARG1, SARG2);
13911 PRE_REG_READ2(long, "fsopen", const char *, fs_name, int, flags);
13912 PRE_MEM_RASCIIZ( "fsopen(filename)", ARG1);
13915 POST(sys_fsopen)
13917 if (!ML_(fd_allowed)(RES, "fsopen", tid, True)) {
13918 VG_(close)(RES);
13919 SET_STATUS_Failure( VKI_EMFILE );
13920 } else {
13921 if (VG_(clo_track_fds))
13922 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
13926 /* int fsmount (int fd, unsigned int flags, unsigned int ms_flags) */
13927 PRE(sys_fsmount)
13929 PRINT("sys_fsmount ( %ld, %ld, %ld", SARG1, SARG2, SARG3);
13930 PRE_REG_READ3(long, "fsmount", int, fd, int, flags, int, ms_flags);
13931 if (!ML_(fd_allowed)(ARG1, "fsmount", tid, False))
13932 SET_STATUS_Failure( VKI_EBADF );
13935 POST(sys_fsmount)
13937 if (!ML_(fd_allowed)(RES, "fsmount", tid, True)) {
13938 VG_(close)(RES);
13939 SET_STATUS_Failure( VKI_EMFILE );
13940 } else {
13941 if (VG_(clo_track_fds))
13942 ML_(record_fd_open_nameless)(tid, RES);
13946 /* int fsconfig (int fd, unsigned int cmd, const char *key,
13947 const void *value, int aux) */
13948 PRE(sys_fsconfig)
13950 PRINT("sys_fsconfig ( %ld, %ld, %#" FMT_REGWORD "x(%s), "
13951 "%#" FMT_REGWORD "x, %ld )",
13952 SARG1, SARG2, ARG3, (HChar*)(Addr)ARG3, ARG4, SARG6);
13953 PRE_REG_READ5(long, "fsconfig", int, fd, int, cmd,
13954 const char *, key, const void *, value, int, aux);
13955 if (ARG3)
13956 PRE_MEM_RASCIIZ( "fsconfig(key)", ARG3);
13957 if (!ML_(fd_allowed)(ARG1, "fsconfig", tid, False))
13958 SET_STATUS_Failure( VKI_EBADF );
13959 /* XXX we could also check the value based on the cmd FSCONFIG_... */
13962 /* int fspick (int dfd, const char *path, unsigned int flags) */
13963 PRE(sys_fspick)
13965 PRINT("sys_fspick ( %ld, %#" FMT_REGWORD "x(%s), %ld",
13966 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
13967 PRE_REG_READ3(long, "fspick",
13968 int, dfd, const char *, filename, int, flags);
13969 PRE_MEM_RASCIIZ( "fspick(path)", ARG2);
13970 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
13971 path is relative to cwd. When comparing dfd against AT_FDCWD,
13972 be sure only to compare the bottom 32 bits. */
13973 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13974 && *(Char *)(Addr)ARG2 != '/'
13975 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
13976 && !ML_(fd_allowed)(ARG1, "fspick", tid, False))
13977 SET_STATUS_Failure( VKI_EBADF );
13980 POST(sys_fspick)
13982 if (!ML_(fd_allowed)(RES, "fspick", tid, True)) {
13983 VG_(close)(RES);
13984 SET_STATUS_Failure( VKI_EMFILE );
13985 } else {
13986 if (VG_(clo_track_fds))
13987 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
13991 #undef PRE
13992 #undef POST
13994 #endif // defined(VGO_linux)
13996 /*--------------------------------------------------------------------*/
13997 /*--- end ---*/
13998 /*--------------------------------------------------------------------*/