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-2017 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_stacks.h"
56#include "pub_core_syscall.h"
57#include "pub_core_syswrap.h"
58#include "pub_core_inner.h"
59#if defined(ENABLE_INNER_CLIENT_REQUEST)
60#include "pub_core_clreq.h"
61#endif
62
63#include "priv_types_n_macros.h"
64#include "priv_syswrap-generic.h"
65#include "priv_syswrap-linux.h"
66#include "priv_syswrap-main.h"
67#include "priv_syswrap-xen.h"
68
69// Run a thread from beginning to end and return the thread's
70// scheduler-return-code.
71static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
72{
73   VgSchedReturnCode ret;
74   ThreadId     tid = (ThreadId)tidW;
75   ThreadState* tst = VG_(get_ThreadState)(tid);
76
77   VG_(debugLog)(1, "syswrap-linux",
78                    "thread_wrapper(tid=%u): entry\n",
79                    tid);
80
81   vg_assert(tst->status == VgTs_Init);
82
83   /* make sure we get the CPU lock before doing anything significant */
84   VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
85
86   if (0)
87      VG_(printf)("thread tid %u started: stack = %p\n",
88		  tid, (void *)&tid);
89
90   /* Make sure error reporting is enabled in the new thread. */
91   tst->err_disablement_level = 0;
92
93   VG_TRACK(pre_thread_first_insn, tid);
94
95   tst->os_state.lwpid = VG_(gettid)();
96   /* Set the threadgroup for real.  This overwrites the provisional value set
97      in do_clone().  See comments in do_clone for background, also #226116. */
98   tst->os_state.threadgroup = VG_(getpid)();
99
100   /* Thread created with all signals blocked; scheduler will set the
101      appropriate mask */
102
103   ret = VG_(scheduler)(tid);
104
105   vg_assert(VG_(is_exiting)(tid));
106
107   vg_assert(tst->status == VgTs_Runnable);
108   vg_assert(VG_(is_running_thread)(tid));
109
110   VG_(debugLog)(1, "syswrap-linux",
111                    "thread_wrapper(tid=%u): exit, schedreturncode %s\n",
112                    tid, VG_(name_of_VgSchedReturnCode)(ret));
113
114   /* Return to caller, still holding the lock. */
115   return ret;
116}
117
118
119/* ---------------------------------------------------------------------
120   clone-related stuff
121   ------------------------------------------------------------------ */
122
123/* Run a thread all the way to the end, then do appropriate exit actions
124   (this is the last-one-out-turn-off-the-lights bit).  */
125static void run_a_thread_NORETURN ( Word tidW )
126{
127   ThreadId          tid = (ThreadId)tidW;
128   VgSchedReturnCode src;
129   Int               c;
130   ThreadState*      tst;
131#ifdef ENABLE_INNER_CLIENT_REQUEST
132   Int               registered_vgstack_id;
133#endif
134
135   VG_(debugLog)(1, "syswrap-linux",
136                    "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
137                    tid);
138
139   tst = VG_(get_ThreadState)(tid);
140   vg_assert(tst);
141
142   /* An thread has two stacks:
143      * the simulated stack (used by the synthetic cpu. Guest process
144        is using this stack).
145      * the valgrind stack (used by the real cpu. Valgrind code is running
146        on this stack).
147      When Valgrind runs as an inner, it must signals that its (real) stack
148      is the stack to use by the outer to e.g. do stacktraces.
149   */
150   INNER_REQUEST
151      (registered_vgstack_id
152       = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
153                                  tst->os_state.valgrind_stack_init_SP));
154
155   /* Run the thread all the way through. */
156   src = thread_wrapper(tid);
157
158   VG_(debugLog)(1, "syswrap-linux",
159                    "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
160                    tid);
161
162   c = VG_(count_living_threads)();
163   vg_assert(c >= 1); /* stay sane */
164
165   /* Deregister thread's stack. */
166   if (tst->os_state.stk_id != NULL_STK_ID)
167      VG_(deregister_stack)(tst->os_state.stk_id);
168
169   // Tell the tool this thread is exiting
170   VG_TRACK( pre_thread_ll_exit, tid );
171
172   /* If the thread is exiting with errors disabled, complain loudly;
173      doing so is bad (does the user know this has happened?)  Also,
174      in all cases, be paranoid and clear the flag anyway so that the
175      thread slot is safe in this respect if later reallocated.  This
176      should be unnecessary since the flag should be cleared when the
177      slot is reallocated, in thread_wrapper(). */
178   if (tst->err_disablement_level > 0) {
179      VG_(umsg)(
180         "WARNING: exiting thread has error reporting disabled.\n"
181         "WARNING: possibly as a result of some mistake in the use\n"
182         "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
183      );
184      VG_(debugLog)(
185         1, "syswrap-linux",
186            "run_a_thread_NORETURN(tid=%u): "
187            "WARNING: exiting thread has err_disablement_level = %u\n",
188            tid, tst->err_disablement_level
189      );
190   }
191   tst->err_disablement_level = 0;
192
193   if (c == 1) {
194
195      VG_(debugLog)(1, "syswrap-linux",
196                       "run_a_thread_NORETURN(tid=%u): "
197                          "last one standing\n",
198                          tid);
199
200      /* We are the last one standing.  Keep hold of the lock and
201         carry on to show final tool results, then exit the entire system.
202         Use the continuation pointer set at startup in m_main. */
203      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
204   } else {
205
206      VG_(debugLog)(1, "syswrap-linux",
207                       "run_a_thread_NORETURN(tid=%u): "
208                          "not last one standing\n",
209                          tid);
210
211      /* OK, thread is dead, but others still exist.  Just exit. */
212
213      /* This releases the run lock */
214      VG_(exit_thread)(tid);
215      vg_assert(tst->status == VgTs_Zombie);
216      vg_assert(sizeof(tst->status) == 4);
217      vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
218
219      INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
220
221      /* We have to use this sequence to terminate the thread to
222         prevent a subtle race.  If VG_(exit_thread)() had left the
223         ThreadState as Empty, then it could have been reallocated,
224         reusing the stack while we're doing these last cleanups.
225         Instead, VG_(exit_thread) leaves it as Zombie to prevent
226         reallocation.  We need to make sure we don't touch the stack
227         between marking it Empty and exiting.  Hence the
228         assembler. */
229#if defined(VGP_x86_linux)
230      asm volatile (
231         "pushl %%ebx\n"
232         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
233         "movl	%2, %%eax\n"    /* set %eax = __NR_exit */
234         "movl	%3, %%ebx\n"    /* set %ebx = tst->os_state.exitcode */
235         "int	$0x80\n"	/* exit(tst->os_state.exitcode) */
236	 "popl %%ebx\n"
237         : "=m" (tst->status)
238         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
239         : "eax"
240      );
241#elif defined(VGP_amd64_linux)
242      asm volatile (
243         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
244         "movq	%2, %%rax\n"    /* set %rax = __NR_exit */
245         "movq	%3, %%rdi\n"    /* set %rdi = tst->os_state.exitcode */
246         "syscall\n"		/* exit(tst->os_state.exitcode) */
247         : "=m" (tst->status)
248         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
249         : "rax", "rdi"
250      );
251#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
252      || defined(VGP_ppc64le_linux)
253      { UInt vgts_empty = (UInt)VgTs_Empty;
254        asm volatile (
255          "stw %1,%0\n\t"          /* set tst->status = VgTs_Empty */
256          "li  0,%2\n\t"           /* set r0 = __NR_exit */
257          "lwz 3,%3\n\t"           /* set r3 = tst->os_state.exitcode */
258          "sc\n\t"                 /* exit(tst->os_state.exitcode) */
259          : "=m" (tst->status)
260          : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
261          : "r0", "r3"
262        );
263      }
264#elif defined(VGP_arm_linux)
265      asm volatile (
266         "str  %1, %0\n"      /* set tst->status = VgTs_Empty */
267         "mov  r7, %2\n"      /* set %r7 = __NR_exit */
268         "ldr  r0, %3\n"      /* set %r0 = tst->os_state.exitcode */
269         "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
270         : "=m" (tst->status)
271         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
272         : "r0", "r7"
273      );
274#elif defined(VGP_arm64_linux)
275      asm volatile (
276         "str  %w1, %0\n"     /* set tst->status = VgTs_Empty (32-bit store) */
277         "mov  x8,  %2\n"     /* set %x8 = __NR_exit */
278         "ldr  x0,  %3\n"     /* set %x0 = tst->os_state.exitcode */
279         "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
280         : "=m" (tst->status)
281         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
282         : "x0", "x8"
283      );
284#elif defined(VGP_s390x_linux)
285      asm volatile (
286         "st   %1, %0\n"        /* set tst->status = VgTs_Empty */
287         "lg   2, %3\n"         /* set r2 = tst->os_state.exitcode */
288         "svc %2\n"             /* exit(tst->os_state.exitcode) */
289         : "=m" (tst->status)
290         : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
291         : "2"
292      );
293#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
294      asm volatile (
295         "sw   %1, %0\n\t"     /* set tst->status = VgTs_Empty */
296         "li   $2, %2\n\t"     /* set v0 = __NR_exit */
297         "lw   $4, %3\n\t"     /* set a0 = tst->os_state.exitcode */
298         "syscall\n\t"         /* exit(tst->os_state.exitcode) */
299         "nop"
300         : "=m" (tst->status)
301         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
302         : "cc", "memory" , "v0", "a0"
303      );
304#else
305# error Unknown platform
306#endif
307
308      VG_(core_panic)("Thread exit failed?\n");
309   }
310
311   /*NOTREACHED*/
312   vg_assert(0);
313}
314
315Word ML_(start_thread_NORETURN) ( void* arg )
316{
317   ThreadState* tst = (ThreadState*)arg;
318   ThreadId     tid = tst->tid;
319
320   run_a_thread_NORETURN ( (Word)tid );
321   /*NOTREACHED*/
322   vg_assert(0);
323}
324
325/* Allocate a stack for this thread, if it doesn't already have one.
326   They're allocated lazily, and never freed.  Returns the initial stack
327   pointer value to use, or 0 if allocation failed. */
328Addr ML_(allocstack)(ThreadId tid)
329{
330   ThreadState* tst = VG_(get_ThreadState)(tid);
331   VgStack*     stack;
332   Addr         initial_SP;
333
334   /* Either the stack_base and stack_init_SP are both zero (in which
335      case a stack hasn't been allocated) or they are both non-zero,
336      in which case it has. */
337
338   if (tst->os_state.valgrind_stack_base == 0)
339      vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
340
341   if (tst->os_state.valgrind_stack_base != 0)
342      vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
343
344   /* If no stack is present, allocate one. */
345
346   if (tst->os_state.valgrind_stack_base == 0) {
347      stack = VG_(am_alloc_VgStack)( &initial_SP );
348      if (stack) {
349         tst->os_state.valgrind_stack_base    = (Addr)stack;
350         tst->os_state.valgrind_stack_init_SP = initial_SP;
351      }
352   }
353
354   if (0)
355      VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
356                   tid,
357                   (void*)tst->os_state.valgrind_stack_base,
358                   (void*)tst->os_state.valgrind_stack_init_SP );
359
360   return tst->os_state.valgrind_stack_init_SP;
361}
362
363/* Allocate a stack for the main thread, and run it all the way to the
364   end.  Although we already have a working VgStack
365   (VG_(interim_stack)) it's better to allocate a new one, so that
366   overflow detection works uniformly for all threads.
367*/
368void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
369{
370   Addr sp;
371   VG_(debugLog)(1, "syswrap-linux",
372                    "entering VG_(main_thread_wrapper_NORETURN)\n");
373
374   sp = ML_(allocstack)(tid);
375#if defined(ENABLE_INNER_CLIENT_REQUEST)
376   {
377      // we must register the main thread stack before the call
378      // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
379      // reports 'write error' on the non registered stack.
380      ThreadState* tst = VG_(get_ThreadState)(tid);
381      INNER_REQUEST
382         ((void)
383          VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
384                                   tst->os_state.valgrind_stack_init_SP));
385   }
386#endif
387
388#if defined(VGP_ppc32_linux)
389   /* make a stack frame */
390   sp -= 16;
391   sp &= ~0xF;
392   *(UWord *)sp = 0;
393#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
394   /* make a stack frame */
395   sp -= 112;
396   sp &= ~((Addr)0xF);
397   *(UWord *)sp = 0;
398#elif defined(VGP_s390x_linux)
399   /* make a stack frame */
400   sp -= 160;
401   sp &= ~((Addr)0xF);
402   *(UWord *)sp = 0;
403#endif
404
405   /* If we can't even allocate the first thread's stack, we're hosed.
406      Give up. */
407   vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
408
409   /* shouldn't be any other threads around yet */
410   vg_assert( VG_(count_living_threads)() == 1 );
411
412   ML_(call_on_new_stack_0_1)(
413      (Addr)sp,               /* stack */
414      0,                      /* bogus return address */
415      run_a_thread_NORETURN,  /* fn to call */
416      (Word)tid               /* arg to give it */
417   );
418
419   /*NOTREACHED*/
420   vg_assert(0);
421}
422
423/* Clone a new thread. Note that in the clone syscalls, we hard-code
424   tlsaddr argument as NULL : the guest TLS is emulated via guest
425   registers, and Valgrind itself has no thread local storage. */
426static SysRes clone_new_thread ( Word (*fn)(void *),
427                                 void* stack,
428                                 Word  flags,
429                                 ThreadState* ctst,
430                                 Int* child_tidptr,
431                                 Int* parent_tidptr)
432{
433   SysRes res;
434   /* Note that in all the below, we make sys_clone appear to have returned
435      Success(0) in the child, by assigning the relevant child guest
436      register(s) just before the clone syscall. */
437#if defined(VGP_x86_linux)
438   Int          eax;
439   ctst->arch.vex.guest_EAX = 0;
440   eax = do_syscall_clone_x86_linux
441      (ML_(start_thread_NORETURN), stack, flags, ctst,
442       child_tidptr, parent_tidptr, NULL);
443   res = VG_(mk_SysRes_x86_linux)( eax );
444#elif defined(VGP_amd64_linux)
445   Long         rax;
446   ctst->arch.vex.guest_RAX = 0;
447   rax = do_syscall_clone_amd64_linux
448      (ML_(start_thread_NORETURN), stack, flags, ctst,
449       child_tidptr, parent_tidptr, NULL);
450   res = VG_(mk_SysRes_amd64_linux)( rax );
451#elif defined(VGP_ppc32_linux)
452   ULong        word64;
453   UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
454   /* %r3 = 0 */
455   ctst->arch.vex.guest_GPR3 = 0;
456   /* %cr0.so = 0 */
457   LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
458   word64 = do_syscall_clone_ppc32_linux
459      (ML_(start_thread_NORETURN), stack, flags, ctst,
460       child_tidptr, parent_tidptr, NULL);
461   /* High half word64 is syscall return value.  Low half is
462      the entire CR, from which we need to extract CR0.SO. */
463   /* VG_(printf)("word64 = 0x%llx\n", word64); */
464   res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
465                                    /*errflag*/ (((UInt)word64) >> 28) & 1);
466#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
467   ULong        word64;
468   UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
469   /* %r3 = 0 */
470   ctst->arch.vex.guest_GPR3 = 0;
471   /* %cr0.so = 0 */
472   LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
473   word64 = do_syscall_clone_ppc64_linux
474      (ML_(start_thread_NORETURN), stack, flags, ctst,
475       child_tidptr, parent_tidptr, NULL);
476   /* Low half word64 is syscall return value.  Hi half is
477      the entire CR, from which we need to extract CR0.SO. */
478   /* VG_(printf)("word64 = 0x%llx\n", word64); */
479   res = VG_(mk_SysRes_ppc64_linux)
480      (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
481       /*errflag*/ (UInt)((word64 >> (32+28)) & 1));
482#elif defined(VGP_s390x_linux)
483   ULong        r2;
484   ctst->arch.vex.guest_r2 = 0;
485   r2 = do_syscall_clone_s390x_linux
486      (stack, flags, parent_tidptr, child_tidptr, NULL,
487       ML_(start_thread_NORETURN), ctst);
488   res = VG_(mk_SysRes_s390x_linux)( r2 );
489#elif defined(VGP_arm64_linux)
490   ULong        x0;
491   ctst->arch.vex.guest_X0 = 0;
492   x0 = do_syscall_clone_arm64_linux
493      (ML_(start_thread_NORETURN), stack, flags, ctst,
494       child_tidptr, parent_tidptr, NULL);
495   res = VG_(mk_SysRes_arm64_linux)( x0 );
496#elif defined(VGP_arm_linux)
497   UInt r0;
498   ctst->arch.vex.guest_R0 = 0;
499   r0 = do_syscall_clone_arm_linux
500      (ML_(start_thread_NORETURN), stack, flags, ctst,
501       child_tidptr, parent_tidptr, NULL);
502   res = VG_(mk_SysRes_arm_linux)( r0 );
503#elif defined(VGP_mips64_linux)
504   UInt ret = 0;
505   ctst->arch.vex.guest_r2 = 0;
506   ctst->arch.vex.guest_r7 = 0;
507   ret = do_syscall_clone_mips64_linux
508      (ML_(start_thread_NORETURN), stack, flags, ctst,
509       parent_tidptr, NULL, child_tidptr);
510   res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
511#elif defined(VGP_mips32_linux)
512   UInt ret = 0;
513   ctst->arch.vex.guest_r2 = 0;
514   ctst->arch.vex.guest_r7 = 0;
515   ret = do_syscall_clone_mips_linux
516      (ML_(start_thread_NORETURN), stack, flags, ctst,
517       child_tidptr, parent_tidptr, NULL);
518   /* High half word64 is syscall return value.  Low half is
519      the entire CR, from which we need to extract CR0.SO. */
520   res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
521#else
522# error Unknown platform
523#endif
524   return res;
525}
526
527static void setup_child ( /*OUT*/ ThreadArchState *child,
528                          /*IN*/  ThreadArchState *parent )
529{
530   /* We inherit our parent's guest state. */
531   child->vex = parent->vex;
532   child->vex_shadow1 = parent->vex_shadow1;
533   child->vex_shadow2 = parent->vex_shadow2;
534
535#if defined(VGP_x86_linux)
536   extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
537                                        /*IN*/  ThreadArchState *parent );
538   ML_(x86_setup_LDT_GDT)(child, parent);
539#endif
540}
541
542static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
543{
544   static const Bool debug = False;
545   ThreadState* ctst = VG_(get_ThreadState)(ctid);
546   // res is succesful by default, overriden if a real syscall is needed/done.
547   SysRes res = VG_(mk_SysRes_Success)(0);
548
549   if (debug)
550      VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
551
552#if defined(VGP_x86_linux)
553   vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
554   if (debug)
555      VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
556                  "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
557                  tlsinfo, tlsinfo->entry_number,
558                  tlsinfo->base_addr, tlsinfo->limit,
559                  ctst->arch.vex.guest_ESP,
560                  ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
561   res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
562#elif defined(VGP_amd64_linux)
563   ctst->arch.vex.guest_FS_CONST = tlsaddr;
564#elif defined(VGP_ppc32_linux)
565   ctst->arch.vex.guest_GPR2 = tlsaddr;
566#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
567   ctst->arch.vex.guest_GPR13 = tlsaddr;
568#elif defined(VGP_s390x_linux)
569   ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
570   ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
571#elif defined(VGP_arm64_linux)
572   /* Just assign the tls pointer in the guest TPIDR_EL0. */
573   ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
574#elif defined(VGP_arm_linux)
575   /* Just assign the tls pointer in the guest TPIDRURO. */
576   ctst->arch.vex.guest_TPIDRURO = tlsaddr;
577#elif defined(VGP_mips64_linux)
578   ctst->arch.vex.guest_ULR = tlsaddr;
579   ctst->arch.vex.guest_r27 = tlsaddr;
580#elif defined(VGP_mips32_linux)
581   ctst->arch.vex.guest_ULR = tlsaddr;
582   ctst->arch.vex.guest_r27 = tlsaddr;
583#else
584# error Unknown platform
585#endif
586   return res;
587}
588
589/*
590   When a client clones, we need to keep track of the new thread.  This means:
591   1. allocate a ThreadId+ThreadState+stack for the thread
592
593   2. initialize the thread's new VCPU state
594
595   3. create the thread using the same args as the client requested,
596   but using the scheduler entrypoint for EIP, and a separate stack
597   for ESP.
598 */
599static SysRes do_clone ( ThreadId ptid,
600                         UWord flags, Addr sp,
601                         Int* parent_tidptr,
602                         Int* child_tidptr,
603                         Addr tlsaddr)
604{
605   ThreadId     ctid = VG_(alloc_ThreadState)();
606   ThreadState* ptst = VG_(get_ThreadState)(ptid);
607   ThreadState* ctst = VG_(get_ThreadState)(ctid);
608   UWord*       stack;
609   SysRes       res;
610   vki_sigset_t blockall, savedmask;
611
612   VG_(sigfillset)(&blockall);
613
614   vg_assert(VG_(is_running_thread)(ptid));
615   vg_assert(VG_(is_valid_tid)(ctid));
616
617   stack = (UWord*)ML_(allocstack)(ctid);
618   if (stack == NULL) {
619      res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
620      goto out;
621   }
622
623   /* Copy register state
624
625      Both parent and child return to the same place, and the code
626      following the clone syscall works out which is which, so we
627      don't need to worry about it.
628
629      The parent gets the child's new tid returned from clone, but the
630      child gets 0.
631
632      If the clone call specifies a NULL sp for the new thread, then
633      it actually gets a copy of the parent's sp.
634   */
635   setup_child( &ctst->arch, &ptst->arch );
636
637   if (sp != 0)
638      VG_(set_SP)(ctid, sp);
639
640   ctst->os_state.parent = ptid;
641
642   /* inherit signal mask */
643   ctst->sig_mask     = ptst->sig_mask;
644   ctst->tmp_sig_mask = ptst->sig_mask;
645
646   /* Start the child with its threadgroup being the same as the
647      parent's.  This is so that any exit_group calls that happen
648      after the child is created but before it sets its
649      os_state.threadgroup field for real (in thread_wrapper in
650      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
651      a race condition in which the thread is unkillable (via
652      exit_group) because its threadgroup is not set.  The race window
653      is probably only a few hundred or a few thousand cycles long.
654      See #226116. */
655   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
656
657   ML_(guess_and_register_stack) (sp, ctst);
658
659   /* Assume the clone will succeed, and tell any tool that wants to
660      know that this thread has come into existence.  We cannot defer
661      it beyond this point because setup_tls, just below,
662      causes checks to assert by making references to the new ThreadId
663      if we don't state the new thread exists prior to that point.
664      If the clone fails, we'll send out a ll_exit notification for it
665      at the out: label below, to clean up. */
666   vg_assert(VG_(owns_BigLock_LL)(ptid));
667   VG_TRACK ( pre_thread_ll_create, ptid, ctid );
668
669   if (flags & VKI_CLONE_SETTLS) {
670      res = setup_child_tls(ctid, tlsaddr);
671      if (sr_isError(res))
672	 goto out;
673   }
674   flags &= ~VKI_CLONE_SETTLS;
675
676   /* start the thread with everything blocked */
677   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
678
679   /* Create the new thread */
680   res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
681                            child_tidptr, parent_tidptr);
682
683   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
684
685  out:
686   if (sr_isError(res)) {
687      /* clone failed */
688      VG_(cleanup_thread)(&ctst->arch);
689      ctst->status = VgTs_Empty;
690      /* oops.  Better tell the tool the thread exited in a hurry :-) */
691      VG_TRACK( pre_thread_ll_exit, ctid );
692   }
693
694   return res;
695}
696
697/* Do a clone which is really a fork().
698   ML_(do_fork_clone) uses the clone syscall to fork a child process.
699   Note that this should not be called for a thread creation.
700   Also, some flags combinations are not supported, and such combinations
701   are handled either by masking the non supported flags or by asserting.
702
703   The CLONE_VFORK flag is accepted, as this just tells that the parent is
704   suspended till the child exits or calls execve. We better keep this flag,
705   just in case the guests parent/client code depends on this synchronisation.
706
707   We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
708   instructions in the child process, that will mess up the parent host
709   memory. So, we hope for the best and assumes that the guest application does
710   not (really) depends on sharing the memory between parent and child in the
711   interval between clone and exits/execve.
712
713   If child_sp != 0, the child (guest) sp will be set to child_sp just after the
714   clone syscall, before child guest instructions are executed. */
715static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
716                                   Int* parent_tidptr, Int* child_tidptr,
717                                   Addr child_sp)
718{
719   vki_sigset_t fork_saved_mask;
720   vki_sigset_t mask;
721   SysRes       res;
722
723   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
724                | VKI_CLONE_FILES))
725      return VG_(mk_SysRes_Error)( VKI_EINVAL );
726
727   /* Block all signals during fork, so that we can fix things up in
728      the child without being interrupted. */
729   VG_(sigfillset)(&mask);
730   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
731
732   VG_(do_atfork_pre)(tid);
733
734   /* Since this is the fork() form of clone, we don't need all that
735      VG_(clone) stuff */
736#if defined(VGP_x86_linux) \
737    || defined(VGP_ppc32_linux) \
738    || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)	\
739    || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
740    || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
741   res = VG_(do_syscall5)( __NR_clone, flags,
742                           (UWord)NULL, (UWord)parent_tidptr,
743                           (UWord)NULL, (UWord)child_tidptr );
744#elif defined(VGP_amd64_linux)
745   /* note that the last two arguments are the opposite way round to x86 and
746      ppc32 as the amd64 kernel expects the arguments in a different order */
747   res = VG_(do_syscall5)( __NR_clone, flags,
748                           (UWord)NULL, (UWord)parent_tidptr,
749                           (UWord)child_tidptr, (UWord)NULL );
750#elif defined(VGP_s390x_linux)
751   /* Note that s390 has the stack first and then the flags */
752   res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
753                          (UWord)parent_tidptr, (UWord)child_tidptr);
754#else
755# error Unknown platform
756#endif
757
758   if (!sr_isError(res) && sr_Res(res) == 0) {
759      /* child */
760      if (child_sp != 0)
761          VG_(set_SP)(tid, child_sp);
762      VG_(do_atfork_child)(tid);
763
764      /* restore signal mask */
765      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
766   }
767   else
768   if (!sr_isError(res) && sr_Res(res) > 0) {
769      /* parent */
770      VG_(do_atfork_parent)(tid);
771
772      if (VG_(clo_trace_syscalls))
773	  VG_(printf)("   clone(fork): process %d created child %lu\n",
774                      VG_(getpid)(), sr_Res(res));
775
776      /* restore signal mask */
777      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
778   }
779
780   return res;
781}
782
783/* ---------------------------------------------------------------------
784   PRE/POST wrappers for arch-generic, Linux-specific syscalls
785   ------------------------------------------------------------------ */
786
787// Nb: See the comment above the generic PRE/POST wrappers in
788// m_syswrap/syswrap-generic.c for notes about how they work.
789
790#define PRE(name)       DEFN_PRE_TEMPLATE(linux, name)
791#define POST(name)      DEFN_POST_TEMPLATE(linux, name)
792
793PRE(sys_clone)
794{
795   UInt cloneflags;
796   Bool badarg = False;
797
798   PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
799
800// Order of arguments differs between platforms.
801#if defined(VGP_x86_linux) \
802    || defined(VGP_ppc32_linux) \
803    || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)	\
804    || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
805    || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
806#define ARG_CHILD_TIDPTR ARG5
807#define PRA_CHILD_TIDPTR PRA5
808#define ARG_TLS          ARG4
809#define PRA_TLS          PRA4
810#elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
811#define ARG_CHILD_TIDPTR ARG4
812#define PRA_CHILD_TIDPTR PRA4
813#define ARG_TLS          ARG5
814#define PRA_TLS          PRA5
815#else
816# error Unknown platform
817#endif
818// And s390x is even more special, and inverts flags and child stack args
819#if defined(VGP_s390x_linux)
820#define ARG_FLAGS       ARG2
821#define PRA_FLAGS       PRA2
822#define ARG_CHILD_STACK ARG1
823#define PRA_CHILD_STACK PRA1
824#else
825#define ARG_FLAGS       ARG1
826#define PRA_FLAGS       PRA1
827#define ARG_CHILD_STACK ARG2
828#define PRA_CHILD_STACK PRA2
829#endif
830
831   if (VG_(tdict).track_pre_reg_read) {
832      PRA_FLAGS("clone", unsigned long, flags);
833      PRA_CHILD_STACK("clone",  void *, child_stack);
834   }
835
836   if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID) {
837      if (VG_(tdict).track_pre_reg_read) {
838         PRA3("clone", int *, parent_tidptr);
839      }
840      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
841      if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
842                                             VKI_PROT_WRITE)) {
843         badarg = True;
844      }
845   }
846   if (ARG_FLAGS & VKI_CLONE_SETTLS) {
847      if (VG_(tdict).track_pre_reg_read) {
848         PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
849      }
850      /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
851         dummy type (that we define as a char). We only dereference/check the
852         ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
853      if (sizeof(vki_modify_ldt_t) > 1) {
854         PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
855         if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
856                                          VKI_PROT_READ)) {
857            badarg = True;
858         }
859      }
860   }
861   if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
862      if (VG_(tdict).track_pre_reg_read) {
863         PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
864      }
865      PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
866      if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
867                                             VKI_PROT_WRITE)) {
868         badarg = True;
869      }
870   }
871
872   if (badarg) {
873      SET_STATUS_Failure( VKI_EFAULT );
874      return;
875   }
876
877   cloneflags = ARG_FLAGS;
878
879   if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
880      SET_STATUS_Failure( VKI_EINVAL );
881      return;
882   }
883
884   /* Only look at the flags we really care about */
885   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
886                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
887   case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
888      /* thread creation */
889      SET_STATUS_from_SysRes(
890         do_clone(tid,
891                  ARG_FLAGS,               /* flags */
892                  (Addr)ARG_CHILD_STACK,   /* child ESP */
893                  (Int*)ARG3,              /* parent_tidptr */
894                  (Int*)ARG_CHILD_TIDPTR,  /* child_tidptr */
895                  (Addr)ARG_TLS));         /* set_tls */
896      break;
897
898   case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
899      // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
900      cloneflags &= ~VKI_CLONE_VM;
901
902   case 0: /* plain fork */
903      SET_STATUS_from_SysRes(
904         ML_(do_fork_clone)(tid,
905                       cloneflags,      /* flags */
906                       (Int*)ARG3,     /* parent_tidptr */
907                       (Int*)ARG_CHILD_TIDPTR,     /* child_tidptr */
908                       (Addr)ARG_CHILD_STACK));
909      break;
910
911   default:
912      /* should we just ENOSYS? */
913      VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG_FLAGS);
914      VG_(message)(Vg_UserMsg, "\n");
915      VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
916      VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
917      VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
918      VG_(unimplemented)
919         ("Valgrind does not support general clone().");
920   }
921
922   if (SUCCESS) {
923      if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID)
924         POST_MEM_WRITE(ARG3, sizeof(Int));
925      if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
926         POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
927
928      /* Thread creation was successful; let the child have the chance
929         to run */
930      *flags |= SfYieldAfter;
931   }
932
933#undef ARG_CHILD_TIDPTR
934#undef PRA_CHILD_TIDPTR
935#undef ARG_TLS
936#undef PRA_TLS
937#undef ARG_FLAGS
938#undef PRA_FLAGS
939#undef ARG_CHILD_STACK
940#undef PRA_CHILD_STACK
941}
942
943/* ---------------------------------------------------------------------
944   *mount wrappers
945   ------------------------------------------------------------------ */
946
947PRE(sys_mount)
948{
949   // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
950   // We are conservative and check everything, except the memory pointed to
951   // by 'data'.
952   *flags |= SfMayBlock;
953   PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx(%s), %#lx, %#lx )",
954         ARG1,(HChar*)ARG1, ARG2,(HChar*)ARG2, ARG3,(HChar*)ARG3, ARG4, ARG5);
955   PRE_REG_READ5(long, "mount",
956                 char *, source, char *, target, char *, type,
957                 unsigned long, flags, void *, data);
958   if (ARG1)
959      PRE_MEM_RASCIIZ( "mount(source)", ARG1);
960   PRE_MEM_RASCIIZ( "mount(target)", ARG2);
961   PRE_MEM_RASCIIZ( "mount(type)", ARG3);
962}
963
964PRE(sys_oldumount)
965{
966   PRINT("sys_oldumount( %#lx )", ARG1);
967   PRE_REG_READ1(long, "umount", char *, path);
968   PRE_MEM_RASCIIZ( "umount(path)", ARG1);
969}
970
971PRE(sys_umount)
972{
973   PRINT("sys_umount( %#lx, %ld )", ARG1, SARG2);
974   PRE_REG_READ2(long, "umount2", char *, path, int, flags);
975   PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
976}
977
978/* Not actually wrapped by GLibc but does things with the system
979 * mounts so it is put here.
980 */
981PRE(sys_pivot_root)
982{
983   PRINT("sys_pivot_root ( %s %s )", (HChar*)ARG1, (HChar*)ARG2);
984   PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
985   PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
986   PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
987}
988
989
990/* ---------------------------------------------------------------------
991   16- and 32-bit uid/gid wrappers
992   ------------------------------------------------------------------ */
993
994PRE(sys_setfsuid16)
995{
996   PRINT("sys_setfsuid16 ( %lu )", ARG1);
997   PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
998}
999
1000PRE(sys_setfsuid)
1001{
1002   PRINT("sys_setfsuid ( %lu )", ARG1);
1003   PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1004}
1005
1006PRE(sys_setfsgid16)
1007{
1008   PRINT("sys_setfsgid16 ( %lu )", ARG1);
1009   PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1010}
1011
1012PRE(sys_setfsgid)
1013{
1014   PRINT("sys_setfsgid ( %lu )", ARG1);
1015   PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1016}
1017
1018PRE(sys_setresuid16)
1019{
1020   PRINT("sys_setresuid16 ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1021   PRE_REG_READ3(long, "setresuid16",
1022                 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1023}
1024
1025PRE(sys_setresuid)
1026{
1027   PRINT("sys_setresuid ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1028   PRE_REG_READ3(long, "setresuid",
1029                 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1030}
1031
1032PRE(sys_getresuid16)
1033{
1034   PRINT("sys_getresuid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1035   PRE_REG_READ3(long, "getresuid16",
1036                 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1037                 vki_old_uid_t *, suid);
1038   PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1039   PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1040   PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1041}
1042POST(sys_getresuid16)
1043{
1044   vg_assert(SUCCESS);
1045   if (RES == 0) {
1046      POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1047      POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1048      POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1049   }
1050}
1051
1052PRE(sys_getresuid)
1053{
1054   PRINT("sys_getresuid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1055   PRE_REG_READ3(long, "getresuid",
1056                 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1057   PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1058   PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1059   PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1060}
1061POST(sys_getresuid)
1062{
1063   vg_assert(SUCCESS);
1064   if (RES == 0) {
1065      POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1066      POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1067      POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1068   }
1069}
1070
1071PRE(sys_setresgid16)
1072{
1073   PRINT("sys_setresgid16 ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1074   PRE_REG_READ3(long, "setresgid16",
1075                 vki_old_gid_t, rgid,
1076                 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1077}
1078
1079PRE(sys_setresgid)
1080{
1081   PRINT("sys_setresgid ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1082   PRE_REG_READ3(long, "setresgid",
1083                 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1084}
1085
1086PRE(sys_getresgid16)
1087{
1088   PRINT("sys_getresgid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1089   PRE_REG_READ3(long, "getresgid16",
1090                 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1091                 vki_old_gid_t *, sgid);
1092   PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1093   PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1094   PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1095}
1096POST(sys_getresgid16)
1097{
1098   vg_assert(SUCCESS);
1099   if (RES == 0) {
1100      POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1101      POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1102      POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1103   }
1104}
1105
1106PRE(sys_getresgid)
1107{
1108   PRINT("sys_getresgid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1109   PRE_REG_READ3(long, "getresgid",
1110                 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1111   PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1112   PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1113   PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1114}
1115POST(sys_getresgid)
1116{
1117   vg_assert(SUCCESS);
1118   if (RES == 0) {
1119      POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1120      POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1121      POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1122   }
1123}
1124
1125/* ---------------------------------------------------------------------
1126   miscellaneous wrappers
1127   ------------------------------------------------------------------ */
1128
1129PRE(sys_exit_group)
1130{
1131   ThreadId     t;
1132   ThreadState* tst;
1133
1134   PRINT("exit_group( %ld )", SARG1);
1135   PRE_REG_READ1(void, "exit_group", int, status);
1136
1137   tst = VG_(get_ThreadState)(tid);
1138   /* A little complex; find all the threads with the same threadgroup
1139      as this one (including this one), and mark them to exit */
1140   /* It is unclear how one can get a threadgroup in this process which
1141      is not the threadgroup of the calling thread:
1142      The assignments to threadgroups are:
1143        = 0; /// scheduler.c os_state_clear
1144        = getpid(); /// scheduler.c in child after fork
1145        = getpid(); /// this file, in thread_wrapper
1146        = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1147                           copying the thread group of the thread doing clone
1148      So, the only case where the threadgroup might be different to the getpid
1149      value is in the child, just after fork. But then the fork syscall is
1150      still going on, the forked thread has had no chance yet to make this
1151      syscall. */
1152   for (t = 1; t < VG_N_THREADS; t++) {
1153      if ( /* not alive */
1154           VG_(threads)[t].status == VgTs_Empty
1155           ||
1156	   /* not our group */
1157           VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1158         )
1159         continue;
1160      /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1161         the exitreason. */
1162      VG_(threads)[t].os_state.exitcode = ARG1;
1163   }
1164
1165   /* Indicate in all other threads that the process is exiting.
1166      Then wait using VG_(reap_threads) for these threads to disappear.
1167
1168      Can this give a deadlock if another thread is calling exit in parallel
1169      and would then wait for this thread to disappear ?
1170      The answer is no:
1171      Other threads are either blocked in a syscall or have yielded the CPU.
1172
1173      A thread that has yielded the CPU is trying to get the big lock in
1174      VG_(scheduler). This thread will get the CPU thanks to the call
1175      to VG_(reap_threads). The scheduler will then check for signals,
1176      kill the process if this is a fatal signal, and otherwise prepare
1177      the thread for handling this signal. After this preparation, if
1178      the thread status is VG_(is_exiting), the scheduler exits the thread.
1179      So, a thread that has yielded the CPU does not have a chance to
1180      call exit => no deadlock for this thread.
1181
1182      VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1183      to all threads blocked in a syscall.
1184      The syscall will be interrupted, and the control will go to the
1185      scheduler. The scheduler will then return, as the thread is in
1186      exiting state. */
1187
1188   VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1189   VG_(reap_threads)(tid);
1190   VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1191   /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1192      is the thread calling exit_group and so its registers must be considered
1193      as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1194
1195   /* We have to claim the syscall already succeeded. */
1196   SET_STATUS_Success(0);
1197}
1198
1199PRE(sys_llseek)
1200{
1201   PRINT("sys_llseek ( %lu, 0x%lx, 0x%lx, %#lx, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5);
1202   PRE_REG_READ5(long, "llseek",
1203                 unsigned int, fd, unsigned long, offset_high,
1204                 unsigned long, offset_low, vki_loff_t *, result,
1205                 unsigned int, whence);
1206   if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1207      SET_STATUS_Failure( VKI_EBADF );
1208   else
1209      PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1210}
1211POST(sys_llseek)
1212{
1213   vg_assert(SUCCESS);
1214   if (RES == 0)
1215      POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1216}
1217
1218PRE(sys_adjtimex)
1219{
1220   struct vki_timex *tx = (struct vki_timex *)ARG1;
1221   PRINT("sys_adjtimex ( %#lx )", ARG1);
1222   PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1223
1224   if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1225      PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1226
1227#define ADJX(bits,field) 				\
1228         if (tx->modes & (bits))                              \
1229         PRE_MEM_READ( "adjtimex(timex->"#field")",	\
1230		       (Addr)&tx->field, sizeof(tx->field))
1231
1232      if (tx->modes & VKI_ADJ_ADJTIME) {
1233         if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1234            PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1235      } else {
1236         ADJX(VKI_ADJ_OFFSET, offset);
1237         ADJX(VKI_ADJ_FREQUENCY, freq);
1238         ADJX(VKI_ADJ_MAXERROR, maxerror);
1239         ADJX(VKI_ADJ_ESTERROR, esterror);
1240         ADJX(VKI_ADJ_STATUS, status);
1241         ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1242         ADJX(VKI_ADJ_TICK, tick);
1243      }
1244#undef ADJX
1245   }
1246
1247   PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1248}
1249
1250POST(sys_adjtimex)
1251{
1252   POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1253}
1254
1255PRE(sys_clock_adjtime)
1256{
1257   struct vki_timex *tx = (struct vki_timex *)ARG2;
1258   PRINT("sys_clock_adjtime ( %ld, %#lx )", SARG1,ARG2);
1259   PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1260   PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1261
1262#define ADJX(bits,field)                                \
1263   if (tx->modes & (bits))                              \
1264      PRE_MEM_READ( "clock_adjtime(timex->"#field")",   \
1265                    (Addr)&tx->field, sizeof(tx->field))
1266
1267   if (tx->modes & VKI_ADJ_ADJTIME) {
1268      if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1269         PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1270   } else {
1271      ADJX(VKI_ADJ_OFFSET, offset);
1272      ADJX(VKI_ADJ_FREQUENCY, freq);
1273      ADJX(VKI_ADJ_MAXERROR, maxerror);
1274      ADJX(VKI_ADJ_ESTERROR, esterror);
1275      ADJX(VKI_ADJ_STATUS, status);
1276      ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1277      ADJX(VKI_ADJ_TICK, tick);
1278   }
1279#undef ADJX
1280
1281   PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1282}
1283
1284POST(sys_clock_adjtime)
1285{
1286   POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1287}
1288
1289PRE(sys_ioperm)
1290{
1291   PRINT("sys_ioperm ( %lu, %lu, %ld )", ARG1, ARG2, SARG3 );
1292   PRE_REG_READ3(long, "ioperm",
1293                 unsigned long, from, unsigned long, num, int, turn_on);
1294}
1295
1296PRE(sys_syslog)
1297{
1298   *flags |= SfMayBlock;
1299   PRINT("sys_syslog (%ld, %#lx, %ld)", SARG1, ARG2, SARG3);
1300   PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1301   switch (ARG1) {
1302   // The kernel uses magic numbers here, rather than named constants,
1303   // therefore so do we.
1304   case 2: case 3: case 4:
1305      PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1306      break;
1307   default:
1308      break;
1309   }
1310}
1311POST(sys_syslog)
1312{
1313   switch (ARG1) {
1314   case 2: case 3: case 4:
1315      POST_MEM_WRITE( ARG2, ARG3 );
1316      break;
1317   default:
1318      break;
1319   }
1320}
1321
1322PRE(sys_vhangup)
1323{
1324   PRINT("sys_vhangup ( )");
1325   PRE_REG_READ0(long, "vhangup");
1326}
1327
1328PRE(sys_sysinfo)
1329{
1330   PRINT("sys_sysinfo ( %#lx )",ARG1);
1331   PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1332   PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1333}
1334POST(sys_sysinfo)
1335{
1336   POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1337}
1338
1339PRE(sys_personality)
1340{
1341   PRINT("sys_personality ( %llu )", (ULong)ARG1);
1342   PRE_REG_READ1(long, "personality", vki_u_long, persona);
1343}
1344
1345PRE(sys_sysctl)
1346{
1347   struct __vki_sysctl_args *args;
1348   PRINT("sys_sysctl ( %#lx )", ARG1 );
1349   args = (struct __vki_sysctl_args *)ARG1;
1350   PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1351   PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1352   if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1353                                          VKI_PROT_READ)) {
1354      SET_STATUS_Failure( VKI_EFAULT );
1355      return;
1356   }
1357
1358   PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1359   if (args->newval != NULL)
1360      PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1361   if (args->oldlenp != NULL) {
1362      PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1363      PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1364   }
1365}
1366POST(sys_sysctl)
1367{
1368   struct __vki_sysctl_args *args;
1369   args = (struct __vki_sysctl_args *)ARG1;
1370   if (args->oldlenp != NULL) {
1371      POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1372      POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1373   }
1374}
1375
1376PRE(sys_prctl)
1377{
1378   *flags |= SfMayBlock;
1379   PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1380   switch (ARG1) {
1381   case VKI_PR_SET_PDEATHSIG:
1382      PRE_REG_READ2(int, "prctl", int, option, int, signal);
1383      break;
1384   case VKI_PR_GET_PDEATHSIG:
1385      PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1386      PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1387      break;
1388   case VKI_PR_GET_DUMPABLE:
1389      PRE_REG_READ1(int, "prctl", int, option);
1390      break;
1391   case VKI_PR_SET_DUMPABLE:
1392      PRE_REG_READ2(int, "prctl", int, option, int, dump);
1393      break;
1394   case VKI_PR_GET_UNALIGN:
1395      PRE_REG_READ2(int, "prctl", int, option, int *, value);
1396      PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1397      break;
1398   case VKI_PR_SET_UNALIGN:
1399      PRE_REG_READ2(int, "prctl", int, option, int, value);
1400      break;
1401   case VKI_PR_GET_KEEPCAPS:
1402      PRE_REG_READ1(int, "prctl", int, option);
1403      break;
1404   case VKI_PR_SET_KEEPCAPS:
1405      PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1406      break;
1407   case VKI_PR_GET_FPEMU:
1408      PRE_REG_READ2(int, "prctl", int, option, int *, value);
1409      PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1410      break;
1411   case VKI_PR_SET_FPEMU:
1412      PRE_REG_READ2(int, "prctl", int, option, int, value);
1413      break;
1414   case VKI_PR_GET_FPEXC:
1415      PRE_REG_READ2(int, "prctl", int, option, int *, value);
1416      PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1417      break;
1418   case VKI_PR_SET_FPEXC:
1419      PRE_REG_READ2(int, "prctl", int, option, int, value);
1420      break;
1421   case VKI_PR_GET_TIMING:
1422      PRE_REG_READ1(int, "prctl", int, option);
1423      break;
1424   case VKI_PR_SET_TIMING:
1425      PRE_REG_READ2(int, "prctl", int, option, int, timing);
1426      break;
1427   case VKI_PR_SET_NAME:
1428      PRE_REG_READ2(int, "prctl", int, option, char *, name);
1429      /* The name can be up to TASK_COMM_LEN(16) bytes long, including
1430         the terminating null byte. So do not check more than 16 bytes. */
1431      if (ML_(safe_to_deref)((const HChar *) ARG2, VKI_TASK_COMM_LEN)) {
1432         SizeT len = VG_(strnlen)((const HChar *) ARG2, VKI_TASK_COMM_LEN);
1433         if (len < VKI_TASK_COMM_LEN) {
1434            PRE_MEM_RASCIIZ("prctl(set-name)", ARG2);
1435         } else {
1436            PRE_MEM_READ("prctl(set-name)", ARG2, VKI_TASK_COMM_LEN);
1437         }
1438      } else {
1439         /* Do it the slow way, one byte at a time, while checking for
1440            terminating '\0'. */
1441         const HChar *name = (const HChar *) ARG2;
1442         for (UInt i = 0; i < VKI_TASK_COMM_LEN; i++) {
1443            PRE_MEM_READ("prctl(set-name)", (Addr) &name[i], 1);
1444            if (!ML_(safe_to_deref)(&name[i], 1) || name[i] == '\0') {
1445               break;
1446            }
1447         }
1448      }
1449      break;
1450   case VKI_PR_GET_NAME:
1451      PRE_REG_READ2(int, "prctl", int, option, char *, name);
1452      PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1453      break;
1454   case VKI_PR_GET_ENDIAN:
1455      PRE_REG_READ2(int, "prctl", int, option, int *, value);
1456      PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1457      break;
1458   case VKI_PR_SET_ENDIAN:
1459      PRE_REG_READ2(int, "prctl", int, option, int, value);
1460      break;
1461   case VKI_PR_SET_PTRACER:
1462      PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1463      break;
1464   case VKI_PR_SET_SECCOMP:
1465      /* This is a bit feeble in that it uses |option| before checking
1466         it, but at least both sides of the conditional check it. */
1467      if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1468         PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1469         if (ARG3) {
1470            /* Should check that ARG3 points at a valid struct sock_fprog.
1471               Sounds complex; hence be lame. */
1472            PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1473                          ARG3, 1 );
1474         }
1475      } else {
1476         PRE_REG_READ2(int, "prctl", int, option, int, mode);
1477      }
1478      break;
1479   default:
1480      PRE_REG_READ5(long, "prctl",
1481                    int, option, unsigned long, arg2, unsigned long, arg3,
1482                    unsigned long, arg4, unsigned long, arg5);
1483      break;
1484   }
1485}
1486POST(sys_prctl)
1487{
1488   switch (ARG1) {
1489   case VKI_PR_GET_PDEATHSIG:
1490      POST_MEM_WRITE(ARG2, sizeof(Int));
1491      break;
1492   case VKI_PR_GET_UNALIGN:
1493      POST_MEM_WRITE(ARG2, sizeof(Int));
1494      break;
1495   case VKI_PR_GET_FPEMU:
1496      POST_MEM_WRITE(ARG2, sizeof(Int));
1497      break;
1498   case VKI_PR_GET_FPEXC:
1499      POST_MEM_WRITE(ARG2, sizeof(Int));
1500      break;
1501   case VKI_PR_GET_NAME:
1502      POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1503      break;
1504   case VKI_PR_GET_ENDIAN:
1505      POST_MEM_WRITE(ARG2, sizeof(Int));
1506      break;
1507   case VKI_PR_SET_NAME:
1508      {
1509         const HChar* new_name = (const HChar*) ARG2;
1510         if (new_name) {    // Paranoia
1511            ThreadState* tst = VG_(get_ThreadState)(tid);
1512            SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1513
1514            /* Don't bother reusing the memory. This is a rare event. */
1515            tst->thread_name =
1516              VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1517            VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1518         }
1519      }
1520      break;
1521   }
1522}
1523
1524PRE(sys_sendfile)
1525{
1526   *flags |= SfMayBlock;
1527   PRINT("sys_sendfile ( %ld, %ld, %#lx, %lu )", SARG1,SARG2,ARG3,ARG4);
1528   PRE_REG_READ4(ssize_t, "sendfile",
1529                 int, out_fd, int, in_fd, vki_off_t *, offset,
1530                 vki_size_t, count);
1531   if (ARG3 != 0)
1532      PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1533}
1534POST(sys_sendfile)
1535{
1536   if (ARG3 != 0 ) {
1537      POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1538   }
1539}
1540
1541PRE(sys_sendfile64)
1542{
1543   *flags |= SfMayBlock;
1544   PRINT("sendfile64 ( %ld, %ld, %#lx, %lu )",SARG1,SARG2,ARG3,ARG4);
1545   PRE_REG_READ4(ssize_t, "sendfile64",
1546                 int, out_fd, int, in_fd, vki_loff_t *, offset,
1547                 vki_size_t, count);
1548   if (ARG3 != 0)
1549      PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1550}
1551POST(sys_sendfile64)
1552{
1553   if (ARG3 != 0 ) {
1554      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1555   }
1556}
1557
1558PRE(sys_futex)
1559{
1560   /*
1561      arg    param                              used by ops
1562
1563      ARG1 - u32 *futex				all
1564      ARG2 - int op
1565      ARG3 - int val				WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1566      ARG4 - struct timespec *utime		WAIT:time*	REQUEUE,CMP_REQUEUE:val2
1567      ARG5 - u32 *uaddr2			REQUEUE,CMP_REQUEUE
1568      ARG6 - int val3				CMP_REQUEUE
1569    */
1570   PRINT("sys_futex ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,SARG2,SARG3,ARG4,ARG5);
1571   switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1572   case VKI_FUTEX_CMP_REQUEUE:
1573   case VKI_FUTEX_WAKE_OP:
1574   case VKI_FUTEX_CMP_REQUEUE_PI:
1575      PRE_REG_READ6(long, "futex",
1576                    vki_u32 *, futex, int, op, int, val,
1577                    struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1578      break;
1579   case VKI_FUTEX_REQUEUE:
1580   case VKI_FUTEX_WAIT_REQUEUE_PI:
1581      PRE_REG_READ5(long, "futex",
1582                    vki_u32 *, futex, int, op, int, val,
1583                    struct timespec *, utime, vki_u32 *, uaddr2);
1584      break;
1585   case VKI_FUTEX_WAIT_BITSET:
1586      /* Check that the address at least begins in client-accessible area. */
1587      if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1588            SET_STATUS_Failure( VKI_EFAULT );
1589            return;
1590      }
1591      if (*(vki_u32 *)ARG1 != ARG3) {
1592         PRE_REG_READ4(long, "futex",
1593                       vki_u32 *, futex, int, op, int, val,
1594                       struct timespec *, utime);
1595      } else {
1596        /* Note argument 5 is unused, but argument 6 is used.
1597           So we cannot just PRE_REG_READ6. Read argument 6 separately.  */
1598         PRE_REG_READ4(long, "futex",
1599                       vki_u32 *, futex, int, op, int, val,
1600                       struct timespec *, utime);
1601         if (VG_(tdict).track_pre_reg_read)
1602            PRA6("futex",int,val3);
1603      }
1604      break;
1605   case VKI_FUTEX_WAKE_BITSET:
1606      PRE_REG_READ3(long, "futex",
1607                    vki_u32 *, futex, int, op, int, val);
1608      if (VG_(tdict).track_pre_reg_read) {
1609         PRA6("futex", int, val3);
1610      }
1611      break;
1612   case VKI_FUTEX_WAIT:
1613   case VKI_FUTEX_LOCK_PI:
1614      PRE_REG_READ4(long, "futex",
1615                    vki_u32 *, futex, int, op, int, val,
1616                    struct timespec *, utime);
1617      break;
1618   case VKI_FUTEX_WAKE:
1619   case VKI_FUTEX_FD:
1620      PRE_REG_READ3(long, "futex",
1621                    vki_u32 *, futex, int, op, int, val);
1622      break;
1623   case VKI_FUTEX_TRYLOCK_PI:
1624   case VKI_FUTEX_UNLOCK_PI:
1625   default:
1626      PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1627      break;
1628   }
1629
1630   *flags |= SfMayBlock;
1631
1632   switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1633   case VKI_FUTEX_WAIT:
1634   case VKI_FUTEX_LOCK_PI:
1635   case VKI_FUTEX_WAIT_BITSET:
1636   case VKI_FUTEX_WAIT_REQUEUE_PI:
1637      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1638      if (ARG4 != 0)
1639	 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1640      break;
1641
1642   case VKI_FUTEX_REQUEUE:
1643   case VKI_FUTEX_CMP_REQUEUE:
1644   case VKI_FUTEX_CMP_REQUEUE_PI:
1645   case VKI_FUTEX_WAKE_OP:
1646      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1647      PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1648      break;
1649
1650   case VKI_FUTEX_FD:
1651   case VKI_FUTEX_TRYLOCK_PI:
1652   case VKI_FUTEX_UNLOCK_PI:
1653   case VKI_FUTEX_WAKE:
1654   case VKI_FUTEX_WAKE_BITSET:
1655      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1656     break;
1657
1658   default:
1659      SET_STATUS_Failure( VKI_ENOSYS );   // some futex function we don't understand
1660      break;
1661   }
1662}
1663POST(sys_futex)
1664{
1665   vg_assert(SUCCESS);
1666   POST_MEM_WRITE( ARG1, sizeof(int) );
1667   if (ARG2 == VKI_FUTEX_FD) {
1668      if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1669         VG_(close)(RES);
1670         SET_STATUS_Failure( VKI_EMFILE );
1671      } else {
1672         if (VG_(clo_track_fds))
1673            ML_(record_fd_open_nameless)(tid, RES);
1674      }
1675   }
1676}
1677
1678PRE(sys_set_robust_list)
1679{
1680   PRINT("sys_set_robust_list ( %#lx, %lu )", ARG1,ARG2);
1681   PRE_REG_READ2(long, "set_robust_list",
1682                 struct vki_robust_list_head *, head, vki_size_t, len);
1683
1684   /* Just check the robust_list_head structure is readable - don't
1685      try and chase the list as the kernel will only read it when
1686      the thread exits so the current contents is irrelevant. */
1687   if (ARG1 != 0)
1688      PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1689}
1690
1691PRE(sys_get_robust_list)
1692{
1693   PRINT("sys_get_robust_list ( %ld, %#lx, %#lx )", SARG1,ARG2,ARG3);
1694   PRE_REG_READ3(long, "get_robust_list",
1695                 int, pid,
1696                 struct vki_robust_list_head **, head_ptr,
1697                 vki_size_t *, len_ptr);
1698   PRE_MEM_WRITE("get_robust_list(head_ptr)",
1699                 ARG2, sizeof(struct vki_robust_list_head *));
1700   PRE_MEM_WRITE("get_robust_list(len_ptr)",
1701                 ARG3, sizeof(struct vki_size_t *));
1702}
1703POST(sys_get_robust_list)
1704{
1705   POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1706   POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1707}
1708
1709struct pselect_sized_sigset {
1710    const vki_sigset_t *ss;
1711    vki_size_t ss_len;
1712};
1713struct pselect_adjusted_sigset {
1714    struct pselect_sized_sigset ss; /* The actual syscall arg */
1715    vki_sigset_t adjusted_ss;
1716};
1717
1718PRE(sys_pselect6)
1719{
1720   *flags |= SfMayBlock | SfPostOnFail;
1721   PRINT("sys_pselect6 ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )",
1722         SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1723   PRE_REG_READ6(long, "pselect6",
1724                 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1725                 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1726                 void *, sig);
1727   // XXX: this possibly understates how much memory is read.
1728   if (ARG2 != 0)
1729      PRE_MEM_READ( "pselect6(readfds)",
1730		     ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1731   if (ARG3 != 0)
1732      PRE_MEM_READ( "pselect6(writefds)",
1733		     ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1734   if (ARG4 != 0)
1735      PRE_MEM_READ( "pselect6(exceptfds)",
1736		     ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1737   if (ARG5 != 0)
1738      PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1739   if (ARG6 != 0) {
1740      const struct pselect_sized_sigset *pss =
1741          (struct pselect_sized_sigset *)ARG6;
1742      PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1743      if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1744         ARG6 = 1; /* Something recognisable to POST() hook. */
1745      } else {
1746         struct pselect_adjusted_sigset *pas;
1747         pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1748         ARG6 = (Addr)pas;
1749         pas->ss.ss = (void *)1;
1750         pas->ss.ss_len = pss->ss_len;
1751         if (pss->ss_len == sizeof(*pss->ss)) {
1752            if (pss->ss == NULL) {
1753               pas->ss.ss = NULL;
1754            } else {
1755               PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1756               if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1757                  pas->adjusted_ss = *pss->ss;
1758                  pas->ss.ss = &pas->adjusted_ss;
1759                  VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1760               }
1761            }
1762         }
1763      }
1764   }
1765}
1766POST(sys_pselect6)
1767{
1768   if (ARG6 != 0 && ARG6 != 1) {
1769       VG_(free)((struct pselect_adjusted_sigset *)ARG6);
1770   }
1771}
1772
1773PRE(sys_ppoll)
1774{
1775   UInt i;
1776   struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1777   *flags |= SfMayBlock | SfPostOnFail;
1778   PRINT("sys_ppoll ( %#lx, %lu, %#lx, %#lx, %lu )\n", ARG1,ARG2,ARG3,ARG4,ARG5);
1779   PRE_REG_READ5(long, "ppoll",
1780                 struct vki_pollfd *, ufds, unsigned int, nfds,
1781                 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1782                 vki_size_t, sigsetsize);
1783
1784   for (i = 0; i < ARG2; i++) {
1785      PRE_MEM_READ( "ppoll(ufds.fd)",
1786                    (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1787      PRE_MEM_READ( "ppoll(ufds.events)",
1788                    (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1789      PRE_MEM_WRITE( "ppoll(ufds.revents)",
1790                     (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1791   }
1792
1793   if (ARG3)
1794      PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1795   if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1796      const vki_sigset_t *guest_sigmask = (vki_sigset_t *)ARG4;
1797      PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1798      if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1799         ARG4 = 1; /* Something recognisable to POST() hook. */
1800      } else {
1801         vki_sigset_t *vg_sigmask =
1802             VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
1803         ARG4 = (Addr)vg_sigmask;
1804         *vg_sigmask = *guest_sigmask;
1805         VG_(sanitize_client_sigmask)(vg_sigmask);
1806      }
1807   }
1808}
1809
1810POST(sys_ppoll)
1811{
1812   vg_assert(SUCCESS || FAILURE);
1813   if (SUCCESS && (RES >= 0)) {
1814      UInt i;
1815      struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1816      for (i = 0; i < ARG2; i++)
1817	 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1818   }
1819   if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
1820      VG_(free)((vki_sigset_t *) ARG4);
1821   }
1822}
1823
1824
1825/* ---------------------------------------------------------------------
1826   epoll_* wrappers
1827   ------------------------------------------------------------------ */
1828
1829PRE(sys_epoll_create)
1830{
1831   PRINT("sys_epoll_create ( %ld )", SARG1);
1832   PRE_REG_READ1(long, "epoll_create", int, size);
1833}
1834POST(sys_epoll_create)
1835{
1836   vg_assert(SUCCESS);
1837   if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1838      VG_(close)(RES);
1839      SET_STATUS_Failure( VKI_EMFILE );
1840   } else {
1841      if (VG_(clo_track_fds))
1842         ML_(record_fd_open_nameless) (tid, RES);
1843   }
1844}
1845
1846PRE(sys_epoll_create1)
1847{
1848   PRINT("sys_epoll_create1 ( %ld )", SARG1);
1849   PRE_REG_READ1(long, "epoll_create1", int, flags);
1850}
1851POST(sys_epoll_create1)
1852{
1853   vg_assert(SUCCESS);
1854   if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1855      VG_(close)(RES);
1856      SET_STATUS_Failure( VKI_EMFILE );
1857   } else {
1858      if (VG_(clo_track_fds))
1859         ML_(record_fd_open_nameless) (tid, RES);
1860   }
1861}
1862
1863PRE(sys_epoll_ctl)
1864{
1865   static const HChar* epoll_ctl_s[3] = {
1866      "EPOLL_CTL_ADD",
1867      "EPOLL_CTL_DEL",
1868      "EPOLL_CTL_MOD"
1869   };
1870   PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#lx )",
1871         SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
1872   PRE_REG_READ4(long, "epoll_ctl",
1873                 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1874   if (ARG2 != VKI_EPOLL_CTL_DEL)
1875      PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1876}
1877
1878PRE(sys_epoll_wait)
1879{
1880   *flags |= SfMayBlock;
1881   PRINT("sys_epoll_wait ( %ld, %#lx, %ld, %ld )", SARG1, ARG2, SARG3, SARG4);
1882   PRE_REG_READ4(long, "epoll_wait",
1883                 int, epfd, struct vki_epoll_event *, events,
1884                 int, maxevents, int, timeout);
1885   PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1886}
1887POST(sys_epoll_wait)
1888{
1889   vg_assert(SUCCESS);
1890   if (RES > 0)
1891      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1892}
1893
1894PRE(sys_epoll_pwait)
1895{
1896   *flags |= SfMayBlock;
1897   PRINT("sys_epoll_pwait ( %ld, %#lx, %ld, %ld, %#lx, %lu )",
1898         SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
1899   PRE_REG_READ6(long, "epoll_pwait",
1900                 int, epfd, struct vki_epoll_event *, events,
1901                 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1902                 vki_size_t, sigsetsize);
1903   PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1904   if (ARG4)
1905      PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1906}
1907POST(sys_epoll_pwait)
1908{
1909   vg_assert(SUCCESS);
1910   if (RES > 0)
1911      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1912}
1913
1914PRE(sys_eventfd)
1915{
1916   PRINT("sys_eventfd ( %lu )", ARG1);
1917   PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1918}
1919POST(sys_eventfd)
1920{
1921   if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1922      VG_(close)(RES);
1923      SET_STATUS_Failure( VKI_EMFILE );
1924   } else {
1925      if (VG_(clo_track_fds))
1926         ML_(record_fd_open_nameless) (tid, RES);
1927   }
1928}
1929
1930PRE(sys_eventfd2)
1931{
1932   PRINT("sys_eventfd2 ( %lu, %ld )", ARG1, SARG2);
1933   PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1934}
1935POST(sys_eventfd2)
1936{
1937   if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1938      VG_(close)(RES);
1939      SET_STATUS_Failure( VKI_EMFILE );
1940   } else {
1941      if (VG_(clo_track_fds))
1942         ML_(record_fd_open_nameless) (tid, RES);
1943   }
1944}
1945
1946PRE(sys_fallocate)
1947{
1948   *flags |= SfMayBlock;
1949#if VG_WORDSIZE == 4
1950   PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1951         SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
1952   PRE_REG_READ6(long, "fallocate",
1953                 int, fd, int, mode,
1954                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1955                 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1956#elif VG_WORDSIZE == 8
1957   PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
1958         SARG1, SARG2, SARG3, SARG4);
1959   PRE_REG_READ4(long, "fallocate",
1960                 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1961#else
1962#  error Unexpected word size
1963#endif
1964   if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
1965      SET_STATUS_Failure( VKI_EBADF );
1966}
1967
1968PRE(sys_prlimit64)
1969{
1970   PRINT("sys_prlimit64 ( %ld, %lu, %#lx, %#lx )", SARG1,ARG2,ARG3,ARG4);
1971   PRE_REG_READ4(long, "prlimit64",
1972                 vki_pid_t, pid, unsigned int, resource,
1973                 const struct rlimit64 *, new_rlim,
1974                 struct rlimit64 *, old_rlim);
1975   if (ARG3)
1976      PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
1977   if (ARG4)
1978      PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
1979
1980   if (ARG3 &&
1981       ((struct vki_rlimit64 *)ARG3)->rlim_cur > ((struct vki_rlimit64 *)ARG3)->rlim_max) {
1982      SET_STATUS_Failure( VKI_EINVAL );
1983   }
1984   else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
1985      switch (ARG2) {
1986      case VKI_RLIMIT_NOFILE:
1987         SET_STATUS_Success( 0 );
1988         if (ARG4) {
1989            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(fd_soft_limit);
1990            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(fd_hard_limit);
1991         }
1992         if (ARG3) {
1993            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(fd_hard_limit) ||
1994                ((struct vki_rlimit64 *)ARG3)->rlim_max != VG_(fd_hard_limit)) {
1995               SET_STATUS_Failure( VKI_EPERM );
1996            }
1997            else {
1998               VG_(fd_soft_limit) = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1999            }
2000         }
2001         break;
2002
2003      case VKI_RLIMIT_DATA:
2004         SET_STATUS_Success( 0 );
2005         if (ARG4) {
2006            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_data).rlim_cur;
2007            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_data).rlim_max;
2008         }
2009         if (ARG3) {
2010            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_data).rlim_max ||
2011                ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_data).rlim_max) {
2012               SET_STATUS_Failure( VKI_EPERM );
2013            }
2014            else {
2015               VG_(client_rlimit_data).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2016               VG_(client_rlimit_data).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
2017            }
2018         }
2019         break;
2020
2021      case VKI_RLIMIT_STACK:
2022         SET_STATUS_Success( 0 );
2023         if (ARG4) {
2024            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_stack).rlim_cur;
2025            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_stack).rlim_max;
2026         }
2027         if (ARG3) {
2028            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_stack).rlim_max ||
2029                ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_stack).rlim_max) {
2030               SET_STATUS_Failure( VKI_EPERM );
2031            }
2032            else {
2033               VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2034               VG_(client_rlimit_stack).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2035               VG_(client_rlimit_stack).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
2036           }
2037         }
2038         break;
2039      }
2040   }
2041}
2042
2043POST(sys_prlimit64)
2044{
2045   if (ARG4)
2046      POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2047}
2048
2049/* ---------------------------------------------------------------------
2050   tid-related wrappers
2051   ------------------------------------------------------------------ */
2052
2053PRE(sys_gettid)
2054{
2055   PRINT("sys_gettid ()");
2056   PRE_REG_READ0(long, "gettid");
2057}
2058
2059PRE(sys_set_tid_address)
2060{
2061   PRINT("sys_set_tid_address ( %#lx )", ARG1);
2062   PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2063}
2064
2065PRE(sys_tkill)
2066{
2067   PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2068   PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2069   if (!ML_(client_signal_OK)(ARG2)) {
2070      SET_STATUS_Failure( VKI_EINVAL );
2071      return;
2072   }
2073
2074   /* Check to see if this kill gave us a pending signal */
2075   *flags |= SfPollAfter;
2076
2077   if (VG_(clo_trace_signals))
2078      VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2079		   SARG2, SARG1);
2080
2081   /* If we're sending SIGKILL, check to see if the target is one of
2082      our threads and handle it specially. */
2083   if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2084      SET_STATUS_Success(0);
2085      return;
2086   }
2087
2088   /* Ask to handle this syscall via the slow route, since that's the
2089      only one that sets tst->status to VgTs_WaitSys.  If the result
2090      of doing the syscall is an immediate run of
2091      async_signalhandler() in m_signals, then we need the thread to
2092      be properly tidied away.  I have the impression the previous
2093      version of this wrapper worked on x86/amd64 only because the
2094      kernel did not immediately deliver the async signal to this
2095      thread (on ppc it did, which broke the assertion re tst->status
2096      at the top of async_signalhandler()). */
2097   *flags |= SfMayBlock;
2098}
2099POST(sys_tkill)
2100{
2101   if (VG_(clo_trace_signals))
2102      VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2103                   SARG2, SARG1);
2104}
2105
2106PRE(sys_tgkill)
2107{
2108   PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2109   PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2110   if (!ML_(client_signal_OK)(ARG3)) {
2111      SET_STATUS_Failure( VKI_EINVAL );
2112      return;
2113   }
2114
2115   /* Check to see if this kill gave us a pending signal */
2116   *flags |= SfPollAfter;
2117
2118   if (VG_(clo_trace_signals))
2119      VG_(message)(Vg_DebugMsg,
2120                   "tgkill: sending signal %ld to pid %ld/%ld\n",
2121		   SARG3, SARG1, SARG2);
2122
2123   /* If we're sending SIGKILL, check to see if the target is one of
2124      our threads and handle it specially. */
2125   if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2126      SET_STATUS_Success(0);
2127      return;
2128   }
2129
2130   /* Ask to handle this syscall via the slow route, since that's the
2131      only one that sets tst->status to VgTs_WaitSys.  If the result
2132      of doing the syscall is an immediate run of
2133      async_signalhandler() in m_signals, then we need the thread to
2134      be properly tidied away.  I have the impression the previous
2135      version of this wrapper worked on x86/amd64 only because the
2136      kernel did not immediately deliver the async signal to this
2137      thread (on ppc it did, which broke the assertion re tst->status
2138      at the top of async_signalhandler()). */
2139   *flags |= SfMayBlock;
2140}
2141POST(sys_tgkill)
2142{
2143   if (VG_(clo_trace_signals))
2144      VG_(message)(Vg_DebugMsg,
2145                   "tgkill: sent signal %ld to pid %ld/%ld\n",
2146                   SARG3, SARG1, SARG2);
2147}
2148
2149/* ---------------------------------------------------------------------
2150   fadvise64* wrappers
2151   ------------------------------------------------------------------ */
2152
2153PRE(sys_fadvise64)
2154{
2155   PRINT("sys_fadvise64 ( %ld, %llu, %lu, %ld )",
2156         SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2157   PRE_REG_READ5(long, "fadvise64",
2158                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2159                 vki_size_t, len, int, advice);
2160}
2161
2162PRE(sys_fadvise64_64)
2163{
2164   PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2165         SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2166   PRE_REG_READ6(long, "fadvise64_64",
2167                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2168                 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2169}
2170
2171/* ---------------------------------------------------------------------
2172   io_* wrappers
2173   ------------------------------------------------------------------ */
2174
2175// Nb: this wrapper has to pad/unpad memory around the syscall itself,
2176// and this allows us to control exactly the code that gets run while
2177// the padding is in place.
2178
2179PRE(sys_io_setup)
2180{
2181   PRINT("sys_io_setup ( %lu, %#lx )", ARG1,ARG2);
2182   PRE_REG_READ2(long, "io_setup",
2183                 unsigned, nr_events, vki_aio_context_t *, ctxp);
2184   PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2185}
2186
2187POST(sys_io_setup)
2188{
2189   SizeT size;
2190   struct vki_aio_ring *r;
2191
2192   size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2193                       ARG1*sizeof(struct vki_io_event));
2194   r = *(struct vki_aio_ring **)ARG2;
2195   vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2196
2197   ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2198                                      VKI_PROT_READ | VKI_PROT_WRITE,
2199                                      VKI_MAP_ANONYMOUS, -1, 0 );
2200
2201   POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2202}
2203
2204// Nb: This wrapper is "Special" because we need 'size' to do the unmap
2205// after the syscall.  We must get 'size' from the aio_ring structure,
2206// before the syscall, while the aio_ring structure still exists.  (And we
2207// know that we must look at the aio_ring structure because Tom inspected the
2208// kernel and glibc sources to see what they do, yuk.)
2209//
2210// XXX This segment can be implicitly unmapped when aio
2211// file-descriptors are closed...
2212PRE(sys_io_destroy)
2213{
2214   SizeT size = 0;
2215
2216   PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2217   PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2218
2219   // If we are going to seg fault (due to a bogus ARG1) do it as late as
2220   // possible...
2221   if (ML_(safe_to_deref)( (void*)ARG1, sizeof(struct vki_aio_ring))) {
2222      struct vki_aio_ring *r = (struct vki_aio_ring *)ARG1;
2223      size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2224                          r->nr*sizeof(struct vki_io_event));
2225   }
2226
2227   SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2228
2229   if (SUCCESS && RES == 0) {
2230      Bool d = VG_(am_notify_munmap)( ARG1, size );
2231      VG_TRACK( die_mem_munmap, ARG1, size );
2232      if (d)
2233        VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2234                                    "PRE(sys_io_destroy)" );
2235   }
2236}
2237
2238PRE(sys_io_getevents)
2239{
2240   *flags |= SfMayBlock;
2241   PRINT("sys_io_getevents ( %llu, %lld, %lld, %#lx, %#lx )",
2242         (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2243   PRE_REG_READ5(long, "io_getevents",
2244                 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2245                 struct io_event *, events,
2246                 struct timespec *, timeout);
2247   if (ARG3 > 0)
2248      PRE_MEM_WRITE( "io_getevents(events)",
2249                     ARG4, sizeof(struct vki_io_event)*ARG3 );
2250   if (ARG5 != 0)
2251      PRE_MEM_READ( "io_getevents(timeout)",
2252                    ARG5, sizeof(struct vki_timespec));
2253}
2254POST(sys_io_getevents)
2255{
2256   Int i;
2257   vg_assert(SUCCESS);
2258   if (RES > 0) {
2259      POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2260      for (i = 0; i < RES; i++) {
2261         const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
2262         const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2263
2264         switch (cb->aio_lio_opcode) {
2265         case VKI_IOCB_CMD_PREAD:
2266            if (vev->result > 0)
2267               POST_MEM_WRITE( cb->aio_buf, vev->result );
2268            break;
2269
2270         case VKI_IOCB_CMD_PWRITE:
2271            break;
2272
2273         case VKI_IOCB_CMD_FSYNC:
2274            break;
2275
2276         case VKI_IOCB_CMD_FDSYNC:
2277            break;
2278
2279         case VKI_IOCB_CMD_PREADV:
2280	     if (vev->result > 0) {
2281                  struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2282                  Int remains = vev->result;
2283                  Int j;
2284
2285                  for (j = 0; j < cb->aio_nbytes; j++) {
2286                       Int nReadThisBuf = vec[j].iov_len;
2287                       if (nReadThisBuf > remains) nReadThisBuf = remains;
2288                       POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2289                       remains -= nReadThisBuf;
2290                       if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2291                  }
2292	     }
2293             break;
2294
2295         case VKI_IOCB_CMD_PWRITEV:
2296             break;
2297
2298         default:
2299            VG_(message)(Vg_DebugMsg,
2300                        "Warning: unhandled io_getevents opcode: %u\n",
2301                        cb->aio_lio_opcode);
2302            break;
2303         }
2304      }
2305   }
2306}
2307
2308PRE(sys_io_submit)
2309{
2310   Int i, j;
2311
2312   PRINT("sys_io_submit ( %lu, %ld, %#lx )", ARG1, SARG2, ARG3);
2313   PRE_REG_READ3(long, "io_submit",
2314                 vki_aio_context_t, ctx_id, long, nr,
2315                 struct iocb **, iocbpp);
2316   PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2317   if (ARG3 != 0) {
2318      for (i = 0; i < ARG2; i++) {
2319         struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
2320         struct vki_iovec *iov;
2321
2322         PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2323         switch (cb->aio_lio_opcode) {
2324         case VKI_IOCB_CMD_PREAD:
2325            PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2326            break;
2327
2328         case VKI_IOCB_CMD_PWRITE:
2329            PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2330            break;
2331
2332         case VKI_IOCB_CMD_FSYNC:
2333            break;
2334
2335         case VKI_IOCB_CMD_FDSYNC:
2336            break;
2337
2338         case VKI_IOCB_CMD_PREADV:
2339            iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2340            PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2341            for (j = 0; j < cb->aio_nbytes; j++)
2342                PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2343            break;
2344
2345         case VKI_IOCB_CMD_PWRITEV:
2346            iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2347            PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2348            for (j = 0; j < cb->aio_nbytes; j++)
2349                PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2350            break;
2351
2352         default:
2353            VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2354                         cb->aio_lio_opcode);
2355            break;
2356         }
2357      }
2358   }
2359}
2360
2361PRE(sys_io_cancel)
2362{
2363   PRINT("sys_io_cancel ( %llu, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3);
2364   PRE_REG_READ3(long, "io_cancel",
2365                 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2366                 struct io_event *, result);
2367   PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2368   PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2369}
2370POST(sys_io_cancel)
2371{
2372   POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2373}
2374
2375/* ---------------------------------------------------------------------
2376   *_mempolicy wrappers
2377   ------------------------------------------------------------------ */
2378
2379PRE(sys_mbind)
2380{
2381   PRINT("sys_mbind ( %#lx, %lu, %lu, %#lx, %lu, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
2382   PRE_REG_READ6(long, "mbind",
2383                 unsigned long, start, unsigned long, len,
2384                 unsigned long, policy, unsigned long *, nodemask,
2385                 unsigned long, maxnode, unsigned, flags);
2386   if (ARG1 != 0)
2387      PRE_MEM_READ( "mbind(nodemask)", ARG4,
2388                    VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2389}
2390
2391PRE(sys_set_mempolicy)
2392{
2393   PRINT("sys_set_mempolicy ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
2394   PRE_REG_READ3(long, "set_mempolicy",
2395                 int, policy, unsigned long *, nodemask,
2396                 unsigned long, maxnode);
2397   PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2398                 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2399}
2400
2401PRE(sys_get_mempolicy)
2402{
2403   PRINT("sys_get_mempolicy ( %#lx, %#lx, %lu, %#lx, %lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
2404   PRE_REG_READ5(long, "get_mempolicy",
2405                 int *, policy, unsigned long *, nodemask,
2406                 unsigned long, maxnode, unsigned long, addr,
2407                 unsigned long, flags);
2408   if (ARG1 != 0)
2409      PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2410   if (ARG2 != 0)
2411      PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2412                     VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2413}
2414POST(sys_get_mempolicy)
2415{
2416   if (ARG1 != 0)
2417      POST_MEM_WRITE( ARG1, sizeof(Int) );
2418   if (ARG2 != 0)
2419      POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2420}
2421
2422/* ---------------------------------------------------------------------
2423   fanotify_* wrappers
2424   ------------------------------------------------------------------ */
2425
2426PRE(sys_fanotify_init)
2427{
2428   PRINT("sys_fanotify_init ( %lu, %lu )", ARG1,ARG2);
2429   PRE_REG_READ2(long, "fanotify_init",
2430                 unsigned int, flags, unsigned int, event_f_flags);
2431}
2432
2433POST(sys_fanotify_init)
2434{
2435   vg_assert(SUCCESS);
2436   if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2437      VG_(close)(RES);
2438      SET_STATUS_Failure( VKI_EMFILE );
2439   } else {
2440      if (VG_(clo_track_fds))
2441         ML_(record_fd_open_nameless) (tid, RES);
2442   }
2443}
2444
2445PRE(sys_fanotify_mark)
2446{
2447#if VG_WORDSIZE == 4
2448   PRINT( "sys_fanotify_mark ( %ld, %lu, %llu, %ld, %#lx(%s))",
2449          SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6, (HChar *)ARG6);
2450   PRE_REG_READ6(long, "sys_fanotify_mark",
2451                 int, fanotify_fd, unsigned int, flags,
2452                 __vki_u32, mask0, __vki_u32, mask1,
2453                 int, dfd, const char *, pathname);
2454   if (ARG6)
2455      PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2456#elif VG_WORDSIZE == 8
2457   PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2458          SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)ARG5);
2459   PRE_REG_READ5(long, "sys_fanotify_mark",
2460                 int, fanotify_fd, unsigned int, flags,
2461                 __vki_u64, mask,
2462                 int, dfd, const char *, pathname);
2463   if (ARG5)
2464      PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2465#else
2466#  error Unexpected word size
2467#endif
2468}
2469
2470/* ---------------------------------------------------------------------
2471   inotify_* wrappers
2472   ------------------------------------------------------------------ */
2473
2474PRE(sys_inotify_init)
2475{
2476   PRINT("sys_inotify_init ( )");
2477   PRE_REG_READ0(long, "inotify_init");
2478}
2479POST(sys_inotify_init)
2480{
2481   vg_assert(SUCCESS);
2482   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2483      VG_(close)(RES);
2484      SET_STATUS_Failure( VKI_EMFILE );
2485   } else {
2486      if (VG_(clo_track_fds))
2487         ML_(record_fd_open_nameless) (tid, RES);
2488   }
2489}
2490
2491PRE(sys_inotify_init1)
2492{
2493   PRINT("sys_inotify_init ( %ld )", SARG1);
2494   PRE_REG_READ1(long, "inotify_init", int, flag);
2495}
2496
2497POST(sys_inotify_init1)
2498{
2499   vg_assert(SUCCESS);
2500   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2501      VG_(close)(RES);
2502      SET_STATUS_Failure( VKI_EMFILE );
2503   } else {
2504      if (VG_(clo_track_fds))
2505         ML_(record_fd_open_nameless) (tid, RES);
2506   }
2507}
2508
2509PRE(sys_inotify_add_watch)
2510{
2511   PRINT( "sys_inotify_add_watch ( %ld, %#lx, %lx )", SARG1, ARG2, ARG3);
2512   PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2513   PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2514}
2515
2516PRE(sys_inotify_rm_watch)
2517{
2518   PRINT( "sys_inotify_rm_watch ( %ld, %lx )", SARG1, ARG2);
2519   PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2520}
2521
2522/* ---------------------------------------------------------------------
2523   mq_* wrappers
2524   ------------------------------------------------------------------ */
2525
2526PRE(sys_mq_open)
2527{
2528   PRINT("sys_mq_open( %#lx(%s), %ld, %lu, %#lx )",
2529         ARG1, (HChar*)ARG1, SARG2, ARG3, ARG4);
2530   PRE_REG_READ4(long, "mq_open",
2531                 const char *, name, int, oflag, vki_mode_t, mode,
2532                 struct mq_attr *, attr);
2533   PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2534   if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2535      const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
2536      PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2537                     (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2538      PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2539                     (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2540   }
2541}
2542POST(sys_mq_open)
2543{
2544   vg_assert(SUCCESS);
2545   if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2546      VG_(close)(RES);
2547      SET_STATUS_Failure( VKI_EMFILE );
2548   } else {
2549      if (VG_(clo_track_fds))
2550         ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1);
2551   }
2552}
2553
2554PRE(sys_mq_unlink)
2555{
2556   PRINT("sys_mq_unlink ( %#lx(%s) )", ARG1,(char*)ARG1);
2557   PRE_REG_READ1(long, "mq_unlink", const char *, name);
2558   PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2559}
2560
2561PRE(sys_mq_timedsend)
2562{
2563   *flags |= SfMayBlock;
2564   PRINT("sys_mq_timedsend ( %ld, %#lx, %lu, %lu, %#lx )",
2565         SARG1,ARG2,ARG3,ARG4,ARG5);
2566   PRE_REG_READ5(long, "mq_timedsend",
2567                 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2568                 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2569   if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2570      SET_STATUS_Failure( VKI_EBADF );
2571   } else {
2572      PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2573      if (ARG5 != 0)
2574         PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2575                        sizeof(struct vki_timespec) );
2576   }
2577}
2578
2579PRE(sys_mq_timedreceive)
2580{
2581   *flags |= SfMayBlock;
2582   PRINT("sys_mq_timedreceive( %ld, %#lx, %lu, %#lx, %#lx )",
2583         SARG1,ARG2,ARG3,ARG4,ARG5);
2584   PRE_REG_READ5(ssize_t, "mq_timedreceive",
2585                 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2586                 unsigned int *, msg_prio,
2587                 const struct timespec *, abs_timeout);
2588   if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2589      SET_STATUS_Failure( VKI_EBADF );
2590   } else {
2591      PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2592      if (ARG4 != 0)
2593         PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2594                        ARG4, sizeof(unsigned int) );
2595      if (ARG5 != 0)
2596         PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2597                        ARG5, sizeof(struct vki_timespec) );
2598   }
2599}
2600POST(sys_mq_timedreceive)
2601{
2602   POST_MEM_WRITE( ARG2, RES );
2603   if (ARG4 != 0)
2604      POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2605}
2606
2607PRE(sys_mq_notify)
2608{
2609   PRINT("sys_mq_notify( %ld, %#lx )", SARG1, ARG2 );
2610   PRE_REG_READ2(long, "mq_notify",
2611                 vki_mqd_t, mqdes, const struct sigevent *, notification);
2612   if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2613      SET_STATUS_Failure( VKI_EBADF );
2614   else if (ARG2 != 0)
2615      PRE_MEM_READ( "mq_notify(notification)",
2616                    ARG2, sizeof(struct vki_sigevent) );
2617}
2618
2619PRE(sys_mq_getsetattr)
2620{
2621   PRINT("sys_mq_getsetattr( %ld, %#lx, %#lx )", SARG1,ARG2,ARG3 );
2622   PRE_REG_READ3(long, "mq_getsetattr",
2623                 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2624                 struct mq_attr *, omqstat);
2625   if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2626      SET_STATUS_Failure( VKI_EBADF );
2627   } else {
2628      if (ARG2 != 0) {
2629         const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
2630         PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2631                        (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2632      }
2633      if (ARG3 != 0)
2634         PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2635                        sizeof(struct vki_mq_attr) );
2636   }
2637}
2638POST(sys_mq_getsetattr)
2639{
2640   if (ARG3 != 0)
2641      POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2642}
2643
2644/* ---------------------------------------------------------------------
2645   clock_* wrappers
2646   ------------------------------------------------------------------ */
2647
2648PRE(sys_clock_settime)
2649{
2650   PRINT("sys_clock_settime( %ld, %#lx )", SARG1, ARG2);
2651   PRE_REG_READ2(long, "clock_settime",
2652                 vki_clockid_t, clk_id, const struct timespec *, tp);
2653   PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2654}
2655
2656PRE(sys_clock_gettime)
2657{
2658   PRINT("sys_clock_gettime( %ld, %#lx )" , SARG1, ARG2);
2659   PRE_REG_READ2(long, "clock_gettime",
2660                 vki_clockid_t, clk_id, struct timespec *, tp);
2661   PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2662}
2663POST(sys_clock_gettime)
2664{
2665   POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2666}
2667
2668PRE(sys_clock_getres)
2669{
2670   PRINT("sys_clock_getres( %ld, %#lx )" , SARG1, ARG2);
2671   // Nb: we can't use "RES" as the param name because that's a macro
2672   // defined above!
2673   PRE_REG_READ2(long, "clock_getres",
2674                 vki_clockid_t, clk_id, struct timespec *, res);
2675   if (ARG2 != 0)
2676      PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2677}
2678POST(sys_clock_getres)
2679{
2680   if (ARG2 != 0)
2681      POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2682}
2683
2684PRE(sys_clock_nanosleep)
2685{
2686   *flags |= SfMayBlock|SfPostOnFail;
2687   PRINT("sys_clock_nanosleep( %ld, %ld, %#lx, %#lx )",
2688         SARG1, SARG2, ARG3, ARG4);
2689   PRE_REG_READ4(int32_t, "clock_nanosleep",
2690                 vki_clockid_t, clkid, int, flags,
2691                 const struct timespec *, rqtp, struct timespec *, rmtp);
2692   PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2693   if (ARG4 != 0)
2694      PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2695}
2696POST(sys_clock_nanosleep)
2697{
2698   if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2699      POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2700}
2701
2702/* ---------------------------------------------------------------------
2703   timer_* wrappers
2704   ------------------------------------------------------------------ */
2705
2706PRE(sys_timer_create)
2707{
2708   PRINT("sys_timer_create( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
2709   PRE_REG_READ3(long, "timer_create",
2710                 vki_clockid_t, clockid, struct sigevent *, evp,
2711                 vki_timer_t *, timerid);
2712   if (ARG2 != 0) {
2713      struct vki_sigevent *evp = (struct vki_sigevent *) ARG2;
2714      PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2715                    sizeof(vki_sigval_t) );
2716      PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2717                    sizeof(int) );
2718      PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2719                    sizeof(int) );
2720      if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2721          && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2722         PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2723                       (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2724   }
2725   PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2726}
2727POST(sys_timer_create)
2728{
2729   POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2730}
2731
2732PRE(sys_timer_settime)
2733{
2734   PRINT("sys_timer_settime( %ld, %ld, %#lx, %#lx )", SARG1,SARG2,ARG3,ARG4);
2735   PRE_REG_READ4(long, "timer_settime",
2736                 vki_timer_t, timerid, int, flags,
2737                 const struct itimerspec *, value,
2738                 struct itimerspec *, ovalue);
2739   PRE_MEM_READ( "timer_settime(value)", ARG3,
2740                  sizeof(struct vki_itimerspec) );
2741   if (ARG4 != 0)
2742       PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2743                      sizeof(struct vki_itimerspec) );
2744}
2745POST(sys_timer_settime)
2746{
2747   if (ARG4 != 0)
2748      POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2749}
2750
2751PRE(sys_timer_gettime)
2752{
2753   PRINT("sys_timer_gettime( %ld, %#lx )", SARG1, ARG2);
2754   PRE_REG_READ2(long, "timer_gettime",
2755                 vki_timer_t, timerid, struct itimerspec *, value);
2756   PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2757                  sizeof(struct vki_itimerspec));
2758}
2759POST(sys_timer_gettime)
2760{
2761   POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2762}
2763
2764PRE(sys_timer_getoverrun)
2765{
2766   PRINT("sys_timer_getoverrun( %#lx )", ARG1);
2767   PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2768}
2769
2770PRE(sys_timer_delete)
2771{
2772   PRINT("sys_timer_delete( %#lx )", ARG1);
2773   PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2774}
2775
2776/* ---------------------------------------------------------------------
2777   timerfd* wrappers
2778   See also http://lwn.net/Articles/260172/ for an overview.
2779   See also /usr/src/linux/fs/timerfd.c for the implementation.
2780   ------------------------------------------------------------------ */
2781
2782/* Returns True if running on 2.6.22, else False (or False if
2783   cannot be determined). */
2784static Bool linux_kernel_2_6_22(void)
2785{
2786   static Int result = -1;
2787   Int fd, read;
2788   HChar release[64];   // large enough
2789   SysRes res;
2790
2791   if (result == -1) {
2792      res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2793      if (sr_isError(res))
2794         return False;
2795      fd = sr_Res(res);
2796      read = VG_(read)(fd, release, sizeof(release) - 1);
2797      if (read < 0)
2798         return False;
2799      release[read] = 0;
2800      VG_(close)(fd);
2801      //VG_(printf)("kernel release = %s\n", release);
2802      result = VG_(strncmp)(release, "2.6.22", 6) == 0
2803               && ! VG_(isdigit)(release[6]);
2804   }
2805   vg_assert(result == 0 || result == 1);
2806   return result == 1;
2807}
2808
2809PRE(sys_timerfd_create)
2810{
2811   if (linux_kernel_2_6_22()) {
2812      /* 2.6.22 kernel: timerfd system call. */
2813      PRINT("sys_timerfd ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
2814      PRE_REG_READ3(long, "sys_timerfd",
2815                    int, fd, int, clockid, const struct itimerspec *, tmr);
2816      PRE_MEM_READ("timerfd(tmr)", ARG3,
2817                   sizeof(struct vki_itimerspec) );
2818      if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2819         SET_STATUS_Failure( VKI_EBADF );
2820   } else {
2821      /* 2.6.24 and later kernels: timerfd_create system call. */
2822      PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
2823      PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2824   }
2825}
2826POST(sys_timerfd_create)
2827{
2828   if (linux_kernel_2_6_22())
2829   {
2830      /* 2.6.22 kernel: timerfd system call. */
2831      if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2832         VG_(close)(RES);
2833         SET_STATUS_Failure( VKI_EMFILE );
2834      } else {
2835         if (VG_(clo_track_fds))
2836            ML_(record_fd_open_nameless) (tid, RES);
2837      }
2838   }
2839   else
2840   {
2841      /* 2.6.24 and later kernels: timerfd_create system call. */
2842      if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2843         VG_(close)(RES);
2844         SET_STATUS_Failure( VKI_EMFILE );
2845      } else {
2846         if (VG_(clo_track_fds))
2847            ML_(record_fd_open_nameless) (tid, RES);
2848      }
2849   }
2850}
2851
2852PRE(sys_timerfd_gettime)
2853{
2854   PRINT("sys_timerfd_gettime ( %ld, %#lx )", SARG1, ARG2);
2855   PRE_REG_READ2(long, "timerfd_gettime",
2856                 int, ufd,
2857                 struct vki_itimerspec*, otmr);
2858   if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2859      SET_STATUS_Failure(VKI_EBADF);
2860   else
2861      PRE_MEM_WRITE("timerfd_gettime(result)",
2862                    ARG2, sizeof(struct vki_itimerspec));
2863}
2864POST(sys_timerfd_gettime)
2865{
2866   if (RES == 0)
2867      POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2868}
2869
2870PRE(sys_timerfd_settime)
2871{
2872   PRINT("sys_timerfd_settime ( %ld, %ld, %#lx, %#lx )",
2873         SARG1, SARG2, ARG3, ARG4);
2874   PRE_REG_READ4(long, "timerfd_settime",
2875                 int, ufd,
2876                 int, flags,
2877                 const struct vki_itimerspec*, utmr,
2878                 struct vki_itimerspec*, otmr);
2879   if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2880      SET_STATUS_Failure(VKI_EBADF);
2881   else
2882   {
2883      PRE_MEM_READ("timerfd_settime(result)",
2884                   ARG3, sizeof(struct vki_itimerspec));
2885      if (ARG4)
2886      {
2887         PRE_MEM_WRITE("timerfd_settime(result)",
2888                       ARG4, sizeof(struct vki_itimerspec));
2889      }
2890   }
2891}
2892POST(sys_timerfd_settime)
2893{
2894   if (RES == 0 && ARG4 != 0)
2895      POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2896}
2897
2898/* ---------------------------------------------------------------------
2899   capabilities wrappers
2900   ------------------------------------------------------------------ */
2901
2902PRE(sys_capget)
2903{
2904   PRINT("sys_capget ( %#lx, %#lx )", ARG1, ARG2 );
2905   PRE_REG_READ2(long, "capget",
2906                 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2907   PRE_MEM_READ( "capget(header)", ARG1,
2908                  sizeof(struct __vki_user_cap_header_struct) );
2909   if (ARG2 != (Addr)NULL)
2910      PRE_MEM_WRITE( "capget(data)", ARG2,
2911                     sizeof(struct __vki_user_cap_data_struct) );
2912}
2913POST(sys_capget)
2914{
2915   if (ARG2 != (Addr)NULL)
2916      POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2917}
2918
2919PRE(sys_capset)
2920{
2921   PRINT("sys_capset ( %#lx, %#lx )", ARG1, ARG2 );
2922   PRE_REG_READ2(long, "capset",
2923                 vki_cap_user_header_t, header,
2924                 const vki_cap_user_data_t, data);
2925   PRE_MEM_READ( "capset(header)",
2926                  ARG1, sizeof(struct __vki_user_cap_header_struct) );
2927   PRE_MEM_READ( "capset(data)",
2928                  ARG2, sizeof(struct __vki_user_cap_data_struct) );
2929}
2930
2931/* ---------------------------------------------------------------------
2932   16-bit uid/gid/groups wrappers
2933   ------------------------------------------------------------------ */
2934
2935PRE(sys_getuid16)
2936{
2937   PRINT("sys_getuid16 ( )");
2938   PRE_REG_READ0(long, "getuid16");
2939}
2940
2941PRE(sys_setuid16)
2942{
2943   PRINT("sys_setuid16 ( %lu )", ARG1);
2944   PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
2945}
2946
2947PRE(sys_getgid16)
2948{
2949   PRINT("sys_getgid16 ( )");
2950   PRE_REG_READ0(long, "getgid16");
2951}
2952
2953PRE(sys_setgid16)
2954{
2955   PRINT("sys_setgid16 ( %lu )", ARG1);
2956   PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
2957}
2958
2959PRE(sys_geteuid16)
2960{
2961   PRINT("sys_geteuid16 ( )");
2962   PRE_REG_READ0(long, "geteuid16");
2963}
2964
2965PRE(sys_getegid16)
2966{
2967   PRINT("sys_getegid16 ( )");
2968   PRE_REG_READ0(long, "getegid16");
2969}
2970
2971PRE(sys_setreuid16)
2972{
2973   PRINT("setreuid16 ( 0x%lx, 0x%lx )", ARG1, ARG2);
2974   PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
2975}
2976
2977PRE(sys_setregid16)
2978{
2979   PRINT("sys_setregid16 ( %lu, %lu )", ARG1, ARG2);
2980   PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2981}
2982
2983PRE(sys_getgroups16)
2984{
2985   PRINT("sys_getgroups16 ( %ld, %#lx )", SARG1, ARG2);
2986   PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2987   if (ARG1 > 0)
2988      PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2989}
2990POST(sys_getgroups16)
2991{
2992   vg_assert(SUCCESS);
2993   if (ARG1 > 0 && RES > 0)
2994      POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2995}
2996
2997PRE(sys_setgroups16)
2998{
2999   PRINT("sys_setgroups16 ( %llu, %#lx )", (ULong)ARG1, ARG2);
3000   PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3001   if (ARG1 > 0)
3002      PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3003}
3004
3005/* ---------------------------------------------------------------------
3006   *chown16 wrappers
3007   ------------------------------------------------------------------ */
3008
3009PRE(sys_chown16)
3010{
3011   PRINT("sys_chown16 ( %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3);
3012   PRE_REG_READ3(long, "chown16",
3013                 const char *, path,
3014                 vki_old_uid_t, owner, vki_old_gid_t, group);
3015   PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3016}
3017
3018PRE(sys_fchown16)
3019{
3020   PRINT("sys_fchown16 ( %lu, %lu, %lu )", ARG1,ARG2,ARG3);
3021   PRE_REG_READ3(long, "fchown16",
3022                 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3023}
3024
3025/* ---------------------------------------------------------------------
3026   *xattr wrappers
3027   ------------------------------------------------------------------ */
3028
3029PRE(sys_setxattr)
3030{
3031   *flags |= SfMayBlock;
3032   PRINT("sys_setxattr ( %#lx, %#lx, %#lx, %lu, %ld )",
3033         ARG1, ARG2, ARG3, ARG4, SARG5);
3034   PRE_REG_READ5(long, "setxattr",
3035                 char *, path, char *, name,
3036                 void *, value, vki_size_t, size, int, flags);
3037   PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3038   PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3039   PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3040}
3041
3042PRE(sys_lsetxattr)
3043{
3044   *flags |= SfMayBlock;
3045   PRINT("sys_lsetxattr ( %#lx, %#lx, %#lx, %lu, %ld )",
3046         ARG1, ARG2, ARG3, ARG4, SARG5);
3047   PRE_REG_READ5(long, "lsetxattr",
3048                 char *, path, char *, name,
3049                 void *, value, vki_size_t, size, int, flags);
3050   PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3051   PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3052   PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3053}
3054
3055PRE(sys_fsetxattr)
3056{
3057   *flags |= SfMayBlock;
3058   PRINT("sys_fsetxattr ( %ld, %#lx, %#lx, %lu, %ld )",
3059         SARG1, ARG2, ARG3, ARG4, SARG5);
3060   PRE_REG_READ5(long, "fsetxattr",
3061                 int, fd, char *, name, void *, value,
3062                 vki_size_t, size, int, flags);
3063   PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3064   PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3065}
3066
3067PRE(sys_getxattr)
3068{
3069   *flags |= SfMayBlock;
3070   PRINT("sys_getxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
3071   PRE_REG_READ4(ssize_t, "getxattr",
3072                 char *, path, char *, name, void *, value, vki_size_t, size);
3073   PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3074   PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3075   PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3076}
3077POST(sys_getxattr)
3078{
3079   vg_assert(SUCCESS);
3080   if (RES > 0 && ARG3 != (Addr)NULL) {
3081      POST_MEM_WRITE( ARG3, RES );
3082   }
3083}
3084
3085PRE(sys_lgetxattr)
3086{
3087   *flags |= SfMayBlock;
3088   PRINT("sys_lgetxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
3089   PRE_REG_READ4(ssize_t, "lgetxattr",
3090                 char *, path, char *, name, void *, value, vki_size_t, size);
3091   PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3092   PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3093   PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3094}
3095POST(sys_lgetxattr)
3096{
3097   vg_assert(SUCCESS);
3098   if (RES > 0 && ARG3 != (Addr)NULL) {
3099      POST_MEM_WRITE( ARG3, RES );
3100   }
3101}
3102
3103PRE(sys_fgetxattr)
3104{
3105   *flags |= SfMayBlock;
3106   PRINT("sys_fgetxattr ( %ld, %#lx, %#lx, %lu )", SARG1, ARG2, ARG3, ARG4);
3107   PRE_REG_READ4(ssize_t, "fgetxattr",
3108                 int, fd, char *, name, void *, value, vki_size_t, size);
3109   PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3110   PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3111}
3112POST(sys_fgetxattr)
3113{
3114   if (RES > 0 && ARG3 != (Addr)NULL)
3115      POST_MEM_WRITE( ARG3, RES );
3116}
3117
3118PRE(sys_listxattr)
3119{
3120   *flags |= SfMayBlock;
3121   PRINT("sys_listxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
3122   PRE_REG_READ3(ssize_t, "listxattr",
3123                 char *, path, char *, list, vki_size_t, size);
3124   PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3125   PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3126}
3127POST(sys_listxattr)
3128{
3129   if (RES > 0 && ARG2 != (Addr)NULL)
3130      POST_MEM_WRITE( ARG2, RES );
3131}
3132
3133PRE(sys_llistxattr)
3134{
3135   *flags |= SfMayBlock;
3136   PRINT("sys_llistxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
3137   PRE_REG_READ3(ssize_t, "llistxattr",
3138                 char *, path, char *, list, vki_size_t, size);
3139   PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3140   PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3141}
3142POST(sys_llistxattr)
3143{
3144   if (RES > 0 && ARG2 != (Addr)NULL)
3145      POST_MEM_WRITE( ARG2, RES );
3146}
3147
3148PRE(sys_flistxattr)
3149{
3150   *flags |= SfMayBlock;
3151   PRINT("sys_flistxattr ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
3152   PRE_REG_READ3(ssize_t, "flistxattr",
3153                 int, fd, char *, list, vki_size_t, size);
3154   PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3155}
3156POST(sys_flistxattr)
3157{
3158   if (RES > 0 && ARG2 != (Addr)NULL)
3159      POST_MEM_WRITE( ARG2, RES );
3160}
3161
3162PRE(sys_removexattr)
3163{
3164   *flags |= SfMayBlock;
3165   PRINT("sys_removexattr ( %#lx, %#lx )", ARG1, ARG2);
3166   PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3167   PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3168   PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3169}
3170
3171PRE(sys_lremovexattr)
3172{
3173   *flags |= SfMayBlock;
3174   PRINT("sys_lremovexattr ( %#lx, %#lx )", ARG1, ARG2);
3175   PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3176   PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3177   PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3178}
3179
3180PRE(sys_fremovexattr)
3181{
3182   *flags |= SfMayBlock;
3183   PRINT("sys_fremovexattr ( %ld, %#lx )", SARG1, ARG2);
3184   PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3185   PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3186}
3187
3188/* ---------------------------------------------------------------------
3189   sched_* wrappers
3190   ------------------------------------------------------------------ */
3191
3192PRE(sys_sched_setparam)
3193{
3194   PRINT("sched_setparam ( %ld, %#lx )", SARG1, ARG2 );
3195   PRE_REG_READ2(long, "sched_setparam",
3196                 vki_pid_t, pid, struct sched_param *, p);
3197   PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3198}
3199POST(sys_sched_setparam)
3200{
3201   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3202}
3203
3204PRE(sys_sched_getparam)
3205{
3206   PRINT("sched_getparam ( %ld, %#lx )", SARG1, ARG2 );
3207   PRE_REG_READ2(long, "sched_getparam",
3208                 vki_pid_t, pid, struct sched_param *, p);
3209   PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3210}
3211POST(sys_sched_getparam)
3212{
3213   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3214}
3215
3216PRE(sys_sched_getscheduler)
3217{
3218   PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3219   PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3220}
3221
3222PRE(sys_sched_setscheduler)
3223{
3224   PRINT("sys_sched_setscheduler ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
3225   PRE_REG_READ3(long, "sched_setscheduler",
3226                 vki_pid_t, pid, int, policy, struct sched_param *, p);
3227   if (ARG3 != 0)
3228      PRE_MEM_READ( "sched_setscheduler(p)",
3229		    ARG3, sizeof(struct vki_sched_param));
3230}
3231
3232PRE(sys_sched_yield)
3233{
3234   *flags |= SfMayBlock;
3235   PRINT("sched_yield()");
3236   PRE_REG_READ0(long, "sys_sched_yield");
3237}
3238
3239PRE(sys_sched_get_priority_max)
3240{
3241   PRINT("sched_get_priority_max ( %ld )", SARG1);
3242   PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3243}
3244
3245PRE(sys_sched_get_priority_min)
3246{
3247   PRINT("sched_get_priority_min ( %ld )", SARG1);
3248   PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3249}
3250
3251PRE(sys_sched_rr_get_interval)
3252{
3253   PRINT("sys_sched_rr_get_interval ( %ld, %#lx )", SARG1, ARG2);
3254   PRE_REG_READ2(int, "sched_rr_get_interval",
3255                 vki_pid_t, pid,
3256                 struct vki_timespec *, tp);
3257   PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3258                 ARG2, sizeof(struct vki_timespec));
3259}
3260
3261POST(sys_sched_rr_get_interval)
3262{
3263   POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3264}
3265
3266PRE(sys_sched_setaffinity)
3267{
3268   PRINT("sched_setaffinity ( %ld, %lu, %#lx )", SARG1, ARG2, ARG3);
3269   PRE_REG_READ3(long, "sched_setaffinity",
3270                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3271   PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3272}
3273
3274PRE(sys_sched_getaffinity)
3275{
3276   PRINT("sched_getaffinity ( %ld, %lu, %#lx )", SARG1, ARG2, ARG3);
3277   PRE_REG_READ3(long, "sched_getaffinity",
3278                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3279   PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3280}
3281POST(sys_sched_getaffinity)
3282{
3283   POST_MEM_WRITE(ARG3, ARG2);
3284}
3285
3286PRE(sys_unshare)
3287{
3288   PRINT("sys_unshare ( %#lx )", ARG1);
3289   PRE_REG_READ1(int, "unshare", unsigned long, flags);
3290}
3291
3292/* ---------------------------------------------------------------------
3293   miscellaneous wrappers
3294   ------------------------------------------------------------------ */
3295
3296PRE(sys_munlockall)
3297{
3298   *flags |= SfMayBlock;
3299   PRINT("sys_munlockall ( )");
3300   PRE_REG_READ0(long, "munlockall");
3301}
3302
3303// This has different signatures for different platforms.
3304//
3305//  x86:   int  sys_pipe(unsigned long __user *fildes);
3306//  AMD64: long sys_pipe(int *fildes);
3307//  ppc32: int  sys_pipe(int __user *fildes);
3308//  ppc64: int  sys_pipe(int __user *fildes);
3309//
3310// The type of the argument is most important, and it is an array of 32 bit
3311// values in all cases.  (The return type differs across platforms, but it
3312// is not used.)  So we use 'int' as its type.  This fixed bug #113230 which
3313// was caused by using an array of 'unsigned long's, which didn't work on
3314// AMD64.
3315PRE(sys_pipe)
3316{
3317   PRINT("sys_pipe ( %#lx )", ARG1);
3318   PRE_REG_READ1(int, "pipe", int *, filedes);
3319   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3320}
3321POST(sys_pipe)
3322{
3323   Int *p = (Int *)ARG1;
3324   if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3325       !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3326      VG_(close)(p[0]);
3327      VG_(close)(p[1]);
3328      SET_STATUS_Failure( VKI_EMFILE );
3329   } else {
3330      POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3331      if (VG_(clo_track_fds)) {
3332         ML_(record_fd_open_nameless)(tid, p[0]);
3333         ML_(record_fd_open_nameless)(tid, p[1]);
3334      }
3335   }
3336}
3337
3338/* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3339   there's a second arg containing flags to be applied to the new file
3340   descriptors.  It hardly seems worth the effort to factor out the
3341   duplicated code, hence: */
3342PRE(sys_pipe2)
3343{
3344   PRINT("sys_pipe2 ( %#lx, %#lx )", ARG1, ARG2);
3345   PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3346   PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3347}
3348POST(sys_pipe2)
3349{
3350   Int *p = (Int *)ARG1;
3351   if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3352       !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3353      VG_(close)(p[0]);
3354      VG_(close)(p[1]);
3355      SET_STATUS_Failure( VKI_EMFILE );
3356   } else {
3357      POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3358      if (VG_(clo_track_fds)) {
3359         ML_(record_fd_open_nameless)(tid, p[0]);
3360         ML_(record_fd_open_nameless)(tid, p[1]);
3361      }
3362   }
3363}
3364
3365PRE(sys_dup3)
3366{
3367   PRINT("sys_dup3 ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
3368   PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3369   if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3370      SET_STATUS_Failure( VKI_EBADF );
3371}
3372
3373POST(sys_dup3)
3374{
3375   vg_assert(SUCCESS);
3376   if (VG_(clo_track_fds))
3377      ML_(record_fd_open_named)(tid, RES);
3378}
3379
3380PRE(sys_quotactl)
3381{
3382   PRINT("sys_quotactl (0x%lx, %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3, ARG4);
3383   PRE_REG_READ4(long, "quotactl",
3384                 unsigned int, cmd, const char *, special, vki_qid_t, id,
3385                 void *, addr);
3386   PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3387}
3388
3389PRE(sys_waitid)
3390{
3391   *flags |= SfMayBlock;
3392   PRINT("sys_waitid( %ld, %ld, %#lx, %ld, %#lx )",
3393         SARG1, SARG2, ARG3, SARG4, ARG5);
3394   PRE_REG_READ5(int32_t, "sys_waitid",
3395                 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3396                 int, options, struct vki_rusage *, ru);
3397   PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3398   if (ARG5 != 0)
3399      PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3400}
3401POST(sys_waitid)
3402{
3403   POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3404   if (ARG5 != 0)
3405      POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3406}
3407
3408PRE(sys_sync_file_range)
3409{
3410   *flags |= SfMayBlock;
3411#if VG_WORDSIZE == 4
3412   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#lx )",
3413         SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3414   PRE_REG_READ6(long, "sync_file_range",
3415                 int, fd,
3416                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3417                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3418                 unsigned int, flags);
3419#elif VG_WORDSIZE == 8
3420   PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3421         SARG1, SARG2, SARG3, ARG4);
3422   PRE_REG_READ4(long, "sync_file_range",
3423                 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3424                 unsigned int, flags);
3425#else
3426#  error Unexpected word size
3427#endif
3428   if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3429      SET_STATUS_Failure( VKI_EBADF );
3430}
3431
3432PRE(sys_sync_file_range2)
3433{
3434   *flags |= SfMayBlock;
3435#if VG_WORDSIZE == 4
3436   PRINT("sys_sync_file_range2 ( %ld, %lu, %lld, %lld )",
3437         SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3438   PRE_REG_READ6(long, "sync_file_range2",
3439                 int, fd, unsigned int, flags,
3440                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3441                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3442#elif VG_WORDSIZE == 8
3443   PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3444         SARG1, ARG2, SARG3, SARG4);
3445   PRE_REG_READ4(long, "sync_file_range2",
3446                 int, fd, unsigned int, flags,
3447                 vki_loff_t, offset, vki_loff_t, nbytes);
3448#else
3449#  error Unexpected word size
3450#endif
3451   if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3452      SET_STATUS_Failure( VKI_EBADF );
3453}
3454
3455PRE(sys_stime)
3456{
3457   PRINT("sys_stime ( %#lx )", ARG1);
3458   PRE_REG_READ1(int, "stime", vki_time_t*, t);
3459   PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3460}
3461
3462PRE(sys_perf_event_open)
3463{
3464   struct vki_perf_event_attr *attr;
3465   PRINT("sys_perf_event_open ( %#lx, %ld, %ld, %ld, %#lx )",
3466         ARG1, SARG2, SARG3, SARG4, ARG5);
3467   PRE_REG_READ5(long, "perf_event_open",
3468                 struct vki_perf_event_attr *, attr,
3469                 vki_pid_t, pid, int, cpu, int, group_fd,
3470                 unsigned long, flags);
3471   attr = (struct vki_perf_event_attr *)ARG1;
3472   PRE_MEM_READ( "perf_event_open(attr->size)",
3473                 (Addr)&attr->size, sizeof(attr->size) );
3474   PRE_MEM_READ( "perf_event_open(attr)",
3475                 (Addr)attr, attr->size );
3476}
3477
3478POST(sys_perf_event_open)
3479{
3480   vg_assert(SUCCESS);
3481   if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3482      VG_(close)(RES);
3483      SET_STATUS_Failure( VKI_EMFILE );
3484   } else {
3485      if (VG_(clo_track_fds))
3486         ML_(record_fd_open_nameless)(tid, RES);
3487   }
3488}
3489
3490PRE(sys_getcpu)
3491{
3492   PRINT("sys_getcpu ( %#lx, %#lx, %#lx )" , ARG1,ARG2,ARG3);
3493   PRE_REG_READ3(int, "getcpu",
3494                 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3495   if (ARG1 != 0)
3496      PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3497   if (ARG2 != 0)
3498      PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3499   if (ARG3 != 0)
3500      PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3501}
3502
3503POST(sys_getcpu)
3504{
3505   if (ARG1 != 0)
3506      POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3507   if (ARG2 != 0)
3508      POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3509   if (ARG3 != 0)
3510      POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3511}
3512
3513PRE(sys_move_pages)
3514{
3515   PRINT("sys_move_pages ( %ld, %lu, %#lx, %#lx, %#lx, %#lx )",
3516         SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3517   PRE_REG_READ6(int, "move_pages",
3518                 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3519                 const int *, nodes, int *, status, int, flags);
3520   PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3521   if (ARG4)
3522      PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3523   PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3524}
3525
3526POST(sys_move_pages)
3527{
3528   POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3529}
3530
3531PRE(sys_getrandom)
3532{
3533   PRINT("sys_getrandom ( %#lx, %lu, %lu )" , ARG1, ARG2, ARG3);
3534   PRE_REG_READ3(int, "getrandom",
3535                 char *, buf, vki_size_t, count, unsigned int, flags);
3536   PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3537}
3538
3539POST(sys_getrandom)
3540{
3541   POST_MEM_WRITE( ARG1, ARG2 );
3542}
3543
3544PRE(sys_memfd_create)
3545{
3546   PRINT("sys_memfd_create ( %#lx, %lu )" , ARG1, ARG2);
3547   PRE_REG_READ2(int, "memfd_create",
3548                 char *, uname, unsigned int, flags);
3549   PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3550}
3551
3552POST(sys_memfd_create)
3553{
3554   vg_assert(SUCCESS);
3555   if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3556      VG_(close)(RES);
3557      SET_STATUS_Failure( VKI_EMFILE );
3558   } else {
3559      if (VG_(clo_track_fds))
3560         ML_(record_fd_open_nameless)(tid, RES);
3561   }
3562}
3563
3564PRE(sys_syncfs)
3565{
3566   *flags |= SfMayBlock;
3567   PRINT("sys_syncfs ( %lu )", ARG1);
3568   PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3569}
3570
3571/* ---------------------------------------------------------------------
3572   utime wrapper
3573   ------------------------------------------------------------------ */
3574
3575PRE(sys_utime)
3576{
3577   *flags |= SfMayBlock;
3578   PRINT("sys_utime ( %#lx, %#lx )", ARG1,ARG2);
3579   PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3580   PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3581   if (ARG2 != 0)
3582      PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3583}
3584
3585/* ---------------------------------------------------------------------
3586   lseek wrapper
3587   ------------------------------------------------------------------ */
3588
3589PRE(sys_lseek)
3590{
3591   PRINT("sys_lseek ( %lu, %ld, %lu )", ARG1, SARG2, ARG3);
3592   PRE_REG_READ3(vki_off_t, "lseek",
3593                 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3594}
3595
3596/* ---------------------------------------------------------------------
3597   readahead wrapper
3598   ------------------------------------------------------------------ */
3599
3600PRE(sys_readahead)
3601{
3602   *flags |= SfMayBlock;
3603#if VG_WORDSIZE == 4
3604   PRINT("sys_readahead ( %ld, %lld, %lu )",
3605         SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
3606   PRE_REG_READ4(vki_off_t, "readahead",
3607                 int, fd, unsigned, MERGE64_FIRST(offset),
3608                 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3609#elif VG_WORDSIZE == 8
3610   PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
3611   PRE_REG_READ3(vki_off_t, "readahead",
3612                 int, fd, vki_loff_t, offset, vki_size_t, count);
3613#else
3614#  error Unexpected word size
3615#endif
3616   if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3617      SET_STATUS_Failure( VKI_EBADF );
3618}
3619
3620/* ---------------------------------------------------------------------
3621   sig* wrappers
3622   ------------------------------------------------------------------ */
3623
3624PRE(sys_sigpending)
3625{
3626   PRINT( "sys_sigpending ( %#lx )", ARG1 );
3627   PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3628   PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3629}
3630POST(sys_sigpending)
3631{
3632   POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3633}
3634
3635// This syscall is not used on amd64/Linux -- it only provides
3636// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3637// This wrapper is only suitable for 32-bit architectures.
3638// (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3639// conditional compilation like this?)
3640#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3641    || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
3642PRE(sys_sigprocmask)
3643{
3644   vki_old_sigset_t* set;
3645   vki_old_sigset_t* oldset;
3646   vki_sigset_t bigger_set;
3647   vki_sigset_t bigger_oldset;
3648
3649   PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3650   PRE_REG_READ3(long, "sigprocmask",
3651                 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3652   if (ARG2 != 0)
3653      PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3654   if (ARG3 != 0)
3655      PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3656
3657   // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3658   // vki_sigset_t params.
3659   set    = (vki_old_sigset_t*)ARG2;
3660   oldset = (vki_old_sigset_t*)ARG3;
3661
3662   VG_(memset)(&bigger_set,    0, sizeof(vki_sigset_t));
3663   VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3664   if (set)
3665      bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3666
3667   SET_STATUS_from_SysRes(
3668      VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3669                                set ? &bigger_set    : NULL,
3670                             oldset ? &bigger_oldset : NULL)
3671   );
3672
3673   if (oldset)
3674      *oldset = bigger_oldset.sig[0];
3675
3676   if (SUCCESS)
3677      *flags |= SfPollAfter;
3678}
3679POST(sys_sigprocmask)
3680{
3681   vg_assert(SUCCESS);
3682   if (RES == 0 && ARG3 != 0)
3683      POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3684}
3685
3686/* Convert from non-RT to RT sigset_t's */
3687static
3688void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3689{
3690   VG_(sigemptyset)(set);
3691   set->sig[0] = *oldset;
3692}
3693PRE(sys_sigaction)
3694{
3695   vki_sigaction_toK_t   new, *newp;
3696   vki_sigaction_fromK_t old, *oldp;
3697
3698   PRINT("sys_sigaction ( %ld, %#lx, %#lx )",  SARG1, ARG2, ARG3);
3699   PRE_REG_READ3(int, "sigaction",
3700                 int, signum, const struct old_sigaction *, act,
3701                 struct old_sigaction *, oldact);
3702
3703   newp = oldp = NULL;
3704
3705   if (ARG2 != 0) {
3706      struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
3707      PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3708      PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3709      PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3710      if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
3711          && (sa->sa_flags & VKI_SA_RESTORER))
3712         PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3713   }
3714
3715   if (ARG3 != 0) {
3716      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3717      oldp = &old;
3718   }
3719
3720   /* If the new or old sigaction is not NULL, but the structs
3721      aren't accessible then sigaction returns EFAULT and we cannot
3722      use either struct for our own bookkeeping. Just fail early. */
3723   if (ARG2 != 0
3724       && ! ML_(safe_to_deref)((void *)ARG2,
3725                               sizeof(struct vki_old_sigaction))) {
3726      VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
3727                (void *)ARG2);
3728      SET_STATUS_Failure ( VKI_EFAULT );
3729   } else if ((ARG3 != 0
3730               && ! ML_(safe_to_deref)((void *)ARG3,
3731                                       sizeof(struct vki_old_sigaction)))) {
3732      VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
3733                (void *)ARG3);
3734      SET_STATUS_Failure ( VKI_EFAULT );
3735   } else {
3736      if (ARG2 != 0) {
3737         struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
3738
3739         new.ksa_handler = oldnew->ksa_handler;
3740         new.sa_flags = oldnew->sa_flags;
3741         new.sa_restorer = oldnew->sa_restorer;
3742         convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3743         newp = &new;
3744      }
3745
3746      SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3747
3748      if (ARG3 != 0 && SUCCESS && RES == 0) {
3749         struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
3750
3751         oldold->ksa_handler = oldp->ksa_handler;
3752         oldold->sa_flags = oldp->sa_flags;
3753         oldold->sa_restorer = oldp->sa_restorer;
3754         oldold->sa_mask = oldp->sa_mask.sig[0];
3755      }
3756  }
3757}
3758POST(sys_sigaction)
3759{
3760   vg_assert(SUCCESS);
3761   if (RES == 0 && ARG3 != 0)
3762      POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3763}
3764#endif
3765
3766PRE(sys_signalfd)
3767{
3768   PRINT("sys_signalfd ( %d, %#lx, %llu )", (Int)ARG1,ARG2,(ULong)ARG3);
3769   PRE_REG_READ3(long, "sys_signalfd",
3770                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3771   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3772   if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3773      SET_STATUS_Failure( VKI_EBADF );
3774}
3775POST(sys_signalfd)
3776{
3777   if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3778      VG_(close)(RES);
3779      SET_STATUS_Failure( VKI_EMFILE );
3780   } else {
3781      if (VG_(clo_track_fds))
3782         ML_(record_fd_open_nameless) (tid, RES);
3783   }
3784}
3785
3786PRE(sys_signalfd4)
3787{
3788   PRINT("sys_signalfd4 ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
3789   PRE_REG_READ4(long, "sys_signalfd4",
3790                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3791   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3792   if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3793      SET_STATUS_Failure( VKI_EBADF );
3794}
3795POST(sys_signalfd4)
3796{
3797   if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3798      VG_(close)(RES);
3799      SET_STATUS_Failure( VKI_EMFILE );
3800   } else {
3801      if (VG_(clo_track_fds))
3802         ML_(record_fd_open_nameless) (tid, RES);
3803   }
3804}
3805
3806
3807/* ---------------------------------------------------------------------
3808   rt_sig* wrappers
3809   ------------------------------------------------------------------ */
3810
3811PRE(sys_rt_sigaction)
3812{
3813   PRINT("sys_rt_sigaction ( %ld, %#lx, %#lx, %lu )", SARG1, ARG2, ARG3, ARG4);
3814   PRE_REG_READ4(long, "rt_sigaction",
3815                 int, signum, const struct sigaction *, act,
3816                 struct sigaction *, oldact, vki_size_t, sigsetsize);
3817
3818   if (ARG2 != 0) {
3819      vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
3820      PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3821      PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3822      PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3823      if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
3824          && (sa->sa_flags & VKI_SA_RESTORER))
3825         PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3826   }
3827   if (ARG3 != 0)
3828      PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3829
3830   /* If the new or old sigaction is not NULL, but the structs
3831      aren't accessible then sigaction returns EFAULT and we cannot
3832      use either struct for our own bookkeeping. Just fail early. */
3833   if (ARG2 != 0
3834       && ! ML_(safe_to_deref)((void *)ARG2,
3835                               sizeof(vki_sigaction_toK_t))) {
3836      VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
3837                (void *)ARG2);
3838      SET_STATUS_Failure ( VKI_EFAULT );
3839   } else if ((ARG3 != 0
3840               && ! ML_(safe_to_deref)((void *)ARG3,
3841                                       sizeof(vki_sigaction_fromK_t)))) {
3842      VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
3843                (void *)ARG3);
3844      SET_STATUS_Failure ( VKI_EFAULT );
3845   } else {
3846
3847      // XXX: doesn't seem right to be calling do_sys_sigaction for
3848      // sys_rt_sigaction... perhaps this function should be renamed
3849      // VG_(do_sys_rt_sigaction)()  --njn
3850
3851      SET_STATUS_from_SysRes(
3852         VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
3853                               (vki_sigaction_fromK_t *)ARG3)
3854      );
3855   }
3856}
3857POST(sys_rt_sigaction)
3858{
3859   vg_assert(SUCCESS);
3860   if (RES == 0 && ARG3 != 0)
3861      POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3862}
3863
3864PRE(sys_rt_sigprocmask)
3865{
3866   PRINT("sys_rt_sigprocmask ( %ld, %#lx, %#lx, %lu )",
3867         SARG1, ARG2, ARG3, ARG4);
3868   PRE_REG_READ4(long, "rt_sigprocmask",
3869                 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3870                 vki_size_t, sigsetsize);
3871   if (ARG2 != 0)
3872      PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3873   if (ARG3 != 0)
3874      PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3875
3876   // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3877   // Since we want to use the set and oldset for bookkeeping we also want
3878   // to make sure they are addressable otherwise, like the kernel, we EFAULT.
3879   if (sizeof(vki_sigset_t) != ARG4)
3880      SET_STATUS_Failure( VKI_EINVAL );
3881   else if (ARG2 != 0
3882             && ! ML_(safe_to_deref)((void *)ARG2, sizeof(vki_sigset_t))) {
3883            VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
3884                      (void *)ARG2);
3885            SET_STATUS_Failure ( VKI_EFAULT );
3886         }
3887   else if (ARG3 != 0
3888             && ! ML_(safe_to_deref)((void *)ARG3, sizeof(vki_sigset_t))) {
3889            VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
3890                      (void *)ARG3);
3891            SET_STATUS_Failure ( VKI_EFAULT );
3892         }
3893
3894   else {
3895      SET_STATUS_from_SysRes(
3896                  VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3897                                            (vki_sigset_t*) ARG2,
3898                                            (vki_sigset_t*) ARG3 )
3899      );
3900   }
3901
3902   if (SUCCESS)
3903      *flags |= SfPollAfter;
3904}
3905POST(sys_rt_sigprocmask)
3906{
3907   vg_assert(SUCCESS);
3908   if (RES == 0 && ARG3 != 0)
3909      POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3910}
3911
3912PRE(sys_rt_sigpending)
3913{
3914   PRINT( "sys_rt_sigpending ( %#lx )", ARG1 );
3915   PRE_REG_READ2(long, "rt_sigpending",
3916                 vki_sigset_t *, set, vki_size_t, sigsetsize);
3917   PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
3918}
3919POST(sys_rt_sigpending)
3920{
3921   POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3922}
3923
3924PRE(sys_rt_sigtimedwait)
3925{
3926   *flags |= SfMayBlock;
3927   PRINT("sys_rt_sigtimedwait ( %#lx, %#lx, %#lx, %lu )",
3928         ARG1, ARG2, ARG3, ARG4);
3929   PRE_REG_READ4(long, "rt_sigtimedwait",
3930                 const vki_sigset_t *, set, vki_siginfo_t *, info,
3931                 const struct timespec *, timeout, vki_size_t, sigsetsize);
3932   if (ARG1 != 0)
3933      PRE_MEM_READ(  "rt_sigtimedwait(set)",  ARG1, sizeof(vki_sigset_t));
3934   if (ARG2 != 0)
3935      PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
3936   if (ARG3 != 0)
3937      PRE_MEM_READ( "rt_sigtimedwait(timeout)",
3938                    ARG3, sizeof(struct vki_timespec) );
3939}
3940POST(sys_rt_sigtimedwait)
3941{
3942   if (ARG2 != 0)
3943      POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3944}
3945
3946PRE(sys_rt_sigqueueinfo)
3947{
3948   PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#lx)", SARG1, SARG2, ARG3);
3949   PRE_REG_READ3(long, "rt_sigqueueinfo",
3950                 int, pid, int, sig, vki_siginfo_t *, uinfo);
3951   if (ARG2 != 0)
3952      PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
3953}
3954POST(sys_rt_sigqueueinfo)
3955{
3956   if (!ML_(client_signal_OK)(ARG2))
3957      SET_STATUS_Failure( VKI_EINVAL );
3958}
3959
3960PRE(sys_rt_tgsigqueueinfo)
3961{
3962   PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#lx)",
3963         SARG1, SARG2, SARG3, ARG4);
3964   PRE_REG_READ4(long, "rt_tgsigqueueinfo",
3965                 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
3966   if (ARG3 != 0)
3967      PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
3968}
3969
3970POST(sys_rt_tgsigqueueinfo)
3971{
3972   if (!ML_(client_signal_OK)(ARG3))
3973      SET_STATUS_Failure( VKI_EINVAL );
3974}
3975
3976// XXX: x86-specific?  The kernel prototypes for the different archs are
3977//      hard to decipher.
3978PRE(sys_rt_sigsuspend)
3979{
3980   /* The C library interface to sigsuspend just takes a pointer to
3981      a signal mask but this system call has two arguments - a pointer
3982      to the mask and the number of bytes used by it. The kernel insists
3983      on the size being equal to sizeof(sigset_t) however and will just
3984      return EINVAL if it isn't.
3985    */
3986   *flags |= SfMayBlock;
3987   PRINT("sys_rt_sigsuspend ( %#lx, %lu )", ARG1, ARG2 );
3988   PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
3989   if (ARG1 != (Addr)NULL) {
3990      PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
3991      if (ML_(safe_to_deref)((vki_sigset_t *) ARG1, sizeof(vki_sigset_t))) {
3992         VG_(sigdelset)((vki_sigset_t *) ARG1, VG_SIGVGKILL);
3993         /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
3994            be killable by VG_(nuke_all_threads_except).
3995            We thus silently ignore the user request to mask this signal.
3996            Note that this is similar to what is done for e.g.
3997            sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
3998      } else {
3999         SET_STATUS_Failure(VKI_EFAULT);
4000      }
4001   }
4002}
4003
4004/* ---------------------------------------------------------------------
4005   linux msg* wrapper helpers
4006   ------------------------------------------------------------------ */
4007
4008void
4009ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4010                            UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4011{
4012   /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4013   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4014   PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4015   PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4016}
4017
4018void
4019ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4020                            UWord arg0, UWord arg1, UWord arg2,
4021                            UWord arg3, UWord arg4 )
4022{
4023   /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4024                     long msgtyp, int msgflg); */
4025   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4026   PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4027   PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4028}
4029void
4030ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4031                             UWord res,
4032                             UWord arg0, UWord arg1, UWord arg2,
4033                             UWord arg3, UWord arg4 )
4034{
4035   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4036   POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4037   POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4038}
4039
4040void
4041ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4042                            UWord arg0, UWord arg1, UWord arg2 )
4043{
4044   /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4045   switch (arg1 /* cmd */) {
4046   case VKI_IPC_INFO:
4047   case VKI_MSG_INFO:
4048   case VKI_IPC_INFO|VKI_IPC_64:
4049   case VKI_MSG_INFO|VKI_IPC_64:
4050      PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4051                     arg2, sizeof(struct vki_msginfo) );
4052      break;
4053   case VKI_IPC_STAT:
4054   case VKI_MSG_STAT:
4055      PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4056                     arg2, sizeof(struct vki_msqid_ds) );
4057      break;
4058   case VKI_IPC_STAT|VKI_IPC_64:
4059   case VKI_MSG_STAT|VKI_IPC_64:
4060      PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4061                     arg2, sizeof(struct vki_msqid64_ds) );
4062      break;
4063   case VKI_IPC_SET:
4064      PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4065                    arg2, sizeof(struct vki_msqid_ds) );
4066      break;
4067   case VKI_IPC_SET|VKI_IPC_64:
4068      PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4069                    arg2, sizeof(struct vki_msqid64_ds) );
4070      break;
4071   }
4072}
4073void
4074ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4075                             UWord res,
4076                             UWord arg0, UWord arg1, UWord arg2 )
4077{
4078   switch (arg1 /* cmd */) {
4079   case VKI_IPC_INFO:
4080   case VKI_MSG_INFO:
4081   case VKI_IPC_INFO|VKI_IPC_64:
4082   case VKI_MSG_INFO|VKI_IPC_64:
4083      POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4084      break;
4085   case VKI_IPC_STAT:
4086   case VKI_MSG_STAT:
4087      POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4088      break;
4089   case VKI_IPC_STAT|VKI_IPC_64:
4090   case VKI_MSG_STAT|VKI_IPC_64:
4091      POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4092      break;
4093   }
4094}
4095
4096/* ---------------------------------------------------------------------
4097   Generic handler for sys_ipc
4098   Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4099   are either direct system calls, or are all implemented via sys_ipc.
4100   ------------------------------------------------------------------ */
4101#ifdef __NR_ipc
4102static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4103{
4104   Addr* a_p = (Addr*)a;
4105   PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4106   return *a_p;
4107}
4108
4109static Bool semctl_cmd_has_4args (UWord cmd)
4110{
4111   switch (cmd & ~VKI_IPC_64)
4112   {
4113   case VKI_IPC_INFO:
4114   case VKI_SEM_INFO:
4115   case VKI_IPC_STAT:
4116   case VKI_SEM_STAT:
4117   case VKI_IPC_SET:
4118   case VKI_GETALL:
4119   case VKI_SETALL:
4120      return True;
4121   default:
4122      return False;
4123   }
4124}
4125
4126PRE(sys_ipc)
4127{
4128   PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4129         ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4130
4131   switch (ARG1 /* call */) {
4132   case VKI_SEMOP:
4133      PRE_REG_READ5(int, "ipc",
4134                    vki_uint, call, int, first, int, second, int, third,
4135                    void *, ptr);
4136      ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4137      *flags |= SfMayBlock;
4138      break;
4139   case VKI_SEMGET:
4140      PRE_REG_READ4(int, "ipc",
4141                    vki_uint, call, int, first, int, second, int, third);
4142      break;
4143   case VKI_SEMCTL:
4144   {
4145      PRE_REG_READ5(int, "ipc",
4146                    vki_uint, call, int, first, int, second, int, third,
4147                    void *, ptr);
4148      UWord arg;
4149      if (semctl_cmd_has_4args(ARG4))
4150         arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4151      else
4152         arg = 0;
4153      ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4154      break;
4155   }
4156   case VKI_SEMTIMEDOP:
4157      PRE_REG_READ6(int, "ipc",
4158                    vki_uint, call, int, first, int, second, int, third,
4159                    void *, ptr, long, fifth);
4160      ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4161      *flags |= SfMayBlock;
4162      break;
4163   case VKI_MSGSND:
4164      PRE_REG_READ5(int, "ipc",
4165                    vki_uint, call, int, first, int, second, int, third,
4166                    void *, ptr);
4167      ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4168      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4169         *flags |= SfMayBlock;
4170      break;
4171   case VKI_MSGRCV:
4172   {
4173      PRE_REG_READ5(int, "ipc",
4174                    vki_uint, call, int, first, int, second, int, third,
4175                    void *, ptr);
4176      Addr msgp;
4177      Word msgtyp;
4178
4179      msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
4180                         "msgrcv(msgp)" );
4181      msgtyp = deref_Addr( tid,
4182                           (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
4183                           "msgrcv(msgp)" );
4184
4185      ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4186
4187      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4188         *flags |= SfMayBlock;
4189      break;
4190   }
4191   case VKI_MSGGET:
4192      PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4193      break;
4194   case VKI_MSGCTL:
4195      PRE_REG_READ5(int, "ipc",
4196                    vki_uint, call, int, first, int, second, int, third,
4197                    void *, ptr);
4198      ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4199      break;
4200   case VKI_SHMAT:
4201   {
4202      PRE_REG_READ5(int, "ipc",
4203                    vki_uint, call, int, first, int, second, int, third,
4204                    void *, ptr);
4205      UWord w;
4206      PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4207      w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4208      if (w == 0)
4209         SET_STATUS_Failure( VKI_EINVAL );
4210      else
4211         ARG5 = w;
4212      break;
4213   }
4214   case VKI_SHMDT:
4215      PRE_REG_READ5(int, "ipc",
4216                    vki_uint, call, int, first, int, second, int, third,
4217                    void *, ptr);
4218      if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4219	 SET_STATUS_Failure( VKI_EINVAL );
4220      break;
4221   case VKI_SHMGET:
4222      PRE_REG_READ4(int, "ipc",
4223                    vki_uint, call, int, first, int, second, int, third);
4224      if (ARG4 & VKI_SHM_HUGETLB) {
4225         static Bool warning_given = False;
4226         ARG4 &= ~VKI_SHM_HUGETLB;
4227         if (!warning_given) {
4228            warning_given = True;
4229            VG_(umsg)(
4230               "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4231         }
4232      }
4233      break;
4234   case VKI_SHMCTL: /* IPCOP_shmctl */
4235      PRE_REG_READ5(int, "ipc",
4236                    vki_uint, call, int, first, int, second, int, third,
4237                    void *, ptr);
4238      ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4239      break;
4240   default:
4241      VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4242      VG_(core_panic)("... bye!\n");
4243      break; /*NOTREACHED*/
4244   }
4245}
4246
4247POST(sys_ipc)
4248{
4249   vg_assert(SUCCESS);
4250   switch (ARG1 /* call */) {
4251   case VKI_SEMOP:
4252   case VKI_SEMGET:
4253      break;
4254   case VKI_SEMCTL:
4255   {
4256      UWord arg;
4257      if (semctl_cmd_has_4args(ARG4))
4258         arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4259      else
4260         arg = 0;
4261      ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4262      break;
4263   }
4264   case VKI_SEMTIMEDOP:
4265   case VKI_MSGSND:
4266      break;
4267   case VKI_MSGRCV:
4268   {
4269      Addr msgp;
4270      Word msgtyp;
4271
4272      msgp = deref_Addr( tid,
4273			 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
4274			 "msgrcv(msgp)" );
4275      msgtyp = deref_Addr( tid,
4276			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
4277			   "msgrcv(msgp)" );
4278
4279      ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4280      break;
4281   }
4282   case VKI_MSGGET:
4283      break;
4284   case VKI_MSGCTL:
4285      ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4286      break;
4287   case VKI_SHMAT:
4288   {
4289      Addr addr;
4290
4291      /* force readability. before the syscall it is
4292       * indeed uninitialized, as can be seen in
4293       * glibc/sysdeps/unix/sysv/linux/shmat.c */
4294      POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4295
4296      addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4297      ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4298      break;
4299   }
4300   case VKI_SHMDT:
4301      ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4302      break;
4303   case VKI_SHMGET:
4304      break;
4305   case VKI_SHMCTL:
4306      ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4307      break;
4308   default:
4309      VG_(message)(Vg_DebugMsg,
4310		   "FATAL: unhandled syscall(ipc) %lu\n",
4311		   ARG1 );
4312      VG_(core_panic)("... bye!\n");
4313      break; /*NOTREACHED*/
4314   }
4315}
4316#endif
4317
4318PRE(sys_semget)
4319{
4320   PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4321   PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4322}
4323
4324PRE(sys_semop)
4325{
4326   *flags |= SfMayBlock;
4327   PRINT("sys_semop ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
4328   PRE_REG_READ3(long, "semop",
4329                 int, semid, struct sembuf *, sops, unsigned, nsoops);
4330   ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4331}
4332
4333PRE(sys_semctl)
4334{
4335   switch (ARG3 & ~VKI_IPC_64) {
4336   case VKI_IPC_INFO:
4337   case VKI_SEM_INFO:
4338      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
4339      PRE_REG_READ4(long, "semctl",
4340                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4341      break;
4342   case VKI_IPC_STAT:
4343   case VKI_SEM_STAT:
4344   case VKI_IPC_SET:
4345      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
4346      PRE_REG_READ4(long, "semctl",
4347                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4348      break;
4349   case VKI_GETALL:
4350   case VKI_SETALL:
4351      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
4352      PRE_REG_READ4(long, "semctl",
4353                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
4354      break;
4355   default:
4356      PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4357      PRE_REG_READ3(long, "semctl",
4358                    int, semid, int, semnum, int, cmd);
4359      break;
4360   }
4361#ifdef VGP_amd64_linux
4362   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4363#else
4364   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4365#endif
4366}
4367
4368POST(sys_semctl)
4369{
4370#ifdef VGP_amd64_linux
4371   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4372#else
4373   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4374#endif
4375}
4376
4377PRE(sys_semtimedop)
4378{
4379   *flags |= SfMayBlock;
4380   PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
4381   PRE_REG_READ4(long, "semtimedop",
4382                 int, semid, struct sembuf *, sops, unsigned, nsoops,
4383                 struct timespec *, timeout);
4384   ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4385}
4386
4387PRE(sys_msgget)
4388{
4389   PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4390   PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4391}
4392
4393PRE(sys_msgsnd)
4394{
4395   PRINT("sys_msgsnd ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
4396   PRE_REG_READ4(long, "msgsnd",
4397                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4398   ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4399   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4400      *flags |= SfMayBlock;
4401}
4402
4403PRE(sys_msgrcv)
4404{
4405   PRINT("sys_msgrcv ( %ld, %#lx, %lu, %ld, %ld )",
4406         SARG1, ARG2, ARG3, SARG4, SARG5);
4407   PRE_REG_READ5(long, "msgrcv",
4408                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4409                 long, msgytp, int, msgflg);
4410   ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4411   if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4412      *flags |= SfMayBlock;
4413}
4414POST(sys_msgrcv)
4415{
4416   ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4417}
4418
4419PRE(sys_msgctl)
4420{
4421   PRINT("sys_msgctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
4422   PRE_REG_READ3(long, "msgctl",
4423                 int, msqid, int, cmd, struct msqid_ds *, buf);
4424   ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
4425}
4426
4427POST(sys_msgctl)
4428{
4429   ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
4430}
4431
4432PRE(sys_shmget)
4433{
4434   PRINT("sys_shmget ( %ld, %lu, %ld )", SARG1, ARG2, SARG3);
4435   PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
4436   if (ARG3 & VKI_SHM_HUGETLB) {
4437      static Bool warning_given = False;
4438      ARG3 &= ~VKI_SHM_HUGETLB;
4439      if (!warning_given) {
4440         warning_given = True;
4441         VG_(umsg)(
4442            "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4443      }
4444   }
4445}
4446
4447PRE(sys_shmat)
4448{
4449   UWord arg2tmp;
4450   PRINT("sys_shmat ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
4451   PRE_REG_READ3(long, "shmat",
4452                 int, shmid, const void *, shmaddr, int, shmflg);
4453#if defined(VGP_arm_linux)
4454   /* Round the attach address down to an VKI_SHMLBA boundary if the
4455      client requested rounding.  See #222545.  This is necessary only
4456      on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
4457      other linux targets it is the same as the page size. */
4458   if (ARG3 & VKI_SHM_RND)
4459      ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
4460#endif
4461   arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
4462   if (arg2tmp == 0)
4463      SET_STATUS_Failure( VKI_EINVAL );
4464   else
4465      ARG2 = arg2tmp;  // used in POST
4466}
4467
4468POST(sys_shmat)
4469{
4470   ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
4471}
4472
4473PRE(sys_shmdt)
4474{
4475   PRINT("sys_shmdt ( %#lx )",ARG1);
4476   PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
4477   if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
4478      SET_STATUS_Failure( VKI_EINVAL );
4479}
4480
4481POST(sys_shmdt)
4482{
4483   ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
4484}
4485
4486PRE(sys_shmctl)
4487{
4488   PRINT("sys_shmctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
4489   PRE_REG_READ3(long, "shmctl",
4490                 int, shmid, int, cmd, struct shmid_ds *, buf);
4491#ifdef VGP_amd64_linux
4492   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
4493#else
4494   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
4495#endif
4496}
4497
4498POST(sys_shmctl)
4499{
4500#ifdef VGP_amd64_linux
4501   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
4502#else
4503   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
4504#endif
4505}
4506
4507
4508/* ---------------------------------------------------------------------
4509   Generic handler for sys_socketcall
4510   Depending on the platform, some socket related syscalls (e.g. socketpair,
4511   socket, bind, ...)
4512   are either direct system calls, or are all implemented via sys_socketcall.
4513   ------------------------------------------------------------------ */
4514#ifdef __NR_socketcall
4515PRE(sys_socketcall)
4516{
4517#  define ARG2_0  (((UWord*)ARG2)[0])
4518#  define ARG2_1  (((UWord*)ARG2)[1])
4519#  define ARG2_2  (((UWord*)ARG2)[2])
4520#  define ARG2_3  (((UWord*)ARG2)[3])
4521#  define ARG2_4  (((UWord*)ARG2)[4])
4522#  define ARG2_5  (((UWord*)ARG2)[5])
4523
4524// call PRE_MEM_READ and check for EFAULT result.
4525#define PRE_MEM_READ_ef(msg, arg, size)                         \
4526   {                                                            \
4527      PRE_MEM_READ( msg, arg, size);                            \
4528      if (!ML_(valid_client_addr)(arg, size, tid, NULL)) {      \
4529         SET_STATUS_Failure( VKI_EFAULT );                      \
4530         break;                                                 \
4531      }                                                         \
4532   }
4533
4534   *flags |= SfMayBlock;
4535   PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
4536   PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4537
4538   switch (ARG1 /* request */) {
4539
4540   case VKI_SYS_SOCKETPAIR:
4541      /* int socketpair(int d, int type, int protocol, int sv[2]); */
4542      PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
4543      ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4544      break;
4545
4546   case VKI_SYS_SOCKET:
4547      /* int socket(int domain, int type, int protocol); */
4548      PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
4549      break;
4550
4551   case VKI_SYS_BIND:
4552      /* int bind(int sockfd, struct sockaddr *my_addr,
4553                  int addrlen); */
4554      PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
4555      ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
4556      break;
4557
4558   case VKI_SYS_LISTEN:
4559      /* int listen(int s, int backlog); */
4560      PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
4561      break;
4562
4563   case VKI_SYS_ACCEPT:
4564      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4565      PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4566      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4567      break;
4568
4569   case VKI_SYS_ACCEPT4:
4570      /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4571      PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4572      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4573      break;
4574
4575   case VKI_SYS_SENDTO:
4576      /* int sendto(int s, const void *msg, int len,
4577                    unsigned int flags,
4578                    const struct sockaddr *to, int tolen); */
4579      PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4580      ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4581                                   ARG2_3, ARG2_4, ARG2_5 );
4582      break;
4583
4584   case VKI_SYS_SEND:
4585      /* int send(int s, const void *msg, size_t len, int flags); */
4586      PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4587      ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4588      break;
4589
4590   case VKI_SYS_RECVFROM:
4591      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4592         struct sockaddr *from, int *fromlen); */
4593      PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4594      ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4595                                     ARG2_3, ARG2_4, ARG2_5 );
4596      break;
4597
4598   case VKI_SYS_RECV:
4599      /* int recv(int s, void *buf, int len, unsigned int flags); */
4600      /* man 2 recv says:
4601         The  recv call is normally used only on a connected socket
4602         (see connect(2)) and is identical to recvfrom with a  NULL
4603         from parameter.
4604      */
4605      PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4606      ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4607      break;
4608
4609   case VKI_SYS_CONNECT:
4610      /* int connect(int sockfd,
4611                     struct sockaddr *serv_addr, int addrlen ); */
4612      PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4613      ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4614      break;
4615
4616   case VKI_SYS_SETSOCKOPT:
4617      /* int setsockopt(int s, int level, int optname,
4618                        const void *optval, int optlen); */
4619      PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4620      ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4621                                     ARG2_3, ARG2_4 );
4622      break;
4623
4624   case VKI_SYS_GETSOCKOPT:
4625      /* int getsockopt(int s, int level, int optname,
4626                        void *optval, socklen_t *optlen); */
4627      PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4628      ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4629                                     ARG2_3, ARG2_4 );
4630      break;
4631
4632   case VKI_SYS_GETSOCKNAME:
4633      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4634      PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4635      ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4636      break;
4637
4638   case VKI_SYS_GETPEERNAME:
4639      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4640      PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4641      ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4642      break;
4643
4644   case VKI_SYS_SHUTDOWN:
4645      /* int shutdown(int s, int how); */
4646      PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4647      break;
4648
4649   case VKI_SYS_SENDMSG:
4650      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4651      PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4652      ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
4653      break;
4654
4655   case VKI_SYS_RECVMSG:
4656      /* int recvmsg(int s, struct msghdr *msg, int flags); */
4657      PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4658      ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
4659      break;
4660
4661   case VKI_SYS_RECVMMSG:
4662      /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4663                      struct timespec *timeout); */
4664      PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4665      ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4666                                   ARG2_4 );
4667      break;
4668
4669   case VKI_SYS_SENDMMSG:
4670      /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4671      PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4672      ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4673      break;
4674
4675   default:
4676      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4677      SET_STATUS_Failure( VKI_EINVAL );
4678      break;
4679   }
4680#  undef ARG2_0
4681#  undef ARG2_1
4682#  undef ARG2_2
4683#  undef ARG2_3
4684#  undef ARG2_4
4685#  undef ARG2_5
4686}
4687
4688POST(sys_socketcall)
4689{
4690#  define ARG2_0  (((UWord*)ARG2)[0])
4691#  define ARG2_1  (((UWord*)ARG2)[1])
4692#  define ARG2_2  (((UWord*)ARG2)[2])
4693#  define ARG2_3  (((UWord*)ARG2)[3])
4694#  define ARG2_4  (((UWord*)ARG2)[4])
4695#  define ARG2_5  (((UWord*)ARG2)[5])
4696
4697   SysRes r;
4698   vg_assert(SUCCESS);
4699   switch (ARG1 /* request */) {
4700
4701   case VKI_SYS_SOCKETPAIR:
4702      r = ML_(generic_POST_sys_socketpair)(
4703             tid, VG_(mk_SysRes_Success)(RES),
4704             ARG2_0, ARG2_1, ARG2_2, ARG2_3
4705          );
4706      SET_STATUS_from_SysRes(r);
4707      break;
4708
4709   case VKI_SYS_SOCKET:
4710      r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4711      SET_STATUS_from_SysRes(r);
4712      break;
4713
4714   case VKI_SYS_BIND:
4715      /* int bind(int sockfd, struct sockaddr *my_addr,
4716			int addrlen); */
4717      break;
4718
4719   case VKI_SYS_LISTEN:
4720      /* int listen(int s, int backlog); */
4721      break;
4722
4723   case VKI_SYS_ACCEPT:
4724   case VKI_SYS_ACCEPT4:
4725      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4726      /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4727     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4728                                            ARG2_0, ARG2_1, ARG2_2 );
4729     SET_STATUS_from_SysRes(r);
4730     break;
4731
4732   case VKI_SYS_SENDTO:
4733      break;
4734
4735   case VKI_SYS_SEND:
4736      break;
4737
4738   case VKI_SYS_RECVFROM:
4739      ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4740                                           ARG2_0, ARG2_1, ARG2_2,
4741                                           ARG2_3, ARG2_4, ARG2_5 );
4742      break;
4743
4744   case VKI_SYS_RECV:
4745      ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4746      break;
4747
4748   case VKI_SYS_CONNECT:
4749      break;
4750
4751   case VKI_SYS_SETSOCKOPT:
4752      break;
4753
4754   case VKI_SYS_GETSOCKOPT:
4755      ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4756                                      ARG2_0, ARG2_1,
4757                                      ARG2_2, ARG2_3, ARG2_4 );
4758      break;
4759
4760   case VKI_SYS_GETSOCKNAME:
4761      ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4762                                              ARG2_0, ARG2_1, ARG2_2 );
4763      break;
4764
4765   case VKI_SYS_GETPEERNAME:
4766      ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4767                                              ARG2_0, ARG2_1, ARG2_2 );
4768      break;
4769
4770   case VKI_SYS_SHUTDOWN:
4771      break;
4772
4773   case VKI_SYS_SENDMSG:
4774      break;
4775
4776   case VKI_SYS_RECVMSG:
4777      ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
4778      break;
4779
4780   case VKI_SYS_RECVMMSG:
4781      ML_(linux_POST_sys_recvmmsg)( tid, RES,
4782                                    ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4783      break;
4784
4785   case VKI_SYS_SENDMMSG:
4786      ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4787      break;
4788
4789   default:
4790      VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4791      VG_(core_panic)("... bye!\n");
4792      break; /*NOTREACHED*/
4793   }
4794#  undef ARG2_0
4795#  undef ARG2_1
4796#  undef ARG2_2
4797#  undef ARG2_3
4798#  undef ARG2_4
4799#  undef ARG2_5
4800}
4801#endif
4802
4803PRE(sys_socket)
4804{
4805   PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4806   PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4807}
4808POST(sys_socket)
4809{
4810   SysRes r;
4811   vg_assert(SUCCESS);
4812   r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4813   SET_STATUS_from_SysRes(r);
4814}
4815
4816PRE(sys_setsockopt)
4817{
4818   PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %lu )",
4819         SARG1, SARG2, SARG3, ARG4, ARG5);
4820   PRE_REG_READ5(long, "setsockopt",
4821                 int, s, int, level, int, optname,
4822                 const void *, optval, unsigned, optlen); // socklen_t
4823   ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4824}
4825
4826PRE(sys_getsockopt)
4827{
4828   PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %ld )",
4829         SARG1, SARG2, SARG3, ARG4, SARG5);
4830   PRE_REG_READ5(long, "getsockopt",
4831                 int, s, int, level, int, optname,
4832                 void *, optval, int, *optlen);
4833   ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4834}
4835POST(sys_getsockopt)
4836{
4837   vg_assert(SUCCESS);
4838   ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4839                                       ARG1,ARG2,ARG3,ARG4,ARG5);
4840}
4841
4842PRE(sys_connect)
4843{
4844   *flags |= SfMayBlock;
4845   PRINT("sys_connect ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
4846   PRE_REG_READ3(long, "connect",
4847                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4848   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4849}
4850
4851PRE(sys_accept)
4852{
4853   *flags |= SfMayBlock;
4854   PRINT("sys_accept ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4855   PRE_REG_READ3(long, "accept",
4856                 int, s, struct sockaddr *, addr, int *, addrlen);
4857   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4858}
4859POST(sys_accept)
4860{
4861   SysRes r;
4862   vg_assert(SUCCESS);
4863   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4864                                         ARG1,ARG2,ARG3);
4865   SET_STATUS_from_SysRes(r);
4866}
4867
4868PRE(sys_accept4)
4869{
4870   *flags |= SfMayBlock;
4871   PRINT("sys_accept4 ( %ld, %#lx, %#lx, %ld )", SARG1, ARG2, ARG3, SARG4);
4872   PRE_REG_READ4(long, "accept4",
4873                 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
4874   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4875}
4876POST(sys_accept4)
4877{
4878   SysRes r;
4879   vg_assert(SUCCESS);
4880   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4881                                         ARG1,ARG2,ARG3);
4882   SET_STATUS_from_SysRes(r);
4883}
4884
4885PRE(sys_send)
4886{
4887   *flags |= SfMayBlock;
4888   PRINT("sys_send ( %ld, %#lx, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
4889   PRE_REG_READ4(long, "send",
4890                 int, s, const void *, msg, vki_size_t, len,
4891                 int, flags);
4892
4893   ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
4894}
4895
4896PRE(sys_sendto)
4897{
4898   *flags |= SfMayBlock;
4899   PRINT("sys_sendto ( %ld, %#lx, %lu, %lu, %#lx, %ld )",
4900         SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
4901   PRE_REG_READ6(long, "sendto",
4902                 int, s, const void *, msg, vki_size_t, len,
4903                 unsigned int, flags,
4904                 const struct sockaddr *, to, int, tolen);
4905   ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4906}
4907
4908PRE (sys_recv)
4909{
4910  *flags |= SfMayBlock;
4911  PRINT ("sys_recv ( %ld, %#lx, %lu, %lu )", SARG1, ARG2, ARG3, ARG4);
4912  PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
4913                 unsigned int, flags);
4914  ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
4915}
4916
4917POST (sys_recv)
4918{
4919  ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
4920}
4921
4922PRE(sys_recvfrom)
4923{
4924   *flags |= SfMayBlock;
4925   PRINT("sys_recvfrom ( %ld, %#lx, %lu, %lu, %#lx, %#lx )",
4926         SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4927   PRE_REG_READ6(long, "recvfrom",
4928                 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
4929                 struct sockaddr *, from, int *, fromlen);
4930   ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4931}
4932POST(sys_recvfrom)
4933{
4934   vg_assert(SUCCESS);
4935   ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
4936                                       ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4937}
4938
4939PRE(sys_sendmsg)
4940{
4941   *flags |= SfMayBlock;
4942   PRINT("sys_sendmsg ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
4943   PRE_REG_READ3(long, "sendmsg",
4944                 int, s, const struct msghdr *, msg, unsigned int, flags);
4945   ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4946}
4947
4948PRE(sys_recvmsg)
4949{
4950   *flags |= SfMayBlock;
4951   PRINT("sys_recvmsg ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
4952   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
4953                 unsigned int, flags);
4954   ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4955}
4956POST(sys_recvmsg)
4957{
4958   ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
4959}
4960
4961PRE(sys_shutdown)
4962{
4963   *flags |= SfMayBlock;
4964   PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
4965   PRE_REG_READ2(int, "shutdown", int, s, int, how);
4966}
4967
4968PRE(sys_bind)
4969{
4970   PRINT("sys_bind ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
4971   PRE_REG_READ3(long, "bind",
4972                 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
4973   ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
4974}
4975
4976PRE(sys_listen)
4977{
4978   PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
4979   PRE_REG_READ2(long, "listen", int, s, int, backlog);
4980}
4981
4982PRE(sys_getsockname)
4983{
4984   PRINT("sys_getsockname ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4985   PRE_REG_READ3(long, "getsockname",
4986                 int, s, struct sockaddr *, name, int *, namelen);
4987   ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
4988}
4989POST(sys_getsockname)
4990{
4991   vg_assert(SUCCESS);
4992   ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
4993                                          ARG1,ARG2,ARG3);
4994}
4995
4996PRE(sys_getpeername)
4997{
4998   PRINT("sys_getpeername ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4999   PRE_REG_READ3(long, "getpeername",
5000                 int, s, struct sockaddr *, name, int *, namelen);
5001   ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5002}
5003POST(sys_getpeername)
5004{
5005   vg_assert(SUCCESS);
5006   ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5007                                          ARG1,ARG2,ARG3);
5008}
5009
5010PRE(sys_socketpair)
5011{
5012   PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
5013   PRE_REG_READ4(long, "socketpair",
5014                 int, d, int, type, int, protocol, int*, sv);
5015   ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5016}
5017POST(sys_socketpair)
5018{
5019   vg_assert(SUCCESS);
5020   ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5021                                         ARG1,ARG2,ARG3,ARG4);
5022}
5023
5024
5025/* ---------------------------------------------------------------------
5026   *at wrappers
5027   ------------------------------------------------------------------ */
5028
5029PRE(sys_openat)
5030{
5031   HChar  name[30];   // large enough
5032   SysRes sres;
5033
5034   if (ARG3 & VKI_O_CREAT) {
5035      // 4-arg version
5036      PRINT("sys_openat ( %ld, %#lx(%s), %ld, %ld )",
5037            SARG1, ARG2, (HChar*)ARG2, SARG3, SARG4);
5038      PRE_REG_READ4(long, "openat",
5039                    int, dfd, const char *, filename, int, flags, int, mode);
5040   } else {
5041      // 3-arg version
5042      PRINT("sys_openat ( %ld, %#lx(%s), %ld )",
5043            SARG1, ARG2, (HChar*)ARG2, SARG3);
5044      PRE_REG_READ3(long, "openat",
5045                    int, dfd, const char *, filename, int, flags);
5046   }
5047
5048   PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5049
5050   /* For absolute filenames, dfd is ignored.  If dfd is AT_FDCWD,
5051      filename is relative to cwd.  When comparing dfd against AT_FDCWD,
5052      be sure only to compare the bottom 32 bits. */
5053   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
5054       && *(Char *)ARG2 != '/'
5055       && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5056       && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5057      SET_STATUS_Failure( VKI_EBADF );
5058
5059   /* Handle the case where the open is of /proc/self/cmdline or
5060      /proc/<pid>/cmdline, and just give it a copy of the fd for the
5061      fake file we cooked up at startup (in m_main).  Also, seek the
5062      cloned fd back to the start. */
5063
5064   VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5065   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
5066       && (VG_(strcmp)((HChar *)ARG2, name) == 0
5067           || VG_(strcmp)((HChar *)ARG2, "/proc/self/cmdline") == 0)) {
5068      sres = VG_(dup)( VG_(cl_cmdline_fd) );
5069      SET_STATUS_from_SysRes( sres );
5070      if (!sr_isError(sres)) {
5071         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5072         if (off < 0)
5073            SET_STATUS_Failure( VKI_EMFILE );
5074      }
5075      return;
5076   }
5077
5078   /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5079
5080   VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5081   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
5082       && (VG_(strcmp)((HChar *)ARG2, name) == 0
5083           || VG_(strcmp)((HChar *)ARG2, "/proc/self/auxv") == 0)) {
5084      sres = VG_(dup)( VG_(cl_auxv_fd) );
5085      SET_STATUS_from_SysRes( sres );
5086      if (!sr_isError(sres)) {
5087         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5088         if (off < 0)
5089            SET_STATUS_Failure( VKI_EMFILE );
5090      }
5091      return;
5092   }
5093
5094   /* Otherwise handle normally */
5095   *flags |= SfMayBlock;
5096}
5097
5098POST(sys_openat)
5099{
5100   vg_assert(SUCCESS);
5101   if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5102      VG_(close)(RES);
5103      SET_STATUS_Failure( VKI_EMFILE );
5104   } else {
5105      if (VG_(clo_track_fds))
5106         ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
5107   }
5108}
5109
5110PRE(sys_mkdirat)
5111{
5112   *flags |= SfMayBlock;
5113   PRINT("sys_mkdirat ( %ld, %#lx(%s), %ld )",
5114         SARG1, ARG2, (HChar*)ARG2, SARG3);
5115   PRE_REG_READ3(long, "mkdirat",
5116                 int, dfd, const char *, pathname, int, mode);
5117   PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5118}
5119
5120PRE(sys_mknodat)
5121{
5122   PRINT("sys_mknodat ( %ld, %#lx(%s), 0x%lx, 0x%lx )",
5123         SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4 );
5124   PRE_REG_READ4(long, "mknodat",
5125                 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5126   PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5127}
5128
5129PRE(sys_fchownat)
5130{
5131   PRINT("sys_fchownat ( %ld, %#lx(%s), 0x%lx, 0x%lx )",
5132         SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
5133   PRE_REG_READ4(long, "fchownat",
5134                 int, dfd, const char *, path,
5135                 vki_uid_t, owner, vki_gid_t, group);
5136   PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5137}
5138
5139PRE(sys_futimesat)
5140{
5141   PRINT("sys_futimesat ( %ld, %#lx(%s), %#lx )",
5142         SARG1, ARG2, (HChar*)ARG2, ARG3);
5143   PRE_REG_READ3(long, "futimesat",
5144                 int, dfd, char *, filename, struct timeval *, tvp);
5145   if (ARG2 != 0)
5146      PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5147   if (ARG3 != 0)
5148      PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5149}
5150
5151PRE(sys_utimensat)
5152{
5153   PRINT("sys_utimensat ( %ld, %#lx(%s), %#lx, 0x%lx )",
5154         SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
5155   PRE_REG_READ4(long, "utimensat",
5156                 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5157   if (ARG2 != 0)
5158      PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5159   if (ARG3 != 0)
5160      PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
5161}
5162
5163PRE(sys_newfstatat)
5164{
5165   FUSE_COMPATIBLE_MAY_BLOCK();
5166   PRINT("sys_newfstatat ( %ld, %#lx(%s), %#lx )",
5167         SARG1, ARG2, (HChar*)ARG2, ARG3);
5168   PRE_REG_READ3(long, "fstatat",
5169                 int, dfd, char *, file_name, struct stat *, buf);
5170   PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5171   PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5172}
5173
5174POST(sys_newfstatat)
5175{
5176   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5177}
5178
5179PRE(sys_unlinkat)
5180{
5181   *flags |= SfMayBlock;
5182   PRINT("sys_unlinkat ( %ld, %#lx(%s) )", SARG1, ARG2, (HChar*)ARG2);
5183   PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5184   PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5185}
5186
5187PRE(sys_renameat)
5188{
5189   PRINT("sys_renameat ( %ld, %#lx(%s), %ld, %#lx(%s) )",
5190         SARG1, ARG2, (HChar*)ARG2, SARG3, ARG4, (HChar*)ARG4);
5191   PRE_REG_READ4(long, "renameat",
5192                 int, olddfd, const char *, oldpath,
5193                 int, newdfd, const char *, newpath);
5194   PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5195   PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5196}
5197
5198PRE(sys_renameat2)
5199{
5200   PRINT("sys_renameat2 ( %ld, %#lx(%s), %ld, %#lx(%s), %lu )",
5201         SARG1, ARG2, (HChar*)ARG2, SARG3, ARG4, (HChar*)ARG4, ARG5);
5202   PRE_REG_READ5(long, "renameat2",
5203                 int, olddfd, const char *, oldpath,
5204                 int, newdfd, const char *, newpath,
5205                 unsigned int, flags);
5206   PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5207   PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5208}
5209
5210PRE(sys_linkat)
5211{
5212   *flags |= SfMayBlock;
5213   PRINT("sys_linkat ( %ld, %#lx(%s), %ld, %#lx(%s), %ld )",
5214         SARG1, ARG2, (HChar*)ARG2, SARG3, ARG4, (HChar*)ARG4, SARG5);
5215   PRE_REG_READ5(long, "linkat",
5216                 int, olddfd, const char *, oldpath,
5217                 int, newdfd, const char *, newpath,
5218                 int, flags);
5219   PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5220   PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5221}
5222
5223PRE(sys_symlinkat)
5224{
5225   *flags |= SfMayBlock;
5226   PRINT("sys_symlinkat ( %#lx(%s), %ld, %#lx(%s) )",
5227         ARG1, (HChar*)ARG1, SARG2, ARG3, (HChar*)ARG3);
5228   PRE_REG_READ3(long, "symlinkat",
5229                 const char *, oldpath, int, newdfd, const char *, newpath);
5230   PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5231   PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5232}
5233
5234PRE(sys_readlinkat)
5235{
5236   HChar name[30];       // large enough
5237   Word  saved = SYSNO;
5238
5239   PRINT("sys_readlinkat ( %ld, %#lx(%s), %#lx, %lu )",
5240         SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
5241   PRE_REG_READ4(long, "readlinkat",
5242                 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5243   PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5244   PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5245
5246   /*
5247    * Handle the case where readlinkat is looking at /proc/self/exe or
5248    * /proc/<pid>/exe.
5249    */
5250   VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5251   if (ML_(safe_to_deref)((void*)ARG2, 1)
5252       && (VG_(strcmp)((HChar *)ARG2, name) == 0
5253           || VG_(strcmp)((HChar *)ARG2, "/proc/self/exe") == 0)) {
5254      VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5255      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5256                                                      ARG3, ARG4));
5257   } else {
5258      /* Normal case */
5259      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5260   }
5261
5262   if (SUCCESS && RES > 0)
5263      POST_MEM_WRITE( ARG3, RES );
5264}
5265
5266PRE(sys_fchmodat)
5267{
5268   PRINT("sys_fchmodat ( %ld, %#lx(%s), %lu )",
5269         SARG1, ARG2, (HChar*)ARG2, ARG3);
5270   PRE_REG_READ3(long, "fchmodat",
5271                 int, dfd, const char *, path, vki_mode_t, mode);
5272   PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5273}
5274
5275PRE(sys_faccessat)
5276{
5277   PRINT("sys_faccessat ( %ld, %#lx(%s), %ld )",
5278         SARG1, ARG2, (HChar*)ARG2, SARG3);
5279   PRE_REG_READ3(long, "faccessat",
5280                 int, dfd, const char *, pathname, int, mode);
5281   PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5282}
5283
5284PRE(sys_name_to_handle_at)
5285{
5286   PRINT("sys_name_to_handle_at ( %ld, %#lx(%s), %#lx, %#lx, %ld )",
5287         SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4, SARG5);
5288   PRE_REG_READ5(int, "name_to_handle_at",
5289                 int, dfd, const char *, name,
5290                 struct vki_file_handle *, handle,
5291                 int *, mnt_id, int, flag);
5292   PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5293   if (ML_(safe_to_deref)( (void*)ARG3, sizeof(struct vki_file_handle))) {
5294      struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
5295      PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5296      PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5297   }
5298   PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5299}
5300
5301POST(sys_name_to_handle_at)
5302{
5303   struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
5304   POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5305   POST_MEM_WRITE( ARG4, sizeof(int) );
5306}
5307
5308PRE(sys_open_by_handle_at)
5309{
5310   *flags |= SfMayBlock;
5311   PRINT("sys_open_by_handle_at ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
5312   PRE_REG_READ3(int, "open_by_handle_at",
5313                 int, mountdirfd,
5314                 struct vki_file_handle *, handle,
5315                 int, flags);
5316   PRE_MEM_READ( "open_by_handle_at(handle)", ARG2, sizeof(struct vki_file_handle) + ((struct vki_file_handle*)ARG2)->handle_bytes );
5317}
5318
5319POST(sys_open_by_handle_at)
5320{
5321   vg_assert(SUCCESS);
5322   if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5323      VG_(close)(RES);
5324      SET_STATUS_Failure( VKI_EMFILE );
5325   } else {
5326      if (VG_(clo_track_fds))
5327         ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
5328   }
5329}
5330
5331/* ---------------------------------------------------------------------
5332   p{read,write}v wrappers
5333   ------------------------------------------------------------------ */
5334
5335PRE(sys_preadv)
5336{
5337   Int i;
5338   struct vki_iovec * vec;
5339   *flags |= SfMayBlock;
5340#if VG_WORDSIZE == 4
5341   /* Note that the offset argument here is in lo+hi order on both
5342      big and little endian platforms... */
5343   PRINT("sys_preadv ( %lu, %#lx, %lu, %lld )",
5344         ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5345   PRE_REG_READ5(ssize_t, "preadv",
5346                 unsigned long, fd, const struct iovec *, vector,
5347                 unsigned long, count, vki_u32, offset_low,
5348                 vki_u32, offset_high);
5349#elif VG_WORDSIZE == 8
5350   PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5351   PRE_REG_READ4(ssize_t, "preadv",
5352                 unsigned long, fd, const struct iovec *, vector,
5353                 unsigned long, count, Word, offset);
5354#else
5355#  error Unexpected word size
5356#endif
5357   if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
5358      SET_STATUS_Failure( VKI_EBADF );
5359   } else {
5360      PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
5361
5362      if (ARG2 != 0) {
5363         /* ToDo: don't do any of the following if the vector is invalid */
5364         vec = (struct vki_iovec *)ARG2;
5365         for (i = 0; i < (Int)ARG3; i++)
5366            PRE_MEM_WRITE( "preadv(vector[...])",
5367                           (Addr)vec[i].iov_base, vec[i].iov_len );
5368      }
5369   }
5370}
5371
5372POST(sys_preadv)
5373{
5374   vg_assert(SUCCESS);
5375   if (RES > 0) {
5376      Int i;
5377      struct vki_iovec * vec = (struct vki_iovec *)ARG2;
5378      Int remains = RES;
5379
5380      /* RES holds the number of bytes read. */
5381      for (i = 0; i < (Int)ARG3; i++) {
5382	 Int nReadThisBuf = vec[i].iov_len;
5383	 if (nReadThisBuf > remains) nReadThisBuf = remains;
5384	 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5385	 remains -= nReadThisBuf;
5386	 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
5387      }
5388   }
5389}
5390
5391PRE(sys_pwritev)
5392{
5393   Int i;
5394   struct vki_iovec * vec;
5395   *flags |= SfMayBlock;
5396#if VG_WORDSIZE == 4
5397   /* Note that the offset argument here is in lo+hi order on both
5398      big and little endian platforms... */
5399   PRINT("sys_pwritev ( %lu, %#lx, %lu, %lld )",
5400         ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5401   PRE_REG_READ5(ssize_t, "pwritev",
5402                 unsigned long, fd, const struct iovec *, vector,
5403                 unsigned long, count, vki_u32, offset_low,
5404                 vki_u32, offset_high);
5405#elif VG_WORDSIZE == 8
5406   PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5407   PRE_REG_READ4(ssize_t, "pwritev",
5408                 unsigned long, fd, const struct iovec *, vector,
5409                 unsigned long, count, Word, offset);
5410#else
5411#  error Unexpected word size
5412#endif
5413   if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
5414      SET_STATUS_Failure( VKI_EBADF );
5415   } else {
5416      PRE_MEM_READ( "pwritev(vector)",
5417		     ARG2, ARG3 * sizeof(struct vki_iovec) );
5418      if (ARG2 != 0) {
5419         /* ToDo: don't do any of the following if the vector is invalid */
5420         vec = (struct vki_iovec *)ARG2;
5421         for (i = 0; i < (Int)ARG3; i++)
5422            PRE_MEM_READ( "pwritev(vector[...])",
5423                           (Addr)vec[i].iov_base, vec[i].iov_len );
5424      }
5425   }
5426}
5427
5428/* ---------------------------------------------------------------------
5429   process_vm_{read,write}v wrappers
5430   ------------------------------------------------------------------ */
5431
5432PRE(sys_process_vm_readv)
5433{
5434   PRINT("sys_process_vm_readv ( %ld, %#lx, %lu, %#lx, %lu, %lu )",
5435         SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5436   PRE_REG_READ6(ssize_t, "process_vm_readv",
5437                 vki_pid_t, pid,
5438                 const struct iovec *, lvec,
5439                 unsigned long, liovcnt,
5440                 const struct iovec *, rvec,
5441                 unsigned long, riovcnt,
5442                 unsigned long, flags);
5443   PRE_MEM_READ( "process_vm_readv(lvec)",
5444                 ARG2, ARG3 * sizeof(struct vki_iovec) );
5445   PRE_MEM_READ( "process_vm_readv(rvec)",
5446                 ARG4, ARG5 * sizeof(struct vki_iovec) );
5447   if (ARG2 != 0
5448       && ML_(safe_to_deref) ((void *)ARG2, sizeof(struct vki_iovec) * ARG3)) {
5449      const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
5450      UInt i;
5451      for (i = 0; i < ARG3; i++)
5452         PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
5453                        (Addr)vec[i].iov_base, vec[i].iov_len );
5454   }
5455}
5456
5457POST(sys_process_vm_readv)
5458{
5459   const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
5460   UInt remains = RES;
5461   UInt i;
5462   for (i = 0; i < ARG3; i++) {
5463      UInt nReadThisBuf = vec[i].iov_len <= remains ?
5464                          vec[i].iov_len : remains;
5465      POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5466      remains -= nReadThisBuf;
5467   }
5468}
5469
5470PRE(sys_process_vm_writev)
5471{
5472   PRINT("sys_process_vm_writev ( %ld, %#lx, %lu, %#lx, %lu, %lu )",
5473         SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5474   PRE_REG_READ6(ssize_t, "process_vm_writev",
5475                 vki_pid_t, pid,
5476                 const struct iovec *, lvec,
5477                 unsigned long, liovcnt,
5478                 const struct iovec *, rvec,
5479                 unsigned long, riovcnt,
5480                 unsigned long, flags);
5481   PRE_MEM_READ( "process_vm_writev(lvec)",
5482                 ARG2, ARG3 * sizeof(struct vki_iovec) );
5483   PRE_MEM_READ( "process_vm_writev(rvec)",
5484                 ARG4, ARG5 * sizeof(struct vki_iovec) );
5485   if (ARG2 != 0
5486       && ML_(safe_to_deref) ((void *)ARG2, sizeof(struct vki_iovec) * ARG3)) {
5487      const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
5488      UInt i;
5489      for (i = 0; i < ARG3; i++)
5490         PRE_MEM_READ( "process_vm_writev(lvec[...])",
5491                       (Addr)vec[i].iov_base, vec[i].iov_len );
5492   }
5493}
5494
5495/* ---------------------------------------------------------------------
5496   {send,recv}mmsg wrappers
5497   ------------------------------------------------------------------ */
5498
5499PRE(sys_sendmmsg)
5500{
5501   *flags |= SfMayBlock;
5502   PRINT("sys_sendmmsg ( %ld, %#lx, %ld, %ld )", SARG1, ARG2, SARG3, SARG4);
5503   PRE_REG_READ4(long, "sendmmsg",
5504                 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
5505   ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
5506}
5507
5508POST(sys_sendmmsg)
5509{
5510   ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
5511}
5512
5513PRE(sys_recvmmsg)
5514{
5515   *flags |= SfMayBlock;
5516   PRINT("sys_recvmmsg ( %ld, %#lx, %ld, %ld, %#lx )",
5517         SARG1, ARG2, SARG3, SARG4, ARG5);
5518   PRE_REG_READ5(long, "recvmmsg",
5519                 int, s, struct mmsghdr *, mmsg, int, vlen,
5520                 int, flags, struct timespec *, timeout);
5521   ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5522}
5523
5524POST(sys_recvmmsg)
5525{
5526   ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
5527}
5528
5529/* ---------------------------------------------------------------------
5530   key retention service wrappers
5531   ------------------------------------------------------------------ */
5532
5533PRE(sys_request_key)
5534{
5535   PRINT("sys_request_key ( %#lx(%s), %#lx(%s), %#lx(%s), %ld )",
5536         ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3, (HChar*)ARG3, SARG4);
5537   PRE_REG_READ4(long, "request_key",
5538                 const char *, type, const char *, description,
5539                 const char *, callout_info, vki_key_serial_t, keyring);
5540   PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
5541   PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
5542   if (ARG3 != (UWord)NULL)
5543      PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
5544}
5545
5546PRE(sys_add_key)
5547{
5548   PRINT("sys_add_key ( %#lx(%s), %#lx(%s), %#lx, %lu, %ld )",
5549         ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3, ARG4, SARG5);
5550   PRE_REG_READ5(long, "add_key",
5551                 const char *, type, const char *, description,
5552                 const void *, payload, vki_size_t, plen,
5553                 vki_key_serial_t, keyring);
5554   PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
5555   PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
5556   if (ARG3 != (UWord)NULL)
5557      PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
5558}
5559
5560PRE(sys_keyctl)
5561{
5562   switch (ARG1 /* option */) {
5563   case VKI_KEYCTL_GET_KEYRING_ID:
5564      PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
5565      PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
5566                    int, option, vki_key_serial_t, id, int, create);
5567      break;
5568   case VKI_KEYCTL_JOIN_SESSION_KEYRING:
5569      PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#lx(%s) )", ARG2,(char*)ARG2);
5570      PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
5571                    int, option, const char *, name);
5572      if (ARG2 != (UWord)NULL)
5573         PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
5574      break;
5575   case VKI_KEYCTL_UPDATE:
5576      PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#lx, %lu )", SARG2, ARG3, ARG4);
5577      PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
5578                    int, option, vki_key_serial_t, key,
5579                    const void *, payload, vki_size_t, plen);
5580      if (ARG3 != (UWord)NULL)
5581         PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
5582      break;
5583   case VKI_KEYCTL_REVOKE:
5584      PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
5585      PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
5586                    int, option, vki_key_serial_t, id);
5587      break;
5588   case VKI_KEYCTL_CHOWN:
5589      PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %lu, %lu )", SARG2, ARG3, ARG4);
5590      PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
5591                    int, option, vki_key_serial_t, id,
5592                    vki_uid_t, uid, vki_gid_t, gid);
5593      break;
5594   case VKI_KEYCTL_SETPERM:
5595      PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %lu )", SARG2, ARG3);
5596      PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5597                    int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5598      break;
5599   case VKI_KEYCTL_DESCRIBE:
5600      PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#lx, %lu )", SARG2, ARG3, ARG4);
5601      PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5602                    int, option, vki_key_serial_t, id,
5603                    char *, buffer, vki_size_t, buflen);
5604      if (ARG3 != (UWord)NULL)
5605         PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5606      break;
5607   case VKI_KEYCTL_CLEAR:
5608      PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
5609      PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5610                    int, option, vki_key_serial_t, keyring);
5611      break;
5612   case VKI_KEYCTL_LINK:
5613      PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
5614      PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5615                    vki_key_serial_t, keyring, vki_key_serial_t, key);
5616      break;
5617   case VKI_KEYCTL_UNLINK:
5618      PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
5619      PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5620                    vki_key_serial_t, keyring, vki_key_serial_t, key);
5621      break;
5622   case VKI_KEYCTL_SEARCH:
5623      PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#lx(%s), %#lx(%s), %ld )",
5624            SARG2, ARG3, (HChar*)ARG3, ARG4, (HChar*)ARG4, SARG5);
5625      PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5626                    int, option, vki_key_serial_t, keyring,
5627                    const char *, type, const char *, description,
5628                    vki_key_serial_t, destring);
5629      PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5630      PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5631      break;
5632   case VKI_KEYCTL_READ:
5633      PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#lx, %lu )", SARG2, ARG3, ARG4);
5634      PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5635                    int, option, vki_key_serial_t, keyring,
5636                    char *, buffer, vki_size_t, buflen);
5637      if (ARG3 != (UWord)NULL)
5638         PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5639      break;
5640   case VKI_KEYCTL_INSTANTIATE:
5641      PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#lx, %lu, %ld )",
5642            SARG2, ARG3, ARG4, SARG5);
5643      PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5644                    int, option, vki_key_serial_t, key,
5645                    char *, payload, vki_size_t, plen,
5646                    vki_key_serial_t, keyring);
5647      if (ARG3 != (UWord)NULL)
5648         PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5649      break;
5650   case VKI_KEYCTL_NEGATE:
5651      PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %lu, %ld )", SARG2, ARG3, SARG4);
5652      PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5653                    int, option, vki_key_serial_t, key,
5654                    unsigned, timeout, vki_key_serial_t, keyring);
5655      break;
5656   case VKI_KEYCTL_SET_REQKEY_KEYRING:
5657      PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
5658      PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5659                    int, option, int, reqkey_defl);
5660      break;
5661   case VKI_KEYCTL_SET_TIMEOUT:
5662      PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %lu )", SARG2, ARG3);
5663      PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5664                    int, option, vki_key_serial_t, key, unsigned, timeout);
5665      break;
5666   case VKI_KEYCTL_ASSUME_AUTHORITY:
5667      PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
5668      PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5669                    int, option, vki_key_serial_t, key);
5670      break;
5671   default:
5672      PRINT("sys_keyctl ( %ld ) ", SARG1);
5673      PRE_REG_READ1(long, "keyctl", int, option);
5674      break;
5675   }
5676}
5677
5678POST(sys_keyctl)
5679{
5680   vg_assert(SUCCESS);
5681   switch (ARG1 /* option */) {
5682   case VKI_KEYCTL_DESCRIBE:
5683   case VKI_KEYCTL_READ:
5684      if (RES > ARG4)
5685         POST_MEM_WRITE(ARG3, ARG4);
5686      else
5687         POST_MEM_WRITE(ARG3, RES);
5688      break;
5689   default:
5690      break;
5691   }
5692}
5693
5694/* ---------------------------------------------------------------------
5695   ioprio_ wrappers
5696   ------------------------------------------------------------------ */
5697
5698PRE(sys_ioprio_set)
5699{
5700   PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5701   PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5702}
5703
5704PRE(sys_ioprio_get)
5705{
5706   PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
5707   PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5708}
5709
5710/* ---------------------------------------------------------------------
5711   _module wrappers
5712   ------------------------------------------------------------------ */
5713
5714PRE(sys_init_module)
5715{
5716   *flags |= SfMayBlock;
5717   PRINT("sys_init_module ( %#lx, %lu, %#lx(\"%s\") )",
5718         ARG1, ARG2, ARG3, (HChar*)ARG3);
5719   PRE_REG_READ3(long, "init_module",
5720                 void *, umod, unsigned long, len, const char *, uargs);
5721   PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5722   PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5723}
5724
5725PRE(sys_finit_module)
5726{
5727   *flags |= SfMayBlock;
5728
5729   PRINT("sys_finit_module ( %lx, %#lx(\"%s\"), %lx )",
5730         ARG1, ARG2, (HChar*)ARG2, ARG3);
5731   PRE_REG_READ3(long, "finit_module",
5732                 int, fd, const char *, params, int, flags);
5733   PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
5734}
5735
5736PRE(sys_delete_module)
5737{
5738   *flags |= SfMayBlock;
5739   PRINT("sys_delete_module ( %#lx(\"%s\"), 0x%lx )", ARG1, (HChar*)ARG1, ARG2);
5740   PRE_REG_READ2(long, "delete_module",
5741                 const char *, name_user, unsigned int, flags);
5742   PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5743}
5744
5745/* ---------------------------------------------------------------------
5746   splice wrappers
5747   ------------------------------------------------------------------ */
5748
5749PRE(sys_splice)
5750{
5751   *flags |= SfMayBlock;
5752   PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %lu, %#lx )",
5753         SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
5754   PRE_REG_READ6(vki_ssize_t, "splice",
5755                 int, fd_in, vki_loff_t *, off_in,
5756                 int, fd_out, vki_loff_t *, off_out,
5757                 vki_size_t, len, unsigned int, flags);
5758   if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5759       !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5760      SET_STATUS_Failure( VKI_EBADF );
5761   } else {
5762      if (ARG2 != 0)
5763         PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5764      if (ARG4 != 0)
5765         PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5766   }
5767}
5768
5769PRE(sys_tee)
5770{
5771   *flags |= SfMayBlock;
5772   PRINT("sys_tree ( %ld, %ld, %lu, %#lx )", SARG1, SARG2, ARG3, ARG4);
5773   PRE_REG_READ4(vki_ssize_t, "tee",
5774                 int, fd_in, int, fd_out,
5775                 vki_size_t, len, unsigned int, flags);
5776   if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5777       !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5778      SET_STATUS_Failure( VKI_EBADF );
5779   }
5780}
5781
5782PRE(sys_vmsplice)
5783{
5784   Int fdfl;
5785   *flags |= SfMayBlock;
5786   PRINT("sys_vmsplice ( %ld, %#lx, %lu, %lu )", SARG1, ARG2, ARG3, ARG4);
5787   PRE_REG_READ4(vki_ssize_t, "splice",
5788                 int, fd, struct vki_iovec *, iov,
5789                 unsigned long, nr_segs, unsigned int, flags);
5790   if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5791      SET_STATUS_Failure( VKI_EBADF );
5792   } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5793      SET_STATUS_Failure( VKI_EBADF );
5794   } else {
5795      const struct vki_iovec *iov;
5796      PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5797      for (iov = (struct vki_iovec *)ARG2;
5798           iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5799      {
5800         if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
5801            if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5802               PRE_MEM_WRITE( "vmsplice(iov[...])",
5803                             (Addr)iov->iov_base, iov->iov_len );
5804            else
5805               PRE_MEM_READ( "vmsplice(iov[...])",
5806                            (Addr)iov->iov_base, iov->iov_len );
5807         }
5808      }
5809   }
5810}
5811
5812POST(sys_vmsplice)
5813{
5814   vg_assert(SUCCESS);
5815   if (RES > 0) {
5816      Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
5817      vg_assert(fdfl >= 0);
5818      if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5819      {
5820         const struct vki_iovec *iov;
5821         for (iov = (struct vki_iovec *)ARG2;
5822              iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5823         {
5824            POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
5825         }
5826      }
5827   }
5828}
5829
5830/* ---------------------------------------------------------------------
5831   oprofile-related wrappers
5832   ------------------------------------------------------------------ */
5833
5834#if defined(VGP_x86_linux)
5835PRE(sys_lookup_dcookie)
5836{
5837   PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
5838         MERGE64(ARG1,ARG2), ARG3, ARG4);
5839   PRE_REG_READ4(long, "lookup_dcookie",
5840                 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
5841                 char *, buf, vki_size_t, len);
5842   PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
5843}
5844POST(sys_lookup_dcookie)
5845{
5846   vg_assert(SUCCESS);
5847   if (ARG3 != (Addr)NULL)
5848      POST_MEM_WRITE( ARG3, RES);
5849}
5850#endif
5851
5852#if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)        \
5853      || defined(VGP_arm64_linux)
5854PRE(sys_lookup_dcookie)
5855{
5856   *flags |= SfMayBlock;
5857   PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
5858   PRE_REG_READ3(int, "lookup_dcookie",
5859                 unsigned long long, cookie, char *, buf, vki_size_t, len);
5860
5861   PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
5862}
5863
5864POST(sys_lookup_dcookie)
5865{
5866   vg_assert(SUCCESS);
5867   if (ARG2 != (Addr)NULL)
5868     POST_MEM_WRITE( ARG2, RES );
5869}
5870#endif
5871
5872/* ---------------------------------------------------------------------
5873   fcntl wrappers
5874   ------------------------------------------------------------------ */
5875
5876PRE(sys_fcntl)
5877{
5878   switch (ARG2) {
5879   // These ones ignore ARG3.
5880   case VKI_F_GETFD:
5881   case VKI_F_GETFL:
5882   case VKI_F_GETOWN:
5883   case VKI_F_GETSIG:
5884   case VKI_F_GETLEASE:
5885   case VKI_F_GETPIPE_SZ:
5886      PRINT("sys_fcntl ( %lu, %lu )", ARG1, ARG2);
5887      PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
5888      break;
5889
5890   // These ones use ARG3 as "arg".
5891   case VKI_F_DUPFD:
5892   case VKI_F_DUPFD_CLOEXEC:
5893   case VKI_F_SETFD:
5894   case VKI_F_SETFL:
5895   case VKI_F_SETLEASE:
5896   case VKI_F_NOTIFY:
5897   case VKI_F_SETOWN:
5898   case VKI_F_SETSIG:
5899   case VKI_F_SETPIPE_SZ:
5900      PRINT("sys_fcntl[ARG3=='arg'] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5901      PRE_REG_READ3(long, "fcntl",
5902                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
5903      break;
5904
5905   // These ones use ARG3 as "lock".
5906   case VKI_F_GETLK:
5907   case VKI_F_SETLK:
5908   case VKI_F_SETLKW:
5909   case VKI_F_OFD_GETLK:
5910   case VKI_F_OFD_SETLK:
5911   case VKI_F_OFD_SETLKW:
5912      PRINT("sys_fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
5913      PRE_REG_READ3(long, "fcntl",
5914                    unsigned int, fd, unsigned int, cmd,
5915                    struct vki_flock *, lock);
5916      {
5917         struct vki_flock *lock = (struct vki_flock *) ARG3;
5918         PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
5919         PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
5920         PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
5921         PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
5922         if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
5923            PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
5924         }
5925      }
5926      break;
5927
5928#  if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
5929   case VKI_F_GETLK64:
5930   case VKI_F_SETLK64:
5931   case VKI_F_SETLKW64:
5932      PRINT("sys_fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
5933      PRE_REG_READ3(long, "fcntl",
5934                    unsigned int, fd, unsigned int, cmd,
5935                    struct flock64 *, lock);
5936      {
5937         struct vki_flock64 *lock = (struct vki_flock64 *) ARG3;
5938         PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
5939         PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
5940         PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
5941         PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
5942         if (ARG2 == VKI_F_GETLK64) {
5943            PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
5944         }
5945      }
5946      break;
5947#  endif
5948
5949   case VKI_F_SETOWN_EX:
5950      PRINT("sys_fcntl[F_SETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5951      PRE_REG_READ3(long, "fcntl",
5952                    unsigned int, fd, unsigned int, cmd,
5953                    struct vki_f_owner_ex *, arg);
5954      PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5955      break;
5956
5957   case VKI_F_GETOWN_EX:
5958      PRINT("sys_fcntl[F_GETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5959      PRE_REG_READ3(long, "fcntl",
5960                    unsigned int, fd, unsigned int, cmd,
5961                    struct vki_f_owner_ex *, arg);
5962      PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5963      break;
5964
5965   default:
5966      PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5967      VG_(umsg)("Warning: unimplemented fcntl command: %lu\n", ARG2);
5968      SET_STATUS_Failure( VKI_EINVAL );
5969      break;
5970   }
5971
5972#  if defined(VGP_x86_linux)
5973   if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
5974#  else
5975   if (ARG2 == VKI_F_SETLKW)
5976#  endif
5977      *flags |= SfMayBlock;
5978}
5979
5980POST(sys_fcntl)
5981{
5982   vg_assert(SUCCESS);
5983   if (ARG2 == VKI_F_DUPFD) {
5984      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
5985         VG_(close)(RES);
5986         SET_STATUS_Failure( VKI_EMFILE );
5987      } else {
5988         if (VG_(clo_track_fds))
5989            ML_(record_fd_open_named)(tid, RES);
5990      }
5991   }
5992   else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
5993      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
5994         VG_(close)(RES);
5995         SET_STATUS_Failure( VKI_EMFILE );
5996      } else {
5997         if (VG_(clo_track_fds))
5998            ML_(record_fd_open_named)(tid, RES);
5999      }
6000   } else if (ARG2 == VKI_F_GETOWN_EX) {
6001      POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6002   } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6003      struct vki_flock *lock = (struct vki_flock *) ARG3;
6004      POST_FIELD_WRITE(lock->l_pid);
6005#  if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6006   } else if (ARG2 == VKI_F_GETLK64) {
6007      struct vki_flock64 *lock = (struct vki_flock64 *) ARG3;
6008      PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6009#  endif
6010   }
6011}
6012
6013// XXX: wrapper only suitable for 32-bit systems
6014PRE(sys_fcntl64)
6015{
6016   switch (ARG2) {
6017   // These ones ignore ARG3.
6018   case VKI_F_GETFD:
6019   case VKI_F_GETFL:
6020   case VKI_F_GETOWN:
6021   case VKI_F_SETOWN:
6022   case VKI_F_GETSIG:
6023   case VKI_F_SETSIG:
6024   case VKI_F_GETLEASE:
6025      PRINT("sys_fcntl64 ( %lu, %lu )", ARG1, ARG2);
6026      PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6027      break;
6028
6029   // These ones use ARG3 as "arg".
6030   case VKI_F_DUPFD:
6031   case VKI_F_DUPFD_CLOEXEC:
6032   case VKI_F_SETFD:
6033   case VKI_F_SETFL:
6034   case VKI_F_SETLEASE:
6035   case VKI_F_NOTIFY:
6036      PRINT("sys_fcntl64[ARG3=='arg'] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
6037      PRE_REG_READ3(long, "fcntl64",
6038                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6039      break;
6040
6041   // These ones use ARG3 as "lock".
6042   case VKI_F_GETLK:
6043   case VKI_F_SETLK:
6044   case VKI_F_SETLKW:
6045#  if defined(VGP_x86_linux)
6046   case VKI_F_GETLK64:
6047   case VKI_F_SETLK64:
6048   case VKI_F_SETLKW64:
6049#  endif
6050   case VKI_F_OFD_GETLK:
6051   case VKI_F_OFD_SETLK:
6052   case VKI_F_OFD_SETLKW:
6053      PRINT("sys_fcntl64[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
6054      PRE_REG_READ3(long, "fcntl64",
6055                    unsigned int, fd, unsigned int, cmd,
6056                    struct flock64 *, lock);
6057      break;
6058
6059   case VKI_F_SETOWN_EX:
6060      PRINT("sys_fcntl[F_SETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
6061      PRE_REG_READ3(long, "fcntl",
6062                    unsigned int, fd, unsigned int, cmd,
6063                    struct vki_f_owner_ex *, arg);
6064      PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6065      break;
6066
6067   case VKI_F_GETOWN_EX:
6068      PRINT("sys_fcntl[F_GETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
6069      PRE_REG_READ3(long, "fcntl",
6070                    unsigned int, fd, unsigned int, cmd,
6071                    struct vki_f_owner_ex *, arg);
6072      PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6073      break;
6074   }
6075
6076#  if defined(VGP_x86_linux)
6077   if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6078#  else
6079   if (ARG2 == VKI_F_SETLKW)
6080#  endif
6081      *flags |= SfMayBlock;
6082}
6083
6084POST(sys_fcntl64)
6085{
6086   vg_assert(SUCCESS);
6087   if (ARG2 == VKI_F_DUPFD) {
6088      if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6089         VG_(close)(RES);
6090         SET_STATUS_Failure( VKI_EMFILE );
6091      } else {
6092         if (VG_(clo_track_fds))
6093            ML_(record_fd_open_named)(tid, RES);
6094      }
6095   }
6096   else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6097      if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6098         VG_(close)(RES);
6099         SET_STATUS_Failure( VKI_EMFILE );
6100      } else {
6101         if (VG_(clo_track_fds))
6102            ML_(record_fd_open_named)(tid, RES);
6103      }
6104   } else if (ARG2 == VKI_F_GETOWN_EX) {
6105      POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6106   }
6107}
6108
6109/* ---------------------------------------------------------------------
6110   ioctl wrappers
6111   ------------------------------------------------------------------ */
6112
6113struct vg_drm_version_info {
6114   struct vki_drm_version data;
6115   struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6116};
6117
6118PRE(sys_ioctl)
6119{
6120   *flags |= SfMayBlock;
6121
6122   ARG2 = (UInt)ARG2;
6123
6124   // We first handle the ones that don't use ARG3 (even as a
6125   // scalar/non-pointer argument).
6126   switch (ARG2 /* request */) {
6127
6128      /* asm-generic/ioctls.h */
6129   case VKI_FIOCLEX:
6130   case VKI_FIONCLEX:
6131   case VKI_TIOCNOTTY:
6132
6133   /* linux perf_event ioctls */
6134   case VKI_PERF_EVENT_IOC_ENABLE:
6135   case VKI_PERF_EVENT_IOC_DISABLE:
6136
6137      /* linux/soundcard interface (ALSA) */
6138   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6139   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6140   case VKI_SNDRV_PCM_IOCTL_PREPARE:
6141   case VKI_SNDRV_PCM_IOCTL_RESET:
6142   case VKI_SNDRV_PCM_IOCTL_START:
6143   case VKI_SNDRV_PCM_IOCTL_DROP:
6144   case VKI_SNDRV_PCM_IOCTL_DRAIN:
6145   case VKI_SNDRV_PCM_IOCTL_RESUME:
6146   case VKI_SNDRV_PCM_IOCTL_XRUN:
6147   case VKI_SNDRV_PCM_IOCTL_UNLINK:
6148   case VKI_SNDRV_TIMER_IOCTL_START:
6149   case VKI_SNDRV_TIMER_IOCTL_STOP:
6150   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6151   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6152
6153      /* SCSI no operand */
6154   case VKI_SCSI_IOCTL_DOORLOCK:
6155   case VKI_SCSI_IOCTL_DOORUNLOCK:
6156
6157   /* CDROM stuff. */
6158   case VKI_CDROM_DISC_STATUS:
6159   case VKI_CDROMSTOP:
6160
6161   /* DVD stuff */
6162   case VKI_DVD_READ_STRUCT:
6163
6164   /* KVM ioctls that don't check for a numeric value as parameter */
6165   case VKI_KVM_S390_ENABLE_SIE:
6166   case VKI_KVM_CREATE_IRQCHIP:
6167   case VKI_KVM_S390_INITIAL_RESET:
6168   case VKI_KVM_KVMCLOCK_CTRL:
6169
6170   /* vhost without parameter */
6171   case VKI_VHOST_SET_OWNER:
6172   case VKI_VHOST_RESET_OWNER:
6173
6174   /* User input device creation */
6175   case VKI_UI_DEV_CREATE:
6176   case VKI_UI_DEV_DESTROY:
6177
6178   /* InfiniBand */
6179   case VKI_IB_USER_MAD_ENABLE_PKEY:
6180
6181   /* Lustre */
6182   case VKI_LL_IOC_GROUP_LOCK:
6183   case VKI_LL_IOC_GROUP_UNLOCK:
6184
6185   /* V4L2 */
6186   case VKI_V4L2_LOG_STATUS:
6187
6188   /* DVB */
6189   case VKI_DMX_STOP:
6190      PRINT("sys_ioctl ( %lu, 0x%lx )", ARG1, ARG2);
6191      PRE_REG_READ2(long, "ioctl",
6192                    unsigned int, fd, unsigned int, request);
6193      return;
6194
6195   default:
6196      PRINT("sys_ioctl ( %lu, 0x%lx, 0x%lx )", ARG1, ARG2, ARG3);
6197      PRE_REG_READ3(long, "ioctl",
6198                    unsigned int, fd, unsigned int, request, unsigned long, arg);
6199      break;
6200   }
6201
6202   // We now handle those that do look at ARG3 (and unknown ones fall into
6203   // this category).  Nb: some of these may well belong in the
6204   // doesn't-use-ARG3 switch above.
6205   switch (ARG2 /* request */) {
6206
6207   case VKI_ION_IOC_ALLOC: {
6208      struct vki_ion_allocation_data* data
6209         = (struct vki_ion_allocation_data*)ARG3;
6210      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len",          data->len);
6211      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align",        data->align);
6212      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
6213      PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags",        data->flags);
6214      PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle",       data->handle);
6215      break;
6216   }
6217   case VKI_ION_IOC_MAP: {
6218      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
6219      PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
6220      PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd",     data->fd);
6221      break;
6222   }
6223   case VKI_ION_IOC_IMPORT: {
6224      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
6225      PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd",     data->fd);
6226      PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
6227      break;
6228   }
6229
6230   case VKI_SYNC_IOC_MERGE: {
6231      struct vki_sync_merge_data* data = (struct vki_sync_merge_data*)ARG3;
6232      PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2",   data->fd2);
6233      PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name",  (Addr)(&data->name[0]));
6234      PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
6235      break;
6236   }
6237
6238   case VKI_TCSETS:
6239   case VKI_TCSETSW:
6240   case VKI_TCSETSF:
6241      PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
6242      break;
6243   case VKI_TCGETS:
6244      PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
6245      break;
6246   case VKI_TCSETA:
6247   case VKI_TCSETAW:
6248   case VKI_TCSETAF:
6249      PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
6250      break;
6251   case VKI_TCGETA:
6252      PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
6253      break;
6254   case VKI_TCSBRK:
6255   case VKI_TCXONC:
6256   case VKI_TCSBRKP:
6257   case VKI_TCFLSH:
6258   case VKI_TIOCSIG:
6259      /* These just take an int by value */
6260      break;
6261   case VKI_TIOCGWINSZ:
6262      PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
6263      break;
6264   case VKI_TIOCSWINSZ:
6265      PRE_MEM_READ( "ioctl(TIOCSWINSZ)",  ARG3, sizeof(struct vki_winsize) );
6266      break;
6267   case VKI_TIOCMBIS:
6268      PRE_MEM_READ( "ioctl(TIOCMBIS)",    ARG3, sizeof(unsigned int) );
6269      break;
6270   case VKI_TIOCMBIC:
6271      PRE_MEM_READ( "ioctl(TIOCMBIC)",    ARG3, sizeof(unsigned int) );
6272      break;
6273   case VKI_TIOCMSET:
6274      PRE_MEM_READ( "ioctl(TIOCMSET)",    ARG3, sizeof(unsigned int) );
6275      break;
6276   case VKI_TIOCMGET:
6277      PRE_MEM_WRITE( "ioctl(TIOCMGET)",   ARG3, sizeof(unsigned int) );
6278      break;
6279   case VKI_TIOCLINUX:
6280      PRE_MEM_READ( "ioctl(TIOCLINUX)",   ARG3, sizeof(char *) );
6281      if (*(char *)ARG3 == 11) {
6282	 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
6283      }
6284      break;
6285   case VKI_TIOCGPGRP:
6286      /* Get process group ID for foreground processing group. */
6287      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6288      break;
6289   case VKI_TIOCSPGRP:
6290      /* Set a process group ID? */
6291      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6292      break;
6293   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
6294      PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
6295      break;
6296   case VKI_TIOCSCTTY:
6297      /* Just takes an int value.  */
6298      break;
6299   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
6300      PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
6301      break;
6302   case VKI_FIONBIO:
6303      PRE_MEM_READ( "ioctl(FIONBIO)",    ARG3, sizeof(int) );
6304      break;
6305   case VKI_FIOASYNC:
6306      PRE_MEM_READ( "ioctl(FIOASYNC)",   ARG3, sizeof(int) );
6307      break;
6308   case VKI_FIONREAD:                /* identical to SIOCINQ */
6309      PRE_MEM_WRITE( "ioctl(FIONREAD)",  ARG3, sizeof(int) );
6310      break;
6311   case VKI_FIOQSIZE:
6312      PRE_MEM_WRITE( "ioctl(FIOQSIZE)",  ARG3, sizeof(vki_loff_t) );
6313      break;
6314
6315   case VKI_TIOCSERGETLSR:
6316      PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
6317      break;
6318   case VKI_TIOCGICOUNT:
6319      PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
6320                     sizeof(struct vki_serial_icounter_struct) );
6321      break;
6322
6323   case VKI_SG_SET_COMMAND_Q:
6324      PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
6325      break;
6326   case VKI_SG_IO:
6327      PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
6328      {
6329         vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)ARG3;
6330         PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
6331         if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
6332              sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
6333            PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
6334         }
6335      }
6336      break;
6337   case VKI_SG_GET_SCSI_ID:
6338      PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
6339      break;
6340   case VKI_SG_SET_RESERVED_SIZE:
6341      PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
6342      break;
6343   case VKI_SG_SET_TIMEOUT:
6344      PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
6345      break;
6346   case VKI_SG_GET_RESERVED_SIZE:
6347      PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
6348      break;
6349   case VKI_SG_GET_TIMEOUT:
6350      break;
6351   case VKI_SG_GET_VERSION_NUM:
6352      PRE_MEM_WRITE(  "ioctl(SG_GET_VERSION_NUM)",  ARG3, sizeof(int) );
6353      break;
6354   case VKI_SG_EMULATED_HOST: /* 0x2203 */
6355      PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)",    ARG3, sizeof(int) );
6356      break;
6357   case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
6358      PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
6359      break;
6360
6361   case VKI_IIOCGETCPS:
6362      PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
6363		     VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
6364      break;
6365   case VKI_IIOCNETGPN:
6366      PRE_MEM_READ( "ioctl(IIOCNETGPN)",
6367		     (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
6368		     sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
6369      PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
6370		     sizeof(vki_isdn_net_ioctl_phone) );
6371      break;
6372
6373      /* These all use struct ifreq AFAIK */
6374   case VKI_SIOCGIFINDEX:        /* get iface index              */
6375      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
6376                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6377      PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
6378      break;
6379   case VKI_SIOCGIFFLAGS:        /* get flags                    */
6380      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
6381                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6382      PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6383      break;
6384   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
6385      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
6386                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6387      PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
6388      break;
6389   case VKI_SIOCGIFMTU:          /* get MTU size                 */
6390      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
6391                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6392      PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
6393      break;
6394   case VKI_SIOCGIFADDR:         /* get PA address               */
6395      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
6396                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6397      PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
6398      break;
6399   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
6400      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
6401                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6402      PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
6403      break;
6404   case VKI_SIOCGIFMETRIC:       /* get metric                   */
6405      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
6406                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6407      PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
6408      break;
6409   case VKI_SIOCGIFMAP:          /* Get device parameters        */
6410      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
6411                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6412      PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
6413      break;
6414   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
6415      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
6416                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6417      PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
6418      break;
6419   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
6420      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
6421                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6422      PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
6423      break;
6424   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
6425      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
6426                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6427      PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
6428      break;
6429   case VKI_SIOCGIFNAME:         /* get iface name               */
6430      PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
6431                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
6432                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
6433      PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
6434      break;
6435   case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
6436      struct vki_ifreq *ir = (struct vki_ifreq *)ARG3;
6437      PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
6438      PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
6439      PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
6440      PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
6441      switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6442      case VKI_ETHTOOL_GSET:
6443         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
6444                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6445         break;
6446      case VKI_ETHTOOL_SSET:
6447         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
6448                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6449         break;
6450      case VKI_ETHTOOL_GDRVINFO:
6451         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
6452                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
6453         break;
6454      case VKI_ETHTOOL_GREGS:
6455         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
6456                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
6457         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
6458                        (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
6459                        ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
6460         break;
6461      case VKI_ETHTOOL_GWOL:
6462         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
6463                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6464         break;
6465      case VKI_ETHTOOL_SWOL:
6466         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
6467                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6468         break;
6469      case VKI_ETHTOOL_GMSGLVL:
6470      case VKI_ETHTOOL_GLINK:
6471      case VKI_ETHTOOL_GRXCSUM:
6472      case VKI_ETHTOOL_GSG:
6473      case VKI_ETHTOOL_GTSO:
6474      case VKI_ETHTOOL_GUFO:
6475      case VKI_ETHTOOL_GGSO:
6476      case VKI_ETHTOOL_GFLAGS:
6477      case VKI_ETHTOOL_GGRO:
6478         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
6479                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6480         break;
6481      case VKI_ETHTOOL_SMSGLVL:
6482      case VKI_ETHTOOL_SRXCSUM:
6483      case VKI_ETHTOOL_SSG:
6484      case VKI_ETHTOOL_STSO:
6485      case VKI_ETHTOOL_SUFO:
6486      case VKI_ETHTOOL_SGSO:
6487      case VKI_ETHTOOL_SFLAGS:
6488      case VKI_ETHTOOL_SGRO:
6489         PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
6490                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6491         break;
6492      case VKI_ETHTOOL_NWAY_RST:
6493         break;
6494      case VKI_ETHTOOL_GRINGPARAM:
6495         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
6496                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6497         break;
6498      case VKI_ETHTOOL_SRINGPARAM:
6499         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
6500                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6501         break;
6502      case VKI_ETHTOOL_TEST:
6503         PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
6504                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
6505         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
6506                        (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
6507                        ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
6508         break;
6509      case VKI_ETHTOOL_PHYS_ID:
6510         break;
6511      case VKI_ETHTOOL_GPERMADDR:
6512         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
6513                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
6514         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
6515                        (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
6516                        ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
6517         break;
6518      case VKI_ETHTOOL_RESET:
6519         break;
6520      case VKI_ETHTOOL_GSSET_INFO:
6521         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6522                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
6523         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6524                        (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
6525                        __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
6526         break;
6527      case VKI_ETHTOOL_GFEATURES:
6528         PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
6529                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
6530         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
6531                        (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
6532                        ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
6533         break;
6534      case VKI_ETHTOOL_SFEATURES:
6535         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6536                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
6537         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6538                       (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
6539                       ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
6540         break;
6541      case VKI_ETHTOOL_GCHANNELS:
6542         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
6543                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6544         break;
6545      case VKI_ETHTOOL_SCHANNELS:
6546         PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
6547                       (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6548         break;
6549      case VKI_ETHTOOL_GET_TS_INFO:
6550         PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
6551                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
6552         break;
6553      }
6554      break;
6555   }
6556   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
6557      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
6558                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6559      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
6560      break;
6561   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
6562      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
6563                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6564      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6565                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
6566                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
6567      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6568                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
6569                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
6570      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
6571		     sizeof(struct vki_ifreq));
6572      break;
6573   case VKI_SIOCGIFCONF:         /* get iface list               */
6574      /* WAS:
6575	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
6576	 KERNEL_DO_SYSCALL(tid,RES);
6577	 if (!VG_(is_kerror)(RES) && RES == 0)
6578	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
6579      */
6580      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6581                    (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
6582                    sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
6583      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6584                    (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
6585                    sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
6586      if ( ARG3 ) {
6587	 // TODO len must be readable and writable
6588	 // buf pointer only needs to be readable
6589	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
6590	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
6591			(Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
6592      }
6593      break;
6594   case VKI_SIOCGSTAMP:
6595      PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
6596      break;
6597   case VKI_SIOCGSTAMPNS:
6598      PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
6599      break;
6600      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
6601	 the number of bytes currently in that socket's send buffer.
6602	 It writes this value as an int to the memory location
6603	 indicated by the third argument of ioctl(2). */
6604   case VKI_SIOCOUTQ:
6605      PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
6606      break;
6607   case VKI_SIOCGRARP:           /* get RARP table entry         */
6608   case VKI_SIOCGARP:            /* get ARP table entry          */
6609      PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
6610      break;
6611
6612   case VKI_SIOCSIFFLAGS:        /* set flags                    */
6613      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
6614                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6615      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
6616                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6617                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6618      break;
6619   case VKI_SIOCSIFMAP:          /* Set device parameters        */
6620      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
6621                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6622      PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
6623                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_map,
6624                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_map) );
6625      break;
6626   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
6627      PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
6628                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6629      PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
6630                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_data,
6631                     sizeof(struct vki_hwtstamp_config) );
6632      break;
6633   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
6634      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
6635                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6636      PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
6637                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_qlen,
6638                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_qlen) );
6639      break;
6640   case VKI_SIOCSIFADDR:         /* set PA address               */
6641   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
6642   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
6643   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
6644      PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
6645                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6646      PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
6647                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_addr,
6648                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_addr) );
6649      break;
6650   case VKI_SIOCSIFMETRIC:       /* set metric                   */
6651      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
6652                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6653      PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
6654                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
6655                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
6656      break;
6657   case VKI_SIOCSIFMTU:          /* set MTU size                 */
6658      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
6659                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6660      PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
6661                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
6662                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
6663      break;
6664   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
6665      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
6666                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6667      PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
6668                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr,
6669                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr) );
6670      break;
6671   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
6672      PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
6673                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6674      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6675                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
6676                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
6677      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6678                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
6679                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
6680      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6681                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
6682                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
6683      break;
6684      /* Routing table calls.  */
6685   case VKI_SIOCADDRT:           /* add routing table entry      */
6686   case VKI_SIOCDELRT:           /* delete routing table entry   */
6687      PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
6688		    sizeof(struct vki_rtentry));
6689      break;
6690
6691      /* tun/tap related ioctls */
6692   case VKI_TUNSETNOCSUM:
6693   case VKI_TUNSETDEBUG:
6694      break;
6695   case VKI_TUNSETIFF:
6696      PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
6697                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6698      PRE_MEM_READ( "ioctl(TUNSETIFF)",
6699                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6700                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6701      PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
6702      break;
6703   case VKI_TUNSETPERSIST:
6704   case VKI_TUNSETOWNER:
6705   case VKI_TUNSETLINK:
6706   case VKI_TUNSETGROUP:
6707      break;
6708   case VKI_TUNGETFEATURES:
6709      PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
6710      break;
6711   case VKI_TUNSETOFFLOAD:
6712      break;
6713   case VKI_TUNGETIFF:
6714      PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
6715      break;
6716   case VKI_TUNGETSNDBUF:
6717      PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
6718      break;
6719   case VKI_TUNSETSNDBUF:
6720      PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
6721      break;
6722   case VKI_TUNGETVNETHDRSZ:
6723      PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
6724      break;
6725   case VKI_TUNSETVNETHDRSZ:
6726      PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
6727      break;
6728   case VKI_TUNSETQUEUE:
6729      PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
6730                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6731                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6732      break;
6733   case VKI_TUNSETIFINDEX:
6734      PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
6735      break;
6736
6737      /* RARP cache control calls. */
6738   case VKI_SIOCDRARP:           /* delete RARP table entry      */
6739   case VKI_SIOCSRARP:           /* set RARP table entry         */
6740      /* ARP cache control calls. */
6741   case VKI_SIOCSARP:            /* set ARP table entry          */
6742   case VKI_SIOCDARP:            /* delete ARP table entry       */
6743      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6744      break;
6745
6746   case VKI_SIOCGPGRP:
6747      PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6748      break;
6749   case VKI_SIOCSPGRP:
6750      PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6751      //tst->sys_flags &= ~SfMayBlock;
6752      break;
6753
6754    case VKI_SIOCATMARK:
6755      PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
6756      break;
6757
6758      /* linux/soundcard interface (OSS) */
6759   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6760   case VKI_SNDCTL_SEQ_GETINCOUNT:
6761   case VKI_SNDCTL_SEQ_PERCMODE:
6762   case VKI_SNDCTL_SEQ_TESTMIDI:
6763   case VKI_SNDCTL_SEQ_RESETSAMPLES:
6764   case VKI_SNDCTL_SEQ_NRSYNTHS:
6765   case VKI_SNDCTL_SEQ_NRMIDIS:
6766   case VKI_SNDCTL_SEQ_GETTIME:
6767   case VKI_SNDCTL_DSP_GETBLKSIZE:
6768   case VKI_SNDCTL_DSP_GETFMTS:
6769   case VKI_SNDCTL_DSP_GETTRIGGER:
6770   case VKI_SNDCTL_DSP_GETODELAY:
6771   case VKI_SNDCTL_DSP_GETSPDIF:
6772   case VKI_SNDCTL_DSP_GETCAPS:
6773   case VKI_SOUND_PCM_READ_RATE:
6774   case VKI_SOUND_PCM_READ_CHANNELS:
6775   case VKI_SOUND_PCM_READ_BITS:
6776   case VKI_SOUND_PCM_READ_FILTER:
6777      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6778		     ARG3, sizeof(int));
6779      break;
6780   case VKI_SNDCTL_SEQ_CTRLRATE:
6781   case VKI_SNDCTL_DSP_SPEED:
6782   case VKI_SNDCTL_DSP_STEREO:
6783   case VKI_SNDCTL_DSP_CHANNELS:
6784   case VKI_SOUND_PCM_WRITE_FILTER:
6785   case VKI_SNDCTL_DSP_SUBDIVIDE:
6786   case VKI_SNDCTL_DSP_SETFRAGMENT:
6787   case VKI_SNDCTL_DSP_SETFMT:
6788   case VKI_SNDCTL_DSP_GETCHANNELMASK:
6789   case VKI_SNDCTL_DSP_BIND_CHANNEL:
6790   case VKI_SNDCTL_TMR_TIMEBASE:
6791   case VKI_SNDCTL_TMR_TEMPO:
6792   case VKI_SNDCTL_TMR_SOURCE:
6793   case VKI_SNDCTL_MIDI_PRETIME:
6794   case VKI_SNDCTL_MIDI_MPUMODE:
6795      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6796		     ARG3, sizeof(int));
6797      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6798		     ARG3, sizeof(int));
6799      break;
6800   case VKI_SNDCTL_DSP_GETOSPACE:
6801   case VKI_SNDCTL_DSP_GETISPACE:
6802      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
6803                     ARG3, sizeof(vki_audio_buf_info));
6804      break;
6805   case VKI_SNDCTL_DSP_NONBLOCK:
6806      break;
6807   case VKI_SNDCTL_DSP_SETTRIGGER:
6808      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
6809		     ARG3, sizeof(int));
6810      break;
6811
6812   case VKI_SNDCTL_DSP_POST:
6813   case VKI_SNDCTL_DSP_RESET:
6814   case VKI_SNDCTL_DSP_SYNC:
6815   case VKI_SNDCTL_DSP_SETSYNCRO:
6816   case VKI_SNDCTL_DSP_SETDUPLEX:
6817      break;
6818
6819      /* linux/soundcard interface (ALSA) */
6820   case VKI_SNDRV_PCM_IOCTL_PAUSE:
6821   case VKI_SNDRV_PCM_IOCTL_LINK:
6822      /* these just take an int by value */
6823      break;
6824   case VKI_SNDRV_CTL_IOCTL_PVERSION:
6825      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
6826      break;
6827   case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
6828      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
6829      break;
6830   case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
6831      struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
6832      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
6833      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
6834      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
6835      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
6836      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
6837      if (data->pids) {
6838         PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
6839      }
6840      break;
6841   }
6842   case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
6843      struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
6844      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
6845      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
6846      PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
6847      break;
6848   }
6849   case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
6850   case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
6851      struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
6852      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
6853      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
6854      PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
6855      break;
6856   }
6857
6858      /* Real Time Clock (/dev/rtc) ioctls */
6859   case VKI_RTC_UIE_ON:
6860   case VKI_RTC_UIE_OFF:
6861   case VKI_RTC_AIE_ON:
6862   case VKI_RTC_AIE_OFF:
6863   case VKI_RTC_PIE_ON:
6864   case VKI_RTC_PIE_OFF:
6865   case VKI_RTC_IRQP_SET:
6866      break;
6867   case VKI_RTC_RD_TIME:
6868   case VKI_RTC_ALM_READ:
6869      PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
6870		     ARG3, sizeof(struct vki_rtc_time));
6871      break;
6872   case VKI_RTC_ALM_SET:
6873      PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
6874      break;
6875   case VKI_RTC_IRQP_READ:
6876      PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
6877      break;
6878
6879      /* Block devices */
6880   case VKI_BLKROSET:
6881      PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
6882      break;
6883   case VKI_BLKROGET:
6884      PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
6885      break;
6886   case VKI_BLKGETSIZE:
6887      PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
6888      break;
6889   case VKI_BLKRASET:
6890      break;
6891   case VKI_BLKRAGET:
6892      PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
6893      break;
6894   case VKI_BLKFRASET:
6895      break;
6896   case VKI_BLKFRAGET:
6897      PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
6898      break;
6899   case VKI_BLKSECTGET:
6900      PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
6901      break;
6902   case VKI_BLKSSZGET:
6903      PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
6904      break;
6905   case VKI_BLKBSZGET:
6906      PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
6907      break;
6908   case VKI_BLKBSZSET:
6909      PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
6910      break;
6911   case VKI_BLKGETSIZE64:
6912      PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
6913      break;
6914   case VKI_BLKPBSZGET:
6915      PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
6916      break;
6917   case VKI_BLKDISCARDZEROES:
6918      PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
6919      break;
6920
6921      /* Hard disks */
6922   case VKI_HDIO_GETGEO: /* 0x0301 */
6923      PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
6924      break;
6925   case VKI_HDIO_GET_DMA: /* 0x030b */
6926      PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
6927      break;
6928   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
6929      PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
6930                     VKI_SIZEOF_STRUCT_HD_DRIVEID );
6931      break;
6932
6933      /* SCSI */
6934   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
6935      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
6936      break;
6937   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
6938      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
6939      break;
6940
6941      /* CD ROM stuff (??)  */
6942   case VKI_CDROM_GET_MCN:
6943      PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
6944                    sizeof(struct vki_cdrom_mcn) );
6945      break;
6946   case VKI_CDROM_SEND_PACKET:
6947      PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
6948                    sizeof(struct vki_cdrom_generic_command));
6949      break;
6950   case VKI_CDROMSUBCHNL:
6951      PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
6952		    (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
6953		    sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
6954      PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
6955		     sizeof(struct vki_cdrom_subchnl));
6956      break;
6957   case VKI_CDROMREADMODE1: /*0x530d*/
6958      PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
6959      PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
6960      break;
6961   case VKI_CDROMREADMODE2: /*0x530c*/
6962      PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
6963      PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
6964      break;
6965   case VKI_CDROMREADTOCHDR:
6966      PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
6967		     sizeof(struct vki_cdrom_tochdr));
6968      break;
6969   case VKI_CDROMREADTOCENTRY:
6970      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
6971		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
6972		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
6973      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
6974		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
6975		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
6976      PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
6977		     sizeof(struct vki_cdrom_tocentry));
6978      break;
6979   case VKI_CDROMMULTISESSION: /* 0x5310 */
6980      PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
6981		     sizeof(struct vki_cdrom_multisession));
6982      break;
6983   case VKI_CDROMVOLREAD: /* 0x5313 */
6984      PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
6985		     sizeof(struct vki_cdrom_volctrl));
6986      break;
6987   case VKI_CDROMREADRAW: /* 0x5314 */
6988      PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
6989      PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
6990      break;
6991   case VKI_CDROMREADAUDIO: /* 0x530e */
6992      PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
6993		     sizeof (struct vki_cdrom_read_audio));
6994      if ( ARG3 ) {
6995         /* ToDo: don't do any of the following if the structure is invalid */
6996         struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
6997	 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
6998	                (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
6999      }
7000      break;
7001   case VKI_CDROMPLAYMSF:
7002      PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7003      break;
7004      /* The following two are probably bogus (should check args
7005	 for readability).  JRS 20021117 */
7006   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7007   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7008      break;
7009   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7010      break;
7011
7012   case VKI_FIGETBSZ:
7013      PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7014      break;
7015   case VKI_FIBMAP:
7016      PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7017      break;
7018
7019   case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7020      PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7021                     sizeof(struct vki_fb_var_screeninfo));
7022      break;
7023   case VKI_FBIOPUT_VSCREENINFO:
7024      PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7025                    sizeof(struct vki_fb_var_screeninfo));
7026      break;
7027   case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7028      PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7029                     sizeof(struct vki_fb_fix_screeninfo));
7030      break;
7031   case VKI_FBIOPAN_DISPLAY:
7032      PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7033                    sizeof(struct vki_fb_var_screeninfo));
7034
7035      break;
7036   case VKI_PPCLAIM:
7037   case VKI_PPEXCL:
7038   case VKI_PPYIELD:
7039   case VKI_PPRELEASE:
7040      break;
7041   case VKI_PPSETMODE:
7042      PRE_MEM_READ( "ioctl(PPSETMODE)",   ARG3, sizeof(int) );
7043      break;
7044   case VKI_PPGETMODE:
7045      PRE_MEM_WRITE( "ioctl(PPGETMODE)",  ARG3, sizeof(int) );
7046      break;
7047   case VKI_PPSETPHASE:
7048      PRE_MEM_READ(  "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7049      break;
7050   case VKI_PPGETPHASE:
7051      PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7052      break;
7053   case VKI_PPGETMODES:
7054      PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7055      break;
7056   case VKI_PPSETFLAGS:
7057      PRE_MEM_READ(  "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7058      break;
7059   case VKI_PPGETFLAGS:
7060      PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7061      break;
7062   case VKI_PPRSTATUS:
7063      PRE_MEM_WRITE( "ioctl(PPRSTATUS)",  ARG3, sizeof(unsigned char) );
7064      break;
7065   case VKI_PPRDATA:
7066      PRE_MEM_WRITE( "ioctl(PPRDATA)",    ARG3, sizeof(unsigned char) );
7067      break;
7068   case VKI_PPRCONTROL:
7069      PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7070      break;
7071   case VKI_PPWDATA:
7072      PRE_MEM_READ(  "ioctl(PPWDATA)",    ARG3, sizeof(unsigned char) );
7073      break;
7074   case VKI_PPWCONTROL:
7075      PRE_MEM_READ(  "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7076      break;
7077   case VKI_PPFCONTROL:
7078      PRE_MEM_READ(  "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7079      break;
7080   case VKI_PPDATADIR:
7081      PRE_MEM_READ(  "ioctl(PPDATADIR)",  ARG3, sizeof(int) );
7082      break;
7083   case VKI_PPNEGOT:
7084      PRE_MEM_READ(  "ioctl(PPNEGOT)",    ARG3, sizeof(int) );
7085      break;
7086   case VKI_PPWCTLONIRQ:
7087      PRE_MEM_READ(  "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7088      break;
7089   case VKI_PPCLRIRQ:
7090      PRE_MEM_WRITE( "ioctl(PPCLRIRQ)",   ARG3, sizeof(int) );
7091      break;
7092   case VKI_PPSETTIME:
7093      PRE_MEM_READ(  "ioctl(PPSETTIME)",  ARG3, sizeof(struct vki_timeval) );
7094      break;
7095   case VKI_PPGETTIME:
7096      PRE_MEM_WRITE( "ioctl(PPGETTIME)",  ARG3, sizeof(struct vki_timeval) );
7097      break;
7098
7099   case VKI_GIO_FONT:
7100      PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7101      break;
7102   case VKI_PIO_FONT:
7103      PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7104      break;
7105
7106   case VKI_GIO_FONTX:
7107      PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7108      if ( ARG3 ) {
7109         /* ToDo: don't do any of the following if the structure is invalid */
7110         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
7111         PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7112                        32 * cfd->charcount );
7113      }
7114      break;
7115   case VKI_PIO_FONTX:
7116      PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7117      if ( ARG3 ) {
7118         /* ToDo: don't do any of the following if the structure is invalid */
7119         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
7120         PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7121                       32 * cfd->charcount );
7122      }
7123      break;
7124
7125   case VKI_PIO_FONTRESET:
7126      break;
7127
7128   case VKI_GIO_CMAP:
7129      PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
7130      break;
7131   case VKI_PIO_CMAP:
7132      PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
7133      break;
7134
7135   case VKI_KIOCSOUND:
7136   case VKI_KDMKTONE:
7137      break;
7138
7139   case VKI_KDGETLED:
7140      PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
7141      break;
7142   case VKI_KDSETLED:
7143      break;
7144
7145   case VKI_KDGKBTYPE:
7146      PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
7147      break;
7148
7149   case VKI_KDADDIO:
7150   case VKI_KDDELIO:
7151   case VKI_KDENABIO:
7152   case VKI_KDDISABIO:
7153      break;
7154
7155   case VKI_KDSETMODE:
7156      break;
7157   case VKI_KDGETMODE:
7158      PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
7159      break;
7160
7161   case VKI_KDMAPDISP:
7162   case VKI_KDUNMAPDISP:
7163      break;
7164
7165   case VKI_GIO_SCRNMAP:
7166      PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7167      break;
7168   case VKI_PIO_SCRNMAP:
7169      PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ  );
7170      break;
7171   case VKI_GIO_UNISCRNMAP:
7172      PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
7173                     VKI_E_TABSZ * sizeof(unsigned short) );
7174      break;
7175   case VKI_PIO_UNISCRNMAP:
7176      PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
7177                    VKI_E_TABSZ * sizeof(unsigned short) );
7178      break;
7179
7180   case VKI_GIO_UNIMAP:
7181      if ( ARG3 ) {
7182         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
7183         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7184                       sizeof(unsigned short));
7185         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7186                       sizeof(struct vki_unipair *));
7187         PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
7188                        desc->entry_ct * sizeof(struct vki_unipair));
7189      }
7190      break;
7191   case VKI_PIO_UNIMAP:
7192      if ( ARG3 ) {
7193         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
7194         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7195                       sizeof(unsigned short) );
7196         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7197                       sizeof(struct vki_unipair *) );
7198         PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
7199                       desc->entry_ct * sizeof(struct vki_unipair) );
7200      }
7201      break;
7202   case VKI_PIO_UNIMAPCLR:
7203      PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
7204      break;
7205
7206   case VKI_KDGKBMODE:
7207      PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
7208      break;
7209   case VKI_KDSKBMODE:
7210      break;
7211
7212   case VKI_KDGKBMETA:
7213      PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
7214      break;
7215   case VKI_KDSKBMETA:
7216      break;
7217
7218   case VKI_KDGKBLED:
7219      PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
7220      break;
7221   case VKI_KDSKBLED:
7222      break;
7223
7224   case VKI_KDGKBENT:
7225      PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
7226                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
7227                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
7228      PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
7229                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
7230                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
7231      PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
7232		     (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
7233		     sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
7234      break;
7235   case VKI_KDSKBENT:
7236      PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
7237                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
7238                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
7239      PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
7240                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
7241                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
7242      PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
7243                    (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
7244                    sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
7245      break;
7246
7247   case VKI_KDGKBSENT:
7248      PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
7249                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
7250                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
7251      PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
7252		     (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
7253		     sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
7254      break;
7255   case VKI_KDSKBSENT:
7256      PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
7257                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
7258                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
7259      PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
7260                       (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
7261      break;
7262
7263   case VKI_KDGKBDIACR:
7264      PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7265      break;
7266   case VKI_KDSKBDIACR:
7267      PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7268      break;
7269
7270   case VKI_KDGETKEYCODE:
7271      PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
7272                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
7273                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
7274      PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
7275		     (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
7276		     sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
7277      break;
7278   case VKI_KDSETKEYCODE:
7279      PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
7280                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
7281                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
7282      PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
7283                    (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
7284                    sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
7285      break;
7286
7287   case VKI_KDSIGACCEPT:
7288      break;
7289
7290   case VKI_KDKBDREP:
7291      PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
7292      break;
7293
7294   case VKI_KDFONTOP:
7295      if ( ARG3 ) {
7296         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
7297         PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
7298                       sizeof(struct vki_console_font_op) );
7299         switch ( op->op ) {
7300            case VKI_KD_FONT_OP_SET:
7301               PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
7302                             (Addr)op->data,
7303                             (op->width + 7) / 8 * 32 * op->charcount );
7304               break;
7305            case VKI_KD_FONT_OP_GET:
7306               if ( op->data )
7307                  PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
7308                                 (Addr)op->data,
7309                                 (op->width + 7) / 8 * 32 * op->charcount );
7310               break;
7311            case VKI_KD_FONT_OP_SET_DEFAULT:
7312               if ( op->data )
7313                  PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
7314                                   (Addr)op->data );
7315               break;
7316            case VKI_KD_FONT_OP_COPY:
7317               break;
7318         }
7319      }
7320      break;
7321
7322   case VKI_VT_OPENQRY:
7323      PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
7324      break;
7325   case VKI_VT_GETMODE:
7326      PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7327      break;
7328   case VKI_VT_SETMODE:
7329      PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7330      break;
7331   case VKI_VT_GETSTATE:
7332      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
7333                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
7334                     sizeof(((struct vki_vt_stat*) ARG3)->v_active));
7335      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
7336                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
7337                     sizeof(((struct vki_vt_stat*) ARG3)->v_state));
7338      break;
7339   case VKI_VT_RELDISP:
7340   case VKI_VT_ACTIVATE:
7341   case VKI_VT_WAITACTIVE:
7342   case VKI_VT_DISALLOCATE:
7343      break;
7344   case VKI_VT_RESIZE:
7345      PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
7346      break;
7347   case VKI_VT_RESIZEX:
7348      PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
7349      break;
7350   case VKI_VT_LOCKSWITCH:
7351   case VKI_VT_UNLOCKSWITCH:
7352      break;
7353
7354   case VKI_USBDEVFS_CONTROL:
7355      if ( ARG3 ) {
7356         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
7357         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
7358         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
7359         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
7360         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
7361         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
7362         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
7363         if (vkuc->bRequestType & 0x80)
7364            PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7365         else
7366            PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7367      }
7368      break;
7369   case VKI_USBDEVFS_BULK:
7370      if ( ARG3 ) {
7371         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
7372         PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
7373         if (vkub->ep & 0x80)
7374            PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7375         else
7376            PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7377      }
7378      break;
7379   case VKI_USBDEVFS_GETDRIVER:
7380      if ( ARG3 ) {
7381         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
7382         PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
7383      }
7384      break;
7385   case VKI_USBDEVFS_SUBMITURB:
7386      if ( ARG3 ) {
7387         struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
7388
7389         /* Not the whole struct needs to be initialized */
7390         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
7391         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
7392         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
7393         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
7394         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
7395         PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
7396         if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7397            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
7398            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7399            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
7400            if (vkusp->bRequestType & 0x80)
7401               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7402            else
7403               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7404            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7405         } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7406            int total_length = 0;
7407            int i;
7408            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
7409            for(i=0; i<vkuu->number_of_packets; i++) {
7410               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
7411               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));
7412               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
7413               total_length += vkuu->iso_frame_desc[i].length;
7414            }
7415            if (vkuu->endpoint & 0x80)
7416               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7417            else
7418               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7419            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
7420         } else {
7421            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7422            if (vkuu->endpoint & 0x80)
7423               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7424            else
7425               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7426            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7427         }
7428      }
7429      break;
7430   case VKI_USBDEVFS_DISCARDURB:
7431      break;
7432   case VKI_USBDEVFS_REAPURB:
7433      if ( ARG3 ) {
7434         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7435      }
7436      break;
7437   case VKI_USBDEVFS_REAPURBNDELAY:
7438      if ( ARG3 ) {
7439         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7440      }
7441      break;
7442   case VKI_USBDEVFS_CONNECTINFO:
7443      PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7444      break;
7445   case VKI_USBDEVFS_IOCTL:
7446      if ( ARG3 ) {
7447         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
7448         UInt dir2, size2;
7449         PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
7450         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
7451         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7452         if (size2 > 0) {
7453            if (dir2 & _VKI_IOC_WRITE)
7454               PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
7455            else if (dir2 & _VKI_IOC_READ)
7456               PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
7457         }
7458      }
7459      break;
7460   case VKI_USBDEVFS_RESET:
7461      break;
7462
7463      /* I2C (/dev/i2c-*) ioctls */
7464   case VKI_I2C_SLAVE:
7465   case VKI_I2C_SLAVE_FORCE:
7466   case VKI_I2C_TENBIT:
7467   case VKI_I2C_PEC:
7468      break;
7469   case VKI_I2C_FUNCS:
7470      PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
7471      break;
7472   case VKI_I2C_RDWR:
7473      if ( ARG3 ) {
7474          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
7475          UInt i;
7476          PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
7477          for (i=0; i < vkui->nmsgs; i++) {
7478              struct vki_i2c_msg *msg = vkui->msgs + i;
7479              PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
7480              if (msg->flags & VKI_I2C_M_RD)
7481                  PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7482              else
7483                  PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7484          }
7485      }
7486      break;
7487   case VKI_I2C_SMBUS:
7488       if ( ARG3 ) {
7489            struct vki_i2c_smbus_ioctl_data *vkis
7490               = (struct vki_i2c_smbus_ioctl_data *) ARG3;
7491            PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
7492                         (Addr)&vkis->read_write, sizeof(vkis->read_write));
7493            PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
7494                         (Addr)&vkis->size, sizeof(vkis->size));
7495            PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
7496                         (Addr)&vkis->command, sizeof(vkis->command));
7497            /* i2c_smbus_write_quick hides its value in read_write, so
7498               this variable can have a different meaning */
7499            /* to make matters worse i2c_smbus_write_byte stores its
7500               value in command */
7501            if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
7502                 ((vkis->size == VKI_I2C_SMBUS_BYTE)
7503                  && (vkis->read_write == VKI_I2C_SMBUS_WRITE))))  {
7504                    /* the rest uses the byte array to store the data,
7505                       some the first byte for size */
7506                    UInt size;
7507                    switch(vkis->size) {
7508                        case VKI_I2C_SMBUS_BYTE_DATA:
7509                            size = 1;
7510                            break;
7511                        case VKI_I2C_SMBUS_WORD_DATA:
7512                        case VKI_I2C_SMBUS_PROC_CALL:
7513                            size = 2;
7514                            break;
7515                        case VKI_I2C_SMBUS_BLOCK_DATA:
7516                        case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
7517                        case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
7518                        case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
7519                            size = 1 + vkis->data->block[0];
7520                            break;
7521                        default:
7522                            size = 0;
7523                    }
7524
7525                    if ((vkis->read_write == VKI_I2C_SMBUS_READ)
7526                        || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
7527                        || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
7528                        PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
7529                                      ".i2c_smbus_ioctl_data.data",
7530                                      (Addr)&vkis->data->block[0], size);
7531                    else
7532                        PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
7533                                     "i2c_smbus_ioctl_data.data",
7534                                     (Addr)&vkis->data->block[0], size);
7535            }
7536       }
7537       break;
7538
7539      /* Wireless extensions ioctls */
7540   case VKI_SIOCSIWCOMMIT:
7541   case VKI_SIOCSIWNWID:
7542   case VKI_SIOCSIWFREQ:
7543   case VKI_SIOCSIWMODE:
7544   case VKI_SIOCSIWSENS:
7545   case VKI_SIOCSIWRANGE:
7546   case VKI_SIOCSIWPRIV:
7547   case VKI_SIOCSIWSTATS:
7548   case VKI_SIOCSIWSPY:
7549   case VKI_SIOCSIWTHRSPY:
7550   case VKI_SIOCSIWAP:
7551   case VKI_SIOCSIWSCAN:
7552   case VKI_SIOCSIWESSID:
7553   case VKI_SIOCSIWRATE:
7554   case VKI_SIOCSIWNICKN:
7555   case VKI_SIOCSIWRTS:
7556   case VKI_SIOCSIWFRAG:
7557   case VKI_SIOCSIWTXPOW:
7558   case VKI_SIOCSIWRETRY:
7559   case VKI_SIOCSIWENCODE:
7560   case VKI_SIOCSIWPOWER:
7561   case VKI_SIOCSIWGENIE:
7562   case VKI_SIOCSIWMLME:
7563   case VKI_SIOCSIWAUTH:
7564   case VKI_SIOCSIWENCODEEXT:
7565   case VKI_SIOCSIWPMKSA:
7566      break;
7567   case VKI_SIOCGIWNAME:
7568      if (ARG3) {
7569         PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
7570                       (Addr)((struct vki_iwreq *)ARG3)->u.name,
7571                       sizeof(((struct vki_iwreq *)ARG3)->u.name));
7572      }
7573      break;
7574   case VKI_SIOCGIWNWID:
7575   case VKI_SIOCGIWSENS:
7576   case VKI_SIOCGIWRATE:
7577   case VKI_SIOCGIWRTS:
7578   case VKI_SIOCGIWFRAG:
7579   case VKI_SIOCGIWTXPOW:
7580   case VKI_SIOCGIWRETRY:
7581   case VKI_SIOCGIWPOWER:
7582   case VKI_SIOCGIWAUTH:
7583      if (ARG3) {
7584         PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
7585                       "RETRY|PARAM|AUTH])",
7586                       (Addr)&((struct vki_iwreq *)ARG3)->u.nwid,
7587                       sizeof(struct vki_iw_param));
7588      }
7589      break;
7590   case VKI_SIOCGIWFREQ:
7591      if (ARG3) {
7592         PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
7593                       (Addr)&((struct vki_iwreq *)ARG3)->u.freq,
7594                       sizeof(struct vki_iw_freq));
7595      }
7596      break;
7597   case VKI_SIOCGIWMODE:
7598      if (ARG3) {
7599         PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
7600                       (Addr)&((struct vki_iwreq *)ARG3)->u.mode,
7601                       sizeof(__vki_u32));
7602      }
7603      break;
7604   case VKI_SIOCGIWRANGE:
7605   case VKI_SIOCGIWPRIV:
7606   case VKI_SIOCGIWSTATS:
7607   case VKI_SIOCGIWSPY:
7608   case VKI_SIOCGIWTHRSPY:
7609   case VKI_SIOCGIWAPLIST:
7610   case VKI_SIOCGIWSCAN:
7611   case VKI_SIOCGIWESSID:
7612   case VKI_SIOCGIWNICKN:
7613   case VKI_SIOCGIWENCODE:
7614   case VKI_SIOCGIWGENIE:
7615   case VKI_SIOCGIWENCODEEXT:
7616      if (ARG3) {
7617         struct vki_iw_point* point;
7618         point = &((struct vki_iwreq *)ARG3)->u.data;
7619         PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
7620                       "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
7621                       (Addr)point->pointer, point->length);
7622      }
7623      break;
7624   case VKI_SIOCGIWAP:
7625      if (ARG3) {
7626         PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
7627                       (Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
7628                       sizeof(struct vki_sockaddr));
7629      }
7630      break;
7631
7632  /* User input device creation */
7633  case VKI_UI_SET_EVBIT:
7634  case VKI_UI_SET_KEYBIT:
7635  case VKI_UI_SET_RELBIT:
7636  case VKI_UI_SET_ABSBIT:
7637  case VKI_UI_SET_MSCBIT:
7638  case VKI_UI_SET_LEDBIT:
7639  case VKI_UI_SET_SNDBIT:
7640  case VKI_UI_SET_FFBIT:
7641  case VKI_UI_SET_SWBIT:
7642  case VKI_UI_SET_PROPBIT:
7643      /* These just take an int by value */
7644      break;
7645
7646#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7647      || defined(VGPV_mips32_linux_android) \
7648      || defined(VGPV_arm64_linux_android)
7649   /* ashmem */
7650   case VKI_ASHMEM_GET_SIZE:
7651   case VKI_ASHMEM_SET_SIZE:
7652   case VKI_ASHMEM_GET_PROT_MASK:
7653   case VKI_ASHMEM_SET_PROT_MASK:
7654   case VKI_ASHMEM_GET_PIN_STATUS:
7655   case VKI_ASHMEM_PURGE_ALL_CACHES:
7656       break;
7657   case VKI_ASHMEM_GET_NAME:
7658       PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
7659       break;
7660   case VKI_ASHMEM_SET_NAME:
7661       PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
7662       break;
7663   case VKI_ASHMEM_PIN:
7664   case VKI_ASHMEM_UNPIN:
7665       PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
7666                     ARG3, sizeof(struct vki_ashmem_pin) );
7667       break;
7668
7669   /* binder */
7670   case VKI_BINDER_WRITE_READ:
7671       if (ARG3) {
7672           struct vki_binder_write_read* bwr
7673              = (struct vki_binder_write_read*)ARG3;
7674
7675           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
7676                          bwr->write_buffer);
7677           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
7678                          bwr->write_size);
7679           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
7680                          bwr->write_consumed);
7681           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
7682                          bwr->read_buffer);
7683           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
7684                          bwr->read_size);
7685           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
7686                          bwr->read_consumed);
7687
7688           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
7689                           bwr->write_consumed);
7690           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
7691                           bwr->read_consumed);
7692
7693           if (bwr->read_size)
7694               PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
7695                             (Addr)bwr->read_buffer, bwr->read_size);
7696           if (bwr->write_size)
7697               PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
7698                            (Addr)bwr->write_buffer, bwr->write_size);
7699       }
7700       break;
7701
7702   case VKI_BINDER_SET_IDLE_TIMEOUT:
7703   case VKI_BINDER_SET_MAX_THREADS:
7704   case VKI_BINDER_SET_IDLE_PRIORITY:
7705   case VKI_BINDER_SET_CONTEXT_MGR:
7706   case VKI_BINDER_THREAD_EXIT:
7707       break;
7708   case VKI_BINDER_VERSION:
7709       if (ARG3) {
7710           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
7711           PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
7712       }
7713       break;
7714#  endif /* defined(VGPV_*_linux_android) */
7715
7716   case VKI_HCIGETDEVLIST:
7717      if (ARG3) {
7718         struct vki_hci_dev_list_req* dlr = (struct vki_hci_dev_list_req*)ARG3;
7719         PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
7720                      (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
7721         PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
7722                       (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
7723                       dlr->dev_num * sizeof(struct vki_hci_dev_req));
7724      }
7725      break;
7726
7727   case VKI_HCIINQUIRY:
7728      if (ARG3) {
7729         struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
7730         PRE_MEM_READ("ioctl(HCIINQUIRY)",
7731                      (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
7732         PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
7733                       (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7734                       ir->num_rsp * sizeof(struct vki_inquiry_info));
7735      }
7736      break;
7737
7738   case VKI_DRM_IOCTL_VERSION:
7739      if (ARG3) {
7740         struct vki_drm_version* data = (struct vki_drm_version *)ARG3;
7741         struct vg_drm_version_info* info;
7742	 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
7743         PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
7744         PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
7745         PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
7746         PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
7747         PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
7748         PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
7749         PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
7750         PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
7751         PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
7752         PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
7753         PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
7754         info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
7755         // To ensure we VG_(free) info even when syscall fails:
7756         *flags |= SfPostOnFail;
7757         info->data = *data;
7758         info->orig = data;
7759         ARG3 = (Addr)&info->data;
7760      }
7761      break;
7762   case VKI_DRM_IOCTL_GET_UNIQUE:
7763      if (ARG3) {
7764         struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
7765	 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
7766	 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
7767	 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
7768      }
7769      break;
7770   case VKI_DRM_IOCTL_GET_MAGIC:
7771      if (ARG3) {
7772         struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
7773         PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
7774      }
7775      break;
7776   case VKI_DRM_IOCTL_WAIT_VBLANK:
7777      if (ARG3) {
7778         union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
7779	 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
7780	 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
7781	 /* XXX: It seems request.signal isn't used */
7782         PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
7783      }
7784      break;
7785   case VKI_DRM_IOCTL_GEM_CLOSE:
7786      if (ARG3) {
7787         struct vki_drm_gem_close *data = (struct vki_drm_gem_close *)ARG3;
7788	 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
7789      }
7790      break;
7791   case VKI_DRM_IOCTL_GEM_FLINK:
7792      if (ARG3) {
7793         struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
7794	 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
7795         PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
7796      }
7797      break;
7798   case VKI_DRM_IOCTL_GEM_OPEN:
7799      if (ARG3) {
7800         struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
7801	 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
7802	 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
7803	 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
7804      }
7805      break;
7806   case VKI_DRM_IOCTL_I915_GETPARAM:
7807      if (ARG3) {
7808         vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
7809	 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
7810	 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
7811      }
7812      break;
7813   case VKI_DRM_IOCTL_I915_GEM_BUSY:
7814      if (ARG3) {
7815         struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
7816	 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
7817         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
7818      }
7819      break;
7820   case VKI_DRM_IOCTL_I915_GEM_CREATE:
7821      if (ARG3) {
7822         struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
7823	 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
7824	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
7825      }
7826      break;
7827   case VKI_DRM_IOCTL_I915_GEM_PREAD:
7828      if (ARG3) {
7829         struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
7830	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
7831	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
7832	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
7833	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
7834	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
7835      }
7836      break;
7837   case VKI_DRM_IOCTL_I915_GEM_PWRITE:
7838      if (ARG3) {
7839         struct vki_drm_i915_gem_pwrite *data = (struct vki_drm_i915_gem_pwrite *)ARG3;
7840	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
7841	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
7842	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
7843	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
7844	 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
7845	  * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
7846	  * interleaved vertex attributes may have a wide stride with uninitialized data between
7847	  * consecutive vertices) */
7848      }
7849      break;
7850   case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
7851      if (ARG3) {
7852         struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
7853	 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
7854         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
7855      }
7856      break;
7857   case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
7858      if (ARG3) {
7859         struct vki_drm_i915_gem_set_domain *data = (struct vki_drm_i915_gem_set_domain *)ARG3;
7860	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
7861	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
7862	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
7863      }
7864      break;
7865   case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
7866      if (ARG3) {
7867         struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
7868	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
7869         PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
7870         PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
7871         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
7872      }
7873      break;
7874   case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
7875      if (ARG3) {
7876         struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
7877	 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
7878	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
7879         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
7880      }
7881      break;
7882   case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
7883      if (ARG3) {
7884         struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
7885         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
7886         PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
7887      }
7888      break;
7889
7890   /* KVM ioctls that check for a numeric value as parameter */
7891   case VKI_KVM_GET_API_VERSION:
7892   case VKI_KVM_CREATE_VM:
7893   case VKI_KVM_GET_VCPU_MMAP_SIZE:
7894   case VKI_KVM_CHECK_EXTENSION:
7895   case VKI_KVM_SET_TSS_ADDR:
7896   case VKI_KVM_CREATE_VCPU:
7897   case VKI_KVM_RUN:
7898      break;
7899
7900   case VKI_KVM_S390_MEM_OP: {
7901      struct vki_kvm_s390_mem_op *args =
7902         (struct vki_kvm_s390_mem_op *)(ARG3);
7903      PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
7904                   sizeof(struct vki_kvm_s390_mem_op));
7905      if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
7906         break;
7907      if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
7908         PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
7909      if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
7910         PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
7911      }
7912      break;
7913
7914
7915#ifdef ENABLE_XEN
7916   case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
7917      SyscallArgs harrghs;
7918      struct vki_xen_privcmd_hypercall *args =
7919         (struct vki_xen_privcmd_hypercall *)(ARG3);
7920
7921      if (!args)
7922         break;
7923
7924      VG_(memset)(&harrghs, 0, sizeof(harrghs));
7925      harrghs.sysno = args->op;
7926      harrghs.arg1 = args->arg[0];
7927      harrghs.arg2 = args->arg[1];
7928      harrghs.arg3 = args->arg[2];
7929      harrghs.arg4 = args->arg[3];
7930      harrghs.arg5 = args->arg[4];
7931      harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
7932
7933      WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
7934
7935      /* HACK. arg8 is used to return the number of hypercall
7936       * arguments actually consumed! */
7937      PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
7938                   ( sizeof(args->arg[0]) * harrghs.arg8 ) );
7939
7940      break;
7941   }
7942
7943   case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
7944       struct vki_xen_privcmd_mmap *args =
7945           (struct vki_xen_privcmd_mmap *)(ARG3);
7946       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
7947                    (Addr)&args->num, sizeof(args->num));
7948       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
7949                    (Addr)&args->dom, sizeof(args->dom));
7950       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
7951                    (Addr)args->entry, sizeof(*(args->entry)) * args->num);
7952      break;
7953   }
7954   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
7955       struct vki_xen_privcmd_mmapbatch *args =
7956           (struct vki_xen_privcmd_mmapbatch *)(ARG3);
7957       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
7958                    (Addr)&args->num, sizeof(args->num));
7959       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
7960                    (Addr)&args->dom, sizeof(args->dom));
7961       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
7962                    (Addr)&args->addr, sizeof(args->addr));
7963       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
7964                    (Addr)args->arr, sizeof(*(args->arr)) * args->num);
7965      break;
7966   }
7967   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
7968       struct vki_xen_privcmd_mmapbatch_v2 *args =
7969           (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
7970       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
7971                    (Addr)&args->num, sizeof(args->num));
7972       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
7973                    (Addr)&args->dom, sizeof(args->dom));
7974       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
7975                    (Addr)&args->addr, sizeof(args->addr));
7976       PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
7977                    (Addr)args->arr, sizeof(*(args->arr)) * args->num);
7978      break;
7979   }
7980
7981   case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
7982         struct vki_xen_ioctl_evtchn_bind_virq *args =
7983            (struct vki_xen_ioctl_evtchn_bind_virq *)(ARG3);
7984         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
7985                 (Addr)&args->virq, sizeof(args->virq));
7986      }
7987      break;
7988   case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
7989         struct vki_xen_ioctl_evtchn_bind_interdomain *args =
7990            (struct vki_xen_ioctl_evtchn_bind_interdomain *)(ARG3);
7991         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
7992                 (Addr)&args->remote_domain, sizeof(args->remote_domain));
7993         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
7994                 (Addr)&args->remote_port, sizeof(args->remote_port));
7995      }
7996      break;
7997   case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
7998         struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
7999            (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(ARG3);
8000         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8001                 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8002      }
8003      break;
8004   case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8005         struct vki_xen_ioctl_evtchn_unbind *args =
8006            (struct vki_xen_ioctl_evtchn_unbind *)(ARG3);
8007         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8008                 (Addr)&args->port, sizeof(args->port));
8009      }
8010      break;
8011   case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8012         struct vki_xen_ioctl_evtchn_notify *args =
8013            (struct vki_xen_ioctl_evtchn_notify*)(ARG3);
8014         PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8015                 (Addr)&args->port, sizeof(args->port));
8016      }
8017      break;
8018   case VKI_XEN_IOCTL_EVTCHN_RESET:
8019      /* No input*/
8020      break;
8021#endif
8022
8023   /* Lustre */
8024   case VKI_OBD_IOC_FID2PATH: {
8025      struct vki_getinfo_fid2path *gf = (struct vki_getinfo_fid2path *)ARG3;
8026      PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8027      PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8028      PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8029      PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8030      break;
8031   }
8032
8033   case VKI_LL_IOC_PATH2FID:
8034      PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8035      break;
8036
8037   case VKI_LL_IOC_GETPARENT: {
8038      struct vki_getparent *gp = (struct vki_getparent *)ARG3;
8039      PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8040      PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8041      PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8042      PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8043      break;
8044   }
8045
8046   /* V4L2 */
8047   case VKI_V4L2_QUERYCAP: {
8048      struct vki_v4l2_capability *data = (struct vki_v4l2_capability *)ARG3;
8049      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8050      break;
8051   }
8052   case VKI_V4L2_ENUM_FMT: {
8053      struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)ARG3;
8054      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8055      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8056      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8057      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8058      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8059      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8060      break;
8061   }
8062   case VKI_V4L2_G_FMT: {
8063      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
8064      PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8065      switch (data->type) {
8066      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8067      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8068         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8069         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8070         PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8071               (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8072               sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8073         break;
8074      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8075      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8076         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8077         break;
8078      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8079      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8080         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8081         break;
8082      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8083      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8084         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8085         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
8086         PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8087         if (data->fmt.win.clipcount && data->fmt.win.clips)
8088            PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
8089                  (Addr)data->fmt.win.clips,
8090                  data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8091         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8092         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
8093         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
8094         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
8095         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
8096         break;
8097      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8098      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8099         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
8100         break;
8101      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8102         PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
8103         break;
8104      }
8105      break;
8106   }
8107   case VKI_V4L2_S_FMT: {
8108      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
8109      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
8110      switch (data->type) {
8111      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8112      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8113         PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
8114               (Addr)&data->type + sizeof(data->type),
8115               sizeof(*data) - sizeof(data->type));
8116         break;
8117      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8118      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8119         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
8120         break;
8121      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8122      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8123         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
8124         break;
8125      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8126      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8127         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
8128         if (data->fmt.win.clipcount && data->fmt.win.clips)
8129            PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
8130                  (Addr)data->fmt.win.clips,
8131                  data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8132         if (data->fmt.win.bitmap)
8133            PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
8134                  (Addr)data->fmt.win.bitmap,
8135                  data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8136         break;
8137      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8138      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8139         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
8140         break;
8141      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8142         PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
8143         break;
8144      }
8145      break;
8146   }
8147   case VKI_V4L2_TRY_FMT: {
8148      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
8149      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
8150      switch (data->type) {
8151      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8152      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8153         PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
8154               (Addr)&data->type + sizeof(data->type),
8155               sizeof(*data) - sizeof(data->type));
8156         break;
8157      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8158      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8159         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
8160         break;
8161      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8162      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8163         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
8164         break;
8165      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8166      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8167         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
8168         if (data->fmt.win.clipcount && data->fmt.win.clips)
8169            PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
8170                  (Addr)data->fmt.win.clips,
8171                  data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8172         if (data->fmt.win.bitmap)
8173            PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
8174                  (Addr)data->fmt.win.bitmap,
8175                  data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8176         break;
8177      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8178      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8179         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
8180         break;
8181      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8182         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
8183         break;
8184      }
8185      break;
8186   }
8187   case VKI_V4L2_REQBUFS: {
8188      struct vki_v4l2_requestbuffers *data = (struct vki_v4l2_requestbuffers *)ARG3;
8189      PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
8190      break;
8191   }
8192   case VKI_V4L2_QUERYBUF: {
8193      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8194      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
8195      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
8196      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
8197      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
8198      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8199            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8200         unsigned i;
8201
8202         PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8203         PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
8204         for (i = 0; i < data->length; i++) {
8205            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8206            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
8207            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
8208            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8209            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
8210         }
8211      } else {
8212         PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
8213         PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8214      }
8215      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
8216      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
8217      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
8218      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
8219      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
8220      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8221      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
8222      PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8223      break;
8224   }
8225   case VKI_V4L2_G_FBUF: {
8226      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
8227      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
8228      break;
8229   }
8230   case VKI_V4L2_S_FBUF: {
8231      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
8232      PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
8233      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
8234      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
8235      PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
8236      break;
8237   }
8238   case VKI_V4L2_OVERLAY: {
8239      int *data = (int *)ARG3;
8240      PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
8241      break;
8242   }
8243   case VKI_V4L2_QBUF: {
8244      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8245      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8246         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8247         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8248         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8249
8250      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
8251      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
8252      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
8253      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
8254      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
8255      PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
8256      if (is_output) {
8257         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8258         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8259      }
8260      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8261            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8262         unsigned i;
8263
8264         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
8265         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
8266         for (i = 0; i < data->length; i++) {
8267            if (is_output) {
8268               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8269               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8270            }
8271            if (data->memory == VKI_V4L2_MEMORY_MMAP)
8272               PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8273            else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8274               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
8275            else
8276               PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8277            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
8278         }
8279      } else {
8280         if (data->memory == VKI_V4L2_MEMORY_MMAP)
8281            PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
8282         else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8283            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
8284         else
8285            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
8286         if (is_output) {
8287            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8288            PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8289         }
8290      }
8291      if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
8292         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
8293         PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
8294      }
8295      break;
8296   }
8297   case VKI_V4L2_EXPBUF: {
8298      struct vki_v4l2_exportbuffer *data = (struct vki_v4l2_exportbuffer *)ARG3;
8299      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
8300      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
8301      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
8302      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
8303      PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
8304      PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
8305      break;
8306   }
8307   case VKI_V4L2_DQBUF: {
8308      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8309      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
8310      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
8311      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
8312      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
8313      PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
8314      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8315      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8316      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8317            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8318         unsigned i;
8319
8320         PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
8321         PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
8322         for (i = 0; i < data->length; i++) {
8323            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8324            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8325            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
8326            PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
8327            PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
8328         }
8329      } else {
8330         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
8331         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
8332         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8333         PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8334      }
8335      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
8336      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
8337      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
8338      break;
8339   }
8340   case VKI_V4L2_STREAMON: {
8341      int *data = (int *)ARG3;
8342      PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
8343      break;
8344   }
8345   case VKI_V4L2_STREAMOFF: {
8346      int *data = (int *)ARG3;
8347      PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
8348      break;
8349   }
8350   case VKI_V4L2_G_PARM: {
8351      struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
8352      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8353         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8354         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8355         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8356
8357      PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
8358      if (is_output) {
8359         PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
8360            sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
8361         PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
8362      } else {
8363         PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
8364            sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
8365         PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
8366      }
8367      break;
8368   }
8369   case VKI_V4L2_S_PARM: {
8370      struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
8371      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8372         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8373         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8374         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8375
8376      PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
8377      if (is_output)
8378         PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
8379      else
8380         PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
8381      break;
8382   }
8383   case VKI_V4L2_G_STD: {
8384      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
8385      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
8386      break;
8387   }
8388   case VKI_V4L2_S_STD: {
8389      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
8390      PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
8391      break;
8392   }
8393   case VKI_V4L2_ENUMSTD: {
8394      struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)ARG3;
8395      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
8396      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
8397      break;
8398   }
8399   case VKI_V4L2_ENUMINPUT: {
8400      struct vki_v4l2_input *data = (struct vki_v4l2_input *)ARG3;
8401      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
8402      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8403      break;
8404   }
8405   case VKI_V4L2_G_CTRL: {
8406      struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
8407      PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
8408      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
8409      break;
8410   }
8411   case VKI_V4L2_S_CTRL: {
8412      struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
8413      PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
8414      break;
8415   }
8416   case VKI_V4L2_G_TUNER: {
8417      struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
8418      PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
8419      PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
8420      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
8421            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8422      break;
8423   }
8424   case VKI_V4L2_S_TUNER: {
8425      struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
8426      PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
8427      PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
8428      PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
8429      break;
8430   }
8431   case VKI_V4L2_G_AUDIO: {
8432      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
8433      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
8434            sizeof(*data) - sizeof(data->reserved));
8435      PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
8436      break;
8437   }
8438   case VKI_V4L2_S_AUDIO: {
8439      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
8440      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
8441      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
8442      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
8443      break;
8444   }
8445   case VKI_V4L2_QUERYCTRL: {
8446      struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)ARG3;
8447      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
8448      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
8449            sizeof(*data) - sizeof(data->id));
8450      break;
8451   }
8452   case VKI_V4L2_QUERYMENU: {
8453      struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)ARG3;
8454      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
8455      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
8456      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
8457            sizeof(*data) - sizeof(data->id) - sizeof(data->index));
8458      break;
8459   }
8460   case VKI_V4L2_G_INPUT: {
8461      int *data = (int *)ARG3;
8462      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
8463      break;
8464   }
8465   case VKI_V4L2_S_INPUT: {
8466      int *data = (int *)ARG3;
8467      PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
8468      break;
8469   }
8470   case VKI_V4L2_G_EDID: {
8471      struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
8472      PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
8473      if (data->blocks && data->edid)
8474         PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
8475      break;
8476   }
8477   case VKI_V4L2_S_EDID: {
8478      struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
8479      PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
8480      if (data->blocks && data->edid)
8481         PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
8482      break;
8483   }
8484   case VKI_V4L2_G_OUTPUT: {
8485      int *data = (int *)ARG3;
8486      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
8487      break;
8488   }
8489   case VKI_V4L2_S_OUTPUT: {
8490      int *data = (int *)ARG3;
8491      PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
8492      break;
8493   }
8494   case VKI_V4L2_ENUMOUTPUT: {
8495      struct vki_v4l2_output *data = (struct vki_v4l2_output *)ARG3;
8496      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
8497      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8498      break;
8499   }
8500   case VKI_V4L2_G_AUDOUT: {
8501      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
8502      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
8503            sizeof(*data) - sizeof(data->reserved));
8504      PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
8505      break;
8506   }
8507   case VKI_V4L2_S_AUDOUT: {
8508      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
8509      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
8510      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
8511      PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
8512      break;
8513   }
8514   case VKI_V4L2_G_MODULATOR: {
8515      struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
8516      PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
8517      PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
8518      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
8519            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8520      break;
8521   }
8522   case VKI_V4L2_S_MODULATOR: {
8523      struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
8524      PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
8525      PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
8526      PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
8527      break;
8528   }
8529   case VKI_V4L2_G_FREQUENCY: {
8530      struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
8531      PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
8532      PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
8533      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
8534      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
8535      break;
8536   }
8537   case VKI_V4L2_S_FREQUENCY: {
8538      struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
8539      PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
8540      break;
8541   }
8542   case VKI_V4L2_CROPCAP: {
8543      struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)ARG3;
8544      PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
8545      PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
8546      break;
8547   }
8548   case VKI_V4L2_G_CROP: {
8549      struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
8550      PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
8551      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
8552      break;
8553   }
8554   case VKI_V4L2_S_CROP: {
8555      struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
8556      PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
8557      break;
8558   }
8559   case VKI_V4L2_G_JPEGCOMP: {
8560      struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
8561      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
8562      break;
8563   }
8564   case VKI_V4L2_S_JPEGCOMP: {
8565      struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
8566      PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
8567      break;
8568   }
8569   case VKI_V4L2_QUERYSTD: {
8570      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
8571      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
8572      break;
8573   }
8574   case VKI_V4L2_ENUMAUDIO: {
8575      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
8576      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
8577      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
8578      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
8579            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8580      break;
8581   }
8582   case VKI_V4L2_ENUMAUDOUT: {
8583      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
8584      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
8585      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
8586      PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
8587            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8588      break;
8589   }
8590   case VKI_V4L2_G_PRIORITY: {
8591      __vki_u32 *data = (__vki_u32 *)ARG3;
8592      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
8593      break;
8594   }
8595   case VKI_V4L2_S_PRIORITY: {
8596      __vki_u32 *data = (__vki_u32 *)ARG3;
8597      PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
8598      break;
8599   }
8600   case VKI_V4L2_G_SLICED_VBI_CAP: {
8601      struct vki_v4l2_sliced_vbi_cap *data = (struct vki_v4l2_sliced_vbi_cap *)ARG3;
8602      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
8603      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
8604      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
8605            sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
8606      break;
8607   }
8608   case VKI_V4L2_G_EXT_CTRLS: {
8609      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
8610      PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
8611      PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
8612      if (data->count) {
8613         unsigned i;
8614
8615         PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
8616         for (i = 0; i < data->count; i++) {
8617            PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
8618            PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
8619            PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
8620            if (data->controls[i].size) {
8621               PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
8622               PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
8623                     (Addr)data->controls[i].ptr, data->controls[i].size);
8624            } else {
8625               PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
8626                     data->controls[i].value64);
8627            }
8628         }
8629      }
8630      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
8631      PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
8632      break;
8633   }
8634   case VKI_V4L2_S_EXT_CTRLS: {
8635      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
8636      PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
8637      PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
8638      if (data->count) {
8639         unsigned i;
8640
8641         PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
8642         PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
8643               data->count * sizeof(data->controls[0]));
8644         for (i = 0; i < data->count; i++) {
8645            if (data->controls[i].size) {
8646               PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
8647                     (Addr)data->controls[i].ptr, data->controls[i].size);
8648            }
8649         }
8650      }
8651      PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
8652      PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
8653      break;
8654   }
8655   case VKI_V4L2_TRY_EXT_CTRLS: {
8656      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
8657      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
8658      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
8659      if (data->count) {
8660         unsigned i;
8661
8662         PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
8663         PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
8664               data->count * sizeof(data->controls[0]));
8665         for (i = 0; i < data->count; i++) {
8666            if (data->controls[i].size) {
8667               PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
8668                     (Addr)data->controls[i].ptr, data->controls[i].size);
8669            }
8670         }
8671      }
8672      PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
8673      PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
8674      break;
8675   }
8676   case VKI_V4L2_ENUM_FRAMESIZES: {
8677      struct vki_v4l2_frmsizeenum *data = (struct vki_v4l2_frmsizeenum *)ARG3;
8678      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
8679      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
8680      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
8681      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
8682      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
8683      break;
8684   }
8685   case VKI_V4L2_ENUM_FRAMEINTERVALS: {
8686      struct vki_v4l2_frmivalenum *data = (struct vki_v4l2_frmivalenum *)ARG3;
8687      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
8688      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
8689      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
8690      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
8691      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
8692      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
8693      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
8694      break;
8695   }
8696   case VKI_V4L2_G_ENC_INDEX: {
8697      struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)ARG3;
8698      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
8699      break;
8700   }
8701   case VKI_V4L2_ENCODER_CMD: {
8702      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
8703      PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
8704      break;
8705   }
8706   case VKI_V4L2_TRY_ENCODER_CMD: {
8707      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
8708      PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
8709      break;
8710   }
8711   case VKI_V4L2_DBG_S_REGISTER: {
8712      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
8713      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
8714      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
8715      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
8716      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
8717      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
8718      break;
8719   }
8720   case VKI_V4L2_DBG_G_REGISTER: {
8721      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
8722      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
8723      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
8724      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
8725      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
8726      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
8727      break;
8728   }
8729   case VKI_V4L2_S_HW_FREQ_SEEK: {
8730      struct vki_v4l2_hw_freq_seek *data = (struct vki_v4l2_hw_freq_seek *)ARG3;
8731      PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
8732      break;
8733   }
8734   case VKI_V4L2_S_DV_TIMINGS: {
8735      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8736      PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
8737      PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
8738      break;
8739   }
8740   case VKI_V4L2_G_DV_TIMINGS: {
8741      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8742      PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
8743      break;
8744   }
8745   case VKI_V4L2_DQEVENT: {
8746      struct vki_v4l2_event *data = (struct vki_v4l2_event *)ARG3;
8747      PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
8748      break;
8749   }
8750   case VKI_V4L2_SUBSCRIBE_EVENT: {
8751      struct vki_v4l2_event_subscription *data = (struct vki_v4l2_event_subscription *)ARG3;
8752      PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8753      break;
8754   }
8755   case VKI_V4L2_UNSUBSCRIBE_EVENT: {
8756      struct vki_v4l2_event_subscription *data = (struct vki_v4l2_event_subscription *)ARG3;
8757      PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8758      break;
8759   }
8760   case VKI_V4L2_CREATE_BUFS: {
8761      struct vki_v4l2_create_buffers *data = (struct vki_v4l2_create_buffers *)ARG3;
8762      struct vki_v4l2_format *fmt = &data->format;
8763      PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
8764      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
8765      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
8766      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
8767      PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
8768      switch (fmt->type) {
8769      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8770      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8771         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
8772         break;
8773      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8774      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8775         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
8776         break;
8777      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8778      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8779         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
8780         break;
8781      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8782      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8783         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
8784         break;
8785      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8786      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8787         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
8788         break;
8789      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8790         PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
8791         break;
8792      }
8793      break;
8794   }
8795   case VKI_V4L2_PREPARE_BUF: {
8796      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8797      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
8798      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
8799      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
8800      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
8801      PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
8802      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8803            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8804         unsigned i;
8805
8806         PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
8807         PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
8808         for (i = 0; i < data->length; i++) {
8809            PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
8810         }
8811      }
8812      break;
8813   }
8814   case VKI_V4L2_G_SELECTION: {
8815      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
8816      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
8817      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
8818      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
8819      PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
8820      PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
8821      break;
8822   }
8823   case VKI_V4L2_S_SELECTION: {
8824      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
8825      PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
8826      break;
8827   }
8828   case VKI_V4L2_DECODER_CMD: {
8829      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
8830      PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
8831      break;
8832   }
8833   case VKI_V4L2_TRY_DECODER_CMD: {
8834      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
8835      PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
8836      break;
8837   }
8838   case VKI_V4L2_ENUM_DV_TIMINGS: {
8839      struct vki_v4l2_enum_dv_timings *data = (struct vki_v4l2_enum_dv_timings *)ARG3;
8840      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
8841      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
8842      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
8843      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
8844      break;
8845   }
8846   case VKI_V4L2_QUERY_DV_TIMINGS: {
8847      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8848      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
8849      break;
8850   }
8851   case VKI_V4L2_DV_TIMINGS_CAP: {
8852      struct vki_v4l2_dv_timings_cap *data = (struct vki_v4l2_dv_timings_cap *)ARG3;
8853      PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
8854      break;
8855   }
8856   case VKI_V4L2_ENUM_FREQ_BANDS: {
8857      struct vki_v4l2_frequency_band *data = (struct vki_v4l2_frequency_band *)ARG3;
8858      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
8859      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
8860      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
8861      PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
8862      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
8863      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
8864      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
8865      PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
8866      break;
8867   }
8868   case VKI_V4L2_DBG_G_CHIP_INFO: {
8869      struct vki_v4l2_dbg_chip_info *data = (struct vki_v4l2_dbg_chip_info *)ARG3;
8870      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
8871      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
8872      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
8873      PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
8874      PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
8875      break;
8876   }
8877   case VKI_V4L2_QUERY_EXT_CTRL: {
8878      struct vki_v4l2_query_ext_ctrl *data = (struct vki_v4l2_query_ext_ctrl *)ARG3;
8879      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
8880      PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
8881      PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
8882            sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
8883      break;
8884   }
8885   case VKI_V4L2_SUBDEV_G_FMT: {
8886      struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
8887      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
8888      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
8889      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
8890      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
8891      break;
8892   }
8893   case VKI_V4L2_SUBDEV_S_FMT: {
8894      struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
8895      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
8896      break;
8897   }
8898   case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
8899      struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
8900      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
8901      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
8902      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
8903      break;
8904   }
8905   case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
8906      struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
8907      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
8908      break;
8909   }
8910   case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
8911      struct vki_v4l2_subdev_mbus_code_enum *data = (struct vki_v4l2_subdev_mbus_code_enum *)ARG3;
8912      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
8913      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
8914      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
8915      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
8916      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
8917      break;
8918   }
8919   case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
8920      struct vki_v4l2_subdev_frame_size_enum *data = (struct vki_v4l2_subdev_frame_size_enum *)ARG3;
8921      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
8922      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
8923      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
8924      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
8925      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
8926      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
8927      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
8928      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
8929      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
8930      break;
8931   }
8932   case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
8933      struct vki_v4l2_subdev_frame_interval_enum *data = (struct vki_v4l2_subdev_frame_interval_enum *)ARG3;
8934      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
8935      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
8936      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
8937      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
8938      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
8939      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
8940      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
8941      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
8942      break;
8943   }
8944   case VKI_V4L2_SUBDEV_G_CROP: {
8945      struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
8946      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
8947      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
8948      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
8949      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
8950      break;
8951   }
8952   case VKI_V4L2_SUBDEV_S_CROP: {
8953      struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
8954      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
8955      break;
8956   }
8957   case VKI_V4L2_SUBDEV_G_SELECTION: {
8958      struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
8959      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
8960      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
8961      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
8962      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
8963      PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
8964      PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
8965      break;
8966   }
8967   case VKI_V4L2_SUBDEV_S_SELECTION: {
8968      struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
8969      PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
8970      break;
8971   }
8972   case VKI_MEDIA_IOC_DEVICE_INFO: {
8973      struct vki_media_device_info *data = (struct vki_media_device_info *)ARG3;
8974      PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
8975      PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
8976            (Addr)data, sizeof(*data) - sizeof(data->reserved));
8977      break;
8978   }
8979   case VKI_MEDIA_IOC_ENUM_ENTITIES: {
8980      struct vki_media_entity_desc *data = (struct vki_media_entity_desc *)ARG3;
8981      PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
8982      PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
8983            (Addr)data->name, sizeof(*data) - sizeof(data->id));
8984      break;
8985   }
8986   case VKI_MEDIA_IOC_ENUM_LINKS: {
8987      struct vki_media_links_enum *data = (struct vki_media_links_enum *)ARG3;
8988      PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
8989      break;
8990   }
8991   case VKI_MEDIA_IOC_SETUP_LINK: {
8992      struct vki_media_link_desc *data = (struct vki_media_link_desc *)ARG3;
8993      PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
8994      break;
8995   }
8996
8997   /* Serial */
8998   case VKI_TIOCGSERIAL: {
8999      struct vki_serial_struct *data = (struct vki_serial_struct *)ARG3;
9000      PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9001      break;
9002   }
9003   case VKI_TIOCSSERIAL: {
9004      struct vki_serial_struct *data = (struct vki_serial_struct *)ARG3;
9005      PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9006      break;
9007   }
9008
9009   case VKI_PERF_EVENT_IOC_RESET:
9010   case VKI_PERF_EVENT_IOC_REFRESH:
9011   case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9012   case VKI_PERF_EVENT_IOC_SET_BPF:
9013      /* These take scalar arguments, so already handled above */
9014      break;
9015
9016   case VKI_PERF_EVENT_IOC_PERIOD:
9017      PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9018      break;
9019
9020   case VKI_PERF_EVENT_IOC_SET_FILTER:
9021      PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9022      break;
9023
9024   case VKI_PERF_EVENT_IOC_ID:
9025      PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9026      break;
9027
9028   default:
9029      /* EVIOC* are variable length and return size written on success */
9030      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
9031      case VKI_EVIOCGNAME(0):
9032      case VKI_EVIOCGPHYS(0):
9033      case VKI_EVIOCGUNIQ(0):
9034      case VKI_EVIOCGKEY(0):
9035      case VKI_EVIOCGLED(0):
9036      case VKI_EVIOCGSND(0):
9037      case VKI_EVIOCGSW(0):
9038      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
9039      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
9040      case VKI_EVIOCGBIT(VKI_EV_REL,0):
9041      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
9042      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
9043      case VKI_EVIOCGBIT(VKI_EV_SW,0):
9044      case VKI_EVIOCGBIT(VKI_EV_LED,0):
9045      case VKI_EVIOCGBIT(VKI_EV_SND,0):
9046      case VKI_EVIOCGBIT(VKI_EV_REP,0):
9047      case VKI_EVIOCGBIT(VKI_EV_FF,0):
9048      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
9049      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
9050         PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
9051         break;
9052      default:
9053         ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
9054         break;
9055      }
9056      break;
9057   }
9058}
9059
9060POST(sys_ioctl)
9061{
9062   ARG2 = (UInt)ARG2;
9063
9064   vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
9065
9066   /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
9067
9068   /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9069   if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
9070                       VG_(clo_kernel_variant))) {
9071
9072      if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
9073         /* What's going on here: there appear to be a bunch of ioctls
9074            of the form 0xC01C67xx which are undocumented, and if
9075            unhandled give rise to a vast number of false positives in
9076            Memcheck.
9077
9078            The "normal" interpretation of an ioctl of this form would
9079            be that the 3rd arg is a pointer to an area of size 0x1C
9080            (28 bytes) which is filled in by the kernel.  Hence you
9081            might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
9082            But it doesn't.
9083
9084            It requires POST_MEM_WRITE(ARG3, 256) to silence them.
9085            One interpretation of this is that ARG3 really does point
9086            to a 28 byte struct, but inside that are pointers to other
9087            areas also filled in by the kernel.  If these happen to be
9088            allocated just back up the stack then the 256 byte paint
9089            might cover them too, somewhat indiscriminately.
9090
9091            By printing out ARG3 and also the 28 bytes that it points
9092            at, it's possible to guess that the 7 word structure has
9093            this form
9094
9095              0            1    2    3        4    5        6
9096              ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
9097
9098            Unfortunately that doesn't seem to work for some reason,
9099            so stay with the blunt-instrument approach for the time
9100            being.
9101         */
9102         if (1) {
9103            /* blunt-instrument approach */
9104            POST_MEM_WRITE(ARG3, 256);
9105         } else {
9106            /* be a bit more sophisticated */
9107            POST_MEM_WRITE(ARG3, 28);
9108            UInt* word = (UInt*)ARG3;
9109            if (word && word[2] && word[3] < 0x200/*stay sane*/)
9110               POST_MEM_WRITE(word[2], word[3]); // "ptr1"
9111            if (word && word[4] && word[5] < 0x200/*stay sane*/)
9112               POST_MEM_WRITE(word[4], word[5]); // "ptr2"
9113         }
9114         goto post_sys_ioctl__out;
9115      }
9116   }
9117   /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9118
9119   /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
9120   if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
9121                       VG_(clo_kernel_variant))) {
9122     if (ARG2 == 0xC00C0902) {
9123         POST_MEM_WRITE(ARG3, 24); // 16 is not enough
9124         goto post_sys_ioctl__out;
9125     }
9126   }
9127   /* END undocumented ioctls for Qualcomm Adreno 3xx */
9128
9129   /* --- END special IOCTL handlers for specific Android hardware --- */
9130
9131   /* --- normal handling --- */
9132   switch (ARG2 /* request */) {
9133
9134   /* The Linux kernel "ion" memory allocator, used on Android.  Note:
9135      this is pretty poor given that there's no pre-handling to check
9136      that writable areas are addressable. */
9137   case VKI_ION_IOC_ALLOC: {
9138      struct vki_ion_allocation_data* data
9139         = (struct vki_ion_allocation_data*)ARG3;
9140      POST_FIELD_WRITE(data->handle);
9141      break;
9142   }
9143   case VKI_ION_IOC_MAP: {
9144      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
9145      POST_FIELD_WRITE(data->fd);
9146      break;
9147   }
9148   case VKI_ION_IOC_FREE: // is this necessary?
9149      POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
9150      break;
9151   case VKI_ION_IOC_SHARE:
9152      break;
9153   case VKI_ION_IOC_IMPORT: {
9154      struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
9155      POST_FIELD_WRITE(data->handle);
9156      break;
9157   }
9158   case VKI_ION_IOC_SYNC:
9159      break;
9160   case VKI_ION_IOC_CUSTOM: // is this necessary?
9161      POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
9162      break;
9163
9164   case VKI_SYNC_IOC_MERGE: {
9165      struct vki_sync_merge_data* data = (struct vki_sync_merge_data*)ARG3;
9166      POST_FIELD_WRITE(data->fence);
9167      break;
9168   }
9169
9170   case VKI_TCSETS:
9171   case VKI_TCSETSW:
9172   case VKI_TCSETSF:
9173   case VKI_IB_USER_MAD_ENABLE_PKEY:
9174      break;
9175   case VKI_TCGETS:
9176      POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
9177      break;
9178   case VKI_TCSETA:
9179   case VKI_TCSETAW:
9180   case VKI_TCSETAF:
9181      break;
9182   case VKI_TCGETA:
9183      POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
9184      break;
9185   case VKI_TCSBRK:
9186   case VKI_TCXONC:
9187   case VKI_TCSBRKP:
9188   case VKI_TCFLSH:
9189   case VKI_TIOCSIG:
9190      break;
9191   case VKI_TIOCGWINSZ:
9192      POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
9193      break;
9194   case VKI_TIOCSWINSZ:
9195   case VKI_TIOCMBIS:
9196   case VKI_TIOCMBIC:
9197   case VKI_TIOCMSET:
9198      break;
9199   case VKI_TIOCMGET:
9200      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9201      break;
9202   case VKI_TIOCLINUX:
9203      POST_MEM_WRITE( ARG3, sizeof(char *) );
9204      break;
9205   case VKI_TIOCGPGRP:
9206      /* Get process group ID for foreground processing group. */
9207      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9208      break;
9209   case VKI_TIOCSPGRP:
9210      /* Set a process group ID? */
9211      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9212      break;
9213   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
9214      POST_MEM_WRITE( ARG3, sizeof(int));
9215      break;
9216   case VKI_TIOCSCTTY:
9217      break;
9218   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
9219      break;
9220   case VKI_FIONBIO:
9221      break;
9222   case VKI_FIONCLEX:
9223      break;
9224   case VKI_FIOCLEX:
9225      break;
9226   case VKI_TIOCNOTTY:
9227      break;
9228   case VKI_FIOASYNC:
9229      break;
9230   case VKI_FIONREAD:                /* identical to SIOCINQ */
9231      POST_MEM_WRITE( ARG3, sizeof(int) );
9232      break;
9233   case VKI_FIOQSIZE:
9234      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
9235      break;
9236
9237   case VKI_TIOCSERGETLSR:
9238      POST_MEM_WRITE( ARG3, sizeof(int) );
9239      break;
9240   case VKI_TIOCGICOUNT:
9241      POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
9242      break;
9243
9244   case VKI_SG_SET_COMMAND_Q:
9245      break;
9246   case VKI_SG_IO:
9247      {
9248         vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)ARG3;
9249         if ( sgio->sbp ) {
9250            POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
9251         }
9252         if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
9253              sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
9254            int transferred = sgio->dxfer_len - sgio->resid;
9255            POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
9256         }
9257      }
9258      break;
9259   case VKI_SG_GET_SCSI_ID:
9260      POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
9261      break;
9262   case VKI_SG_SET_RESERVED_SIZE:
9263      break;
9264   case VKI_SG_SET_TIMEOUT:
9265      break;
9266   case VKI_SG_GET_RESERVED_SIZE:
9267      POST_MEM_WRITE(ARG3, sizeof(int));
9268      break;
9269   case VKI_SG_GET_TIMEOUT:
9270      break;
9271   case VKI_SG_GET_VERSION_NUM:
9272      POST_MEM_WRITE(ARG3, sizeof(int));
9273      break;
9274   case VKI_SG_EMULATED_HOST:
9275      POST_MEM_WRITE(ARG3, sizeof(int));
9276      break;
9277   case VKI_SG_GET_SG_TABLESIZE:
9278      POST_MEM_WRITE(ARG3, sizeof(int));
9279      break;
9280
9281   case VKI_IIOCGETCPS:
9282      POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
9283      break;
9284   case VKI_IIOCNETGPN:
9285      POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
9286      break;
9287
9288      /* These all use struct ifreq AFAIK */
9289   case VKI_SIOCGIFINDEX:        /* get iface index              */
9290      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
9291                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
9292      break;
9293   case VKI_SIOCGIFFLAGS:        /* get flags                    */
9294      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
9295                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
9296      break;
9297   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
9298      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr,
9299                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr) );
9300      break;
9301   case VKI_SIOCGIFMTU:          /* get MTU size                 */
9302      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
9303                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
9304      break;
9305   case VKI_SIOCGIFADDR:         /* get PA address               */
9306   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
9307   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
9308   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
9309      POST_MEM_WRITE(
9310                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_addr,
9311                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_addr) );
9312      break;
9313   case VKI_SIOCGIFMETRIC:       /* get metric                   */
9314      POST_MEM_WRITE(
9315                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
9316                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
9317      break;
9318   case VKI_SIOCGIFMAP:          /* Get device parameters        */
9319      POST_MEM_WRITE(
9320                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_map,
9321                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_map) );
9322      break;
9323     break;
9324   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
9325      POST_MEM_WRITE(
9326                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_qlen,
9327                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_qlen) );
9328      break;
9329   case VKI_SIOCGIFNAME:         /* get iface name               */
9330      POST_MEM_WRITE(
9331                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
9332                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
9333      break;
9334   case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
9335      struct vki_ifreq *ir = (struct vki_ifreq *)ARG3;
9336      switch ( *(vki_u32 *)ir->vki_ifr_data ) {
9337      case VKI_ETHTOOL_GSET:
9338         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
9339         break;
9340      case VKI_ETHTOOL_SSET:
9341         break;
9342      case VKI_ETHTOOL_GDRVINFO:
9343         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
9344         break;
9345      case VKI_ETHTOOL_GREGS:
9346         POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
9347                         ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
9348         break;
9349      case VKI_ETHTOOL_GWOL:
9350         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
9351         break;
9352      case VKI_ETHTOOL_SWOL:
9353         break;
9354      case VKI_ETHTOOL_GMSGLVL:
9355      case VKI_ETHTOOL_GLINK:
9356      case VKI_ETHTOOL_GRXCSUM:
9357      case VKI_ETHTOOL_GSG:
9358      case VKI_ETHTOOL_GTSO:
9359      case VKI_ETHTOOL_GUFO:
9360      case VKI_ETHTOOL_GGSO:
9361      case VKI_ETHTOOL_GFLAGS:
9362      case VKI_ETHTOOL_GGRO:
9363         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
9364         break;
9365      case VKI_ETHTOOL_SMSGLVL:
9366      case VKI_ETHTOOL_SRXCSUM:
9367      case VKI_ETHTOOL_SSG:
9368      case VKI_ETHTOOL_STSO:
9369      case VKI_ETHTOOL_SUFO:
9370      case VKI_ETHTOOL_SGSO:
9371      case VKI_ETHTOOL_SFLAGS:
9372      case VKI_ETHTOOL_SGRO:
9373         break;
9374      case VKI_ETHTOOL_NWAY_RST:
9375         break;
9376      case VKI_ETHTOOL_GRINGPARAM:
9377         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
9378         break;
9379      case VKI_ETHTOOL_SRINGPARAM:
9380         break;
9381      case VKI_ETHTOOL_TEST:
9382         POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
9383                         ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
9384         break;
9385      case VKI_ETHTOOL_PHYS_ID:
9386         break;
9387      case VKI_ETHTOOL_GPERMADDR:
9388         POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
9389                         ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
9390         break;
9391      case VKI_ETHTOOL_RESET:
9392         break;
9393      case VKI_ETHTOOL_GSSET_INFO:
9394         POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
9395                        __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
9396         break;
9397      case VKI_ETHTOOL_GFEATURES:
9398         POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
9399                         ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
9400         break;
9401      case VKI_ETHTOOL_SFEATURES:
9402         break;
9403      case VKI_ETHTOOL_GCHANNELS:
9404         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
9405         break;
9406      case VKI_ETHTOOL_SCHANNELS:
9407         break;
9408      case VKI_ETHTOOL_GET_TS_INFO:
9409         POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
9410         break;
9411      }
9412      break;
9413   }
9414   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
9415      POST_MEM_WRITE(
9416                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
9417                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
9418      break;
9419   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
9420      POST_MEM_WRITE(
9421                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
9422                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
9423      break;
9424
9425      /* tun/tap related ioctls */
9426   case VKI_TUNSETIFF:
9427      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
9428                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
9429      break;
9430   case VKI_TUNGETFEATURES:
9431      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9432      break;
9433   case VKI_TUNGETIFF:
9434      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
9435                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
9436      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
9437                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
9438      break;
9439   case VKI_TUNGETSNDBUF:
9440      POST_MEM_WRITE( ARG3, sizeof(int) );
9441      break;
9442   case VKI_TUNGETVNETHDRSZ:
9443      POST_MEM_WRITE( ARG3, sizeof(int) );
9444      break;
9445
9446   case VKI_SIOCGIFCONF:         /* get iface list               */
9447      /* WAS:
9448	 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
9449	 KERNEL_DO_SYSCALL(tid,RES);
9450	 if (!VG_(is_kerror)(RES) && RES == 0)
9451	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
9452      */
9453      if (RES == 0 && ARG3 ) {
9454	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
9455	 if (ifc->vki_ifc_buf != NULL)
9456	    POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
9457      }
9458      break;
9459   case VKI_SIOCGSTAMP:
9460      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9461      break;
9462   case VKI_SIOCGSTAMPNS:
9463      POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
9464      break;
9465      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
9466	 the number of bytes currently in that socket's send buffer.
9467	 It writes this value as an int to the memory location
9468	 indicated by the third argument of ioctl(2). */
9469   case VKI_SIOCOUTQ:
9470      POST_MEM_WRITE(ARG3, sizeof(int));
9471      break;
9472   case VKI_SIOCGRARP:           /* get RARP table entry         */
9473   case VKI_SIOCGARP:            /* get ARP table entry          */
9474      POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
9475      break;
9476
9477   case VKI_SIOCSIFFLAGS:        /* set flags                    */
9478   case VKI_SIOCSIFMAP:          /* Set device parameters        */
9479   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
9480   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
9481   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
9482   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
9483   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
9484   case VKI_SIOCSIFMETRIC:       /* set metric                   */
9485   case VKI_SIOCSIFADDR:         /* set PA address               */
9486   case VKI_SIOCSIFMTU:          /* set MTU size                 */
9487   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
9488   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
9489      break;
9490      /* Routing table calls.  */
9491   case VKI_SIOCADDRT:           /* add routing table entry      */
9492   case VKI_SIOCDELRT:           /* delete routing table entry   */
9493      break;
9494
9495      /* RARP cache control calls. */
9496   case VKI_SIOCDRARP:           /* delete RARP table entry      */
9497   case VKI_SIOCSRARP:           /* set RARP table entry         */
9498      /* ARP cache control calls. */
9499   case VKI_SIOCSARP:            /* set ARP table entry          */
9500   case VKI_SIOCDARP:            /* delete ARP table entry       */
9501      break;
9502
9503   case VKI_SIOCGPGRP:
9504      POST_MEM_WRITE(ARG3, sizeof(int));
9505      break;
9506   case VKI_SIOCSPGRP:
9507      break;
9508
9509   case VKI_SIOCATMARK:
9510      POST_MEM_WRITE(ARG3, sizeof(int));
9511      break;
9512
9513      /* linux/soundcard interface (OSS) */
9514   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
9515   case VKI_SNDCTL_SEQ_GETINCOUNT:
9516   case VKI_SNDCTL_SEQ_PERCMODE:
9517   case VKI_SNDCTL_SEQ_TESTMIDI:
9518   case VKI_SNDCTL_SEQ_RESETSAMPLES:
9519   case VKI_SNDCTL_SEQ_NRSYNTHS:
9520   case VKI_SNDCTL_SEQ_NRMIDIS:
9521   case VKI_SNDCTL_SEQ_GETTIME:
9522   case VKI_SNDCTL_DSP_GETBLKSIZE:
9523   case VKI_SNDCTL_DSP_GETFMTS:
9524   case VKI_SNDCTL_DSP_SETFMT:
9525   case VKI_SNDCTL_DSP_GETTRIGGER:
9526   case VKI_SNDCTL_DSP_GETODELAY:
9527   case VKI_SNDCTL_DSP_GETSPDIF:
9528   case VKI_SNDCTL_DSP_GETCAPS:
9529   case VKI_SOUND_PCM_READ_RATE:
9530   case VKI_SOUND_PCM_READ_CHANNELS:
9531   case VKI_SOUND_PCM_READ_BITS:
9532   case VKI_SOUND_PCM_READ_FILTER:
9533      POST_MEM_WRITE(ARG3, sizeof(int));
9534      break;
9535   case VKI_SNDCTL_SEQ_CTRLRATE:
9536   case VKI_SNDCTL_DSP_SPEED:
9537   case VKI_SNDCTL_DSP_STEREO:
9538   case VKI_SNDCTL_DSP_CHANNELS:
9539   case VKI_SOUND_PCM_WRITE_FILTER:
9540   case VKI_SNDCTL_DSP_SUBDIVIDE:
9541   case VKI_SNDCTL_DSP_SETFRAGMENT:
9542   case VKI_SNDCTL_DSP_GETCHANNELMASK:
9543   case VKI_SNDCTL_DSP_BIND_CHANNEL:
9544   case VKI_SNDCTL_TMR_TIMEBASE:
9545   case VKI_SNDCTL_TMR_TEMPO:
9546   case VKI_SNDCTL_TMR_SOURCE:
9547   case VKI_SNDCTL_MIDI_PRETIME:
9548   case VKI_SNDCTL_MIDI_MPUMODE:
9549      break;
9550   case VKI_SNDCTL_DSP_GETOSPACE:
9551   case VKI_SNDCTL_DSP_GETISPACE:
9552      POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
9553      break;
9554   case VKI_SNDCTL_DSP_NONBLOCK:
9555      break;
9556   case VKI_SNDCTL_DSP_SETTRIGGER:
9557      break;
9558
9559   case VKI_SNDCTL_DSP_POST:
9560   case VKI_SNDCTL_DSP_RESET:
9561   case VKI_SNDCTL_DSP_SYNC:
9562   case VKI_SNDCTL_DSP_SETSYNCRO:
9563   case VKI_SNDCTL_DSP_SETDUPLEX:
9564      break;
9565
9566      /* linux/soundcard interface (ALSA) */
9567   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
9568   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
9569   case VKI_SNDRV_PCM_IOCTL_PREPARE:
9570   case VKI_SNDRV_PCM_IOCTL_RESET:
9571   case VKI_SNDRV_PCM_IOCTL_START:
9572   case VKI_SNDRV_PCM_IOCTL_DROP:
9573   case VKI_SNDRV_PCM_IOCTL_DRAIN:
9574   case VKI_SNDRV_PCM_IOCTL_RESUME:
9575   case VKI_SNDRV_PCM_IOCTL_XRUN:
9576   case VKI_SNDRV_PCM_IOCTL_UNLINK:
9577   case VKI_SNDRV_TIMER_IOCTL_START:
9578   case VKI_SNDRV_TIMER_IOCTL_STOP:
9579   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
9580   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
9581      break;
9582
9583   case VKI_SNDRV_CTL_IOCTL_PVERSION: {
9584      POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
9585      break;
9586   }
9587   case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
9588      POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
9589      break;
9590   case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
9591      struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
9592      POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
9593      POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
9594      if (data->pids) {
9595         POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
9596      }
9597      break;
9598   }
9599   case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
9600      struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
9601      POST_MEM_WRITE( (Addr)data->tlv, data->length );
9602      break;
9603   }
9604   case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
9605   case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
9606      break;
9607
9608      /* SCSI no operand */
9609   case VKI_SCSI_IOCTL_DOORLOCK:
9610   case VKI_SCSI_IOCTL_DOORUNLOCK:
9611      break;
9612
9613      /* Real Time Clock (/dev/rtc) ioctls */
9614   case VKI_RTC_UIE_ON:
9615   case VKI_RTC_UIE_OFF:
9616   case VKI_RTC_AIE_ON:
9617   case VKI_RTC_AIE_OFF:
9618   case VKI_RTC_PIE_ON:
9619   case VKI_RTC_PIE_OFF:
9620   case VKI_RTC_IRQP_SET:
9621      break;
9622   case VKI_RTC_RD_TIME:
9623   case VKI_RTC_ALM_READ:
9624      POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
9625      break;
9626   case VKI_RTC_ALM_SET:
9627      break;
9628   case VKI_RTC_IRQP_READ:
9629      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9630      break;
9631
9632      /* Block devices */
9633   case VKI_BLKROSET:
9634      break;
9635   case VKI_BLKROGET:
9636      POST_MEM_WRITE(ARG3, sizeof(int));
9637      break;
9638   case VKI_BLKGETSIZE:
9639      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9640      break;
9641   case VKI_BLKRASET:
9642      break;
9643   case VKI_BLKRAGET:
9644      POST_MEM_WRITE(ARG3, sizeof(long));
9645      break;
9646   case VKI_BLKFRASET:
9647      break;
9648   case VKI_BLKFRAGET:
9649      POST_MEM_WRITE(ARG3, sizeof(long));
9650      break;
9651   case VKI_BLKSECTGET:
9652      POST_MEM_WRITE(ARG3, sizeof(unsigned short));
9653      break;
9654   case VKI_BLKSSZGET:
9655      POST_MEM_WRITE(ARG3, sizeof(int));
9656      break;
9657   case VKI_BLKBSZGET:
9658      POST_MEM_WRITE(ARG3, sizeof(int));
9659      break;
9660   case VKI_BLKBSZSET:
9661      break;
9662   case VKI_BLKGETSIZE64:
9663      POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
9664      break;
9665   case VKI_BLKPBSZGET:
9666      POST_MEM_WRITE(ARG3, sizeof(int));
9667      break;
9668   case VKI_BLKDISCARDZEROES:
9669      POST_MEM_WRITE(ARG3, sizeof(vki_uint));
9670      break;
9671
9672      /* Hard disks */
9673   case VKI_HDIO_GETGEO: /* 0x0301 */
9674      POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
9675      break;
9676   case VKI_HDIO_GET_DMA: /* 0x030b */
9677      POST_MEM_WRITE(ARG3, sizeof(long));
9678      break;
9679   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
9680      POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
9681      break;
9682
9683      /* SCSI */
9684   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
9685      POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
9686      break;
9687   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
9688      POST_MEM_WRITE(ARG3, sizeof(int));
9689      break;
9690
9691      /* CD ROM stuff (??)  */
9692   case VKI_CDROM_DISC_STATUS:
9693   case VKI_CDROMSTOP:
9694      break;
9695   case VKI_CDROMSUBCHNL:
9696      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
9697      break;
9698   case VKI_CDROMREADTOCHDR:
9699      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
9700      break;
9701   case VKI_CDROMREADTOCENTRY:
9702      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
9703      break;
9704   case VKI_CDROMMULTISESSION:
9705      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
9706      break;
9707   case VKI_CDROMVOLREAD:
9708      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
9709      break;
9710   case VKI_CDROMREADMODE1:
9711      POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
9712      break;
9713   case VKI_CDROMREADMODE2:
9714      POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
9715      break;
9716   case VKI_CDROMREADRAW:
9717      POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
9718      break;
9719   case VKI_CDROMREADAUDIO:
9720   {
9721      struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
9722      POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
9723      break;
9724   }
9725
9726   case VKI_CDROMPLAYMSF:
9727      break;
9728      /* The following two are probably bogus (should check args
9729	 for readability).  JRS 20021117 */
9730   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
9731   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
9732      break;
9733   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
9734      break;
9735
9736      /* DVD stuff */
9737   case VKI_DVD_READ_STRUCT:
9738      break;
9739
9740   case VKI_FIGETBSZ:
9741      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9742      break;
9743   case VKI_FIBMAP:
9744      POST_MEM_WRITE(ARG3, sizeof(int));
9745      break;
9746
9747   case VKI_FBIOGET_VSCREENINFO: //0x4600
9748      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
9749      break;
9750   case VKI_FBIOGET_FSCREENINFO: //0x4602
9751      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
9752      break;
9753
9754   case VKI_PPCLAIM:
9755   case VKI_PPEXCL:
9756   case VKI_PPYIELD:
9757   case VKI_PPRELEASE:
9758   case VKI_PPSETMODE:
9759   case VKI_PPSETPHASE:
9760   case VKI_PPSETFLAGS:
9761   case VKI_PPWDATA:
9762   case VKI_PPWCONTROL:
9763   case VKI_PPFCONTROL:
9764   case VKI_PPDATADIR:
9765   case VKI_PPNEGOT:
9766   case VKI_PPWCTLONIRQ:
9767   case VKI_PPSETTIME:
9768      break;
9769   case VKI_PPGETMODE:
9770      POST_MEM_WRITE( ARG3, sizeof(int) );
9771      break;
9772   case VKI_PPGETPHASE:
9773      POST_MEM_WRITE( ARG3, sizeof(int) );
9774      break;
9775   case VKI_PPGETMODES:
9776      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9777      break;
9778   case VKI_PPGETFLAGS:
9779      POST_MEM_WRITE( ARG3, sizeof(int) );
9780      break;
9781   case VKI_PPRSTATUS:
9782      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9783      break;
9784   case VKI_PPRDATA:
9785      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9786      break;
9787   case VKI_PPRCONTROL:
9788      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9789      break;
9790   case VKI_PPCLRIRQ:
9791      POST_MEM_WRITE( ARG3, sizeof(int) );
9792      break;
9793   case VKI_PPGETTIME:
9794      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9795      break;
9796
9797   case VKI_GIO_FONT:
9798      POST_MEM_WRITE( ARG3, 32 * 256 );
9799      break;
9800   case VKI_PIO_FONT:
9801      break;
9802
9803   case VKI_GIO_FONTX:
9804      POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
9805                      32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
9806      break;
9807   case VKI_PIO_FONTX:
9808      break;
9809
9810   case VKI_PIO_FONTRESET:
9811      break;
9812
9813   case VKI_GIO_CMAP:
9814      POST_MEM_WRITE( ARG3, 16 * 3 );
9815      break;
9816   case VKI_PIO_CMAP:
9817      break;
9818
9819   case VKI_KIOCSOUND:
9820   case VKI_KDMKTONE:
9821      break;
9822
9823   case VKI_KDGETLED:
9824      POST_MEM_WRITE( ARG3, sizeof(char) );
9825      break;
9826   case VKI_KDSETLED:
9827      break;
9828
9829   case VKI_KDGKBTYPE:
9830      POST_MEM_WRITE( ARG3, sizeof(char) );
9831      break;
9832
9833   case VKI_KDADDIO:
9834   case VKI_KDDELIO:
9835   case VKI_KDENABIO:
9836   case VKI_KDDISABIO:
9837      break;
9838
9839   case VKI_KDSETMODE:
9840      break;
9841   case VKI_KDGETMODE:
9842      POST_MEM_WRITE( ARG3, sizeof(int) );
9843      break;
9844
9845   case VKI_KDMAPDISP:
9846   case VKI_KDUNMAPDISP:
9847      break;
9848
9849   case VKI_GIO_SCRNMAP:
9850      POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
9851      break;
9852   case VKI_PIO_SCRNMAP:
9853      break;
9854   case VKI_GIO_UNISCRNMAP:
9855      POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
9856      break;
9857   case VKI_PIO_UNISCRNMAP:
9858      break;
9859
9860   case VKI_GIO_UNIMAP:
9861      if ( ARG3 ) {
9862         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
9863         POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
9864         POST_MEM_WRITE( (Addr)desc->entries,
9865      	                 desc->entry_ct * sizeof(struct vki_unipair) );
9866      }
9867      break;
9868   case VKI_PIO_UNIMAP:
9869      break;
9870   case VKI_PIO_UNIMAPCLR:
9871      break;
9872
9873   case VKI_KDGKBMODE:
9874      POST_MEM_WRITE( ARG3, sizeof(int) );
9875      break;
9876   case VKI_KDSKBMODE:
9877      break;
9878
9879   case VKI_KDGKBMETA:
9880      POST_MEM_WRITE( ARG3, sizeof(int) );
9881      break;
9882   case VKI_KDSKBMETA:
9883      break;
9884
9885   case VKI_KDGKBLED:
9886      POST_MEM_WRITE( ARG3, sizeof(char) );
9887      break;
9888   case VKI_KDSKBLED:
9889      break;
9890
9891   case VKI_KDGKBENT:
9892      POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
9893                      sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
9894      break;
9895   case VKI_KDSKBENT:
9896      break;
9897
9898   case VKI_KDGKBSENT:
9899      POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
9900                      sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
9901      break;
9902   case VKI_KDSKBSENT:
9903      break;
9904
9905   case VKI_KDGKBDIACR:
9906      POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
9907      break;
9908   case VKI_KDSKBDIACR:
9909      break;
9910
9911   case VKI_KDGETKEYCODE:
9912      POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
9913                      sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
9914      break;
9915   case VKI_KDSETKEYCODE:
9916      break;
9917
9918   case VKI_KDSIGACCEPT:
9919      break;
9920
9921   case VKI_KDKBDREP:
9922      break;
9923
9924   case VKI_KDFONTOP:
9925      if ( ARG3 ) {
9926         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
9927         switch ( op->op ) {
9928            case VKI_KD_FONT_OP_SET:
9929               break;
9930            case VKI_KD_FONT_OP_GET:
9931               if ( op->data )
9932                  POST_MEM_WRITE( (Addr) op->data,
9933                                  (op->width + 7) / 8 * 32 * op->charcount );
9934               break;
9935            case VKI_KD_FONT_OP_SET_DEFAULT:
9936               break;
9937            case VKI_KD_FONT_OP_COPY:
9938               break;
9939         }
9940         POST_MEM_WRITE( (Addr) op, sizeof(*op));
9941      }
9942      break;
9943
9944   case VKI_VT_OPENQRY:
9945      POST_MEM_WRITE( ARG3, sizeof(int) );
9946      break;
9947   case VKI_VT_GETMODE:
9948      POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
9949      break;
9950   case VKI_VT_SETMODE:
9951      break;
9952   case VKI_VT_GETSTATE:
9953      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
9954                      sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
9955      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
9956                      sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
9957      break;
9958   case VKI_VT_RELDISP:
9959   case VKI_VT_ACTIVATE:
9960   case VKI_VT_WAITACTIVE:
9961   case VKI_VT_DISALLOCATE:
9962      break;
9963   case VKI_VT_RESIZE:
9964      break;
9965   case VKI_VT_RESIZEX:
9966      break;
9967   case VKI_VT_LOCKSWITCH:
9968   case VKI_VT_UNLOCKSWITCH:
9969      break;
9970
9971   case VKI_USBDEVFS_CONTROL:
9972      if ( ARG3 ) {
9973         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
9974         if (vkuc->bRequestType & 0x80)
9975            POST_MEM_WRITE((Addr)vkuc->data, RES);
9976      }
9977      break;
9978   case VKI_USBDEVFS_BULK:
9979      if ( ARG3 ) {
9980         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
9981         if (vkub->ep & 0x80)
9982            POST_MEM_WRITE((Addr)vkub->data, RES);
9983      }
9984      break;
9985   case VKI_USBDEVFS_GETDRIVER:
9986      if ( ARG3 ) {
9987         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
9988         POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
9989      }
9990      break;
9991   case VKI_USBDEVFS_REAPURB:
9992   case VKI_USBDEVFS_REAPURBNDELAY:
9993      if ( ARG3 ) {
9994         struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
9995         POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
9996         if (!*vkuu)
9997            break;
9998         POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
9999         if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
10000            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
10001            if (vkusp->bRequestType & 0x80)
10002               POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
10003            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10004         } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
10005            char *bp = (*vkuu)->buffer;
10006            int i;
10007            for(i=0; i<(*vkuu)->number_of_packets; i++) {
10008               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
10009               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
10010               if ((*vkuu)->endpoint & 0x80)
10011                  POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
10012               bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
10013            }
10014            POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
10015         } else {
10016            if ((*vkuu)->endpoint & 0x80)
10017               POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
10018            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10019         }
10020      }
10021      break;
10022   case VKI_USBDEVFS_CONNECTINFO:
10023      POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
10024      break;
10025   case VKI_USBDEVFS_IOCTL:
10026      if ( ARG3 ) {
10027         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
10028         UInt dir2, size2;
10029         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
10030         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
10031         if (size2 > 0) {
10032            if (dir2 & _VKI_IOC_READ)
10033               POST_MEM_WRITE((Addr)vkui->data, size2);
10034         }
10035      }
10036      break;
10037
10038      /* I2C (/dev/i2c-*) ioctls */
10039   case VKI_I2C_SLAVE:
10040   case VKI_I2C_SLAVE_FORCE:
10041   case VKI_I2C_TENBIT:
10042   case VKI_I2C_PEC:
10043      break;
10044   case VKI_I2C_FUNCS:
10045      POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
10046      break;
10047   case VKI_I2C_RDWR:
10048      if ( ARG3 ) {
10049          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
10050          UInt i;
10051          for (i=0; i < vkui->nmsgs; i++) {
10052              struct vki_i2c_msg *msg = vkui->msgs + i;
10053              if (msg->flags & VKI_I2C_M_RD)
10054                  POST_MEM_WRITE((Addr)msg->buf, msg->len);
10055          }
10056      }
10057      break;
10058   case VKI_I2C_SMBUS:
10059       if ( ARG3 ) {
10060            struct vki_i2c_smbus_ioctl_data *vkis
10061               = (struct vki_i2c_smbus_ioctl_data *) ARG3;
10062            /* i2c_smbus_write_quick hides its value in read_write, so
10063               this variable can have a different meaning */
10064            if ((vkis->read_write == VKI_I2C_SMBUS_READ)
10065                || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
10066                || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
10067                if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
10068                    UInt size;
10069                    switch(vkis->size) {
10070                        case VKI_I2C_SMBUS_BYTE:
10071                        case VKI_I2C_SMBUS_BYTE_DATA:
10072                            size = 1;
10073                            break;
10074                        case VKI_I2C_SMBUS_WORD_DATA:
10075                        case VKI_I2C_SMBUS_PROC_CALL:
10076                            size = 2;
10077                            break;
10078                        case VKI_I2C_SMBUS_BLOCK_DATA:
10079                        case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
10080                        case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
10081                        case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
10082                            size = 1 + vkis->data->block[0];
10083                            break;
10084                        default:
10085                            size = 0;
10086                    }
10087                    POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
10088                }
10089            }
10090       }
10091       break;
10092
10093      /* Wireless extensions ioctls */
10094   case VKI_SIOCSIWCOMMIT:
10095   case VKI_SIOCSIWNWID:
10096   case VKI_SIOCSIWFREQ:
10097   case VKI_SIOCSIWMODE:
10098   case VKI_SIOCSIWSENS:
10099   case VKI_SIOCSIWRANGE:
10100   case VKI_SIOCSIWPRIV:
10101   case VKI_SIOCSIWSTATS:
10102   case VKI_SIOCSIWSPY:
10103   case VKI_SIOCSIWTHRSPY:
10104   case VKI_SIOCSIWAP:
10105   case VKI_SIOCSIWSCAN:
10106   case VKI_SIOCSIWESSID:
10107   case VKI_SIOCSIWRATE:
10108   case VKI_SIOCSIWNICKN:
10109   case VKI_SIOCSIWRTS:
10110   case VKI_SIOCSIWFRAG:
10111   case VKI_SIOCSIWTXPOW:
10112   case VKI_SIOCSIWRETRY:
10113   case VKI_SIOCSIWENCODE:
10114   case VKI_SIOCSIWPOWER:
10115   case VKI_SIOCSIWGENIE:
10116   case VKI_SIOCSIWMLME:
10117   case VKI_SIOCSIWAUTH:
10118   case VKI_SIOCSIWENCODEEXT:
10119   case VKI_SIOCSIWPMKSA:
10120      break;
10121   case VKI_SIOCGIWNAME:
10122      if (ARG3) {
10123         POST_MEM_WRITE((Addr)((struct vki_iwreq *)ARG3)->u.name,
10124                        sizeof(((struct vki_iwreq *)ARG3)->u.name));
10125      }
10126      break;
10127   case VKI_SIOCGIWNWID:
10128   case VKI_SIOCGIWSENS:
10129   case VKI_SIOCGIWRATE:
10130   case VKI_SIOCGIWRTS:
10131   case VKI_SIOCGIWFRAG:
10132   case VKI_SIOCGIWTXPOW:
10133   case VKI_SIOCGIWRETRY:
10134   case VKI_SIOCGIWPOWER:
10135   case VKI_SIOCGIWAUTH:
10136      if (ARG3) {
10137         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.param,
10138                        sizeof(struct vki_iw_param));
10139      }
10140      break;
10141   case VKI_SIOCGIWFREQ:
10142      if (ARG3) {
10143         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.freq,
10144                        sizeof(struct vki_iw_freq));
10145      }
10146      break;
10147   case VKI_SIOCGIWMODE:
10148      if (ARG3) {
10149         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.mode,
10150                       sizeof(__vki_u32));
10151      }
10152      break;
10153   case VKI_SIOCGIWRANGE:
10154   case VKI_SIOCGIWPRIV:
10155   case VKI_SIOCGIWSTATS:
10156   case VKI_SIOCGIWSPY:
10157   case VKI_SIOCGIWTHRSPY:
10158   case VKI_SIOCGIWAPLIST:
10159   case VKI_SIOCGIWSCAN:
10160   case VKI_SIOCGIWESSID:
10161   case VKI_SIOCGIWNICKN:
10162   case VKI_SIOCGIWENCODE:
10163   case VKI_SIOCGIWGENIE:
10164   case VKI_SIOCGIWENCODEEXT:
10165      if (ARG3) {
10166         struct vki_iw_point* point;
10167         point = &((struct vki_iwreq *)ARG3)->u.data;
10168         POST_MEM_WRITE((Addr)point->pointer, point->length);
10169      }
10170      break;
10171   case VKI_SIOCGIWAP:
10172      if (ARG3) {
10173         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
10174                        sizeof(struct vki_sockaddr));
10175      }
10176      break;
10177
10178#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
10179      || defined(VGPV_mips32_linux_android) \
10180      || defined(VGPV_arm64_linux_android)
10181   /* ashmem */
10182   case VKI_ASHMEM_GET_SIZE:
10183   case VKI_ASHMEM_SET_SIZE:
10184   case VKI_ASHMEM_GET_PROT_MASK:
10185   case VKI_ASHMEM_SET_PROT_MASK:
10186   case VKI_ASHMEM_GET_PIN_STATUS:
10187   case VKI_ASHMEM_PURGE_ALL_CACHES:
10188   case VKI_ASHMEM_SET_NAME:
10189   case VKI_ASHMEM_PIN:
10190   case VKI_ASHMEM_UNPIN:
10191       break;
10192   case VKI_ASHMEM_GET_NAME:
10193       POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
10194       break;
10195
10196   /* binder */
10197   case VKI_BINDER_WRITE_READ:
10198       if (ARG3) {
10199           struct vki_binder_write_read* bwr
10200              = (struct vki_binder_write_read*)ARG3;
10201           POST_FIELD_WRITE(bwr->write_consumed);
10202           POST_FIELD_WRITE(bwr->read_consumed);
10203
10204           if (bwr->read_size)
10205               POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
10206       }
10207       break;
10208
10209   case VKI_BINDER_SET_IDLE_TIMEOUT:
10210   case VKI_BINDER_SET_MAX_THREADS:
10211   case VKI_BINDER_SET_IDLE_PRIORITY:
10212   case VKI_BINDER_SET_CONTEXT_MGR:
10213   case VKI_BINDER_THREAD_EXIT:
10214       break;
10215   case VKI_BINDER_VERSION:
10216       if (ARG3) {
10217           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
10218           POST_FIELD_WRITE(bv->protocol_version);
10219       }
10220       break;
10221#  endif /* defined(VGPV_*_linux_android) */
10222
10223   case VKI_HCIGETDEVLIST:
10224      if (ARG3) {
10225        struct vki_hci_dev_list_req* dlr = (struct vki_hci_dev_list_req*)ARG3;
10226        POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
10227                       dlr->dev_num * sizeof(struct vki_hci_dev_req));
10228      }
10229      break;
10230
10231   case VKI_HCIINQUIRY:
10232      if (ARG3) {
10233        struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
10234        POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
10235                       ir->num_rsp * sizeof(struct vki_inquiry_info));
10236      }
10237      break;
10238
10239   case VKI_DRM_IOCTL_VERSION:
10240      if (ARG3) {
10241         struct vki_drm_version* data = (struct vki_drm_version *)ARG3;
10242         struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
10243         const vki_size_t orig_name_len = info->orig->name_len;
10244         const vki_size_t orig_date_len = info->orig->date_len;
10245         const vki_size_t orig_desc_len = info->orig->desc_len;
10246         *info->orig = info->data;
10247         ARG3 = (Addr)info->orig;
10248         data = info->orig;
10249         VG_(free)(info);
10250         if (SUCCESS) {
10251            POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
10252            POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
10253            POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
10254            POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
10255            POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
10256            POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
10257            POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
10258            POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
10259            POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
10260         }
10261      }
10262      break;
10263   case VKI_DRM_IOCTL_GET_UNIQUE:
10264      if (ARG3) {
10265         struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
10266	 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
10267      }
10268      break;
10269   case VKI_DRM_IOCTL_GET_MAGIC:
10270      if (ARG3) {
10271         struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
10272         POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
10273      }
10274      break;
10275   case VKI_DRM_IOCTL_WAIT_VBLANK:
10276      if (ARG3) {
10277         union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
10278         POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
10279      }
10280      break;
10281   case VKI_DRM_IOCTL_GEM_FLINK:
10282      if (ARG3) {
10283         struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
10284         POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
10285      }
10286      break;
10287   case VKI_DRM_IOCTL_GEM_OPEN:
10288      if (ARG3) {
10289         struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
10290	 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10291	 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
10292      }
10293      break;
10294   case VKI_DRM_IOCTL_I915_GETPARAM:
10295      if (ARG3) {
10296         vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
10297	 POST_MEM_WRITE((Addr)data->value, sizeof(int));
10298      }
10299      break;
10300   case VKI_DRM_IOCTL_I915_GEM_BUSY:
10301      if (ARG3) {
10302         struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
10303         POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
10304      }
10305      break;
10306   case VKI_DRM_IOCTL_I915_GEM_CREATE:
10307      if (ARG3) {
10308         struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
10309	 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10310      }
10311      break;
10312   case VKI_DRM_IOCTL_I915_GEM_PREAD:
10313      if (ARG3) {
10314         struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
10315	 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
10316      }
10317      break;
10318   case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
10319      if (ARG3) {
10320         struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
10321         POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
10322      }
10323      break;
10324   case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
10325      if (ARG3) {
10326         struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
10327         POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10328         POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
10329         POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10330      }
10331      break;
10332   case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
10333      if (ARG3) {
10334         struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
10335	 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10336         POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10337      }
10338      break;
10339   case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
10340      if (ARG3) {
10341         struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
10342         POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
10343         POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
10344      }
10345      break;
10346
10347   /* KVM ioctls that only write the system call return value */
10348   case VKI_KVM_GET_API_VERSION:
10349   case VKI_KVM_CREATE_VM:
10350   case VKI_KVM_CHECK_EXTENSION:
10351   case VKI_KVM_GET_VCPU_MMAP_SIZE:
10352   case VKI_KVM_S390_ENABLE_SIE:
10353   case VKI_KVM_CREATE_VCPU:
10354   case VKI_KVM_SET_TSS_ADDR:
10355   case VKI_KVM_CREATE_IRQCHIP:
10356   case VKI_KVM_RUN:
10357   case VKI_KVM_S390_INITIAL_RESET:
10358   case VKI_KVM_KVMCLOCK_CTRL:
10359      break;
10360
10361   case VKI_KVM_S390_MEM_OP: {
10362      struct vki_kvm_s390_mem_op *args =
10363         (struct vki_kvm_s390_mem_op *)(ARG3);
10364      if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
10365         break;
10366      if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
10367         POST_MEM_WRITE((Addr)args->buf, args->size);
10368      }
10369      break;
10370
10371#ifdef ENABLE_XEN
10372   case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
10373       SyscallArgs harrghs;
10374       struct vki_xen_privcmd_hypercall *args =
10375          (struct vki_xen_privcmd_hypercall *)(ARG3);
10376
10377       if (!args)
10378          break;
10379
10380       VG_(memset)(&harrghs, 0, sizeof(harrghs));
10381       harrghs.sysno = args->op;
10382       harrghs.arg1 = args->arg[0];
10383       harrghs.arg2 = args->arg[1];
10384       harrghs.arg3 = args->arg[2];
10385       harrghs.arg4 = args->arg[3];
10386       harrghs.arg5 = args->arg[4];
10387       harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
10388
10389       WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
10390      }
10391      break;
10392
10393   case VKI_XEN_IOCTL_PRIVCMD_MMAP:
10394      break;
10395   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
10396       struct vki_xen_privcmd_mmapbatch *args =
10397           (struct vki_xen_privcmd_mmapbatch *)(ARG3);
10398       POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
10399      }
10400      break;
10401   case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
10402       struct vki_xen_privcmd_mmapbatch_v2 *args =
10403           (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
10404       POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
10405      }
10406      break;
10407
10408   case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
10409   case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
10410   case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
10411   case VKI_XEN_IOCTL_EVTCHN_UNBIND:
10412   case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
10413   case VKI_XEN_IOCTL_EVTCHN_RESET:
10414      /* No output */
10415      break;
10416#endif
10417
10418   /* Lustre */
10419   case VKI_OBD_IOC_FID2PATH: {
10420       struct vki_getinfo_fid2path *args = (void *)(ARG3);
10421       POST_FIELD_WRITE(args->gf_recno);
10422       POST_FIELD_WRITE(args->gf_linkno);
10423       POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
10424       break;
10425      }
10426
10427   case VKI_LL_IOC_PATH2FID:
10428       POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
10429      break;
10430
10431   case VKI_LL_IOC_GETPARENT: {
10432       struct vki_getparent *gp = (struct vki_getparent *)ARG3;
10433       POST_FIELD_WRITE(gp->gp_fid);
10434       POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
10435       break;
10436   }
10437
10438   /* V4L2 */
10439   case VKI_V4L2_S_FMT:
10440   case VKI_V4L2_TRY_FMT:
10441   case VKI_V4L2_REQBUFS:
10442   case VKI_V4L2_OVERLAY:
10443   case VKI_V4L2_STREAMON:
10444   case VKI_V4L2_STREAMOFF:
10445   case VKI_V4L2_S_PARM:
10446   case VKI_V4L2_S_STD:
10447   case VKI_V4L2_S_FREQUENCY:
10448   case VKI_V4L2_S_CTRL:
10449   case VKI_V4L2_S_TUNER:
10450   case VKI_V4L2_S_AUDIO:
10451   case VKI_V4L2_S_INPUT:
10452   case VKI_V4L2_S_EDID:
10453   case VKI_V4L2_S_OUTPUT:
10454   case VKI_V4L2_S_AUDOUT:
10455   case VKI_V4L2_S_MODULATOR:
10456   case VKI_V4L2_S_JPEGCOMP:
10457   case VKI_V4L2_S_CROP:
10458   case VKI_V4L2_S_PRIORITY:
10459   case VKI_V4L2_S_HW_FREQ_SEEK:
10460   case VKI_V4L2_S_DV_TIMINGS:
10461   case VKI_V4L2_SUBSCRIBE_EVENT:
10462   case VKI_V4L2_UNSUBSCRIBE_EVENT:
10463   case VKI_V4L2_PREPARE_BUF:
10464      break;
10465   case VKI_V4L2_QUERYCAP: {
10466      struct vki_v4l2_capability *data = (struct vki_v4l2_capability *)ARG3;
10467      POST_MEM_WRITE((Addr)data, sizeof(*data));
10468      break;
10469   }
10470   case VKI_V4L2_ENUM_FMT: {
10471      struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)ARG3;
10472      POST_FIELD_WRITE(data->flags);
10473      POST_FIELD_WRITE(data->description);
10474      POST_FIELD_WRITE(data->pixelformat);
10475      POST_FIELD_WRITE(data->reserved);
10476      break;
10477   }
10478   case VKI_V4L2_G_FMT: {
10479      struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
10480      switch (data->type) {
10481      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
10482      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
10483         POST_FIELD_WRITE(data->fmt.pix);
10484         break;
10485      case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
10486      case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
10487         POST_FIELD_WRITE(data->fmt.vbi);
10488         break;
10489      case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
10490      case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
10491         POST_FIELD_WRITE(data->fmt.sliced);
10492         break;
10493      case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
10494      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
10495         POST_FIELD_WRITE(data->fmt.win);
10496         break;
10497      case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
10498      case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
10499         POST_FIELD_WRITE(data->fmt.pix_mp);
10500         break;
10501      case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
10502         POST_FIELD_WRITE(data->fmt.sdr);
10503         break;
10504      }
10505      break;
10506   }
10507   case VKI_V4L2_QUERYBUF: {
10508      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
10509      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10510            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10511         unsigned i;
10512
10513         for (i = 0; i < data->length; i++) {
10514            POST_FIELD_WRITE(data->m.planes[i].bytesused);
10515            POST_FIELD_WRITE(data->m.planes[i].length);
10516            POST_FIELD_WRITE(data->m.planes[i].m);
10517            POST_FIELD_WRITE(data->m.planes[i].data_offset);
10518            POST_FIELD_WRITE(data->m.planes[i].reserved);
10519         }
10520      } else {
10521         POST_FIELD_WRITE(data->m);
10522         POST_FIELD_WRITE(data->length);
10523      }
10524      POST_FIELD_WRITE(data->bytesused);
10525      POST_FIELD_WRITE(data->flags);
10526      POST_FIELD_WRITE(data->field);
10527      POST_FIELD_WRITE(data->timestamp);
10528      POST_FIELD_WRITE(data->timecode);
10529      POST_FIELD_WRITE(data->sequence);
10530      POST_FIELD_WRITE(data->memory);
10531      POST_FIELD_WRITE(data->sequence);
10532      break;
10533   }
10534   case VKI_V4L2_G_FBUF: {
10535      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
10536      POST_MEM_WRITE((Addr)data, sizeof(*data));
10537      break;
10538   }
10539   case VKI_V4L2_S_FBUF: {
10540      struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
10541      POST_FIELD_WRITE(data->capability);
10542      POST_FIELD_WRITE(data->flags);
10543      POST_FIELD_WRITE(data->fmt);
10544      break;
10545   }
10546   case VKI_V4L2_QBUF: {
10547      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
10548
10549      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10550            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10551         unsigned i;
10552
10553         for (i = 0; i < data->length; i++) {
10554            POST_FIELD_WRITE(data->m.planes[i].length);
10555            if (data->memory == VKI_V4L2_MEMORY_MMAP)
10556               POST_FIELD_WRITE(data->m.planes[i].m);
10557         }
10558      } else {
10559         if (data->memory == VKI_V4L2_MEMORY_MMAP)
10560            POST_FIELD_WRITE(data->m);
10561         POST_FIELD_WRITE(data->length);
10562      }
10563      break;
10564   }
10565   case VKI_V4L2_EXPBUF: {
10566      struct vki_v4l2_exportbuffer *data = (struct vki_v4l2_exportbuffer *)ARG3;
10567      POST_FIELD_WRITE(data->fd);
10568      break;
10569   }
10570   case VKI_V4L2_DQBUF: {
10571      struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
10572      POST_FIELD_WRITE(data->index);
10573      POST_FIELD_WRITE(data->bytesused);
10574      POST_FIELD_WRITE(data->field);
10575      if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10576            data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10577         unsigned i;
10578
10579         for (i = 0; i < data->length; i++) {
10580            POST_FIELD_WRITE(data->m.planes[i].bytesused);
10581            POST_FIELD_WRITE(data->m.planes[i].data_offset);
10582            POST_FIELD_WRITE(data->m.planes[i].length);
10583            POST_FIELD_WRITE(data->m.planes[i].m);
10584         }
10585      } else {
10586         POST_FIELD_WRITE(data->m);
10587         POST_FIELD_WRITE(data->length);
10588         POST_FIELD_WRITE(data->bytesused);
10589         POST_FIELD_WRITE(data->field);
10590      }
10591      POST_FIELD_WRITE(data->timestamp);
10592      POST_FIELD_WRITE(data->timecode);
10593      POST_FIELD_WRITE(data->sequence);
10594      break;
10595   }
10596   case VKI_V4L2_G_PARM: {
10597      struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
10598      int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
10599         data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
10600         data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
10601         data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
10602
10603      if (is_output)
10604        POST_MEM_WRITE((Addr)&data->parm.output,
10605            sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
10606      else
10607        POST_MEM_WRITE((Addr)&data->parm.capture,
10608            sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
10609      break;
10610   }
10611   case VKI_V4L2_G_STD: {
10612      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
10613      POST_MEM_WRITE((Addr)data, sizeof(*data));
10614      break;
10615   }
10616   case VKI_V4L2_ENUMSTD: {
10617      struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)ARG3;
10618      POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
10619      break;
10620   }
10621   case VKI_V4L2_ENUMINPUT: {
10622      struct vki_v4l2_input *data = (struct vki_v4l2_input *)ARG3;
10623      POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10624      break;
10625   }
10626   case VKI_V4L2_G_CTRL: {
10627      struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
10628      POST_FIELD_WRITE(data->value);
10629      break;
10630   }
10631   case VKI_V4L2_G_TUNER: {
10632      struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
10633      POST_MEM_WRITE((Addr)data->name,
10634            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10635      break;
10636   }
10637   case VKI_V4L2_G_AUDIO: {
10638      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
10639      POST_MEM_WRITE((Addr)data,
10640            sizeof(*data) - sizeof(data->reserved));
10641      break;
10642   }
10643   case VKI_V4L2_QUERYCTRL: {
10644      struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)ARG3;
10645      POST_MEM_WRITE((Addr)&data->type,
10646            sizeof(*data) - sizeof(data->id));
10647      break;
10648   }
10649   case VKI_V4L2_QUERYMENU: {
10650      struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)ARG3;
10651      POST_MEM_WRITE((Addr)data->name,
10652            sizeof(*data) - sizeof(data->id) - sizeof(data->index));
10653      break;
10654   }
10655   case VKI_V4L2_G_INPUT: {
10656      int *data = (int *)ARG3;
10657      POST_MEM_WRITE((Addr)data, sizeof(*data));
10658      break;
10659   }
10660   case VKI_V4L2_G_EDID: {
10661      struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
10662      if (data->blocks && data->edid)
10663         POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
10664      break;
10665   }
10666   case VKI_V4L2_G_OUTPUT: {
10667      int *data = (int *)ARG3;
10668      POST_MEM_WRITE((Addr)data, sizeof(*data));
10669      break;
10670   }
10671   case VKI_V4L2_ENUMOUTPUT: {
10672      struct vki_v4l2_output *data = (struct vki_v4l2_output *)ARG3;
10673      POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10674      break;
10675   }
10676   case VKI_V4L2_G_AUDOUT: {
10677      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
10678      POST_MEM_WRITE((Addr)data,
10679            sizeof(*data) - sizeof(data->reserved));
10680      break;
10681   }
10682   case VKI_V4L2_G_MODULATOR: {
10683      struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
10684      POST_MEM_WRITE((Addr)data->name,
10685            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10686      break;
10687   }
10688   case VKI_V4L2_G_FREQUENCY: {
10689      struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
10690      POST_FIELD_WRITE(data->type);
10691      POST_FIELD_WRITE(data->frequency);
10692      break;
10693   }
10694   case VKI_V4L2_CROPCAP: {
10695      struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)ARG3;
10696      POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
10697      break;
10698   }
10699   case VKI_V4L2_G_CROP: {
10700      struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
10701      POST_FIELD_WRITE(data->c);
10702      break;
10703   }
10704   case VKI_V4L2_G_JPEGCOMP: {
10705      struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
10706      POST_MEM_WRITE((Addr)data, sizeof(*data));
10707      break;
10708   }
10709   case VKI_V4L2_QUERYSTD: {
10710      vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
10711      POST_MEM_WRITE((Addr)data, sizeof(*data));
10712      break;
10713   }
10714   case VKI_V4L2_ENUMAUDIO: {
10715      struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
10716      POST_MEM_WRITE((Addr)data->name,
10717            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10718      break;
10719   }
10720   case VKI_V4L2_ENUMAUDOUT: {
10721      struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
10722      POST_MEM_WRITE((Addr)data->name,
10723            sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10724      break;
10725   }
10726   case VKI_V4L2_G_PRIORITY: {
10727      __vki_u32 *data = (__vki_u32 *)ARG3;
10728      POST_MEM_WRITE((Addr)data, sizeof(*data));
10729      break;
10730   }
10731   case VKI_V4L2_G_SLICED_VBI_CAP: {
10732      struct vki_v4l2_sliced_vbi_cap *data = (struct vki_v4l2_sliced_vbi_cap *)ARG3;
10733      POST_MEM_WRITE((Addr)data,
10734            sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
10735      break;
10736   }
10737   case VKI_V4L2_G_EXT_CTRLS: {
10738      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10739      if (data->count) {
10740         unsigned i;
10741
10742         for (i = 0; i < data->count; i++) {
10743            if (data->controls[i].size)
10744               POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
10745            else
10746               POST_FIELD_WRITE(data->controls[i].value64);
10747         }
10748      }
10749      POST_FIELD_WRITE(data->error_idx);
10750      break;
10751   }
10752   case VKI_V4L2_S_EXT_CTRLS: {
10753      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10754      POST_FIELD_WRITE(data->error_idx);
10755      break;
10756   }
10757   case VKI_V4L2_TRY_EXT_CTRLS: {
10758      struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10759      POST_FIELD_WRITE(data->error_idx);
10760      break;
10761   }
10762   case VKI_V4L2_ENUM_FRAMESIZES: {
10763      struct vki_v4l2_frmsizeenum *data = (struct vki_v4l2_frmsizeenum *)ARG3;
10764      POST_FIELD_WRITE(data->type);
10765      POST_FIELD_WRITE(data->stepwise);
10766      break;
10767   }
10768   case VKI_V4L2_ENUM_FRAMEINTERVALS: {
10769      struct vki_v4l2_frmivalenum *data = (struct vki_v4l2_frmivalenum *)ARG3;
10770      POST_FIELD_WRITE(data->type);
10771      POST_FIELD_WRITE(data->stepwise);
10772      break;
10773   }
10774   case VKI_V4L2_G_ENC_INDEX: {
10775      struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)ARG3;
10776      POST_MEM_WRITE((Addr)data, sizeof(*data));
10777      break;
10778   }
10779   case VKI_V4L2_ENCODER_CMD: {
10780      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
10781      POST_FIELD_WRITE(data->flags);
10782      break;
10783   }
10784   case VKI_V4L2_TRY_ENCODER_CMD: {
10785      struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
10786      POST_FIELD_WRITE(data->flags);
10787      break;
10788   }
10789   case VKI_V4L2_DBG_S_REGISTER: {
10790      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
10791      POST_FIELD_WRITE(data->size);
10792      break;
10793   }
10794   case VKI_V4L2_DBG_G_REGISTER: {
10795      struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
10796      POST_FIELD_WRITE(data->val);
10797      POST_FIELD_WRITE(data->size);
10798      break;
10799   }
10800   case VKI_V4L2_G_DV_TIMINGS: {
10801      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
10802      POST_MEM_WRITE((Addr)data, sizeof(*data));
10803      break;
10804   }
10805   case VKI_V4L2_DQEVENT: {
10806      struct vki_v4l2_event *data = (struct vki_v4l2_event *)ARG3;
10807      POST_MEM_WRITE((Addr)data, sizeof(*data));
10808      break;
10809   }
10810   case VKI_V4L2_CREATE_BUFS: {
10811      struct vki_v4l2_create_buffers *data = (struct vki_v4l2_create_buffers *)ARG3;
10812      POST_FIELD_WRITE(data->index);
10813      break;
10814   }
10815   case VKI_V4L2_G_SELECTION: {
10816      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
10817      POST_FIELD_WRITE(data->r);
10818      break;
10819   }
10820   case VKI_V4L2_S_SELECTION: {
10821      struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
10822      POST_FIELD_WRITE(data->r);
10823      break;
10824   }
10825   case VKI_V4L2_DECODER_CMD: {
10826      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
10827      POST_FIELD_WRITE(data->flags);
10828      break;
10829   }
10830   case VKI_V4L2_TRY_DECODER_CMD: {
10831      struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
10832      POST_FIELD_WRITE(data->flags);
10833      break;
10834   }
10835   case VKI_V4L2_ENUM_DV_TIMINGS: {
10836      struct vki_v4l2_enum_dv_timings *data = (struct vki_v4l2_enum_dv_timings *)ARG3;
10837      POST_FIELD_WRITE(data->timings);
10838      break;
10839   }
10840   case VKI_V4L2_QUERY_DV_TIMINGS: {
10841      struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
10842      POST_MEM_WRITE((Addr)data, sizeof(*data));
10843      break;
10844   }
10845   case VKI_V4L2_DV_TIMINGS_CAP: {
10846      struct vki_v4l2_dv_timings_cap *data = (struct vki_v4l2_dv_timings_cap *)ARG3;
10847      POST_MEM_WRITE((Addr)data, sizeof(*data));
10848      break;
10849   }
10850   case VKI_V4L2_ENUM_FREQ_BANDS: {
10851      struct vki_v4l2_frequency_band *data = (struct vki_v4l2_frequency_band *)ARG3;
10852      POST_FIELD_WRITE(data->capability);
10853      POST_FIELD_WRITE(data->rangelow);
10854      POST_FIELD_WRITE(data->rangehigh);
10855      POST_FIELD_WRITE(data->modulation);
10856      break;
10857   }
10858   case VKI_V4L2_DBG_G_CHIP_INFO: {
10859      struct vki_v4l2_dbg_chip_info *data = (struct vki_v4l2_dbg_chip_info *)ARG3;
10860      POST_FIELD_WRITE(data->name);
10861      POST_FIELD_WRITE(data->flags);
10862      break;
10863   }
10864   case VKI_V4L2_QUERY_EXT_CTRL: {
10865      struct vki_v4l2_query_ext_ctrl *data = (struct vki_v4l2_query_ext_ctrl *)ARG3;
10866      POST_MEM_WRITE((Addr)&data->type,
10867            sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
10868      break;
10869   }
10870
10871   case VKI_V4L2_SUBDEV_S_FMT:
10872   case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
10873   case VKI_V4L2_SUBDEV_S_CROP:
10874   case VKI_V4L2_SUBDEV_S_SELECTION:
10875      break;
10876
10877   case VKI_V4L2_SUBDEV_G_FMT: {
10878      struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
10879      POST_FIELD_WRITE(data->format);
10880      break;
10881   }
10882   case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
10883      struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
10884      POST_FIELD_WRITE(data->interval);
10885      break;
10886   }
10887   case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
10888      struct vki_v4l2_subdev_mbus_code_enum *data = (struct vki_v4l2_subdev_mbus_code_enum *)ARG3;
10889      POST_FIELD_WRITE(data->code);
10890      break;
10891   }
10892   case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
10893      struct vki_v4l2_subdev_frame_size_enum *data = (struct vki_v4l2_subdev_frame_size_enum *)ARG3;
10894      POST_FIELD_WRITE(data->min_width);
10895      POST_FIELD_WRITE(data->min_height);
10896      POST_FIELD_WRITE(data->max_width);
10897      POST_FIELD_WRITE(data->max_height);
10898      break;
10899   }
10900   case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10901      struct vki_v4l2_subdev_frame_interval_enum *data = (struct vki_v4l2_subdev_frame_interval_enum *)ARG3;
10902      POST_FIELD_WRITE(data->interval);
10903      break;
10904   }
10905   case VKI_V4L2_SUBDEV_G_CROP: {
10906      struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
10907      POST_FIELD_WRITE(data->rect);
10908      break;
10909   }
10910   case VKI_V4L2_SUBDEV_G_SELECTION: {
10911      struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
10912      POST_FIELD_WRITE(data->r);
10913      break;
10914   }
10915   case VKI_MEDIA_IOC_DEVICE_INFO: {
10916      struct vki_media_device_info *data = (struct vki_media_device_info *)ARG3;
10917      POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
10918      break;
10919   }
10920   case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10921      struct vki_media_entity_desc *data = (struct vki_media_entity_desc *)ARG3;
10922      POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
10923      break;
10924   }
10925   case VKI_MEDIA_IOC_ENUM_LINKS:
10926      /*
10927       * This ioctl does write to the provided pointers, but it's not
10928       * possible to deduce the size of the array those pointers point to.
10929       */
10930      break;
10931   case VKI_MEDIA_IOC_SETUP_LINK:
10932      break;
10933
10934   /* Serial */
10935   case VKI_TIOCGSERIAL: {
10936      struct vki_serial_struct *data = (struct vki_serial_struct *)ARG3;
10937      POST_MEM_WRITE((Addr)data, sizeof(*data));
10938      break;
10939   }
10940   case VKI_TIOCSSERIAL:
10941      break;
10942
10943   case VKI_PERF_EVENT_IOC_ENABLE:
10944   case VKI_PERF_EVENT_IOC_DISABLE:
10945   case VKI_PERF_EVENT_IOC_REFRESH:
10946   case VKI_PERF_EVENT_IOC_RESET:
10947   case VKI_PERF_EVENT_IOC_PERIOD:
10948   case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10949   case VKI_PERF_EVENT_IOC_SET_FILTER:
10950   case VKI_PERF_EVENT_IOC_SET_BPF:
10951      break;
10952
10953   case VKI_PERF_EVENT_IOC_ID:
10954      POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
10955      break;
10956
10957   default:
10958      /* EVIOC* are variable length and return size written on success */
10959      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10960      case VKI_EVIOCGNAME(0):
10961      case VKI_EVIOCGPHYS(0):
10962      case VKI_EVIOCGUNIQ(0):
10963      case VKI_EVIOCGKEY(0):
10964      case VKI_EVIOCGLED(0):
10965      case VKI_EVIOCGSND(0):
10966      case VKI_EVIOCGSW(0):
10967      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10968      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10969      case VKI_EVIOCGBIT(VKI_EV_REL,0):
10970      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10971      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10972      case VKI_EVIOCGBIT(VKI_EV_SW,0):
10973      case VKI_EVIOCGBIT(VKI_EV_LED,0):
10974      case VKI_EVIOCGBIT(VKI_EV_SND,0):
10975      case VKI_EVIOCGBIT(VKI_EV_REP,0):
10976      case VKI_EVIOCGBIT(VKI_EV_FF,0):
10977      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10978      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10979         if (RES > 0)
10980            POST_MEM_WRITE(ARG3, RES);
10981         break;
10982      default:
10983         ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
10984         break;
10985      }
10986      break;
10987   }
10988
10989  post_sys_ioctl__out:
10990   {} /* keep C compilers happy */
10991}
10992
10993/* ---------------------------------------------------------------------
10994   socketcall wrapper helpers
10995   ------------------------------------------------------------------ */
10996
10997void
10998ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
10999                                UWord arg0, UWord arg1, UWord arg2,
11000                                UWord arg3, UWord arg4 )
11001{
11002   /* int getsockopt(int s, int level, int optname,
11003                     void *optval, socklen_t *optlen); */
11004   Addr optval_p = arg3;
11005   Addr optlen_p = arg4;
11006   /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
11007   if (optval_p != (Addr)NULL) {
11008      ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
11009                                   "socketcall.getsockopt(optval)",
11010                                   "socketcall.getsockopt(optlen)" );
11011      if (arg1 == VKI_SOL_SCTP &&
11012          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11013           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11014      {
11015         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11016         int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
11017         PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
11018                        (Addr)ga->addrs, address_bytes );
11019      }
11020   }
11021}
11022
11023void
11024ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
11025                                 SysRes res,
11026                                 UWord arg0, UWord arg1, UWord arg2,
11027                                 UWord arg3, UWord arg4 )
11028{
11029   Addr optval_p = arg3;
11030   Addr optlen_p = arg4;
11031   vg_assert(!sr_isError(res)); /* guaranteed by caller */
11032   if (optval_p != (Addr)NULL) {
11033      ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
11034                                    "socketcall.getsockopt(optlen_out)" );
11035      if (arg1 == VKI_SOL_SCTP &&
11036          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11037           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11038      {
11039         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11040         struct vki_sockaddr *a = ga->addrs;
11041         int i;
11042         for (i = 0; i < ga->addr_num; i++) {
11043            int sl = 0;
11044            if (a->sa_family == VKI_AF_INET)
11045               sl = sizeof(struct vki_sockaddr_in);
11046            else if (a->sa_family == VKI_AF_INET6)
11047               sl = sizeof(struct vki_sockaddr_in6);
11048            else {
11049               VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
11050                                        "address type %d\n", a->sa_family);
11051            }
11052            a = (struct vki_sockaddr*)((char*)a + sl);
11053         }
11054         POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
11055      }
11056   }
11057}
11058
11059void
11060ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
11061                                UWord arg0, UWord arg1, UWord arg2,
11062                                UWord arg3, UWord arg4 )
11063{
11064   /* int setsockopt(int s, int level, int optname,
11065                     const void *optval, socklen_t optlen); */
11066   Addr optval_p = arg3;
11067   if (optval_p != (Addr)NULL) {
11068      /*
11069       * OK, let's handle at least some setsockopt levels and options
11070       * ourselves, so we don't get false claims of references to
11071       * uninitialized memory (such as padding in structures) and *do*
11072       * check what pointers in the argument point to.
11073       */
11074      if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
11075      {
11076         struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
11077
11078         /*
11079          * struct sock_fprog has a 16-bit count of instructions,
11080          * followed by a pointer to an array of those instructions.
11081          * There's padding between those two elements.
11082          *
11083          * So that we don't bogusly complain about the padding bytes,
11084          * we just report that we read len and and filter.
11085          *
11086          * We then make sure that what filter points to is valid.
11087          */
11088         PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
11089                       (Addr)&fp->len, sizeof(fp->len) );
11090         PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
11091                       (Addr)&fp->filter, sizeof(fp->filter) );
11092
11093         /* len * sizeof (*filter) */
11094         if (fp->filter != NULL)
11095         {
11096            PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
11097                          (Addr)(fp->filter),
11098                          fp->len * sizeof(*fp->filter) );
11099         }
11100      }
11101      else
11102      {
11103         PRE_MEM_READ( "socketcall.setsockopt(optval)",
11104                       arg3, /* optval */
11105                       arg4  /* optlen */ );
11106      }
11107   }
11108}
11109
11110void
11111ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
11112                              UWord arg1, UWord arg2, UWord arg3,
11113                              UWord arg4, UWord arg5 )
11114{
11115   struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11116   HChar name[40];     // large enough
11117   UInt i;
11118   for (i = 0; i < arg3; i++) {
11119      VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11120      ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
11121      VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
11122      PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11123   }
11124   if (arg5)
11125      PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
11126}
11127
11128void
11129ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
11130                              UWord arg1, UWord arg2, UWord arg3,
11131                              UWord arg4, UWord arg5 )
11132{
11133   if (res > 0) {
11134      struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11135      HChar name[32];    // large enough
11136      UInt i;
11137      for (i = 0; i < res; i++) {
11138         VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11139         ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
11140         POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11141      }
11142   }
11143}
11144
11145void
11146ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
11147                              UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11148{
11149   struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11150   HChar name[40];     // large enough
11151   UInt i;
11152   for (i = 0; i < arg3; i++) {
11153      VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11154      ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
11155      VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
11156      PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11157   }
11158}
11159
11160void
11161ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
11162                              UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11163{
11164   if (res > 0) {
11165      struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11166      UInt i;
11167      for (i = 0; i < res; i++) {
11168         POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11169      }
11170   }
11171}
11172
11173/* ---------------------------------------------------------------------
11174   ptrace wrapper helpers
11175   ------------------------------------------------------------------ */
11176
11177void
11178ML_(linux_POST_traceme) ( ThreadId tid )
11179{
11180  ThreadState *tst = VG_(get_ThreadState)(tid);
11181  tst->ptrace = VKI_PT_PTRACED;
11182}
11183
11184void
11185ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
11186{
11187   struct vki_iovec *iov = (struct vki_iovec *) arg4;
11188
11189   PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
11190   PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
11191   if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11192      PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
11193                    (Addr) iov->iov_base, iov->iov_len);
11194   }
11195}
11196
11197void
11198ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
11199{
11200   struct vki_iovec *iov = (struct vki_iovec *) arg4;
11201
11202   PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
11203   PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
11204   if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11205      PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
11206                   (Addr) iov->iov_base, iov->iov_len);
11207   }
11208}
11209
11210void
11211ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
11212{
11213   struct vki_iovec *iov = (struct vki_iovec *) arg4;
11214
11215   /* XXX: The actual amount of data written by the kernel might be
11216      less than iov_len, depending on the regset (arg3). */
11217   POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
11218}
11219
11220PRE(sys_kcmp)
11221{
11222   PRINT("kcmp ( %ld, %ld, %ld, %lu, %lu )", SARG1, SARG2, SARG3, ARG4, ARG5);
11223   switch (ARG3) {
11224      case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
11225      case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
11226         /* Most of the comparison types don't look at |idx1| or
11227            |idx2|. */
11228         PRE_REG_READ3(long, "kcmp",
11229                       vki_pid_t, pid1, vki_pid_t, pid2, int, type);
11230         break;
11231      case VKI_KCMP_FILE:
11232      default:
11233         PRE_REG_READ5(long, "kcmp",
11234                       vki_pid_t, pid1, vki_pid_t, pid2, int, type,
11235                       unsigned long, idx1, unsigned long, idx2);
11236         break;
11237   }
11238}
11239
11240#undef PRE
11241#undef POST
11242
11243#endif // defined(VGO_linux)
11244
11245/*--------------------------------------------------------------------*/
11246/*--- end                                                          ---*/
11247/*--------------------------------------------------------------------*/
11248