1
2/*--------------------------------------------------------------------*/
3/*--- Linux-specific syscalls, etc.                syswrap-linux.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2013 Nicholas Nethercote
11      njn@valgrind.org
12
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.
17
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.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#if defined(VGO_linux)
32
33#include "pub_core_basics.h"
34#include "pub_core_vki.h"
35#include "pub_core_vkiscnums.h"
36#include "pub_core_threadstate.h"
37#include "pub_core_aspacemgr.h"
38#include "pub_core_debuginfo.h"    // VG_(di_notify_*)
39#include "pub_core_transtab.h"     // VG_(discard_translations)
40#include "pub_core_xarray.h"
41#include "pub_core_clientstate.h"
42#include "pub_core_debuglog.h"
43#include "pub_core_libcbase.h"
44#include "pub_core_libcassert.h"
45#include "pub_core_libcfile.h"
46#include "pub_core_libcprint.h"
47#include "pub_core_libcproc.h"
48#include "pub_core_libcsignal.h"
49#include "pub_core_machine.h"      // VG_(get_SP)
50#include "pub_core_mallocfree.h"
51#include "pub_core_tooliface.h"
52#include "pub_core_options.h"
53#include "pub_core_scheduler.h"
54#include "pub_core_signals.h"
55#include "pub_core_syscall.h"
56#include "pub_core_syswrap.h"
57#include "pub_core_inner.h"
58#if defined(ENABLE_INNER_CLIENT_REQUEST)
59#include "pub_core_clreq.h"
60#endif
61
62#include "priv_types_n_macros.h"
63#include "priv_syswrap-generic.h"
64#include "priv_syswrap-linux.h"
65#include "priv_syswrap-xen.h"
66
67// Run a thread from beginning to end and return the thread's
68// scheduler-return-code.
69static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
70{
71   VgSchedReturnCode ret;
72   ThreadId     tid = (ThreadId)tidW;
73   ThreadState* tst = VG_(get_ThreadState)(tid);
74
75   VG_(debugLog)(1, "syswrap-linux",
76                    "thread_wrapper(tid=%lld): entry\n",
77                    (ULong)tidW);
78
79   vg_assert(tst->status == VgTs_Init);
80
81   /* make sure we get the CPU lock before doing anything significant */
82   VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
83
84   if (0)
85      VG_(printf)("thread tid %d started: stack = %p\n",
86		  tid, &tid);
87
88   /* Make sure error reporting is enabled in the new thread. */
89   tst->err_disablement_level = 0;
90
91   VG_TRACK(pre_thread_first_insn, tid);
92
93   tst->os_state.lwpid = VG_(gettid)();
94   /* Set the threadgroup for real.  This overwrites the provisional
95      value set in do_clone() syswrap-*-linux.c.  See comments in
96      do_clone for background, also #226116. */
97   tst->os_state.threadgroup = VG_(getpid)();
98
99   /* Thread created with all signals blocked; scheduler will set the
100      appropriate mask */
101
102   ret = VG_(scheduler)(tid);
103
104   vg_assert(VG_(is_exiting)(tid));
105
106   vg_assert(tst->status == VgTs_Runnable);
107   vg_assert(VG_(is_running_thread)(tid));
108
109   VG_(debugLog)(1, "syswrap-linux",
110                    "thread_wrapper(tid=%lld): exit, schedreturncode %s\n",
111                    (ULong)tidW, VG_(name_of_VgSchedReturnCode)(ret));
112
113   /* Return to caller, still holding the lock. */
114   return ret;
115}
116
117
118/* ---------------------------------------------------------------------
119   clone-related stuff
120   ------------------------------------------------------------------ */
121
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).  */
124static void run_a_thread_NORETURN ( Word tidW )
125{
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
133
134   VG_(debugLog)(1, "syswrap-linux",
135                    "run_a_thread_NORETURN(tid=%lld): pre-thread_wrapper\n",
136                    (ULong)tidW);
137
138   tst = VG_(get_ThreadState)(tid);
139   vg_assert(tst);
140
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.
148   */
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));
153
154   /* Run the thread all the way through. */
155   src = thread_wrapper(tid);
156
157   VG_(debugLog)(1, "syswrap-linux",
158                    "run_a_thread_NORETURN(tid=%lld): post-thread_wrapper\n",
159                    (ULong)tidW);
160
161   c = VG_(count_living_threads)();
162   vg_assert(c >= 1); /* stay sane */
163
164   // Tell the tool this thread is exiting
165   VG_TRACK( pre_thread_ll_exit, tid );
166
167   /* If the thread is exiting with errors disabled, complain loudly;
168      doing so is bad (does the user know this has happened?)  Also,
169      in all cases, be paranoid and clear the flag anyway so that the
170      thread slot is safe in this respect if later reallocated.  This
171      should be unnecessary since the flag should be cleared when the
172      slot is reallocated, in thread_wrapper(). */
173   if (tst->err_disablement_level > 0) {
174      VG_(umsg)(
175         "WARNING: exiting thread has error reporting disabled.\n"
176         "WARNING: possibly as a result of some mistake in the use\n"
177         "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
178      );
179      VG_(debugLog)(
180         1, "syswrap-linux",
181            "run_a_thread_NORETURN(tid=%lld): "
182            "WARNING: exiting thread has err_disablement_level = %u\n",
183            (ULong)tidW, tst->err_disablement_level
184      );
185   }
186   tst->err_disablement_level = 0;
187
188   if (c == 1) {
189
190      VG_(debugLog)(1, "syswrap-linux",
191                       "run_a_thread_NORETURN(tid=%lld): "
192                          "last one standing\n",
193                          (ULong)tidW);
194
195      /* We are the last one standing.  Keep hold of the lock and
196         carry on to show final tool results, then exit the entire system.
197         Use the continuation pointer set at startup in m_main. */
198      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
199   } else {
200
201      VG_(debugLog)(1, "syswrap-linux",
202                       "run_a_thread_NORETURN(tid=%lld): "
203                          "not last one standing\n",
204                          (ULong)tidW);
205
206      /* OK, thread is dead, but others still exist.  Just exit. */
207
208      /* This releases the run lock */
209      VG_(exit_thread)(tid);
210      vg_assert(tst->status == VgTs_Zombie);
211      vg_assert(sizeof(tst->status) == 4);
212      vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
213
214      INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
215
216      /* We have to use this sequence to terminate the thread to
217         prevent a subtle race.  If VG_(exit_thread)() had left the
218         ThreadState as Empty, then it could have been reallocated,
219         reusing the stack while we're doing these last cleanups.
220         Instead, VG_(exit_thread) leaves it as Zombie to prevent
221         reallocation.  We need to make sure we don't touch the stack
222         between marking it Empty and exiting.  Hence the
223         assembler. */
224#if defined(VGP_x86_linux)
225      asm volatile (
226         "pushl %%ebx\n"
227         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
228         "movl	%2, %%eax\n"    /* set %eax = __NR_exit */
229         "movl	%3, %%ebx\n"    /* set %ebx = tst->os_state.exitcode */
230         "int	$0x80\n"	/* exit(tst->os_state.exitcode) */
231	 "popl %%ebx\n"
232         : "=m" (tst->status)
233         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
234         : "eax"
235      );
236#elif defined(VGP_amd64_linux)
237      asm volatile (
238         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
239         "movq	%2, %%rax\n"    /* set %rax = __NR_exit */
240         "movq	%3, %%rdi\n"    /* set %rdi = tst->os_state.exitcode */
241         "syscall\n"		/* exit(tst->os_state.exitcode) */
242         : "=m" (tst->status)
243         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
244         : "rax", "rdi"
245      );
246#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
247      || defined(VGP_ppc64le_linux)
248      { UInt vgts_empty = (UInt)VgTs_Empty;
249        asm volatile (
250          "stw %1,%0\n\t"          /* set tst->status = VgTs_Empty */
251          "li  0,%2\n\t"           /* set r0 = __NR_exit */
252          "lwz 3,%3\n\t"           /* set r3 = tst->os_state.exitcode */
253          "sc\n\t"                 /* exit(tst->os_state.exitcode) */
254          : "=m" (tst->status)
255          : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
256          : "r0", "r3"
257        );
258      }
259#elif defined(VGP_arm_linux)
260      asm volatile (
261         "str  %1, %0\n"      /* set tst->status = VgTs_Empty */
262         "mov  r7, %2\n"      /* set %r7 = __NR_exit */
263         "ldr  r0, %3\n"      /* set %r0 = tst->os_state.exitcode */
264         "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
265         : "=m" (tst->status)
266         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
267         : "r0", "r7"
268      );
269#elif defined(VGP_arm64_linux)
270      asm volatile (
271         "str  %w1, %0\n"     /* set tst->status = VgTs_Empty (32-bit store) */
272         "mov  x8,  %2\n"     /* set %r7 = __NR_exit */
273         "ldr  x0,  %3\n"     /* set %r0 = tst->os_state.exitcode */
274         "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
275         : "=m" (tst->status)
276         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
277         : "r0", "r7"
278      );
279#elif defined(VGP_s390x_linux)
280      asm volatile (
281         "st   %1, %0\n"        /* set tst->status = VgTs_Empty */
282         "lg   2, %3\n"         /* set r2 = tst->os_state.exitcode */
283         "svc %2\n"             /* exit(tst->os_state.exitcode) */
284         : "=m" (tst->status)
285         : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
286         : "2"
287      );
288#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
289      asm volatile (
290         "sw   %1, %0\n\t"     /* set tst->status = VgTs_Empty */
291         "li   $2, %2\n\t"     /* set v0 = __NR_exit */
292         "lw   $4, %3\n\t"     /* set a0 = tst->os_state.exitcode */
293         "syscall\n\t"         /* exit(tst->os_state.exitcode) */
294         "nop"
295         : "=m" (tst->status)
296         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
297         : "cc", "memory" , "v0", "a0"
298      );
299#elif defined(VGP_tilegx_linux)
300      asm volatile (
301         "st4    %0,  %1\n"      /* set tst->status = VgTs_Empty */
302         "moveli r10, %2\n"      /* set r10 = __NR_exit */
303         "move   r0,  %3\n"      /* set  r0 = tst->os_state.exitcode */
304         "swint1\n"              /* exit(tst->os_state.exitcode) */
305         : "=m" (tst->status)
306         : "r" (VgTs_Empty), "n" (__NR_exit), "r" (tst->os_state.exitcode)
307         : "r0", "r1", "r2", "r3", "r4", "r5");
308#else
309# error Unknown platform
310#endif
311
312      VG_(core_panic)("Thread exit failed?\n");
313   }
314
315   /*NOTREACHED*/
316   vg_assert(0);
317}
318
319Word ML_(start_thread_NORETURN) ( void* arg )
320{
321   ThreadState* tst = (ThreadState*)arg;
322   ThreadId     tid = tst->tid;
323
324   run_a_thread_NORETURN ( (Word)tid );
325   /*NOTREACHED*/
326   vg_assert(0);
327}
328
329/* Allocate a stack for this thread, if it doesn't already have one.
330   They're allocated lazily, and never freed.  Returns the initial stack
331   pointer value to use, or 0 if allocation failed. */
332Addr ML_(allocstack)(ThreadId tid)
333{
334   ThreadState* tst = VG_(get_ThreadState)(tid);
335   VgStack*     stack;
336   Addr         initial_SP;
337
338   /* Either the stack_base and stack_init_SP are both zero (in which
339      case a stack hasn't been allocated) or they are both non-zero,
340      in which case it has. */
341
342   if (tst->os_state.valgrind_stack_base == 0)
343      vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
344
345   if (tst->os_state.valgrind_stack_base != 0)
346      vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
347
348   /* If no stack is present, allocate one. */
349
350   if (tst->os_state.valgrind_stack_base == 0) {
351      stack = VG_(am_alloc_VgStack)( &initial_SP );
352      if (stack) {
353         tst->os_state.valgrind_stack_base    = (Addr)stack;
354         tst->os_state.valgrind_stack_init_SP = initial_SP;
355      }
356   }
357
358   if (0)
359      VG_(printf)( "stack for tid %d at %p; init_SP=%p\n",
360                   tid,
361                   (void*)tst->os_state.valgrind_stack_base,
362                   (void*)tst->os_state.valgrind_stack_init_SP );
363
364   return tst->os_state.valgrind_stack_init_SP;
365}
366
367/* Allocate a stack for the main thread, and run it all the way to the
368   end.  Although we already have a working VgStack
369   (VG_(interim_stack)) it's better to allocate a new one, so that
370   overflow detection works uniformly for all threads.
371*/
372void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
373{
374   Addr sp;
375   VG_(debugLog)(1, "syswrap-linux",
376                    "entering VG_(main_thread_wrapper_NORETURN)\n");
377
378   sp = ML_(allocstack)(tid);
379#if defined(ENABLE_INNER_CLIENT_REQUEST)
380   {
381      // we must register the main thread stack before the call
382      // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
383      // reports 'write error' on the non registered stack.
384      ThreadState* tst = VG_(get_ThreadState)(tid);
385      INNER_REQUEST
386         ((void)
387          VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
388                                   tst->os_state.valgrind_stack_init_SP));
389   }
390#endif
391
392#if defined(VGP_ppc32_linux)
393   /* make a stack frame */
394   sp -= 16;
395   sp &= ~0xF;
396   *(UWord *)sp = 0;
397#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
398   /* make a stack frame */
399   sp -= 112;
400   sp &= ~((Addr)0xF);
401   *(UWord *)sp = 0;
402#elif defined(VGP_s390x_linux)
403   /* make a stack frame */
404   sp -= 160;
405   sp &= ~((Addr)0xF);
406   *(UWord *)sp = 0;
407#endif
408
409   /* If we can't even allocate the first thread's stack, we're hosed.
410      Give up. */
411   vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
412
413   /* shouldn't be any other threads around yet */
414   vg_assert( VG_(count_living_threads)() == 1 );
415
416   ML_(call_on_new_stack_0_1)(
417      (Addr)sp,               /* stack */
418      0,                      /* bogus return address */
419      run_a_thread_NORETURN,  /* fn to call */
420      (Word)tid               /* arg to give it */
421   );
422
423   /*NOTREACHED*/
424   vg_assert(0);
425}
426
427
428/* Do a clone which is really a fork() */
429SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
430                            Int* parent_tidptr, Int* child_tidptr )
431{
432   vki_sigset_t fork_saved_mask;
433   vki_sigset_t mask;
434   SysRes       res;
435
436   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
437                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
438      return VG_(mk_SysRes_Error)( VKI_EINVAL );
439
440   /* Block all signals during fork, so that we can fix things up in
441      the child without being interrupted. */
442   VG_(sigfillset)(&mask);
443   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
444
445   VG_(do_atfork_pre)(tid);
446
447   /* Since this is the fork() form of clone, we don't need all that
448      VG_(clone) stuff */
449#if defined(VGP_x86_linux) \
450    || defined(VGP_ppc32_linux) \
451    || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)	\
452    || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
453    || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
454   res = VG_(do_syscall5)( __NR_clone, flags,
455                           (UWord)NULL, (UWord)parent_tidptr,
456                           (UWord)NULL, (UWord)child_tidptr );
457#elif defined(VGP_amd64_linux) || defined(VGP_tilegx_linux)
458   /* note that the last two arguments are the opposite way round to x86 and
459      ppc32 as the amd64 kernel expects the arguments in a different order */
460   res = VG_(do_syscall5)( __NR_clone, flags,
461                           (UWord)NULL, (UWord)parent_tidptr,
462                           (UWord)child_tidptr, (UWord)NULL );
463#elif defined(VGP_s390x_linux)
464   /* Note that s390 has the stack first and then the flags */
465   res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
466                          (UWord)parent_tidptr, (UWord)child_tidptr);
467#else
468# error Unknown platform
469#endif
470
471   if (!sr_isError(res) && sr_Res(res) == 0) {
472      /* child */
473      VG_(do_atfork_child)(tid);
474
475      /* restore signal mask */
476      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
477
478      /* If --child-silent-after-fork=yes was specified, set the
479         output file descriptors to 'impossible' values.  This is
480         noticed by send_bytes_to_logging_sink in m_libcprint.c, which
481         duly stops writing any further output. */
482      if (VG_(clo_child_silent_after_fork)) {
483         if (!VG_(log_output_sink).is_socket)
484            VG_(log_output_sink).fd = -1;
485         if (!VG_(xml_output_sink).is_socket)
486            VG_(xml_output_sink).fd = -1;
487      }
488   }
489   else
490   if (!sr_isError(res) && sr_Res(res) > 0) {
491      /* parent */
492      VG_(do_atfork_parent)(tid);
493
494      if (VG_(clo_trace_syscalls))
495	  VG_(printf)("   clone(fork): process %d created child %ld\n",
496                      VG_(getpid)(), sr_Res(res));
497
498      /* restore signal mask */
499      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
500   }
501
502   return res;
503}
504
505
506/* ---------------------------------------------------------------------
507   PRE/POST wrappers for arch-generic, Linux-specific syscalls
508   ------------------------------------------------------------------ */
509
510// Nb: See the comment above the generic PRE/POST wrappers in
511// m_syswrap/syswrap-generic.c for notes about how they work.
512
513#define PRE(name)       DEFN_PRE_TEMPLATE(linux, name)
514#define POST(name)      DEFN_POST_TEMPLATE(linux, name)
515
516// Macros to support 64-bit syscall args split into two 32 bit values
517#define LOHI64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
518#if defined(VG_LITTLEENDIAN)
519#define MERGE64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
520#define MERGE64_FIRST(name) name##_low
521#define MERGE64_SECOND(name) name##_high
522#elif defined(VG_BIGENDIAN)
523#define MERGE64(hi,lo)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
524#define MERGE64_FIRST(name) name##_high
525#define MERGE64_SECOND(name) name##_low
526#else
527#error Unknown endianness
528#endif
529
530/* ---------------------------------------------------------------------
531   *mount wrappers
532   ------------------------------------------------------------------ */
533
534PRE(sys_mount)
535{
536   // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
537   // We are conservative and check everything, except the memory pointed to
538   // by 'data'.
539   *flags |= SfMayBlock;
540   PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx(%s), %#lx, %#lx )",
541         ARG1,(HChar*)ARG1, ARG2,(HChar*)ARG2, ARG3,(HChar*)ARG3, ARG4, ARG5);
542   PRE_REG_READ5(long, "mount",
543                 char *, source, char *, target, char *, type,
544                 unsigned long, flags, void *, data);
545   if (ARG1)
546      PRE_MEM_RASCIIZ( "mount(source)", ARG1);
547   PRE_MEM_RASCIIZ( "mount(target)", ARG2);
548   PRE_MEM_RASCIIZ( "mount(type)", ARG3);
549}
550
551PRE(sys_oldumount)
552{
553   PRINT("sys_oldumount( %#lx )", ARG1);
554   PRE_REG_READ1(long, "umount", char *, path);
555   PRE_MEM_RASCIIZ( "umount(path)", ARG1);
556}
557
558PRE(sys_umount)
559{
560   PRINT("sys_umount( %#lx, %ld )", ARG1, ARG2);
561   PRE_REG_READ2(long, "umount2", char *, path, int, flags);
562   PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
563}
564
565/* Not actually wrapped by GLibc but does things with the system
566 * mounts so it is put here.
567 */
568PRE(sys_pivot_root)
569{
570   PRINT("sys_pivot_root ( %s %s )", (HChar*)ARG1, (HChar*)ARG2);
571   PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
572   PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
573   PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
574}
575
576
577/* ---------------------------------------------------------------------
578   16- and 32-bit uid/gid wrappers
579   ------------------------------------------------------------------ */
580
581PRE(sys_setfsuid16)
582{
583   PRINT("sys_setfsuid16 ( %ld )", ARG1);
584   PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
585}
586
587PRE(sys_setfsuid)
588{
589   PRINT("sys_setfsuid ( %ld )", ARG1);
590   PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
591}
592
593PRE(sys_setfsgid16)
594{
595   PRINT("sys_setfsgid16 ( %ld )", ARG1);
596   PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
597}
598
599PRE(sys_setfsgid)
600{
601   PRINT("sys_setfsgid ( %ld )", ARG1);
602   PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
603}
604
605PRE(sys_setresuid16)
606{
607   PRINT("sys_setresuid16 ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
608   PRE_REG_READ3(long, "setresuid16",
609                 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
610}
611
612PRE(sys_setresuid)
613{
614   PRINT("sys_setresuid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
615   PRE_REG_READ3(long, "setresuid",
616                 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
617}
618
619PRE(sys_getresuid16)
620{
621   PRINT("sys_getresuid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
622   PRE_REG_READ3(long, "getresuid16",
623                 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
624                 vki_old_uid_t *, suid);
625   PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
626   PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
627   PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
628}
629POST(sys_getresuid16)
630{
631   vg_assert(SUCCESS);
632   if (RES == 0) {
633      POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
634      POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
635      POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
636   }
637}
638
639PRE(sys_getresuid)
640{
641   PRINT("sys_getresuid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
642   PRE_REG_READ3(long, "getresuid",
643                 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
644   PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
645   PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
646   PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
647}
648POST(sys_getresuid)
649{
650   vg_assert(SUCCESS);
651   if (RES == 0) {
652      POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
653      POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
654      POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
655   }
656}
657
658PRE(sys_setresgid16)
659{
660   PRINT("sys_setresgid16 ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
661   PRE_REG_READ3(long, "setresgid16",
662                 vki_old_gid_t, rgid,
663                 vki_old_gid_t, egid, vki_old_gid_t, sgid);
664}
665
666PRE(sys_setresgid)
667{
668   PRINT("sys_setresgid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
669   PRE_REG_READ3(long, "setresgid",
670                 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
671}
672
673PRE(sys_getresgid16)
674{
675   PRINT("sys_getresgid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
676   PRE_REG_READ3(long, "getresgid16",
677                 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
678                 vki_old_gid_t *, sgid);
679   PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
680   PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
681   PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
682}
683POST(sys_getresgid16)
684{
685   vg_assert(SUCCESS);
686   if (RES == 0) {
687      POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
688      POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
689      POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
690   }
691}
692
693PRE(sys_getresgid)
694{
695   PRINT("sys_getresgid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
696   PRE_REG_READ3(long, "getresgid",
697                 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
698   PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
699   PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
700   PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
701}
702POST(sys_getresgid)
703{
704   vg_assert(SUCCESS);
705   if (RES == 0) {
706      POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
707      POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
708      POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
709   }
710}
711
712/* ---------------------------------------------------------------------
713   miscellaneous wrappers
714   ------------------------------------------------------------------ */
715
716PRE(sys_exit_group)
717{
718   ThreadId     t;
719   ThreadState* tst;
720
721   PRINT("exit_group( %ld )", ARG1);
722   PRE_REG_READ1(void, "exit_group", int, status);
723
724   tst = VG_(get_ThreadState)(tid);
725   /* A little complex; find all the threads with the same threadgroup
726      as this one (including this one), and mark them to exit */
727   /* It is unclear how one can get a threadgroup in this process which
728      is not the threadgroup of the calling thread:
729      The assignments to threadgroups are:
730        = 0; /// scheduler.c os_state_clear
731        = getpid(); /// scheduler.c in child after fork
732        = getpid(); /// this file, in thread_wrapper
733        = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
734                           copying the thread group of the thread doing clone
735      So, the only case where the threadgroup might be different to the getpid
736      value is in the child, just after fork. But then the fork syscall is
737      still going on, the forked thread has had no chance yet to make this
738      syscall. */
739   for (t = 1; t < VG_N_THREADS; t++) {
740      if ( /* not alive */
741           VG_(threads)[t].status == VgTs_Empty
742           ||
743	   /* not our group */
744           VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
745         )
746         continue;
747      /* Assign the exit code, VG_(nuke_all_threads_except) will assign
748         the exitreason. */
749      VG_(threads)[t].os_state.exitcode = ARG1;
750   }
751
752   /* Indicate in all other threads that the process is exiting.
753      Then wait using VG_(reap_threads) for these threads to disappear.
754
755      Can this give a deadlock if another thread is calling exit in parallel
756      and would then wait for this thread to disappear ?
757      The answer is no:
758      Other threads are either blocked in a syscall or have yielded the CPU.
759
760      A thread that has yielded the CPU is trying to get the big lock in
761      VG_(scheduler). This thread will get the CPU thanks to the call
762      to VG_(reap_threads). The scheduler will then check for signals,
763      kill the process if this is a fatal signal, and otherwise prepare
764      the thread for handling this signal. After this preparation, if
765      the thread status is VG_(is_exiting), the scheduler exits the thread.
766      So, a thread that has yielded the CPU does not have a chance to
767      call exit => no deadlock for this thread.
768
769      VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
770      to all threads blocked in a syscall.
771      The syscall will be interrupted, and the control will go to the
772      scheduler. The scheduler will then return, as the thread is in
773      exiting state. */
774
775   VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
776   VG_(reap_threads)(tid);
777   VG_(threads)[tid].exitreason = VgSrc_ExitThread;
778   /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
779      is the thread calling exit_group and so its registers must be considered
780      as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
781
782   /* We have to claim the syscall already succeeded. */
783   SET_STATUS_Success(0);
784}
785
786PRE(sys_llseek)
787{
788   PRINT("sys_llseek ( %ld, 0x%lx, 0x%lx, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5);
789   PRE_REG_READ5(long, "llseek",
790                 unsigned int, fd, unsigned long, offset_high,
791                 unsigned long, offset_low, vki_loff_t *, result,
792                 unsigned int, whence);
793   if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
794      SET_STATUS_Failure( VKI_EBADF );
795   else
796      PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
797}
798POST(sys_llseek)
799{
800   vg_assert(SUCCESS);
801   if (RES == 0)
802      POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
803}
804
805PRE(sys_adjtimex)
806{
807   struct vki_timex *tx = (struct vki_timex *)ARG1;
808   PRINT("sys_adjtimex ( %#lx )", ARG1);
809   PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
810   PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
811
812#define ADJX(bits,field) 				\
813   if (tx->modes & (bits))                              \
814      PRE_MEM_READ( "adjtimex(timex->"#field")",	\
815		    (Addr)&tx->field, sizeof(tx->field))
816
817   if (tx->modes & VKI_ADJ_ADJTIME) {
818      if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
819         PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
820   } else {
821      ADJX(VKI_ADJ_OFFSET, offset);
822      ADJX(VKI_ADJ_FREQUENCY, freq);
823      ADJX(VKI_ADJ_MAXERROR, maxerror);
824      ADJX(VKI_ADJ_ESTERROR, esterror);
825      ADJX(VKI_ADJ_STATUS, status);
826      ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
827      ADJX(VKI_ADJ_TICK, tick);
828   }
829#undef ADJX
830
831   PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
832}
833
834POST(sys_adjtimex)
835{
836   POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
837}
838
839PRE(sys_clock_adjtime)
840{
841   struct vki_timex *tx = (struct vki_timex *)ARG2;
842   PRINT("sys_clock_adjtime ( %ld, %#lx )", ARG1,ARG2);
843   PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
844   PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
845
846#define ADJX(bits,field)                                \
847   if (tx->modes & (bits))                              \
848      PRE_MEM_READ( "clock_adjtime(timex->"#field")",   \
849                    (Addr)&tx->field, sizeof(tx->field))
850
851   if (tx->modes & VKI_ADJ_ADJTIME) {
852      if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
853         PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
854   } else {
855      ADJX(VKI_ADJ_OFFSET, offset);
856      ADJX(VKI_ADJ_FREQUENCY, freq);
857      ADJX(VKI_ADJ_MAXERROR, maxerror);
858      ADJX(VKI_ADJ_ESTERROR, esterror);
859      ADJX(VKI_ADJ_STATUS, status);
860      ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
861      ADJX(VKI_ADJ_TICK, tick);
862   }
863#undef ADJX
864
865   PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
866}
867
868POST(sys_clock_adjtime)
869{
870   POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
871}
872
873PRE(sys_ioperm)
874{
875   PRINT("sys_ioperm ( %ld, %ld, %ld )", ARG1, ARG2, ARG3 );
876   PRE_REG_READ3(long, "ioperm",
877                 unsigned long, from, unsigned long, num, int, turn_on);
878}
879
880PRE(sys_syslog)
881{
882   *flags |= SfMayBlock;
883   PRINT("sys_syslog (%ld, %#lx, %ld)", ARG1,ARG2,ARG3);
884   PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
885   switch (ARG1) {
886   // The kernel uses magic numbers here, rather than named constants,
887   // therefore so do we.
888   case 2: case 3: case 4:
889      PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
890      break;
891   default:
892      break;
893   }
894}
895POST(sys_syslog)
896{
897   switch (ARG1) {
898   case 2: case 3: case 4:
899      POST_MEM_WRITE( ARG2, ARG3 );
900      break;
901   default:
902      break;
903   }
904}
905
906PRE(sys_vhangup)
907{
908   PRINT("sys_vhangup ( )");
909   PRE_REG_READ0(long, "vhangup");
910}
911
912PRE(sys_sysinfo)
913{
914   PRINT("sys_sysinfo ( %#lx )",ARG1);
915   PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
916   PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
917}
918POST(sys_sysinfo)
919{
920   POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
921}
922
923PRE(sys_personality)
924{
925   PRINT("sys_personality ( %llu )", (ULong)ARG1);
926   PRE_REG_READ1(long, "personality", vki_u_long, persona);
927}
928
929PRE(sys_sysctl)
930{
931   struct __vki_sysctl_args *args;
932   PRINT("sys_sysctl ( %#lx )", ARG1 );
933   args = (struct __vki_sysctl_args *)ARG1;
934   PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
935   PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
936   if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
937                                          VKI_PROT_READ)) {
938      SET_STATUS_Failure( VKI_EFAULT );
939      return;
940   }
941
942   PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
943   if (args->newval != NULL)
944      PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
945   if (args->oldlenp != NULL) {
946      PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
947      PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
948   }
949}
950POST(sys_sysctl)
951{
952   struct __vki_sysctl_args *args;
953   args = (struct __vki_sysctl_args *)ARG1;
954   if (args->oldlenp != NULL) {
955      POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
956      POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
957   }
958}
959
960PRE(sys_prctl)
961{
962   *flags |= SfMayBlock;
963   PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4, ARG5 );
964   switch (ARG1) {
965   case VKI_PR_SET_PDEATHSIG:
966      PRE_REG_READ2(int, "prctl", int, option, int, signal);
967      break;
968   case VKI_PR_GET_PDEATHSIG:
969      PRE_REG_READ2(int, "prctl", int, option, int *, signal);
970      PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
971      break;
972   case VKI_PR_GET_DUMPABLE:
973      PRE_REG_READ1(int, "prctl", int, option);
974      break;
975   case VKI_PR_SET_DUMPABLE:
976      PRE_REG_READ2(int, "prctl", int, option, int, dump);
977      break;
978   case VKI_PR_GET_UNALIGN:
979      PRE_REG_READ2(int, "prctl", int, option, int *, value);
980      PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
981      break;
982   case VKI_PR_SET_UNALIGN:
983      PRE_REG_READ2(int, "prctl", int, option, int, value);
984      break;
985   case VKI_PR_GET_KEEPCAPS:
986      PRE_REG_READ1(int, "prctl", int, option);
987      break;
988   case VKI_PR_SET_KEEPCAPS:
989      PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
990      break;
991   case VKI_PR_GET_FPEMU:
992      PRE_REG_READ2(int, "prctl", int, option, int *, value);
993      PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
994      break;
995   case VKI_PR_SET_FPEMU:
996      PRE_REG_READ2(int, "prctl", int, option, int, value);
997      break;
998   case VKI_PR_GET_FPEXC:
999      PRE_REG_READ2(int, "prctl", int, option, int *, value);
1000      PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1001      break;
1002   case VKI_PR_SET_FPEXC:
1003      PRE_REG_READ2(int, "prctl", int, option, int, value);
1004      break;
1005   case VKI_PR_GET_TIMING:
1006      PRE_REG_READ1(int, "prctl", int, option);
1007      break;
1008   case VKI_PR_SET_TIMING:
1009      PRE_REG_READ2(int, "prctl", int, option, int, timing);
1010      break;
1011   case VKI_PR_SET_NAME:
1012      PRE_REG_READ2(int, "prctl", int, option, char *, name);
1013      PRE_MEM_RASCIIZ("prctl(set-name)", ARG2);
1014      break;
1015   case VKI_PR_GET_NAME:
1016      PRE_REG_READ2(int, "prctl", int, option, char *, name);
1017      PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1018      break;
1019   case VKI_PR_GET_ENDIAN:
1020      PRE_REG_READ2(int, "prctl", int, option, int *, value);
1021      PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1022      break;
1023   case VKI_PR_SET_ENDIAN:
1024      PRE_REG_READ2(int, "prctl", int, option, int, value);
1025      break;
1026   case VKI_PR_SET_PTRACER:
1027      PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1028      break;
1029   case VKI_PR_SET_SECCOMP:
1030      /* This is a bit feeble in that it uses |option| before checking
1031         it, but at least both sides of the conditional check it. */
1032      if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1033         PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1034         if (ARG3) {
1035            /* Should check that ARG3 points at a valid struct sock_fprog.
1036               Sounds complex; hence be lame. */
1037            PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1038                          ARG3, 1 );
1039         }
1040      } else {
1041         PRE_REG_READ2(int, "prctl", int, option, int, mode);
1042      }
1043      break;
1044   default:
1045      PRE_REG_READ5(long, "prctl",
1046                    int, option, unsigned long, arg2, unsigned long, arg3,
1047                    unsigned long, arg4, unsigned long, arg5);
1048      break;
1049   }
1050}
1051POST(sys_prctl)
1052{
1053   switch (ARG1) {
1054   case VKI_PR_GET_PDEATHSIG:
1055      POST_MEM_WRITE(ARG2, sizeof(Int));
1056      break;
1057   case VKI_PR_GET_UNALIGN:
1058      POST_MEM_WRITE(ARG2, sizeof(Int));
1059      break;
1060   case VKI_PR_GET_FPEMU:
1061      POST_MEM_WRITE(ARG2, sizeof(Int));
1062      break;
1063   case VKI_PR_GET_FPEXC:
1064      POST_MEM_WRITE(ARG2, sizeof(Int));
1065      break;
1066   case VKI_PR_GET_NAME:
1067      POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1068      break;
1069   case VKI_PR_GET_ENDIAN:
1070      POST_MEM_WRITE(ARG2, sizeof(Int));
1071      break;
1072   case VKI_PR_SET_NAME:
1073      {
1074         const HChar* new_name = (const HChar*) ARG2;
1075         if (new_name) {    // Paranoia
1076            ThreadState* tst = VG_(get_ThreadState)(tid);
1077            SizeT new_len = VG_(strlen)(new_name);
1078
1079            /* Don't bother reusing the memory. This is a rare event. */
1080            tst->thread_name =
1081              VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1082            VG_(strcpy)(tst->thread_name, new_name);
1083         }
1084      }
1085      break;
1086   }
1087}
1088
1089PRE(sys_sendfile)
1090{
1091   *flags |= SfMayBlock;
1092   PRINT("sys_sendfile ( %ld, %ld, %#lx, %lu )", ARG1,ARG2,ARG3,ARG4);
1093   PRE_REG_READ4(ssize_t, "sendfile",
1094                 int, out_fd, int, in_fd, vki_off_t *, offset,
1095                 vki_size_t, count);
1096   if (ARG3 != 0)
1097      PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1098}
1099POST(sys_sendfile)
1100{
1101   if (ARG3 != 0 ) {
1102      POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1103   }
1104}
1105
1106PRE(sys_sendfile64)
1107{
1108   *flags |= SfMayBlock;
1109   PRINT("sendfile64 ( %ld, %ld, %#lx, %lu )",ARG1,ARG2,ARG3,ARG4);
1110   PRE_REG_READ4(ssize_t, "sendfile64",
1111                 int, out_fd, int, in_fd, vki_loff_t *, offset,
1112                 vki_size_t, count);
1113   if (ARG3 != 0)
1114      PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1115}
1116POST(sys_sendfile64)
1117{
1118   if (ARG3 != 0 ) {
1119      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1120   }
1121}
1122
1123PRE(sys_futex)
1124{
1125   /*
1126      arg    param                              used by ops
1127
1128      ARG1 - u32 *futex				all
1129      ARG2 - int op
1130      ARG3 - int val				WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1131      ARG4 - struct timespec *utime		WAIT:time*	REQUEUE,CMP_REQUEUE:val2
1132      ARG5 - u32 *uaddr2			REQUEUE,CMP_REQUEUE
1133      ARG6 - int val3				CMP_REQUEUE
1134    */
1135   PRINT("sys_futex ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
1136   switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1137   case VKI_FUTEX_CMP_REQUEUE:
1138   case VKI_FUTEX_WAKE_OP:
1139   case VKI_FUTEX_CMP_REQUEUE_PI:
1140      PRE_REG_READ6(long, "futex",
1141                    vki_u32 *, futex, int, op, int, val,
1142                    struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1143      break;
1144   case VKI_FUTEX_REQUEUE:
1145   case VKI_FUTEX_WAIT_REQUEUE_PI:
1146      PRE_REG_READ5(long, "futex",
1147                    vki_u32 *, futex, int, op, int, val,
1148                    struct timespec *, utime, vki_u32 *, uaddr2);
1149      break;
1150   case VKI_FUTEX_WAIT_BITSET:
1151      /* Check that the address at least begins in client-accessible area. */
1152      if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1153            SET_STATUS_Failure( VKI_EFAULT );
1154            return;
1155      }
1156      if (*(vki_u32 *)ARG1 != ARG3) {
1157         PRE_REG_READ5(long, "futex",
1158                       vki_u32 *, futex, int, op, int, val,
1159                       struct timespec *, utime, int, dummy);
1160      } else {
1161         PRE_REG_READ6(long, "futex",
1162                       vki_u32 *, futex, int, op, int, val,
1163                       struct timespec *, utime, int, dummy, int, val3);
1164      }
1165      break;
1166   case VKI_FUTEX_WAKE_BITSET:
1167      PRE_REG_READ6(long, "futex",
1168                    vki_u32 *, futex, int, op, int, val,
1169                    int, dummy, int, dummy2, int, val3);
1170      break;
1171   case VKI_FUTEX_WAIT:
1172   case VKI_FUTEX_LOCK_PI:
1173      PRE_REG_READ4(long, "futex",
1174                    vki_u32 *, futex, int, op, int, val,
1175                    struct timespec *, utime);
1176      break;
1177   case VKI_FUTEX_WAKE:
1178   case VKI_FUTEX_FD:
1179   case VKI_FUTEX_TRYLOCK_PI:
1180      PRE_REG_READ3(long, "futex",
1181                    vki_u32 *, futex, int, op, int, val);
1182      break;
1183   case VKI_FUTEX_UNLOCK_PI:
1184   default:
1185      PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1186      break;
1187   }
1188
1189   *flags |= SfMayBlock;
1190
1191   switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1192   case VKI_FUTEX_WAIT:
1193   case VKI_FUTEX_LOCK_PI:
1194   case VKI_FUTEX_WAIT_BITSET:
1195   case VKI_FUTEX_WAIT_REQUEUE_PI:
1196      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1197      if (ARG4 != 0)
1198	 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1199      break;
1200
1201   case VKI_FUTEX_REQUEUE:
1202   case VKI_FUTEX_CMP_REQUEUE:
1203   case VKI_FUTEX_CMP_REQUEUE_PI:
1204   case VKI_FUTEX_WAKE_OP:
1205      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1206      PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1207      break;
1208
1209   case VKI_FUTEX_FD:
1210   case VKI_FUTEX_TRYLOCK_PI:
1211   case VKI_FUTEX_UNLOCK_PI:
1212      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1213     break;
1214
1215   case VKI_FUTEX_WAKE:
1216   case VKI_FUTEX_WAKE_BITSET:
1217      /* no additional pointers */
1218      break;
1219
1220   default:
1221      SET_STATUS_Failure( VKI_ENOSYS );   // some futex function we don't understand
1222      break;
1223   }
1224}
1225POST(sys_futex)
1226{
1227   vg_assert(SUCCESS);
1228   POST_MEM_WRITE( ARG1, sizeof(int) );
1229   if (ARG2 == VKI_FUTEX_FD) {
1230      if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1231         VG_(close)(RES);
1232         SET_STATUS_Failure( VKI_EMFILE );
1233      } else {
1234         if (VG_(clo_track_fds))
1235            ML_(record_fd_open_nameless)(tid, RES);
1236      }
1237   }
1238}
1239
1240PRE(sys_set_robust_list)
1241{
1242   PRINT("sys_set_robust_list ( %#lx, %ld )", ARG1,ARG2);
1243   PRE_REG_READ2(long, "set_robust_list",
1244                 struct vki_robust_list_head *, head, vki_size_t, len);
1245
1246   /* Just check the robust_list_head structure is readable - don't
1247      try and chase the list as the kernel will only read it when
1248      the thread exits so the current contents is irrelevant. */
1249   if (ARG1 != 0)
1250      PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1251}
1252
1253PRE(sys_get_robust_list)
1254{
1255   PRINT("sys_get_robust_list ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
1256   PRE_REG_READ3(long, "get_robust_list",
1257                 int, pid,
1258                 struct vki_robust_list_head **, head_ptr,
1259                 vki_size_t *, len_ptr);
1260   PRE_MEM_WRITE("get_robust_list(head_ptr)",
1261                 ARG2, sizeof(struct vki_robust_list_head *));
1262   PRE_MEM_WRITE("get_robust_list(len_ptr)",
1263                 ARG3, sizeof(struct vki_size_t *));
1264}
1265POST(sys_get_robust_list)
1266{
1267   POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1268   POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1269}
1270
1271PRE(sys_pselect6)
1272{
1273   *flags |= SfMayBlock;
1274   PRINT("sys_pselect6 ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1275   PRE_REG_READ6(long, "pselect6",
1276                 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1277                 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1278                 void *, sig);
1279   // XXX: this possibly understates how much memory is read.
1280   if (ARG2 != 0)
1281      PRE_MEM_READ( "pselect6(readfds)",
1282		     ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1283   if (ARG3 != 0)
1284      PRE_MEM_READ( "pselect6(writefds)",
1285		     ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1286   if (ARG4 != 0)
1287      PRE_MEM_READ( "pselect6(exceptfds)",
1288		     ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1289   if (ARG5 != 0)
1290      PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1291   if (ARG6 != 0)
1292      PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(void *)+sizeof(vki_size_t) );
1293}
1294
1295PRE(sys_ppoll)
1296{
1297   UInt i;
1298   struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1299   *flags |= SfMayBlock;
1300   PRINT("sys_ppoll ( %#lx, %ld, %#lx, %#lx, %llu )\n", ARG1,ARG2,ARG3,ARG4,(ULong)ARG5);
1301   PRE_REG_READ5(long, "ppoll",
1302                 struct vki_pollfd *, ufds, unsigned int, nfds,
1303                 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1304                 vki_size_t, sigsetsize);
1305
1306   for (i = 0; i < ARG2; i++) {
1307      PRE_MEM_READ( "ppoll(ufds.fd)",
1308                    (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1309      PRE_MEM_READ( "ppoll(ufds.events)",
1310                    (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1311      PRE_MEM_WRITE( "ppoll(ufds.revents)",
1312                     (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1313   }
1314
1315   if (ARG3)
1316      PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1317   if (ARG4)
1318      PRE_MEM_READ( "ppoll(sigmask)", ARG4, sizeof(vki_sigset_t) );
1319}
1320
1321POST(sys_ppoll)
1322{
1323   if (RES > 0) {
1324      UInt i;
1325      struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1326      for (i = 0; i < ARG2; i++)
1327	 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1328   }
1329}
1330
1331
1332/* ---------------------------------------------------------------------
1333   epoll_* wrappers
1334   ------------------------------------------------------------------ */
1335
1336PRE(sys_epoll_create)
1337{
1338   PRINT("sys_epoll_create ( %ld )", ARG1);
1339   PRE_REG_READ1(long, "epoll_create", int, size);
1340}
1341POST(sys_epoll_create)
1342{
1343   vg_assert(SUCCESS);
1344   if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1345      VG_(close)(RES);
1346      SET_STATUS_Failure( VKI_EMFILE );
1347   } else {
1348      if (VG_(clo_track_fds))
1349         ML_(record_fd_open_nameless) (tid, RES);
1350   }
1351}
1352
1353PRE(sys_epoll_create1)
1354{
1355   PRINT("sys_epoll_create1 ( %ld )", ARG1);
1356   PRE_REG_READ1(long, "epoll_create1", int, flags);
1357}
1358POST(sys_epoll_create1)
1359{
1360   vg_assert(SUCCESS);
1361   if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1362      VG_(close)(RES);
1363      SET_STATUS_Failure( VKI_EMFILE );
1364   } else {
1365      if (VG_(clo_track_fds))
1366         ML_(record_fd_open_nameless) (tid, RES);
1367   }
1368}
1369
1370PRE(sys_epoll_ctl)
1371{
1372   static const HChar* epoll_ctl_s[3] = {
1373      "EPOLL_CTL_ADD",
1374      "EPOLL_CTL_DEL",
1375      "EPOLL_CTL_MOD"
1376   };
1377   PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#lx )",
1378         ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
1379   PRE_REG_READ4(long, "epoll_ctl",
1380                 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1381   if (ARG2 != VKI_EPOLL_CTL_DEL)
1382      PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1383}
1384
1385PRE(sys_epoll_wait)
1386{
1387   *flags |= SfMayBlock;
1388   PRINT("sys_epoll_wait ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
1389   PRE_REG_READ4(long, "epoll_wait",
1390                 int, epfd, struct vki_epoll_event *, events,
1391                 int, maxevents, int, timeout);
1392   PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1393}
1394POST(sys_epoll_wait)
1395{
1396   vg_assert(SUCCESS);
1397   if (RES > 0)
1398      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1399}
1400
1401PRE(sys_epoll_pwait)
1402{
1403   *flags |= SfMayBlock;
1404   PRINT("sys_epoll_pwait ( %ld, %#lx, %ld, %ld, %#lx, %llu )", ARG1,ARG2,ARG3,ARG4,ARG5,(ULong)ARG6);
1405   PRE_REG_READ6(long, "epoll_pwait",
1406                 int, epfd, struct vki_epoll_event *, events,
1407                 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1408                 vki_size_t, sigsetsize);
1409   PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1410   if (ARG4)
1411      PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1412}
1413POST(sys_epoll_pwait)
1414{
1415   vg_assert(SUCCESS);
1416   if (RES > 0)
1417      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1418}
1419
1420PRE(sys_eventfd)
1421{
1422   PRINT("sys_eventfd ( %lu )", ARG1);
1423   PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1424}
1425POST(sys_eventfd)
1426{
1427   if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1428      VG_(close)(RES);
1429      SET_STATUS_Failure( VKI_EMFILE );
1430   } else {
1431      if (VG_(clo_track_fds))
1432         ML_(record_fd_open_nameless) (tid, RES);
1433   }
1434}
1435
1436PRE(sys_eventfd2)
1437{
1438   PRINT("sys_eventfd2 ( %lu, %ld )", ARG1,ARG2);
1439   PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1440}
1441POST(sys_eventfd2)
1442{
1443   if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1444      VG_(close)(RES);
1445      SET_STATUS_Failure( VKI_EMFILE );
1446   } else {
1447      if (VG_(clo_track_fds))
1448         ML_(record_fd_open_nameless) (tid, RES);
1449   }
1450}
1451
1452PRE(sys_fallocate)
1453{
1454   *flags |= SfMayBlock;
1455#if VG_WORDSIZE == 4
1456   PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1457         ARG1, ARG2, MERGE64(ARG3,ARG4), MERGE64(ARG5,ARG6));
1458   PRE_REG_READ6(long, "fallocate",
1459                 int, fd, int, mode,
1460                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1461                 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1462#elif VG_WORDSIZE == 8
1463   PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1464         ARG1, ARG2, (Long)ARG3, (Long)ARG4);
1465   PRE_REG_READ4(long, "fallocate",
1466                 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1467#else
1468#  error Unexpected word size
1469#endif
1470   if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
1471      SET_STATUS_Failure( VKI_EBADF );
1472}
1473
1474PRE(sys_prlimit64)
1475{
1476   PRINT("sys_prlimit64 ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
1477   PRE_REG_READ4(long, "prlimit64",
1478                 vki_pid_t, pid, unsigned int, resource,
1479                 const struct rlimit64 *, new_rlim,
1480                 struct rlimit64 *, old_rlim);
1481   if (ARG3)
1482      PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
1483   if (ARG4)
1484      PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
1485
1486   if (ARG3 &&
1487       ((struct vki_rlimit64 *)ARG3)->rlim_cur > ((struct vki_rlimit64 *)ARG3)->rlim_max) {
1488      SET_STATUS_Failure( VKI_EINVAL );
1489   }
1490   else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
1491      switch (ARG2) {
1492      case VKI_RLIMIT_NOFILE:
1493         SET_STATUS_Success( 0 );
1494         if (ARG4) {
1495            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(fd_soft_limit);
1496            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(fd_hard_limit);
1497         }
1498         if (ARG3) {
1499            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(fd_hard_limit) ||
1500                ((struct vki_rlimit64 *)ARG3)->rlim_max != VG_(fd_hard_limit)) {
1501               SET_STATUS_Failure( VKI_EPERM );
1502            }
1503            else {
1504               VG_(fd_soft_limit) = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1505            }
1506         }
1507         break;
1508
1509      case VKI_RLIMIT_DATA:
1510         SET_STATUS_Success( 0 );
1511         if (ARG4) {
1512            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_data).rlim_cur;
1513            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_data).rlim_max;
1514         }
1515         if (ARG3) {
1516            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_data).rlim_max ||
1517                ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_data).rlim_max) {
1518               SET_STATUS_Failure( VKI_EPERM );
1519            }
1520            else {
1521               VG_(client_rlimit_data).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1522               VG_(client_rlimit_data).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
1523            }
1524         }
1525         break;
1526
1527      case VKI_RLIMIT_STACK:
1528         SET_STATUS_Success( 0 );
1529         if (ARG4) {
1530            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_stack).rlim_cur;
1531            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_stack).rlim_max;
1532         }
1533         if (ARG3) {
1534            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_stack).rlim_max ||
1535                ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_stack).rlim_max) {
1536               SET_STATUS_Failure( VKI_EPERM );
1537            }
1538            else {
1539               VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1540               VG_(client_rlimit_stack).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1541               VG_(client_rlimit_stack).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
1542           }
1543         }
1544         break;
1545      }
1546   }
1547}
1548
1549POST(sys_prlimit64)
1550{
1551   if (ARG4)
1552      POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
1553}
1554
1555/* ---------------------------------------------------------------------
1556   tid-related wrappers
1557   ------------------------------------------------------------------ */
1558
1559PRE(sys_gettid)
1560{
1561   PRINT("sys_gettid ()");
1562   PRE_REG_READ0(long, "gettid");
1563}
1564
1565PRE(sys_set_tid_address)
1566{
1567   PRINT("sys_set_tid_address ( %#lx )", ARG1);
1568   PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
1569}
1570
1571PRE(sys_tkill)
1572{
1573   PRINT("sys_tgkill ( %ld, %ld )", ARG1,ARG2);
1574   PRE_REG_READ2(long, "tkill", int, tid, int, sig);
1575   if (!ML_(client_signal_OK)(ARG2)) {
1576      SET_STATUS_Failure( VKI_EINVAL );
1577      return;
1578   }
1579
1580   /* Check to see if this kill gave us a pending signal */
1581   *flags |= SfPollAfter;
1582
1583   if (VG_(clo_trace_signals))
1584      VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
1585		   ARG2, ARG1);
1586
1587   /* If we're sending SIGKILL, check to see if the target is one of
1588      our threads and handle it specially. */
1589   if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
1590      SET_STATUS_Success(0);
1591      return;
1592   }
1593
1594   /* Ask to handle this syscall via the slow route, since that's the
1595      only one that sets tst->status to VgTs_WaitSys.  If the result
1596      of doing the syscall is an immediate run of
1597      async_signalhandler() in m_signals, then we need the thread to
1598      be properly tidied away.  I have the impression the previous
1599      version of this wrapper worked on x86/amd64 only because the
1600      kernel did not immediately deliver the async signal to this
1601      thread (on ppc it did, which broke the assertion re tst->status
1602      at the top of async_signalhandler()). */
1603   *flags |= SfMayBlock;
1604}
1605POST(sys_tkill)
1606{
1607   if (VG_(clo_trace_signals))
1608      VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
1609                   ARG2, ARG1);
1610}
1611
1612PRE(sys_tgkill)
1613{
1614   PRINT("sys_tgkill ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
1615   PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
1616   if (!ML_(client_signal_OK)(ARG3)) {
1617      SET_STATUS_Failure( VKI_EINVAL );
1618      return;
1619   }
1620
1621   /* Check to see if this kill gave us a pending signal */
1622   *flags |= SfPollAfter;
1623
1624   if (VG_(clo_trace_signals))
1625      VG_(message)(Vg_DebugMsg,
1626                   "tgkill: sending signal %ld to pid %ld/%ld\n",
1627		   ARG3, ARG1, ARG2);
1628
1629   /* If we're sending SIGKILL, check to see if the target is one of
1630      our threads and handle it specially. */
1631   if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
1632      SET_STATUS_Success(0);
1633      return;
1634   }
1635
1636   /* Ask to handle this syscall via the slow route, since that's the
1637      only one that sets tst->status to VgTs_WaitSys.  If the result
1638      of doing the syscall is an immediate run of
1639      async_signalhandler() in m_signals, then we need the thread to
1640      be properly tidied away.  I have the impression the previous
1641      version of this wrapper worked on x86/amd64 only because the
1642      kernel did not immediately deliver the async signal to this
1643      thread (on ppc it did, which broke the assertion re tst->status
1644      at the top of async_signalhandler()). */
1645   *flags |= SfMayBlock;
1646}
1647POST(sys_tgkill)
1648{
1649   if (VG_(clo_trace_signals))
1650      VG_(message)(Vg_DebugMsg,
1651                   "tgkill: sent signal %ld to pid %ld/%ld\n",
1652                   ARG3, ARG1, ARG2);
1653}
1654
1655/* ---------------------------------------------------------------------
1656   fadvise64* wrappers
1657   ------------------------------------------------------------------ */
1658
1659PRE(sys_fadvise64)
1660{
1661   PRINT("sys_fadvise64 ( %ld, %lld, %lu, %ld )",
1662         ARG1, MERGE64(ARG2,ARG3), ARG4, ARG5);
1663   PRE_REG_READ5(long, "fadvise64",
1664                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
1665                 vki_size_t, len, int, advice);
1666}
1667
1668PRE(sys_fadvise64_64)
1669{
1670   PRINT("sys_fadvise64_64 ( %ld, %lld, %lld, %ld )",
1671         ARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), ARG6);
1672   PRE_REG_READ6(long, "fadvise64_64",
1673                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
1674                 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
1675}
1676
1677/* ---------------------------------------------------------------------
1678   io_* wrappers
1679   ------------------------------------------------------------------ */
1680
1681// Nb: this wrapper has to pad/unpad memory around the syscall itself,
1682// and this allows us to control exactly the code that gets run while
1683// the padding is in place.
1684
1685PRE(sys_io_setup)
1686{
1687   PRINT("sys_io_setup ( %lu, %#lx )", ARG1,ARG2);
1688   PRE_REG_READ2(long, "io_setup",
1689                 unsigned, nr_events, vki_aio_context_t *, ctxp);
1690   PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
1691}
1692
1693POST(sys_io_setup)
1694{
1695   SizeT size;
1696   struct vki_aio_ring *r;
1697
1698   size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
1699                       ARG1*sizeof(struct vki_io_event));
1700   r = *(struct vki_aio_ring **)ARG2;
1701   vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
1702
1703   ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
1704                                      VKI_PROT_READ | VKI_PROT_WRITE,
1705                                      VKI_MAP_ANONYMOUS, -1, 0 );
1706
1707   POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
1708}
1709
1710// Nb: This wrapper is "Special" because we need 'size' to do the unmap
1711// after the syscall.  We must get 'size' from the aio_ring structure,
1712// before the syscall, while the aio_ring structure still exists.  (And we
1713// know that we must look at the aio_ring structure because Tom inspected the
1714// kernel and glibc sources to see what they do, yuk.)
1715//
1716// XXX This segment can be implicitly unmapped when aio
1717// file-descriptors are closed...
1718PRE(sys_io_destroy)
1719{
1720   SizeT size = 0;
1721
1722   PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
1723   PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
1724
1725   // If we are going to seg fault (due to a bogus ARG1) do it as late as
1726   // possible...
1727   if (ML_(safe_to_deref)( (void*)ARG1, sizeof(struct vki_aio_ring))) {
1728      struct vki_aio_ring *r = (struct vki_aio_ring *)ARG1;
1729      size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
1730                          r->nr*sizeof(struct vki_io_event));
1731   }
1732
1733   SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
1734
1735   if (SUCCESS && RES == 0) {
1736      Bool d = VG_(am_notify_munmap)( ARG1, size );
1737      VG_TRACK( die_mem_munmap, ARG1, size );
1738      if (d)
1739        VG_(discard_translations)( (Addr)ARG1, (ULong)size,
1740                                    "PRE(sys_io_destroy)" );
1741   }
1742}
1743
1744PRE(sys_io_getevents)
1745{
1746   *flags |= SfMayBlock;
1747   PRINT("sys_io_getevents ( %llu, %lld, %lld, %#lx, %#lx )",
1748         (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
1749   PRE_REG_READ5(long, "io_getevents",
1750                 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
1751                 struct io_event *, events,
1752                 struct timespec *, timeout);
1753   if (ARG3 > 0)
1754      PRE_MEM_WRITE( "io_getevents(events)",
1755                     ARG4, sizeof(struct vki_io_event)*ARG3 );
1756   if (ARG5 != 0)
1757      PRE_MEM_READ( "io_getevents(timeout)",
1758                    ARG5, sizeof(struct vki_timespec));
1759}
1760POST(sys_io_getevents)
1761{
1762   Int i;
1763   vg_assert(SUCCESS);
1764   if (RES > 0) {
1765      POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
1766      for (i = 0; i < RES; i++) {
1767         const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
1768         const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
1769
1770         switch (cb->aio_lio_opcode) {
1771         case VKI_IOCB_CMD_PREAD:
1772            if (vev->result > 0)
1773               POST_MEM_WRITE( cb->aio_buf, vev->result );
1774            break;
1775
1776         case VKI_IOCB_CMD_PWRITE:
1777            break;
1778
1779         case VKI_IOCB_CMD_FSYNC:
1780            break;
1781
1782         case VKI_IOCB_CMD_FDSYNC:
1783            break;
1784
1785         case VKI_IOCB_CMD_PREADV:
1786	     if (vev->result > 0) {
1787                  struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
1788                  Int remains = vev->result;
1789                  Int j;
1790
1791                  for (j = 0; j < cb->aio_nbytes; j++) {
1792                       Int nReadThisBuf = vec[j].iov_len;
1793                       if (nReadThisBuf > remains) nReadThisBuf = remains;
1794                       POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
1795                       remains -= nReadThisBuf;
1796                       if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
1797                  }
1798	     }
1799             break;
1800
1801         case VKI_IOCB_CMD_PWRITEV:
1802             break;
1803
1804         default:
1805            VG_(message)(Vg_DebugMsg,
1806                        "Warning: unhandled io_getevents opcode: %u\n",
1807                        cb->aio_lio_opcode);
1808            break;
1809         }
1810      }
1811   }
1812}
1813
1814PRE(sys_io_submit)
1815{
1816   Int i, j;
1817
1818   PRINT("sys_io_submit ( %llu, %ld, %#lx )", (ULong)ARG1,ARG2,ARG3);
1819   PRE_REG_READ3(long, "io_submit",
1820                 vki_aio_context_t, ctx_id, long, nr,
1821                 struct iocb **, iocbpp);
1822   PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
1823   if (ARG3 != 0) {
1824      for (i = 0; i < ARG2; i++) {
1825         struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
1826         struct vki_iovec *iov;
1827
1828         PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
1829         switch (cb->aio_lio_opcode) {
1830         case VKI_IOCB_CMD_PREAD:
1831            PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
1832            break;
1833
1834         case VKI_IOCB_CMD_PWRITE:
1835            PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
1836            break;
1837
1838         case VKI_IOCB_CMD_FSYNC:
1839            break;
1840
1841         case VKI_IOCB_CMD_FDSYNC:
1842            break;
1843
1844         case VKI_IOCB_CMD_PREADV:
1845            iov = (struct vki_iovec *)(Addr)cb->aio_buf;
1846            PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
1847            for (j = 0; j < cb->aio_nbytes; j++)
1848                PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
1849            break;
1850
1851         case VKI_IOCB_CMD_PWRITEV:
1852            iov = (struct vki_iovec *)(Addr)cb->aio_buf;
1853            PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
1854            for (j = 0; j < cb->aio_nbytes; j++)
1855                PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
1856            break;
1857
1858         default:
1859            VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
1860                         cb->aio_lio_opcode);
1861            break;
1862         }
1863      }
1864   }
1865}
1866
1867PRE(sys_io_cancel)
1868{
1869   PRINT("sys_io_cancel ( %llu, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3);
1870   PRE_REG_READ3(long, "io_cancel",
1871                 vki_aio_context_t, ctx_id, struct iocb *, iocb,
1872                 struct io_event *, result);
1873   PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
1874   PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
1875}
1876POST(sys_io_cancel)
1877{
1878   POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
1879}
1880
1881/* ---------------------------------------------------------------------
1882   *_mempolicy wrappers
1883   ------------------------------------------------------------------ */
1884
1885PRE(sys_mbind)
1886{
1887   PRINT("sys_mbind ( %#lx, %lu, %ld, %#lx, %lu, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1888   PRE_REG_READ6(long, "mbind",
1889                 unsigned long, start, unsigned long, len,
1890                 unsigned long, policy, unsigned long *, nodemask,
1891                 unsigned long, maxnode, unsigned, flags);
1892   if (ARG1 != 0)
1893      PRE_MEM_READ( "mbind(nodemask)", ARG4,
1894                    VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
1895}
1896
1897PRE(sys_set_mempolicy)
1898{
1899   PRINT("sys_set_mempolicy ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
1900   PRE_REG_READ3(long, "set_mempolicy",
1901                 int, policy, unsigned long *, nodemask,
1902                 unsigned long, maxnode);
1903   PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
1904                 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
1905}
1906
1907PRE(sys_get_mempolicy)
1908{
1909   PRINT("sys_get_mempolicy ( %#lx, %#lx, %ld, %#lx, %lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
1910   PRE_REG_READ5(long, "get_mempolicy",
1911                 int *, policy, unsigned long *, nodemask,
1912                 unsigned long, maxnode, unsigned long, addr,
1913                 unsigned long, flags);
1914   if (ARG1 != 0)
1915      PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
1916   if (ARG2 != 0)
1917      PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
1918                     VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
1919}
1920POST(sys_get_mempolicy)
1921{
1922   if (ARG1 != 0)
1923      POST_MEM_WRITE( ARG1, sizeof(Int) );
1924   if (ARG2 != 0)
1925      POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
1926}
1927
1928/* ---------------------------------------------------------------------
1929   fanotify_* wrappers
1930   ------------------------------------------------------------------ */
1931
1932PRE(sys_fanotify_init)
1933{
1934   PRINT("sys_fanotify_init ( %lu, %lu )", ARG1,ARG2);
1935   PRE_REG_READ2(long, "fanotify_init",
1936                 unsigned int, flags, unsigned int, event_f_flags);
1937}
1938
1939POST(sys_fanotify_init)
1940{
1941   vg_assert(SUCCESS);
1942   if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
1943      VG_(close)(RES);
1944      SET_STATUS_Failure( VKI_EMFILE );
1945   } else {
1946      if (VG_(clo_track_fds))
1947         ML_(record_fd_open_nameless) (tid, RES);
1948   }
1949}
1950
1951PRE(sys_fanotify_mark)
1952{
1953#if VG_WORDSIZE == 4
1954   PRINT( "sys_fanotify_mark ( %ld, %lu, %llu, %ld, %#lx(%s))",
1955          ARG1,ARG2,MERGE64(ARG3,ARG4),ARG5,ARG6,(char *)ARG6);
1956   PRE_REG_READ6(long, "sys_fanotify_mark",
1957                 int, fanotify_fd, unsigned int, flags,
1958                 __vki_u32, mask0, __vki_u32, mask1,
1959                 int, dfd, const char *, pathname);
1960   if (ARG6)
1961      PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
1962#elif VG_WORDSIZE == 8
1963   PRINT( "sys_fanotify_mark ( %ld, %lu, %llu, %ld, %#lx(%s))",
1964           ARG1,ARG2,(ULong)ARG3,ARG4,ARG5,(char *)ARG5);
1965   PRE_REG_READ5(long, "sys_fanotify_mark",
1966                 int, fanotify_fd, unsigned int, flags,
1967                 __vki_u64, mask,
1968                 int, dfd, const char *, pathname);
1969   if (ARG5)
1970      PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
1971#else
1972#  error Unexpected word size
1973#endif
1974}
1975
1976/* ---------------------------------------------------------------------
1977   inotify_* wrappers
1978   ------------------------------------------------------------------ */
1979
1980PRE(sys_inotify_init)
1981{
1982   PRINT("sys_inotify_init ( )");
1983   PRE_REG_READ0(long, "inotify_init");
1984}
1985POST(sys_inotify_init)
1986{
1987   vg_assert(SUCCESS);
1988   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
1989      VG_(close)(RES);
1990      SET_STATUS_Failure( VKI_EMFILE );
1991   } else {
1992      if (VG_(clo_track_fds))
1993         ML_(record_fd_open_nameless) (tid, RES);
1994   }
1995}
1996
1997PRE(sys_inotify_init1)
1998{
1999   PRINT("sys_inotify_init ( %ld )", ARG1);
2000   PRE_REG_READ1(long, "inotify_init", int, flag);
2001}
2002
2003POST(sys_inotify_init1)
2004{
2005   vg_assert(SUCCESS);
2006   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2007      VG_(close)(RES);
2008      SET_STATUS_Failure( VKI_EMFILE );
2009   } else {
2010      if (VG_(clo_track_fds))
2011         ML_(record_fd_open_nameless) (tid, RES);
2012   }
2013}
2014
2015PRE(sys_inotify_add_watch)
2016{
2017   PRINT( "sys_inotify_add_watch ( %ld, %#lx, %lx )", ARG1,ARG2,ARG3);
2018   PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2019   PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2020}
2021
2022PRE(sys_inotify_rm_watch)
2023{
2024   PRINT( "sys_inotify_rm_watch ( %ld, %lx )", ARG1,ARG2);
2025   PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2026}
2027
2028/* ---------------------------------------------------------------------
2029   mq_* wrappers
2030   ------------------------------------------------------------------ */
2031
2032PRE(sys_mq_open)
2033{
2034   PRINT("sys_mq_open( %#lx(%s), %ld, %lld, %#lx )",
2035         ARG1,(char*)ARG1,ARG2,(ULong)ARG3,ARG4);
2036   PRE_REG_READ4(long, "mq_open",
2037                 const char *, name, int, oflag, vki_mode_t, mode,
2038                 struct mq_attr *, attr);
2039   PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2040   if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2041      const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
2042      PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2043                     (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2044      PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2045                     (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2046   }
2047}
2048POST(sys_mq_open)
2049{
2050   vg_assert(SUCCESS);
2051   if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2052      VG_(close)(RES);
2053      SET_STATUS_Failure( VKI_EMFILE );
2054   } else {
2055      if (VG_(clo_track_fds))
2056         ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1);
2057   }
2058}
2059
2060PRE(sys_mq_unlink)
2061{
2062   PRINT("sys_mq_unlink ( %#lx(%s) )", ARG1,(char*)ARG1);
2063   PRE_REG_READ1(long, "mq_unlink", const char *, name);
2064   PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2065}
2066
2067PRE(sys_mq_timedsend)
2068{
2069   *flags |= SfMayBlock;
2070   PRINT("sys_mq_timedsend ( %ld, %#lx, %llu, %ld, %#lx )",
2071         ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
2072   PRE_REG_READ5(long, "mq_timedsend",
2073                 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2074                 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2075   if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2076      SET_STATUS_Failure( VKI_EBADF );
2077   } else {
2078      PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2079      if (ARG5 != 0)
2080         PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2081                        sizeof(struct vki_timespec) );
2082   }
2083}
2084
2085PRE(sys_mq_timedreceive)
2086{
2087   *flags |= SfMayBlock;
2088   PRINT("sys_mq_timedreceive( %ld, %#lx, %llu, %#lx, %#lx )",
2089         ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
2090   PRE_REG_READ5(ssize_t, "mq_timedreceive",
2091                 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2092                 unsigned int *, msg_prio,
2093                 const struct timespec *, abs_timeout);
2094   if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2095      SET_STATUS_Failure( VKI_EBADF );
2096   } else {
2097      PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2098      if (ARG4 != 0)
2099         PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2100                        ARG4, sizeof(unsigned int) );
2101      if (ARG5 != 0)
2102         PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2103                        ARG5, sizeof(struct vki_timespec) );
2104   }
2105}
2106POST(sys_mq_timedreceive)
2107{
2108   POST_MEM_WRITE( ARG2, RES );
2109   if (ARG4 != 0)
2110      POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2111}
2112
2113PRE(sys_mq_notify)
2114{
2115   PRINT("sys_mq_notify( %ld, %#lx )", ARG1,ARG2 );
2116   PRE_REG_READ2(long, "mq_notify",
2117                 vki_mqd_t, mqdes, const struct sigevent *, notification);
2118   if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2119      SET_STATUS_Failure( VKI_EBADF );
2120   else if (ARG2 != 0)
2121      PRE_MEM_READ( "mq_notify(notification)",
2122                    ARG2, sizeof(struct vki_sigevent) );
2123}
2124
2125PRE(sys_mq_getsetattr)
2126{
2127   PRINT("sys_mq_getsetattr( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3 );
2128   PRE_REG_READ3(long, "mq_getsetattr",
2129                 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2130                 struct mq_attr *, omqstat);
2131   if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2132      SET_STATUS_Failure( VKI_EBADF );
2133   } else {
2134      if (ARG2 != 0) {
2135         const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
2136         PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2137                        (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2138      }
2139      if (ARG3 != 0)
2140         PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2141                        sizeof(struct vki_mq_attr) );
2142   }
2143}
2144POST(sys_mq_getsetattr)
2145{
2146   if (ARG3 != 0)
2147      POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2148}
2149
2150/* ---------------------------------------------------------------------
2151   clock_* wrappers
2152   ------------------------------------------------------------------ */
2153
2154PRE(sys_clock_settime)
2155{
2156   PRINT("sys_clock_settime( %ld, %#lx )", ARG1,ARG2);
2157   PRE_REG_READ2(long, "clock_settime",
2158                 vki_clockid_t, clk_id, const struct timespec *, tp);
2159   PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2160}
2161
2162PRE(sys_clock_gettime)
2163{
2164   PRINT("sys_clock_gettime( %ld, %#lx )" , ARG1,ARG2);
2165   PRE_REG_READ2(long, "clock_gettime",
2166                 vki_clockid_t, clk_id, struct timespec *, tp);
2167   PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2168}
2169POST(sys_clock_gettime)
2170{
2171   POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2172}
2173
2174PRE(sys_clock_getres)
2175{
2176   PRINT("sys_clock_getres( %ld, %#lx )" , ARG1,ARG2);
2177   // Nb: we can't use "RES" as the param name because that's a macro
2178   // defined above!
2179   PRE_REG_READ2(long, "clock_getres",
2180                 vki_clockid_t, clk_id, struct timespec *, res);
2181   if (ARG2 != 0)
2182      PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2183}
2184POST(sys_clock_getres)
2185{
2186   if (ARG2 != 0)
2187      POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2188}
2189
2190PRE(sys_clock_nanosleep)
2191{
2192   *flags |= SfMayBlock|SfPostOnFail;
2193   PRINT("sys_clock_nanosleep( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
2194   PRE_REG_READ4(int32_t, "clock_nanosleep",
2195                 vki_clockid_t, clkid, int, flags,
2196                 const struct timespec *, rqtp, struct timespec *, rmtp);
2197   PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2198   if (ARG4 != 0)
2199      PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2200}
2201POST(sys_clock_nanosleep)
2202{
2203   if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2204      POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2205}
2206
2207/* ---------------------------------------------------------------------
2208   timer_* wrappers
2209   ------------------------------------------------------------------ */
2210
2211PRE(sys_timer_create)
2212{
2213   PRINT("sys_timer_create( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
2214   PRE_REG_READ3(long, "timer_create",
2215                 vki_clockid_t, clockid, struct sigevent *, evp,
2216                 vki_timer_t *, timerid);
2217   if (ARG2 != 0) {
2218      struct vki_sigevent *evp = (struct vki_sigevent *) ARG2;
2219      PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2220                    sizeof(vki_sigval_t) );
2221      PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2222                    sizeof(int) );
2223      PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2224                    sizeof(int) );
2225      if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2226          && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2227         PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2228                       (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2229   }
2230   PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2231}
2232POST(sys_timer_create)
2233{
2234   POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2235}
2236
2237PRE(sys_timer_settime)
2238{
2239   PRINT("sys_timer_settime( %lld, %ld, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3,ARG4);
2240   PRE_REG_READ4(long, "timer_settime",
2241                 vki_timer_t, timerid, int, flags,
2242                 const struct itimerspec *, value,
2243                 struct itimerspec *, ovalue);
2244   PRE_MEM_READ( "timer_settime(value)", ARG3,
2245                  sizeof(struct vki_itimerspec) );
2246   if (ARG4 != 0)
2247       PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2248                      sizeof(struct vki_itimerspec) );
2249}
2250POST(sys_timer_settime)
2251{
2252   if (ARG4 != 0)
2253      POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2254}
2255
2256PRE(sys_timer_gettime)
2257{
2258   PRINT("sys_timer_gettime( %lld, %#lx )", (ULong)ARG1,ARG2);
2259   PRE_REG_READ2(long, "timer_gettime",
2260                 vki_timer_t, timerid, struct itimerspec *, value);
2261   PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2262                  sizeof(struct vki_itimerspec));
2263}
2264POST(sys_timer_gettime)
2265{
2266   POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2267}
2268
2269PRE(sys_timer_getoverrun)
2270{
2271   PRINT("sys_timer_getoverrun( %#lx )", ARG1);
2272   PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2273}
2274
2275PRE(sys_timer_delete)
2276{
2277   PRINT("sys_timer_delete( %#lx )", ARG1);
2278   PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2279}
2280
2281/* ---------------------------------------------------------------------
2282   timerfd* wrappers
2283   See also http://lwn.net/Articles/260172/ for an overview.
2284   See also /usr/src/linux/fs/timerfd.c for the implementation.
2285   ------------------------------------------------------------------ */
2286
2287/* Returns True if running on 2.6.22, else False (or False if
2288   cannot be determined). */
2289static Bool linux_kernel_2_6_22(void)
2290{
2291   static Int result = -1;
2292   Int fd, read;
2293   HChar release[64];   // large enough
2294   SysRes res;
2295
2296   if (result == -1) {
2297      res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2298      if (sr_isError(res))
2299         return False;
2300      fd = sr_Res(res);
2301      read = VG_(read)(fd, release, sizeof(release) - 1);
2302      if (read < 0)
2303         return False;
2304      release[read] = 0;
2305      VG_(close)(fd);
2306      //VG_(printf)("kernel release = %s\n", release);
2307      result = VG_(strncmp)(release, "2.6.22", 6) == 0
2308               && ! VG_(isdigit)(release[6]);
2309   }
2310   vg_assert(result == 0 || result == 1);
2311   return result == 1;
2312}
2313
2314PRE(sys_timerfd_create)
2315{
2316   if (linux_kernel_2_6_22()) {
2317      /* 2.6.22 kernel: timerfd system call. */
2318      PRINT("sys_timerfd ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
2319      PRE_REG_READ3(long, "sys_timerfd",
2320                    int, fd, int, clockid, const struct itimerspec *, tmr);
2321      PRE_MEM_READ("timerfd(tmr)", ARG3,
2322                   sizeof(struct vki_itimerspec) );
2323      if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2324         SET_STATUS_Failure( VKI_EBADF );
2325   } else {
2326      /* 2.6.24 and later kernels: timerfd_create system call. */
2327      PRINT("sys_timerfd_create (%ld, %ld )", ARG1, ARG2);
2328      PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2329   }
2330}
2331POST(sys_timerfd_create)
2332{
2333   if (linux_kernel_2_6_22())
2334   {
2335      /* 2.6.22 kernel: timerfd system call. */
2336      if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2337         VG_(close)(RES);
2338         SET_STATUS_Failure( VKI_EMFILE );
2339      } else {
2340         if (VG_(clo_track_fds))
2341            ML_(record_fd_open_nameless) (tid, RES);
2342      }
2343   }
2344   else
2345   {
2346      /* 2.6.24 and later kernels: timerfd_create system call. */
2347      if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2348         VG_(close)(RES);
2349         SET_STATUS_Failure( VKI_EMFILE );
2350      } else {
2351         if (VG_(clo_track_fds))
2352            ML_(record_fd_open_nameless) (tid, RES);
2353      }
2354   }
2355}
2356
2357PRE(sys_timerfd_gettime)
2358{
2359   PRINT("sys_timerfd_gettime ( %ld, %#lx )", ARG1, ARG2);
2360   PRE_REG_READ2(long, "timerfd_gettime",
2361                 int, ufd,
2362                 struct vki_itimerspec*, otmr);
2363   if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2364      SET_STATUS_Failure(VKI_EBADF);
2365   else
2366      PRE_MEM_WRITE("timerfd_gettime(result)",
2367                    ARG2, sizeof(struct vki_itimerspec));
2368}
2369POST(sys_timerfd_gettime)
2370{
2371   if (RES == 0)
2372      POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2373}
2374
2375PRE(sys_timerfd_settime)
2376{
2377   PRINT("sys_timerfd_settime ( %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
2378   PRE_REG_READ4(long, "timerfd_settime",
2379                 int, ufd,
2380                 int, flags,
2381                 const struct vki_itimerspec*, utmr,
2382                 struct vki_itimerspec*, otmr);
2383   if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2384      SET_STATUS_Failure(VKI_EBADF);
2385   else
2386   {
2387      PRE_MEM_READ("timerfd_settime(result)",
2388                   ARG3, sizeof(struct vki_itimerspec));
2389      if (ARG4)
2390      {
2391         PRE_MEM_WRITE("timerfd_settime(result)",
2392                       ARG4, sizeof(struct vki_itimerspec));
2393      }
2394   }
2395}
2396POST(sys_timerfd_settime)
2397{
2398   if (RES == 0 && ARG4 != 0)
2399      POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2400}
2401
2402/* ---------------------------------------------------------------------
2403   capabilities wrappers
2404   ------------------------------------------------------------------ */
2405
2406PRE(sys_capget)
2407{
2408   PRINT("sys_capget ( %#lx, %#lx )", ARG1, ARG2 );
2409   PRE_REG_READ2(long, "capget",
2410                 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2411   PRE_MEM_READ( "capget(header)", ARG1,
2412                  sizeof(struct __vki_user_cap_header_struct) );
2413   if (ARG2 != (Addr)NULL)
2414      PRE_MEM_WRITE( "capget(data)", ARG2,
2415                     sizeof(struct __vki_user_cap_data_struct) );
2416}
2417POST(sys_capget)
2418{
2419   if (ARG2 != (Addr)NULL)
2420      POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2421}
2422
2423PRE(sys_capset)
2424{
2425   PRINT("sys_capset ( %#lx, %#lx )", ARG1, ARG2 );
2426   PRE_REG_READ2(long, "capset",
2427                 vki_cap_user_header_t, header,
2428                 const vki_cap_user_data_t, data);
2429   PRE_MEM_READ( "capset(header)",
2430                  ARG1, sizeof(struct __vki_user_cap_header_struct) );
2431   PRE_MEM_READ( "capset(data)",
2432                  ARG2, sizeof(struct __vki_user_cap_data_struct) );
2433}
2434
2435/* ---------------------------------------------------------------------
2436   16-bit uid/gid/groups wrappers
2437   ------------------------------------------------------------------ */
2438
2439PRE(sys_getuid16)
2440{
2441   PRINT("sys_getuid16 ( )");
2442   PRE_REG_READ0(long, "getuid16");
2443}
2444
2445PRE(sys_setuid16)
2446{
2447   PRINT("sys_setuid16 ( %ld )", ARG1);
2448   PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
2449}
2450
2451PRE(sys_getgid16)
2452{
2453   PRINT("sys_getgid16 ( )");
2454   PRE_REG_READ0(long, "getgid16");
2455}
2456
2457PRE(sys_setgid16)
2458{
2459   PRINT("sys_setgid16 ( %ld )", ARG1);
2460   PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
2461}
2462
2463PRE(sys_geteuid16)
2464{
2465   PRINT("sys_geteuid16 ( )");
2466   PRE_REG_READ0(long, "geteuid16");
2467}
2468
2469PRE(sys_getegid16)
2470{
2471   PRINT("sys_getegid16 ( )");
2472   PRE_REG_READ0(long, "getegid16");
2473}
2474
2475PRE(sys_setreuid16)
2476{
2477   PRINT("setreuid16 ( 0x%lx, 0x%lx )", ARG1, ARG2);
2478   PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
2479}
2480
2481PRE(sys_setregid16)
2482{
2483   PRINT("sys_setregid16 ( %ld, %ld )", ARG1, ARG2);
2484   PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2485}
2486
2487PRE(sys_getgroups16)
2488{
2489   PRINT("sys_getgroups16 ( %ld, %#lx )", ARG1, ARG2);
2490   PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2491   if (ARG1 > 0)
2492      PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2493}
2494POST(sys_getgroups16)
2495{
2496   vg_assert(SUCCESS);
2497   if (ARG1 > 0 && RES > 0)
2498      POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2499}
2500
2501PRE(sys_setgroups16)
2502{
2503   PRINT("sys_setgroups16 ( %llu, %#lx )", (ULong)ARG1, ARG2);
2504   PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
2505   if (ARG1 > 0)
2506      PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2507}
2508
2509/* ---------------------------------------------------------------------
2510   *chown16 wrappers
2511   ------------------------------------------------------------------ */
2512
2513PRE(sys_chown16)
2514{
2515   PRINT("sys_chown16 ( %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3);
2516   PRE_REG_READ3(long, "chown16",
2517                 const char *, path,
2518                 vki_old_uid_t, owner, vki_old_gid_t, group);
2519   PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
2520}
2521
2522PRE(sys_fchown16)
2523{
2524   PRINT("sys_fchown16 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
2525   PRE_REG_READ3(long, "fchown16",
2526                 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
2527}
2528
2529/* ---------------------------------------------------------------------
2530   *xattr wrappers
2531   ------------------------------------------------------------------ */
2532
2533PRE(sys_setxattr)
2534{
2535   *flags |= SfMayBlock;
2536   PRINT("sys_setxattr ( %#lx, %#lx, %#lx, %llu, %ld )",
2537         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2538   PRE_REG_READ5(long, "setxattr",
2539                 char *, path, char *, name,
2540                 void *, value, vki_size_t, size, int, flags);
2541   PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
2542   PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
2543   PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
2544}
2545
2546PRE(sys_lsetxattr)
2547{
2548   *flags |= SfMayBlock;
2549   PRINT("sys_lsetxattr ( %#lx, %#lx, %#lx, %llu, %ld )",
2550         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2551   PRE_REG_READ5(long, "lsetxattr",
2552                 char *, path, char *, name,
2553                 void *, value, vki_size_t, size, int, flags);
2554   PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
2555   PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
2556   PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
2557}
2558
2559PRE(sys_fsetxattr)
2560{
2561   *flags |= SfMayBlock;
2562   PRINT("sys_fsetxattr ( %ld, %#lx, %#lx, %llu, %ld )",
2563         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2564   PRE_REG_READ5(long, "fsetxattr",
2565                 int, fd, char *, name, void *, value,
2566                 vki_size_t, size, int, flags);
2567   PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
2568   PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
2569}
2570
2571PRE(sys_getxattr)
2572{
2573   *flags |= SfMayBlock;
2574   PRINT("sys_getxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
2575   PRE_REG_READ4(ssize_t, "getxattr",
2576                 char *, path, char *, name, void *, value, vki_size_t, size);
2577   PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
2578   PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
2579   PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
2580}
2581POST(sys_getxattr)
2582{
2583   vg_assert(SUCCESS);
2584   if (RES > 0 && ARG3 != (Addr)NULL) {
2585      POST_MEM_WRITE( ARG3, RES );
2586   }
2587}
2588
2589PRE(sys_lgetxattr)
2590{
2591   *flags |= SfMayBlock;
2592   PRINT("sys_lgetxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
2593   PRE_REG_READ4(ssize_t, "lgetxattr",
2594                 char *, path, char *, name, void *, value, vki_size_t, size);
2595   PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
2596   PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
2597   PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
2598}
2599POST(sys_lgetxattr)
2600{
2601   vg_assert(SUCCESS);
2602   if (RES > 0 && ARG3 != (Addr)NULL) {
2603      POST_MEM_WRITE( ARG3, RES );
2604   }
2605}
2606
2607PRE(sys_fgetxattr)
2608{
2609   *flags |= SfMayBlock;
2610   PRINT("sys_fgetxattr ( %ld, %#lx, %#lx, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
2611   PRE_REG_READ4(ssize_t, "fgetxattr",
2612                 int, fd, char *, name, void *, value, vki_size_t, size);
2613   PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
2614   PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
2615}
2616POST(sys_fgetxattr)
2617{
2618   if (RES > 0 && ARG3 != (Addr)NULL)
2619      POST_MEM_WRITE( ARG3, RES );
2620}
2621
2622PRE(sys_listxattr)
2623{
2624   *flags |= SfMayBlock;
2625   PRINT("sys_listxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
2626   PRE_REG_READ3(ssize_t, "listxattr",
2627                 char *, path, char *, list, vki_size_t, size);
2628   PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
2629   PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
2630}
2631POST(sys_listxattr)
2632{
2633   if (RES > 0 && ARG2 != (Addr)NULL)
2634      POST_MEM_WRITE( ARG2, RES );
2635}
2636
2637PRE(sys_llistxattr)
2638{
2639   *flags |= SfMayBlock;
2640   PRINT("sys_llistxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
2641   PRE_REG_READ3(ssize_t, "llistxattr",
2642                 char *, path, char *, list, vki_size_t, size);
2643   PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
2644   PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
2645}
2646POST(sys_llistxattr)
2647{
2648   if (RES > 0 && ARG2 != (Addr)NULL)
2649      POST_MEM_WRITE( ARG2, RES );
2650}
2651
2652PRE(sys_flistxattr)
2653{
2654   *flags |= SfMayBlock;
2655   PRINT("sys_flistxattr ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
2656   PRE_REG_READ3(ssize_t, "flistxattr",
2657                 int, fd, char *, list, vki_size_t, size);
2658   PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
2659}
2660POST(sys_flistxattr)
2661{
2662   if (RES > 0 && ARG2 != (Addr)NULL)
2663      POST_MEM_WRITE( ARG2, RES );
2664}
2665
2666PRE(sys_removexattr)
2667{
2668   *flags |= SfMayBlock;
2669   PRINT("sys_removexattr ( %#lx, %#lx )", ARG1, ARG2);
2670   PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
2671   PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
2672   PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
2673}
2674
2675PRE(sys_lremovexattr)
2676{
2677   *flags |= SfMayBlock;
2678   PRINT("sys_lremovexattr ( %#lx, %#lx )", ARG1, ARG2);
2679   PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
2680   PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
2681   PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
2682}
2683
2684PRE(sys_fremovexattr)
2685{
2686   *flags |= SfMayBlock;
2687   PRINT("sys_fremovexattr ( %ld, %#lx )", ARG1, ARG2);
2688   PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
2689   PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
2690}
2691
2692/* ---------------------------------------------------------------------
2693   sched_* wrappers
2694   ------------------------------------------------------------------ */
2695
2696PRE(sys_sched_setparam)
2697{
2698   PRINT("sched_setparam ( %ld, %#lx )", ARG1, ARG2 );
2699   PRE_REG_READ2(long, "sched_setparam",
2700                 vki_pid_t, pid, struct sched_param *, p);
2701   PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
2702}
2703POST(sys_sched_setparam)
2704{
2705   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
2706}
2707
2708PRE(sys_sched_getparam)
2709{
2710   PRINT("sched_getparam ( %ld, %#lx )", ARG1, ARG2 );
2711   PRE_REG_READ2(long, "sched_getparam",
2712                 vki_pid_t, pid, struct sched_param *, p);
2713   PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
2714}
2715POST(sys_sched_getparam)
2716{
2717   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
2718}
2719
2720PRE(sys_sched_getscheduler)
2721{
2722   PRINT("sys_sched_getscheduler ( %ld )", ARG1);
2723   PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
2724}
2725
2726PRE(sys_sched_setscheduler)
2727{
2728   PRINT("sys_sched_setscheduler ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
2729   PRE_REG_READ3(long, "sched_setscheduler",
2730                 vki_pid_t, pid, int, policy, struct sched_param *, p);
2731   if (ARG3 != 0)
2732      PRE_MEM_READ( "sched_setscheduler(p)",
2733		    ARG3, sizeof(struct vki_sched_param));
2734}
2735
2736PRE(sys_sched_yield)
2737{
2738   *flags |= SfMayBlock;
2739   PRINT("sched_yield()");
2740   PRE_REG_READ0(long, "sys_sched_yield");
2741}
2742
2743PRE(sys_sched_get_priority_max)
2744{
2745   PRINT("sched_get_priority_max ( %ld )", ARG1);
2746   PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
2747}
2748
2749PRE(sys_sched_get_priority_min)
2750{
2751   PRINT("sched_get_priority_min ( %ld )", ARG1);
2752   PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
2753}
2754
2755PRE(sys_sched_rr_get_interval)
2756{
2757   PRINT("sys_sched_rr_get_interval ( %ld, %#lx )", ARG1, ARG2);
2758   PRE_REG_READ2(int, "sched_rr_get_interval",
2759                 vki_pid_t, pid,
2760                 struct vki_timespec *, tp);
2761   PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
2762                 ARG2, sizeof(struct vki_timespec));
2763}
2764
2765POST(sys_sched_rr_get_interval)
2766{
2767   POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
2768}
2769
2770PRE(sys_sched_setaffinity)
2771{
2772   PRINT("sched_setaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
2773   PRE_REG_READ3(long, "sched_setaffinity",
2774                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
2775   PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
2776}
2777
2778PRE(sys_sched_getaffinity)
2779{
2780   PRINT("sched_getaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
2781   PRE_REG_READ3(long, "sched_getaffinity",
2782                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
2783   PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
2784}
2785POST(sys_sched_getaffinity)
2786{
2787   POST_MEM_WRITE(ARG3, ARG2);
2788}
2789
2790PRE(sys_unshare)
2791{
2792   PRINT("sys_unshare ( %ld )", ARG1);
2793   PRE_REG_READ1(int, "unshare", int, flags);
2794}
2795
2796/* ---------------------------------------------------------------------
2797   miscellaneous wrappers
2798   ------------------------------------------------------------------ */
2799
2800PRE(sys_munlockall)
2801{
2802   *flags |= SfMayBlock;
2803   PRINT("sys_munlockall ( )");
2804   PRE_REG_READ0(long, "munlockall");
2805}
2806
2807// This has different signatures for different platforms.
2808//
2809//  x86:   int  sys_pipe(unsigned long __user *fildes);
2810//  AMD64: long sys_pipe(int *fildes);
2811//  ppc32: int  sys_pipe(int __user *fildes);
2812//  ppc64: int  sys_pipe(int __user *fildes);
2813//
2814// The type of the argument is most important, and it is an array of 32 bit
2815// values in all cases.  (The return type differs across platforms, but it
2816// is not used.)  So we use 'int' as its type.  This fixed bug #113230 which
2817// was caused by using an array of 'unsigned long's, which didn't work on
2818// AMD64.
2819PRE(sys_pipe)
2820{
2821   PRINT("sys_pipe ( %#lx )", ARG1);
2822   PRE_REG_READ1(int, "pipe", int *, filedes);
2823   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
2824}
2825POST(sys_pipe)
2826{
2827   Int *p = (Int *)ARG1;
2828   if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
2829       !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
2830      VG_(close)(p[0]);
2831      VG_(close)(p[1]);
2832      SET_STATUS_Failure( VKI_EMFILE );
2833   } else {
2834      POST_MEM_WRITE( ARG1, 2*sizeof(int) );
2835      if (VG_(clo_track_fds)) {
2836         ML_(record_fd_open_nameless)(tid, p[0]);
2837         ML_(record_fd_open_nameless)(tid, p[1]);
2838      }
2839   }
2840}
2841
2842/* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
2843   there's a second arg containing flags to be applied to the new file
2844   descriptors.  It hardly seems worth the effort to factor out the
2845   duplicated code, hence: */
2846PRE(sys_pipe2)
2847{
2848   PRINT("sys_pipe2 ( %#lx, %#lx )", ARG1, ARG2);
2849   PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
2850   PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
2851}
2852POST(sys_pipe2)
2853{
2854   Int *p = (Int *)ARG1;
2855   if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
2856       !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
2857      VG_(close)(p[0]);
2858      VG_(close)(p[1]);
2859      SET_STATUS_Failure( VKI_EMFILE );
2860   } else {
2861      POST_MEM_WRITE( ARG1, 2*sizeof(int) );
2862      if (VG_(clo_track_fds)) {
2863         ML_(record_fd_open_nameless)(tid, p[0]);
2864         ML_(record_fd_open_nameless)(tid, p[1]);
2865      }
2866   }
2867}
2868
2869PRE(sys_dup3)
2870{
2871   PRINT("sys_dup3 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
2872   PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
2873   if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
2874      SET_STATUS_Failure( VKI_EBADF );
2875}
2876
2877POST(sys_dup3)
2878{
2879   vg_assert(SUCCESS);
2880   if (VG_(clo_track_fds))
2881      ML_(record_fd_open_named)(tid, RES);
2882}
2883
2884PRE(sys_quotactl)
2885{
2886   PRINT("sys_quotactl (0x%lx, %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3, ARG4);
2887   PRE_REG_READ4(long, "quotactl",
2888                 unsigned int, cmd, const char *, special, vki_qid_t, id,
2889                 void *, addr);
2890   PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
2891}
2892
2893PRE(sys_waitid)
2894{
2895   *flags |= SfMayBlock;
2896   PRINT("sys_waitid( %ld, %ld, %#lx, %ld, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
2897   PRE_REG_READ5(int32_t, "sys_waitid",
2898                 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
2899                 int, options, struct vki_rusage *, ru);
2900   PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
2901   if (ARG5 != 0)
2902      PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
2903}
2904POST(sys_waitid)
2905{
2906   POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
2907   if (ARG5 != 0)
2908      POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
2909}
2910
2911PRE(sys_sync_file_range)
2912{
2913   *flags |= SfMayBlock;
2914#if VG_WORDSIZE == 4
2915   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
2916         ARG1,MERGE64(ARG2,ARG3),MERGE64(ARG4,ARG5),ARG6);
2917   PRE_REG_READ6(long, "sync_file_range",
2918                 int, fd,
2919                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2920                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
2921                 unsigned int, flags);
2922#elif VG_WORDSIZE == 8
2923   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
2924         ARG1,(Long)ARG2,(Long)ARG3,ARG4);
2925   PRE_REG_READ4(long, "sync_file_range",
2926                 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
2927                 unsigned int, flags);
2928#else
2929#  error Unexpected word size
2930#endif
2931   if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
2932      SET_STATUS_Failure( VKI_EBADF );
2933}
2934
2935PRE(sys_sync_file_range2)
2936{
2937   *flags |= SfMayBlock;
2938#if VG_WORDSIZE == 4
2939   PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
2940         ARG1,ARG2,MERGE64(ARG3,ARG4),MERGE64(ARG5,ARG6));
2941   PRE_REG_READ6(long, "sync_file_range2",
2942                 int, fd, unsigned int, flags,
2943                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2944                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
2945#elif VG_WORDSIZE == 8
2946   PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
2947         ARG1,ARG2,(Long)ARG3,(Long)ARG4);
2948   PRE_REG_READ4(long, "sync_file_range2",
2949                 int, fd, unsigned int, flags,
2950                 vki_loff_t, offset, vki_loff_t, nbytes);
2951#else
2952#  error Unexpected word size
2953#endif
2954   if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
2955      SET_STATUS_Failure( VKI_EBADF );
2956}
2957
2958PRE(sys_stime)
2959{
2960   PRINT("sys_stime ( %#lx )", ARG1);
2961   PRE_REG_READ1(int, "stime", vki_time_t*, t);
2962   PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
2963}
2964
2965PRE(sys_perf_event_open)
2966{
2967   struct vki_perf_event_attr *attr;
2968   PRINT("sys_perf_event_open ( %#lx, %ld, %ld, %ld, %ld )",
2969         ARG1,ARG2,ARG3,ARG4,ARG5);
2970   PRE_REG_READ5(long, "perf_event_open",
2971                 struct vki_perf_event_attr *, attr,
2972                 vki_pid_t, pid, int, cpu, int, group_fd,
2973                 unsigned long, flags);
2974   attr = (struct vki_perf_event_attr *)ARG1;
2975   PRE_MEM_READ( "perf_event_open(attr->size)",
2976                 (Addr)&attr->size, sizeof(attr->size) );
2977   PRE_MEM_READ( "perf_event_open(attr)",
2978                 (Addr)attr, attr->size );
2979}
2980
2981POST(sys_perf_event_open)
2982{
2983   vg_assert(SUCCESS);
2984   if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
2985      VG_(close)(RES);
2986      SET_STATUS_Failure( VKI_EMFILE );
2987   } else {
2988      if (VG_(clo_track_fds))
2989         ML_(record_fd_open_nameless)(tid, RES);
2990   }
2991}
2992
2993PRE(sys_getcpu)
2994{
2995   PRINT("sys_getcpu ( %#lx, %#lx, %#lx )" , ARG1,ARG2,ARG3);
2996   PRE_REG_READ3(int, "getcpu",
2997                 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
2998   if (ARG1 != 0)
2999      PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3000   if (ARG2 != 0)
3001      PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3002   if (ARG3 != 0)
3003      PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3004}
3005
3006POST(sys_getcpu)
3007{
3008   if (ARG1 != 0)
3009      POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3010   if (ARG2 != 0)
3011      POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3012   if (ARG3 != 0)
3013      POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3014}
3015
3016PRE(sys_move_pages)
3017{
3018   PRINT("sys_move_pages ( %ld, %ld, %#lx, %#lx, %#lx, %lx )",
3019         ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3020   PRE_REG_READ6(int, "move_pages",
3021                 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3022                 const int *, nodes, int *, status, int, flags);
3023   PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3024   if (ARG4)
3025      PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3026   PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3027}
3028
3029POST(sys_move_pages)
3030{
3031   POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3032}
3033
3034PRE(sys_getrandom)
3035{
3036   PRINT("sys_getrandom ( %#lx, %ld, %ld )" , ARG1,ARG2,ARG3);
3037   PRE_REG_READ3(int, "getrandom",
3038                 char *, buf, vki_size_t, count, unsigned int, flags);
3039   PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3040}
3041
3042POST(sys_getrandom)
3043{
3044   POST_MEM_WRITE( ARG1, ARG2 );
3045}
3046
3047PRE(sys_memfd_create)
3048{
3049   PRINT("sys_memfd_create ( %#lx, %ld )" , ARG1,ARG2);
3050   PRE_REG_READ2(int, "memfd_create",
3051                 char *, uname, unsigned int, flags);
3052   PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3053}
3054
3055POST(sys_memfd_create)
3056{
3057   vg_assert(SUCCESS);
3058   if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3059      VG_(close)(RES);
3060      SET_STATUS_Failure( VKI_EMFILE );
3061   } else {
3062      if (VG_(clo_track_fds))
3063         ML_(record_fd_open_nameless)(tid, RES);
3064   }
3065}
3066
3067PRE(sys_syncfs)
3068{
3069   *flags |= SfMayBlock;
3070   PRINT("sys_syncfs ( %ld )", ARG1);
3071   PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3072}
3073
3074/* ---------------------------------------------------------------------
3075   utime wrapper
3076   ------------------------------------------------------------------ */
3077
3078PRE(sys_utime)
3079{
3080   *flags |= SfMayBlock;
3081   PRINT("sys_utime ( %#lx, %#lx )", ARG1,ARG2);
3082   PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3083   PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3084   if (ARG2 != 0)
3085      PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3086}
3087
3088/* ---------------------------------------------------------------------
3089   lseek wrapper
3090   ------------------------------------------------------------------ */
3091
3092PRE(sys_lseek)
3093{
3094   PRINT("sys_lseek ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
3095   PRE_REG_READ3(vki_off_t, "lseek",
3096                 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3097}
3098
3099/* ---------------------------------------------------------------------
3100   readahead wrapper
3101   ------------------------------------------------------------------ */
3102
3103PRE(sys_readahead)
3104{
3105   *flags |= SfMayBlock;
3106#if VG_WORDSIZE == 4
3107   PRINT("sys_readahead ( %ld, %lld, %ld )", ARG1, MERGE64(ARG2,ARG3), ARG4);
3108   PRE_REG_READ4(vki_off_t, "readahead",
3109                 int, fd, unsigned, MERGE64_FIRST(offset),
3110                 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3111#elif VG_WORDSIZE == 8
3112   PRINT("sys_readahead ( %ld, %lld, %ld )", ARG1, (Long)ARG2, ARG3);
3113   PRE_REG_READ3(vki_off_t, "readahead",
3114                 int, fd, vki_loff_t, offset, vki_size_t, count);
3115#else
3116#  error Unexpected word size
3117#endif
3118   if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3119      SET_STATUS_Failure( VKI_EBADF );
3120}
3121
3122/* ---------------------------------------------------------------------
3123   sig* wrappers
3124   ------------------------------------------------------------------ */
3125
3126PRE(sys_sigpending)
3127{
3128   PRINT( "sys_sigpending ( %#lx )", ARG1 );
3129   PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3130   PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3131}
3132POST(sys_sigpending)
3133{
3134   POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3135}
3136
3137// This syscall is not used on amd64/Linux -- it only provides
3138// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3139// This wrapper is only suitable for 32-bit architectures.
3140// (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3141// conditional compilation like this?)
3142#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3143    || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
3144PRE(sys_sigprocmask)
3145{
3146   vki_old_sigset_t* set;
3147   vki_old_sigset_t* oldset;
3148   vki_sigset_t bigger_set;
3149   vki_sigset_t bigger_oldset;
3150
3151   PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
3152   PRE_REG_READ3(long, "sigprocmask",
3153                 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3154   if (ARG2 != 0)
3155      PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3156   if (ARG3 != 0)
3157      PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3158
3159   // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3160   // vki_sigset_t params.
3161   set    = (vki_old_sigset_t*)ARG2;
3162   oldset = (vki_old_sigset_t*)ARG3;
3163
3164   VG_(memset)(&bigger_set,    0, sizeof(vki_sigset_t));
3165   VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3166   if (set)
3167      bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3168
3169   SET_STATUS_from_SysRes(
3170      VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3171                                set ? &bigger_set    : NULL,
3172                             oldset ? &bigger_oldset : NULL)
3173   );
3174
3175   if (oldset)
3176      *oldset = bigger_oldset.sig[0];
3177
3178   if (SUCCESS)
3179      *flags |= SfPollAfter;
3180}
3181POST(sys_sigprocmask)
3182{
3183   vg_assert(SUCCESS);
3184   if (RES == 0 && ARG3 != 0)
3185      POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3186}
3187
3188/* Convert from non-RT to RT sigset_t's */
3189static
3190void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3191{
3192   VG_(sigemptyset)(set);
3193   set->sig[0] = *oldset;
3194}
3195PRE(sys_sigaction)
3196{
3197   vki_sigaction_toK_t   new, *newp;
3198   vki_sigaction_fromK_t old, *oldp;
3199
3200   PRINT("sys_sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
3201   PRE_REG_READ3(int, "sigaction",
3202                 int, signum, const struct old_sigaction *, act,
3203                 struct old_sigaction *, oldact);
3204
3205   newp = oldp = NULL;
3206
3207   if (ARG2 != 0) {
3208      struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
3209      PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3210      PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3211      PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3212      if (ML_(safe_to_deref)(sa,sizeof(sa))
3213          && (sa->sa_flags & VKI_SA_RESTORER))
3214         PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3215   }
3216
3217   if (ARG3 != 0) {
3218      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3219      oldp = &old;
3220   }
3221
3222   if (ARG2 != 0) {
3223      struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
3224
3225      new.ksa_handler = oldnew->ksa_handler;
3226      new.sa_flags = oldnew->sa_flags;
3227      new.sa_restorer = oldnew->sa_restorer;
3228      convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3229      newp = &new;
3230   }
3231
3232   SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3233
3234   if (ARG3 != 0 && SUCCESS && RES == 0) {
3235      struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
3236
3237      oldold->ksa_handler = oldp->ksa_handler;
3238      oldold->sa_flags = oldp->sa_flags;
3239      oldold->sa_restorer = oldp->sa_restorer;
3240      oldold->sa_mask = oldp->sa_mask.sig[0];
3241   }
3242}
3243POST(sys_sigaction)
3244{
3245   vg_assert(SUCCESS);
3246   if (RES == 0 && ARG3 != 0)
3247      POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3248}
3249#endif
3250
3251PRE(sys_signalfd)
3252{
3253   PRINT("sys_signalfd ( %d, %#lx, %llu )", (Int)ARG1,ARG2,(ULong)ARG3);
3254   PRE_REG_READ3(long, "sys_signalfd",
3255                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3256   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3257   if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3258      SET_STATUS_Failure( VKI_EBADF );
3259}
3260POST(sys_signalfd)
3261{
3262   if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3263      VG_(close)(RES);
3264      SET_STATUS_Failure( VKI_EMFILE );
3265   } else {
3266      if (VG_(clo_track_fds))
3267         ML_(record_fd_open_nameless) (tid, RES);
3268   }
3269}
3270
3271PRE(sys_signalfd4)
3272{
3273   PRINT("sys_signalfd4 ( %d, %#lx, %llu, %ld )", (Int)ARG1,ARG2,(ULong)ARG3,ARG4);
3274   PRE_REG_READ4(long, "sys_signalfd4",
3275                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3276   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3277   if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3278      SET_STATUS_Failure( VKI_EBADF );
3279}
3280POST(sys_signalfd4)
3281{
3282   if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3283      VG_(close)(RES);
3284      SET_STATUS_Failure( VKI_EMFILE );
3285   } else {
3286      if (VG_(clo_track_fds))
3287         ML_(record_fd_open_nameless) (tid, RES);
3288   }
3289}
3290
3291
3292/* ---------------------------------------------------------------------
3293   rt_sig* wrappers
3294   ------------------------------------------------------------------ */
3295
3296PRE(sys_rt_sigaction)
3297{
3298   PRINT("sys_rt_sigaction ( %ld, %#lx, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4);
3299   PRE_REG_READ4(long, "rt_sigaction",
3300                 int, signum, const struct sigaction *, act,
3301                 struct sigaction *, oldact, vki_size_t, sigsetsize);
3302
3303   if (ARG2 != 0) {
3304      vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
3305      PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3306      PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3307      PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3308      if (sa->sa_flags & VKI_SA_RESTORER)
3309         PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3310   }
3311   if (ARG3 != 0)
3312      PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3313
3314   // XXX: doesn't seem right to be calling do_sys_sigaction for
3315   // sys_rt_sigaction... perhaps this function should be renamed
3316   // VG_(do_sys_rt_sigaction)()  --njn
3317
3318   SET_STATUS_from_SysRes(
3319      VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
3320                            (vki_sigaction_fromK_t *)ARG3)
3321   );
3322}
3323POST(sys_rt_sigaction)
3324{
3325   vg_assert(SUCCESS);
3326   if (RES == 0 && ARG3 != 0)
3327      POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3328}
3329
3330PRE(sys_rt_sigprocmask)
3331{
3332   PRINT("sys_rt_sigprocmask ( %ld, %#lx, %#lx, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
3333   PRE_REG_READ4(long, "rt_sigprocmask",
3334                 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3335                 vki_size_t, sigsetsize);
3336   if (ARG2 != 0)
3337      PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3338   if (ARG3 != 0)
3339      PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3340
3341   // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3342   if (sizeof(vki_sigset_t) != ARG4)
3343      SET_STATUS_Failure( VKI_EMFILE );
3344   else {
3345      SET_STATUS_from_SysRes(
3346                  VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3347                                            (vki_sigset_t*) ARG2,
3348                                            (vki_sigset_t*) ARG3 )
3349      );
3350   }
3351
3352   if (SUCCESS)
3353      *flags |= SfPollAfter;
3354}
3355POST(sys_rt_sigprocmask)
3356{
3357   vg_assert(SUCCESS);
3358   if (RES == 0 && ARG3 != 0)
3359      POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3360}
3361
3362PRE(sys_rt_sigpending)
3363{
3364   PRINT( "sys_rt_sigpending ( %#lx )", ARG1 );
3365   PRE_REG_READ2(long, "rt_sigpending",
3366                 vki_sigset_t *, set, vki_size_t, sigsetsize);
3367   PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
3368}
3369POST(sys_rt_sigpending)
3370{
3371   POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3372}
3373
3374PRE(sys_rt_sigtimedwait)
3375{
3376   *flags |= SfMayBlock;
3377   PRINT("sys_rt_sigtimedwait ( %#lx, %#lx, %#lx, %lld )",
3378         ARG1,ARG2,ARG3,(ULong)ARG4);
3379   PRE_REG_READ4(long, "rt_sigtimedwait",
3380                 const vki_sigset_t *, set, vki_siginfo_t *, info,
3381                 const struct timespec *, timeout, vki_size_t, sigsetsize);
3382   if (ARG1 != 0)
3383      PRE_MEM_READ(  "rt_sigtimedwait(set)",  ARG1, sizeof(vki_sigset_t));
3384   if (ARG2 != 0)
3385      PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
3386   if (ARG3 != 0)
3387      PRE_MEM_READ( "rt_sigtimedwait(timeout)",
3388                    ARG3, sizeof(struct vki_timespec) );
3389}
3390POST(sys_rt_sigtimedwait)
3391{
3392   if (ARG2 != 0)
3393      POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3394}
3395
3396PRE(sys_rt_sigqueueinfo)
3397{
3398   PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#lx)", ARG1, ARG2, ARG3);
3399   PRE_REG_READ3(long, "rt_sigqueueinfo",
3400                 int, pid, int, sig, vki_siginfo_t *, uinfo);
3401   if (ARG2 != 0)
3402      PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
3403}
3404POST(sys_rt_sigqueueinfo)
3405{
3406   if (!ML_(client_signal_OK)(ARG2))
3407      SET_STATUS_Failure( VKI_EINVAL );
3408}
3409
3410PRE(sys_rt_tgsigqueueinfo)
3411{
3412   PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#lx)", ARG1, ARG2, ARG3, ARG4);
3413   PRE_REG_READ4(long, "rt_tgsigqueueinfo",
3414                 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
3415   if (ARG3 != 0)
3416      PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
3417}
3418
3419POST(sys_rt_tgsigqueueinfo)
3420{
3421   if (!ML_(client_signal_OK)(ARG3))
3422      SET_STATUS_Failure( VKI_EINVAL );
3423}
3424
3425// XXX: x86-specific?  The kernel prototypes for the different archs are
3426//      hard to decipher.
3427PRE(sys_rt_sigsuspend)
3428{
3429   /* The C library interface to sigsuspend just takes a pointer to
3430      a signal mask but this system call has two arguments - a pointer
3431      to the mask and the number of bytes used by it. The kernel insists
3432      on the size being equal to sizeof(sigset_t) however and will just
3433      return EINVAL if it isn't.
3434    */
3435   *flags |= SfMayBlock;
3436   PRINT("sys_rt_sigsuspend ( %#lx, %ld )", ARG1,ARG2 );
3437   PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
3438   if (ARG1 != (Addr)NULL) {
3439      PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
3440   }
3441}
3442
3443/* ---------------------------------------------------------------------
3444   linux msg* wrapper helpers
3445   ------------------------------------------------------------------ */
3446
3447void
3448ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
3449                            UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
3450{
3451   /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
3452   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3453   PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3454   PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
3455}
3456
3457void
3458ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
3459                            UWord arg0, UWord arg1, UWord arg2,
3460                            UWord arg3, UWord arg4 )
3461{
3462   /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
3463                     long msgtyp, int msgflg); */
3464   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3465   PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3466   PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
3467}
3468void
3469ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
3470                             UWord res,
3471                             UWord arg0, UWord arg1, UWord arg2,
3472                             UWord arg3, UWord arg4 )
3473{
3474   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3475   POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3476   POST_MEM_WRITE( (Addr)&msgp->mtext, res );
3477}
3478
3479void
3480ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
3481                            UWord arg0, UWord arg1, UWord arg2 )
3482{
3483   /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
3484   switch (arg1 /* cmd */) {
3485   case VKI_IPC_INFO:
3486   case VKI_MSG_INFO:
3487   case VKI_IPC_INFO|VKI_IPC_64:
3488   case VKI_MSG_INFO|VKI_IPC_64:
3489      PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
3490                     arg2, sizeof(struct vki_msginfo) );
3491      break;
3492   case VKI_IPC_STAT:
3493   case VKI_MSG_STAT:
3494      PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
3495                     arg2, sizeof(struct vki_msqid_ds) );
3496      break;
3497   case VKI_IPC_STAT|VKI_IPC_64:
3498   case VKI_MSG_STAT|VKI_IPC_64:
3499      PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
3500                     arg2, sizeof(struct vki_msqid64_ds) );
3501      break;
3502   case VKI_IPC_SET:
3503      PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
3504                    arg2, sizeof(struct vki_msqid_ds) );
3505      break;
3506   case VKI_IPC_SET|VKI_IPC_64:
3507      PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
3508                    arg2, sizeof(struct vki_msqid64_ds) );
3509      break;
3510   }
3511}
3512void
3513ML_(linux_POST_sys_msgctl) ( ThreadId tid,
3514                             UWord res,
3515                             UWord arg0, UWord arg1, UWord arg2 )
3516{
3517   switch (arg1 /* cmd */) {
3518   case VKI_IPC_INFO:
3519   case VKI_MSG_INFO:
3520   case VKI_IPC_INFO|VKI_IPC_64:
3521   case VKI_MSG_INFO|VKI_IPC_64:
3522      POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
3523      break;
3524   case VKI_IPC_STAT:
3525   case VKI_MSG_STAT:
3526      POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
3527      break;
3528   case VKI_IPC_STAT|VKI_IPC_64:
3529   case VKI_MSG_STAT|VKI_IPC_64:
3530      POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
3531      break;
3532   }
3533}
3534
3535/* ---------------------------------------------------------------------
3536   Generic handler for sys_ipc
3537   Depending on the platform, some syscalls (e.g. semctl, semop, ...)
3538   are either direct system calls, or are all implemented via sys_ipc.
3539   ------------------------------------------------------------------ */
3540#ifdef __NR_ipc
3541static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
3542{
3543   Addr* a_p = (Addr*)a;
3544   PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
3545   return *a_p;
3546}
3547
3548static Bool semctl_cmd_has_4args (UWord cmd)
3549{
3550   switch (cmd & ~VKI_IPC_64)
3551   {
3552   case VKI_IPC_INFO:
3553   case VKI_SEM_INFO:
3554   case VKI_IPC_STAT:
3555   case VKI_SEM_STAT:
3556   case VKI_IPC_SET:
3557   case VKI_GETALL:
3558   case VKI_SETALL:
3559      return True;
3560   default:
3561      return False;
3562   }
3563}
3564
3565PRE(sys_ipc)
3566{
3567   PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )",
3568         ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3569
3570   switch (ARG1 /* call */) {
3571   case VKI_SEMOP:
3572      PRE_REG_READ5(int, "ipc",
3573                    vki_uint, call, int, first, int, second, int, third,
3574                    void *, ptr);
3575      ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
3576      *flags |= SfMayBlock;
3577      break;
3578   case VKI_SEMGET:
3579      PRE_REG_READ4(int, "ipc",
3580                    vki_uint, call, int, first, int, second, int, third);
3581      break;
3582   case VKI_SEMCTL:
3583   {
3584      PRE_REG_READ5(int, "ipc",
3585                    vki_uint, call, int, first, int, second, int, third,
3586                    void *, ptr);
3587      UWord arg;
3588      if (semctl_cmd_has_4args(ARG4))
3589         arg = deref_Addr( tid, ARG5, "semctl(arg)" );
3590      else
3591         arg = 0;
3592      ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
3593      break;
3594   }
3595   case VKI_SEMTIMEDOP:
3596      PRE_REG_READ6(int, "ipc",
3597                    vki_uint, call, int, first, int, second, int, third,
3598                    void *, ptr, long, fifth);
3599      ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
3600      *flags |= SfMayBlock;
3601      break;
3602   case VKI_MSGSND:
3603      PRE_REG_READ5(int, "ipc",
3604                    vki_uint, call, int, first, int, second, int, third,
3605                    void *, ptr);
3606      ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
3607      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
3608         *flags |= SfMayBlock;
3609      break;
3610   case VKI_MSGRCV:
3611   {
3612      PRE_REG_READ5(int, "ipc",
3613                    vki_uint, call, int, first, int, second, int, third,
3614                    void *, ptr);
3615      Addr msgp;
3616      Word msgtyp;
3617
3618      msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
3619                         "msgrcv(msgp)" );
3620      msgtyp = deref_Addr( tid,
3621                           (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
3622                           "msgrcv(msgp)" );
3623
3624      ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
3625
3626      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
3627         *flags |= SfMayBlock;
3628      break;
3629   }
3630   case VKI_MSGGET:
3631      PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
3632      break;
3633   case VKI_MSGCTL:
3634      PRE_REG_READ5(int, "ipc",
3635                    vki_uint, call, int, first, int, second, int, third,
3636                    void *, ptr);
3637      ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
3638      break;
3639   case VKI_SHMAT:
3640   {
3641      PRE_REG_READ5(int, "ipc",
3642                    vki_uint, call, int, first, int, second, int, third,
3643                    void *, ptr);
3644      UWord w;
3645      PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
3646      w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
3647      if (w == 0)
3648         SET_STATUS_Failure( VKI_EINVAL );
3649      else
3650         ARG5 = w;
3651      break;
3652   }
3653   case VKI_SHMDT:
3654      PRE_REG_READ5(int, "ipc",
3655                    vki_uint, call, int, first, int, second, int, third,
3656                    void *, ptr);
3657      if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
3658	 SET_STATUS_Failure( VKI_EINVAL );
3659      break;
3660   case VKI_SHMGET:
3661      PRE_REG_READ4(int, "ipc",
3662                    vki_uint, call, int, first, int, second, int, third);
3663      if (ARG4 & VKI_SHM_HUGETLB) {
3664         static Bool warning_given = False;
3665         ARG4 &= ~VKI_SHM_HUGETLB;
3666         if (!warning_given) {
3667            warning_given = True;
3668            VG_(umsg)(
3669               "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
3670         }
3671      }
3672      break;
3673   case VKI_SHMCTL: /* IPCOP_shmctl */
3674      PRE_REG_READ5(int, "ipc",
3675                    vki_uint, call, int, first, int, second, int, third,
3676                    void *, ptr);
3677      ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
3678      break;
3679   default:
3680      VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
3681      VG_(core_panic)("... bye!\n");
3682      break; /*NOTREACHED*/
3683   }
3684}
3685
3686POST(sys_ipc)
3687{
3688   vg_assert(SUCCESS);
3689   switch (ARG1 /* call */) {
3690   case VKI_SEMOP:
3691   case VKI_SEMGET:
3692      break;
3693   case VKI_SEMCTL:
3694   {
3695      UWord arg;
3696      if (semctl_cmd_has_4args(ARG4))
3697         arg = deref_Addr( tid, ARG5, "semctl(arg)" );
3698      else
3699         arg = 0;
3700      ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
3701      break;
3702   }
3703   case VKI_SEMTIMEDOP:
3704   case VKI_MSGSND:
3705      break;
3706   case VKI_MSGRCV:
3707   {
3708      Addr msgp;
3709      Word msgtyp;
3710
3711      msgp = deref_Addr( tid,
3712			 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
3713			 "msgrcv(msgp)" );
3714      msgtyp = deref_Addr( tid,
3715			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
3716			   "msgrcv(msgp)" );
3717
3718      ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
3719      break;
3720   }
3721   case VKI_MSGGET:
3722      break;
3723   case VKI_MSGCTL:
3724      ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
3725      break;
3726   case VKI_SHMAT:
3727   {
3728      Addr addr;
3729
3730      /* force readability. before the syscall it is
3731       * indeed uninitialized, as can be seen in
3732       * glibc/sysdeps/unix/sysv/linux/shmat.c */
3733      POST_MEM_WRITE( ARG4, sizeof( Addr ) );
3734
3735      addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
3736      ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
3737      break;
3738   }
3739   case VKI_SHMDT:
3740      ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
3741      break;
3742   case VKI_SHMGET:
3743      break;
3744   case VKI_SHMCTL:
3745      ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
3746      break;
3747   default:
3748      VG_(message)(Vg_DebugMsg,
3749		   "FATAL: unhandled syscall(ipc) %ld\n",
3750		   ARG1 );
3751      VG_(core_panic)("... bye!\n");
3752      break; /*NOTREACHED*/
3753   }
3754}
3755#endif
3756
3757PRE(sys_semget)
3758{
3759   PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
3760   PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
3761}
3762
3763PRE(sys_semop)
3764{
3765   *flags |= SfMayBlock;
3766   PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
3767   PRE_REG_READ3(long, "semop",
3768                 int, semid, struct sembuf *, sops, unsigned, nsoops);
3769   ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
3770}
3771
3772PRE(sys_semctl)
3773{
3774   switch (ARG3 & ~VKI_IPC_64) {
3775   case VKI_IPC_INFO:
3776   case VKI_SEM_INFO:
3777      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3778      PRE_REG_READ4(long, "semctl",
3779                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
3780      break;
3781   case VKI_IPC_STAT:
3782   case VKI_SEM_STAT:
3783   case VKI_IPC_SET:
3784      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3785      PRE_REG_READ4(long, "semctl",
3786                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
3787      break;
3788   case VKI_GETALL:
3789   case VKI_SETALL:
3790      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3791      PRE_REG_READ4(long, "semctl",
3792                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
3793      break;
3794   default:
3795      PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
3796      PRE_REG_READ3(long, "semctl",
3797                    int, semid, int, semnum, int, cmd);
3798      break;
3799   }
3800#ifdef VGP_amd64_linux
3801   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
3802#else
3803   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
3804#endif
3805}
3806
3807POST(sys_semctl)
3808{
3809#ifdef VGP_amd64_linux
3810   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
3811#else
3812   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
3813#endif
3814}
3815
3816PRE(sys_semtimedop)
3817{
3818   *flags |= SfMayBlock;
3819   PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
3820   PRE_REG_READ4(long, "semtimedop",
3821                 int, semid, struct sembuf *, sops, unsigned, nsoops,
3822                 struct timespec *, timeout);
3823   ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
3824}
3825
3826PRE(sys_msgget)
3827{
3828   PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
3829   PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
3830}
3831
3832PRE(sys_msgsnd)
3833{
3834   PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
3835   PRE_REG_READ4(long, "msgsnd",
3836                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
3837   ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
3838   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
3839      *flags |= SfMayBlock;
3840}
3841
3842PRE(sys_msgrcv)
3843{
3844   PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
3845   PRE_REG_READ5(long, "msgrcv",
3846                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
3847                 long, msgytp, int, msgflg);
3848   ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
3849   if ((ARG5 & VKI_IPC_NOWAIT) == 0)
3850      *flags |= SfMayBlock;
3851}
3852POST(sys_msgrcv)
3853{
3854   ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
3855}
3856
3857PRE(sys_msgctl)
3858{
3859   PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
3860   PRE_REG_READ3(long, "msgctl",
3861                 int, msqid, int, cmd, struct msqid_ds *, buf);
3862   ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
3863}
3864
3865POST(sys_msgctl)
3866{
3867   ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
3868}
3869
3870PRE(sys_shmget)
3871{
3872   PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
3873   PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
3874   if (ARG3 & VKI_SHM_HUGETLB) {
3875      static Bool warning_given = False;
3876      ARG3 &= ~VKI_SHM_HUGETLB;
3877      if (!warning_given) {
3878         warning_given = True;
3879         VG_(umsg)(
3880            "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
3881      }
3882   }
3883}
3884
3885PRE(wrap_sys_shmat)
3886{
3887   UWord arg2tmp;
3888   PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3889   PRE_REG_READ3(long, "shmat",
3890                 int, shmid, const void *, shmaddr, int, shmflg);
3891#if defined(VGP_arm_linux)
3892   /* Round the attach address down to an VKI_SHMLBA boundary if the
3893      client requested rounding.  See #222545.  This is necessary only
3894      on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
3895      other linux targets it is the same as the page size. */
3896   if (ARG3 & VKI_SHM_RND)
3897      ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
3898#endif
3899   arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
3900   if (arg2tmp == 0)
3901      SET_STATUS_Failure( VKI_EINVAL );
3902   else
3903      ARG2 = arg2tmp;  // used in POST
3904}
3905
3906POST(wrap_sys_shmat)
3907{
3908   ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
3909}
3910
3911PRE(sys_shmdt)
3912{
3913   PRINT("sys_shmdt ( %#lx )",ARG1);
3914   PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
3915   if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
3916      SET_STATUS_Failure( VKI_EINVAL );
3917}
3918
3919POST(sys_shmdt)
3920{
3921   ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
3922}
3923
3924PRE(sys_shmctl)
3925{
3926   PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
3927   PRE_REG_READ3(long, "shmctl",
3928                 int, shmid, int, cmd, struct shmid_ds *, buf);
3929#ifdef VGP_amd64_linux
3930   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
3931#else
3932   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
3933#endif
3934}
3935
3936POST(sys_shmctl)
3937{
3938#ifdef VGP_amd64_linux
3939   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
3940#else
3941   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
3942#endif
3943}
3944
3945
3946/* ---------------------------------------------------------------------
3947   Generic handler for sys_socketcall
3948   Depending on the platform, some socket related syscalls (e.g. socketpair,
3949   socket, bind, ...)
3950   are either direct system calls, or are all implemented via sys_socketcall.
3951   ------------------------------------------------------------------ */
3952#ifdef __NR_socketcall
3953PRE(sys_socketcall)
3954{
3955#  define ARG2_0  (((UWord*)ARG2)[0])
3956#  define ARG2_1  (((UWord*)ARG2)[1])
3957#  define ARG2_2  (((UWord*)ARG2)[2])
3958#  define ARG2_3  (((UWord*)ARG2)[3])
3959#  define ARG2_4  (((UWord*)ARG2)[4])
3960#  define ARG2_5  (((UWord*)ARG2)[5])
3961
3962// call PRE_MEM_READ and check for EFAULT result.
3963#define PRE_MEM_READ_ef(msg, arg, size)                         \
3964   {                                                            \
3965      PRE_MEM_READ( msg, arg, size);                            \
3966      if (!ML_(valid_client_addr)(arg, size, tid, NULL)) {      \
3967         SET_STATUS_Failure( VKI_EFAULT );                      \
3968         break;                                                 \
3969      }                                                         \
3970   }
3971
3972   *flags |= SfMayBlock;
3973   PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
3974   PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
3975
3976   switch (ARG1 /* request */) {
3977
3978   case VKI_SYS_SOCKETPAIR:
3979      /* int socketpair(int d, int type, int protocol, int sv[2]); */
3980      PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
3981      ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
3982      break;
3983
3984   case VKI_SYS_SOCKET:
3985      /* int socket(int domain, int type, int protocol); */
3986      PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
3987      break;
3988
3989   case VKI_SYS_BIND:
3990      /* int bind(int sockfd, struct sockaddr *my_addr,
3991                  int addrlen); */
3992      PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
3993      ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
3994      break;
3995
3996   case VKI_SYS_LISTEN:
3997      /* int listen(int s, int backlog); */
3998      PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
3999      break;
4000
4001   case VKI_SYS_ACCEPT:
4002      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4003      PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4004      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4005      break;
4006
4007   case VKI_SYS_ACCEPT4:
4008      /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4009      PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4010      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4011      break;
4012
4013   case VKI_SYS_SENDTO:
4014      /* int sendto(int s, const void *msg, int len,
4015                    unsigned int flags,
4016                    const struct sockaddr *to, int tolen); */
4017      PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4018      ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4019                                   ARG2_3, ARG2_4, ARG2_5 );
4020      break;
4021
4022   case VKI_SYS_SEND:
4023      /* int send(int s, const void *msg, size_t len, int flags); */
4024      PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4025      ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4026      break;
4027
4028   case VKI_SYS_RECVFROM:
4029      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4030         struct sockaddr *from, int *fromlen); */
4031      PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4032      ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4033                                     ARG2_3, ARG2_4, ARG2_5 );
4034      break;
4035
4036   case VKI_SYS_RECV:
4037      /* int recv(int s, void *buf, int len, unsigned int flags); */
4038      /* man 2 recv says:
4039         The  recv call is normally used only on a connected socket
4040         (see connect(2)) and is identical to recvfrom with a  NULL
4041         from parameter.
4042      */
4043      PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4044      ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4045      break;
4046
4047   case VKI_SYS_CONNECT:
4048      /* int connect(int sockfd,
4049                     struct sockaddr *serv_addr, int addrlen ); */
4050      PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4051      ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4052      break;
4053
4054   case VKI_SYS_SETSOCKOPT:
4055      /* int setsockopt(int s, int level, int optname,
4056                        const void *optval, int optlen); */
4057      PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4058      ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4059                                     ARG2_3, ARG2_4 );
4060      break;
4061
4062   case VKI_SYS_GETSOCKOPT:
4063      /* int getsockopt(int s, int level, int optname,
4064                        void *optval, socklen_t *optlen); */
4065      PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4066      ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4067                                     ARG2_3, ARG2_4 );
4068      break;
4069
4070   case VKI_SYS_GETSOCKNAME:
4071      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4072      PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4073      ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4074      break;
4075
4076   case VKI_SYS_GETPEERNAME:
4077      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4078      PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4079      ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4080      break;
4081
4082   case VKI_SYS_SHUTDOWN:
4083      /* int shutdown(int s, int how); */
4084      PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4085      break;
4086
4087   case VKI_SYS_SENDMSG:
4088      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4089      PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4090      ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
4091      break;
4092
4093   case VKI_SYS_RECVMSG:
4094      /* int recvmsg(int s, struct msghdr *msg, int flags); */
4095      PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4096      ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
4097      break;
4098
4099   case VKI_SYS_RECVMMSG:
4100      /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4101                      struct timespec *timeout); */
4102      PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4103      ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4104                                   ARG2_4 );
4105      break;
4106
4107   case VKI_SYS_SENDMMSG:
4108      /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4109      PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4110      ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4111      break;
4112
4113   default:
4114      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4115      SET_STATUS_Failure( VKI_EINVAL );
4116      break;
4117   }
4118#  undef ARG2_0
4119#  undef ARG2_1
4120#  undef ARG2_2
4121#  undef ARG2_3
4122#  undef ARG2_4
4123#  undef ARG2_5
4124}
4125
4126POST(sys_socketcall)
4127{
4128#  define ARG2_0  (((UWord*)ARG2)[0])
4129#  define ARG2_1  (((UWord*)ARG2)[1])
4130#  define ARG2_2  (((UWord*)ARG2)[2])
4131#  define ARG2_3  (((UWord*)ARG2)[3])
4132#  define ARG2_4  (((UWord*)ARG2)[4])
4133#  define ARG2_5  (((UWord*)ARG2)[5])
4134
4135   SysRes r;
4136   vg_assert(SUCCESS);
4137   switch (ARG1 /* request */) {
4138
4139   case VKI_SYS_SOCKETPAIR:
4140      r = ML_(generic_POST_sys_socketpair)(
4141             tid, VG_(mk_SysRes_Success)(RES),
4142             ARG2_0, ARG2_1, ARG2_2, ARG2_3
4143          );
4144      SET_STATUS_from_SysRes(r);
4145      break;
4146
4147   case VKI_SYS_SOCKET:
4148      r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4149      SET_STATUS_from_SysRes(r);
4150      break;
4151
4152   case VKI_SYS_BIND:
4153      /* int bind(int sockfd, struct sockaddr *my_addr,
4154			int addrlen); */
4155      break;
4156
4157   case VKI_SYS_LISTEN:
4158      /* int listen(int s, int backlog); */
4159      break;
4160
4161   case VKI_SYS_ACCEPT:
4162   case VKI_SYS_ACCEPT4:
4163      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4164      /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4165     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4166                                            ARG2_0, ARG2_1, ARG2_2 );
4167     SET_STATUS_from_SysRes(r);
4168     break;
4169
4170   case VKI_SYS_SENDTO:
4171      break;
4172
4173   case VKI_SYS_SEND:
4174      break;
4175
4176   case VKI_SYS_RECVFROM:
4177      ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4178                                           ARG2_0, ARG2_1, ARG2_2,
4179                                           ARG2_3, ARG2_4, ARG2_5 );
4180      break;
4181
4182   case VKI_SYS_RECV:
4183      ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4184      break;
4185
4186   case VKI_SYS_CONNECT:
4187      break;
4188
4189   case VKI_SYS_SETSOCKOPT:
4190      break;
4191
4192   case VKI_SYS_GETSOCKOPT:
4193      ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4194                                      ARG2_0, ARG2_1,
4195                                      ARG2_2, ARG2_3, ARG2_4 );
4196      break;
4197
4198   case VKI_SYS_GETSOCKNAME:
4199      ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4200                                              ARG2_0, ARG2_1, ARG2_2 );
4201      break;
4202
4203   case VKI_SYS_GETPEERNAME:
4204      ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4205                                              ARG2_0, ARG2_1, ARG2_2 );
4206      break;
4207
4208   case VKI_SYS_SHUTDOWN:
4209      break;
4210
4211   case VKI_SYS_SENDMSG:
4212      break;
4213
4214   case VKI_SYS_RECVMSG:
4215      ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
4216      break;
4217
4218   case VKI_SYS_RECVMMSG:
4219      ML_(linux_POST_sys_recvmmsg)( tid, RES,
4220                                    ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4221      break;
4222
4223   case VKI_SYS_SENDMMSG:
4224      ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4225      break;
4226
4227   default:
4228      VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4229      VG_(core_panic)("... bye!\n");
4230      break; /*NOTREACHED*/
4231   }
4232#  undef ARG2_0
4233#  undef ARG2_1
4234#  undef ARG2_2
4235#  undef ARG2_3
4236#  undef ARG2_4
4237#  undef ARG2_5
4238}
4239#endif
4240
4241PRE(sys_socket)
4242{
4243   PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
4244   PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4245}
4246POST(sys_socket)
4247{
4248   SysRes r;
4249   vg_assert(SUCCESS);
4250   r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4251   SET_STATUS_from_SysRes(r);
4252}
4253
4254PRE(sys_setsockopt)
4255{
4256   PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
4257   PRE_REG_READ5(long, "setsockopt",
4258                 int, s, int, level, int, optname,
4259                 const void *, optval, int, optlen);
4260   ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4261}
4262
4263PRE(sys_getsockopt)
4264{
4265   PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
4266   PRE_REG_READ5(long, "getsockopt",
4267                 int, s, int, level, int, optname,
4268                 void *, optval, int, *optlen);
4269   ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4270}
4271POST(sys_getsockopt)
4272{
4273   vg_assert(SUCCESS);
4274   ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4275                                       ARG1,ARG2,ARG3,ARG4,ARG5);
4276}
4277
4278PRE(sys_connect)
4279{
4280   *flags |= SfMayBlock;
4281   PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4282   PRE_REG_READ3(long, "connect",
4283                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4284   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4285}
4286
4287PRE(sys_accept)
4288{
4289   *flags |= SfMayBlock;
4290   PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4291   PRE_REG_READ3(long, "accept",
4292                 int, s, struct sockaddr *, addr, int, *addrlen);
4293   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4294}
4295POST(sys_accept)
4296{
4297   SysRes r;
4298   vg_assert(SUCCESS);
4299   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4300                                         ARG1,ARG2,ARG3);
4301   SET_STATUS_from_SysRes(r);
4302}
4303
4304PRE(sys_accept4)
4305{
4306   *flags |= SfMayBlock;
4307   PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
4308   PRE_REG_READ4(long, "accept4",
4309                 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
4310   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4311}
4312POST(sys_accept4)
4313{
4314   SysRes r;
4315   vg_assert(SUCCESS);
4316   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4317                                         ARG1,ARG2,ARG3);
4318   SET_STATUS_from_SysRes(r);
4319}
4320
4321PRE(sys_send)
4322{
4323   *flags |= SfMayBlock;
4324   PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
4325   PRE_REG_READ4(long, "send",
4326                 int, s, const void *, msg, int, len,
4327                 unsigned int, flags);
4328
4329   ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
4330}
4331
4332PRE(sys_sendto)
4333{
4334   *flags |= SfMayBlock;
4335   PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4336   PRE_REG_READ6(long, "sendto",
4337                 int, s, const void *, msg, int, len,
4338                 unsigned int, flags,
4339                 const struct sockaddr *, to, int, tolen);
4340   ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4341}
4342
4343PRE (sys_recv)
4344{
4345  *flags |= SfMayBlock;
4346  PRINT ("sys_recv ( %ld, %#lx, %ld, %lu )", ARG1, ARG2, ARG3, ARG4);
4347  PRE_REG_READ4 (long, "recv", int, s, void *, buf, int, len,
4348                 unsigned int, flags);
4349  ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
4350}
4351
4352POST (sys_recv)
4353{
4354  ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
4355}
4356
4357PRE(sys_recvfrom)
4358{
4359   *flags |= SfMayBlock;
4360   PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4361   PRE_REG_READ6(long, "recvfrom",
4362                 int, s, void *, buf, int, len, unsigned int, flags,
4363                 struct sockaddr *, from, int *, fromlen);
4364   ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4365}
4366POST(sys_recvfrom)
4367{
4368   vg_assert(SUCCESS);
4369   ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
4370                                       ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4371}
4372
4373PRE(sys_sendmsg)
4374{
4375   *flags |= SfMayBlock;
4376   PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4377   PRE_REG_READ3(long, "sendmsg",
4378                 int, s, const struct msghdr *, msg, int, flags);
4379   ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4380}
4381
4382PRE(sys_recvmsg)
4383{
4384   *flags |= SfMayBlock;
4385   PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4386   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
4387   ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4388}
4389POST(sys_recvmsg)
4390{
4391   ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
4392}
4393
4394PRE(sys_shutdown)
4395{
4396   *flags |= SfMayBlock;
4397   PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
4398   PRE_REG_READ2(int, "shutdown", int, s, int, how);
4399}
4400
4401PRE(sys_bind)
4402{
4403   PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4404   PRE_REG_READ3(long, "bind",
4405                 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
4406   ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
4407}
4408
4409PRE(sys_listen)
4410{
4411   PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
4412   PRE_REG_READ2(long, "listen", int, s, int, backlog);
4413}
4414
4415PRE(sys_getsockname)
4416{
4417   PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
4418   PRE_REG_READ3(long, "getsockname",
4419                 int, s, struct sockaddr *, name, int *, namelen);
4420   ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
4421}
4422POST(sys_getsockname)
4423{
4424   vg_assert(SUCCESS);
4425   ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
4426                                          ARG1,ARG2,ARG3);
4427}
4428
4429PRE(sys_getpeername)
4430{
4431   PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
4432   PRE_REG_READ3(long, "getpeername",
4433                 int, s, struct sockaddr *, name, int *, namelen);
4434   ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
4435}
4436POST(sys_getpeername)
4437{
4438   vg_assert(SUCCESS);
4439   ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
4440                                          ARG1,ARG2,ARG3);
4441}
4442
4443PRE(sys_socketpair)
4444{
4445   PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
4446   PRE_REG_READ4(long, "socketpair",
4447                 int, d, int, type, int, protocol, int*, sv);
4448   ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
4449}
4450POST(sys_socketpair)
4451{
4452   vg_assert(SUCCESS);
4453   ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
4454                                         ARG1,ARG2,ARG3,ARG4);
4455}
4456
4457
4458/* ---------------------------------------------------------------------
4459   *at wrappers
4460   ------------------------------------------------------------------ */
4461
4462PRE(sys_openat)
4463{
4464   HChar  name[30];   // large enough
4465   SysRes sres;
4466
4467   if (ARG3 & VKI_O_CREAT) {
4468      // 4-arg version
4469      PRINT("sys_openat ( %ld, %#lx(%s), %ld, %ld )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
4470      PRE_REG_READ4(long, "openat",
4471                    int, dfd, const char *, filename, int, flags, int, mode);
4472   } else {
4473      // 3-arg version
4474      PRINT("sys_openat ( %ld, %#lx(%s), %ld )",ARG1,ARG2,(char*)ARG2,ARG3);
4475      PRE_REG_READ3(long, "openat",
4476                    int, dfd, const char *, filename, int, flags);
4477   }
4478
4479   PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
4480
4481   /* For absolute filenames, dfd is ignored.  If dfd is AT_FDCWD,
4482      filename is relative to cwd.  When comparing dfd against AT_FDCWD,
4483      be sure only to compare the bottom 32 bits. */
4484   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
4485       && *(Char *)ARG2 != '/'
4486       && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
4487       && !ML_(fd_allowed)(ARG1, "openat", tid, False))
4488      SET_STATUS_Failure( VKI_EBADF );
4489
4490   /* Handle the case where the open is of /proc/self/cmdline or
4491      /proc/<pid>/cmdline, and just give it a copy of the fd for the
4492      fake file we cooked up at startup (in m_main).  Also, seek the
4493      cloned fd back to the start. */
4494
4495   VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
4496   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
4497       && (VG_(strcmp)((HChar *)ARG2, name) == 0
4498           || VG_(strcmp)((HChar *)ARG2, "/proc/self/cmdline") == 0)) {
4499      sres = VG_(dup)( VG_(cl_cmdline_fd) );
4500      SET_STATUS_from_SysRes( sres );
4501      if (!sr_isError(sres)) {
4502         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
4503         if (off < 0)
4504            SET_STATUS_Failure( VKI_EMFILE );
4505      }
4506      return;
4507   }
4508
4509   /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
4510
4511   VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
4512   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
4513       && (VG_(strcmp)((HChar *)ARG2, name) == 0
4514           || VG_(strcmp)((HChar *)ARG2, "/proc/self/auxv") == 0)) {
4515      sres = VG_(dup)( VG_(cl_auxv_fd) );
4516      SET_STATUS_from_SysRes( sres );
4517      if (!sr_isError(sres)) {
4518         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
4519         if (off < 0)
4520            SET_STATUS_Failure( VKI_EMFILE );
4521      }
4522      return;
4523   }
4524
4525   /* Otherwise handle normally */
4526   *flags |= SfMayBlock;
4527}
4528
4529POST(sys_openat)
4530{
4531   vg_assert(SUCCESS);
4532   if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
4533      VG_(close)(RES);
4534      SET_STATUS_Failure( VKI_EMFILE );
4535   } else {
4536      if (VG_(clo_track_fds))
4537         ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
4538   }
4539}
4540
4541PRE(sys_mkdirat)
4542{
4543   *flags |= SfMayBlock;
4544   PRINT("sys_mkdirat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
4545   PRE_REG_READ3(long, "mkdirat",
4546                 int, dfd, const char *, pathname, int, mode);
4547   PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
4548}
4549
4550PRE(sys_mknodat)
4551{
4552  PRINT("sys_mknodat ( %ld, %#lx(%s), 0x%lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 );
4553   PRE_REG_READ4(long, "mknodat",
4554                 int, dfd, const char *, pathname, int, mode, unsigned, dev);
4555   PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
4556}
4557
4558PRE(sys_fchownat)
4559{
4560   PRINT("sys_fchownat ( %ld, %#lx(%s), 0x%lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
4561   PRE_REG_READ4(long, "fchownat",
4562                 int, dfd, const char *, path,
4563                 vki_uid_t, owner, vki_gid_t, group);
4564   PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
4565}
4566
4567PRE(sys_futimesat)
4568{
4569   PRINT("sys_futimesat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3);
4570   PRE_REG_READ3(long, "futimesat",
4571                 int, dfd, char *, filename, struct timeval *, tvp);
4572   if (ARG2 != 0)
4573      PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
4574   if (ARG3 != 0)
4575      PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
4576}
4577
4578PRE(sys_utimensat)
4579{
4580   PRINT("sys_utimensat ( %ld, %#lx(%s), %#lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
4581   PRE_REG_READ4(long, "utimensat",
4582                 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
4583   if (ARG2 != 0)
4584      PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
4585   if (ARG3 != 0)
4586      PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
4587}
4588
4589PRE(sys_newfstatat)
4590{
4591   FUSE_COMPATIBLE_MAY_BLOCK();
4592   PRINT("sys_newfstatat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3);
4593   PRE_REG_READ3(long, "fstatat",
4594                 int, dfd, char *, file_name, struct stat *, buf);
4595   PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
4596   PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
4597}
4598
4599POST(sys_newfstatat)
4600{
4601   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
4602}
4603
4604PRE(sys_unlinkat)
4605{
4606   *flags |= SfMayBlock;
4607   PRINT("sys_unlinkat ( %ld, %#lx(%s) )", ARG1,ARG2,(char*)ARG2);
4608   PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
4609   PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
4610}
4611
4612PRE(sys_renameat)
4613{
4614   PRINT("sys_renameat ( %ld, %#lx(%s), %ld, %#lx(%s) )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4);
4615   PRE_REG_READ4(long, "renameat",
4616                 int, olddfd, const char *, oldpath,
4617                 int, newdfd, const char *, newpath);
4618   PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
4619   PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
4620}
4621
4622PRE(sys_linkat)
4623{
4624   *flags |= SfMayBlock;
4625   PRINT("sys_linkat ( %ld, %#lx(%s), %ld, %#lx(%s), %ld )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4,ARG5);
4626   PRE_REG_READ5(long, "linkat",
4627                 int, olddfd, const char *, oldpath,
4628                 int, newdfd, const char *, newpath,
4629                 int, flags);
4630   PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
4631   PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
4632}
4633
4634PRE(sys_symlinkat)
4635{
4636   *flags |= SfMayBlock;
4637   PRINT("sys_symlinkat ( %#lx(%s), %ld, %#lx(%s) )",ARG1,(char*)ARG1,ARG2,ARG3,(char*)ARG3);
4638   PRE_REG_READ3(long, "symlinkat",
4639                 const char *, oldpath, int, newdfd, const char *, newpath);
4640   PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
4641   PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
4642}
4643
4644PRE(sys_readlinkat)
4645{
4646   HChar name[30];       // large enough
4647   Word  saved = SYSNO;
4648
4649   PRINT("sys_readlinkat ( %ld, %#lx(%s), %#lx, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4);
4650   PRE_REG_READ4(long, "readlinkat",
4651                 int, dfd, const char *, path, char *, buf, int, bufsiz);
4652   PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
4653   PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
4654
4655   /*
4656    * Handle the case where readlinkat is looking at /proc/self/exe or
4657    * /proc/<pid>/exe.
4658    */
4659   VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
4660   if (ML_(safe_to_deref)((void*)ARG2, 1)
4661       && (VG_(strcmp)((HChar *)ARG2, name) == 0
4662           || VG_(strcmp)((HChar *)ARG2, "/proc/self/exe") == 0)) {
4663      VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
4664      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
4665                                                      ARG3, ARG4));
4666   } else {
4667      /* Normal case */
4668      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
4669   }
4670
4671   if (SUCCESS && RES > 0)
4672      POST_MEM_WRITE( ARG3, RES );
4673}
4674
4675PRE(sys_fchmodat)
4676{
4677   PRINT("sys_fchmodat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
4678   PRE_REG_READ3(long, "fchmodat",
4679                 int, dfd, const char *, path, vki_mode_t, mode);
4680   PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
4681}
4682
4683PRE(sys_faccessat)
4684{
4685   PRINT("sys_faccessat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
4686   PRE_REG_READ3(long, "faccessat",
4687                 int, dfd, const char *, pathname, int, mode);
4688   PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
4689}
4690
4691PRE(sys_name_to_handle_at)
4692{
4693   PRINT("sys_name_to_handle_at ( %ld, %#lx(%s), %#lx, %#lx, %ld )", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
4694   PRE_REG_READ5(int, "name_to_handle_at",
4695                 int, dfd, const char *, name,
4696                 struct vki_file_handle *, handle,
4697                 int *, mnt_id, int, flag);
4698   PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
4699   if (ML_(safe_to_deref)( (void*)ARG3, sizeof(struct vki_file_handle))) {
4700      struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
4701      PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
4702      PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
4703   }
4704   PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
4705}
4706
4707POST(sys_name_to_handle_at)
4708{
4709   struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
4710   POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
4711   POST_MEM_WRITE( ARG4, sizeof(int) );
4712}
4713
4714PRE(sys_open_by_handle_at)
4715{
4716   *flags |= SfMayBlock;
4717   PRINT("sys_open_by_handle_at ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
4718   PRE_REG_READ3(int, "open_by_handle_at",
4719                 int, mountdirfd,
4720                 struct vki_file_handle *, handle,
4721                 int, flags);
4722   PRE_MEM_READ( "open_by_handle_at(handle)", ARG2, sizeof(struct vki_file_handle) + ((struct vki_file_handle*)ARG2)->handle_bytes );
4723}
4724
4725POST(sys_open_by_handle_at)
4726{
4727   vg_assert(SUCCESS);
4728   if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
4729      VG_(close)(RES);
4730      SET_STATUS_Failure( VKI_EMFILE );
4731   } else {
4732      if (VG_(clo_track_fds))
4733         ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
4734   }
4735}
4736
4737/* ---------------------------------------------------------------------
4738   p{read,write}v wrappers
4739   ------------------------------------------------------------------ */
4740
4741PRE(sys_preadv)
4742{
4743   Int i;
4744   struct vki_iovec * vec;
4745   *flags |= SfMayBlock;
4746#if VG_WORDSIZE == 4
4747   /* Note that the offset argument here is in lo+hi order on both
4748      big and little endian platforms... */
4749   PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5));
4750   PRE_REG_READ5(ssize_t, "preadv",
4751                 unsigned long, fd, const struct iovec *, vector,
4752                 unsigned long, count, vki_u32, offset_low,
4753                 vki_u32, offset_high);
4754#elif VG_WORDSIZE == 8
4755   PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4);
4756   PRE_REG_READ4(ssize_t, "preadv",
4757                 unsigned long, fd, const struct iovec *, vector,
4758                 unsigned long, count, Word, offset);
4759#else
4760#  error Unexpected word size
4761#endif
4762   if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
4763      SET_STATUS_Failure( VKI_EBADF );
4764   } else {
4765      PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
4766
4767      if (ARG2 != 0) {
4768         /* ToDo: don't do any of the following if the vector is invalid */
4769         vec = (struct vki_iovec *)ARG2;
4770         for (i = 0; i < (Int)ARG3; i++)
4771            PRE_MEM_WRITE( "preadv(vector[...])",
4772                           (Addr)vec[i].iov_base, vec[i].iov_len );
4773      }
4774   }
4775}
4776
4777POST(sys_preadv)
4778{
4779   vg_assert(SUCCESS);
4780   if (RES > 0) {
4781      Int i;
4782      struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4783      Int remains = RES;
4784
4785      /* RES holds the number of bytes read. */
4786      for (i = 0; i < (Int)ARG3; i++) {
4787	 Int nReadThisBuf = vec[i].iov_len;
4788	 if (nReadThisBuf > remains) nReadThisBuf = remains;
4789	 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4790	 remains -= nReadThisBuf;
4791	 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
4792      }
4793   }
4794}
4795
4796PRE(sys_pwritev)
4797{
4798   Int i;
4799   struct vki_iovec * vec;
4800   *flags |= SfMayBlock;
4801#if VG_WORDSIZE == 4
4802   /* Note that the offset argument here is in lo+hi order on both
4803      big and little endian platforms... */
4804   PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5));
4805   PRE_REG_READ5(ssize_t, "pwritev",
4806                 unsigned long, fd, const struct iovec *, vector,
4807                 unsigned long, count, vki_u32, offset_low,
4808                 vki_u32, offset_high);
4809#elif VG_WORDSIZE == 8
4810   PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4);
4811   PRE_REG_READ4(ssize_t, "pwritev",
4812                 unsigned long, fd, const struct iovec *, vector,
4813                 unsigned long, count, Word, offset);
4814#else
4815#  error Unexpected word size
4816#endif
4817   if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
4818      SET_STATUS_Failure( VKI_EBADF );
4819   } else {
4820      PRE_MEM_READ( "pwritev(vector)",
4821		     ARG2, ARG3 * sizeof(struct vki_iovec) );
4822      if (ARG2 != 0) {
4823         /* ToDo: don't do any of the following if the vector is invalid */
4824         vec = (struct vki_iovec *)ARG2;
4825         for (i = 0; i < (Int)ARG3; i++)
4826            PRE_MEM_READ( "pwritev(vector[...])",
4827                           (Addr)vec[i].iov_base, vec[i].iov_len );
4828      }
4829   }
4830}
4831
4832/* ---------------------------------------------------------------------
4833   process_vm_{read,write}v wrappers
4834   ------------------------------------------------------------------ */
4835
4836PRE(sys_process_vm_readv)
4837{
4838   PRINT("sys_process_vm_readv ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
4839         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4840   PRE_REG_READ6(ssize_t, "process_vm_readv",
4841                 vki_pid_t, pid,
4842                 const struct iovec *, lvec,
4843                 unsigned long, liovcnt,
4844                 const struct iovec *, rvec,
4845                 unsigned long, riovcnt,
4846                 unsigned long, flags);
4847   PRE_MEM_READ( "process_vm_readv(lvec)",
4848                 ARG2, ARG3 * sizeof(struct vki_iovec) );
4849   PRE_MEM_READ( "process_vm_readv(rvec)",
4850                 ARG4, ARG5 * sizeof(struct vki_iovec) );
4851   if (ARG2 != 0) {
4852      /* TODO: Don't do any of the following if lvec is invalid */
4853      const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
4854      UInt i;
4855      for (i = 0; i < ARG3; i++)
4856         PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
4857                        (Addr)vec[i].iov_base, vec[i].iov_len );
4858   }
4859}
4860
4861POST(sys_process_vm_readv)
4862{
4863   const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
4864   UInt remains = RES;
4865   UInt i;
4866   for (i = 0; i < ARG3; i++) {
4867      UInt nReadThisBuf = vec[i].iov_len <= remains ?
4868                          vec[i].iov_len : remains;
4869      POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4870      remains -= nReadThisBuf;
4871   }
4872}
4873
4874PRE(sys_process_vm_writev)
4875{
4876   PRINT("sys_process_vm_writev ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
4877         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4878   PRE_REG_READ6(ssize_t, "process_vm_writev",
4879                 vki_pid_t, pid,
4880                 const struct iovec *, lvec,
4881                 unsigned long, liovcnt,
4882                 const struct iovec *, rvec,
4883                 unsigned long, riovcnt,
4884                 unsigned long, flags);
4885   PRE_MEM_READ( "process_vm_writev(lvec)",
4886                 ARG2, ARG3 * sizeof(struct vki_iovec) );
4887   PRE_MEM_READ( "process_vm_writev(rvec)",
4888                 ARG4, ARG5 * sizeof(struct vki_iovec) );
4889   if (ARG2 != 0) {
4890      /* TODO: Don't do any of the following if lvec is invalid */
4891      const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
4892      UInt i;
4893      for (i = 0; i < ARG3; i++)
4894         PRE_MEM_READ( "process_vm_writev(lvec[...])",
4895                       (Addr)vec[i].iov_base, vec[i].iov_len );
4896   }
4897}
4898
4899/* ---------------------------------------------------------------------
4900   {send,recv}mmsg wrappers
4901   ------------------------------------------------------------------ */
4902
4903PRE(sys_sendmmsg)
4904{
4905   *flags |= SfMayBlock;
4906   PRINT("sys_sendmmsg ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
4907   PRE_REG_READ4(long, "sendmmsg",
4908                 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
4909   ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
4910}
4911
4912POST(sys_sendmmsg)
4913{
4914   ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
4915}
4916
4917PRE(sys_recvmmsg)
4918{
4919   *flags |= SfMayBlock;
4920   PRINT("sys_recvmmsg ( %ld, %#lx, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
4921   PRE_REG_READ5(long, "recvmmsg",
4922                 int, s, struct mmsghdr *, mmsg, int, vlen,
4923                 int, flags, struct timespec *, timeout);
4924   ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4925}
4926
4927POST(sys_recvmmsg)
4928{
4929   ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
4930}
4931
4932/* ---------------------------------------------------------------------
4933   key retention service wrappers
4934   ------------------------------------------------------------------ */
4935
4936PRE(sys_request_key)
4937{
4938   PRINT("sys_request_key ( %#lx(%s), %#lx(%s), %#lx(%s), %ld )",
4939         ARG1,(char*)ARG1,ARG2,(char*)ARG2,ARG3,(char*)ARG3,ARG4);
4940   PRE_REG_READ4(long, "request_key",
4941                 const char *, type, const char *, description,
4942                 const char *, callout_info, vki_key_serial_t, keyring);
4943   PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
4944   PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
4945   if (ARG3 != (UWord)NULL)
4946      PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
4947}
4948
4949PRE(sys_add_key)
4950{
4951   PRINT("sys_add_key ( %#lx(%s), %#lx(%s), %#lx, %ld, %ld )",
4952         ARG1,(char*)ARG1,ARG2,(char*)ARG2,ARG3,ARG4,ARG5);
4953   PRE_REG_READ5(long, "add_key",
4954                 const char *, type, const char *, description,
4955                 const void *, payload, vki_size_t, plen,
4956                 vki_key_serial_t, keyring);
4957   PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
4958   PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
4959   if (ARG3 != (UWord)NULL)
4960      PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
4961}
4962
4963PRE(sys_keyctl)
4964{
4965   switch (ARG1 /* option */) {
4966   case VKI_KEYCTL_GET_KEYRING_ID:
4967      PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", ARG2,ARG3);
4968      PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
4969                    int, option, vki_key_serial_t, id, int, create);
4970      break;
4971   case VKI_KEYCTL_JOIN_SESSION_KEYRING:
4972      PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#lx(%s) )", ARG2,(char*)ARG2);
4973      PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
4974                    int, option, const char *, name);
4975      if (ARG2 != (UWord)NULL)
4976         PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
4977      break;
4978   case VKI_KEYCTL_UPDATE:
4979      PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
4980      PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
4981                    int, option, vki_key_serial_t, key,
4982                    const void *, payload, vki_size_t, plen);
4983      if (ARG3 != (UWord)NULL)
4984         PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
4985      break;
4986   case VKI_KEYCTL_REVOKE:
4987      PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", ARG2);
4988      PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
4989                    int, option, vki_key_serial_t, id);
4990      break;
4991   case VKI_KEYCTL_CHOWN:
4992      PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %ld, %ld )", ARG2,ARG3,ARG4);
4993      PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
4994                    int, option, vki_key_serial_t, id,
4995                    vki_uid_t, uid, vki_gid_t, gid);
4996      break;
4997   case VKI_KEYCTL_SETPERM:
4998      PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %ld )", ARG2,ARG3);
4999      PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5000                    int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5001      break;
5002   case VKI_KEYCTL_DESCRIBE:
5003      PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
5004      PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5005                    int, option, vki_key_serial_t, id,
5006                    char *, buffer, vki_size_t, buflen);
5007      if (ARG3 != (UWord)NULL)
5008         PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5009      break;
5010   case VKI_KEYCTL_CLEAR:
5011      PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", ARG2);
5012      PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5013                    int, option, vki_key_serial_t, keyring);
5014      break;
5015   case VKI_KEYCTL_LINK:
5016      PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", ARG2,ARG3);
5017      PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5018                    vki_key_serial_t, keyring, vki_key_serial_t, key);
5019      break;
5020   case VKI_KEYCTL_UNLINK:
5021      PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", ARG2,ARG3);
5022      PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5023                    vki_key_serial_t, keyring, vki_key_serial_t, key);
5024      break;
5025   case VKI_KEYCTL_SEARCH:
5026      PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#lx(%s), %#lx(%s), %ld )",
5027            ARG2,ARG3,(char*)ARG3,ARG4,(char*)ARG4,ARG5);
5028      PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5029                    int, option, vki_key_serial_t, keyring,
5030                    const char *, type, const char *, description,
5031                    vki_key_serial_t, destring);
5032      PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5033      PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5034      break;
5035   case VKI_KEYCTL_READ:
5036      PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
5037      PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5038                    int, option, vki_key_serial_t, keyring,
5039                    char *, buffer, vki_size_t, buflen);
5040      if (ARG3 != (UWord)NULL)
5041         PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5042      break;
5043   case VKI_KEYCTL_INSTANTIATE:
5044      PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#lx, %ld, %ld )",
5045            ARG2,ARG3,ARG4,ARG5);
5046      PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5047                    int, option, vki_key_serial_t, key,
5048                    char *, payload, vki_size_t, plen,
5049                    vki_key_serial_t, keyring);
5050      if (ARG3 != (UWord)NULL)
5051         PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5052      break;
5053   case VKI_KEYCTL_NEGATE:
5054      PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %lu, %ld )", ARG2,ARG3,ARG4);
5055      PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5056                    int, option, vki_key_serial_t, key,
5057                    unsigned, timeout, vki_key_serial_t, keyring);
5058      break;
5059   case VKI_KEYCTL_SET_REQKEY_KEYRING:
5060      PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", ARG2);
5061      PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5062                    int, option, int, reqkey_defl);
5063      break;
5064   case VKI_KEYCTL_SET_TIMEOUT:
5065      PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %ld )", ARG2,ARG3);
5066      PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5067                    int, option, vki_key_serial_t, key, unsigned, timeout);
5068      break;
5069   case VKI_KEYCTL_ASSUME_AUTHORITY:
5070      PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", ARG2);
5071      PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5072                    int, option, vki_key_serial_t, key);
5073      break;
5074   default:
5075      PRINT("sys_keyctl ( %ld ) ", ARG1);
5076      PRE_REG_READ1(long, "keyctl", int, option);
5077      break;
5078   }
5079}
5080
5081POST(sys_keyctl)
5082{
5083   vg_assert(SUCCESS);
5084   switch (ARG1 /* option */) {
5085   case VKI_KEYCTL_DESCRIBE:
5086   case VKI_KEYCTL_READ:
5087      if (RES > ARG4)
5088         POST_MEM_WRITE(ARG3, ARG4);
5089      else
5090         POST_MEM_WRITE(ARG3, RES);
5091      break;
5092   default:
5093      break;
5094   }
5095}
5096
5097/* ---------------------------------------------------------------------
5098   ioprio_ wrappers
5099   ------------------------------------------------------------------ */
5100
5101PRE(sys_ioprio_set)
5102{
5103   PRINT("sys_ioprio_set ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5104   PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5105}
5106
5107PRE(sys_ioprio_get)
5108{
5109   PRINT("sys_ioprio_get ( %ld, %ld )", ARG1,ARG2);
5110   PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5111}
5112
5113/* ---------------------------------------------------------------------
5114   _module wrappers
5115   ------------------------------------------------------------------ */
5116
5117PRE(sys_init_module)
5118{
5119   *flags |= SfMayBlock;
5120   PRINT("sys_init_module ( %#lx, %llu, %#lx(\"%s\") )",
5121         ARG1, (ULong)ARG2, ARG3, (char*)ARG3);
5122   PRE_REG_READ3(long, "init_module",
5123                 void *, umod, unsigned long, len, const char *, uargs);
5124   PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5125   PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5126}
5127
5128PRE(sys_delete_module)
5129{
5130   *flags |= SfMayBlock;
5131   PRINT("sys_delete_module ( %#lx(\"%s\"), 0x%lx )", ARG1,(char*)ARG1, ARG2);
5132   PRE_REG_READ2(long, "delete_module",
5133                 const char *, name_user, unsigned int, flags);
5134   PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5135}
5136
5137/* ---------------------------------------------------------------------
5138   splice wrappers
5139   ------------------------------------------------------------------ */
5140
5141PRE(sys_splice)
5142{
5143   *flags |= SfMayBlock;
5144   PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %ld, %ld )",
5145         ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5146   PRE_REG_READ6(vki_ssize_t, "splice",
5147                 int, fd_in, vki_loff_t *, off_in,
5148                 int, fd_out, vki_loff_t *, off_out,
5149                 vki_size_t, len, unsigned int, flags);
5150   if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5151       !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5152      SET_STATUS_Failure( VKI_EBADF );
5153   } else {
5154      if (ARG2 != 0)
5155         PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5156      if (ARG4 != 0)
5157         PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5158   }
5159}
5160
5161PRE(sys_tee)
5162{
5163   *flags |= SfMayBlock;
5164   PRINT("sys_tree ( %ld, %ld, %ld, %ld )", ARG1,ARG2,ARG3,ARG4);
5165   PRE_REG_READ4(vki_ssize_t, "tee",
5166                 int, fd_in, int, fd_out,
5167                 vki_size_t, len, unsigned int, flags);
5168   if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5169       !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5170      SET_STATUS_Failure( VKI_EBADF );
5171   }
5172}
5173
5174PRE(sys_vmsplice)
5175{
5176   Int fdfl;
5177   *flags |= SfMayBlock;
5178   PRINT("sys_vmsplice ( %ld, %#lx, %ld, %ld )",
5179         ARG1,ARG2,ARG3,ARG4);
5180   PRE_REG_READ4(vki_ssize_t, "splice",
5181                 int, fd, struct vki_iovec *, iov,
5182                 unsigned long, nr_segs, unsigned int, flags);
5183   if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5184      SET_STATUS_Failure( VKI_EBADF );
5185   } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5186      SET_STATUS_Failure( VKI_EBADF );
5187   } else {
5188      const struct vki_iovec *iov;
5189      PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5190      for (iov = (struct vki_iovec *)ARG2;
5191           iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5192      {
5193         if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5194            PRE_MEM_WRITE( "vmsplice(iov[...])", (Addr)iov->iov_base, iov->iov_len );
5195         else
5196            PRE_MEM_READ( "vmsplice(iov[...])", (Addr)iov->iov_base, iov->iov_len );
5197      }
5198   }
5199}
5200
5201POST(sys_vmsplice)
5202{
5203   vg_assert(SUCCESS);
5204   if (RES > 0) {
5205      Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
5206      vg_assert(fdfl >= 0);
5207      if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5208      {
5209         const struct vki_iovec *iov;
5210         for (iov = (struct vki_iovec *)ARG2;
5211              iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5212         {
5213            POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
5214         }
5215      }
5216   }
5217}
5218
5219/* ---------------------------------------------------------------------
5220   oprofile-related wrappers
5221   ------------------------------------------------------------------ */
5222
5223#if defined(VGP_x86_linux)
5224PRE(sys_lookup_dcookie)
5225{
5226   PRINT("sys_lookup_dcookie (0x%llx, %#lx, %ld)",
5227         MERGE64(ARG1,ARG2), ARG3, ARG4);
5228   PRE_REG_READ4(long, "lookup_dcookie",
5229                 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
5230                 char *, buf, vki_size_t, len);
5231   PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
5232}
5233POST(sys_lookup_dcookie)
5234{
5235   vg_assert(SUCCESS);
5236   if (ARG3 != (Addr)NULL)
5237      POST_MEM_WRITE( ARG3, RES);
5238}
5239#endif
5240
5241#if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)        \
5242      || defined(VGP_tilegx_linux)
5243PRE(sys_lookup_dcookie)
5244{
5245   *flags |= SfMayBlock;
5246   PRINT("sys_lookup_dcookie ( %llu, %#lx, %llu )",
5247	 (ULong)ARG1, ARG2, (ULong)ARG3);
5248   PRE_REG_READ3(int, "lookup_dcookie",
5249                 unsigned long long, cookie, char *, buf, vki_size_t, len);
5250
5251   PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
5252}
5253
5254POST(sys_lookup_dcookie)
5255{
5256   vg_assert(SUCCESS);
5257   if (ARG2 != (Addr)NULL)
5258     POST_MEM_WRITE( ARG2, RES );
5259}
5260#endif
5261
5262/* ---------------------------------------------------------------------
5263   fcntl wrappers
5264   ------------------------------------------------------------------ */
5265
5266PRE(sys_fcntl)
5267{
5268   switch (ARG2) {
5269   // These ones ignore ARG3.
5270   case VKI_F_GETFD:
5271   case VKI_F_GETFL:
5272   case VKI_F_GETOWN:
5273   case VKI_F_GETSIG:
5274   case VKI_F_GETLEASE:
5275   case VKI_F_GETPIPE_SZ:
5276      PRINT("sys_fcntl ( %ld, %ld )", ARG1,ARG2);
5277      PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
5278      break;
5279
5280   // These ones use ARG3 as "arg".
5281   case VKI_F_DUPFD:
5282   case VKI_F_DUPFD_CLOEXEC:
5283   case VKI_F_SETFD:
5284   case VKI_F_SETFL:
5285   case VKI_F_SETLEASE:
5286   case VKI_F_NOTIFY:
5287   case VKI_F_SETOWN:
5288   case VKI_F_SETSIG:
5289   case VKI_F_SETPIPE_SZ:
5290      PRINT("sys_fcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5291      PRE_REG_READ3(long, "fcntl",
5292                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
5293      break;
5294
5295   // These ones use ARG3 as "lock".
5296   case VKI_F_GETLK:
5297   case VKI_F_SETLK:
5298   case VKI_F_SETLKW:
5299#  if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
5300   case VKI_F_GETLK64:
5301   case VKI_F_SETLK64:
5302   case VKI_F_SETLKW64:
5303#  endif
5304   case VKI_F_OFD_GETLK:
5305   case VKI_F_OFD_SETLK:
5306   case VKI_F_OFD_SETLKW:
5307      PRINT("sys_fcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
5308      PRE_REG_READ3(long, "fcntl",
5309                    unsigned int, fd, unsigned int, cmd,
5310                    struct flock64 *, lock);
5311      break;
5312
5313   case VKI_F_SETOWN_EX:
5314      PRINT("sys_fcntl[F_SETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5315      PRE_REG_READ3(long, "fcntl",
5316                    unsigned int, fd, unsigned int, cmd,
5317                    struct vki_f_owner_ex *, arg);
5318      PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5319      break;
5320
5321   case VKI_F_GETOWN_EX:
5322      PRINT("sys_fcntl[F_GETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5323      PRE_REG_READ3(long, "fcntl",
5324                    unsigned int, fd, unsigned int, cmd,
5325                    struct vki_f_owner_ex *, arg);
5326      PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5327      break;
5328
5329   default:
5330      PRINT("sys_fcntl[UNKNOWN] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5331      I_die_here;
5332      break;
5333   }
5334
5335#  if defined(VGP_x86_linux)
5336   if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
5337#  else
5338   if (ARG2 == VKI_F_SETLKW)
5339#  endif
5340      *flags |= SfMayBlock;
5341}
5342
5343POST(sys_fcntl)
5344{
5345   vg_assert(SUCCESS);
5346   if (ARG2 == VKI_F_DUPFD) {
5347      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
5348         VG_(close)(RES);
5349         SET_STATUS_Failure( VKI_EMFILE );
5350      } else {
5351         if (VG_(clo_track_fds))
5352            ML_(record_fd_open_named)(tid, RES);
5353      }
5354   }
5355   else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
5356      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
5357         VG_(close)(RES);
5358         SET_STATUS_Failure( VKI_EMFILE );
5359      } else {
5360         if (VG_(clo_track_fds))
5361            ML_(record_fd_open_named)(tid, RES);
5362      }
5363   } else if (ARG2 == VKI_F_GETOWN_EX) {
5364      POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
5365   }
5366}
5367
5368// XXX: wrapper only suitable for 32-bit systems
5369PRE(sys_fcntl64)
5370{
5371   switch (ARG2) {
5372   // These ones ignore ARG3.
5373   case VKI_F_GETFD:
5374   case VKI_F_GETFL:
5375   case VKI_F_GETOWN:
5376   case VKI_F_SETOWN:
5377   case VKI_F_GETSIG:
5378   case VKI_F_SETSIG:
5379   case VKI_F_GETLEASE:
5380      PRINT("sys_fcntl64 ( %ld, %ld )", ARG1,ARG2);
5381      PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
5382      break;
5383
5384   // These ones use ARG3 as "arg".
5385   case VKI_F_DUPFD:
5386   case VKI_F_DUPFD_CLOEXEC:
5387   case VKI_F_SETFD:
5388   case VKI_F_SETFL:
5389   case VKI_F_SETLEASE:
5390   case VKI_F_NOTIFY:
5391      PRINT("sys_fcntl64[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5392      PRE_REG_READ3(long, "fcntl64",
5393                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
5394      break;
5395
5396   // These ones use ARG3 as "lock".
5397   case VKI_F_GETLK:
5398   case VKI_F_SETLK:
5399   case VKI_F_SETLKW:
5400#  if defined(VGP_x86_linux)
5401   case VKI_F_GETLK64:
5402   case VKI_F_SETLK64:
5403   case VKI_F_SETLKW64:
5404#  endif
5405   case VKI_F_OFD_GETLK:
5406   case VKI_F_OFD_SETLK:
5407   case VKI_F_OFD_SETLKW:
5408      PRINT("sys_fcntl64[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
5409      PRE_REG_READ3(long, "fcntl64",
5410                    unsigned int, fd, unsigned int, cmd,
5411                    struct flock64 *, lock);
5412      break;
5413
5414   case VKI_F_SETOWN_EX:
5415      PRINT("sys_fcntl[F_SETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5416      PRE_REG_READ3(long, "fcntl",
5417                    unsigned int, fd, unsigned int, cmd,
5418                    struct vki_f_owner_ex *, arg);
5419      PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5420      break;
5421
5422   case VKI_F_GETOWN_EX:
5423      PRINT("sys_fcntl[F_GETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5424      PRE_REG_READ3(long, "fcntl",
5425                    unsigned int, fd, unsigned int, cmd,
5426                    struct vki_f_owner_ex *, arg);
5427      PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5428      break;
5429   }
5430
5431#  if defined(VGP_x86_linux)
5432   if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
5433#  else
5434   if (ARG2 == VKI_F_SETLKW)
5435#  endif
5436      *flags |= SfMayBlock;
5437}
5438
5439POST(sys_fcntl64)
5440{
5441   vg_assert(SUCCESS);
5442   if (ARG2 == VKI_F_DUPFD) {
5443      if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
5444         VG_(close)(RES);
5445         SET_STATUS_Failure( VKI_EMFILE );
5446      } else {
5447         if (VG_(clo_track_fds))
5448            ML_(record_fd_open_named)(tid, RES);
5449      }
5450   }
5451   else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
5452      if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
5453         VG_(close)(RES);
5454         SET_STATUS_Failure( VKI_EMFILE );
5455      } else {
5456         if (VG_(clo_track_fds))
5457            ML_(record_fd_open_named)(tid, RES);
5458      }
5459   } else if (ARG2 == VKI_F_GETOWN_EX) {
5460      POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
5461   }
5462}
5463
5464/* ---------------------------------------------------------------------
5465   ioctl wrappers
5466   ------------------------------------------------------------------ */
5467
5468PRE(sys_ioctl)
5469{
5470   *flags |= SfMayBlock;
5471
5472   ARG2 = (UInt)ARG2;
5473
5474   // We first handle the ones that don't use ARG3 (even as a
5475   // scalar/non-pointer argument).
5476   switch (ARG2 /* request */) {
5477
5478      /* asm-generic/ioctls.h */
5479   case VKI_FIOCLEX:
5480   case VKI_FIONCLEX:
5481   case VKI_TIOCNOTTY:
5482
5483      /* linux/soundcard interface (ALSA) */
5484   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
5485   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
5486   case VKI_SNDRV_PCM_IOCTL_PREPARE:
5487   case VKI_SNDRV_PCM_IOCTL_RESET:
5488   case VKI_SNDRV_PCM_IOCTL_START:
5489   case VKI_SNDRV_PCM_IOCTL_DROP:
5490   case VKI_SNDRV_PCM_IOCTL_DRAIN:
5491   case VKI_SNDRV_PCM_IOCTL_RESUME:
5492   case VKI_SNDRV_PCM_IOCTL_XRUN:
5493   case VKI_SNDRV_PCM_IOCTL_UNLINK:
5494   case VKI_SNDRV_TIMER_IOCTL_START:
5495   case VKI_SNDRV_TIMER_IOCTL_STOP:
5496   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
5497   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
5498
5499      /* SCSI no operand */
5500   case VKI_SCSI_IOCTL_DOORLOCK:
5501   case VKI_SCSI_IOCTL_DOORUNLOCK:
5502
5503   /* CDROM stuff. */
5504   case VKI_CDROM_DISC_STATUS:
5505
5506   /* KVM ioctls that dont check for a numeric value as parameter */
5507   case VKI_KVM_S390_ENABLE_SIE:
5508   case VKI_KVM_CREATE_IRQCHIP:
5509   case VKI_KVM_S390_INITIAL_RESET:
5510   case VKI_KVM_KVMCLOCK_CTRL:
5511
5512   /* vhost without parameter */
5513   case VKI_VHOST_SET_OWNER:
5514   case VKI_VHOST_RESET_OWNER:
5515
5516   /* User input device creation */
5517   case VKI_UI_DEV_CREATE:
5518   case VKI_UI_DEV_DESTROY:
5519
5520   /* InfiniBand */
5521   case VKI_IB_USER_MAD_ENABLE_PKEY:
5522
5523   /* V4L2 */
5524   case VKI_V4L2_LOG_STATUS:
5525      PRINT("sys_ioctl ( %ld, 0x%lx )",ARG1,ARG2);
5526      PRE_REG_READ2(long, "ioctl",
5527                    unsigned int, fd, unsigned int, request);
5528      return;
5529
5530   default:
5531      PRINT("sys_ioctl ( %ld, 0x%lx, 0x%lx )",ARG1,ARG2,ARG3);
5532      PRE_REG_READ3(long, "ioctl",
5533                    unsigned int, fd, unsigned int, request, unsigned long, arg);
5534      break;
5535   }
5536
5537   // We now handle those that do look at ARG3 (and unknown ones fall into
5538   // this category).  Nb: some of these may well belong in the
5539   // doesn't-use-ARG3 switch above.
5540   switch (ARG2 /* request */) {
5541
5542   case VKI_ION_IOC_ALLOC: {
5543      struct vki_ion_allocation_data* data
5544         = (struct vki_ion_allocation_data*)ARG3;
5545      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len",          data->len);
5546      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align",        data->align);
5547      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
5548      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags",        data->flags);
5549      PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle",       data->handle);
5550      break;
5551   }
5552   case VKI_ION_IOC_MAP: {
5553      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
5554      PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
5555      PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd",     data->fd);
5556      break;
5557   }
5558   case VKI_ION_IOC_IMPORT: {
5559      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
5560      PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd",     data->fd);
5561      PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
5562      break;
5563   }
5564
5565   case VKI_SYNC_IOC_MERGE: {
5566      struct vki_sync_merge_data* data = (struct vki_sync_merge_data*)ARG3;
5567      PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2",   data->fd2);
5568      PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name",  (Addr)(&data->name[0]));
5569      PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
5570      break;
5571   }
5572
5573   case VKI_TCSETS:
5574   case VKI_TCSETSW:
5575   case VKI_TCSETSF:
5576      PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
5577      break;
5578   case VKI_TCGETS:
5579      PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
5580      break;
5581   case VKI_TCSETA:
5582   case VKI_TCSETAW:
5583   case VKI_TCSETAF:
5584      PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
5585      break;
5586   case VKI_TCGETA:
5587      PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
5588      break;
5589   case VKI_TCSBRK:
5590   case VKI_TCXONC:
5591   case VKI_TCSBRKP:
5592   case VKI_TCFLSH:
5593   case VKI_TIOCSIG:
5594      /* These just take an int by value */
5595      break;
5596   case VKI_TIOCGWINSZ:
5597      PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
5598      break;
5599   case VKI_TIOCSWINSZ:
5600      PRE_MEM_READ( "ioctl(TIOCSWINSZ)",  ARG3, sizeof(struct vki_winsize) );
5601      break;
5602   case VKI_TIOCMBIS:
5603      PRE_MEM_READ( "ioctl(TIOCMBIS)",    ARG3, sizeof(unsigned int) );
5604      break;
5605   case VKI_TIOCMBIC:
5606      PRE_MEM_READ( "ioctl(TIOCMBIC)",    ARG3, sizeof(unsigned int) );
5607      break;
5608   case VKI_TIOCMSET:
5609      PRE_MEM_READ( "ioctl(TIOCMSET)",    ARG3, sizeof(unsigned int) );
5610      break;
5611   case VKI_TIOCMGET:
5612      PRE_MEM_WRITE( "ioctl(TIOCMGET)",   ARG3, sizeof(unsigned int) );
5613      break;
5614   case VKI_TIOCLINUX:
5615      PRE_MEM_READ( "ioctl(TIOCLINUX)",   ARG3, sizeof(char *) );
5616      if (*(char *)ARG3 == 11) {
5617	 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
5618      }
5619      break;
5620   case VKI_TIOCGPGRP:
5621      /* Get process group ID for foreground processing group. */
5622      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
5623      break;
5624   case VKI_TIOCSPGRP:
5625      /* Set a process group ID? */
5626      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
5627      break;
5628   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
5629      PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
5630      break;
5631   case VKI_TIOCSCTTY:
5632      /* Just takes an int value.  */
5633      break;
5634   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
5635      PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
5636      break;
5637   case VKI_FIONBIO:
5638      PRE_MEM_READ( "ioctl(FIONBIO)",    ARG3, sizeof(int) );
5639      break;
5640   case VKI_FIOASYNC:
5641      PRE_MEM_READ( "ioctl(FIOASYNC)",   ARG3, sizeof(int) );
5642      break;
5643   case VKI_FIONREAD:                /* identical to SIOCINQ */
5644      PRE_MEM_WRITE( "ioctl(FIONREAD)",  ARG3, sizeof(int) );
5645      break;
5646   case VKI_FIOQSIZE:
5647      PRE_MEM_WRITE( "ioctl(FIOQSIZE)",  ARG3, sizeof(vki_loff_t) );
5648      break;
5649
5650   case VKI_TIOCSERGETLSR:
5651      PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
5652      break;
5653   case VKI_TIOCGICOUNT:
5654      PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
5655                     sizeof(struct vki_serial_icounter_struct) );
5656      break;
5657
5658   case VKI_SG_SET_COMMAND_Q:
5659      PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
5660      break;
5661   case VKI_SG_IO:
5662      PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
5663      {
5664         vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)ARG3;
5665         PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
5666         if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
5667              sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
5668            PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
5669         }
5670      }
5671      break;
5672   case VKI_SG_GET_SCSI_ID:
5673      PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
5674      break;
5675   case VKI_SG_SET_RESERVED_SIZE:
5676      PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
5677      break;
5678   case VKI_SG_SET_TIMEOUT:
5679      PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
5680      break;
5681   case VKI_SG_GET_RESERVED_SIZE:
5682      PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
5683      break;
5684   case VKI_SG_GET_TIMEOUT:
5685      break;
5686   case VKI_SG_GET_VERSION_NUM:
5687      PRE_MEM_WRITE(  "ioctl(SG_GET_VERSION_NUM)",  ARG3, sizeof(int) );
5688      break;
5689   case VKI_SG_EMULATED_HOST: /* 0x2203 */
5690      PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)",    ARG3, sizeof(int) );
5691      break;
5692   case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
5693      PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
5694      break;
5695
5696   case VKI_IIOCGETCPS:
5697      PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
5698		     VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
5699      break;
5700   case VKI_IIOCNETGPN:
5701      PRE_MEM_READ( "ioctl(IIOCNETGPN)",
5702		     (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
5703		     sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
5704      PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
5705		     sizeof(vki_isdn_net_ioctl_phone) );
5706      break;
5707
5708      /* These all use struct ifreq AFAIK */
5709   case VKI_SIOCGIFINDEX:        /* get iface index              */
5710      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
5711                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5712      PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
5713      break;
5714   case VKI_SIOCGIFFLAGS:        /* get flags                    */
5715      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
5716                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5717      PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
5718      break;
5719   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
5720      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
5721                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5722      PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
5723      break;
5724   case VKI_SIOCGIFMTU:          /* get MTU size                 */
5725      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
5726                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5727      PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
5728      break;
5729   case VKI_SIOCGIFADDR:         /* get PA address               */
5730      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
5731                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5732      PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
5733      break;
5734   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
5735      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
5736                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5737      PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
5738      break;
5739   case VKI_SIOCGIFMETRIC:       /* get metric                   */
5740      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
5741                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5742      PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
5743      break;
5744   case VKI_SIOCGIFMAP:          /* Get device parameters        */
5745      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
5746                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5747      PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
5748      break;
5749   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
5750      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
5751                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5752      PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
5753      break;
5754   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
5755      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
5756                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5757      PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
5758      break;
5759   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
5760      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
5761                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5762      PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
5763      break;
5764   case VKI_SIOCGIFNAME:         /* get iface name               */
5765      PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
5766                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
5767                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
5768      PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
5769      break;
5770   case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
5771      struct vki_ifreq *ir = (struct vki_ifreq *)ARG3;
5772      PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
5773      PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
5774      PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
5775      PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
5776      switch ( *(vki_u32 *)ir->vki_ifr_data ) {
5777      case VKI_ETHTOOL_GSET:
5778         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
5779                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
5780         break;
5781      case VKI_ETHTOOL_SSET:
5782         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
5783                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
5784         break;
5785      case VKI_ETHTOOL_GDRVINFO:
5786         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
5787                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
5788         break;
5789      case VKI_ETHTOOL_GREGS:
5790         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
5791                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
5792         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
5793                        (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
5794                        ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
5795         break;
5796      case VKI_ETHTOOL_GWOL:
5797         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
5798                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
5799         break;
5800      case VKI_ETHTOOL_SWOL:
5801         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
5802                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
5803         break;
5804      case VKI_ETHTOOL_GMSGLVL:
5805      case VKI_ETHTOOL_GLINK:
5806      case VKI_ETHTOOL_GRXCSUM:
5807      case VKI_ETHTOOL_GSG:
5808      case VKI_ETHTOOL_GTSO:
5809      case VKI_ETHTOOL_GUFO:
5810      case VKI_ETHTOOL_GGSO:
5811      case VKI_ETHTOOL_GFLAGS:
5812      case VKI_ETHTOOL_GGRO:
5813         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
5814                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
5815         break;
5816      case VKI_ETHTOOL_SMSGLVL:
5817      case VKI_ETHTOOL_SRXCSUM:
5818      case VKI_ETHTOOL_SSG:
5819      case VKI_ETHTOOL_STSO:
5820      case VKI_ETHTOOL_SUFO:
5821      case VKI_ETHTOOL_SGSO:
5822      case VKI_ETHTOOL_SFLAGS:
5823      case VKI_ETHTOOL_SGRO:
5824         PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
5825                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
5826         break;
5827      case VKI_ETHTOOL_NWAY_RST:
5828         break;
5829      case VKI_ETHTOOL_GRINGPARAM:
5830         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
5831                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
5832         break;
5833      case VKI_ETHTOOL_SRINGPARAM:
5834         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
5835                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
5836         break;
5837      case VKI_ETHTOOL_TEST:
5838         PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
5839                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
5840         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
5841                        (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
5842                        ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
5843         break;
5844      case VKI_ETHTOOL_PHYS_ID:
5845         break;
5846      case VKI_ETHTOOL_GPERMADDR:
5847         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
5848                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
5849         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
5850                        (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
5851                        ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
5852         break;
5853      case VKI_ETHTOOL_RESET:
5854         break;
5855      case VKI_ETHTOOL_GSSET_INFO:
5856         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
5857                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
5858         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
5859                        (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
5860                        __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
5861         break;
5862      case VKI_ETHTOOL_GFEATURES:
5863         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
5864                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
5865         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
5866                        (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
5867                        ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
5868         break;
5869      case VKI_ETHTOOL_SFEATURES:
5870         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
5871                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
5872         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
5873                       (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
5874                       ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
5875         break;
5876      case VKI_ETHTOOL_GCHANNELS:
5877         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
5878                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
5879         break;
5880      case VKI_ETHTOOL_SCHANNELS:
5881         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
5882                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
5883         break;
5884      case VKI_ETHTOOL_GET_TS_INFO:
5885         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
5886                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
5887         break;
5888      }
5889      break;
5890   }
5891   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
5892      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
5893                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5894      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
5895      break;
5896   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
5897      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
5898                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5899      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
5900                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
5901                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
5902      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
5903                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
5904                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
5905      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
5906		     sizeof(struct vki_ifreq));
5907      break;
5908   case VKI_SIOCGIFCONF:         /* get iface list               */
5909      /* WAS:
5910	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
5911	 KERNEL_DO_SYSCALL(tid,RES);
5912	 if (!VG_(is_kerror)(RES) && RES == 0)
5913	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
5914      */
5915      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
5916                    (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
5917                    sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
5918      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
5919                    (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
5920                    sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
5921      if ( ARG3 ) {
5922	 // TODO len must be readable and writable
5923	 // buf pointer only needs to be readable
5924	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
5925	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
5926			(Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
5927      }
5928      break;
5929   case VKI_SIOCGSTAMP:
5930      PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
5931      break;
5932   case VKI_SIOCGSTAMPNS:
5933      PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
5934      break;
5935      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
5936	 the number of bytes currently in that socket's send buffer.
5937	 It writes this value as an int to the memory location
5938	 indicated by the third argument of ioctl(2). */
5939   case VKI_SIOCOUTQ:
5940      PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
5941      break;
5942   case VKI_SIOCGRARP:           /* get RARP table entry         */
5943   case VKI_SIOCGARP:            /* get ARP table entry          */
5944      PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
5945      break;
5946
5947   case VKI_SIOCSIFFLAGS:        /* set flags                    */
5948      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
5949                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5950      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
5951                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
5952                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
5953      break;
5954   case VKI_SIOCSIFMAP:          /* Set device parameters        */
5955      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
5956                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5957      PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
5958                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
5959                     sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
5960      break;
5961   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
5962      PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
5963                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5964      PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
5965                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_data,
5966                     sizeof(struct vki_hwtstamp_config) );
5967      break;
5968   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
5969      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
5970                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5971      PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
5972                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
5973                     sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
5974      break;
5975   case VKI_SIOCSIFADDR:         /* set PA address               */
5976   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
5977   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
5978   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
5979      PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
5980                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5981      PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
5982                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
5983                     sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
5984      break;
5985   case VKI_SIOCSIFMETRIC:       /* set metric                   */
5986      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
5987                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5988      PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
5989                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
5990                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
5991      break;
5992   case VKI_SIOCSIFMTU:          /* set MTU size                 */
5993      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
5994                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5995      PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
5996                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
5997                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
5998      break;
5999   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
6000      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
6001                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6002      PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
6003                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
6004                     sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
6005      break;
6006   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
6007      PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
6008                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6009      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6010                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
6011                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
6012      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6013                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
6014                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
6015      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6016                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
6017                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
6018      break;
6019      /* Routing table calls.  */
6020   case VKI_SIOCADDRT:           /* add routing table entry      */
6021   case VKI_SIOCDELRT:           /* delete routing table entry   */
6022      PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
6023		    sizeof(struct vki_rtentry));
6024      break;
6025
6026      /* tun/tap related ioctls */
6027   case VKI_TUNSETNOCSUM:
6028   case VKI_TUNSETDEBUG:
6029      break;
6030   case VKI_TUNSETIFF:
6031      PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
6032                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6033      PRE_MEM_READ( "ioctl(TUNSETIFF)",
6034                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6035                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6036      PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
6037      break;
6038   case VKI_TUNSETPERSIST:
6039   case VKI_TUNSETOWNER:
6040   case VKI_TUNSETLINK:
6041   case VKI_TUNSETGROUP:
6042      break;
6043   case VKI_TUNGETFEATURES:
6044      PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
6045      break;
6046   case VKI_TUNSETOFFLOAD:
6047      break;
6048   case VKI_TUNGETIFF:
6049      PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
6050      break;
6051   case VKI_TUNGETSNDBUF:
6052      PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
6053      break;
6054   case VKI_TUNSETSNDBUF:
6055      PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
6056      break;
6057   case VKI_TUNGETVNETHDRSZ:
6058      PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
6059      break;
6060   case VKI_TUNSETVNETHDRSZ:
6061      PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
6062      break;
6063   case VKI_TUNSETQUEUE:
6064      PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
6065                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6066                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6067      break;
6068   case VKI_TUNSETIFINDEX:
6069      PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
6070      break;
6071
6072      /* RARP cache control calls. */
6073   case VKI_SIOCDRARP:           /* delete RARP table entry      */
6074   case VKI_SIOCSRARP:           /* set RARP table entry         */
6075      /* ARP cache control calls. */
6076   case VKI_SIOCSARP:            /* set ARP table entry          */
6077   case VKI_SIOCDARP:            /* delete ARP table entry       */
6078      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6079      break;
6080
6081   case VKI_SIOCGPGRP:
6082      PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6083      break;
6084   case VKI_SIOCSPGRP:
6085      PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6086      //tst->sys_flags &= ~SfMayBlock;
6087      break;
6088
6089    case VKI_SIOCATMARK:
6090      PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
6091      break;
6092
6093      /* linux/soundcard interface (OSS) */
6094   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6095   case VKI_SNDCTL_SEQ_GETINCOUNT:
6096   case VKI_SNDCTL_SEQ_PERCMODE:
6097   case VKI_SNDCTL_SEQ_TESTMIDI:
6098   case VKI_SNDCTL_SEQ_RESETSAMPLES:
6099   case VKI_SNDCTL_SEQ_NRSYNTHS:
6100   case VKI_SNDCTL_SEQ_NRMIDIS:
6101   case VKI_SNDCTL_SEQ_GETTIME:
6102   case VKI_SNDCTL_DSP_GETBLKSIZE:
6103   case VKI_SNDCTL_DSP_GETFMTS:
6104   case VKI_SNDCTL_DSP_GETTRIGGER:
6105   case VKI_SNDCTL_DSP_GETODELAY:
6106   case VKI_SNDCTL_DSP_GETSPDIF:
6107   case VKI_SNDCTL_DSP_GETCAPS:
6108   case VKI_SOUND_PCM_READ_RATE:
6109   case VKI_SOUND_PCM_READ_CHANNELS:
6110   case VKI_SOUND_PCM_READ_BITS:
6111   case VKI_SOUND_PCM_READ_FILTER:
6112      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6113		     ARG3, sizeof(int));
6114      break;
6115   case VKI_SNDCTL_SEQ_CTRLRATE:
6116   case VKI_SNDCTL_DSP_SPEED:
6117   case VKI_SNDCTL_DSP_STEREO:
6118   case VKI_SNDCTL_DSP_CHANNELS:
6119   case VKI_SOUND_PCM_WRITE_FILTER:
6120   case VKI_SNDCTL_DSP_SUBDIVIDE:
6121   case VKI_SNDCTL_DSP_SETFRAGMENT:
6122   case VKI_SNDCTL_DSP_SETFMT:
6123   case VKI_SNDCTL_DSP_GETCHANNELMASK:
6124   case VKI_SNDCTL_DSP_BIND_CHANNEL:
6125   case VKI_SNDCTL_TMR_TIMEBASE:
6126   case VKI_SNDCTL_TMR_TEMPO:
6127   case VKI_SNDCTL_TMR_SOURCE:
6128   case VKI_SNDCTL_MIDI_PRETIME:
6129   case VKI_SNDCTL_MIDI_MPUMODE:
6130      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6131		     ARG3, sizeof(int));
6132      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6133		     ARG3, sizeof(int));
6134      break;
6135   case VKI_SNDCTL_DSP_GETOSPACE:
6136   case VKI_SNDCTL_DSP_GETISPACE:
6137      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
6138                     ARG3, sizeof(vki_audio_buf_info));
6139      break;
6140   case VKI_SNDCTL_DSP_NONBLOCK:
6141      break;
6142   case VKI_SNDCTL_DSP_SETTRIGGER:
6143      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
6144		     ARG3, sizeof(int));
6145      break;
6146
6147   case VKI_SNDCTL_DSP_POST:
6148   case VKI_SNDCTL_DSP_RESET:
6149   case VKI_SNDCTL_DSP_SYNC:
6150   case VKI_SNDCTL_DSP_SETSYNCRO:
6151   case VKI_SNDCTL_DSP_SETDUPLEX:
6152      break;
6153
6154      /* linux/soundcard interface (ALSA) */
6155   case VKI_SNDRV_PCM_IOCTL_PAUSE:
6156   case VKI_SNDRV_PCM_IOCTL_LINK:
6157      /* these just take an int by value */
6158      break;
6159   case VKI_SNDRV_CTL_IOCTL_PVERSION:
6160      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
6161      break;
6162   case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
6163      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
6164      break;
6165   case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
6166      struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
6167      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
6168      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
6169      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
6170      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
6171      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
6172      if (data->pids) {
6173         PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
6174      }
6175      break;
6176   }
6177   case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
6178      struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
6179      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
6180      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
6181      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
6182      break;
6183   }
6184   case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
6185   case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
6186      struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
6187      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
6188      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
6189      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
6190      break;
6191   }
6192
6193      /* Real Time Clock (/dev/rtc) ioctls */
6194   case VKI_RTC_UIE_ON:
6195   case VKI_RTC_UIE_OFF:
6196   case VKI_RTC_AIE_ON:
6197   case VKI_RTC_AIE_OFF:
6198   case VKI_RTC_PIE_ON:
6199   case VKI_RTC_PIE_OFF:
6200   case VKI_RTC_IRQP_SET:
6201      break;
6202   case VKI_RTC_RD_TIME:
6203   case VKI_RTC_ALM_READ:
6204      PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
6205		     ARG3, sizeof(struct vki_rtc_time));
6206      break;
6207   case VKI_RTC_ALM_SET:
6208      PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
6209      break;
6210   case VKI_RTC_IRQP_READ:
6211      PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
6212      break;
6213
6214      /* Block devices */
6215   case VKI_BLKROSET:
6216      PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
6217      break;
6218   case VKI_BLKROGET:
6219      PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
6220      break;
6221   case VKI_BLKGETSIZE:
6222      PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
6223      break;
6224   case VKI_BLKRASET:
6225      break;
6226   case VKI_BLKRAGET:
6227      PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
6228      break;
6229   case VKI_BLKFRASET:
6230      break;
6231   case VKI_BLKFRAGET:
6232      PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
6233      break;
6234   case VKI_BLKSECTGET:
6235      PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
6236      break;
6237   case VKI_BLKSSZGET:
6238      PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
6239      break;
6240   case VKI_BLKBSZGET:
6241      PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
6242      break;
6243   case VKI_BLKBSZSET:
6244      PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
6245      break;
6246   case VKI_BLKGETSIZE64:
6247      PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
6248      break;
6249   case VKI_BLKPBSZGET:
6250      PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
6251      break;
6252   case VKI_BLKDISCARDZEROES:
6253      PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
6254      break;
6255
6256      /* Hard disks */
6257   case VKI_HDIO_GETGEO: /* 0x0301 */
6258      PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
6259      break;
6260   case VKI_HDIO_GET_DMA: /* 0x030b */
6261      PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
6262      break;
6263   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
6264      PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
6265                     VKI_SIZEOF_STRUCT_HD_DRIVEID );
6266      break;
6267
6268      /* SCSI */
6269   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
6270      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
6271      break;
6272   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
6273      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
6274      break;
6275
6276      /* CD ROM stuff (??)  */
6277   case VKI_CDROM_GET_MCN:
6278      PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
6279                    sizeof(struct vki_cdrom_mcn) );
6280      break;
6281   case VKI_CDROM_SEND_PACKET:
6282      PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
6283                    sizeof(struct vki_cdrom_generic_command));
6284      break;
6285   case VKI_CDROMSUBCHNL:
6286      PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
6287		    (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
6288		    sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
6289      PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
6290		     sizeof(struct vki_cdrom_subchnl));
6291      break;
6292   case VKI_CDROMREADMODE2:
6293      PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
6294      break;
6295   case VKI_CDROMREADTOCHDR:
6296      PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
6297		     sizeof(struct vki_cdrom_tochdr));
6298      break;
6299   case VKI_CDROMREADTOCENTRY:
6300      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
6301		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
6302		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
6303      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
6304		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
6305		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
6306      PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
6307		     sizeof(struct vki_cdrom_tocentry));
6308      break;
6309   case VKI_CDROMMULTISESSION: /* 0x5310 */
6310      PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
6311		     sizeof(struct vki_cdrom_multisession));
6312      break;
6313   case VKI_CDROMVOLREAD: /* 0x5313 */
6314      PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
6315		     sizeof(struct vki_cdrom_volctrl));
6316      break;
6317   case VKI_CDROMREADRAW: /* 0x5314 */
6318      PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
6319      PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
6320      break;
6321   case VKI_CDROMREADAUDIO: /* 0x530e */
6322      PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
6323		     sizeof (struct vki_cdrom_read_audio));
6324      if ( ARG3 ) {
6325         /* ToDo: don't do any of the following if the structure is invalid */
6326         struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
6327	 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
6328	                (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
6329      }
6330      break;
6331   case VKI_CDROMPLAYMSF:
6332      PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
6333      break;
6334      /* The following two are probably bogus (should check args
6335	 for readability).  JRS 20021117 */
6336   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
6337   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
6338      break;
6339   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
6340      break;
6341
6342   case VKI_FIGETBSZ:
6343      PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
6344      break;
6345   case VKI_FIBMAP:
6346      PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
6347      break;
6348
6349   case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
6350      PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
6351                     sizeof(struct vki_fb_var_screeninfo));
6352      break;
6353   case VKI_FBIOPUT_VSCREENINFO:
6354      PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
6355                    sizeof(struct vki_fb_var_screeninfo));
6356      break;
6357   case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
6358      PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
6359                     sizeof(struct vki_fb_fix_screeninfo));
6360      break;
6361   case VKI_FBIOPAN_DISPLAY:
6362      PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
6363                    sizeof(struct vki_fb_var_screeninfo));
6364
6365      break;
6366   case VKI_PPCLAIM:
6367   case VKI_PPEXCL:
6368   case VKI_PPYIELD:
6369   case VKI_PPRELEASE:
6370      break;
6371   case VKI_PPSETMODE:
6372      PRE_MEM_READ( "ioctl(PPSETMODE)",   ARG3, sizeof(int) );
6373      break;
6374   case VKI_PPGETMODE:
6375      PRE_MEM_WRITE( "ioctl(PPGETMODE)",  ARG3, sizeof(int) );
6376      break;
6377   case VKI_PPSETPHASE:
6378      PRE_MEM_READ(  "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
6379      break;
6380   case VKI_PPGETPHASE:
6381      PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
6382      break;
6383   case VKI_PPGETMODES:
6384      PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
6385      break;
6386   case VKI_PPSETFLAGS:
6387      PRE_MEM_READ(  "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
6388      break;
6389   case VKI_PPGETFLAGS:
6390      PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
6391      break;
6392   case VKI_PPRSTATUS:
6393      PRE_MEM_WRITE( "ioctl(PPRSTATUS)",  ARG3, sizeof(unsigned char) );
6394      break;
6395   case VKI_PPRDATA:
6396      PRE_MEM_WRITE( "ioctl(PPRDATA)",    ARG3, sizeof(unsigned char) );
6397      break;
6398   case VKI_PPRCONTROL:
6399      PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
6400      break;
6401   case VKI_PPWDATA:
6402      PRE_MEM_READ(  "ioctl(PPWDATA)",    ARG3, sizeof(unsigned char) );
6403      break;
6404   case VKI_PPWCONTROL:
6405      PRE_MEM_READ(  "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
6406      break;
6407   case VKI_PPFCONTROL:
6408      PRE_MEM_READ(  "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
6409      break;
6410   case VKI_PPDATADIR:
6411      PRE_MEM_READ(  "ioctl(PPDATADIR)",  ARG3, sizeof(int) );
6412      break;
6413   case VKI_PPNEGOT:
6414      PRE_MEM_READ(  "ioctl(PPNEGOT)",    ARG3, sizeof(int) );
6415      break;
6416   case VKI_PPWCTLONIRQ:
6417      PRE_MEM_READ(  "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
6418      break;
6419   case VKI_PPCLRIRQ:
6420      PRE_MEM_WRITE( "ioctl(PPCLRIRQ)",   ARG3, sizeof(int) );
6421      break;
6422   case VKI_PPSETTIME:
6423      PRE_MEM_READ(  "ioctl(PPSETTIME)",  ARG3, sizeof(struct vki_timeval) );
6424      break;
6425   case VKI_PPGETTIME:
6426      PRE_MEM_WRITE( "ioctl(PPGETTIME)",  ARG3, sizeof(struct vki_timeval) );
6427      break;
6428
6429   case VKI_GIO_FONT:
6430      PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
6431      break;
6432   case VKI_PIO_FONT:
6433      PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
6434      break;
6435
6436   case VKI_GIO_FONTX:
6437      PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
6438      if ( ARG3 ) {
6439         /* ToDo: don't do any of the following if the structure is invalid */
6440         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
6441         PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
6442                        32 * cfd->charcount );
6443      }
6444      break;
6445   case VKI_PIO_FONTX:
6446      PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
6447      if ( ARG3 ) {
6448         /* ToDo: don't do any of the following if the structure is invalid */
6449         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
6450         PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
6451                       32 * cfd->charcount );
6452      }
6453      break;
6454
6455   case VKI_PIO_FONTRESET:
6456      break;
6457
6458   case VKI_GIO_CMAP:
6459      PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
6460      break;
6461   case VKI_PIO_CMAP:
6462      PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
6463      break;
6464
6465   case VKI_KIOCSOUND:
6466   case VKI_KDMKTONE:
6467      break;
6468
6469   case VKI_KDGETLED:
6470      PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
6471      break;
6472   case VKI_KDSETLED:
6473      break;
6474
6475   case VKI_KDGKBTYPE:
6476      PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
6477      break;
6478
6479   case VKI_KDADDIO:
6480   case VKI_KDDELIO:
6481   case VKI_KDENABIO:
6482   case VKI_KDDISABIO:
6483      break;
6484
6485   case VKI_KDSETMODE:
6486      break;
6487   case VKI_KDGETMODE:
6488      PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
6489      break;
6490
6491   case VKI_KDMAPDISP:
6492   case VKI_KDUNMAPDISP:
6493      break;
6494
6495   case VKI_GIO_SCRNMAP:
6496      PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
6497      break;
6498   case VKI_PIO_SCRNMAP:
6499      PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ  );
6500      break;
6501   case VKI_GIO_UNISCRNMAP:
6502      PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
6503                     VKI_E_TABSZ * sizeof(unsigned short) );
6504      break;
6505   case VKI_PIO_UNISCRNMAP:
6506      PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
6507                    VKI_E_TABSZ * sizeof(unsigned short) );
6508      break;
6509
6510   case VKI_GIO_UNIMAP:
6511      if ( ARG3 ) {
6512         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
6513         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
6514                       sizeof(unsigned short));
6515         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
6516                       sizeof(struct vki_unipair *));
6517         PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
6518                        desc->entry_ct * sizeof(struct vki_unipair));
6519      }
6520      break;
6521   case VKI_PIO_UNIMAP:
6522      if ( ARG3 ) {
6523         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
6524         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
6525                       sizeof(unsigned short) );
6526         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
6527                       sizeof(struct vki_unipair *) );
6528         PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
6529                       desc->entry_ct * sizeof(struct vki_unipair) );
6530      }
6531      break;
6532   case VKI_PIO_UNIMAPCLR:
6533      PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
6534      break;
6535
6536   case VKI_KDGKBMODE:
6537      PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
6538      break;
6539   case VKI_KDSKBMODE:
6540      break;
6541
6542   case VKI_KDGKBMETA:
6543      PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
6544      break;
6545   case VKI_KDSKBMETA:
6546      break;
6547
6548   case VKI_KDGKBLED:
6549      PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
6550      break;
6551   case VKI_KDSKBLED:
6552      break;
6553
6554   case VKI_KDGKBENT:
6555      PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
6556                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
6557                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
6558      PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
6559                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
6560                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
6561      PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
6562		     (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
6563		     sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
6564      break;
6565   case VKI_KDSKBENT:
6566      PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
6567                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
6568                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
6569      PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
6570                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
6571                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
6572      PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
6573                    (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
6574                    sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
6575      break;
6576
6577   case VKI_KDGKBSENT:
6578      PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
6579                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
6580                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
6581      PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
6582		     (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
6583		     sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
6584      break;
6585   case VKI_KDSKBSENT:
6586      PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
6587                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
6588                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
6589      PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
6590                       (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
6591      break;
6592
6593   case VKI_KDGKBDIACR:
6594      PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
6595      break;
6596   case VKI_KDSKBDIACR:
6597      PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
6598      break;
6599
6600   case VKI_KDGETKEYCODE:
6601      PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
6602                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
6603                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
6604      PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
6605		     (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
6606		     sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
6607      break;
6608   case VKI_KDSETKEYCODE:
6609      PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
6610                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
6611                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
6612      PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
6613                    (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
6614                    sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
6615      break;
6616
6617   case VKI_KDSIGACCEPT:
6618      break;
6619
6620   case VKI_KDKBDREP:
6621      PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
6622      break;
6623
6624   case VKI_KDFONTOP:
6625      if ( ARG3 ) {
6626         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
6627         PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
6628                       sizeof(struct vki_console_font_op) );
6629         switch ( op->op ) {
6630            case VKI_KD_FONT_OP_SET:
6631               PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
6632                             (Addr)op->data,
6633                             (op->width + 7) / 8 * 32 * op->charcount );
6634               break;
6635            case VKI_KD_FONT_OP_GET:
6636               if ( op->data )
6637                  PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
6638                                 (Addr)op->data,
6639                                 (op->width + 7) / 8 * 32 * op->charcount );
6640               break;
6641            case VKI_KD_FONT_OP_SET_DEFAULT:
6642               if ( op->data )
6643                  PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
6644                                   (Addr)op->data );
6645               break;
6646            case VKI_KD_FONT_OP_COPY:
6647               break;
6648         }
6649      }
6650      break;
6651
6652   case VKI_VT_OPENQRY:
6653      PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
6654      break;
6655   case VKI_VT_GETMODE:
6656      PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
6657      break;
6658   case VKI_VT_SETMODE:
6659      PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
6660      break;
6661   case VKI_VT_GETSTATE:
6662      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
6663                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
6664                     sizeof(((struct vki_vt_stat*) ARG3)->v_active));
6665      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
6666                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
6667                     sizeof(((struct vki_vt_stat*) ARG3)->v_state));
6668      break;
6669   case VKI_VT_RELDISP:
6670   case VKI_VT_ACTIVATE:
6671   case VKI_VT_WAITACTIVE:
6672   case VKI_VT_DISALLOCATE:
6673      break;
6674   case VKI_VT_RESIZE:
6675      PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
6676      break;
6677   case VKI_VT_RESIZEX:
6678      PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
6679      break;
6680   case VKI_VT_LOCKSWITCH:
6681   case VKI_VT_UNLOCKSWITCH:
6682      break;
6683
6684   case VKI_USBDEVFS_CONTROL:
6685      if ( ARG3 ) {
6686         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
6687         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
6688         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
6689         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
6690         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
6691         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
6692         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
6693         if (vkuc->bRequestType & 0x80)
6694            PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
6695         else
6696            PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
6697      }
6698      break;
6699   case VKI_USBDEVFS_BULK:
6700      if ( ARG3 ) {
6701         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
6702         PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
6703         if (vkub->ep & 0x80)
6704            PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
6705         else
6706            PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
6707      }
6708      break;
6709   case VKI_USBDEVFS_GETDRIVER:
6710      if ( ARG3 ) {
6711         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
6712         PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
6713      }
6714      break;
6715   case VKI_USBDEVFS_SUBMITURB:
6716      if ( ARG3 ) {
6717         struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
6718
6719         /* Not the whole struct needs to be initialized */
6720         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
6721         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
6722         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
6723         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
6724         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
6725         PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
6726         if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
6727            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
6728            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
6729            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
6730            if (vkusp->bRequestType & 0x80)
6731               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
6732            else
6733               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
6734            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
6735         } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
6736            int total_length = 0;
6737            int i;
6738            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
6739            for(i=0; i<vkuu->number_of_packets; i++) {
6740               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
6741               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));
6742               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
6743               total_length += vkuu->iso_frame_desc[i].length;
6744            }
6745            if (vkuu->endpoint & 0x80)
6746               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
6747            else
6748               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
6749            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
6750         } else {
6751            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
6752            if (vkuu->endpoint & 0x80)
6753               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
6754            else
6755               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
6756            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
6757         }
6758      }
6759      break;
6760   case VKI_USBDEVFS_DISCARDURB:
6761      break;
6762   case VKI_USBDEVFS_REAPURB:
6763      if ( ARG3 ) {
6764         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
6765      }
6766      break;
6767   case VKI_USBDEVFS_REAPURBNDELAY:
6768      if ( ARG3 ) {
6769         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
6770      }
6771      break;
6772   case VKI_USBDEVFS_CONNECTINFO:
6773      PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
6774      break;
6775   case VKI_USBDEVFS_IOCTL:
6776      if ( ARG3 ) {
6777         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
6778         UInt dir2, size2;
6779         PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
6780         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
6781         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
6782         if (size2 > 0) {
6783            if (dir2 & _VKI_IOC_WRITE)
6784               PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
6785            else if (dir2 & _VKI_IOC_READ)
6786               PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
6787         }
6788      }
6789      break;
6790   case VKI_USBDEVFS_RESET:
6791      break;
6792
6793      /* I2C (/dev/i2c-*) ioctls */
6794   case VKI_I2C_SLAVE:
6795   case VKI_I2C_SLAVE_FORCE:
6796   case VKI_I2C_TENBIT:
6797   case VKI_I2C_PEC:
6798      break;
6799   case VKI_I2C_FUNCS:
6800      PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
6801      break;
6802   case VKI_I2C_RDWR:
6803      if ( ARG3 ) {
6804          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
6805          UInt i;
6806          PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
6807          for (i=0; i < vkui->nmsgs; i++) {
6808              struct vki_i2c_msg *msg = vkui->msgs + i;
6809              PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
6810              if (msg->flags & VKI_I2C_M_RD)
6811                  PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
6812              else
6813                  PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
6814          }
6815      }
6816      break;
6817   case VKI_I2C_SMBUS:
6818       if ( ARG3 ) {
6819            struct vki_i2c_smbus_ioctl_data *vkis
6820               = (struct vki_i2c_smbus_ioctl_data *) ARG3;
6821            PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
6822                         (Addr)&vkis->read_write, sizeof(vkis->read_write));
6823            PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
6824                         (Addr)&vkis->size, sizeof(vkis->size));
6825            PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
6826                         (Addr)&vkis->command, sizeof(vkis->command));
6827            /* i2c_smbus_write_quick hides its value in read_write, so
6828               this variable can hava a different meaning */
6829            /* to make matters worse i2c_smbus_write_byte stores its
6830               value in command */
6831            if ( ! (((vkis->size == VKI_I2C_SMBUS_QUICK)
6832                     && (vkis->command == VKI_I2C_SMBUS_QUICK)) ||
6833                 ((vkis->size == VKI_I2C_SMBUS_BYTE)
6834                  && (vkis->read_write == VKI_I2C_SMBUS_WRITE))))  {
6835                    /* the rest uses the byte array to store the data,
6836                       some the first byte for size */
6837                    UInt size;
6838                    switch(vkis->size) {
6839                        case VKI_I2C_SMBUS_BYTE_DATA:
6840                            size = 1;
6841                            break;
6842                        case VKI_I2C_SMBUS_WORD_DATA:
6843                        case VKI_I2C_SMBUS_PROC_CALL:
6844                            size = 2;
6845                            break;
6846                        case VKI_I2C_SMBUS_BLOCK_DATA:
6847                        case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
6848                        case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
6849                        case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
6850                            size = vkis->data->block[0];
6851                            break;
6852                        default:
6853                            size = 0;
6854                    }
6855
6856                    if ((vkis->read_write == VKI_I2C_SMBUS_READ)
6857                        || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
6858                        || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
6859                        PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
6860                                      ".i2c_smbus_ioctl_data.data",
6861                                      (Addr)&vkis->data->block[0], size);
6862                    else
6863                        PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
6864                                     "i2c_smbus_ioctl_data.data",
6865                                     (Addr)&vkis->data->block[0], size);
6866            }
6867       }
6868       break;
6869
6870      /* Wireless extensions ioctls */
6871   case VKI_SIOCSIWCOMMIT:
6872   case VKI_SIOCSIWNWID:
6873   case VKI_SIOCSIWFREQ:
6874   case VKI_SIOCSIWMODE:
6875   case VKI_SIOCSIWSENS:
6876   case VKI_SIOCSIWRANGE:
6877   case VKI_SIOCSIWPRIV:
6878   case VKI_SIOCSIWSTATS:
6879   case VKI_SIOCSIWSPY:
6880   case VKI_SIOCSIWTHRSPY:
6881   case VKI_SIOCSIWAP:
6882   case VKI_SIOCSIWSCAN:
6883   case VKI_SIOCSIWESSID:
6884   case VKI_SIOCSIWRATE:
6885   case VKI_SIOCSIWNICKN:
6886   case VKI_SIOCSIWRTS:
6887   case VKI_SIOCSIWFRAG:
6888   case VKI_SIOCSIWTXPOW:
6889   case VKI_SIOCSIWRETRY:
6890   case VKI_SIOCSIWENCODE:
6891   case VKI_SIOCSIWPOWER:
6892   case VKI_SIOCSIWGENIE:
6893   case VKI_SIOCSIWMLME:
6894   case VKI_SIOCSIWAUTH:
6895   case VKI_SIOCSIWENCODEEXT:
6896   case VKI_SIOCSIWPMKSA:
6897      break;
6898   case VKI_SIOCGIWNAME:
6899      if (ARG3) {
6900         PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
6901                       (Addr)((struct vki_iwreq *)ARG3)->u.name,
6902                       sizeof(((struct vki_iwreq *)ARG3)->u.name));
6903      }
6904      break;
6905   case VKI_SIOCGIWNWID:
6906   case VKI_SIOCGIWSENS:
6907   case VKI_SIOCGIWRATE:
6908   case VKI_SIOCGIWRTS:
6909   case VKI_SIOCGIWFRAG:
6910   case VKI_SIOCGIWTXPOW:
6911   case VKI_SIOCGIWRETRY:
6912   case VKI_SIOCGIWPOWER:
6913   case VKI_SIOCGIWAUTH:
6914      if (ARG3) {
6915         PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
6916                       "RETRY|PARAM|AUTH])",
6917                       (Addr)&((struct vki_iwreq *)ARG3)->u.nwid,
6918                       sizeof(struct vki_iw_param));
6919      }
6920      break;
6921   case VKI_SIOCGIWFREQ:
6922      if (ARG3) {
6923         PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
6924                       (Addr)&((struct vki_iwreq *)ARG3)->u.freq,
6925                       sizeof(struct vki_iw_freq));
6926      }
6927      break;
6928   case VKI_SIOCGIWMODE:
6929      if (ARG3) {
6930         PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
6931                       (Addr)&((struct vki_iwreq *)ARG3)->u.mode,
6932                       sizeof(__vki_u32));
6933      }
6934      break;
6935   case VKI_SIOCGIWRANGE:
6936   case VKI_SIOCGIWPRIV:
6937   case VKI_SIOCGIWSTATS:
6938   case VKI_SIOCGIWSPY:
6939   case VKI_SIOCGIWTHRSPY:
6940   case VKI_SIOCGIWAPLIST:
6941   case VKI_SIOCGIWSCAN:
6942   case VKI_SIOCGIWESSID:
6943   case VKI_SIOCGIWNICKN:
6944   case VKI_SIOCGIWENCODE:
6945   case VKI_SIOCGIWGENIE:
6946   case VKI_SIOCGIWENCODEEXT:
6947      if (ARG3) {
6948         struct vki_iw_point* point;
6949         point = &((struct vki_iwreq *)ARG3)->u.data;
6950         PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
6951                       "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
6952                       (Addr)point->pointer, point->length);
6953      }
6954      break;
6955   case VKI_SIOCGIWAP:
6956      if (ARG3) {
6957         PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
6958                       (Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
6959                       sizeof(struct vki_sockaddr));
6960      }
6961      break;
6962
6963  /* User input device creation */
6964  case VKI_UI_SET_EVBIT:
6965  case VKI_UI_SET_KEYBIT:
6966  case VKI_UI_SET_RELBIT:
6967  case VKI_UI_SET_ABSBIT:
6968  case VKI_UI_SET_MSCBIT:
6969  case VKI_UI_SET_LEDBIT:
6970  case VKI_UI_SET_SNDBIT:
6971  case VKI_UI_SET_FFBIT:
6972  case VKI_UI_SET_SWBIT:
6973  case VKI_UI_SET_PROPBIT:
6974      /* These just take an int by value */
6975      break;
6976
6977#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
6978      || defined(VGPV_mips32_linux_android)
6979   /* ashmem */
6980   case VKI_ASHMEM_GET_SIZE:
6981   case VKI_ASHMEM_SET_SIZE:
6982   case VKI_ASHMEM_GET_PROT_MASK:
6983   case VKI_ASHMEM_SET_PROT_MASK:
6984   case VKI_ASHMEM_GET_PIN_STATUS:
6985   case VKI_ASHMEM_PURGE_ALL_CACHES:
6986       break;
6987   case VKI_ASHMEM_GET_NAME:
6988       PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
6989       break;
6990   case VKI_ASHMEM_SET_NAME:
6991       PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
6992       break;
6993   case VKI_ASHMEM_PIN:
6994   case VKI_ASHMEM_UNPIN:
6995       PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
6996                     ARG3, sizeof(struct vki_ashmem_pin) );
6997       break;
6998
6999   /* binder */
7000   case VKI_BINDER_WRITE_READ:
7001       if (ARG3) {
7002           struct vki_binder_write_read* bwr
7003              = (struct vki_binder_write_read*)ARG3;
7004
7005           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
7006                          bwr->write_buffer);
7007           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
7008                          bwr->write_size);
7009           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
7010                          bwr->write_consumed);
7011           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
7012                          bwr->read_buffer);
7013           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
7014                          bwr->read_size);
7015           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
7016                          bwr->read_consumed);
7017
7018           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
7019                           bwr->write_consumed);
7020           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
7021                           bwr->read_consumed);
7022
7023           if (bwr->read_size)
7024               PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
7025                             (Addr)bwr->read_buffer, bwr->read_size);
7026           if (bwr->write_size)
7027               PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
7028                            (Addr)bwr->write_buffer, bwr->write_size);
7029       }
7030       break;
7031
7032   case VKI_BINDER_SET_IDLE_TIMEOUT:
7033   case VKI_BINDER_SET_MAX_THREADS:
7034   case VKI_BINDER_SET_IDLE_PRIORITY:
7035   case VKI_BINDER_SET_CONTEXT_MGR:
7036   case VKI_BINDER_THREAD_EXIT:
7037       break;
7038   case VKI_BINDER_VERSION:
7039       if (ARG3) {
7040           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
7041           PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
7042       }
7043       break;
7044#  endif /* defined(VGPV_*_linux_android) */
7045
7046   case VKI_HCIGETDEVLIST:
7047      if (ARG3) {
7048         struct vki_hci_dev_list_req* dlr = (struct vki_hci_dev_list_req*)ARG3;
7049         PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
7050                      (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
7051         PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
7052                       (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
7053                       dlr->dev_num * sizeof(struct vki_hci_dev_req));
7054      }
7055      break;
7056
7057   case VKI_HCIINQUIRY:
7058      if (ARG3) {
7059         struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
7060         PRE_MEM_READ("ioctl(HCIINQUIRY)",
7061                      (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
7062         PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
7063                       (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7064                       ir->num_rsp * sizeof(struct vki_inquiry_info));
7065      }
7066      break;
7067
7068   case VKI_DRM_IOCTL_VERSION:
7069      if (ARG3) {
7070         struct vki_drm_version *data = (struct vki_drm_version *)ARG3;
7071	 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
7072         PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
7073         PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
7074         PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
7075         PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
7076         PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
7077         PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
7078         PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
7079         PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
7080         PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
7081         PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
7082         PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
7083      }
7084      break;
7085   case VKI_DRM_IOCTL_GET_UNIQUE:
7086      if (ARG3) {
7087         struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
7088	 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
7089	 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
7090	 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
7091      }
7092      break;
7093   case VKI_DRM_IOCTL_GET_MAGIC:
7094      if (ARG3) {
7095         struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
7096         PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
7097      }
7098      break;
7099   case VKI_DRM_IOCTL_WAIT_VBLANK:
7100      if (ARG3) {
7101         union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
7102	 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
7103	 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
7104	 /* XXX: It seems request.signal isn't used */
7105         PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
7106      }
7107      break;
7108   case VKI_DRM_IOCTL_GEM_CLOSE:
7109      if (ARG3) {
7110         struct vki_drm_gem_close *data = (struct vki_drm_gem_close *)ARG3;
7111	 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
7112      }
7113      break;
7114   case VKI_DRM_IOCTL_GEM_FLINK:
7115      if (ARG3) {
7116         struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
7117	 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
7118         PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
7119      }
7120      break;
7121   case VKI_DRM_IOCTL_GEM_OPEN:
7122      if (ARG3) {
7123         struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
7124	 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
7125	 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
7126	 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
7127      }
7128      break;
7129   case VKI_DRM_IOCTL_I915_GETPARAM:
7130      if (ARG3) {
7131         vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
7132	 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
7133	 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
7134      }
7135      break;
7136   case VKI_DRM_IOCTL_I915_GEM_BUSY:
7137      if (ARG3) {
7138         struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
7139	 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
7140         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
7141      }
7142      break;
7143   case VKI_DRM_IOCTL_I915_GEM_CREATE:
7144      if (ARG3) {
7145         struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
7146	 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
7147	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
7148      }
7149      break;
7150   case VKI_DRM_IOCTL_I915_GEM_PREAD:
7151      if (ARG3) {
7152         struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
7153	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
7154	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
7155	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
7156	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
7157	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
7158      }
7159      break;
7160   case VKI_DRM_IOCTL_I915_GEM_PWRITE:
7161      if (ARG3) {
7162         struct vki_drm_i915_gem_pwrite *data = (struct vki_drm_i915_gem_pwrite *)ARG3;
7163	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
7164	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
7165	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
7166	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
7167	 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
7168	  * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
7169	  * interleaved vertex attributes may have a wide stride with uninitialized data between
7170	  * consecutive vertices) */
7171      }
7172      break;
7173   case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
7174      if (ARG3) {
7175         struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
7176	 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
7177         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
7178      }
7179      break;
7180   case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
7181      if (ARG3) {
7182         struct vki_drm_i915_gem_set_domain *data = (struct vki_drm_i915_gem_set_domain *)ARG3;
7183	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
7184	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
7185	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
7186      }
7187      break;
7188   case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
7189      if (ARG3) {
7190         struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
7191	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
7192         PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
7193         PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
7194         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
7195      }
7196      break;
7197   case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
7198      if (ARG3) {
7199         struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
7200	 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
7201	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
7202         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
7203      }
7204      break;
7205   case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
7206      if (ARG3) {
7207         struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
7208         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
7209         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
7210      }
7211      break;
7212
7213   /* KVM ioctls that check for a numeric value as parameter */
7214   case VKI_KVM_GET_API_VERSION:
7215   case VKI_KVM_CREATE_VM:
7216   case VKI_KVM_GET_VCPU_MMAP_SIZE:
7217   case VKI_KVM_CHECK_EXTENSION:
7218   case VKI_KVM_SET_TSS_ADDR:
7219   case VKI_KVM_CREATE_VCPU:
7220   case VKI_KVM_RUN:
7221      break;
7222
7223#ifdef ENABLE_XEN
7224   case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
7225      SyscallArgs harrghs;
7226      struct vki_xen_privcmd_hypercall *args =
7227         (struct vki_xen_privcmd_hypercall *)(ARG3);
7228
7229      if (!args)
7230         break;
7231
7232      VG_(memset)(&harrghs, 0, sizeof(harrghs));
7233      harrghs.sysno = args->op;
7234      harrghs.arg1 = args->arg[0];
7235      harrghs.arg2 = args->arg[1];
7236      harrghs.arg3 = args->arg[2];
7237      harrghs.arg4 = args->arg[3];
7238      harrghs.arg5 = args->arg[4];
7239      harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
7240
7241      WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
7242
7243      /* HACK. arg8 is used to return the number of hypercall
7244       * arguments actually consumed! */
7245      PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
7246                   ( sizeof(args->arg[0]) * harrghs.arg8 ) );
7247
7248      break;
7249   }
7250
7251   case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
7252       struct vki_xen_privcmd_mmap *args =
7253           (struct vki_xen_privcmd_mmap *)(ARG3);
7254       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
7255                    (Addr)&args->num, sizeof(args->num));
7256       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
7257                    (Addr)&args->dom, sizeof(args->dom));
7258       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
7259                    (Addr)args->entry, sizeof(*(args->entry)) * args->num);
7260      break;
7261   }
7262   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
7263       struct vki_xen_privcmd_mmapbatch *args =
7264           (struct vki_xen_privcmd_mmapbatch *)(ARG3);
7265       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
7266                    (Addr)&args->num, sizeof(args->num));
7267       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
7268                    (Addr)&args->dom, sizeof(args->dom));
7269       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
7270                    (Addr)&args->addr, sizeof(args->addr));
7271       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
7272                    (Addr)args->arr, sizeof(*(args->arr)) * args->num);
7273      break;
7274   }
7275   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
7276       struct vki_xen_privcmd_mmapbatch_v2 *args =
7277           (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
7278       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
7279                    (Addr)&args->num, sizeof(args->num));
7280       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
7281                    (Addr)&args->dom, sizeof(args->dom));
7282       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
7283                    (Addr)&args->addr, sizeof(args->addr));
7284       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
7285                    (Addr)args->arr, sizeof(*(args->arr)) * args->num);
7286      break;
7287   }
7288
7289   case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
7290         struct vki_xen_ioctl_evtchn_bind_virq *args =
7291            (struct vki_xen_ioctl_evtchn_bind_virq *)(ARG3);
7292         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
7293                 (Addr)&args->virq, sizeof(args->virq));
7294      }
7295      break;
7296   case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
7297         struct vki_xen_ioctl_evtchn_bind_interdomain *args =
7298            (struct vki_xen_ioctl_evtchn_bind_interdomain *)(ARG3);
7299         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
7300                 (Addr)&args->remote_domain, sizeof(args->remote_domain));
7301         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
7302                 (Addr)&args->remote_port, sizeof(args->remote_port));
7303      }
7304      break;
7305   case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
7306         struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
7307            (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(ARG3);
7308         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
7309                 (Addr)&args->remote_domain, sizeof(args->remote_domain));
7310      }
7311      break;
7312   case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
7313         struct vki_xen_ioctl_evtchn_unbind *args =
7314            (struct vki_xen_ioctl_evtchn_unbind *)(ARG3);
7315         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
7316                 (Addr)&args->port, sizeof(args->port));
7317      }
7318      break;
7319   case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
7320         struct vki_xen_ioctl_evtchn_notify *args =
7321            (struct vki_xen_ioctl_evtchn_notify*)(ARG3);
7322         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
7323                 (Addr)&args->port, sizeof(args->port));
7324      }
7325      break;
7326   case VKI_XEN_IOCTL_EVTCHN_RESET:
7327      /* No input*/
7328      break;
7329#endif
7330
7331   /* Lustre */
7332   case VKI_OBD_IOC_FID2PATH: {
7333      struct vki_getinfo_fid2path *gf = (struct vki_getinfo_fid2path *)ARG3;
7334      PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
7335      PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
7336      PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
7337      PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
7338      break;
7339   }
7340
7341   case VKI_LL_IOC_PATH2FID:
7342      PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
7343      break;
7344
7345   case VKI_LL_IOC_GETPARENT: {
7346      struct vki_getparent *gp = (struct vki_getparent *)ARG3;
7347      PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
7348      PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
7349      PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
7350      PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
7351      break;
7352   }
7353
7354   /* V4L2 */
7355   case VKI_V4L2_QUERYCAP: {
7356      struct vki_v4l2_capability *data = (struct vki_v4l2_capability *)ARG3;
7357      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
7358      break;
7359   }
7360   case VKI_V4L2_ENUM_FMT: {
7361      struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)ARG3;
7362      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
7363      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
7364      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
7365      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
7366      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
7367      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
7368      break;
7369   }
7370   case VKI_V4L2_G_FMT: {
7371      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
7372      PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
7373      switch (data->type) {
7374      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
7375      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
7376         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
7377         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
7378         PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
7379               (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
7380               sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
7381         break;
7382      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
7383      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
7384         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
7385         break;
7386      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
7387      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
7388         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
7389         break;
7390      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
7391      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
7392         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
7393         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
7394         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
7395         if (data->fmt.win.clipcount && data->fmt.win.clips)
7396            PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
7397                  (Addr)data->fmt.win.clips,
7398                  data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
7399         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
7400         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
7401         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
7402         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
7403         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
7404         break;
7405      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
7406      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
7407         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
7408         break;
7409      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
7410         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
7411         break;
7412      }
7413      break;
7414   }
7415   case VKI_V4L2_S_FMT: {
7416      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
7417      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
7418      switch (data->type) {
7419      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
7420      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
7421         PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
7422               (Addr)&data->type + sizeof(data->type),
7423               sizeof(*data) - sizeof(data->type));
7424         break;
7425      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
7426      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
7427         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
7428         break;
7429      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
7430      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
7431         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
7432         break;
7433      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
7434      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
7435         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
7436         if (data->fmt.win.clipcount && data->fmt.win.clips)
7437            PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
7438                  (Addr)data->fmt.win.clips,
7439                  data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
7440         if (data->fmt.win.bitmap)
7441            PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
7442                  (Addr)data->fmt.win.bitmap,
7443                  data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
7444         break;
7445      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
7446      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
7447         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
7448         break;
7449      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
7450         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
7451         break;
7452      }
7453      break;
7454   }
7455   case VKI_V4L2_TRY_FMT: {
7456      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
7457      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
7458      switch (data->type) {
7459      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
7460      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
7461         PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
7462               (Addr)&data->type + sizeof(data->type),
7463               sizeof(*data) - sizeof(data->type));
7464         break;
7465      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
7466      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
7467         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
7468         break;
7469      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
7470      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
7471         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
7472         break;
7473      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
7474      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
7475         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
7476         if (data->fmt.win.clipcount && data->fmt.win.clips)
7477            PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
7478                  (Addr)data->fmt.win.clips,
7479                  data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
7480         if (data->fmt.win.bitmap)
7481            PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
7482                  (Addr)data->fmt.win.bitmap,
7483                  data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
7484         break;
7485      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
7486      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
7487         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
7488         break;
7489      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
7490         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
7491         break;
7492      }
7493      break;
7494   }
7495   case VKI_V4L2_REQBUFS: {
7496      struct vki_v4l2_requestbuffers *data = (struct vki_v4l2_requestbuffers *)ARG3;
7497      PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
7498      break;
7499   }
7500   case VKI_V4L2_QUERYBUF: {
7501      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
7502      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
7503      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
7504      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
7505      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
7506      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
7507            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
7508         unsigned i;
7509
7510         PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
7511         PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
7512         for (i = 0; i < data->length; i++) {
7513            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
7514            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
7515            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
7516            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
7517            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
7518         }
7519      } else {
7520         PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
7521         PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
7522      }
7523      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
7524      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
7525      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
7526      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
7527      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
7528      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
7529      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
7530      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
7531      break;
7532   }
7533   case VKI_V4L2_G_FBUF: {
7534      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
7535      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
7536      break;
7537   }
7538   case VKI_V4L2_S_FBUF: {
7539      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
7540      PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
7541      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
7542      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
7543      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
7544      break;
7545   }
7546   case VKI_V4L2_OVERLAY: {
7547      int *data = (int *)ARG3;
7548      PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
7549      break;
7550   }
7551   case VKI_V4L2_QBUF: {
7552      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
7553      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
7554         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
7555         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
7556         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
7557
7558      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
7559      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
7560      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
7561      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
7562      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
7563      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
7564      if (is_output) {
7565         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
7566         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
7567      }
7568      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
7569            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
7570         unsigned i;
7571
7572         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
7573         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
7574         for (i = 0; i < data->length; i++) {
7575            if (is_output) {
7576               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
7577               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
7578            }
7579            if (data->memory == VKI_V4L2_MEMORY_MMAP)
7580               PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
7581            else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
7582               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
7583            else
7584               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
7585            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
7586         }
7587      } else {
7588         if (data->memory == VKI_V4L2_MEMORY_MMAP)
7589            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
7590         else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
7591            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
7592         else
7593            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
7594         if (is_output) {
7595            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
7596            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
7597         }
7598      }
7599      if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
7600         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
7601         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
7602      }
7603      break;
7604   }
7605   case VKI_V4L2_EXPBUF: {
7606      struct vki_v4l2_exportbuffer *data = (struct vki_v4l2_exportbuffer *)ARG3;
7607      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
7608      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
7609      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
7610      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
7611      PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
7612      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
7613      break;
7614   }
7615   case VKI_V4L2_DQBUF: {
7616      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
7617      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
7618      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
7619      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
7620      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
7621      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
7622      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
7623      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
7624      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
7625            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
7626         unsigned i;
7627
7628         PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
7629         PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
7630         for (i = 0; i < data->length; i++) {
7631            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
7632            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
7633            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
7634            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
7635            PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
7636         }
7637      } else {
7638         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
7639         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
7640         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
7641         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
7642      }
7643      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
7644      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
7645      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
7646      break;
7647   }
7648   case VKI_V4L2_STREAMON: {
7649      int *data = (int *)ARG3;
7650      PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
7651      break;
7652   }
7653   case VKI_V4L2_STREAMOFF: {
7654      int *data = (int *)ARG3;
7655      PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
7656      break;
7657   }
7658   case VKI_V4L2_G_PARM: {
7659      struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
7660      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
7661         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
7662         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
7663         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
7664
7665      PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
7666      if (is_output) {
7667         PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
7668            sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
7669         PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
7670      } else {
7671         PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
7672            sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
7673         PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
7674      }
7675      break;
7676   }
7677   case VKI_V4L2_S_PARM: {
7678      struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
7679      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
7680         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
7681         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
7682         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
7683
7684      PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
7685      if (is_output)
7686         PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
7687      else
7688         PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
7689      break;
7690   }
7691   case VKI_V4L2_G_STD: {
7692      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
7693      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
7694      break;
7695   }
7696   case VKI_V4L2_S_STD: {
7697      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
7698      PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
7699      break;
7700   }
7701   case VKI_V4L2_ENUMSTD: {
7702      struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)ARG3;
7703      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
7704      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
7705      break;
7706   }
7707   case VKI_V4L2_ENUMINPUT: {
7708      struct vki_v4l2_input *data = (struct vki_v4l2_input *)ARG3;
7709      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
7710      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
7711      break;
7712   }
7713   case VKI_V4L2_G_CTRL: {
7714      struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
7715      PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
7716      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
7717      break;
7718   }
7719   case VKI_V4L2_S_CTRL: {
7720      struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
7721      PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
7722      break;
7723   }
7724   case VKI_V4L2_G_TUNER: {
7725      struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
7726      PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
7727      PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
7728      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
7729            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
7730      break;
7731   }
7732   case VKI_V4L2_S_TUNER: {
7733      struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
7734      PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
7735      PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
7736      PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
7737      break;
7738   }
7739   case VKI_V4L2_G_AUDIO: {
7740      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
7741      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
7742            sizeof(*data) - sizeof(data->reserved));
7743      PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
7744      break;
7745   }
7746   case VKI_V4L2_S_AUDIO: {
7747      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
7748      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
7749      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
7750      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
7751      break;
7752   }
7753   case VKI_V4L2_QUERYCTRL: {
7754      struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)ARG3;
7755      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
7756      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
7757            sizeof(*data) - sizeof(data->id));
7758      break;
7759   }
7760   case VKI_V4L2_QUERYMENU: {
7761      struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)ARG3;
7762      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
7763      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
7764      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
7765            sizeof(*data) - sizeof(data->id) - sizeof(data->index));
7766      break;
7767   }
7768   case VKI_V4L2_G_INPUT: {
7769      int *data = (int *)ARG3;
7770      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
7771      break;
7772   }
7773   case VKI_V4L2_S_INPUT: {
7774      int *data = (int *)ARG3;
7775      PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
7776      break;
7777   }
7778   case VKI_V4L2_G_EDID: {
7779      struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
7780      PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
7781      if (data->blocks && data->edid)
7782         PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
7783      break;
7784   }
7785   case VKI_V4L2_S_EDID: {
7786      struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
7787      PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
7788      if (data->blocks && data->edid)
7789         PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
7790      break;
7791   }
7792   case VKI_V4L2_G_OUTPUT: {
7793      int *data = (int *)ARG3;
7794      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
7795      break;
7796   }
7797   case VKI_V4L2_S_OUTPUT: {
7798      int *data = (int *)ARG3;
7799      PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
7800      break;
7801   }
7802   case VKI_V4L2_ENUMOUTPUT: {
7803      struct vki_v4l2_output *data = (struct vki_v4l2_output *)ARG3;
7804      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
7805      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
7806      break;
7807   }
7808   case VKI_V4L2_G_AUDOUT: {
7809      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
7810      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
7811            sizeof(*data) - sizeof(data->reserved));
7812      PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
7813      break;
7814   }
7815   case VKI_V4L2_S_AUDOUT: {
7816      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
7817      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
7818      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
7819      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
7820      break;
7821   }
7822   case VKI_V4L2_G_MODULATOR: {
7823      struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
7824      PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
7825      PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
7826      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
7827            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
7828      break;
7829   }
7830   case VKI_V4L2_S_MODULATOR: {
7831      struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
7832      PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
7833      PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
7834      PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
7835      break;
7836   }
7837   case VKI_V4L2_G_FREQUENCY: {
7838      struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
7839      PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
7840      PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
7841      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
7842      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
7843      break;
7844   }
7845   case VKI_V4L2_S_FREQUENCY: {
7846      struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
7847      PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
7848      break;
7849   }
7850   case VKI_V4L2_CROPCAP: {
7851      struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)ARG3;
7852      PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
7853      PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
7854      break;
7855   }
7856   case VKI_V4L2_G_CROP: {
7857      struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
7858      PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
7859      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
7860      break;
7861   }
7862   case VKI_V4L2_S_CROP: {
7863      struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
7864      PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
7865      break;
7866   }
7867   case VKI_V4L2_G_JPEGCOMP: {
7868      struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
7869      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
7870      break;
7871   }
7872   case VKI_V4L2_S_JPEGCOMP: {
7873      struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
7874      PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
7875      break;
7876   }
7877   case VKI_V4L2_QUERYSTD: {
7878      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
7879      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
7880      break;
7881   }
7882   case VKI_V4L2_ENUMAUDIO: {
7883      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
7884      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
7885      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
7886      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
7887            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
7888      break;
7889   }
7890   case VKI_V4L2_ENUMAUDOUT: {
7891      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
7892      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
7893      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
7894      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
7895            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
7896      break;
7897   }
7898   case VKI_V4L2_G_PRIORITY: {
7899      __vki_u32 *data = (__vki_u32 *)ARG3;
7900      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
7901      break;
7902   }
7903   case VKI_V4L2_S_PRIORITY: {
7904      __vki_u32 *data = (__vki_u32 *)ARG3;
7905      PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
7906      break;
7907   }
7908   case VKI_V4L2_G_SLICED_VBI_CAP: {
7909      struct vki_v4l2_sliced_vbi_cap *data = (struct vki_v4l2_sliced_vbi_cap *)ARG3;
7910      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
7911      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
7912      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
7913            sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
7914      break;
7915   }
7916   case VKI_V4L2_G_EXT_CTRLS: {
7917      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
7918      PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
7919      PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
7920      if (data->count) {
7921         unsigned i;
7922
7923         PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
7924         for (i = 0; i < data->count; i++) {
7925            PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
7926            PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
7927            PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
7928            if (data->controls[i].size) {
7929               PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
7930               PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
7931                     (Addr)data->controls[i].ptr, data->controls[i].size);
7932            } else {
7933               PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
7934                     data->controls[i].value64);
7935            }
7936         }
7937      }
7938      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
7939      PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
7940      break;
7941   }
7942   case VKI_V4L2_S_EXT_CTRLS: {
7943      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
7944      PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
7945      PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
7946      if (data->count) {
7947         unsigned i;
7948
7949         PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
7950         PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
7951               data->count * sizeof(data->controls[0]));
7952         for (i = 0; i < data->count; i++) {
7953            if (data->controls[i].size) {
7954               PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
7955                     (Addr)data->controls[i].ptr, data->controls[i].size);
7956            }
7957         }
7958      }
7959      PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
7960      PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
7961      break;
7962   }
7963   case VKI_V4L2_TRY_EXT_CTRLS: {
7964      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
7965      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
7966      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
7967      if (data->count) {
7968         unsigned i;
7969
7970         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
7971         PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
7972               data->count * sizeof(data->controls[0]));
7973         for (i = 0; i < data->count; i++) {
7974            if (data->controls[i].size) {
7975               PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
7976                     (Addr)data->controls[i].ptr, data->controls[i].size);
7977            }
7978         }
7979      }
7980      PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
7981      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
7982      break;
7983   }
7984   case VKI_V4L2_ENUM_FRAMESIZES: {
7985      struct vki_v4l2_frmsizeenum *data = (struct vki_v4l2_frmsizeenum *)ARG3;
7986      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
7987      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
7988      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
7989      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
7990      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
7991      break;
7992   }
7993   case VKI_V4L2_ENUM_FRAMEINTERVALS: {
7994      struct vki_v4l2_frmivalenum *data = (struct vki_v4l2_frmivalenum *)ARG3;
7995      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
7996      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
7997      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
7998      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
7999      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
8000      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
8001      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
8002      break;
8003   }
8004   case VKI_V4L2_G_ENC_INDEX: {
8005      struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)ARG3;
8006      PRE_MEM_READ("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
8007      break;
8008   }
8009   case VKI_V4L2_ENCODER_CMD: {
8010      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
8011      PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
8012      break;
8013   }
8014   case VKI_V4L2_TRY_ENCODER_CMD: {
8015      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
8016      PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
8017      break;
8018   }
8019   case VKI_V4L2_DBG_S_REGISTER: {
8020      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
8021      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
8022      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
8023      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
8024      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
8025      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
8026      break;
8027   }
8028   case VKI_V4L2_DBG_G_REGISTER: {
8029      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
8030      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
8031      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
8032      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
8033      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
8034      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
8035      break;
8036   }
8037   case VKI_V4L2_S_HW_FREQ_SEEK: {
8038      struct vki_v4l2_hw_freq_seek *data = (struct vki_v4l2_hw_freq_seek *)ARG3;
8039      PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
8040      break;
8041   }
8042   case VKI_V4L2_S_DV_TIMINGS: {
8043      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8044      PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
8045      PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
8046      break;
8047   }
8048   case VKI_V4L2_G_DV_TIMINGS: {
8049      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8050      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
8051      break;
8052   }
8053   case VKI_V4L2_DQEVENT: {
8054      struct vki_v4l2_event *data = (struct vki_v4l2_event *)ARG3;
8055      PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
8056      break;
8057   }
8058   case VKI_V4L2_SUBSCRIBE_EVENT: {
8059      struct vki_v4l2_event_subscription *data = (struct vki_v4l2_event_subscription *)ARG3;
8060      PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8061      break;
8062   }
8063   case VKI_V4L2_UNSUBSCRIBE_EVENT: {
8064      struct vki_v4l2_event_subscription *data = (struct vki_v4l2_event_subscription *)ARG3;
8065      PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8066      break;
8067   }
8068   case VKI_V4L2_CREATE_BUFS: {
8069      struct vki_v4l2_create_buffers *data = (struct vki_v4l2_create_buffers *)ARG3;
8070      struct vki_v4l2_format *fmt = &data->format;
8071      PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
8072      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
8073      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
8074      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
8075      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
8076      switch (fmt->type) {
8077      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8078      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8079         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
8080         break;
8081      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8082      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8083         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
8084         break;
8085      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8086      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8087         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
8088         break;
8089      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8090      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8091         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
8092         break;
8093      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8094      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8095         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
8096         break;
8097      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8098         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
8099         break;
8100      }
8101      break;
8102   }
8103   case VKI_V4L2_PREPARE_BUF: {
8104      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8105      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
8106      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
8107      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
8108      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
8109      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
8110      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8111            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8112         unsigned i;
8113
8114         PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
8115         PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
8116         for (i = 0; i < data->length; i++) {
8117            PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
8118         }
8119      }
8120      break;
8121   }
8122   case VKI_V4L2_G_SELECTION: {
8123      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
8124      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
8125      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
8126      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
8127      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
8128      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
8129      break;
8130   }
8131   case VKI_V4L2_S_SELECTION: {
8132      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
8133      PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
8134      break;
8135   }
8136   case VKI_V4L2_DECODER_CMD: {
8137      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
8138      PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
8139      break;
8140   }
8141   case VKI_V4L2_TRY_DECODER_CMD: {
8142      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
8143      PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
8144      break;
8145   }
8146   case VKI_V4L2_ENUM_DV_TIMINGS: {
8147      struct vki_v4l2_enum_dv_timings *data = (struct vki_v4l2_enum_dv_timings *)ARG3;
8148      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
8149      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
8150      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
8151      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
8152      break;
8153   }
8154   case VKI_V4L2_QUERY_DV_TIMINGS: {
8155      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8156      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
8157      break;
8158   }
8159   case VKI_V4L2_DV_TIMINGS_CAP: {
8160      struct vki_v4l2_dv_timings_cap *data = (struct vki_v4l2_dv_timings_cap *)ARG3;
8161      PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
8162      break;
8163   }
8164   case VKI_V4L2_ENUM_FREQ_BANDS: {
8165      struct vki_v4l2_frequency_band *data = (struct vki_v4l2_frequency_band *)ARG3;
8166      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
8167      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
8168      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
8169      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
8170      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
8171      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
8172      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
8173      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
8174      break;
8175   }
8176   case VKI_V4L2_DBG_G_CHIP_INFO: {
8177      struct vki_v4l2_dbg_chip_info *data = (struct vki_v4l2_dbg_chip_info *)ARG3;
8178      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
8179      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
8180      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
8181      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
8182      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
8183      break;
8184   }
8185   case VKI_V4L2_QUERY_EXT_CTRL: {
8186      struct vki_v4l2_query_ext_ctrl *data = (struct vki_v4l2_query_ext_ctrl *)ARG3;
8187      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
8188      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
8189      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
8190            sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
8191      break;
8192   }
8193   case VKI_V4L2_SUBDEV_G_FMT: {
8194      struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
8195      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
8196      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
8197      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
8198      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
8199      break;
8200   }
8201   case VKI_V4L2_SUBDEV_S_FMT: {
8202      struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
8203      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
8204      break;
8205   }
8206   case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
8207      struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
8208      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
8209      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
8210      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
8211      break;
8212   }
8213   case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
8214      struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
8215      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
8216      break;
8217   }
8218   case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
8219      struct vki_v4l2_subdev_mbus_code_enum *data = (struct vki_v4l2_subdev_mbus_code_enum *)ARG3;
8220      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
8221      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
8222      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
8223      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
8224      break;
8225   }
8226   case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
8227      struct vki_v4l2_subdev_frame_size_enum *data = (struct vki_v4l2_subdev_frame_size_enum *)ARG3;
8228      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
8229      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
8230      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
8231      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
8232      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
8233      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
8234      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
8235      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
8236      break;
8237   }
8238   case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
8239      struct vki_v4l2_subdev_frame_interval_enum *data = (struct vki_v4l2_subdev_frame_interval_enum *)ARG3;
8240      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
8241      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
8242      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
8243      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
8244      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
8245      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
8246      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
8247      break;
8248   }
8249   case VKI_V4L2_SUBDEV_G_CROP: {
8250      struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
8251      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
8252      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
8253      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
8254      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
8255      break;
8256   }
8257   case VKI_V4L2_SUBDEV_S_CROP: {
8258      struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
8259      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
8260      break;
8261   }
8262   case VKI_V4L2_SUBDEV_G_SELECTION: {
8263      struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
8264      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
8265      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
8266      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
8267      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
8268      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
8269      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
8270      break;
8271   }
8272   case VKI_V4L2_SUBDEV_S_SELECTION: {
8273      struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
8274      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
8275      break;
8276   }
8277   case VKI_MEDIA_IOC_DEVICE_INFO: {
8278      struct vki_media_device_info *data = (struct vki_media_device_info *)ARG3;
8279      PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
8280      PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
8281            (Addr)data, sizeof(*data) - sizeof(data->reserved));
8282      break;
8283   }
8284   case VKI_MEDIA_IOC_ENUM_ENTITIES: {
8285      struct vki_media_entity_desc *data = (struct vki_media_entity_desc *)ARG3;
8286      PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
8287      PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
8288            (Addr)data->name, sizeof(*data) - sizeof(data->id));
8289      break;
8290   }
8291   case VKI_MEDIA_IOC_ENUM_LINKS: {
8292      struct vki_media_links_enum *data = (struct vki_media_links_enum *)ARG3;
8293      PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
8294      break;
8295   }
8296   case VKI_MEDIA_IOC_SETUP_LINK: {
8297      struct vki_media_link_desc *data = (struct vki_media_link_desc *)ARG3;
8298      PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
8299      break;
8300   }
8301
8302   default:
8303      /* EVIOC* are variable length and return size written on success */
8304      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
8305      case VKI_EVIOCGNAME(0):
8306      case VKI_EVIOCGPHYS(0):
8307      case VKI_EVIOCGUNIQ(0):
8308      case VKI_EVIOCGKEY(0):
8309      case VKI_EVIOCGLED(0):
8310      case VKI_EVIOCGSND(0):
8311      case VKI_EVIOCGSW(0):
8312      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
8313      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
8314      case VKI_EVIOCGBIT(VKI_EV_REL,0):
8315      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
8316      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
8317      case VKI_EVIOCGBIT(VKI_EV_SW,0):
8318      case VKI_EVIOCGBIT(VKI_EV_LED,0):
8319      case VKI_EVIOCGBIT(VKI_EV_SND,0):
8320      case VKI_EVIOCGBIT(VKI_EV_REP,0):
8321      case VKI_EVIOCGBIT(VKI_EV_FF,0):
8322      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
8323      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
8324         PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
8325         break;
8326      default:
8327         ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
8328         break;
8329      }
8330      break;
8331   }
8332}
8333
8334POST(sys_ioctl)
8335{
8336   vg_assert(SUCCESS);
8337
8338   ARG2 = (UInt)ARG2;
8339
8340   /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
8341
8342   /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
8343   if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
8344                       VG_(clo_kernel_variant))) {
8345
8346      if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
8347         /* What's going on here: there appear to be a bunch of ioctls
8348            of the form 0xC01C67xx which are undocumented, and if
8349            unhandled give rise to a vast number of false positives in
8350            Memcheck.
8351
8352            The "normal" interpretation of an ioctl of this form would
8353            be that the 3rd arg is a pointer to an area of size 0x1C
8354            (28 bytes) which is filled in by the kernel.  Hence you
8355            might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
8356            But it doesn't.
8357
8358            It requires POST_MEM_WRITE(ARG3, 256) to silence them.
8359            One interpretation of this is that ARG3 really does point
8360            to a 28 byte struct, but inside that are pointers to other
8361            areas also filled in by the kernel.  If these happen to be
8362            allocated just back up the stack then the 256 byte paint
8363            might cover them too, somewhat indiscriminately.
8364
8365            By printing out ARG3 and also the 28 bytes that it points
8366            at, it's possible to guess that the 7 word structure has
8367            this form
8368
8369              0            1    2    3        4    5        6
8370              ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
8371
8372            Unfortunately that doesn't seem to work for some reason,
8373            so stay with the blunt-instrument approach for the time
8374            being.
8375         */
8376         if (1) {
8377            /* blunt-instrument approach */
8378            POST_MEM_WRITE(ARG3, 256);
8379         } else {
8380            /* be a bit more sophisticated */
8381            POST_MEM_WRITE(ARG3, 28);
8382            UInt* word = (UInt*)ARG3;
8383            if (word && word[2] && word[3] < 0x200/*stay sane*/)
8384               POST_MEM_WRITE(word[2], word[3]); // "ptr1"
8385            if (word && word[4] && word[5] < 0x200/*stay sane*/)
8386               POST_MEM_WRITE(word[4], word[5]); // "ptr2"
8387         }
8388         goto post_sys_ioctl__out;
8389      }
8390   }
8391   /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
8392
8393   /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
8394   if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
8395                       VG_(clo_kernel_variant))) {
8396     if (ARG2 == 0xC00C0902) {
8397         POST_MEM_WRITE(ARG3, 24); // 16 is not enough
8398         goto post_sys_ioctl__out;
8399     }
8400   }
8401   /* END undocumented ioctls for Qualcomm Adreno 3xx */
8402
8403   /* --- END special IOCTL handlers for specific Android hardware --- */
8404
8405   /* --- normal handling --- */
8406   switch (ARG2 /* request */) {
8407
8408   /* The Linux kernel "ion" memory allocator, used on Android.  Note:
8409      this is pretty poor given that there's no pre-handling to check
8410      that writable areas are addressable. */
8411   case VKI_ION_IOC_ALLOC: {
8412      struct vki_ion_allocation_data* data
8413         = (struct vki_ion_allocation_data*)ARG3;
8414      POST_FIELD_WRITE(data->handle);
8415      break;
8416   }
8417   case VKI_ION_IOC_MAP: {
8418      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
8419      POST_FIELD_WRITE(data->fd);
8420      break;
8421   }
8422   case VKI_ION_IOC_FREE: // is this necessary?
8423      POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
8424      break;
8425   case VKI_ION_IOC_SHARE:
8426      break;
8427   case VKI_ION_IOC_IMPORT: {
8428      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
8429      POST_FIELD_WRITE(data->handle);
8430      break;
8431   }
8432   case VKI_ION_IOC_SYNC:
8433      break;
8434   case VKI_ION_IOC_CUSTOM: // is this necessary?
8435      POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
8436      break;
8437
8438   case VKI_SYNC_IOC_MERGE: {
8439      struct vki_sync_merge_data* data = (struct vki_sync_merge_data*)ARG3;
8440      POST_FIELD_WRITE(data->fence);
8441      break;
8442   }
8443
8444   case VKI_TCSETS:
8445   case VKI_TCSETSW:
8446   case VKI_TCSETSF:
8447   case VKI_IB_USER_MAD_ENABLE_PKEY:
8448      break;
8449   case VKI_TCGETS:
8450      POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
8451      break;
8452   case VKI_TCSETA:
8453   case VKI_TCSETAW:
8454   case VKI_TCSETAF:
8455      break;
8456   case VKI_TCGETA:
8457      POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
8458      break;
8459   case VKI_TCSBRK:
8460   case VKI_TCXONC:
8461   case VKI_TCSBRKP:
8462   case VKI_TCFLSH:
8463   case VKI_TIOCSIG:
8464      break;
8465   case VKI_TIOCGWINSZ:
8466      POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
8467      break;
8468   case VKI_TIOCSWINSZ:
8469   case VKI_TIOCMBIS:
8470   case VKI_TIOCMBIC:
8471   case VKI_TIOCMSET:
8472      break;
8473   case VKI_TIOCMGET:
8474      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
8475      break;
8476   case VKI_TIOCLINUX:
8477      POST_MEM_WRITE( ARG3, sizeof(char *) );
8478      break;
8479   case VKI_TIOCGPGRP:
8480      /* Get process group ID for foreground processing group. */
8481      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
8482      break;
8483   case VKI_TIOCSPGRP:
8484      /* Set a process group ID? */
8485      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
8486      break;
8487   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
8488      POST_MEM_WRITE( ARG3, sizeof(int));
8489      break;
8490   case VKI_TIOCSCTTY:
8491      break;
8492   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
8493      break;
8494   case VKI_FIONBIO:
8495      break;
8496   case VKI_FIONCLEX:
8497      break;
8498   case VKI_FIOCLEX:
8499      break;
8500   case VKI_TIOCNOTTY:
8501      break;
8502   case VKI_FIOASYNC:
8503      break;
8504   case VKI_FIONREAD:                /* identical to SIOCINQ */
8505      POST_MEM_WRITE( ARG3, sizeof(int) );
8506      break;
8507   case VKI_FIOQSIZE:
8508      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
8509      break;
8510
8511   case VKI_TIOCSERGETLSR:
8512      POST_MEM_WRITE( ARG3, sizeof(int) );
8513      break;
8514   case VKI_TIOCGICOUNT:
8515      POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
8516      break;
8517
8518   case VKI_SG_SET_COMMAND_Q:
8519      break;
8520   case VKI_SG_IO:
8521      {
8522         vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)ARG3;
8523         if ( sgio->sbp ) {
8524            POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
8525         }
8526         if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
8527              sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
8528            int transferred = sgio->dxfer_len - sgio->resid;
8529            POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
8530         }
8531      }
8532      break;
8533   case VKI_SG_GET_SCSI_ID:
8534      POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
8535      break;
8536   case VKI_SG_SET_RESERVED_SIZE:
8537      break;
8538   case VKI_SG_SET_TIMEOUT:
8539      break;
8540   case VKI_SG_GET_RESERVED_SIZE:
8541      POST_MEM_WRITE(ARG3, sizeof(int));
8542      break;
8543   case VKI_SG_GET_TIMEOUT:
8544      break;
8545   case VKI_SG_GET_VERSION_NUM:
8546      POST_MEM_WRITE(ARG3, sizeof(int));
8547      break;
8548   case VKI_SG_EMULATED_HOST:
8549      POST_MEM_WRITE(ARG3, sizeof(int));
8550      break;
8551   case VKI_SG_GET_SG_TABLESIZE:
8552      POST_MEM_WRITE(ARG3, sizeof(int));
8553      break;
8554
8555   case VKI_IIOCGETCPS:
8556      POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
8557      break;
8558   case VKI_IIOCNETGPN:
8559      POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
8560      break;
8561
8562      /* These all use struct ifreq AFAIK */
8563   case VKI_SIOCGIFINDEX:        /* get iface index              */
8564      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
8565                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
8566      break;
8567   case VKI_SIOCGIFFLAGS:        /* get flags                    */
8568      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
8569                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
8570      break;
8571   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
8572      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
8573                      sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
8574      break;
8575   case VKI_SIOCGIFMTU:          /* get MTU size                 */
8576      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
8577                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
8578      break;
8579   case VKI_SIOCGIFADDR:         /* get PA address               */
8580   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
8581   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
8582   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
8583      POST_MEM_WRITE(
8584                (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
8585                sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
8586      break;
8587   case VKI_SIOCGIFMETRIC:       /* get metric                   */
8588      POST_MEM_WRITE(
8589                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
8590                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
8591      break;
8592   case VKI_SIOCGIFMAP:          /* Get device parameters        */
8593      POST_MEM_WRITE(
8594                (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
8595                sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
8596      break;
8597     break;
8598   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
8599      POST_MEM_WRITE(
8600                (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
8601                sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
8602      break;
8603   case VKI_SIOCGIFNAME:         /* get iface name               */
8604      POST_MEM_WRITE(
8605                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
8606                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
8607      break;
8608   case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
8609      struct vki_ifreq *ir = (struct vki_ifreq *)ARG3;
8610      switch ( *(vki_u32 *)ir->vki_ifr_data ) {
8611      case VKI_ETHTOOL_GSET:
8612         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
8613         break;
8614      case VKI_ETHTOOL_SSET:
8615         break;
8616      case VKI_ETHTOOL_GDRVINFO:
8617         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
8618         break;
8619      case VKI_ETHTOOL_GREGS:
8620         POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
8621                         ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
8622         break;
8623      case VKI_ETHTOOL_GWOL:
8624         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
8625         break;
8626      case VKI_ETHTOOL_SWOL:
8627         break;
8628      case VKI_ETHTOOL_GMSGLVL:
8629      case VKI_ETHTOOL_GLINK:
8630      case VKI_ETHTOOL_GRXCSUM:
8631      case VKI_ETHTOOL_GSG:
8632      case VKI_ETHTOOL_GTSO:
8633      case VKI_ETHTOOL_GUFO:
8634      case VKI_ETHTOOL_GGSO:
8635      case VKI_ETHTOOL_GFLAGS:
8636      case VKI_ETHTOOL_GGRO:
8637         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
8638         break;
8639      case VKI_ETHTOOL_SMSGLVL:
8640      case VKI_ETHTOOL_SRXCSUM:
8641      case VKI_ETHTOOL_SSG:
8642      case VKI_ETHTOOL_STSO:
8643      case VKI_ETHTOOL_SUFO:
8644      case VKI_ETHTOOL_SGSO:
8645      case VKI_ETHTOOL_SFLAGS:
8646      case VKI_ETHTOOL_SGRO:
8647         break;
8648      case VKI_ETHTOOL_NWAY_RST:
8649         break;
8650      case VKI_ETHTOOL_GRINGPARAM:
8651         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
8652         break;
8653      case VKI_ETHTOOL_SRINGPARAM:
8654         break;
8655      case VKI_ETHTOOL_TEST:
8656         POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
8657                         ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
8658         break;
8659      case VKI_ETHTOOL_PHYS_ID:
8660         break;
8661      case VKI_ETHTOOL_GPERMADDR:
8662         POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
8663                         ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
8664         break;
8665      case VKI_ETHTOOL_RESET:
8666         break;
8667      case VKI_ETHTOOL_GSSET_INFO:
8668         POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
8669                        __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
8670         break;
8671      case VKI_ETHTOOL_GFEATURES:
8672         POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
8673                         ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
8674         break;
8675      case VKI_ETHTOOL_SFEATURES:
8676         break;
8677      case VKI_ETHTOOL_GCHANNELS:
8678         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
8679         break;
8680      case VKI_ETHTOOL_SCHANNELS:
8681         break;
8682      case VKI_ETHTOOL_GET_TS_INFO:
8683         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
8684         break;
8685      }
8686      break;
8687   }
8688   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
8689      POST_MEM_WRITE(
8690                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
8691                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
8692      break;
8693   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
8694      POST_MEM_WRITE(
8695                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
8696                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
8697      break;
8698
8699      /* tun/tap related ioctls */
8700   case VKI_TUNSETIFF:
8701      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
8702                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
8703      break;
8704   case VKI_TUNGETFEATURES:
8705      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
8706      break;
8707   case VKI_TUNGETIFF:
8708      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
8709                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
8710      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
8711                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
8712      break;
8713   case VKI_TUNGETSNDBUF:
8714      POST_MEM_WRITE( ARG3, sizeof(int) );
8715      break;
8716   case VKI_TUNGETVNETHDRSZ:
8717      POST_MEM_WRITE( ARG3, sizeof(int) );
8718      break;
8719
8720   case VKI_SIOCGIFCONF:         /* get iface list               */
8721      /* WAS:
8722	 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
8723	 KERNEL_DO_SYSCALL(tid,RES);
8724	 if (!VG_(is_kerror)(RES) && RES == 0)
8725	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
8726      */
8727      if (RES == 0 && ARG3 ) {
8728	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
8729	 if (ifc->vki_ifc_buf != NULL)
8730	    POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
8731      }
8732      break;
8733   case VKI_SIOCGSTAMP:
8734      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
8735      break;
8736   case VKI_SIOCGSTAMPNS:
8737      POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
8738      break;
8739      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
8740	 the number of bytes currently in that socket's send buffer.
8741	 It writes this value as an int to the memory location
8742	 indicated by the third argument of ioctl(2). */
8743   case VKI_SIOCOUTQ:
8744      POST_MEM_WRITE(ARG3, sizeof(int));
8745      break;
8746   case VKI_SIOCGRARP:           /* get RARP table entry         */
8747   case VKI_SIOCGARP:            /* get ARP table entry          */
8748      POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
8749      break;
8750
8751   case VKI_SIOCSIFFLAGS:        /* set flags                    */
8752   case VKI_SIOCSIFMAP:          /* Set device parameters        */
8753   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
8754   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
8755   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
8756   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
8757   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
8758   case VKI_SIOCSIFMETRIC:       /* set metric                   */
8759   case VKI_SIOCSIFADDR:         /* set PA address               */
8760   case VKI_SIOCSIFMTU:          /* set MTU size                 */
8761   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
8762   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
8763      break;
8764      /* Routing table calls.  */
8765   case VKI_SIOCADDRT:           /* add routing table entry      */
8766   case VKI_SIOCDELRT:           /* delete routing table entry   */
8767      break;
8768
8769      /* RARP cache control calls. */
8770   case VKI_SIOCDRARP:           /* delete RARP table entry      */
8771   case VKI_SIOCSRARP:           /* set RARP table entry         */
8772      /* ARP cache control calls. */
8773   case VKI_SIOCSARP:            /* set ARP table entry          */
8774   case VKI_SIOCDARP:            /* delete ARP table entry       */
8775      break;
8776
8777   case VKI_SIOCGPGRP:
8778      POST_MEM_WRITE(ARG3, sizeof(int));
8779      break;
8780   case VKI_SIOCSPGRP:
8781      break;
8782
8783   case VKI_SIOCATMARK:
8784      POST_MEM_WRITE(ARG3, sizeof(int));
8785      break;
8786
8787      /* linux/soundcard interface (OSS) */
8788   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
8789   case VKI_SNDCTL_SEQ_GETINCOUNT:
8790   case VKI_SNDCTL_SEQ_PERCMODE:
8791   case VKI_SNDCTL_SEQ_TESTMIDI:
8792   case VKI_SNDCTL_SEQ_RESETSAMPLES:
8793   case VKI_SNDCTL_SEQ_NRSYNTHS:
8794   case VKI_SNDCTL_SEQ_NRMIDIS:
8795   case VKI_SNDCTL_SEQ_GETTIME:
8796   case VKI_SNDCTL_DSP_GETBLKSIZE:
8797   case VKI_SNDCTL_DSP_GETFMTS:
8798   case VKI_SNDCTL_DSP_SETFMT:
8799   case VKI_SNDCTL_DSP_GETTRIGGER:
8800   case VKI_SNDCTL_DSP_GETODELAY:
8801   case VKI_SNDCTL_DSP_GETSPDIF:
8802   case VKI_SNDCTL_DSP_GETCAPS:
8803   case VKI_SOUND_PCM_READ_RATE:
8804   case VKI_SOUND_PCM_READ_CHANNELS:
8805   case VKI_SOUND_PCM_READ_BITS:
8806   case VKI_SOUND_PCM_READ_FILTER:
8807      POST_MEM_WRITE(ARG3, sizeof(int));
8808      break;
8809   case VKI_SNDCTL_SEQ_CTRLRATE:
8810   case VKI_SNDCTL_DSP_SPEED:
8811   case VKI_SNDCTL_DSP_STEREO:
8812   case VKI_SNDCTL_DSP_CHANNELS:
8813   case VKI_SOUND_PCM_WRITE_FILTER:
8814   case VKI_SNDCTL_DSP_SUBDIVIDE:
8815   case VKI_SNDCTL_DSP_SETFRAGMENT:
8816   case VKI_SNDCTL_DSP_GETCHANNELMASK:
8817   case VKI_SNDCTL_DSP_BIND_CHANNEL:
8818   case VKI_SNDCTL_TMR_TIMEBASE:
8819   case VKI_SNDCTL_TMR_TEMPO:
8820   case VKI_SNDCTL_TMR_SOURCE:
8821   case VKI_SNDCTL_MIDI_PRETIME:
8822   case VKI_SNDCTL_MIDI_MPUMODE:
8823      break;
8824   case VKI_SNDCTL_DSP_GETOSPACE:
8825   case VKI_SNDCTL_DSP_GETISPACE:
8826      POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
8827      break;
8828   case VKI_SNDCTL_DSP_NONBLOCK:
8829      break;
8830   case VKI_SNDCTL_DSP_SETTRIGGER:
8831      break;
8832
8833   case VKI_SNDCTL_DSP_POST:
8834   case VKI_SNDCTL_DSP_RESET:
8835   case VKI_SNDCTL_DSP_SYNC:
8836   case VKI_SNDCTL_DSP_SETSYNCRO:
8837   case VKI_SNDCTL_DSP_SETDUPLEX:
8838      break;
8839
8840      /* linux/soundcard interface (ALSA) */
8841   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
8842   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
8843   case VKI_SNDRV_PCM_IOCTL_PREPARE:
8844   case VKI_SNDRV_PCM_IOCTL_RESET:
8845   case VKI_SNDRV_PCM_IOCTL_START:
8846   case VKI_SNDRV_PCM_IOCTL_DROP:
8847   case VKI_SNDRV_PCM_IOCTL_DRAIN:
8848   case VKI_SNDRV_PCM_IOCTL_RESUME:
8849   case VKI_SNDRV_PCM_IOCTL_XRUN:
8850   case VKI_SNDRV_PCM_IOCTL_UNLINK:
8851   case VKI_SNDRV_TIMER_IOCTL_START:
8852   case VKI_SNDRV_TIMER_IOCTL_STOP:
8853   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
8854   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
8855   case VKI_SNDRV_CTL_IOCTL_PVERSION: {
8856      POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
8857      break;
8858   }
8859   case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
8860      POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
8861      break;
8862   case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
8863      struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
8864      POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
8865      POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
8866      if (data->pids) {
8867         POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
8868      }
8869      break;
8870   }
8871   case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
8872      struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
8873      POST_MEM_WRITE( (Addr)data->tlv, data->length );
8874      break;
8875   }
8876   case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
8877   case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
8878      break;
8879
8880      /* SCSI no operand */
8881   case VKI_SCSI_IOCTL_DOORLOCK:
8882   case VKI_SCSI_IOCTL_DOORUNLOCK:
8883      break;
8884
8885      /* Real Time Clock (/dev/rtc) ioctls */
8886   case VKI_RTC_UIE_ON:
8887   case VKI_RTC_UIE_OFF:
8888   case VKI_RTC_AIE_ON:
8889   case VKI_RTC_AIE_OFF:
8890   case VKI_RTC_PIE_ON:
8891   case VKI_RTC_PIE_OFF:
8892   case VKI_RTC_IRQP_SET:
8893      break;
8894   case VKI_RTC_RD_TIME:
8895   case VKI_RTC_ALM_READ:
8896      POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
8897      break;
8898   case VKI_RTC_ALM_SET:
8899      break;
8900   case VKI_RTC_IRQP_READ:
8901      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
8902      break;
8903
8904      /* Block devices */
8905   case VKI_BLKROSET:
8906      break;
8907   case VKI_BLKROGET:
8908      POST_MEM_WRITE(ARG3, sizeof(int));
8909      break;
8910   case VKI_BLKGETSIZE:
8911      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
8912      break;
8913   case VKI_BLKRASET:
8914      break;
8915   case VKI_BLKRAGET:
8916      POST_MEM_WRITE(ARG3, sizeof(long));
8917      break;
8918   case VKI_BLKFRASET:
8919      break;
8920   case VKI_BLKFRAGET:
8921      POST_MEM_WRITE(ARG3, sizeof(long));
8922      break;
8923   case VKI_BLKSECTGET:
8924      POST_MEM_WRITE(ARG3, sizeof(unsigned short));
8925      break;
8926   case VKI_BLKSSZGET:
8927      POST_MEM_WRITE(ARG3, sizeof(int));
8928      break;
8929   case VKI_BLKBSZGET:
8930      POST_MEM_WRITE(ARG3, sizeof(int));
8931      break;
8932   case VKI_BLKBSZSET:
8933      break;
8934   case VKI_BLKGETSIZE64:
8935      POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
8936      break;
8937   case VKI_BLKPBSZGET:
8938      POST_MEM_WRITE(ARG3, sizeof(int));
8939      break;
8940   case VKI_BLKDISCARDZEROES:
8941      POST_MEM_WRITE(ARG3, sizeof(vki_uint));
8942      break;
8943
8944      /* Hard disks */
8945   case VKI_HDIO_GETGEO: /* 0x0301 */
8946      POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
8947      break;
8948   case VKI_HDIO_GET_DMA: /* 0x030b */
8949      POST_MEM_WRITE(ARG3, sizeof(long));
8950      break;
8951   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
8952      POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
8953      break;
8954
8955      /* SCSI */
8956   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
8957      POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
8958      break;
8959   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
8960      POST_MEM_WRITE(ARG3, sizeof(int));
8961      break;
8962
8963      /* CD ROM stuff (??)  */
8964   case VKI_CDROM_DISC_STATUS:
8965      break;
8966   case VKI_CDROMSUBCHNL:
8967      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
8968      break;
8969   case VKI_CDROMREADTOCHDR:
8970      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
8971      break;
8972   case VKI_CDROMREADTOCENTRY:
8973      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
8974      break;
8975   case VKI_CDROMMULTISESSION:
8976      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
8977      break;
8978   case VKI_CDROMVOLREAD:
8979      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
8980      break;
8981   case VKI_CDROMREADRAW:
8982      POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
8983      break;
8984   case VKI_CDROMREADAUDIO:
8985   {
8986      struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
8987      POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
8988      break;
8989   }
8990
8991   case VKI_CDROMPLAYMSF:
8992      break;
8993      /* The following two are probably bogus (should check args
8994	 for readability).  JRS 20021117 */
8995   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
8996   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
8997      break;
8998   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
8999      break;
9000
9001   case VKI_FIGETBSZ:
9002      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9003      break;
9004   case VKI_FIBMAP:
9005      POST_MEM_WRITE(ARG3, sizeof(int));
9006      break;
9007
9008   case VKI_FBIOGET_VSCREENINFO: //0x4600
9009      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
9010      break;
9011   case VKI_FBIOGET_FSCREENINFO: //0x4602
9012      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
9013      break;
9014
9015   case VKI_PPCLAIM:
9016   case VKI_PPEXCL:
9017   case VKI_PPYIELD:
9018   case VKI_PPRELEASE:
9019   case VKI_PPSETMODE:
9020   case VKI_PPSETPHASE:
9021   case VKI_PPSETFLAGS:
9022   case VKI_PPWDATA:
9023   case VKI_PPWCONTROL:
9024   case VKI_PPFCONTROL:
9025   case VKI_PPDATADIR:
9026   case VKI_PPNEGOT:
9027   case VKI_PPWCTLONIRQ:
9028   case VKI_PPSETTIME:
9029      break;
9030   case VKI_PPGETMODE:
9031      POST_MEM_WRITE( ARG3, sizeof(int) );
9032      break;
9033   case VKI_PPGETPHASE:
9034      POST_MEM_WRITE( ARG3, sizeof(int) );
9035      break;
9036   case VKI_PPGETMODES:
9037      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9038      break;
9039   case VKI_PPGETFLAGS:
9040      POST_MEM_WRITE( ARG3, sizeof(int) );
9041      break;
9042   case VKI_PPRSTATUS:
9043      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9044      break;
9045   case VKI_PPRDATA:
9046      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9047      break;
9048   case VKI_PPRCONTROL:
9049      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9050      break;
9051   case VKI_PPCLRIRQ:
9052      POST_MEM_WRITE( ARG3, sizeof(int) );
9053      break;
9054   case VKI_PPGETTIME:
9055      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9056      break;
9057
9058   case VKI_GIO_FONT:
9059      POST_MEM_WRITE( ARG3, 32 * 256 );
9060      break;
9061   case VKI_PIO_FONT:
9062      break;
9063
9064   case VKI_GIO_FONTX:
9065      POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
9066                      32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
9067      break;
9068   case VKI_PIO_FONTX:
9069      break;
9070
9071   case VKI_PIO_FONTRESET:
9072      break;
9073
9074   case VKI_GIO_CMAP:
9075      POST_MEM_WRITE( ARG3, 16 * 3 );
9076      break;
9077   case VKI_PIO_CMAP:
9078      break;
9079
9080   case VKI_KIOCSOUND:
9081   case VKI_KDMKTONE:
9082      break;
9083
9084   case VKI_KDGETLED:
9085      POST_MEM_WRITE( ARG3, sizeof(char) );
9086      break;
9087   case VKI_KDSETLED:
9088      break;
9089
9090   case VKI_KDGKBTYPE:
9091      POST_MEM_WRITE( ARG3, sizeof(char) );
9092      break;
9093
9094   case VKI_KDADDIO:
9095   case VKI_KDDELIO:
9096   case VKI_KDENABIO:
9097   case VKI_KDDISABIO:
9098      break;
9099
9100   case VKI_KDSETMODE:
9101      break;
9102   case VKI_KDGETMODE:
9103      POST_MEM_WRITE( ARG3, sizeof(int) );
9104      break;
9105
9106   case VKI_KDMAPDISP:
9107   case VKI_KDUNMAPDISP:
9108      break;
9109
9110   case VKI_GIO_SCRNMAP:
9111      POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
9112      break;
9113   case VKI_PIO_SCRNMAP:
9114      break;
9115   case VKI_GIO_UNISCRNMAP:
9116      POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
9117      break;
9118   case VKI_PIO_UNISCRNMAP:
9119      break;
9120
9121   case VKI_GIO_UNIMAP:
9122      if ( ARG3 ) {
9123         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
9124         POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
9125         POST_MEM_WRITE( (Addr)desc->entries,
9126      	                 desc->entry_ct * sizeof(struct vki_unipair) );
9127      }
9128      break;
9129   case VKI_PIO_UNIMAP:
9130      break;
9131   case VKI_PIO_UNIMAPCLR:
9132      break;
9133
9134   case VKI_KDGKBMODE:
9135      POST_MEM_WRITE( ARG3, sizeof(int) );
9136      break;
9137   case VKI_KDSKBMODE:
9138      break;
9139
9140   case VKI_KDGKBMETA:
9141      POST_MEM_WRITE( ARG3, sizeof(int) );
9142      break;
9143   case VKI_KDSKBMETA:
9144      break;
9145
9146   case VKI_KDGKBLED:
9147      POST_MEM_WRITE( ARG3, sizeof(char) );
9148      break;
9149   case VKI_KDSKBLED:
9150      break;
9151
9152   case VKI_KDGKBENT:
9153      POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
9154                      sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
9155      break;
9156   case VKI_KDSKBENT:
9157      break;
9158
9159   case VKI_KDGKBSENT:
9160      POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
9161                      sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
9162      break;
9163   case VKI_KDSKBSENT:
9164      break;
9165
9166   case VKI_KDGKBDIACR:
9167      POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
9168      break;
9169   case VKI_KDSKBDIACR:
9170      break;
9171
9172   case VKI_KDGETKEYCODE:
9173      POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
9174                      sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
9175      break;
9176   case VKI_KDSETKEYCODE:
9177      break;
9178
9179   case VKI_KDSIGACCEPT:
9180      break;
9181
9182   case VKI_KDKBDREP:
9183      break;
9184
9185   case VKI_KDFONTOP:
9186      if ( ARG3 ) {
9187         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
9188         switch ( op->op ) {
9189            case VKI_KD_FONT_OP_SET:
9190               break;
9191            case VKI_KD_FONT_OP_GET:
9192               if ( op->data )
9193                  POST_MEM_WRITE( (Addr) op->data,
9194                                  (op->width + 7) / 8 * 32 * op->charcount );
9195               break;
9196            case VKI_KD_FONT_OP_SET_DEFAULT:
9197               break;
9198            case VKI_KD_FONT_OP_COPY:
9199               break;
9200         }
9201         POST_MEM_WRITE( (Addr) op, sizeof(*op));
9202      }
9203      break;
9204
9205   case VKI_VT_OPENQRY:
9206      POST_MEM_WRITE( ARG3, sizeof(int) );
9207      break;
9208   case VKI_VT_GETMODE:
9209      POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
9210      break;
9211   case VKI_VT_SETMODE:
9212      break;
9213   case VKI_VT_GETSTATE:
9214      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
9215                      sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
9216      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
9217                      sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
9218      break;
9219   case VKI_VT_RELDISP:
9220   case VKI_VT_ACTIVATE:
9221   case VKI_VT_WAITACTIVE:
9222   case VKI_VT_DISALLOCATE:
9223      break;
9224   case VKI_VT_RESIZE:
9225      break;
9226   case VKI_VT_RESIZEX:
9227      break;
9228   case VKI_VT_LOCKSWITCH:
9229   case VKI_VT_UNLOCKSWITCH:
9230      break;
9231
9232   case VKI_USBDEVFS_CONTROL:
9233      if ( ARG3 ) {
9234         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
9235         if (vkuc->bRequestType & 0x80)
9236            POST_MEM_WRITE((Addr)vkuc->data, RES);
9237      }
9238      break;
9239   case VKI_USBDEVFS_BULK:
9240      if ( ARG3 ) {
9241         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
9242         if (vkub->ep & 0x80)
9243            POST_MEM_WRITE((Addr)vkub->data, RES);
9244      }
9245      break;
9246   case VKI_USBDEVFS_GETDRIVER:
9247      if ( ARG3 ) {
9248         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
9249         POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
9250      }
9251      break;
9252   case VKI_USBDEVFS_REAPURB:
9253   case VKI_USBDEVFS_REAPURBNDELAY:
9254      if ( ARG3 ) {
9255         struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
9256         POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
9257         if (!*vkuu)
9258            break;
9259         POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
9260         if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
9261            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
9262            if (vkusp->bRequestType & 0x80)
9263               POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
9264            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
9265         } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
9266            char *bp = (*vkuu)->buffer;
9267            int i;
9268            for(i=0; i<(*vkuu)->number_of_packets; i++) {
9269               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
9270               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
9271               if ((*vkuu)->endpoint & 0x80)
9272                  POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
9273               bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
9274            }
9275            POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
9276         } else {
9277            if ((*vkuu)->endpoint & 0x80)
9278               POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
9279            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
9280         }
9281      }
9282      break;
9283   case VKI_USBDEVFS_CONNECTINFO:
9284      POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
9285      break;
9286   case VKI_USBDEVFS_IOCTL:
9287      if ( ARG3 ) {
9288         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
9289         UInt dir2, size2;
9290         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
9291         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
9292         if (size2 > 0) {
9293            if (dir2 & _VKI_IOC_READ)
9294               POST_MEM_WRITE((Addr)vkui->data, size2);
9295         }
9296      }
9297      break;
9298
9299      /* I2C (/dev/i2c-*) ioctls */
9300   case VKI_I2C_SLAVE:
9301   case VKI_I2C_SLAVE_FORCE:
9302   case VKI_I2C_TENBIT:
9303   case VKI_I2C_PEC:
9304      break;
9305   case VKI_I2C_FUNCS:
9306      POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
9307      break;
9308   case VKI_I2C_RDWR:
9309      if ( ARG3 ) {
9310          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
9311          UInt i;
9312          for (i=0; i < vkui->nmsgs; i++) {
9313              struct vki_i2c_msg *msg = vkui->msgs + i;
9314              if (msg->flags & VKI_I2C_M_RD)
9315                  POST_MEM_WRITE((Addr)msg->buf, msg->len);
9316          }
9317      }
9318      break;
9319   case VKI_I2C_SMBUS:
9320       if ( ARG3 ) {
9321            struct vki_i2c_smbus_ioctl_data *vkis
9322               = (struct vki_i2c_smbus_ioctl_data *) ARG3;
9323            /* i2c_smbus_write_quick hides its value in read_write, so
9324               this variable can hava a different meaning */
9325            /* to make matters worse i2c_smbus_write_byte stores its
9326               value in command */
9327            if ((vkis->read_write == VKI_I2C_SMBUS_READ)
9328                || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
9329                || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
9330                if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK)
9331                        && (vkis->command == VKI_I2C_SMBUS_QUICK))) {
9332                    UInt size;
9333                    switch(vkis->size) {
9334                        case VKI_I2C_SMBUS_BYTE:
9335                        case VKI_I2C_SMBUS_BYTE_DATA:
9336                            size = 1;
9337                            break;
9338                        case VKI_I2C_SMBUS_WORD_DATA:
9339                        case VKI_I2C_SMBUS_PROC_CALL:
9340                            size = 2;
9341                            break;
9342                        case VKI_I2C_SMBUS_BLOCK_DATA:
9343                        case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
9344                        case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
9345                        case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
9346                            size = vkis->data->block[0];
9347                            break;
9348                        default:
9349                            size = 0;
9350                    }
9351                    POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
9352                }
9353            }
9354       }
9355       break;
9356
9357      /* Wireless extensions ioctls */
9358   case VKI_SIOCSIWCOMMIT:
9359   case VKI_SIOCSIWNWID:
9360   case VKI_SIOCSIWFREQ:
9361   case VKI_SIOCSIWMODE:
9362   case VKI_SIOCSIWSENS:
9363   case VKI_SIOCSIWRANGE:
9364   case VKI_SIOCSIWPRIV:
9365   case VKI_SIOCSIWSTATS:
9366   case VKI_SIOCSIWSPY:
9367   case VKI_SIOCSIWTHRSPY:
9368   case VKI_SIOCSIWAP:
9369   case VKI_SIOCSIWSCAN:
9370   case VKI_SIOCSIWESSID:
9371   case VKI_SIOCSIWRATE:
9372   case VKI_SIOCSIWNICKN:
9373   case VKI_SIOCSIWRTS:
9374   case VKI_SIOCSIWFRAG:
9375   case VKI_SIOCSIWTXPOW:
9376   case VKI_SIOCSIWRETRY:
9377   case VKI_SIOCSIWENCODE:
9378   case VKI_SIOCSIWPOWER:
9379   case VKI_SIOCSIWGENIE:
9380   case VKI_SIOCSIWMLME:
9381   case VKI_SIOCSIWAUTH:
9382   case VKI_SIOCSIWENCODEEXT:
9383   case VKI_SIOCSIWPMKSA:
9384      break;
9385   case VKI_SIOCGIWNAME:
9386      if (ARG3) {
9387         POST_MEM_WRITE((Addr)((struct vki_iwreq *)ARG3)->u.name,
9388                        sizeof(((struct vki_iwreq *)ARG3)->u.name));
9389      }
9390      break;
9391   case VKI_SIOCGIWNWID:
9392   case VKI_SIOCGIWSENS:
9393   case VKI_SIOCGIWRATE:
9394   case VKI_SIOCGIWRTS:
9395   case VKI_SIOCGIWFRAG:
9396   case VKI_SIOCGIWTXPOW:
9397   case VKI_SIOCGIWRETRY:
9398   case VKI_SIOCGIWPOWER:
9399   case VKI_SIOCGIWAUTH:
9400      if (ARG3) {
9401         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.param,
9402                        sizeof(struct vki_iw_param));
9403      }
9404      break;
9405   case VKI_SIOCGIWFREQ:
9406      if (ARG3) {
9407         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.freq,
9408                        sizeof(struct vki_iw_freq));
9409      }
9410      break;
9411   case VKI_SIOCGIWMODE:
9412      if (ARG3) {
9413         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.mode,
9414                       sizeof(__vki_u32));
9415      }
9416      break;
9417   case VKI_SIOCGIWRANGE:
9418   case VKI_SIOCGIWPRIV:
9419   case VKI_SIOCGIWSTATS:
9420   case VKI_SIOCGIWSPY:
9421   case VKI_SIOCGIWTHRSPY:
9422   case VKI_SIOCGIWAPLIST:
9423   case VKI_SIOCGIWSCAN:
9424   case VKI_SIOCGIWESSID:
9425   case VKI_SIOCGIWNICKN:
9426   case VKI_SIOCGIWENCODE:
9427   case VKI_SIOCGIWGENIE:
9428   case VKI_SIOCGIWENCODEEXT:
9429      if (ARG3) {
9430         struct vki_iw_point* point;
9431         point = &((struct vki_iwreq *)ARG3)->u.data;
9432         POST_MEM_WRITE((Addr)point->pointer, point->length);
9433      }
9434      break;
9435   case VKI_SIOCGIWAP:
9436      if (ARG3) {
9437         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
9438                        sizeof(struct vki_sockaddr));
9439      }
9440      break;
9441
9442#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
9443      || defined(VGPV_mips32_linux_android)
9444   /* ashmem */
9445   case VKI_ASHMEM_GET_SIZE:
9446   case VKI_ASHMEM_SET_SIZE:
9447   case VKI_ASHMEM_GET_PROT_MASK:
9448   case VKI_ASHMEM_SET_PROT_MASK:
9449   case VKI_ASHMEM_GET_PIN_STATUS:
9450   case VKI_ASHMEM_PURGE_ALL_CACHES:
9451   case VKI_ASHMEM_SET_NAME:
9452   case VKI_ASHMEM_PIN:
9453   case VKI_ASHMEM_UNPIN:
9454       break;
9455   case VKI_ASHMEM_GET_NAME:
9456       POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
9457       break;
9458
9459   /* binder */
9460   case VKI_BINDER_WRITE_READ:
9461       if (ARG3) {
9462           struct vki_binder_write_read* bwr
9463              = (struct vki_binder_write_read*)ARG3;
9464           POST_FIELD_WRITE(bwr->write_consumed);
9465           POST_FIELD_WRITE(bwr->read_consumed);
9466
9467           if (bwr->read_size)
9468               POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
9469       }
9470       break;
9471
9472   case VKI_BINDER_SET_IDLE_TIMEOUT:
9473   case VKI_BINDER_SET_MAX_THREADS:
9474   case VKI_BINDER_SET_IDLE_PRIORITY:
9475   case VKI_BINDER_SET_CONTEXT_MGR:
9476   case VKI_BINDER_THREAD_EXIT:
9477       break;
9478   case VKI_BINDER_VERSION:
9479       if (ARG3) {
9480           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
9481           POST_FIELD_WRITE(bv->protocol_version);
9482       }
9483       break;
9484#  endif /* defined(VGPV_*_linux_android) */
9485
9486   case VKI_HCIGETDEVLIST:
9487      if (ARG3) {
9488        struct vki_hci_dev_list_req* dlr = (struct vki_hci_dev_list_req*)ARG3;
9489        POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
9490                       dlr->dev_num * sizeof(struct vki_hci_dev_req));
9491      }
9492      break;
9493
9494   case VKI_HCIINQUIRY:
9495      if (ARG3) {
9496        struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
9497        POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
9498                       ir->num_rsp * sizeof(struct vki_inquiry_info));
9499      }
9500      break;
9501
9502   case VKI_DRM_IOCTL_VERSION:
9503      if (ARG3) {
9504         struct vki_drm_version *data = (struct vki_drm_version *)ARG3;
9505	 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
9506         POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
9507         POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
9508         POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
9509         POST_MEM_WRITE((Addr)data->name, data->name_len);
9510         POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
9511         POST_MEM_WRITE((Addr)data->date, data->date_len);
9512         POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
9513         POST_MEM_WRITE((Addr)data->desc, data->desc_len);
9514      }
9515      break;
9516   case VKI_DRM_IOCTL_GET_UNIQUE:
9517      if (ARG3) {
9518         struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
9519	 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
9520      }
9521      break;
9522   case VKI_DRM_IOCTL_GET_MAGIC:
9523      if (ARG3) {
9524         struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
9525         POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
9526      }
9527      break;
9528   case VKI_DRM_IOCTL_WAIT_VBLANK:
9529      if (ARG3) {
9530         union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
9531         POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
9532      }
9533      break;
9534   case VKI_DRM_IOCTL_GEM_FLINK:
9535      if (ARG3) {
9536         struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
9537         POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
9538      }
9539      break;
9540   case VKI_DRM_IOCTL_GEM_OPEN:
9541      if (ARG3) {
9542         struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
9543	 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
9544	 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
9545      }
9546      break;
9547   case VKI_DRM_IOCTL_I915_GETPARAM:
9548      if (ARG3) {
9549         vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
9550	 POST_MEM_WRITE((Addr)data->value, sizeof(int));
9551      }
9552      break;
9553   case VKI_DRM_IOCTL_I915_GEM_BUSY:
9554      if (ARG3) {
9555         struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
9556         POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
9557      }
9558      break;
9559   case VKI_DRM_IOCTL_I915_GEM_CREATE:
9560      if (ARG3) {
9561         struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
9562	 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
9563      }
9564      break;
9565   case VKI_DRM_IOCTL_I915_GEM_PREAD:
9566      if (ARG3) {
9567         struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
9568	 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
9569      }
9570      break;
9571   case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
9572      if (ARG3) {
9573         struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
9574         POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
9575      }
9576      break;
9577   case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
9578      if (ARG3) {
9579         struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
9580         POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
9581         POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
9582         POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
9583      }
9584      break;
9585   case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
9586      if (ARG3) {
9587         struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
9588	 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
9589         POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
9590      }
9591      break;
9592   case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
9593      if (ARG3) {
9594         struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
9595         POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
9596         POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
9597      }
9598      break;
9599
9600   /* KVM ioctls that only write the system call return value */
9601   case VKI_KVM_GET_API_VERSION:
9602   case VKI_KVM_CREATE_VM:
9603   case VKI_KVM_CHECK_EXTENSION:
9604   case VKI_KVM_GET_VCPU_MMAP_SIZE:
9605   case VKI_KVM_S390_ENABLE_SIE:
9606   case VKI_KVM_CREATE_VCPU:
9607   case VKI_KVM_SET_TSS_ADDR:
9608   case VKI_KVM_CREATE_IRQCHIP:
9609   case VKI_KVM_RUN:
9610   case VKI_KVM_S390_INITIAL_RESET:
9611   case VKI_KVM_KVMCLOCK_CTRL:
9612      break;
9613
9614#ifdef ENABLE_XEN
9615   case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
9616       SyscallArgs harrghs;
9617       struct vki_xen_privcmd_hypercall *args =
9618          (struct vki_xen_privcmd_hypercall *)(ARG3);
9619
9620       if (!args)
9621          break;
9622
9623       VG_(memset)(&harrghs, 0, sizeof(harrghs));
9624       harrghs.sysno = args->op;
9625       harrghs.arg1 = args->arg[0];
9626       harrghs.arg2 = args->arg[1];
9627       harrghs.arg3 = args->arg[2];
9628       harrghs.arg4 = args->arg[3];
9629       harrghs.arg5 = args->arg[4];
9630       harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
9631
9632       WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
9633      }
9634      break;
9635
9636   case VKI_XEN_IOCTL_PRIVCMD_MMAP:
9637      break;
9638   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
9639       struct vki_xen_privcmd_mmapbatch *args =
9640           (struct vki_xen_privcmd_mmapbatch *)(ARG3);
9641       POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
9642      }
9643      break;
9644   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
9645       struct vki_xen_privcmd_mmapbatch_v2 *args =
9646           (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
9647       POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
9648      }
9649      break;
9650
9651   case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
9652   case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
9653   case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
9654   case VKI_XEN_IOCTL_EVTCHN_UNBIND:
9655   case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
9656   case VKI_XEN_IOCTL_EVTCHN_RESET:
9657      /* No output */
9658      break;
9659#endif
9660
9661   /* Lustre */
9662   case VKI_OBD_IOC_FID2PATH: {
9663       struct vki_getinfo_fid2path *args = (void *)(ARG3);
9664       POST_FIELD_WRITE(args->gf_recno);
9665       POST_FIELD_WRITE(args->gf_linkno);
9666       POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
9667       break;
9668      }
9669
9670   case VKI_LL_IOC_PATH2FID:
9671       POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
9672      break;
9673
9674   case VKI_LL_IOC_GETPARENT: {
9675       struct vki_getparent *gp = (struct vki_getparent *)ARG3;
9676       POST_FIELD_WRITE(gp->gp_fid);
9677       POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
9678       break;
9679   }
9680
9681   /* V4L2 */
9682   case VKI_V4L2_S_FMT:
9683   case VKI_V4L2_TRY_FMT:
9684   case VKI_V4L2_REQBUFS:
9685   case VKI_V4L2_OVERLAY:
9686   case VKI_V4L2_STREAMON:
9687   case VKI_V4L2_STREAMOFF:
9688   case VKI_V4L2_S_PARM:
9689   case VKI_V4L2_S_STD:
9690   case VKI_V4L2_S_FREQUENCY:
9691   case VKI_V4L2_S_CTRL:
9692   case VKI_V4L2_S_TUNER:
9693   case VKI_V4L2_S_AUDIO:
9694   case VKI_V4L2_S_INPUT:
9695   case VKI_V4L2_S_EDID:
9696   case VKI_V4L2_S_OUTPUT:
9697   case VKI_V4L2_S_AUDOUT:
9698   case VKI_V4L2_S_MODULATOR:
9699   case VKI_V4L2_S_JPEGCOMP:
9700   case VKI_V4L2_S_CROP:
9701   case VKI_V4L2_S_PRIORITY:
9702   case VKI_V4L2_G_ENC_INDEX:
9703   case VKI_V4L2_S_HW_FREQ_SEEK:
9704   case VKI_V4L2_S_DV_TIMINGS:
9705   case VKI_V4L2_SUBSCRIBE_EVENT:
9706   case VKI_V4L2_UNSUBSCRIBE_EVENT:
9707   case VKI_V4L2_PREPARE_BUF:
9708      break;
9709   case VKI_V4L2_QUERYCAP: {
9710      struct vki_v4l2_capability *data = (struct vki_v4l2_capability *)ARG3;
9711      POST_MEM_WRITE((Addr)data, sizeof(*data));
9712      break;
9713   }
9714   case VKI_V4L2_ENUM_FMT: {
9715      struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)ARG3;
9716      POST_FIELD_WRITE(data->flags);
9717      POST_FIELD_WRITE(data->description);
9718      POST_FIELD_WRITE(data->pixelformat);
9719      POST_FIELD_WRITE(data->reserved);
9720      break;
9721   }
9722   case VKI_V4L2_G_FMT: {
9723      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
9724      switch (data->type) {
9725      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9726      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9727         POST_FIELD_WRITE(data->fmt.pix);
9728         break;
9729      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9730      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9731         POST_FIELD_WRITE(data->fmt.vbi);
9732         break;
9733      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9734      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9735         POST_FIELD_WRITE(data->fmt.sliced);
9736         break;
9737      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9738      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9739         POST_FIELD_WRITE(data->fmt.win);
9740         break;
9741      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9742      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9743         POST_FIELD_WRITE(data->fmt.pix_mp);
9744         break;
9745      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9746         POST_FIELD_WRITE(data->fmt.sdr);
9747         break;
9748      }
9749      break;
9750   }
9751   case VKI_V4L2_QUERYBUF: {
9752      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
9753      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9754            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9755         unsigned i;
9756
9757         for (i = 0; i < data->length; i++) {
9758            POST_FIELD_WRITE(data->m.planes[i].bytesused);
9759            POST_FIELD_WRITE(data->m.planes[i].length);
9760            POST_FIELD_WRITE(data->m.planes[i].m);
9761            POST_FIELD_WRITE(data->m.planes[i].data_offset);
9762            POST_FIELD_WRITE(data->m.planes[i].reserved);
9763         }
9764      } else {
9765         POST_FIELD_WRITE(data->m);
9766         POST_FIELD_WRITE(data->length);
9767      }
9768      POST_FIELD_WRITE(data->bytesused);
9769      POST_FIELD_WRITE(data->flags);
9770      POST_FIELD_WRITE(data->field);
9771      POST_FIELD_WRITE(data->timestamp);
9772      POST_FIELD_WRITE(data->timecode);
9773      POST_FIELD_WRITE(data->sequence);
9774      POST_FIELD_WRITE(data->memory);
9775      POST_FIELD_WRITE(data->sequence);
9776      break;
9777   }
9778   case VKI_V4L2_G_FBUF: {
9779      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
9780      POST_MEM_WRITE((Addr)data, sizeof(*data));
9781      break;
9782   }
9783   case VKI_V4L2_S_FBUF: {
9784      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
9785      POST_FIELD_WRITE(data->capability);
9786      POST_FIELD_WRITE(data->flags);
9787      POST_FIELD_WRITE(data->fmt);
9788      break;
9789   }
9790   case VKI_V4L2_QBUF: {
9791      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
9792
9793      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9794            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9795         unsigned i;
9796
9797         for (i = 0; i < data->length; i++) {
9798            POST_FIELD_WRITE(data->m.planes[i].length);
9799            if (data->memory == VKI_V4L2_MEMORY_MMAP)
9800               POST_FIELD_WRITE(data->m.planes[i].m);
9801         }
9802      } else {
9803         if (data->memory == VKI_V4L2_MEMORY_MMAP)
9804            POST_FIELD_WRITE(data->m);
9805         POST_FIELD_WRITE(data->length);
9806      }
9807      break;
9808   }
9809   case VKI_V4L2_EXPBUF: {
9810      struct vki_v4l2_exportbuffer *data = (struct vki_v4l2_exportbuffer *)ARG3;
9811      POST_FIELD_WRITE(data->fd);
9812      break;
9813   }
9814   case VKI_V4L2_DQBUF: {
9815      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
9816      POST_FIELD_WRITE(data->index);
9817      POST_FIELD_WRITE(data->bytesused);
9818      POST_FIELD_WRITE(data->field);
9819      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9820            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9821         unsigned i;
9822
9823         for (i = 0; i < data->length; i++) {
9824            POST_FIELD_WRITE(data->m.planes[i].bytesused);
9825            POST_FIELD_WRITE(data->m.planes[i].data_offset);
9826            POST_FIELD_WRITE(data->m.planes[i].length);
9827            POST_FIELD_WRITE(data->m.planes[i].m);
9828         }
9829      } else {
9830         POST_FIELD_WRITE(data->m);
9831         POST_FIELD_WRITE(data->length);
9832         POST_FIELD_WRITE(data->bytesused);
9833         POST_FIELD_WRITE(data->field);
9834      }
9835      POST_FIELD_WRITE(data->timestamp);
9836      POST_FIELD_WRITE(data->timecode);
9837      POST_FIELD_WRITE(data->sequence);
9838      break;
9839   }
9840   case VKI_V4L2_G_PARM: {
9841      struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
9842      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9843         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9844         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9845         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9846
9847      if (is_output)
9848        POST_MEM_WRITE((Addr)&data->parm.output,
9849            sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9850      else
9851        POST_MEM_WRITE((Addr)&data->parm.capture,
9852            sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9853      break;
9854   }
9855   case VKI_V4L2_G_STD: {
9856      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
9857      POST_MEM_WRITE((Addr)data, sizeof(*data));
9858      break;
9859   }
9860   case VKI_V4L2_ENUMSTD: {
9861      struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)ARG3;
9862      POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
9863      break;
9864   }
9865   case VKI_V4L2_ENUMINPUT: {
9866      struct vki_v4l2_input *data = (struct vki_v4l2_input *)ARG3;
9867      POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
9868      break;
9869   }
9870   case VKI_V4L2_G_CTRL: {
9871      struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
9872      POST_FIELD_WRITE(data->value);
9873      break;
9874   }
9875   case VKI_V4L2_G_TUNER: {
9876      struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
9877      POST_MEM_WRITE((Addr)data->name,
9878            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9879      break;
9880   }
9881   case VKI_V4L2_G_AUDIO: {
9882      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
9883      POST_MEM_WRITE((Addr)data,
9884            sizeof(*data) - sizeof(data->reserved));
9885      break;
9886   }
9887   case VKI_V4L2_QUERYCTRL: {
9888      struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)ARG3;
9889      POST_MEM_WRITE((Addr)&data->type,
9890            sizeof(*data) - sizeof(data->id));
9891      break;
9892   }
9893   case VKI_V4L2_QUERYMENU: {
9894      struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)ARG3;
9895      POST_MEM_WRITE((Addr)data->name,
9896            sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9897      break;
9898   }
9899   case VKI_V4L2_G_INPUT: {
9900      int *data = (int *)ARG3;
9901      POST_MEM_WRITE((Addr)data, sizeof(*data));
9902      break;
9903   }
9904   case VKI_V4L2_G_EDID: {
9905      struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
9906      if (data->blocks && data->edid)
9907         POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
9908      break;
9909   }
9910   case VKI_V4L2_G_OUTPUT: {
9911      int *data = (int *)ARG3;
9912      POST_MEM_WRITE((Addr)data, sizeof(*data));
9913      break;
9914   }
9915   case VKI_V4L2_ENUMOUTPUT: {
9916      struct vki_v4l2_output *data = (struct vki_v4l2_output *)ARG3;
9917      POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
9918      break;
9919   }
9920   case VKI_V4L2_G_AUDOUT: {
9921      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
9922      POST_MEM_WRITE((Addr)data,
9923            sizeof(*data) - sizeof(data->reserved));
9924      break;
9925   }
9926   case VKI_V4L2_G_MODULATOR: {
9927      struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
9928      POST_MEM_WRITE((Addr)data->name,
9929            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9930      break;
9931   }
9932   case VKI_V4L2_G_FREQUENCY: {
9933      struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
9934      POST_FIELD_WRITE(data->type);
9935      POST_FIELD_WRITE(data->frequency);
9936      break;
9937   }
9938   case VKI_V4L2_CROPCAP: {
9939      struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)ARG3;
9940      POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9941      break;
9942   }
9943   case VKI_V4L2_G_CROP: {
9944      struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
9945      POST_FIELD_WRITE(data->c);
9946      break;
9947   }
9948   case VKI_V4L2_G_JPEGCOMP: {
9949      struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
9950      POST_MEM_WRITE((Addr)data, sizeof(*data));
9951      break;
9952   }
9953   case VKI_V4L2_QUERYSTD: {
9954      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
9955      POST_MEM_WRITE((Addr)data, sizeof(*data));
9956      break;
9957   }
9958   case VKI_V4L2_ENUMAUDIO: {
9959      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
9960      POST_MEM_WRITE((Addr)data->name,
9961            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9962      break;
9963   }
9964   case VKI_V4L2_ENUMAUDOUT: {
9965      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
9966      POST_MEM_WRITE((Addr)data->name,
9967            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9968      break;
9969   }
9970   case VKI_V4L2_G_PRIORITY: {
9971      __vki_u32 *data = (__vki_u32 *)ARG3;
9972      POST_MEM_WRITE((Addr)data, sizeof(*data));
9973      break;
9974   }
9975   case VKI_V4L2_G_SLICED_VBI_CAP: {
9976      struct vki_v4l2_sliced_vbi_cap *data = (struct vki_v4l2_sliced_vbi_cap *)ARG3;
9977      POST_MEM_WRITE((Addr)data,
9978            sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9979      break;
9980   }
9981   case VKI_V4L2_G_EXT_CTRLS: {
9982      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
9983      if (data->count) {
9984         unsigned i;
9985
9986         for (i = 0; i < data->count; i++) {
9987            if (data->controls[i].size)
9988               POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
9989            else
9990               POST_FIELD_WRITE(data->controls[i].value64);
9991         }
9992      }
9993      POST_FIELD_WRITE(data->error_idx);
9994      break;
9995   }
9996   case VKI_V4L2_S_EXT_CTRLS: {
9997      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
9998      POST_FIELD_WRITE(data->error_idx);
9999      break;
10000   }
10001   case VKI_V4L2_TRY_EXT_CTRLS: {
10002      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10003      POST_FIELD_WRITE(data->error_idx);
10004      break;
10005   }
10006   case VKI_V4L2_ENUM_FRAMESIZES: {
10007      struct vki_v4l2_frmsizeenum *data = (struct vki_v4l2_frmsizeenum *)ARG3;
10008      POST_FIELD_WRITE(data->type);
10009      POST_FIELD_WRITE(data->stepwise);
10010      break;
10011   }
10012   case VKI_V4L2_ENUM_FRAMEINTERVALS: {
10013      struct vki_v4l2_frmivalenum *data = (struct vki_v4l2_frmivalenum *)ARG3;
10014      POST_FIELD_WRITE(data->type);
10015      POST_FIELD_WRITE(data->stepwise);
10016      break;
10017   }
10018   case VKI_V4L2_ENCODER_CMD: {
10019      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
10020      POST_FIELD_WRITE(data->flags);
10021      break;
10022   }
10023   case VKI_V4L2_TRY_ENCODER_CMD: {
10024      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
10025      POST_FIELD_WRITE(data->flags);
10026      break;
10027   }
10028   case VKI_V4L2_DBG_S_REGISTER: {
10029      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
10030      POST_FIELD_WRITE(data->size);
10031      break;
10032   }
10033   case VKI_V4L2_DBG_G_REGISTER: {
10034      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
10035      POST_FIELD_WRITE(data->val);
10036      POST_FIELD_WRITE(data->size);
10037      break;
10038   }
10039   case VKI_V4L2_G_DV_TIMINGS: {
10040      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
10041      POST_MEM_WRITE((Addr)data, sizeof(*data));
10042      break;
10043   }
10044   case VKI_V4L2_DQEVENT: {
10045      struct vki_v4l2_event *data = (struct vki_v4l2_event *)ARG3;
10046      POST_MEM_WRITE((Addr)data, sizeof(*data));
10047      break;
10048   }
10049   case VKI_V4L2_CREATE_BUFS: {
10050      struct vki_v4l2_create_buffers *data = (struct vki_v4l2_create_buffers *)ARG3;
10051      POST_FIELD_WRITE(data->index);
10052      break;
10053   }
10054   case VKI_V4L2_G_SELECTION: {
10055      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
10056      POST_FIELD_WRITE(data->r);
10057      break;
10058   }
10059   case VKI_V4L2_S_SELECTION: {
10060      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
10061      POST_FIELD_WRITE(data->r);
10062      break;
10063   }
10064   case VKI_V4L2_DECODER_CMD: {
10065      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
10066      POST_FIELD_WRITE(data->flags);
10067      break;
10068   }
10069   case VKI_V4L2_TRY_DECODER_CMD: {
10070      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
10071      POST_FIELD_WRITE(data->flags);
10072      break;
10073   }
10074   case VKI_V4L2_ENUM_DV_TIMINGS: {
10075      struct vki_v4l2_enum_dv_timings *data = (struct vki_v4l2_enum_dv_timings *)ARG3;
10076      POST_FIELD_WRITE(data->timings);
10077      break;
10078   }
10079   case VKI_V4L2_QUERY_DV_TIMINGS: {
10080      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
10081      POST_MEM_WRITE((Addr)data, sizeof(*data));
10082      break;
10083   }
10084   case VKI_V4L2_DV_TIMINGS_CAP: {
10085      struct vki_v4l2_dv_timings_cap *data = (struct vki_v4l2_dv_timings_cap *)ARG3;
10086      POST_MEM_WRITE((Addr)data, sizeof(*data));
10087      break;
10088   }
10089   case VKI_V4L2_ENUM_FREQ_BANDS: {
10090      struct vki_v4l2_frequency_band *data = (struct vki_v4l2_frequency_band *)ARG3;
10091      POST_FIELD_WRITE(data->capability);
10092      POST_FIELD_WRITE(data->rangelow);
10093      POST_FIELD_WRITE(data->rangehigh);
10094      POST_FIELD_WRITE(data->modulation);
10095      break;
10096   }
10097   case VKI_V4L2_DBG_G_CHIP_INFO: {
10098      struct vki_v4l2_dbg_chip_info *data = (struct vki_v4l2_dbg_chip_info *)ARG3;
10099      POST_FIELD_WRITE(data->name);
10100      POST_FIELD_WRITE(data->flags);
10101      break;
10102   }
10103   case VKI_V4L2_QUERY_EXT_CTRL: {
10104      struct vki_v4l2_query_ext_ctrl *data = (struct vki_v4l2_query_ext_ctrl *)ARG3;
10105      POST_MEM_WRITE((Addr)&data->type,
10106            sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
10107      break;
10108   }
10109
10110   case VKI_V4L2_SUBDEV_S_FMT:
10111   case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
10112   case VKI_V4L2_SUBDEV_S_CROP:
10113   case VKI_V4L2_SUBDEV_S_SELECTION:
10114      break;
10115
10116   case VKI_V4L2_SUBDEV_G_FMT: {
10117      struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
10118      POST_FIELD_WRITE(data->format);
10119      break;
10120   }
10121   case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
10122      struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
10123      POST_FIELD_WRITE(data->interval);
10124      break;
10125   }
10126   case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
10127      struct vki_v4l2_subdev_mbus_code_enum *data = (struct vki_v4l2_subdev_mbus_code_enum *)ARG3;
10128      POST_FIELD_WRITE(data->code);
10129      break;
10130   }
10131   case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
10132      struct vki_v4l2_subdev_frame_size_enum *data = (struct vki_v4l2_subdev_frame_size_enum *)ARG3;
10133      POST_FIELD_WRITE(data->min_width);
10134      POST_FIELD_WRITE(data->min_height);
10135      POST_FIELD_WRITE(data->max_width);
10136      POST_FIELD_WRITE(data->max_height);
10137      break;
10138   }
10139   case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10140      struct vki_v4l2_subdev_frame_interval_enum *data = (struct vki_v4l2_subdev_frame_interval_enum *)ARG3;
10141      POST_FIELD_WRITE(data->interval);
10142      break;
10143   }
10144   case VKI_V4L2_SUBDEV_G_CROP: {
10145      struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
10146      POST_FIELD_WRITE(data->rect);
10147      break;
10148   }
10149   case VKI_V4L2_SUBDEV_G_SELECTION: {
10150      struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
10151      POST_FIELD_WRITE(data->r);
10152      break;
10153   }
10154   case VKI_MEDIA_IOC_DEVICE_INFO: {
10155      struct vki_media_device_info *data = (struct vki_media_device_info *)ARG3;
10156      POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
10157      break;
10158   }
10159   case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10160      struct vki_media_entity_desc *data = (struct vki_media_entity_desc *)ARG3;
10161      POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
10162      break;
10163   }
10164   case VKI_MEDIA_IOC_ENUM_LINKS:
10165      /*
10166       * This ioctl does write to the provided pointers, but it's not
10167       * possible to deduce the size of the array those pointers point to.
10168       */
10169      break;
10170   case VKI_MEDIA_IOC_SETUP_LINK:
10171      break;
10172
10173   default:
10174      /* EVIOC* are variable length and return size written on success */
10175      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10176      case VKI_EVIOCGNAME(0):
10177      case VKI_EVIOCGPHYS(0):
10178      case VKI_EVIOCGUNIQ(0):
10179      case VKI_EVIOCGKEY(0):
10180      case VKI_EVIOCGLED(0):
10181      case VKI_EVIOCGSND(0):
10182      case VKI_EVIOCGSW(0):
10183      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10184      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10185      case VKI_EVIOCGBIT(VKI_EV_REL,0):
10186      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10187      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10188      case VKI_EVIOCGBIT(VKI_EV_SW,0):
10189      case VKI_EVIOCGBIT(VKI_EV_LED,0):
10190      case VKI_EVIOCGBIT(VKI_EV_SND,0):
10191      case VKI_EVIOCGBIT(VKI_EV_REP,0):
10192      case VKI_EVIOCGBIT(VKI_EV_FF,0):
10193      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10194      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10195         if (RES > 0)
10196            POST_MEM_WRITE(ARG3, RES);
10197         break;
10198      default:
10199         ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
10200         break;
10201      }
10202      break;
10203   }
10204
10205  post_sys_ioctl__out:
10206   {} /* keep C compilers happy */
10207}
10208
10209/* ---------------------------------------------------------------------
10210   socketcall wrapper helpers
10211   ------------------------------------------------------------------ */
10212
10213void
10214ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
10215                                UWord arg0, UWord arg1, UWord arg2,
10216                                UWord arg3, UWord arg4 )
10217{
10218   /* int getsockopt(int s, int level, int optname,
10219                     void *optval, socklen_t *optlen); */
10220   Addr optval_p = arg3;
10221   Addr optlen_p = arg4;
10222   /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
10223   if (optval_p != (Addr)NULL) {
10224      ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
10225                                   "socketcall.getsockopt(optval)",
10226                                   "socketcall.getsockopt(optlen)" );
10227      if (arg1 == VKI_SOL_SCTP &&
10228          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
10229           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
10230      {
10231         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
10232         int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
10233         PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
10234                        (Addr)ga->addrs, address_bytes );
10235      }
10236   }
10237}
10238
10239void
10240ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
10241                                 SysRes res,
10242                                 UWord arg0, UWord arg1, UWord arg2,
10243                                 UWord arg3, UWord arg4 )
10244{
10245   Addr optval_p = arg3;
10246   Addr optlen_p = arg4;
10247   vg_assert(!sr_isError(res)); /* guaranteed by caller */
10248   if (optval_p != (Addr)NULL) {
10249      ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
10250                                    "socketcall.getsockopt(optlen_out)" );
10251      if (arg1 == VKI_SOL_SCTP &&
10252          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
10253           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
10254      {
10255         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
10256         struct vki_sockaddr *a = ga->addrs;
10257         int i;
10258         for (i = 0; i < ga->addr_num; i++) {
10259            int sl = 0;
10260            if (a->sa_family == VKI_AF_INET)
10261               sl = sizeof(struct vki_sockaddr_in);
10262            else if (a->sa_family == VKI_AF_INET6)
10263               sl = sizeof(struct vki_sockaddr_in6);
10264            else {
10265               VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
10266                                        "address type %d\n", a->sa_family);
10267            }
10268            a = (struct vki_sockaddr*)((char*)a + sl);
10269         }
10270         POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
10271      }
10272   }
10273}
10274
10275void
10276ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
10277                                UWord arg0, UWord arg1, UWord arg2,
10278                                UWord arg3, UWord arg4 )
10279{
10280   /* int setsockopt(int s, int level, int optname,
10281                     const void *optval, socklen_t optlen); */
10282   Addr optval_p = arg3;
10283   if (optval_p != (Addr)NULL) {
10284      /*
10285       * OK, let's handle at least some setsockopt levels and options
10286       * ourselves, so we don't get false claims of references to
10287       * uninitialized memory (such as padding in structures) and *do*
10288       * check what pointers in the argument point to.
10289       */
10290      if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
10291      {
10292         struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
10293
10294         /*
10295          * struct sock_fprog has a 16-bit count of instructions,
10296          * followed by a pointer to an array of those instructions.
10297          * There's padding between those two elements.
10298          *
10299          * So that we don't bogusly complain about the padding bytes,
10300          * we just report that we read len and and filter.
10301          *
10302          * We then make sure that what filter points to is valid.
10303          */
10304         PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
10305                       (Addr)&fp->len, sizeof(fp->len) );
10306         PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
10307                       (Addr)&fp->filter, sizeof(fp->filter) );
10308
10309         /* len * sizeof (*filter) */
10310         if (fp->filter != NULL)
10311         {
10312            PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
10313                          (Addr)(fp->filter),
10314                          fp->len * sizeof(*fp->filter) );
10315         }
10316      }
10317      else
10318      {
10319         PRE_MEM_READ( "socketcall.setsockopt(optval)",
10320                       arg3, /* optval */
10321                       arg4  /* optlen */ );
10322      }
10323   }
10324}
10325
10326void
10327ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
10328                              UWord arg1, UWord arg2, UWord arg3,
10329                              UWord arg4, UWord arg5 )
10330{
10331   struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
10332   HChar name[40];     // large enough
10333   UInt i;
10334   for (i = 0; i < arg3; i++) {
10335      VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
10336      ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
10337      VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
10338      PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
10339   }
10340   if (arg5)
10341      PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
10342}
10343
10344void
10345ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
10346                              UWord arg1, UWord arg2, UWord arg3,
10347                              UWord arg4, UWord arg5 )
10348{
10349   if (res > 0) {
10350      struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
10351      HChar name[32];    // large enough
10352      UInt i;
10353      for (i = 0; i < res; i++) {
10354         VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
10355         ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
10356         POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
10357      }
10358   }
10359}
10360
10361void
10362ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
10363                              UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
10364{
10365   struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
10366   HChar name[40];     // large enough
10367   UInt i;
10368   for (i = 0; i < arg3; i++) {
10369      VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
10370      ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
10371      VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
10372      PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
10373   }
10374}
10375
10376void
10377ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
10378                              UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
10379{
10380   if (res > 0) {
10381      struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
10382      UInt i;
10383      for (i = 0; i < res; i++) {
10384         POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
10385      }
10386   }
10387}
10388
10389/* ---------------------------------------------------------------------
10390   ptrace wrapper helpers
10391   ------------------------------------------------------------------ */
10392
10393void
10394ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
10395{
10396   struct vki_iovec *iov = (struct vki_iovec *) arg4;
10397
10398   PRE_MEM_READ("ptrace(getregset iovec->iov_base)",
10399		(unsigned long) &iov->iov_base, sizeof(iov->iov_base));
10400   PRE_MEM_READ("ptrace(getregset iovec->iov_len)",
10401		(unsigned long) &iov->iov_len, sizeof(iov->iov_len));
10402   PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
10403		 (unsigned long) iov->iov_base, iov->iov_len);
10404}
10405
10406void
10407ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
10408{
10409   struct vki_iovec *iov = (struct vki_iovec *) arg4;
10410
10411   PRE_MEM_READ("ptrace(setregset iovec->iov_base)",
10412		(unsigned long) &iov->iov_base, sizeof(iov->iov_base));
10413   PRE_MEM_READ("ptrace(setregset iovec->iov_len)",
10414		(unsigned long) &iov->iov_len, sizeof(iov->iov_len));
10415   PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
10416		(unsigned long) iov->iov_base, iov->iov_len);
10417}
10418
10419void
10420ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
10421{
10422   struct vki_iovec *iov = (struct vki_iovec *) arg4;
10423
10424   /* XXX: The actual amount of data written by the kernel might be
10425      less than iov_len, depending on the regset (arg3). */
10426   POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
10427}
10428
10429PRE(sys_kcmp)
10430{
10431   PRINT("kcmp ( %ld, %ld, %ld, %lu, %lu )", ARG1, ARG2, ARG3, ARG4, ARG5);
10432   switch (ARG3) {
10433      case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
10434      case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
10435         /* Most of the comparison types don't look at |idx1| or
10436            |idx2|. */
10437         PRE_REG_READ3(long, "kcmp",
10438                       vki_pid_t, pid1, vki_pid_t, pid2, int, type);
10439         break;
10440      case VKI_KCMP_FILE:
10441      default:
10442         PRE_REG_READ5(long, "kcmp",
10443                       vki_pid_t, pid1, vki_pid_t, pid2, int, type,
10444                       unsigned long, idx1, unsigned long, idx2);
10445         break;
10446   }
10447}
10448
10449#undef PRE
10450#undef POST
10451
10452#endif // defined(VGO_linux)
10453
10454/*--------------------------------------------------------------------*/
10455/*--- end                                                          ---*/
10456/*--------------------------------------------------------------------*/
10457